From 842272a9e39f8326a99b650a37441d56db9d2aee Mon Sep 17 00:00:00 2001 From: Pip Potter Date: Wed, 9 Jun 2021 22:50:44 -0700 Subject: [PATCH 01/93] LYN-4175: Improve security of s3 bucket example --- .../cdk/example/example_resources_stack.py | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) 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 From 3c46a72672aa24f3d34227396e2d44e641a764af Mon Sep 17 00:00:00 2001 From: Yuriy Toporovskyy Date: Wed, 26 May 2021 16:48:39 -0400 Subject: [PATCH 02/93] Bug fix: handle the case where a container has only default elements --- .../Serialization/Json/BasicContainerSerializer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index 400a3b7949..525e42a1dd 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -102,6 +102,17 @@ namespace AZ return context.Report(retVal, "Processing of basic container was halted."); } + // If each container element was 'DefaultsUsed', then the result code will be 'DefaultsUsed' + // But this is wrong if the container has at least one element, because a container with + // at least one element is certainly not the default container value. + // Basically, the following are different objects: + // [ {} ] // The container which has only default elements, but is not the empty container + // {} // The default container, which is empty + if (index > 0) + { + retVal.Combine(JSR::ResultCode(JSR::Tasks::WriteValue, JSR::Outcomes::Success)); + } + if (context.ShouldKeepDefaults()) { outputValue = AZStd::move(array); From 6f50207b06083766875c0ae8a1a43d963ff963c6 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Thu, 10 Jun 2021 09:23:05 -0700 Subject: [PATCH 03/93] Updated the unit tests for the Json Serialization array fix --- .../Json/BasicContainerSerializer.cpp | 15 ++++----------- .../Json/BasicContainerSerializerTests.cpp | 5 ++--- .../Serialization/Json/MapSerializerTests.cpp | 4 ++-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index 525e42a1dd..8fe1f471c1 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -102,17 +102,6 @@ namespace AZ return context.Report(retVal, "Processing of basic container was halted."); } - // If each container element was 'DefaultsUsed', then the result code will be 'DefaultsUsed' - // But this is wrong if the container has at least one element, because a container with - // at least one element is certainly not the default container value. - // Basically, the following are different objects: - // [ {} ] // The container which has only default elements, but is not the empty container - // {} // The default container, which is empty - if (index > 0) - { - retVal.Combine(JSR::ResultCode(JSR::Tasks::WriteValue, JSR::Outcomes::Success)); - } - if (context.ShouldKeepDefaults()) { outputValue = AZStd::move(array); @@ -134,6 +123,10 @@ namespace AZ { if (retVal.HasDoneWork()) { + // If at least one value was written, even if it has all defaults, then the array has + // a value written to it and is therefore not in a default state anymore. + retVal.Combine(JSR::ResultCode(JSR::Tasks::WriteValue, JSR::Outcomes::Success)); + outputValue = AZStd::move(array); return context.Report(retVal, "Content written to basic container."); } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp index 88e888743e..b3c900c710 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp @@ -301,7 +301,7 @@ namespace JsonSerializationTests ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, &instance, azrtti_typeid(&instance), *m_jsonSerializationContext); EXPECT_EQ(Processing::Completed, result.GetProcessing()); - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); Expect_DocStrEq("[{}]"); } @@ -315,7 +315,7 @@ namespace JsonSerializationTests ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, nullptr, azrtti_typeid(&instance), *m_jsonSerializationContext); EXPECT_EQ(Processing::Completed, result.GetProcessing()); - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); Expect_DocStrEq("[{},{}]"); } @@ -330,7 +330,6 @@ namespace JsonSerializationTests ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, nullptr, azrtti_typeid(&instance), *m_jsonSerializationContext); EXPECT_EQ(Processing::Completed, result.GetProcessing()); EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); - EXPECT_NE(Outcomes::DefaultsUsed, result.GetOutcome()); Expect_DocStrEq(R"([{"$type": "SimpleInheritence"},{"$type": "SimpleInheritence"}])"); } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp index 5dec394351..363cd7a7b7 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp @@ -636,7 +636,7 @@ namespace JsonSerializationTests azrtti_typeid(&values), *m_jsonSerializationContext); EXPECT_EQ(Processing::Completed, result.GetProcessing()); - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); Expect_DocStrEq(R"( { "{}": {} @@ -654,7 +654,7 @@ namespace JsonSerializationTests azrtti_typeid(&values), *m_jsonSerializationContext); EXPECT_EQ(Processing::Completed, result.GetProcessing()); - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); Expect_DocStrEq(R"( { "{}": {} From a98355e000095542aec130f7c8c6b2f5bbb5e1cc Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Fri, 11 Jun 2021 13:41:54 -0700 Subject: [PATCH 04/93] Fix PODs not initializing in Json Serialization When pointers are used new instances are created for pod types, which will have random values at that point. The Json Serialization did not set a value for these if they were explicitly set to defaults. This change adds initialization for explicit defaults in the bool, integer and double serializer plus unit tests to verify. --- .../Serialization/Json/BoolSerializer.cpp | 21 +++++-- .../Serialization/Json/BoolSerializer.h | 1 + .../Serialization/Json/DoubleSerializer.cpp | 31 ++++++++-- .../Serialization/Json/DoubleSerializer.h | 2 + .../Serialization/Json/IntSerializer.cpp | 46 ++++++++++----- .../AzCore/Serialization/Json/IntSerializer.h | 58 +++++++++---------- .../Json/BoolSerializerTests.cpp | 38 ++++++++++++ .../Json/DoubleSerializerTests.cpp | 49 ++++++++++++++++ .../Serialization/Json/IntSerializerTests.cpp | 38 ++++++++++++ 9 files changed, 229 insertions(+), 55 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp index d37e512ac2..7ac16b214d 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp @@ -30,8 +30,8 @@ namespace AZ if (text && textLength > 0) { - static constexpr const char trueString[] = "true"; - static constexpr const char falseString[] = "false"; + static constexpr const char* trueString = "true"; + static constexpr const char* falseString = "false"; // remove null terminator for string length counts // rapidjson stringlength doesn't include it in length calculations, but sizeof() will static constexpr size_t trueStringLength = sizeof(trueString) - 1; @@ -82,12 +82,18 @@ namespace AZ bool* valAsBool = reinterpret_cast(outputValue); + if (IsExplicitDefault(inputValue)) + { + *valAsBool = false; + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Boolean value set to default of 'false'."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: - // fallthrough + [[fallthrough]]; case rapidjson::kObjectType: - // fallthrough + [[fallthrough]]; case rapidjson::kNullType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Booleans can't be read from arrays, objects or null."); @@ -96,7 +102,7 @@ namespace AZ return SerializerInternal::TextToValue(valAsBool, inputValue.GetString(), inputValue.GetStringLength(), context); case rapidjson::kFalseType: - // fallthrough + [[fallthrough]]; case rapidjson::kTrueType: *valAsBool = inputValue.GetBool(); return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read boolean."); @@ -145,4 +151,9 @@ namespace AZ return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default boolean used."); } + + auto JsonBoolSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h index ac288c73ed..f000a03317 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h @@ -27,5 +27,6 @@ namespace AZ JsonDeserializerContext& context) override; JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp index 9140be7fcd..647ff67eb6 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp @@ -62,19 +62,26 @@ namespace AZ } template - static JsonSerializationResult::Result Load(T* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + static JsonSerializationResult::Result Load( + T* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context, bool isExplicitDefault) { namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. static_assert(AZStd::is_floating_point::value, "Expected T to be a floating point type"); AZ_Assert(outputValue, "Expected a valid pointer to load from json value."); + if (isExplicitDefault) + { + *outputValue = 0.0f; + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Double value set to default of 0.0."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: - // fallthrough + [[fallthrough]]; case rapidjson::kObjectType: - // fallthrough + [[fallthrough]]; case rapidjson::kNullType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Floating point values can't be read from arrays, objects or null."); @@ -83,7 +90,7 @@ namespace AZ return TextToValue(outputValue, inputValue.GetString(), context); case rapidjson::kFalseType: - // fallthrough + [[fallthrough]]; case rapidjson::kTrueType: *outputValue = inputValue.GetBool() ? 1.0f : 0.0f; return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, @@ -144,7 +151,8 @@ namespace AZ "Unable to deserialize double to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerFloatingPointInternal::Load(reinterpret_cast(outputValue), inputValue, context); + return SerializerFloatingPointInternal::Load( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonDoubleSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -156,6 +164,11 @@ namespace AZ return SerializerFloatingPointInternal::Store(outputValue, inputValue, defaultValue, context); } + auto JsonDoubleSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + JsonSerializationResult::Result JsonFloatSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { @@ -163,7 +176,8 @@ namespace AZ "Unable to deserialize float to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerFloatingPointInternal::Load(reinterpret_cast(outputValue), inputValue, context); + return SerializerFloatingPointInternal::Load( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonFloatSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -174,4 +188,9 @@ namespace AZ AZ_UNUSED(valueTypeId); return SerializerFloatingPointInternal::Store(outputValue, inputValue, defaultValue, context); } + + auto JsonFloatSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h index 81e631d9ab..a8c37316f0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h @@ -28,6 +28,7 @@ namespace AZ JsonDeserializerContext& context) override; JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; }; class JsonFloatSerializer @@ -40,5 +41,6 @@ namespace AZ JsonDeserializerContext& context) override; JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp index cc365da4f7..28da852da3 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp @@ -25,6 +25,8 @@ namespace AZ { + AZ_CLASS_ALLOCATOR_IMPL(BaseJsonIntegerSerializer, SystemAllocator, 0); + AZ_CLASS_ALLOCATOR_IMPL(JsonCharSerializer, SystemAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(JsonShortSerializer, SystemAllocator, 0); AZ_CLASS_ALLOCATOR_IMPL(JsonIntSerializer, SystemAllocator, 0); @@ -56,19 +58,25 @@ namespace AZ template static JsonSerializationResult::Result LoadInt(T* outputValue, const rapidjson::Value& inputValue, - JsonDeserializerContext& context) + JsonDeserializerContext& context, bool isDefaultValue) { namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. static_assert(AZStd::is_integral(), "Expected T to be a signed or unsigned type"); AZ_Assert(outputValue, "Expected a valid pointer to load from json value."); + if (isDefaultValue) + { + *outputValue = 0; + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Integer value set to default of zero."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: - // fallthrough + [[fallthrough]]; case rapidjson::kObjectType: - // fallthrough + [[fallthrough]]; case rapidjson::kNullType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Integers can't be read from arrays, objects or null."); @@ -77,7 +85,7 @@ namespace AZ return TextToValue(outputValue, inputValue.GetString(), context); case rapidjson::kFalseType: - // fallthrough + [[fallthrough]]; case rapidjson::kTrueType: *outputValue = inputValue.GetBool() ? 1 : 0; return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, @@ -125,6 +133,11 @@ namespace AZ } } // namespace SerializerInternal + auto BaseJsonIntegerSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + JsonSerializationResult::Result JsonCharSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { @@ -132,7 +145,7 @@ namespace AZ "Unable to deserialize char to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonCharSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, @@ -151,7 +164,7 @@ namespace AZ "Unable to deserialize short to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonShortSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, @@ -170,7 +183,7 @@ namespace AZ "Unable to deserialize int to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonIntSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, @@ -189,7 +202,7 @@ namespace AZ "Unable to deserialize long to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, @@ -208,7 +221,7 @@ namespace AZ "Unable to deserialize long long to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonLongLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, @@ -227,7 +240,8 @@ namespace AZ "Unable to deserialize unsigned char to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonUnsignedCharSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -246,7 +260,8 @@ namespace AZ "Unable to deserialize unsigned short to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonUnsignedShortSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -265,7 +280,8 @@ namespace AZ "Unable to deserialize unsigned int to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonUnsignedIntSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -284,7 +300,8 @@ namespace AZ "Unable to deserialize unsigned long to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonUnsignedLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -303,7 +320,8 @@ namespace AZ "Unable to deserialize unsigned long long to json because the provided type is %s", outputValueTypeId.ToString().c_str()); AZ_UNUSED(outputValueTypeId); - return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context); + return SerializerInternal::LoadInt( + reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonUnsignedLongLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h index 9f522619ae..31d5a4164a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h @@ -18,11 +18,18 @@ namespace AZ { - class JsonCharSerializer - : public BaseJsonSerializer + class BaseJsonIntegerSerializer : public BaseJsonSerializer { public: - AZ_RTTI(JsonCharSerializer, "{CA2A4AAC-3068-40B2-94F8-A537FBA8236E}", BaseJsonSerializer); + AZ_RTTI(BaseJsonIntegerSerializer, "{FD060F54-D3B5-4D5B-B64A-AFE371CD6F20}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + OperationFlags GetOperationsFlags() const override; + }; + + class JsonCharSerializer : public BaseJsonIntegerSerializer + { + public: + AZ_RTTI(JsonCharSerializer, "{CA2A4AAC-3068-40B2-94F8-A537FBA8236E}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -30,11 +37,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonShortSerializer - : public BaseJsonSerializer + class JsonShortSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonShortSerializer, "{3D6789BD-231B-4E5D-B81D-609E71A2BCB5}", BaseJsonSerializer); + AZ_RTTI(JsonShortSerializer, "{3D6789BD-231B-4E5D-B81D-609E71A2BCB5}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -42,11 +48,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonIntSerializer - : public BaseJsonSerializer + class JsonIntSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonIntSerializer, "{29E26946-0F1F-44B0-A098-1171B7B0C8FA}", BaseJsonSerializer); + AZ_RTTI(JsonIntSerializer, "{29E26946-0F1F-44B0-A098-1171B7B0C8FA}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -54,11 +59,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonLongSerializer - : public BaseJsonSerializer + class JsonLongSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonLongSerializer, "{0EB432D0-A0C8-43B2-9D65-A73A4D6DFE3E}", BaseJsonSerializer); + AZ_RTTI(JsonLongSerializer, "{0EB432D0-A0C8-43B2-9D65-A73A4D6DFE3E}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -66,11 +70,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonLongLongSerializer - : public BaseJsonSerializer + class JsonLongLongSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonLongLongSerializer, "{5E7967DE-A4DC-40E1-81A1-2896A054BB8A}", BaseJsonSerializer); + AZ_RTTI(JsonLongLongSerializer, "{5E7967DE-A4DC-40E1-81A1-2896A054BB8A}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -78,11 +81,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonUnsignedCharSerializer - : public BaseJsonSerializer + class JsonUnsignedCharSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonUnsignedCharSerializer, "{1E6D606F-8490-4736-AAFF-91046FDEA2BB}", BaseJsonSerializer); + AZ_RTTI(JsonUnsignedCharSerializer, "{1E6D606F-8490-4736-AAFF-91046FDEA2BB}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -90,11 +92,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonUnsignedShortSerializer - : public BaseJsonSerializer + class JsonUnsignedShortSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonUnsignedShortSerializer, "{3C92D2CC-CB13-4A40-B779-47562EE36451}", BaseJsonSerializer); + AZ_RTTI(JsonUnsignedShortSerializer, "{3C92D2CC-CB13-4A40-B779-47562EE36451}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -102,11 +103,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonUnsignedIntSerializer - : public BaseJsonSerializer + class JsonUnsignedIntSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonUnsignedIntSerializer, "{70C0714A-690D-4F30-8986-ABC9DEFE9D62}", BaseJsonSerializer); + AZ_RTTI(JsonUnsignedIntSerializer, "{70C0714A-690D-4F30-8986-ABC9DEFE9D62}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -114,11 +114,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonUnsignedLongSerializer - : public BaseJsonSerializer + class JsonUnsignedLongSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonUnsignedLongSerializer, "{28E5499F-6AF4-4778-AE14-66BA40B56247}", BaseJsonSerializer); + AZ_RTTI(JsonUnsignedLongSerializer, "{28E5499F-6AF4-4778-AE14-66BA40B56247}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -126,11 +125,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonUnsignedLongLongSerializer - : public BaseJsonSerializer + class JsonUnsignedLongLongSerializer : public BaseJsonIntegerSerializer { public: - AZ_RTTI(JsonUnsignedLongLongSerializer, "{AB048BB3-C280-4166-9E2E-54CE2C3413CA}", BaseJsonSerializer); + AZ_RTTI(JsonUnsignedLongLongSerializer, "{AB048BB3-C280-4166-9E2E-54CE2C3413CA}", BaseJsonIntegerSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp index cf9d76e79d..6396e4ccdf 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp @@ -63,6 +63,18 @@ namespace JsonSerializationTests : public BaseJsonSerializerFixture { public: + struct BoolPointerWrapper + { + AZ_TYPE_INFO(BoolPointerWrapper, "{2E67C069-BB0F-4F00-A704-E964F5FE5ED2}"); + + bool* m_value{ nullptr }; + + ~BoolPointerWrapper() + { + azfree(m_value); + } + }; + void SetUp() override { BaseJsonSerializerFixture::SetUp(); @@ -75,6 +87,12 @@ namespace JsonSerializationTests BaseJsonSerializerFixture::TearDown(); } + void RegisterAdditional(AZStd::unique_ptr& serializeContext) override + { + serializeContext->Class() + ->Field("Value", &BoolPointerWrapper::m_value); + } + void Load(rapidjson::Value& testVal, bool expectedBool, AZ::JsonSerializationResult::Outcomes expectedOutcome) { using namespace AZ::JsonSerializationResult; @@ -242,4 +260,24 @@ namespace JsonSerializationTests Load(m_jsonValue.SetDouble(-1.0f), true, AZ::JsonSerializationResult::Outcomes::Success); Load(m_jsonValue.SetDouble(2.0), true, AZ::JsonSerializationResult::Outcomes::Success); } + + TEST_F(JsonBoolSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized) + { + using namespace AZ::JsonSerializationResult; + + BoolPointerWrapper instance; + + this->m_jsonDocument->Parse(R"({ "Value": {}})"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); + + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + ASSERT_NE(nullptr, instance.m_value); + EXPECT_FALSE(*instance.m_value); + } } // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp index d19c38fcdc..4279017276 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp @@ -71,6 +71,20 @@ namespace JsonSerializationTests : public BaseJsonSerializerFixture { public: + struct DoublePointerWrapper + { + AZ_TYPE_INFO(DoublePointerWrapper, "{C2FD9E0B-2641-4D24-A3D9-A29FD1A21A81}"); + + double* m_double{ nullptr }; + float* m_float{ nullptr }; + + ~DoublePointerWrapper() + { + azfree(m_float); + azfree(m_double); + } + }; + void SetUp() override { BaseJsonSerializerFixture::SetUp(); @@ -85,6 +99,13 @@ namespace JsonSerializationTests BaseJsonSerializerFixture::TearDown(); } + void RegisterAdditional(AZStd::unique_ptr& serializeContext) override + { + serializeContext->Class() + ->Field("Double", &DoublePointerWrapper::m_double) + ->Field("Float", &DoublePointerWrapper::m_float); + } + void TestSerializers(rapidjson::Value& testVal, double expectedValue, AZ::JsonSerializationResult::Outcomes expectedOutcome) { using namespace AZ::JsonSerializationResult; @@ -275,4 +296,32 @@ namespace JsonSerializationTests EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); EXPECT_EQ(42.0f, value); } + + // Pointers + + TEST_F(JsonDoubleSerializerTests, Load_LoadDefaultToPointer_ValuesArIsInitialized) + { + using namespace AZ::JsonSerializationResult; + + DoublePointerWrapper instance; + + this->m_jsonDocument->Parse(R"( + { + "Double": {}, + "Float": {} + })"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); + + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + ASSERT_NE(nullptr, instance.m_double); + ASSERT_NE(nullptr, instance.m_float); + EXPECT_DOUBLE_EQ(0.0, *instance.m_double); + EXPECT_FLOAT_EQ(0.0f, *instance.m_float); + } } // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp index db764badcb..c4132e983c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp @@ -147,6 +147,18 @@ namespace JsonSerializationTests : public BaseJsonSerializerFixture { public: + struct IntegerPointerWrapper + { + AZ_TYPE_INFO(IntegerPointerWrapper, "{F6B3BEF1-59A4-4E45-BF02-DDA868C38A28}"); + + typename SerializerInfo::DataType* m_value{ nullptr }; + + ~IntegerPointerWrapper() + { + azfree(m_value); + } + }; + AZStd::unique_ptr m_serializer; void SetUp() override @@ -161,6 +173,12 @@ namespace JsonSerializationTests BaseJsonSerializerFixture::TearDown(); } + void RegisterAdditional(AZStd::unique_ptr& serializeContext) override + { + serializeContext->Class() + ->Field("Value", &IntegerPointerWrapper::m_value); + } + template::value, int> = 0> void SetValue(rapidjson::Value& out, T in) { @@ -487,6 +505,26 @@ namespace JsonSerializationTests EXPECT_EQ(typename SerializerInfo::DataType(), convertedValue); } + TYPED_TEST(TypedJsonIntSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized) + { + using namespace AZ::JsonSerializationResult; + + IntegerPointerWrapper instance; + + this->m_jsonDocument->Parse(R"({ "Value": {}})"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); + + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + ASSERT_NE(nullptr, instance.m_value); + EXPECT_EQ(0, *instance.m_value); + } + TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxInt8Value_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxShortValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxIntValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } From 716e99a8a74cf0c1952c96041896653191a31785 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:28:56 -0700 Subject: [PATCH 05/93] Reverted string change because it cause incorrect string sizes. --- .../AzCore/AzCore/Serialization/Json/BoolSerializer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp index 7ac16b214d..4d0a29df71 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp @@ -30,8 +30,8 @@ namespace AZ if (text && textLength > 0) { - static constexpr const char* trueString = "true"; - static constexpr const char* falseString = "false"; + static constexpr const char trueString[] = "true"; + static constexpr const char falseString[] = "false"; // remove null terminator for string length counts // rapidjson stringlength doesn't include it in length calculations, but sizeof() will static constexpr size_t trueStringLength = sizeof(trueString) - 1; From bc5fc9a1914d8f94a6503479c9caa376d79b92ee Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:07:41 -0700 Subject: [PATCH 06/93] Added missing reflection to NameJsonSerializerTests --- Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp index 4fa816cd4d..cb26937824 100644 --- a/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp @@ -32,6 +32,11 @@ namespace JsonSerializationTests AZ::NameDictionary::Destroy(); } + void Reflect(AZStd::unique_ptr& context) + { + AZ::Name::Reflect(context.get()); + } + void Reflect(AZStd::unique_ptr& context) { AZ::Name::Reflect(context.get()); From 08abc497f39a746c2812eff7a8173a4c0ce8ab63 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:55:24 -0700 Subject: [PATCH 07/93] Fixed initialization of math types for Json Serialization Several math types in AzCore deliberately don't initialize through a constructor. This set of changes make sure that they still get properly initialized in the Json Serialization instead having random values. --- .../AzCore/AzCore/Math/ColorSerializer.cpp | 23 ++++-- .../AzCore/AzCore/Math/ColorSerializer.h | 2 + .../AzCore/Math/MathMatrixSerializer.cpp | 71 ++++++++----------- .../AzCore/AzCore/Math/MathMatrixSerializer.h | 23 +++--- .../AzCore/Math/MathVectorSerializer.cpp | 43 ++++++++--- .../AzCore/AzCore/Math/MathVectorSerializer.h | 28 ++++---- .../AzCore/Math/TransformSerializer.cpp | 13 +++- .../AzCore/AzCore/Math/TransformSerializer.h | 2 + .../AzCore/AzCore/Math/UuidSerializer.cpp | 26 +++++-- .../AzCore/AzCore/Math/UuidSerializer.h | 2 + 10 files changed, 150 insertions(+), 83 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp index 3f7a3c3a5d..ffdd73ffd8 100644 --- a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp @@ -36,6 +36,12 @@ namespace AZ Color* color = reinterpret_cast(outputValue); AZ_Assert(color, "Output value for JsonColorSerializer can't be null."); + if (IsExplicitDefault(inputValue)) + { + *color = Color::CreateZero(); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Color value set to default of zero."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: @@ -43,10 +49,14 @@ namespace AZ case rapidjson::kObjectType: return LoadObject(*color, inputValue, context); - case rapidjson::kStringType: // fall through - case rapidjson::kNumberType: // fall through - case rapidjson::kNullType: // fall through - case rapidjson::kFalseType: // fall through + case rapidjson::kStringType: + [[fallthrough]]; + case rapidjson::kNumberType: + [[fallthrough]]; + case rapidjson::kNullType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; case rapidjson::kTrueType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Colors can only be read from arrays or objects."); @@ -91,6 +101,11 @@ namespace AZ } } + auto JsonColorSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + JsonSerializationResult::Result JsonColorSerializer::LoadObject(Color& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { diff --git a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h index b7b948a25a..cd16506b28 100644 --- a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h +++ b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h @@ -28,6 +28,8 @@ namespace AZ JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; + private: enum class LoadAlpha { diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp index 0b7e3300cf..3d6a378b13 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp @@ -263,7 +263,7 @@ namespace AZ::JsonMathMatrixSerializerInternal template JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, - const rapidjson::Value& inputValue, JsonDeserializerContext& context) + const rapidjson::Value& inputValue, JsonDeserializerContext& context, bool isExplicitDefault) { namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. @@ -279,6 +279,12 @@ namespace AZ::JsonMathMatrixSerializerInternal MatrixType* matrix = reinterpret_cast(outputValue); AZ_Assert(matrix, "Output value for JsonMatrix%zux%zuSerializer can't be null.", RowCount, ColumnCount); + if (isExplicitDefault) + { + *matrix = MatrixType::CreateIdentity(); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Matrix value set to identity matrix."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: @@ -381,6 +387,16 @@ namespace AZ::JsonMathMatrixSerializerInternal namespace AZ { + // BaseJsonMatrixSerializer + + AZ_CLASS_ALLOCATOR_IMPL(BaseJsonMatrixSerializer, SystemAllocator, 0); + + auto BaseJsonMatrixSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + + // Matrix3x3 AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x3Serializer, SystemAllocator, 0); @@ -389,10 +405,7 @@ namespace AZ const rapidjson::Value& inputValue, JsonDeserializerContext& context) { return JsonMathMatrixSerializerInternal::Load( - outputValue, - outputValueTypeId, - inputValue, - context); + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonMatrix3x3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -401,11 +414,7 @@ namespace AZ outputValue.SetObject(); return JsonMathMatrixSerializerInternal::StoreRotationAndScale( - outputValue, - inputValue, - defaultValue, - valueTypeId, - context); + outputValue, inputValue, defaultValue, valueTypeId, context); } @@ -417,10 +426,7 @@ namespace AZ const rapidjson::Value& inputValue, JsonDeserializerContext& context) { return JsonMathMatrixSerializerInternal::Load( - outputValue, - outputValueTypeId, - inputValue, - context); + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonMatrix3x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -428,19 +434,11 @@ namespace AZ { outputValue.SetObject(); - auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( - outputValue, - inputValue, - defaultValue, - valueTypeId, - context); + auto result = + JsonMathMatrixSerializerInternal::StoreRotationAndScale(outputValue, inputValue, defaultValue, valueTypeId, context); - auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation( - outputValue, - inputValue, - defaultValue, - valueTypeId, - context); + auto resultTranslation = + JsonMathMatrixSerializerInternal::StoreTranslation(outputValue, inputValue, defaultValue, valueTypeId, context); result.GetResultCode().Combine(resultTranslation); return result; @@ -454,10 +452,7 @@ namespace AZ const rapidjson::Value& inputValue, JsonDeserializerContext& context) { return JsonMathMatrixSerializerInternal::Load( - outputValue, - outputValueTypeId, - inputValue, - context); + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonMatrix4x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -465,19 +460,11 @@ namespace AZ { outputValue.SetObject(); - auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( - outputValue, - inputValue, - defaultValue, - valueTypeId, - context); + auto result = + JsonMathMatrixSerializerInternal::StoreRotationAndScale(outputValue, inputValue, defaultValue, valueTypeId, context); - auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation( - outputValue, - inputValue, - defaultValue, - valueTypeId, - context); + auto resultTranslation = + JsonMathMatrixSerializerInternal::StoreTranslation(outputValue, inputValue, defaultValue, valueTypeId, context); result.GetResultCode().Combine(resultTranslation); return result; diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h index 81c9635a79..773859a2c8 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h @@ -16,11 +16,18 @@ namespace AZ { - class JsonMatrix3x3Serializer - : public BaseJsonSerializer + class BaseJsonMatrixSerializer : public BaseJsonSerializer { public: - AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", BaseJsonSerializer); + AZ_RTTI(BaseJsonMatrixSerializer, "{18CA4637-C9B7-454B-9126-107E18A8C096}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + OperationFlags GetOperationsFlags() const override; + }; + + class JsonMatrix3x3Serializer : public BaseJsonMatrixSerializer + { + public: + AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", BaseJsonMatrixSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -28,11 +35,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonMatrix3x4Serializer - : public BaseJsonSerializer + class JsonMatrix3x4Serializer : public BaseJsonMatrixSerializer { public: - AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", BaseJsonSerializer); + AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", BaseJsonMatrixSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -40,11 +46,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonMatrix4x4Serializer - : public BaseJsonSerializer + class JsonMatrix4x4Serializer : public BaseJsonMatrixSerializer { public: - AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", BaseJsonSerializer); + AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", BaseJsonMatrixSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; diff --git a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp index aa9686f709..0c0bc04338 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp @@ -124,7 +124,7 @@ namespace AZ template JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, - JsonDeserializerContext& context) + JsonDeserializerContext& context, bool isExplicitDefault) { namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. @@ -138,6 +138,12 @@ namespace AZ VectorType* vector = reinterpret_cast(outputValue); AZ_Assert(vector, "Output value for JsonVector%iSerializer can't be null.", ElementCount); + if (isExplicitDefault) + { + *vector = VectorType::CreateZero(); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Math vector value set to default of zero."); + } + switch (inputValue.GetType()) { case rapidjson::kArrayType: @@ -145,10 +151,14 @@ namespace AZ case rapidjson::kObjectType: return LoadObject(*vector, inputValue, context); - case rapidjson::kStringType: // fall through - case rapidjson::kNumberType: // fall through - case rapidjson::kNullType: // fall through - case rapidjson::kFalseType: // fall through + case rapidjson::kStringType: + [[fallthrough]]; + case rapidjson::kNumberType: + [[fallthrough]]; + case rapidjson::kNullType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; case rapidjson::kTrueType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Math vectors can only be read from arrays or objects."); @@ -189,6 +199,16 @@ namespace AZ } } + + // BaseJsonVectorSerializer + + AZ_CLASS_ALLOCATOR_IMPL(BaseJsonVectorSerializer, SystemAllocator, 0); + + auto BaseJsonVectorSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + // Vector2 @@ -197,7 +217,8 @@ namespace AZ JsonSerializationResult::Result JsonVector2Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { - return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context); + return JsonMathVectorSerializerInternal::Load( + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonVector2Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -214,7 +235,8 @@ namespace AZ JsonSerializationResult::Result JsonVector3Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { - return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context); + return JsonMathVectorSerializerInternal::Load( + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonVector3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -231,7 +253,8 @@ namespace AZ JsonSerializationResult::Result JsonVector4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { - return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context); + return JsonMathVectorSerializerInternal::Load( + outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue)); } JsonSerializationResult::Result JsonVector4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, @@ -252,7 +275,7 @@ namespace AZ // check for "yaw, pitch, roll" object if (inputValue.IsObject()) { - if (inputValue.GetObject().ObjectEmpty()) + if (IsExplicitDefault(inputValue)) { Quaternion* outQuaternion = reinterpret_cast(outputValue); *outQuaternion = Quaternion::CreateIdentity(); @@ -283,7 +306,7 @@ namespace AZ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read quaternion."); } - return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context); + return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context, false); } JsonSerializationResult::Result JsonQuaternionSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, diff --git a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h index 9c2606b932..0f81709c17 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h +++ b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h @@ -16,11 +16,18 @@ namespace AZ { - class JsonVector2Serializer - : public BaseJsonSerializer + class BaseJsonVectorSerializer : public BaseJsonSerializer { public: - AZ_RTTI(JsonVector2Serializer, "{E1EAA209-9682-4120-B26B-3EDD9AD56D6F}", BaseJsonSerializer); + AZ_RTTI(BaseJsonVectorSerializer, "{C188D355-E6DF-4590-8B31-F40591F48A8E}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + OperationFlags GetOperationsFlags() const override; + }; + + class JsonVector2Serializer : public BaseJsonVectorSerializer + { + public: + AZ_RTTI(JsonVector2Serializer, "{E1EAA209-9682-4120-B26B-3EDD9AD56D6F}", BaseJsonVectorSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -28,11 +35,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonVector3Serializer - : public BaseJsonSerializer + class JsonVector3Serializer : public BaseJsonVectorSerializer { public: - AZ_RTTI(JsonVector3Serializer, "{BF82BBF3-3CD9-48DA-97CC-E4DF2EF01552}", BaseJsonSerializer); + AZ_RTTI(JsonVector3Serializer, "{BF82BBF3-3CD9-48DA-97CC-E4DF2EF01552}", BaseJsonVectorSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -40,11 +46,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonVector4Serializer - : public BaseJsonSerializer + class JsonVector4Serializer : public BaseJsonVectorSerializer { public: - AZ_RTTI(JsonVector4Serializer, "{05B45EA7-7102-4281-8AA0-2AC72D74AAFD}", BaseJsonSerializer); + AZ_RTTI(JsonVector4Serializer, "{05B45EA7-7102-4281-8AA0-2AC72D74AAFD}", BaseJsonVectorSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; @@ -52,11 +57,10 @@ namespace AZ const Uuid& valueTypeId, JsonSerializerContext& context) override; }; - class JsonQuaternionSerializer - : public BaseJsonSerializer + class JsonQuaternionSerializer : public BaseJsonVectorSerializer { public: - AZ_RTTI(JsonQuaternionSerializer, "{18604375-3606-49AC-B366-0F6DF9149FF3}", BaseJsonSerializer); + AZ_RTTI(JsonQuaternionSerializer, "{18604375-3606-49AC-B366-0F6DF9149FF3}", BaseJsonVectorSerializer); AZ_CLASS_ALLOCATOR_DECL; JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp index 36c40265af..49ba082618 100644 --- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp @@ -33,6 +33,12 @@ namespace AZ AZ::Transform* transformInstance = reinterpret_cast(outputValue); AZ_Assert(transformInstance, "Output value for JsonTransformSerializer can't be null."); + if (IsExplicitDefault(inputValue)) + { + *transformInstance = AZ::Transform::CreateIdentity(); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Transform value set to identity."); + } + JSR::ResultCode result(JSR::Tasks::ReadField); { @@ -72,7 +78,7 @@ namespace AZ return context.Report( result, - result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded Transform information." + result.GetProcessing() != JSR::Processing::Halted ? "Successfully loaded Transform information." : "Failed to load Transform information."); } @@ -140,4 +146,9 @@ namespace AZ : "Failed to store Transform information."); } + auto JsonTransformSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h index e03c41e31d..ef277f831a 100644 --- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h +++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h @@ -30,6 +30,8 @@ namespace AZ rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; + private: // Note: These need to be defined as "const char[]" instead of "const char*" so that they can be implicitly converted // to a rapidjson::GenericStringRef<>. (This also lets rapidjson get the string length at compile time) diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp index 9da7b11805..2c751e8a1c 100644 --- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp @@ -33,6 +33,11 @@ namespace AZ AZStd::regex_constants::icase | AZStd::regex_constants::optimize); } + auto JsonUuidSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::ManualDefault; + } + JsonSerializationResult::Result JsonUuidSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) { @@ -53,13 +58,24 @@ namespace AZ Uuid* valAsUuid = reinterpret_cast(outputValue); + if (IsExplicitDefault(inputValue)) + { + *valAsUuid = AZ::Uuid::CreateNull(); + return MessageResult("Uuid value set to default of null.", JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed)); + } + switch (inputValue.GetType()) { - case rapidjson::kArrayType: // fallthrough - case rapidjson::kObjectType:// fallthrough - case rapidjson::kFalseType: // fallthrough - case rapidjson::kTrueType: // fallthrough - case rapidjson::kNumberType:// fallthrough + case rapidjson::kArrayType: + [[fallthrough]]; + case rapidjson::kObjectType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; + case rapidjson::kTrueType: + [[fallthrough]]; + case rapidjson::kNumberType: + [[fallthrough]]; case rapidjson::kNullType: return MessageResult("Unsupported type. Uuids can only be read from strings.", JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported)); diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h index 1c350a2fcd..43487dcc10 100644 --- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h +++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h @@ -41,6 +41,8 @@ namespace AZ JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; + //! Does the same as load, but doesn't report through the provided callback in the settings. Instead the final //! ResultCode and message are returned and it's up to the caller to report if need needed. MessageResult UnreportedLoad(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue); From fcd989c295ab2191a87aac6a073c32a50a4fb696 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:00:01 -0700 Subject: [PATCH 08/93] Removed unit tests from bool, int and double Json Serialization A future commit will include a generic test conformity test suite to replace these. --- .../Json/BoolSerializerTests.cpp | 20 ------------- .../Json/DoubleSerializerTests.cpp | 30 +------------------ .../Serialization/Json/IntSerializerTests.cpp | 20 ------------- 3 files changed, 1 insertion(+), 69 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp index 6396e4ccdf..cd6fcef5c5 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp @@ -260,24 +260,4 @@ namespace JsonSerializationTests Load(m_jsonValue.SetDouble(-1.0f), true, AZ::JsonSerializationResult::Outcomes::Success); Load(m_jsonValue.SetDouble(2.0), true, AZ::JsonSerializationResult::Outcomes::Success); } - - TEST_F(JsonBoolSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized) - { - using namespace AZ::JsonSerializationResult; - - BoolPointerWrapper instance; - - this->m_jsonDocument->Parse(R"({ "Value": {}})"); - ASSERT_FALSE(this->m_jsonDocument->HasParseError()); - - AZ::JsonDeserializerSettings settings; - settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); - settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); - ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); - - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); - EXPECT_EQ(Processing::Completed, result.GetProcessing()); - ASSERT_NE(nullptr, instance.m_value); - EXPECT_FALSE(*instance.m_value); - } } // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp index 4279017276..1556318199 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp @@ -32,7 +32,7 @@ namespace JsonSerializationTests AZStd::shared_ptr CreateDefaultInstance() override { - return AZStd::make_shared(-2.0f); + return AZStd::make_shared(0.0f); } AZStd::shared_ptr CreateFullySetInstance() override @@ -296,32 +296,4 @@ namespace JsonSerializationTests EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); EXPECT_EQ(42.0f, value); } - - // Pointers - - TEST_F(JsonDoubleSerializerTests, Load_LoadDefaultToPointer_ValuesArIsInitialized) - { - using namespace AZ::JsonSerializationResult; - - DoublePointerWrapper instance; - - this->m_jsonDocument->Parse(R"( - { - "Double": {}, - "Float": {} - })"); - ASSERT_FALSE(this->m_jsonDocument->HasParseError()); - - AZ::JsonDeserializerSettings settings; - settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); - settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); - ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); - - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); - EXPECT_EQ(Processing::Completed, result.GetProcessing()); - ASSERT_NE(nullptr, instance.m_double); - ASSERT_NE(nullptr, instance.m_float); - EXPECT_DOUBLE_EQ(0.0, *instance.m_double); - EXPECT_FLOAT_EQ(0.0f, *instance.m_float); - } } // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp index c4132e983c..5f81dd1b9c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp @@ -505,26 +505,6 @@ namespace JsonSerializationTests EXPECT_EQ(typename SerializerInfo::DataType(), convertedValue); } - TYPED_TEST(TypedJsonIntSerializerTests, Load_LoadDefaultToPointer_ValueIsIsInitialized) - { - using namespace AZ::JsonSerializationResult; - - IntegerPointerWrapper instance; - - this->m_jsonDocument->Parse(R"({ "Value": {}})"); - ASSERT_FALSE(this->m_jsonDocument->HasParseError()); - - AZ::JsonDeserializerSettings settings; - settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); - settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); - ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); - - EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); - EXPECT_EQ(Processing::Completed, result.GetProcessing()); - ASSERT_NE(nullptr, instance.m_value); - EXPECT_EQ(0, *instance.m_value); - } - TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxInt8Value_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxShortValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } TYPED_TEST(TypedJsonIntSerializerTests, Load_MaxIntValue_ConvertIfFitsOrUnsupported) { this->template TestMaxValue(); } From f00fa26e1246eb2ac7e3ebcb7dec8b3657f4600c Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Tue, 15 Jun 2021 13:44:32 -0700 Subject: [PATCH 09/93] Separated initializing new and all objects in the Json Serialization Introduced OperationFlags::InitializeNewInstance to the Json Serialization which allows custom json serializers to indicate that they need to set defaults only to new instances. Objects created to fill in a pointer are considered new objects and serializer can use the new ContinuationFlags::LoadAsNewInstance to also inform that the load is happening on a new object. Serializer that use the InitializeNewInstance flag know that a new object is begin initialized if they're called with an explicit default object. --- .../AzCore/AzCore/Math/ColorSerializer.cpp | 2 +- .../AzCore/Math/MathMatrixSerializer.cpp | 2 +- .../AzCore/Math/MathVectorSerializer.cpp | 2 +- .../AzCore/Math/TransformSerializer.cpp | 2 +- .../AzCore/AzCore/Math/UuidSerializer.cpp | 2 +- .../Serialization/Json/BaseJsonSerializer.cpp | 3 ++- .../Serialization/Json/BaseJsonSerializer.h | 15 +++++++++----- .../Serialization/Json/BoolSerializer.cpp | 2 +- .../Serialization/Json/DoubleSerializer.cpp | 4 ++-- .../Serialization/Json/IntSerializer.cpp | 2 +- .../Serialization/Json/JsonDeserializer.cpp | 20 +++++++++++-------- .../Serialization/Json/JsonDeserializer.h | 5 +++-- .../Serialization/Json/JsonSerialization.cpp | 2 +- 13 files changed, 37 insertions(+), 26 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp index ffdd73ffd8..0d45a3fb6c 100644 --- a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp @@ -103,7 +103,7 @@ namespace AZ auto JsonColorSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } JsonSerializationResult::Result JsonColorSerializer::LoadObject(Color& output, const rapidjson::Value& inputValue, diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp index 3d6a378b13..7f412f68e6 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp @@ -393,7 +393,7 @@ namespace AZ auto BaseJsonMatrixSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } diff --git a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp index 0c0bc04338..7225f1713c 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp @@ -206,7 +206,7 @@ namespace AZ auto BaseJsonVectorSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp index 49ba082618..b3c9ea3b7c 100644 --- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp @@ -148,7 +148,7 @@ namespace AZ auto JsonTransformSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp index 2c751e8a1c..458744d5b2 100644 --- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp @@ -35,7 +35,7 @@ namespace AZ auto JsonUuidSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } JsonSerializationResult::Result JsonUuidSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 9a426a1e59..666fa0f96a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -216,9 +216,10 @@ namespace AZ JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading( void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags) { + bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance; return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer ? JsonDeserializer::LoadToPointer(object, typeId, value, context) - : JsonDeserializer::Load(object, typeId, value, context); + : JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, context); } JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring( diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index 06c5eda6de..99b63bf4de 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -163,15 +163,20 @@ namespace AZ enum class ContinuationFlags { - None = 0, //! No extra flags. - ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance. - ReplaceDefault = 1 << 1 //! The default value provided for storing will be replaced with a newly created one. + None = 0, //! No extra flags. + ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance. + ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one. + LoadAsNewInstance = 1 << 2 //! Treats the value as if it's a newly created instance. This may trigger serializers marked with + //! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to + //! an array. }; enum class OperationFlags { - None = 0, //! No flags that control how the custom json serializer is used. - ManualDefault = 1 << 0 //! Even if an (explicit) default is found the custom json serializer will still be called. + None = 0, //! No flags that control how the custom json serializer is used. + ManualDefault = 1 << 0, //! Even if an (explicit) default is found the custom json serializer will still be called. + InitializeNewInstance = 1 << 1 //! If set, the custom json serializer will be called with an explicit default if a new + //! instance of its target type is created. }; virtual ~BaseJsonSerializer() = default; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp index 4d0a29df71..defe470bcf 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp @@ -154,6 +154,6 @@ namespace AZ auto JsonBoolSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp index 647ff67eb6..14f2eaae6f 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp @@ -166,7 +166,7 @@ namespace AZ auto JsonDoubleSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } JsonSerializationResult::Result JsonFloatSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, @@ -191,6 +191,6 @@ namespace AZ auto JsonFloatSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp index 28da852da3..ebc99fd8c4 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp @@ -135,7 +135,7 @@ namespace AZ auto BaseJsonIntegerSerializer::GetOperationsFlags() const -> OperationFlags { - return OperationFlags::ManualDefault; + return OperationFlags::InitializeNewInstance; } JsonSerializationResult::Result JsonCharSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 9c4641741e..d948966b4b 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -24,20 +24,24 @@ namespace AZ { JsonSerializationResult::ResultCode JsonDeserializer::DeserializerDefaultCheck(BaseJsonSerializer* serializer, void* object, - const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context) + const Uuid& typeId,const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context) { using namespace AZ::JsonSerializationResult; bool isExplicitDefault = IsExplicitDefault(value); bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == BaseJsonSerializer::OperationFlags::ManualDefault; - return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) + bool initializeNewInstance = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) == + BaseJsonSerializer::OperationFlags::InitializeNewInstance; + + return + !isExplicitDefault || (isExplicitDefault && manuallyDefaults) || (isExplicitDefault && isNewInstance && initializeNewInstance) ? serializer->Load(object, typeId, value, context) : context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); } - JsonSerializationResult::ResultCode JsonDeserializer::Load(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context) + JsonSerializationResult::ResultCode JsonDeserializer::Load( + void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context) { using namespace AZ::JsonSerializationResult; @@ -50,7 +54,7 @@ namespace AZ BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { - return DeserializerDefaultCheck(serializer, object, typeId, value, context); + return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context); } const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId); @@ -72,7 +76,7 @@ namespace AZ serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()); if (serializer) { - return DeserializerDefaultCheck(serializer, object, typeId, value, context); + return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context); } } @@ -133,7 +137,7 @@ namespace AZ const SerializeContext::ClassData* resolvedClassData = context.GetSerializeContext()->FindClassData(resolvedTypeId); if (resolvedClassData) { - status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, context); + status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, context); *objectPtr = resolvedClassData->m_azRtti->Cast(*objectPtr, typeId); @@ -174,7 +178,7 @@ namespace AZ } else { - return Load(object, classElement.m_typeId, value, context); + return Load(object, classElement.m_typeId, value, false, context); } } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h index 5954082ee0..1d16b49e39 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h @@ -58,8 +58,8 @@ namespace AZ JsonDeserializer(const JsonDeserializer& rhs) = delete; JsonDeserializer(JsonDeserializer&& rhs) = delete; - static JsonSerializationResult::ResultCode Load(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context); + static JsonSerializationResult::ResultCode Load( + void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context); static JsonSerializationResult::ResultCode LoadToPointer(void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context); @@ -120,6 +120,7 @@ namespace AZ void* object, const Uuid& typeId, const rapidjson::Value& value, + bool isNewInstance, JsonDeserializerContext& context); }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp index 0629f1c32e..6fabf51237 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp @@ -249,7 +249,7 @@ namespace AZ { StackedString path(StackedString::Format::JsonPointer); JsonDeserializerContext context(settings); - result = JsonDeserializer::Load(object, objectType, root, context); + result = JsonDeserializer::Load(object, objectType, root, false, context); } return result; } From 780dd0df9fe70dbf9c5f3a29a68480fa708b4c5b Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Tue, 15 Jun 2021 13:52:16 -0700 Subject: [PATCH 10/93] Container fixes for the Json Serialization These changes fix the following: - Containers treat new values as new objects and make sure they're initialized. - Fixed sized containers behave slightly different and will initialize all values when a new fixed sized container is created. - Loading any values to a container will now return PartialDefaults instead of defaults used as adding any value to a container no longer makes the container a default as the default is always an empty container. - The previous doesn't apply to fixed sized containers as those containers are always considered to have the exact number of values they can hold. --- .../Serialization/Json/ArraySerializer.cpp | 65 +++++++--- .../Serialization/Json/ArraySerializer.h | 8 +- .../Json/BasicContainerSerializer.cpp | 21 +++- .../Serialization/Json/MapSerializer.cpp | 14 ++- .../Serialization/Json/TupleSerializer.cpp | 113 ++++++++++++------ .../Serialization/Json/TupleSerializer.h | 9 +- 6 files changed, 165 insertions(+), 65 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp index d5a1730364..2e53eb5697 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp @@ -32,13 +32,24 @@ namespace AZ switch (inputValue.GetType()) { case rapidjson::kArrayType: - return LoadContainer(outputValue, outputValueTypeId, inputValue, context); + return LoadContainer(outputValue, outputValueTypeId, inputValue, false, context); - case rapidjson::kObjectType: // fall through - case rapidjson::kNullType: // fall through - case rapidjson::kStringType: // fall through - case rapidjson::kFalseType: // fall through - case rapidjson::kTrueType: // fall through + case rapidjson::kObjectType: + if (IsExplicitDefault(inputValue)) + { + // Because this serializer has only the operation flag "InitializeNewInstance" set, the only time this will be called with + // an explicit default is when a new instance has been created. + return LoadContainer(outputValue, outputValueTypeId, inputValue, true, context); + } + [[fallthrough]]; + case rapidjson::kNullType: + [[fallthrough]]; + case rapidjson::kStringType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; + case rapidjson::kTrueType: + [[fallthrough]]; case rapidjson::kNumberType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. AZStd::array entries can only be read from an array."); @@ -129,7 +140,16 @@ namespace AZ } } - JsonSerializationResult::Result JsonArraySerializer::LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, + auto JsonArraySerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::InitializeNewInstance; + } + + JsonSerializationResult::Result JsonArraySerializer::LoadContainer( + void* outputValue, + const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, + bool isNewInstance, JsonDeserializerContext& context) { namespace JSR = JsonSerializationResult; // Used to remove name conflicts in AzCore in uber builds. @@ -154,14 +174,7 @@ namespace AZ "Unable to retrieve the correct container information for AZStd::array instance."); } - const size_t size = container->Size(outputValue); - if (inputValue.Size() < size) - { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, - "Not enough entries in JSON array to load an AZStd::array from."); - } - - ContinuationFlags flags = ContinuationFlags::None; + ContinuationFlags flags = isNewInstance ? ContinuationFlags::LoadAsNewInstance : ContinuationFlags::None; Uuid elementTypeId = Uuid::CreateNull(); auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement) { @@ -175,13 +188,23 @@ namespace AZ }; container->EnumTypes(typeEnumCallback); + const size_t size = container->Size(outputValue); + if (!isNewInstance && inputValue.Size() < size) + { + return context.Report( + JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Not enough entries in JSON array to load an AZStd::array from."); + } + + rapidjson::Value explicitDefaultValue = GetExplicitDefault(); + JSR::ResultCode retVal(JSR::Tasks::ReadField); for (size_t i = 0; i < size; ++i) { ScopedContextPath subPath(context, i); void* element = container->GetElementByIndex(outputValue, nullptr, i); - JSR::ResultCode result = ContinueLoading(element, elementTypeId, inputValue[aznumeric_caster(i)], context, flags); + JSR::ResultCode result = ContinueLoading( + element, elementTypeId, isNewInstance ? explicitDefaultValue : inputValue[aznumeric_caster(i)], context, flags); if (result.GetProcessing() == JSR::Processing::Halted) { return context.Report(result, "Failed to load data to element in AZStd::array."); @@ -189,15 +212,19 @@ namespace AZ retVal.Combine(result); } - if (container->Size(outputValue) == inputValue.Size()) + if (isNewInstance) + { + return context.Report(retVal, "Filled new instance of AZStd::array with defaults."); + } + else if (container->Size(outputValue) == inputValue.Size()) { return context.Report(retVal, "Successfully read entries into AZStd::array."); } else { retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Skipped)); - return context.Report(retVal, - "Successfully read available entries into AZStd::array, but there were still values left in the JSON array."); + return context.Report( + retVal, "Successfully read available entries into AZStd::array, but there were still values left in the JSON array."); } } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h index 11edc87139..a6d8dd37e3 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h @@ -30,8 +30,14 @@ namespace AZ JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; + protected: - JsonSerializationResult::Result LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, + JsonSerializationResult::Result LoadContainer( + void* outputValue, + const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, + bool isNewInstance, JsonDeserializerContext& context); }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index 8fe1f471c1..4eb4748eb5 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -34,11 +34,16 @@ namespace AZ case rapidjson::kArrayType: return LoadContainer(outputValue, outputValueTypeId, inputValue, context); - case rapidjson::kObjectType: // fall through - case rapidjson::kNullType: // fall through - case rapidjson::kStringType: // fall through - case rapidjson::kFalseType: // fall through - case rapidjson::kTrueType: // fall through + case rapidjson::kObjectType: + [[fallthrough]]; + case rapidjson::kNullType: + [[fallthrough]]; + case rapidjson::kStringType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; + case rapidjson::kTrueType: + [[fallthrough]]; case rapidjson::kNumberType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. Basic containers can only be read from an array."); @@ -169,6 +174,7 @@ namespace AZ ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? ContinuationFlags::ResolvePointer : ContinuationFlags::None; + flags |= ContinuationFlags::LoadAsNewInstance; const size_t capacity = container->IsFixedCapacity() ? container->Capacity(outputValue) : std::numeric_limits::max(); @@ -247,6 +253,11 @@ namespace AZ } size_t addedCount = container->Size(outputValue) - containerSize; + if (addedCount > 0) + { + // Values were added which means the container is no longer in its default state of being emtpy. + retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } AZStd::string_view message = addedCount >= arraySize ? "Successfully read basic container.": addedCount == 0 ? "Unable to read data for basic container." : diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp index 437a648e1e..4dc3c44834 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp @@ -190,6 +190,12 @@ namespace AZ } size_t addedCount = container->Size(outputValue) - containerSize; + if (addedCount > 0) + { + // If at least one entry was added then the map is no longer in it's default state so + // mark is with success so the result can at best be partial defaults. + retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } AZStd::string_view message = addedCount >= maximumSize ? "Successfully read associative container." : addedCount == 0 ? "Unable to read data for the associative container." : @@ -215,10 +221,10 @@ namespace AZ // Load key void* keyAddress = pairContainer->GetElementByIndex(address, pairElement, 0); AZ_Assert(keyAddress, "Element reserved for associative container, but unable to retrieve address of the key."); - ContinuationFlags keyLoadFlags = ContinuationFlags::None; + ContinuationFlags keyLoadFlags = ContinuationFlags::LoadAsNewInstance; if (keyElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - keyLoadFlags = ContinuationFlags::ResolvePointer; + keyLoadFlags |= ContinuationFlags::ResolvePointer; *reinterpret_cast(keyAddress) = nullptr; } JSR::ResultCode keyResult = ContinueLoading(keyAddress, keyElement->m_typeId, key, context, keyLoadFlags); @@ -231,10 +237,10 @@ namespace AZ // Load value void* valueAddress = pairContainer->GetElementByIndex(address, pairElement, 1); AZ_Assert(valueAddress, "Element reserved for associative container, but unable to retrieve address of the value."); - ContinuationFlags valueLoadFlags = ContinuationFlags::None; + ContinuationFlags valueLoadFlags = ContinuationFlags::LoadAsNewInstance; if (valueElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - valueLoadFlags = ContinuationFlags::ResolvePointer; + valueLoadFlags |= ContinuationFlags::ResolvePointer; *reinterpret_cast(valueAddress) = nullptr; } JSR::ResultCode valueResult = ContinueLoading(valueAddress, valueElement->m_typeId, value, context, valueLoadFlags); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp index 5b43cec817..fd8951517a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp @@ -34,13 +34,24 @@ namespace AZ switch (inputValue.GetType()) { case rapidjson::kArrayType: - return LoadContainer(outputValue, outputValueTypeId, inputValue, context); + return LoadContainer(outputValue, outputValueTypeId, inputValue, false, context); - case rapidjson::kObjectType: // fall through - case rapidjson::kNullType: // fall through - case rapidjson::kStringType: // fall through - case rapidjson::kFalseType: // fall through - case rapidjson::kTrueType: // fall through + case rapidjson::kObjectType: + if (IsExplicitDefault(inputValue)) + { + // Because this serializer has only the operation flag "InitializeNewInstance" set, the only time this will be called with + // an explicit default is when a new instance has been created. + return LoadContainer(outputValue, outputValueTypeId, inputValue, true, context); + } + [[fallthrough]]; + case rapidjson::kNullType: + [[fallthrough]]; + case rapidjson::kStringType: + [[fallthrough]]; + case rapidjson::kFalseType: + [[fallthrough]]; + case rapidjson::kTrueType: + [[fallthrough]]; case rapidjson::kNumberType: return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Unsupported type. AZStd::pair or AZStd::tuple can only be read from an array."); @@ -127,8 +138,13 @@ namespace AZ } } + auto JsonTupleSerializer::GetOperationsFlags() const -> OperationFlags + { + return OperationFlags::InitializeNewInstance; + } + JsonSerializationResult::Result JsonTupleSerializer::LoadContainer(void* outputValue, const Uuid& outputValueTypeId, - const rapidjson::Value& inputValue, JsonDeserializerContext& context) + const rapidjson::Value& inputValue, bool isNewInstance, JsonDeserializerContext& context) { namespace JSR = JsonSerializationResult; // Used to remove name conflicts in AzCore in uber builds. @@ -154,7 +170,7 @@ namespace AZ }; container->EnumTypes(typeCountCallback); - rapidjson::SizeType arraySize = inputValue.Size(); + rapidjson::SizeType arraySize = isNewInstance ? typeCount : inputValue.Size(); if (arraySize < typeCount) { return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, @@ -171,46 +187,73 @@ namespace AZ container->EnumTypes(typeEnumCallback); JSR::ResultCode retVal(JSR::Tasks::ReadField); - rapidjson::SizeType arrayIndex = 0; - size_t numElementsWritten = 0; - for (size_t i = 0; i < typeCount; ++i) + if (isNewInstance) { - ScopedContextPath subPath(context, i); - - void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i); - AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i); + rapidjson::Value explicitDefaultValue = GetExplicitDefault(); - ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER - ? ContinuationFlags::ResolvePointer - : ContinuationFlags::None; - - while (arrayIndex < inputValue.Size()) + for (size_t i = 0; i < typeCount; ++i) { - JSR::ResultCode result = ContinueLoading(elementAddress, classElements[i]->m_typeId, inputValue[arrayIndex], context, flags); + ScopedContextPath subPath(context, i); + + void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i); + AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i); + + ContinuationFlags flags = ContinuationFlags::LoadAsNewInstance; + flags |= + (classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None); + JSR::ResultCode result = ContinueLoading(elementAddress, classElements[i]->m_typeId, explicitDefaultValue, context, flags); retVal.Combine(result); - arrayIndex++; if (result.GetProcessing() == JSR::Processing::Halted) { return context.Report(retVal, "Failed to read element for AZStd::pair or AZStd::tuple."); } - else if (result.GetProcessing() != JSR::Processing::Altered) - { - numElementsWritten++; - break; - } } - } - if (numElementsWritten < typeCount) - { - AZStd::string_view message = numElementsWritten == 0 ? - "Unable to read data for AZStd::pair or AZStd::tuple." : - "Partially read data for AZStd::pair or AZStd::tuple."; - return context.Report(retVal, message); + return context.Report(retVal, "Initialized AZStd::pair or AZStd::tuple to defaults."); } else { - return context.Report(retVal, "Successfully read AZStd::pair or AZStd::tuple."); + rapidjson::SizeType arrayIndex = 0; + size_t numElementsWritten = 0; + for (size_t i = 0; i < typeCount; ++i) + { + ScopedContextPath subPath(context, i); + + void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i); + AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i); + + ContinuationFlags flags = + (classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None); + while (arrayIndex < inputValue.Size()) + { + JSR::ResultCode result = + ContinueLoading(elementAddress, classElements[i]->m_typeId, inputValue[arrayIndex], context, flags); + retVal.Combine(result); + arrayIndex++; + if (result.GetProcessing() == JSR::Processing::Halted) + { + return context.Report(retVal, "Failed to read element for AZStd::pair or AZStd::tuple."); + } + else if (result.GetProcessing() != JSR::Processing::Altered) + { + numElementsWritten++; + break; + } + } + } + + if (numElementsWritten < typeCount) + { + AZStd::string_view message = numElementsWritten == 0 ? "Unable to read data for AZStd::pair or AZStd::tuple." + : "Partially read data for AZStd::pair or AZStd::tuple."; + return context.Report(retVal, message); + } + else + { + return context.Report(retVal, "Successfully read AZStd::pair or AZStd::tuple."); + } } } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h index a105272811..70a506eb81 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h @@ -23,13 +23,20 @@ namespace AZ public: AZ_RTTI(JsonTupleSerializer, "{1AA0ADC1-395A-4223-8A73-304ACDEE7793}", BaseJsonSerializer); AZ_CLASS_ALLOCATOR_DECL; + JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, JsonDeserializerContext& context) override; JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + OperationFlags GetOperationsFlags() const override; + private: - JsonSerializationResult::Result LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue, + JsonSerializationResult::Result LoadContainer( + void* outputValue, + const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, + bool isNewInstance, JsonDeserializerContext& context); }; } // namespace AZ From 8af45d28be8c817a2733b71db38c28cd01b87749 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Tue, 15 Jun 2021 14:02:54 -0700 Subject: [PATCH 11/93] Additional unit tests for the Json Serialization To cover the recent changes to the return code from containers and the initialization fixes additional unit tests were added. Almost all new tests are part of the conformity test suite so that they test any custom json serializers outside of AzCore that might need to be updated due to the fixes. --- .../AzCore/Tests/AssetJsonSerializerTests.cpp | 4 + .../Json/ArraySerializerTests.cpp | 63 ++--- .../Json/BasicContainerSerializerTests.cpp | 19 ++ .../Json/JsonSerializerConformityTests.h | 217 +++++++++++++++++- .../Serialization/Json/MapSerializerTests.cpp | 126 +++++++++- .../Json/TupleSerializerTests.cpp | 13 +- .../Json/UnorderedSetSerializerTests.cpp | 10 + 7 files changed, 384 insertions(+), 68 deletions(-) diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index 3e4ddac3af..ceff314c81 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -168,6 +168,10 @@ namespace JsonSerializationTests { features.EnableJsonType(rapidjson::kObjectType); features.m_typeToInject = rapidjson::kNullType; + // The type information in the Serialize Context is incomplete so this test will fail. + // This is because assets have traditionally been treated as a special case, so there's + // information missing in the Json Serialization to deal with these. + features.m_enableNewInstanceTests = false; } bool AreEqual(const Asset& lhs, const Asset& rhs) override diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp index da66bdd0b5..1f39feccbd 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp @@ -126,9 +126,9 @@ namespace JsonSerializationTests { auto array = AZStd::shared_ptr(new Array(), Deleter); (*array)[0] = nullptr; - (*array)[1] = aznew MultipleInheritence(); + (*array)[1] = nullptr; (*array)[2] = nullptr; - (*array)[3] = aznew MultipleInheritence(); + (*array)[3] = nullptr; return array; } @@ -154,6 +154,7 @@ namespace JsonSerializationTests null, null, { + "$type": "MultipleInheritence", "base_var": 242.0, "var1" : 142 } @@ -246,56 +247,21 @@ namespace JsonSerializationTests ])"; } - AZStd::string_view GetJsonFor_Store_SerializeFullySetInstance() override - { - // This is a unique situation because the $type is determined separate from other values, so all - // member values can be changed, but since the default type matches the stored type the $type - // will only be written if default values are explicitly kept. - return R"( - [ - { - "$type": "MultipleInheritence", - "base_var": 1142.0, - "base2_var1": 1242.0, - "base2_var2": 1342.0, - "base2_var3": 1442.0, - "var1" : 1542, - "var2" : 1642.0 - }, - { - "base_var": 2142.0, - "base2_var1": 2242.0, - "base2_var2": 2342.0, - "base2_var3": 2442.0, - "var1" : 2542, - "var2" : 2642.0 - }, - { - "$type": "MultipleInheritence", - "base_var": 3142.0, - "base2_var1": 3242.0, - "base2_var2": 3342.0, - "base2_var3": 3442.0, - "var1" : 3542, - "var2" : 3642.0 - }, - { - "base_var": 4142.0, - "base2_var1": 4242.0, - "base2_var2": 4342.0, - "base2_var3": 4442.0, - "var1" : 4542, - "var2" : 4642.0 - } - ])"; - } - void Reflect(AZStd::unique_ptr& context) override { Base::Reflect(context); MultipleInheritence::Reflect(context, true); } + void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override + { + Base::ConfigureFeatures(features); + // These tests don't work with pointers because there'll be a random value in the pointer + // which the Json Serialization try to delete. The POD version of these tests already cover + // these cases. + features.m_enableNewInstanceTests = false; + } + bool AreEqual(const Array& lhs, const Array& rhs) override { size_t size = lhs.size(); @@ -311,6 +277,11 @@ namespace JsonSerializationTests return rhs[i] == nullptr; } + if (rhs[i] == nullptr) + { + return false; + } + if (!static_cast(lhs[i])->Equals(*static_cast(rhs[i]), true)) { return false; diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp index b3c900c710..508658e2a5 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp @@ -54,6 +54,11 @@ namespace JsonSerializationTests return AZStd::make_shared(Container{ 188, 288, 388 }); } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + return AZStd::make_shared(Container{ 0 }); + } + AZStd::string_view GetJsonForFullySetInstance() override { return "[188, 288, 388]"; @@ -120,6 +125,13 @@ namespace JsonSerializationTests &SimplePointerTestDescription::Delete); } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + int* value = reinterpret_cast(azmalloc(sizeof(int), alignof(int))); + *value = 0; + return AZStd::shared_ptr(new Container{ value }, &SimplePointerTestDescription::Delete); + } + AZStd::string_view GetJsonForFullySetInstance() override { return "[188, 288, 388]"; @@ -180,6 +192,13 @@ namespace JsonSerializationTests return instance; } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + auto instance = AZStd::make_shared(); + *instance = { SimpleClass{} }; + return instance; + } + AZStd::string_view GetJsonForFullySetInstance() override { return R"([ diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index c0f470378c..f45e0a3658 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -62,6 +62,14 @@ namespace JsonSerializationTests //! can be used to manually create these documents. If that is also not an option the tests can be //! disabled by setting this flag to false. bool m_supportsInjection{ true }; + //! Enables the check that tries to determine if variables are initialized and if not whether they have the + //! OperationFlags::ManualDefault set. This applies for instance to integers, which won't be initialized if + //! constructed a new instance is created for pointers. + bool m_enableInitializationTest{ true }; + //! Enable the test that creates a new instance of the provided test type through the factory that's found in + //! the Serialize Context. This test is automatically disabled for classes that don't have a factory or + //! have a null factory. + bool m_enableNewInstanceTests{ true }; private: // There's no way to retrieve the number of types from RapidJSON so they're hard-coded here. @@ -87,6 +95,7 @@ namespace JsonSerializationTests { public: using Type = T; + virtual ~JsonSerializerConformityTestDescriptor() = default; virtual AZStd::shared_ptr CreateSerializer() = 0; @@ -104,13 +113,21 @@ namespace JsonSerializationTests virtual AZStd::shared_ptr CreatePartialDefaultInstance() { return nullptr; } //! Create an instance where all values are set to non-default values. virtual AZStd::shared_ptr CreateFullySetInstance() = 0; + //! Create an instance of the target array type with a single value that has all defaults. + //! If the target type doesn't support arrays or requires more than one entry this can be ignored and + //! tests using this value will be skipped. + virtual AZStd::shared_ptr CreateSingleArrayDefaultInstance() { return nullptr; } //! Get the json that represents the default instance. //! If the target type doesn't support partial specialization this can be ignored and //! tests for partial support will be skipped. - virtual AZStd::string_view GetJsonForPartialDefaultInstance() { return ""; } + virtual AZStd::string_view GetJsonForPartialDefaultInstance() { return ""; } //! Get the json that represents the instance with all values set. virtual AZStd::string_view GetJsonForFullySetInstance() = 0; + //! Get the json that represents an array with a single value that has only defaults. + //! If the target type doesn't support arrays or requires more than one entry this can be ignored and + //! tests using this value will be skipped. + virtual AZStd::string_view GetJsonForSingleArrayDefaultInstance() { return "[{}]"; } //! Get the json where additional values are added to the json file. //! If this function is not overloaded, but features.m_supportsInjection is enabled then //! the Json Serializer Conformity Tests will inject extra values in the json for a fully. @@ -138,12 +155,15 @@ namespace JsonSerializationTests virtual AZStd::string_view GetJsonFor_Load_DeserializeUnreflectedType() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Load_DeserializeFullySetInstance() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Load_DeserializePartialInstance() { return this->GetJsonForPartialDefaultInstance(); } + virtual AZStd::string_view GetJsonFor_Load_DeserializeArrayWithDefaultValue() { return this->GetJsonForSingleArrayDefaultInstance(); } + virtual AZStd::string_view GetJsonFor_Load_DeserializeFullInstanceOnTopOfPartialDefaulted() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Load_HaltedThroughCallback() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Store_SerializeWithDefaultsKept() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Store_SerializeFullySetInstance() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Store_SerializeWithoutDefault() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Store_SerializeWithoutDefaultAndDefaultsKept() { return this->GetJsonForFullySetInstance(); } virtual AZStd::string_view GetJsonFor_Store_SerializePartialInstance() { return this->GetJsonForPartialDefaultInstance(); } + virtual AZStd::string_view GetJsonFor_Store_SerializeArrayWithSingleDefaultValue() { return this->GetJsonForSingleArrayDefaultInstance(); } }; template @@ -154,6 +174,21 @@ namespace JsonSerializationTests using Description = T; using Type = typename T::Type; + struct PointerWrapper + { + AZ_TYPE_INFO(PointerWrapper, "{32FA6645-074A-458A-B79C-B173D0BD4B42}"); + AZ_CLASS_ALLOCATOR(PointerWrapper, AZ::SystemAllocator, 0); + + Type* m_value{ nullptr }; + + ~PointerWrapper() + { + // Using free because not all types can safely use delete. Since this just to clear the memory to satisfy the memory + // leak test, this is fine. + azfree(m_value); + } + }; + void SetUp() override { using namespace AZ::JsonSerializationResult; @@ -165,6 +200,7 @@ namespace JsonSerializationTests descriptor->ConfigureFeatures(this->m_features); descriptor->Reflect(this->m_serializeContext); descriptor->Reflect(this->m_jsonRegistrationContext); + this->m_serializeContext->Class()->Field("Value", &PointerWrapper::m_value); this->m_deserializationSettings->m_reporting = &Internal::VerifyCallback; this->m_serializationSettings->m_reporting = &Internal::VerifyCallback; @@ -185,6 +221,7 @@ namespace JsonSerializationTests this->m_jsonRegistrationContext->DisableRemoveReflection(); this->m_serializeContext->EnableRemoveReflection(); + this->m_serializeContext->Class()->Field("Value", &PointerWrapper::m_value); descriptor->Reflect(this->m_serializeContext); this->m_serializeContext->DisableRemoveReflection(); @@ -487,6 +524,41 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeArrayWithDefaultValue_SucceedsAndReportPartialDefaults) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.SupportsJsonType(rapidjson::kArrayType)) + { + this->m_jsonDocument->Parse(this->m_description.GetJsonFor_Load_DeserializeArrayWithDefaultValue().data()); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateDefaultInstance(); + + this->m_jsonDeserializationContext->PushPath(DefaultPath); + + ResultCode result = + serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); + + if (this->m_features.m_fixedSizeArray) + { + EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); + EXPECT_EQ(Processing::Altered, result.GetProcessing()); + } + else + { + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + + auto compare = this->m_description.CreateSingleArrayDefaultInstance(); + ASSERT_NE(nullptr, compare) + << "Conformity tests for variably sized arrays require an implementation of CreateSingleArrayDefaultInstance"; + EXPECT_TRUE(this->m_description.AreEqual(*compare, *instance)); + } + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Load_InterruptClearingTarget_ContainerIsNotCleared) { using namespace AZ::JsonSerializationResult; @@ -548,7 +620,6 @@ namespace JsonSerializationTests this->m_jsonDocument->Parse(json.data()); ASSERT_FALSE(this->m_jsonDocument->HasParseError()); - auto serializer = this->m_description.CreateSerializer(); auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreateFullySetInstance(); @@ -622,6 +693,94 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeFullInstanceOnTopOfPartialDefaulted_SucceedsAndObjectMatchesParialInstance) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.m_supportsPartialInitialization) + { + AZStd::string_view json = this->m_description.GetJsonFor_Load_DeserializeFullInstanceOnTopOfPartialDefaulted(); + // If tests for partial initialization are enabled than json for the partial initialization is needed. + ASSERT_FALSE(json.empty()); + this->m_jsonDocument->Parse(json.data()); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreatePartialDefaultInstance(); + auto compare = this->m_description.CreateFullySetInstance(); + ASSERT_NE(nullptr, compare); + + // Clear containers which should effectively turn them into default containers. + this->m_deserializationSettings->m_clearContainers = true; + this->ResetJsonContexts(); + this->m_jsonDeserializationContext->PushPath(DefaultPath); + + ResultCode result = + serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); + + EXPECT_EQ(Outcomes::Success, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare)); + } + } + + TYPED_TEST_P(JsonSerializerConformityTests, Load_DefaultToPointer_SucceedsAndValueIsInitialized) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.m_enableNewInstanceTests) + { + AZ::SerializeContext* serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid()); + ASSERT_NE(nullptr, classData); + // Skip this test if the target type doesn't have a factor to create a new instance with or if the factor explicit + // prohibits construction. + if (classData->m_factory && classData->m_factory != AZ::Internal::NullFactory::GetInstance()) + { + PointerWrapper instance; + auto compare = this->m_description.CreateDefaultInstance(); + + this->m_jsonDocument->Parse(R"({ "Value": {}})"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = serializeContext; + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings); + + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + ASSERT_NE(nullptr, instance.m_value); + EXPECT_TRUE(this->m_description.AreEqual(*instance.m_value, *compare)); + } + } + } + + TYPED_TEST_P(JsonSerializerConformityTests, Load_InitializeNewInstance_SucceedsAndValueIsInitialized) + { + using namespace AZ; + using namespace AZ::JsonSerializationResult; + + if (this->m_features.m_enableNewInstanceTests) + { + auto serializer = this->m_description.CreateSerializer(); + if ((serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) == + BaseJsonSerializer::OperationFlags::InitializeNewInstance) + { + Type instance; + auto compare = this->m_description.CreateDefaultInstance(); + this->m_jsonDocument->SetObject(); + + ResultCode result = + serializer->Load(&instance, azrtti_typeid(instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); + + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_TRUE(this->m_description.AreEqual(instance, *compare)); + } + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Load_HaltedThroughCallback_LoadFailsAndHaltReported) { using namespace AZ::JsonSerializationResult; @@ -909,6 +1068,28 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeArrayWithSingleDefaultValue_StoredSuccessfullyAndJsonMatches) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.SupportsJsonType(rapidjson::kArrayType) && !this->m_features.m_fixedSizeArray) + { + this->m_jsonSerializationContext->PushPath(DefaultPath); + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateSingleArrayDefaultInstance(); + ASSERT_NE(nullptr, instance) + << "Conformity tests for variably sized arrays require an implementation of CreateSingleArrayDefaultInstance"; + + ResultCode result = serializer->Store( + *this->m_jsonDocument, instance.get(), instance.get(), azrtti_typeid(*instance), *this->m_jsonSerializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); + this->Expect_DocStrEq(this->m_description.GetJsonFor_Store_SerializeArrayWithSingleDefaultValue()); + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Store_HaltedThroughCallback_StoreFailsAndHaltReported) { using namespace AZ::JsonSerializationResult; @@ -1017,7 +1198,29 @@ namespace JsonSerializationTests } } - TYPED_TEST_P(JsonSerializerConformityTests, GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared) + TYPED_TEST_P(JsonSerializerConformityTests, GetOperationFlags_RequiresExplicitInit_ObjectsThatDoNotConstructHaveExplicitInitOption) + { + using namespace AZ; + using namespace AZ::JsonSerializationResult; + + if (this->m_features.m_enableInitializationTest) + { + auto instance = this->m_description.CreateDefaultInstance(); + Type compare; + if (!this->m_description.AreEqual(*instance, compare)) + { + auto serializer = this->m_description.CreateSerializer(); + BaseJsonSerializer::OperationFlags flags = serializer->GetOperationsFlags(); + bool hasManualDefaultSet = + (flags & BaseJsonSerializer::OperationFlags::ManualDefault) == BaseJsonSerializer::OperationFlags::ManualDefault || + (flags & BaseJsonSerializer::OperationFlags::InitializeNewInstance) == + BaseJsonSerializer::OperationFlags::InitializeNewInstance; + EXPECT_TRUE(hasManualDefaultSet); + } + } + } + + TYPED_TEST_P(JsonSerializerConformityTests, GetOperationFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared) { if (this->m_features.SupportsJsonType(rapidjson::kObjectType)) { @@ -1048,10 +1251,14 @@ namespace JsonSerializationTests Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearEnabled_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearedTarget_SucceedsAndObjectMatchesDefaults, + Load_DeserializeArrayWithDefaultValue_SucceedsAndReportPartialDefaults, Load_InterruptClearingTarget_ContainerIsNotCleared, Load_DeserializeFullySetInstance_SucceedsAndObjectMatchesFullySetInstance, Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance, Load_DeserializePartialInstance_SucceedsAndObjectMatchesParialInstance, + Load_DeserializeFullInstanceOnTopOfPartialDefaulted_SucceedsAndObjectMatchesParialInstance, + Load_DefaultToPointer_SucceedsAndValueIsInitialized, + Load_InitializeNewInstance_SucceedsAndValueIsInitialized, Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported, Load_InsertAdditionalData_SucceedsAndObjectMatchesFullySetInstance, Load_HaltedThroughCallback_LoadFailsAndHaltReported, @@ -1066,13 +1273,15 @@ namespace JsonSerializationTests Store_SerializeWithoutDefaultAndDefaultsKept_StoredSuccessfullyAndJsonMatches, Store_SerializePartialInstance_StoredSuccessfullyAndJsonMatches, Store_SerializeEmptyArray_StoredSuccessfullyAndJsonMatches, + Store_SerializeArrayWithSingleDefaultValue_StoredSuccessfullyAndJsonMatches, Store_HaltedThroughCallback_StoreFailsAndHaltReported, StoreLoad_RoundTripWithPartialDefault_IdenticalInstances, StoreLoad_RoundTripWithFullSet_IdenticalInstances, StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances, - GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared); + GetOperationFlags_RequiresExplicitInit_ObjectsThatDoNotConstructHaveExplicitInitOption, + GetOperationFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared); } // namespace JsonSerializationTests namespace AZ diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp index 363cd7a7b7..7ec5ca3b9a 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp @@ -35,6 +35,11 @@ namespace JsonSerializationTests return AZStd::make_shared(); } + AZStd::string_view GetJsonForSingleArrayDefaultInstance() override + { + return R"({ "{}": {} })"; + } + void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override { features.EnableJsonType(rapidjson::kArrayType); @@ -61,6 +66,13 @@ namespace JsonSerializationTests public: using Map = T; + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + auto instance = AZStd::make_shared(); + instance->emplace(AZStd::make_pair(0, 0.0)); + return instance; + } + AZStd::shared_ptr CreateFullySetInstance() override { auto instance = AZStd::make_shared(); @@ -100,6 +112,13 @@ namespace JsonSerializationTests public: using Map = T; + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + auto instance = AZStd::make_shared(); + instance->emplace(AZStd::make_pair(AZStd::string(), 0.0)); + return instance; + } + AZStd::shared_ptr CreateFullySetInstance() override { auto instance = AZStd::make_shared(); @@ -163,6 +182,14 @@ namespace JsonSerializationTests return instance; } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + auto instance = AZStd::shared_ptr(new Map{}, &Delete); + instance->emplace(AZStd::make_pair(aznew SimpleClass(), aznew SimpleClass())); + return instance; + } + + AZStd::string_view GetJsonForPartialDefaultInstance() override { if constexpr (IsMultiMap) @@ -237,13 +264,23 @@ namespace JsonSerializationTests return false; } - auto compare = [](typename Map::const_reference lhs, typename Map::const_reference rhs) -> bool + // Naive compare to avoid having to split up the test because comparing for ordered and unordered maps would need to be + // different. + for (auto&& [key, value] : lhs) { - return - lhs.first->Equals(*rhs.first, true) && - lhs.second->Equals(*rhs.second, true); - }; - return AZStd::equal(lhs.begin(), lhs.end(), rhs.begin(), compare); + for (auto&& [keyCompare, valueCompare] : rhs) + { + if (key->Equals(*keyCompare, true)) + { + if (!value->Equals(*valueCompare, true)) + { + return false; + } + break; + } + } + } + return true; } }; @@ -393,6 +430,29 @@ namespace JsonSerializationTests { using namespace AZ::JsonSerializationResult; + m_jsonDocument->Parse(R"( + { + "{}": {} + })"); + ASSERT_FALSE(m_jsonDocument->HasParseError()); + + TestStringMap values; + ResultCode result = m_unorderedMapSerializer.Load(&values, azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); + + EXPECT_EQ(1, values.size()); + + auto defaultKey = values.find(TestString()); + EXPECT_NE(values.end(), defaultKey); + EXPECT_STRCASEEQ(TestString().m_value.c_str(), defaultKey->second.m_value.c_str()); + } + + TEST_F(JsonMapSerializerTests, Load_DefaultForStringKeyAndAdditionalValue_LoadedBackWithDefaults) + { + using namespace AZ::JsonSerializationResult; + m_jsonDocument->Parse(R"( { "{}": {}, @@ -563,13 +623,13 @@ namespace JsonSerializationTests EXPECT_EQ(Outcomes::Catastrophic, result.GetOutcome()); } - TEST_F(JsonMapSerializerTests, Load_DefaultValueInMultiMap_DefaultUsed) + TEST_F(JsonMapSerializerTests, Load_DefaultObjectInMultiMap_DefaultUsed) { using namespace AZ::JsonSerializationResult; m_jsonDocument->Parse(R"( { - "Hello": {} + "World": {} })"); ASSERT_FALSE(m_jsonDocument->HasParseError()); @@ -581,17 +641,40 @@ namespace JsonSerializationTests EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); ASSERT_FALSE(values.empty()); - EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str()); + EXPECT_STREQ("World", values.begin()->first.m_value.c_str()); EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str()); } - TEST_F(JsonMapSerializerTests, Load_DefaultArrayValueInMultiMap_DefaultUsed) + TEST_F(JsonMapSerializerTests, Load_FullDefaultObjectInMultiMap_DefaultUsed) { using namespace AZ::JsonSerializationResult; m_jsonDocument->Parse(R"( { - "Hello": [{}] + "{}": {} + })"); + ASSERT_FALSE(m_jsonDocument->HasParseError()); + + TestStringMultiMap values; + ResultCode result = + m_unorderedMultiMapSerializer.Load(&values, azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); + + ASSERT_FALSE(values.empty()); + EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str()); + EXPECT_STREQ("Hello", values.begin()->second.m_value.c_str()); + EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str()); + } + + TEST_F(JsonMapSerializerTests, Load_DefaultObjectValueInMultiMap_DefaultUsed) + { + using namespace AZ::JsonSerializationResult; + + m_jsonDocument->Parse(R"( + { + "World": [{}] })"); ASSERT_FALSE(m_jsonDocument->HasParseError()); @@ -603,7 +686,8 @@ namespace JsonSerializationTests EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); ASSERT_FALSE(values.empty()); - EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str()); + EXPECT_STREQ("World", values.begin()->first.m_value.c_str()); + EXPECT_STREQ("Hello", values.begin()->second.m_value.c_str()); EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str()); } @@ -661,6 +745,24 @@ namespace JsonSerializationTests })"); } + TEST_F(JsonMapSerializerTests, Store_SingleAllDefaulValue_InitializedWithDefaults) + { + using namespace AZ::JsonSerializationResult; + + SimpleClassMap values; + values.emplace(SimpleClass(), SimpleClass()); + + ResultCode result = + m_unorderedMapSerializer.Store(*m_jsonDocument, &values, nullptr, azrtti_typeid(&values), *m_jsonSerializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome()); + Expect_DocStrEq(R"( + { + "{}": {} + })"); + } + TEST_F(JsonMapSerializerTests, Store_DefaultsWithObjectKey_InitializedWithDefaults) { using namespace AZ::JsonSerializationResult; diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TupleSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TupleSerializerTests.cpp index eceaaae5f1..77a88fda6c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TupleSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TupleSerializerTests.cpp @@ -48,12 +48,12 @@ namespace JsonSerializationTests AZStd::shared_ptr CreateDefaultInstance() override { - return AZStd::make_shared(142, 242.0); + return AZStd::make_shared(0, 0.0); } AZStd::shared_ptr CreatePartialDefaultInstance() override { - return AZStd::make_shared(142, 288.0); + return AZStd::make_shared(0, 288.0); } AZStd::shared_ptr CreateFullySetInstance() override @@ -102,12 +102,12 @@ namespace JsonSerializationTests AZStd::shared_ptr CreateDefaultInstance() override { - return AZStd::make_shared(142, 242.0, 342.0f); + return AZStd::make_shared(0, 0.0, 0.0f); } AZStd::shared_ptr CreatePartialDefaultInstance() override { - return AZStd::make_shared(142, 288.0, 342.0f); + return AZStd::make_shared(0, 288.0, 0.0f); } AZStd::shared_ptr CreateFullySetInstance() override @@ -345,6 +345,7 @@ namespace JsonSerializationTests { TupleSerializerTestsInternal::ConfigureFeatures(features); features.m_supportsPartialInitialization = true; + features.m_enableNewInstanceTests = false; } void Reflect(AZStd::unique_ptr& context) override @@ -447,14 +448,14 @@ namespace JsonSerializationTests { return AZStd::make_shared( AZStd::vector(), - AZStd::make_pair(442, "")); + AZStd::make_pair(0, "")); } AZStd::shared_ptr CreatePartialDefaultInstance() override { return AZStd::make_shared( AZStd::vector(), - AZStd::make_pair(442, "hello")); + AZStd::make_pair(0, "hello")); } AZStd::shared_ptr CreateFullySetInstance() override diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/UnorderedSetSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/UnorderedSetSerializerTests.cpp index 6e9cd0f3d6..fb7b683d2e 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/UnorderedSetSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/UnorderedSetSerializerTests.cpp @@ -36,6 +36,11 @@ namespace JsonSerializationTests return AZStd::make_shared(); } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + return AZStd::make_shared(Set{ 0 }); + } + AZStd::shared_ptr CreateFullySetInstance() override { return AZStd::make_shared(Set{42, -88, 342}); @@ -80,6 +85,11 @@ namespace JsonSerializationTests return AZStd::make_shared(); } + AZStd::shared_ptr CreateSingleArrayDefaultInstance() override + { + return AZStd::make_shared(MultiSet{ 0 }); + } + AZStd::shared_ptr CreateFullySetInstance() override { return AZStd::make_shared(MultiSet{ 42, -88, 42, 342 }); From 98ff91d854e48aedefd52fcf0162ce9bd173249b Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Tue, 15 Jun 2021 16:12:36 -0700 Subject: [PATCH 12/93] Removed unused test structure. --- .../Serialization/Json/IntSerializerTests.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp index 5f81dd1b9c..db764badcb 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/IntSerializerTests.cpp @@ -147,18 +147,6 @@ namespace JsonSerializationTests : public BaseJsonSerializerFixture { public: - struct IntegerPointerWrapper - { - AZ_TYPE_INFO(IntegerPointerWrapper, "{F6B3BEF1-59A4-4E45-BF02-DDA868C38A28}"); - - typename SerializerInfo::DataType* m_value{ nullptr }; - - ~IntegerPointerWrapper() - { - azfree(m_value); - } - }; - AZStd::unique_ptr m_serializer; void SetUp() override @@ -173,12 +161,6 @@ namespace JsonSerializationTests BaseJsonSerializerFixture::TearDown(); } - void RegisterAdditional(AZStd::unique_ptr& serializeContext) override - { - serializeContext->Class() - ->Field("Value", &IntegerPointerWrapper::m_value); - } - template::value, int> = 0> void SetValue(rapidjson::Value& out, T in) { From 9fe06453d316087af863ef2993fd70feecdea46c Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Thu, 3 Jun 2021 17:42:24 -0700 Subject: [PATCH 13/93] Initial commit to use qt.conf for all builds --- cmake/LYWrappers.cmake | 9 +- cmake/Platform/Android/PAL_android.cmake | 1 + cmake/Platform/Linux/PAL_linux.cmake | 1 + cmake/Platform/Linux/QtDeploy_linux.cmake | 73 +++++++ cmake/Platform/Linux/Qt_qmake_linux.cmake.in | 38 ++++ cmake/Platform/Mac/PAL_mac.cmake | 1 + cmake/Platform/Mac/QtDeploy_mac.cmake | 70 ++++++ cmake/Platform/Windows/PAL_windows.cmake | 1 + cmake/Platform/Windows/QtDeploy_windows.cmake | 50 +++++ cmake/Platform/iOS/PAL_ios.cmake | 1 + cmake/Qt.cmake | 199 ++++++++++++++++++ 11 files changed, 439 insertions(+), 5 deletions(-) create mode 100644 cmake/Platform/Linux/QtDeploy_linux.cmake create mode 100644 cmake/Platform/Linux/Qt_qmake_linux.cmake.in create mode 100644 cmake/Platform/Mac/QtDeploy_mac.cmake create mode 100644 cmake/Platform/Windows/QtDeploy_windows.cmake create mode 100644 cmake/Qt.cmake diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake index d7f88f12ec..6587fed1a3 100644 --- a/cmake/LYWrappers.cmake +++ b/cmake/LYWrappers.cmake @@ -13,6 +13,9 @@ set(LY_UNITY_BUILD OFF CACHE BOOL "UNITY builds") include(CMakeFindDependencyMacro) include(cmake/LyAutoGen.cmake) +if(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED) + include(cmake/Qt.cmake) +endif() ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) include(${pal_dir}/LYWrappers_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) @@ -334,11 +337,7 @@ function(ly_add_target) detect_qt_dependency(${ly_add_target_NAME} QT_DEPENDENCY) if(QT_DEPENDENCY) - if(NOT COMMAND ly_qt_deploy) - message(FATAL_ERROR "Could not find function \"ly_qt_deploy\", this function should be defined in cmake/3rdParty/Platform/${PAL_PLATFORM_NAME}/Qt_${PAL_PLATFORM_NAME_LOWERCASE}.cmake") - endif() - - ly_qt_deploy(TARGET ${ly_add_target_NAME}) + ly_qt_deploy_qtconf(${ly_add_target_NAME}) endif() endif() diff --git a/cmake/Platform/Android/PAL_android.cmake b/cmake/Platform/Android/PAL_android.cmake index dd61e35e53..b68e922aad 100644 --- a/cmake/Platform/Android/PAL_android.cmake +++ b/cmake/Platform/Android/PAL_android.cmake @@ -12,6 +12,7 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG) set(PAL_LINKOPTION_MODULE MODULE) +ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) diff --git a/cmake/Platform/Linux/PAL_linux.cmake b/cmake/Platform/Linux/PAL_linux.cmake index c15f2bada9..d3e4aba1f8 100644 --- a/cmake/Platform/Linux/PAL_linux.cmake +++ b/cmake/Platform/Linux/PAL_linux.cmake @@ -12,6 +12,7 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG) ly_set(PAL_LINKOPTION_MODULE MODULE) +ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED TRUE) diff --git a/cmake/Platform/Linux/QtDeploy_linux.cmake b/cmake/Platform/Linux/QtDeploy_linux.cmake new file mode 100644 index 0000000000..26f56644a3 --- /dev/null +++ b/cmake/Platform/Linux/QtDeploy_linux.cmake @@ -0,0 +1,73 @@ +# +# 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. +# + +# Clear the cache for found executable +unset(WINDEPLOYQT_EXECUTABLE CACHE) +find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_PATH}/bin") +mark_as_advanced(WINDEPLOYQT_EXECUTABLE) # Hiding from GUI + +function(ly_qt_deploy) + + set(options) + set(oneValueArgs TARGET) + set(multiValueArgs) + + cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Validate input arguments + if(NOT ly_qt_deploy_TARGET) + message(FATAL_ERROR "You must provide a target to detect qt dependencies") + endif() + + # When winqtdeploy is used on a unix platform it copies over the hardcoded platform abstraction plugin + # of qxcb plugin. The qxcb plugin requires an X server to be running on linux and order to load properly + # To avoid the issue of requiring an X server to be running in a headless setup, the qminimal + # platform plugin is also copied over to the target file output directory. + set(plugin_path "${QT_PATH}/plugins") + set(platform_plugins ${plugin_path}/platforms/libqminimal.so) + set(xcbglintegrations_plugins ${plugin_path}/xcbglintegrations/libqxcb-glx-integration.so) + + add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DLY_TIMESTAMP_REFERENCE=$ + -DLY_LOCK_FILE=$/qtdeploy.lock + -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake + EXEC_COMMAND "${CMAKE_COMMAND}" -E + env PATH=${CMAKE_BINARY_DIR}:${QT_PATH}/bin:$ENV{PATH} + "${CMAKE_COMMAND}" -P "${LY_ROOT_FOLDER}/cmake/Platform/Linux/windeployqt_wrapper.cmake" + "$" + "${WINDEPLOYQT_EXECUTABLE}" + --verbose 2 + --no-compiler-runtime + --dir "$" + "$" + EXEC_COMMAND ${CMAKE_COMMAND} -E make_directory + "$/platforms" + EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${platform_plugins} + "$/platforms" + EXEC_COMMAND ${CMAKE_COMMAND} -E make_directory + "$/xcbglintegrations" + EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${xcbglintegrations_plugins} + "$/xcbglintegrations" + DEPENDS $ + COMMENT "Deploying qt..." + VERBATIM + ) + +endfunction() + +# windeployqt uses qmake -query to introspect a given Qt installation. However, +# qmake is not relocatable, so the paths reported are those from the build +# machine, and not from wherever the user has their 3rdParty libraries. So we +# create a fake qmake executable to report the right paths to windeployqt. +configure_file(${CMAKE_CURRENT_LIST_DIR}/Qt_qmake_${PAL_PLATFORM_NAME_LOWERCASE}.cmake.in ${CMAKE_BINARY_DIR}/qmake) diff --git a/cmake/Platform/Linux/Qt_qmake_linux.cmake.in b/cmake/Platform/Linux/Qt_qmake_linux.cmake.in new file mode 100644 index 0000000000..a02b1aa397 --- /dev/null +++ b/cmake/Platform/Linux/Qt_qmake_linux.cmake.in @@ -0,0 +1,38 @@ +#!${CMAKE_COMMAND} -P + +# +# 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. +# + + +execute_process(COMMAND ${CMAKE_COMMAND} -E echo "QT_SYSROOT: +QT_INSTALL_PREFIX:${QT_PATH} +QT_INSTALL_ARCHDATA:${QT_PATH} +QT_INSTALL_DATA:${QT_PATH} +QT_INSTALL_DOCS:${QT_PATH}/doc +QT_INSTALL_HEADERS:${QT_PATH}/include +QT_INSTALL_LIBS:${QT_PATH}/lib +QT_INSTALL_LIBEXECS:${QT_PATH}/libexec +QT_INSTALL_BINS:${QT_PATH}/bin +QT_INSTALL_TESTS:${QT_PATH}/tests +QT_INSTALL_PLUGINS:${QT_PATH}/plugins +QT_INSTALL_IMPORTS:${QT_PATH}/imports +QT_INSTALL_TRANSLATIONS:${QT_PATH}/translations +QT_INSTALL_CONFIGURATION:${QT_PATH}/etc/xdg +QT_INSTALL_EXAMPLES:${QT_PATH}/examples +QT_INSTALL_DEMOS:${QT_PATH}/examples +QT_HOST_PREFIX:${QT_PATH} +QT_HOST_DATA:${QT_PATH} +QT_HOST_BINS:${QT_PATH}/bin +QT_HOST_LIBS:${QT_PATH}/lib +QMAKE_SPEC:linux-g++ +QMAKE_XSPEC:linux-g++ +QMAKE_VERSION:3.1 +QT_VERSION:${QT_PACKAGE_VERSION}") diff --git a/cmake/Platform/Mac/PAL_mac.cmake b/cmake/Platform/Mac/PAL_mac.cmake index f49578a83a..477c8d4afb 100644 --- a/cmake/Platform/Mac/PAL_mac.cmake +++ b/cmake/Platform/Mac/PAL_mac.cmake @@ -12,6 +12,7 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG MACOSX_BUNDLE) ly_set(PAL_LINKOPTION_MODULE MODULE) +ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) diff --git a/cmake/Platform/Mac/QtDeploy_mac.cmake b/cmake/Platform/Mac/QtDeploy_mac.cmake new file mode 100644 index 0000000000..7ab5f61f5d --- /dev/null +++ b/cmake/Platform/Mac/QtDeploy_mac.cmake @@ -0,0 +1,70 @@ +# +# 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. +# + +# Clear the cache for found executable +unset(MACDEPLOYQT_EXECUTABLE CACHE) +find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT_PATH}/bin") +mark_as_advanced(MACDEPLOYQT_EXECUTABLE) # Hiding from GUI + +function(ly_qt_deploy) + + set(options) + set(oneValueArgs TARGET) + set(multiValueArgs) + + cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Validate input arguments + if(NOT ly_qt_deploy_TARGET) + message(FATAL_ERROR "You must provide a target to detect qt dependencies") + endif() + + #get_target_property(is_bundle ${ly_qt_deploy_TARGET} MACOSX_BUNDLE) + if (is_bundle) + add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DLY_TIMESTAMP_REFERENCE=$ + -DLY_LOCK_FILE=$/qtdeploy.lock + -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake + EXEC_COMMAND "${CMAKE_COMMAND}" -E time + ${MACDEPLOYQT_EXECUTABLE} + $ + -always-overwrite + -no-strip + -verbose=0 + -fs=APFS + DEPENDS $ + COMMENT "Deploying qt to the ${ly_qt_deploy_TARGET} bundle ..." + VERBATIM + ) + else() + set(qt_conf_config "[Paths]\nPlugins=@plugin_path@") + set(plugin_path "${QT_PATH}/plugins") + string(CONFIGURE "${qt_conf_config}" qt_conf_output @ONLY) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "${qt_conf_output}") + + # output the qt_conf file using "echo" and file redirection + add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DLY_TIMESTAMP_REFERENCE=$ + -DLY_LOCK_FILE=$/qtdeploy.lock + -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake + EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_BINARY_DIR}/qt.conf + $/qt.conf + COMMENT "copying over qt.conf..." + VERBATIM + ) + endif() + +endfunction() + + diff --git a/cmake/Platform/Windows/PAL_windows.cmake b/cmake/Platform/Windows/PAL_windows.cmake index fbf65db63f..fcbd8acb70 100644 --- a/cmake/Platform/Windows/PAL_windows.cmake +++ b/cmake/Platform/Windows/PAL_windows.cmake @@ -12,6 +12,7 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG WIN32) ly_set(PAL_LINKOPTION_MODULE MODULE) +ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_TESTS_SUPPORTED TRUE) diff --git a/cmake/Platform/Windows/QtDeploy_windows.cmake b/cmake/Platform/Windows/QtDeploy_windows.cmake new file mode 100644 index 0000000000..2fb1a71114 --- /dev/null +++ b/cmake/Platform/Windows/QtDeploy_windows.cmake @@ -0,0 +1,50 @@ +# +# 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. +# + +# Clear the cache for found executable +unset(WINDEPLOYQT_EXECUTABLE CACHE) +find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_PATH}/bin") +mark_as_advanced(WINDEPLOYQT_EXECUTABLE) # Hiding from GUI + +function(ly_qt_deploy) + + set(options) + set(oneValueArgs TARGET) + set(multiValueArgs) + + cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Validate input arguments + if(NOT ly_qt_deploy_TARGET) + message(FATAL_ERROR "You must provide a target to detect qt dependencies") + endif() + + # CMake has an issue with POST_BUILD commands in msbuild when it is executed from outside VS: + # https://gitlab.kitware.com/cmake/cmake/issues/18530 + + add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -DLY_TIMESTAMP_REFERENCE=$ + -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 + $ + DEPENDS $ $ + COMMENT "Deploying qt..." + VERBATIM + ) + +endfunction() \ No newline at end of file diff --git a/cmake/Platform/iOS/PAL_ios.cmake b/cmake/Platform/iOS/PAL_ios.cmake index 981bb9cab1..e9e38ac494 100644 --- a/cmake/Platform/iOS/PAL_ios.cmake +++ b/cmake/Platform/iOS/PAL_ios.cmake @@ -12,6 +12,7 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG MACOSX_BUNDLE) ly_set(PAL_LINKOPTION_MODULE SHARED) # For iOS, 'MODULE' creates a tool/bundle, but we treat it as a shared library +ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) diff --git a/cmake/Qt.cmake b/cmake/Qt.cmake new file mode 100644 index 0000000000..bf4ecb0f28 --- /dev/null +++ b/cmake/Qt.cmake @@ -0,0 +1,199 @@ +# +# 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_guard() + +ly_download_associated_package(Qt) +find_package(Qt REQUIRED MODULE) + +# UIC executable +unset(QT_UIC_EXECUTABLE CACHE) +find_program(QT_UIC_EXECUTABLE uic HINTS "${QT_PATH}/bin") +mark_as_advanced(QT_UIC_EXECUTABLE) # Hiding from GUI + +# RCC executable +unset(AUTORCC_EXECUTABLE CACHE) +find_program(AUTORCC_EXECUTABLE rcc HINTS "${QT_PATH}/bin") +mark_as_advanced(AUTORCC_EXECUTABLE) # Hiding from GUI +set(Qt5Core_RCC_EXECUTABLE "${AUTORCC_EXECUTABLE}" CACHE FILEPATH "Qt's resource compiler, used by qt5_add_resources" FORCE) +mark_as_advanced(Qt5Core_RCC_EXECUTABLE) # Hiding from GUI + +# LRELEASE executable +unset(QT_LRELEASE_EXECUTABLE CACHE) +find_program(QT_LRELEASE_EXECUTABLE lrelease HINTS "${QT_PATH}/bin") +mark_as_advanced(QT_LRELEASE_EXECUTABLE) # Hiding from GUI +if(NOT QT_LRELEASE_EXECUTABLE) + message(FATAL_ERROR "Qt's lrelease executbale not found") +endif() +set(Qt5_LRELEASE_EXECUTABLE "${QT_LRELEASE_EXECUTABLE}" CACHE FILEPATH "Qt's lrelease executable, used by qt5_add_translation" FORCE) +mark_as_advanced(Qt5_LRELEASE_EXECUTABLE) # Hiding from GUI + +#! ly_qt_uic_target: handles qt's ui files by injecting uic generation +# +# AUTOUIC has issues to detect changes in UIC files and trigger regeneration: +# https://gitlab.kitware.com/cmake/cmake/-/issues/18741 +# So instead, we are going to manually wrap the files. We dont use qt5_wrap_ui because +# it outputs to ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h and we want to follow the +# same folder structure that AUTOUIC uses +# +function(ly_qt_uic_target TARGET) + + get_target_property(all_ui_sources ${TARGET} SOURCES) + list(FILTER all_ui_sources INCLUDE REGEX "^.*\\.ui$") + if(NOT all_ui_sources) + message(FATAL_ERROR "Target ${TARGET} contains AUTOUIC but doesnt have any .ui file") + endif() + + if(AUTOGEN_BUILD_DIR) + set(gen_dir ${AUTOGEN_BUILD_DIR}) + else() + set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_autogen/include) + endif() + + foreach(ui_source ${all_ui_sources}) + + get_filename_component(filename ${ui_source} NAME_WE) + get_filename_component(dir ${ui_source} DIRECTORY) + if(IS_ABSOLUTE ${dir}) + file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir}) + endif() + + set(outfolder ${gen_dir}/${dir}) + set(outfile ${outfolder}/ui_${filename}.h) + get_filename_component(infile ${ui_source} ABSOLUTE) + + file(MAKE_DIRECTORY ${outfolder}) + add_custom_command(OUTPUT ${outfile} + COMMAND ${QT_UIC_EXECUTABLE} -o ${outfile} ${infile} + MAIN_DEPENDENCY ${infile} VERBATIM + COMMENT "UIC ${infile}" + ) + + set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC TRUE) + set_source_files_properties(${outfile} PROPERTIES + SKIP_AUTOMOC TRUE + SKIP_AUTOUIC TRUE + GENERATED TRUE + ) + list(APPEND all_ui_wrapped_sources ${outfile}) + + endforeach() + + # Add files to the target + target_sources(${TARGET} PRIVATE ${all_ui_wrapped_sources}) + source_group("Generated Files" FILES ${all_ui_wrapped_sources}) + + # Add include directories relative to the generated folder + # query for the property first to avoid the "NOTFOUND" in a list + get_property(has_includes TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES SET) + if(has_includes) + get_property(all_include_directories TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES) + foreach(dir ${all_include_directories}) + if(IS_ABSOLUTE ${dir}) + file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir}) + endif() + list(APPEND new_includes ${gen_dir}/${dir}) + endforeach() + endif() + list(APPEND new_includes ${gen_dir}) + target_include_directories(${TARGET} PRIVATE ${new_includes}) + +endfunction() + +#! ly_add_translations: adds translations (ts) to a target. +# +# This wrapper will generate a qrc file with those translations and add the files under "prefix" and add them to +# the indicated targets. These files will be added under the "Generated Files" filter +# +# \arg:TARGETS name of the targets that the translations will be added to +# \arg:PREFIX prefix where the translation will be located within the qrc file +# \arg:FILES translation files to add +# +function(ly_add_translations) + + set(options) + set(oneValueArgs PREFIX) + set(multiValueArgs TARGETS FILES) + + cmake_parse_arguments(ly_add_translations "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Validate input arguments + if(NOT ly_add_translations_TARGETS) + message(FATAL_ERROR "You must provide at least one target") + endif() + if(NOT ly_add_translations_FILES) + message(FATAL_ERROR "You must provide at least a translation file") + endif() + + qt5_add_translation(TRANSLATED_FILES ${ly_add_translations_FILES}) + + set(qrc_file_contents +" + +") + foreach(file ${TRANSLATED_FILES}) + get_filename_component(filename ${file} NAME) + string(APPEND qrc_file_contents " ${filename} +") + endforeach() + string(APPEND qrc_file_contents " + +") + set(qrc_file_path ${CMAKE_CURRENT_BINARY_DIR}/i18n_${ly_add_translations_PREFIX}.qrc) + file(WRITE + ${qrc_file_path} + ${qrc_file_contents} + ) + set_source_files_properties( + ${TRANSLATED_FILES} + ${qrc_file_path} + PROPERTIES + GENERATED TRUE + SKIP_AUTORCC TRUE + ) + qt5_add_resources(RESOURCE_FILE ${qrc_file_path}) + + foreach(target ${ly_add_translations_TARGETS}) + target_sources(${target} PRIVATE "${TRANSLATED_FILES};${qrc_file_path};${RESOURCE_FILE}") + endforeach() + +endfunction() + + +#! ly_qt_deploy_qtconf: deploys the qt.conf file for TARGET +# +# Instead of running a qt deploy on regular builds, we are using the qt.conf method: +# https://doc.qt.io/qt-5/qt-conf.html +# With such method we can use Qt from the 3rdParty package folder without requiring to +# copy the dlls/plugins to the output. +# +# A full deploy will be done on cmake install +# +# \arg:TARGET target that defines where to deploy to. This also adds a custom POST_BUILD +# command to TARGET to copy the file. +# +function(ly_qt_deploy_qtconf TARGET) + + add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND "${CMAKE_COMMAND}" + -E copy_if_different + ${CMAKE_BINARY_DIR}/qt.conf + $/qt.conf + COMMENT "Copying over qt.conf..." + VERBATIM + ) + +endfunction() + +# Generate the file once so we copy it per target +file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=${QT_PATH}/plugins") + +include(${LY_ROOT_FOLDER}/cmake/Platform/${PAL_PLATFORM_NAME}/QtDeploy_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) From 47c3c3a5d04af5130bf0b7bdb5dd374782089235 Mon Sep 17 00:00:00 2001 From: pappeste Date: Wed, 9 Jun 2021 17:50:17 -0700 Subject: [PATCH 14/93] Solution that wraps qt deploy with cmake --- .../Platform/Windows/lrelease_windows.cmake | 16 -- Gems/QtForPython/Code/CMakeLists.txt | 3 +- cmake/CommandExecution.cmake | 5 + cmake/LYWrappers.cmake | 63 ------ cmake/Platform/Android/PAL_android.cmake | 1 - cmake/Platform/Common/Install_common.cmake | 23 +- .../Common/RuntimeDependencies_common.cmake | 38 +++- cmake/Platform/Linux/PAL_linux.cmake | 1 - cmake/Platform/Linux/QtDeploy_linux.cmake | 73 ------- cmake/Platform/Linux/Qt_qmake_linux.cmake.in | 38 ---- .../Platform/Linux/platform_linux_files.cmake | 1 - .../Platform/Linux/windeployqt_wrapper.cmake | 121 ----------- cmake/Platform/Mac/PAL_mac.cmake | 1 - cmake/Platform/Mac/QtDeploy_mac.cmake | 70 ------ cmake/Platform/Windows/PAL_windows.cmake | 1 - cmake/Platform/Windows/QtDeploy_windows.cmake | 50 ----- cmake/Qt.cmake | 199 ------------------ 17 files changed, 35 insertions(+), 669 deletions(-) delete mode 100644 cmake/Platform/Linux/QtDeploy_linux.cmake delete mode 100644 cmake/Platform/Linux/Qt_qmake_linux.cmake.in delete mode 100644 cmake/Platform/Linux/windeployqt_wrapper.cmake delete mode 100644 cmake/Platform/Mac/QtDeploy_mac.cmake delete mode 100644 cmake/Platform/Windows/QtDeploy_windows.cmake delete mode 100644 cmake/Qt.cmake 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/QtForPython/Code/CMakeLists.txt b/Gems/QtForPython/Code/CMakeLists.txt index c11d93634e..e7b4723dfb 100644 --- a/Gems/QtForPython/Code/CMakeLists.txt +++ b/Gems/QtForPython/Code/CMakeLists.txt @@ -23,7 +23,6 @@ endif() ly_add_target( NAME QtForPython.Editor.Static STATIC NAMESPACE Gem - find_package(Qt) FILES_CMAKE qtforpython_editor_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake PLATFORM_INCLUDE_FILES @@ -41,7 +40,7 @@ ly_add_target( Gem::EditorPythonBindings.Static RUNTIME_DEPENDENCIES 3rdParty::pyside2 - Qt5::Test + 3rdParty::Qt::Test ) ly_add_target( diff --git a/cmake/CommandExecution.cmake b/cmake/CommandExecution.cmake index b37664c048..a10e30eb26 100644 --- a/cmake/CommandExecution.cmake +++ b/cmake/CommandExecution.cmake @@ -87,4 +87,9 @@ endif() if(LY_TIMESTAMP_REFERENCE) # Touch the timestamp file file(TOUCH ${LY_TIMESTAMP_FILE}) +endif() + +if(LY_LOCK_FILE) + file(LOCK ${LY_LOCK_FILE} RELEASE) + file(REMOVE ${LY_LOCK_FILE}) endif() \ No newline at end of file diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake index 6587fed1a3..81c36a9c56 100644 --- a/cmake/LYWrappers.cmake +++ b/cmake/LYWrappers.cmake @@ -13,9 +13,6 @@ set(LY_UNITY_BUILD OFF CACHE BOOL "UNITY builds") include(CMakeFindDependencyMacro) include(cmake/LyAutoGen.cmake) -if(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED) - include(cmake/Qt.cmake) -endif() ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}) include(${pal_dir}/LYWrappers_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) @@ -292,8 +289,6 @@ function(ly_add_target) foreach(prop IN ITEMS AUTOMOC AUTORCC) if(${ly_add_target_${prop}}) set_property(TARGET ${ly_add_target_NAME} PROPERTY ${prop} ON) - # Flag this target as depending on Qt - set_property(GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${ly_add_target_NAME} ON) endif() endforeach() if(${ly_add_target_AUTOUIC}) @@ -335,10 +330,6 @@ function(ly_add_target) VERBATIM ) - detect_qt_dependency(${ly_add_target_NAME} QT_DEPENDENCY) - if(QT_DEPENDENCY) - ly_qt_deploy_qtconf(${ly_add_target_NAME}) - endif() endif() if(ly_add_target_AUTOGEN_RULES) @@ -429,60 +420,6 @@ function(ly_delayed_target_link_libraries) endfunction() -#! detect_qt_dependency: Determine if a target will link directly to a Qt library -# -# qt deployment introspects a shared library or executable for its direct -# dependencies on Qt libraries. In CMake, this will be true if a target, or any -# of its link libraries which are static libraries, recursively, links to Qt. -function(detect_qt_dependency TARGET_NAME OUTPUT_VARIABLE) - - if(TARGET ${TARGET_NAME}) - get_target_property(alias ${TARGET_NAME} ALIASED_TARGET) - if(alias) - set(TARGET_NAME ${alias}) - endif() - endif() - - get_property(cached_is_qt_dependency GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${TARGET_NAME}) - if(cached_is_qt_dependency) - set(${OUTPUT_VARIABLE} ${cached_is_qt_dependency} PARENT_SCOPE) - return() - endif() - - if(${TARGET_NAME} MATCHES "^3rdParty::Qt::.*") - set_property(GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${TARGET_NAME} ON) - set(${OUTPUT_VARIABLE} ON PARENT_SCOPE) - return() - endif() - - get_property(delayed_link GLOBAL PROPERTY LY_DELAYED_LINK_${TARGET_NAME}) - set(exclude_library_types SHARED_LIBRARY MODULE_LIBRARY) - foreach(library IN LISTS delayed_link) - - if(TARGET ${library}) - get_target_property(child_target_type ${library} TYPE) - - # If the dependency to Qt has to go through a shared/module library, - # it is not a direct dependency - if (child_target_type IN_LIST exclude_library_types) - continue() - endif() - endif() - - detect_qt_dependency(${library} child_depends_on_qt) - if(child_depends_on_qt) - set_property(GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${TARGET_NAME} ON) - set(${OUTPUT_VARIABLE} ON PARENT_SCOPE) - return() - endif() - - endforeach() - - set_property(GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${TARGET_NAME} OFF) - set(${OUTPUT_VARIABLE} OFF PARENT_SCOPE) - -endfunction() - #! ly_parse_third_party_dependencies: Validates any 3rdParty library dependencies through the find_package command # # \arg:ly_THIRD_PARTY_LIBRARIES name of the target libraries to validate existance of through the find_package command. diff --git a/cmake/Platform/Android/PAL_android.cmake b/cmake/Platform/Android/PAL_android.cmake index b68e922aad..dd61e35e53 100644 --- a/cmake/Platform/Android/PAL_android.cmake +++ b/cmake/Platform/Android/PAL_android.cmake @@ -12,7 +12,6 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG) set(PAL_LINKOPTION_MODULE MODULE) -ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 933d64149b..2842b1448d 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -389,16 +389,7 @@ function(ly_setup_runtime_dependencies) # Common functions used by the bellow code install(CODE -"function(ly_deploy_qt_install target_output) - execute_process(COMMAND \"${WINDEPLOYQT_EXECUTABLE}\" --verbose 0 --no-compiler-runtime \"\${target_output}\" ERROR_VARIABLE deploy_error RESULT_VARIABLE deploy_result) - if (NOT \${deploy_result} EQUAL 0) - if(NOT deploy_error MATCHES \"does not seem to be a Qt executable\" ) - message(SEND_ERROR \"Deploying qt for \${target_output} returned \${deploy_result}: \${deploy_error}\") - endif() - endif() -endfunction() - -function(ly_copy source_file target_directory) +"function(ly_copy source_file target_directory) file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) endfunction()" ) @@ -419,18 +410,6 @@ endfunction()" file(RELATIVE_PATH target_runtime_output_subdirectory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${target_runtime_output_directory}) endif() - # Qt - get_property(has_qt_dependency GLOBAL PROPERTY LY_DETECT_QT_DEPENDENCY_${target}) - if(has_qt_dependency) - # Qt deploy needs to be done after the binary is copied to the output, so we do a install(CODE) which effectively - # puts it as a postbuild step of the "install" target. Binaries are copied at that point. - if(NOT EXISTS ${WINDEPLOYQT_EXECUTABLE}) - message(FATAL_ERROR "Qt deploy executable not found: ${WINDEPLOYQT_EXECUTABLE}") - endif() - set(target_output "${install_output_folder}/${target_runtime_output_subdirectory}/$") - list(APPEND runtime_commands "ly_deploy_qt_install(\"${target_output}\")\n") - endif() - # runtime dependencies that need to be copied to the output set(target_file_dir "${install_output_folder}/${target_runtime_output_subdirectory}") ly_get_runtime_dependencies(runtime_dependencies ${target}) diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index 4ae914744f..57484da9eb 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -35,6 +35,8 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) return() # Nothing to do endif() + ly_de_alias_target(${ly_TARGET} ly_TARGET) + # To optimize the search, we are going to cache the dependencies for the targets we already walked through. # To do so, we will create a variable named LY_RUNTIME_DEPENDENCIES_${ly_TARGET} which will contain a list # of all the dependencies @@ -96,15 +98,7 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) # Add the imported locations get_target_property(is_imported ${ly_TARGET} IMPORTED) if(is_imported) - # Skip Qt if this is a 3rdParty - # Qt is deployed using qt_deploy, no need to copy the dependencies set(skip_imported FALSE) - string(REGEX MATCH "3rdParty::([^:,]*)" target_package ${ly_TARGET}) - if(target_package) - if(${CMAKE_MATCH_1} STREQUAL "Qt") - set(skip_imported TRUE) - endif() - endif() if(target_type MATCHES "(STATIC_LIBRARY)") # No need to copy these dependencies since the outputs are not used at runtime set(skip_imported TRUE) @@ -118,12 +112,34 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) else() set(imported_property IMPORTED_LOCATION) endif() - get_target_property(target_locations ${ly_TARGET} ${imported_property}) + set(target_locations) + get_target_property(current_target_locations ${ly_TARGET} ${imported_property}) + if(current_target_locations) + string(APPEND target_locations ${current_target_locations}) + else() + # Check if the property exists for configurations + foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${conf} UCONF) + unset(current_target_locations) + get_target_property(current_target_locations ${ly_TARGET} ${imported_property}_${UCONF}) + if(current_target_locations) + string(APPEND target_locations $<$:${current_target_locations}>) + else() + # try to use the mapping + get_target_property(mapped_conf ${ly_TARGET} MAP_IMPORTED_CONFIG_${UCONF}) + if(mapped_conf) + get_target_property(current_target_locations ${ly_TARGET} ${imported_property}_${mapped_conf}) + if(current_target_locations) + string(APPEND target_locations $<$:${current_target_locations}>) + endif() + endif() + endif() + endforeach() + endif() if(target_locations) list(APPEND all_runtime_dependencies ${target_locations}) endif() - endif() endif() @@ -238,6 +254,8 @@ function(ly_copy source_file target_directory) if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") file(LOCK \"\${target_directory}/\${target_filename}.lock\" GUARD FUNCTION TIMEOUT 30) file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) + file(LOCK \"\${target_directory}/\${target_filename}.lock\" RELEASE) + file(REMOVE \"\${target_directory}/\${target_filename}.lock\") endif() endif() endfunction() diff --git a/cmake/Platform/Linux/PAL_linux.cmake b/cmake/Platform/Linux/PAL_linux.cmake index d3e4aba1f8..c15f2bada9 100644 --- a/cmake/Platform/Linux/PAL_linux.cmake +++ b/cmake/Platform/Linux/PAL_linux.cmake @@ -12,7 +12,6 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG) ly_set(PAL_LINKOPTION_MODULE MODULE) -ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED TRUE) diff --git a/cmake/Platform/Linux/QtDeploy_linux.cmake b/cmake/Platform/Linux/QtDeploy_linux.cmake deleted file mode 100644 index 26f56644a3..0000000000 --- a/cmake/Platform/Linux/QtDeploy_linux.cmake +++ /dev/null @@ -1,73 +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. -# - -# Clear the cache for found executable -unset(WINDEPLOYQT_EXECUTABLE CACHE) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_PATH}/bin") -mark_as_advanced(WINDEPLOYQT_EXECUTABLE) # Hiding from GUI - -function(ly_qt_deploy) - - set(options) - set(oneValueArgs TARGET) - set(multiValueArgs) - - cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Validate input arguments - if(NOT ly_qt_deploy_TARGET) - message(FATAL_ERROR "You must provide a target to detect qt dependencies") - endif() - - # When winqtdeploy is used on a unix platform it copies over the hardcoded platform abstraction plugin - # of qxcb plugin. The qxcb plugin requires an X server to be running on linux and order to load properly - # To avoid the issue of requiring an X server to be running in a headless setup, the qminimal - # platform plugin is also copied over to the target file output directory. - set(plugin_path "${QT_PATH}/plugins") - set(platform_plugins ${plugin_path}/platforms/libqminimal.so) - set(xcbglintegrations_plugins ${plugin_path}/xcbglintegrations/libqxcb-glx-integration.so) - - add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DLY_TIMESTAMP_REFERENCE=$ - -DLY_LOCK_FILE=$/qtdeploy.lock - -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake - EXEC_COMMAND "${CMAKE_COMMAND}" -E - env PATH=${CMAKE_BINARY_DIR}:${QT_PATH}/bin:$ENV{PATH} - "${CMAKE_COMMAND}" -P "${LY_ROOT_FOLDER}/cmake/Platform/Linux/windeployqt_wrapper.cmake" - "$" - "${WINDEPLOYQT_EXECUTABLE}" - --verbose 2 - --no-compiler-runtime - --dir "$" - "$" - EXEC_COMMAND ${CMAKE_COMMAND} -E make_directory - "$/platforms" - EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${platform_plugins} - "$/platforms" - EXEC_COMMAND ${CMAKE_COMMAND} -E make_directory - "$/xcbglintegrations" - EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${xcbglintegrations_plugins} - "$/xcbglintegrations" - DEPENDS $ - COMMENT "Deploying qt..." - VERBATIM - ) - -endfunction() - -# windeployqt uses qmake -query to introspect a given Qt installation. However, -# qmake is not relocatable, so the paths reported are those from the build -# machine, and not from wherever the user has their 3rdParty libraries. So we -# create a fake qmake executable to report the right paths to windeployqt. -configure_file(${CMAKE_CURRENT_LIST_DIR}/Qt_qmake_${PAL_PLATFORM_NAME_LOWERCASE}.cmake.in ${CMAKE_BINARY_DIR}/qmake) diff --git a/cmake/Platform/Linux/Qt_qmake_linux.cmake.in b/cmake/Platform/Linux/Qt_qmake_linux.cmake.in deleted file mode 100644 index a02b1aa397..0000000000 --- a/cmake/Platform/Linux/Qt_qmake_linux.cmake.in +++ /dev/null @@ -1,38 +0,0 @@ -#!${CMAKE_COMMAND} -P - -# -# 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. -# - - -execute_process(COMMAND ${CMAKE_COMMAND} -E echo "QT_SYSROOT: -QT_INSTALL_PREFIX:${QT_PATH} -QT_INSTALL_ARCHDATA:${QT_PATH} -QT_INSTALL_DATA:${QT_PATH} -QT_INSTALL_DOCS:${QT_PATH}/doc -QT_INSTALL_HEADERS:${QT_PATH}/include -QT_INSTALL_LIBS:${QT_PATH}/lib -QT_INSTALL_LIBEXECS:${QT_PATH}/libexec -QT_INSTALL_BINS:${QT_PATH}/bin -QT_INSTALL_TESTS:${QT_PATH}/tests -QT_INSTALL_PLUGINS:${QT_PATH}/plugins -QT_INSTALL_IMPORTS:${QT_PATH}/imports -QT_INSTALL_TRANSLATIONS:${QT_PATH}/translations -QT_INSTALL_CONFIGURATION:${QT_PATH}/etc/xdg -QT_INSTALL_EXAMPLES:${QT_PATH}/examples -QT_INSTALL_DEMOS:${QT_PATH}/examples -QT_HOST_PREFIX:${QT_PATH} -QT_HOST_DATA:${QT_PATH} -QT_HOST_BINS:${QT_PATH}/bin -QT_HOST_LIBS:${QT_PATH}/lib -QMAKE_SPEC:linux-g++ -QMAKE_XSPEC:linux-g++ -QMAKE_VERSION:3.1 -QT_VERSION:${QT_PACKAGE_VERSION}") diff --git a/cmake/Platform/Linux/platform_linux_files.cmake b/cmake/Platform/Linux/platform_linux_files.cmake index 8b6bdf1361..0a9a244ef0 100644 --- a/cmake/Platform/Linux/platform_linux_files.cmake +++ b/cmake/Platform/Linux/platform_linux_files.cmake @@ -19,6 +19,5 @@ set(FILES LYWrappers_linux.cmake PAL_linux.cmake PALDetection_linux.cmake - windeployqt_wrapper.cmake RPathChange.cmake ) diff --git a/cmake/Platform/Linux/windeployqt_wrapper.cmake b/cmake/Platform/Linux/windeployqt_wrapper.cmake deleted file mode 100644 index 320b49aa7a..0000000000 --- a/cmake/Platform/Linux/windeployqt_wrapper.cmake +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/cmake -P - -# -# 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. -# - -# We use windeployqt on Linux to copy the necessary Qt libraries and files to -# the build directory. After these files are copied, we need to adjust their -# rpath to point to Qt from the build tree. - -# This script is invoked through the CommandExecution.cmake script. The invoked -# commandline is something like: -# cmake -P CommandExecution.cmake EXEC_COMMAND cmake -E env ... cmake -P windeployqt_wrapper.cmake args -# ^ 1 ^ 2 ^ 3 -# cmake #1 invokes cmake #2 which invokes cmake #3. But cmake #1 also sees 2 -P -# arguments, so cmake #1 also invokes windeployqt_wrapper.cmake after -# CommandExecution.cmake finishes. We don't want to run this script 2x, so -# detect this case and exit early - -# Find the first -P argument -foreach(argi RANGE 1 ${CMAKE_ARGC}) - if("${CMAKE_ARGV${argi}}" STREQUAL "-P") - math(EXPR script_argi "${argi} + 1") - set(script_file "${CMAKE_ARGV${script_argi}}") - break() - endif() -endforeach() - -if(NOT script_file STREQUAL "${CMAKE_CURRENT_LIST_FILE}") - return() -endif() - -set(runtime_directory ${CMAKE_ARGV3}) - -foreach(argi RANGE 4 ${CMAKE_ARGC}) - list(APPEND command_arguments "${CMAKE_ARGV${argi}}") -endforeach() -execute_process(COMMAND ${command_arguments} RESULT_VARIABLE command_result OUTPUT_VARIABLE command_output ERROR_VARIABLE command_err) - -if(command_result) - message(FATAL_ERROR "windeployqt returned a non-zero exit status. stdout: ${command_output} stderr: ${command_err}") -endif() - -# Process the output to find the list of files that were updated - -# Transform the output to a list -string(REGEX REPLACE ";" "\\\\;" command_output "${command_output}") -string(REGEX REPLACE "\n" ";" command_output "${command_output}") - -foreach(line IN LISTS command_output) - # windeployqt has output that looks like this if it updated a file: - # > Checking /path/to/src/file.so, /path/to/dst/file.so - # > Updating file.so - # If the file was not modified, it will look like this: - # > Checking /path/to/src/file.so, /path/to/dst/file.so - # > file.so is up to date - if(line MATCHES "^Checking .*") - set(curfile "${line}") - continue() - endif() - - if(line MATCHES "^Updating .*") - # curline has 3 parts, 1) "Checking ", 2) source_file, 3) updated_target_file. We - # just need part 3. But we also want to handle the unfortunate - # possibility of spaces in the filename. - - string(REGEX REPLACE "^Checking " "" curfile "${curfile}") - string(REPLACE ", " ";" curfile "${curfile}") - list(LENGTH curfile curfile_parts_count) - if(NOT curfile_parts_count EQUAL 2) - message(SEND_ERROR "Unable to parse output of windeployqt output line ${curfile}") - continue() - endif() - list(GET curfile 1 updated_file) - - file(RELATIVE_PATH relative_file "${runtime_directory}" "${updated_file}") - - get_filename_component(basename "${relative_file}" NAME) - if(basename MATCHES "^libQt5Core\\.so.*") - # We don't need to patch QtCore - continue() - endif() - - # READ_ELF has a CAPTURE_ERROR argument, but that is only set on - # platforms that don't support cmake's elf parser. On linux, no error - # will be set, even when the input is not an ELF formatted file. We - # want to skip any non-executable files, so check for the ELF tag at - # the head of the file. - file(READ "${updated_file}" elf_tag LIMIT 4 HEX) - if(NOT elf_tag STREQUAL 7f454c46) # Binary \0x7f followed by ELF - continue() - endif() - - # READ_ELF is an undocumented command that allows us to introspect the - # current rpath set in the file - file(READ_ELF "${updated_file}" RUNPATH plugin_runpath) - - get_filename_component(dirname "${relative_file}" DIRECTORY) - if(dirname) - file(RELATIVE_PATH parent_dirs "${updated_file}" "${runtime_directory}") - string(REGEX REPLACE "/../$" "" parent_dirs "${parent_dirs}") - set(new_runpath "\$ORIGIN/${parent_dirs}") - else() - set(new_runpath "\$ORIGIN") - endif() - - # RPATH_CHANGE is an undocumented command that allows for replacing an - # existing rpath entry with a new value, as long as the new value's - # strlen is <= the current rpath - file(RPATH_CHANGE FILE "${updated_file}" OLD_RPATH "${plugin_runpath}" NEW_RPATH "${new_runpath}") - - unset(curfile) - endif() -endforeach() diff --git a/cmake/Platform/Mac/PAL_mac.cmake b/cmake/Platform/Mac/PAL_mac.cmake index 477c8d4afb..f49578a83a 100644 --- a/cmake/Platform/Mac/PAL_mac.cmake +++ b/cmake/Platform/Mac/PAL_mac.cmake @@ -12,7 +12,6 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG MACOSX_BUNDLE) ly_set(PAL_LINKOPTION_MODULE MODULE) -ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) diff --git a/cmake/Platform/Mac/QtDeploy_mac.cmake b/cmake/Platform/Mac/QtDeploy_mac.cmake deleted file mode 100644 index 7ab5f61f5d..0000000000 --- a/cmake/Platform/Mac/QtDeploy_mac.cmake +++ /dev/null @@ -1,70 +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. -# - -# Clear the cache for found executable -unset(MACDEPLOYQT_EXECUTABLE CACHE) -find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT_PATH}/bin") -mark_as_advanced(MACDEPLOYQT_EXECUTABLE) # Hiding from GUI - -function(ly_qt_deploy) - - set(options) - set(oneValueArgs TARGET) - set(multiValueArgs) - - cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Validate input arguments - if(NOT ly_qt_deploy_TARGET) - message(FATAL_ERROR "You must provide a target to detect qt dependencies") - endif() - - #get_target_property(is_bundle ${ly_qt_deploy_TARGET} MACOSX_BUNDLE) - if (is_bundle) - add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DLY_TIMESTAMP_REFERENCE=$ - -DLY_LOCK_FILE=$/qtdeploy.lock - -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake - EXEC_COMMAND "${CMAKE_COMMAND}" -E time - ${MACDEPLOYQT_EXECUTABLE} - $ - -always-overwrite - -no-strip - -verbose=0 - -fs=APFS - DEPENDS $ - COMMENT "Deploying qt to the ${ly_qt_deploy_TARGET} bundle ..." - VERBATIM - ) - else() - set(qt_conf_config "[Paths]\nPlugins=@plugin_path@") - set(plugin_path "${QT_PATH}/plugins") - string(CONFIGURE "${qt_conf_config}" qt_conf_output @ONLY) - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "${qt_conf_output}") - - # output the qt_conf file using "echo" and file redirection - add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DLY_TIMESTAMP_REFERENCE=$ - -DLY_LOCK_FILE=$/qtdeploy.lock - -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake - EXEC_COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_CURRENT_BINARY_DIR}/qt.conf - $/qt.conf - COMMENT "copying over qt.conf..." - VERBATIM - ) - endif() - -endfunction() - - diff --git a/cmake/Platform/Windows/PAL_windows.cmake b/cmake/Platform/Windows/PAL_windows.cmake index fcbd8acb70..fbf65db63f 100644 --- a/cmake/Platform/Windows/PAL_windows.cmake +++ b/cmake/Platform/Windows/PAL_windows.cmake @@ -12,7 +12,6 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG WIN32) ly_set(PAL_LINKOPTION_MODULE MODULE) -ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED TRUE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS TRUE) ly_set(PAL_TRAIT_BUILD_TESTS_SUPPORTED TRUE) diff --git a/cmake/Platform/Windows/QtDeploy_windows.cmake b/cmake/Platform/Windows/QtDeploy_windows.cmake deleted file mode 100644 index 2fb1a71114..0000000000 --- a/cmake/Platform/Windows/QtDeploy_windows.cmake +++ /dev/null @@ -1,50 +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. -# - -# Clear the cache for found executable -unset(WINDEPLOYQT_EXECUTABLE CACHE) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${QT_PATH}/bin") -mark_as_advanced(WINDEPLOYQT_EXECUTABLE) # Hiding from GUI - -function(ly_qt_deploy) - - set(options) - set(oneValueArgs TARGET) - set(multiValueArgs) - - cmake_parse_arguments(ly_qt_deploy "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Validate input arguments - if(NOT ly_qt_deploy_TARGET) - message(FATAL_ERROR "You must provide a target to detect qt dependencies") - endif() - - # CMake has an issue with POST_BUILD commands in msbuild when it is executed from outside VS: - # https://gitlab.kitware.com/cmake/cmake/issues/18530 - - add_custom_command(TARGET ${ly_qt_deploy_TARGET} POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DLY_TIMESTAMP_REFERENCE=$ - -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 - $ - DEPENDS $ $ - COMMENT "Deploying qt..." - VERBATIM - ) - -endfunction() \ No newline at end of file diff --git a/cmake/Qt.cmake b/cmake/Qt.cmake deleted file mode 100644 index bf4ecb0f28..0000000000 --- a/cmake/Qt.cmake +++ /dev/null @@ -1,199 +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. -# - -include_guard() - -ly_download_associated_package(Qt) -find_package(Qt REQUIRED MODULE) - -# UIC executable -unset(QT_UIC_EXECUTABLE CACHE) -find_program(QT_UIC_EXECUTABLE uic HINTS "${QT_PATH}/bin") -mark_as_advanced(QT_UIC_EXECUTABLE) # Hiding from GUI - -# RCC executable -unset(AUTORCC_EXECUTABLE CACHE) -find_program(AUTORCC_EXECUTABLE rcc HINTS "${QT_PATH}/bin") -mark_as_advanced(AUTORCC_EXECUTABLE) # Hiding from GUI -set(Qt5Core_RCC_EXECUTABLE "${AUTORCC_EXECUTABLE}" CACHE FILEPATH "Qt's resource compiler, used by qt5_add_resources" FORCE) -mark_as_advanced(Qt5Core_RCC_EXECUTABLE) # Hiding from GUI - -# LRELEASE executable -unset(QT_LRELEASE_EXECUTABLE CACHE) -find_program(QT_LRELEASE_EXECUTABLE lrelease HINTS "${QT_PATH}/bin") -mark_as_advanced(QT_LRELEASE_EXECUTABLE) # Hiding from GUI -if(NOT QT_LRELEASE_EXECUTABLE) - message(FATAL_ERROR "Qt's lrelease executbale not found") -endif() -set(Qt5_LRELEASE_EXECUTABLE "${QT_LRELEASE_EXECUTABLE}" CACHE FILEPATH "Qt's lrelease executable, used by qt5_add_translation" FORCE) -mark_as_advanced(Qt5_LRELEASE_EXECUTABLE) # Hiding from GUI - -#! ly_qt_uic_target: handles qt's ui files by injecting uic generation -# -# AUTOUIC has issues to detect changes in UIC files and trigger regeneration: -# https://gitlab.kitware.com/cmake/cmake/-/issues/18741 -# So instead, we are going to manually wrap the files. We dont use qt5_wrap_ui because -# it outputs to ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h and we want to follow the -# same folder structure that AUTOUIC uses -# -function(ly_qt_uic_target TARGET) - - get_target_property(all_ui_sources ${TARGET} SOURCES) - list(FILTER all_ui_sources INCLUDE REGEX "^.*\\.ui$") - if(NOT all_ui_sources) - message(FATAL_ERROR "Target ${TARGET} contains AUTOUIC but doesnt have any .ui file") - endif() - - if(AUTOGEN_BUILD_DIR) - set(gen_dir ${AUTOGEN_BUILD_DIR}) - else() - set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_autogen/include) - endif() - - foreach(ui_source ${all_ui_sources}) - - get_filename_component(filename ${ui_source} NAME_WE) - get_filename_component(dir ${ui_source} DIRECTORY) - if(IS_ABSOLUTE ${dir}) - file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir}) - endif() - - set(outfolder ${gen_dir}/${dir}) - set(outfile ${outfolder}/ui_${filename}.h) - get_filename_component(infile ${ui_source} ABSOLUTE) - - file(MAKE_DIRECTORY ${outfolder}) - add_custom_command(OUTPUT ${outfile} - COMMAND ${QT_UIC_EXECUTABLE} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile} VERBATIM - COMMENT "UIC ${infile}" - ) - - set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC TRUE) - set_source_files_properties(${outfile} PROPERTIES - SKIP_AUTOMOC TRUE - SKIP_AUTOUIC TRUE - GENERATED TRUE - ) - list(APPEND all_ui_wrapped_sources ${outfile}) - - endforeach() - - # Add files to the target - target_sources(${TARGET} PRIVATE ${all_ui_wrapped_sources}) - source_group("Generated Files" FILES ${all_ui_wrapped_sources}) - - # Add include directories relative to the generated folder - # query for the property first to avoid the "NOTFOUND" in a list - get_property(has_includes TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES SET) - if(has_includes) - get_property(all_include_directories TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES) - foreach(dir ${all_include_directories}) - if(IS_ABSOLUTE ${dir}) - file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir}) - endif() - list(APPEND new_includes ${gen_dir}/${dir}) - endforeach() - endif() - list(APPEND new_includes ${gen_dir}) - target_include_directories(${TARGET} PRIVATE ${new_includes}) - -endfunction() - -#! ly_add_translations: adds translations (ts) to a target. -# -# This wrapper will generate a qrc file with those translations and add the files under "prefix" and add them to -# the indicated targets. These files will be added under the "Generated Files" filter -# -# \arg:TARGETS name of the targets that the translations will be added to -# \arg:PREFIX prefix where the translation will be located within the qrc file -# \arg:FILES translation files to add -# -function(ly_add_translations) - - set(options) - set(oneValueArgs PREFIX) - set(multiValueArgs TARGETS FILES) - - cmake_parse_arguments(ly_add_translations "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Validate input arguments - if(NOT ly_add_translations_TARGETS) - message(FATAL_ERROR "You must provide at least one target") - endif() - if(NOT ly_add_translations_FILES) - message(FATAL_ERROR "You must provide at least a translation file") - endif() - - qt5_add_translation(TRANSLATED_FILES ${ly_add_translations_FILES}) - - set(qrc_file_contents -" - -") - foreach(file ${TRANSLATED_FILES}) - get_filename_component(filename ${file} NAME) - string(APPEND qrc_file_contents " ${filename} -") - endforeach() - string(APPEND qrc_file_contents " - -") - set(qrc_file_path ${CMAKE_CURRENT_BINARY_DIR}/i18n_${ly_add_translations_PREFIX}.qrc) - file(WRITE - ${qrc_file_path} - ${qrc_file_contents} - ) - set_source_files_properties( - ${TRANSLATED_FILES} - ${qrc_file_path} - PROPERTIES - GENERATED TRUE - SKIP_AUTORCC TRUE - ) - qt5_add_resources(RESOURCE_FILE ${qrc_file_path}) - - foreach(target ${ly_add_translations_TARGETS}) - target_sources(${target} PRIVATE "${TRANSLATED_FILES};${qrc_file_path};${RESOURCE_FILE}") - endforeach() - -endfunction() - - -#! ly_qt_deploy_qtconf: deploys the qt.conf file for TARGET -# -# Instead of running a qt deploy on regular builds, we are using the qt.conf method: -# https://doc.qt.io/qt-5/qt-conf.html -# With such method we can use Qt from the 3rdParty package folder without requiring to -# copy the dlls/plugins to the output. -# -# A full deploy will be done on cmake install -# -# \arg:TARGET target that defines where to deploy to. This also adds a custom POST_BUILD -# command to TARGET to copy the file. -# -function(ly_qt_deploy_qtconf TARGET) - - add_custom_command(TARGET ${TARGET} POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -E copy_if_different - ${CMAKE_BINARY_DIR}/qt.conf - $/qt.conf - COMMENT "Copying over qt.conf..." - VERBATIM - ) - -endfunction() - -# Generate the file once so we copy it per target -file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=${QT_PATH}/plugins") - -include(${LY_ROOT_FOLDER}/cmake/Platform/${PAL_PLATFORM_NAME}/QtDeploy_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) From 355c5ced1ff2283cd4b5cb0969061f39940e3abe Mon Sep 17 00:00:00 2001 From: pappeste Date: Thu, 10 Jun 2021 14:48:09 -0700 Subject: [PATCH 15/93] fixing runtime dependencies for cases with multiple values --- Code/Sandbox/Editor/CMakeLists.txt | 1 - .../Common/RuntimeDependencies_common.cmake | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Code/Sandbox/Editor/CMakeLists.txt b/Code/Sandbox/Editor/CMakeLists.txt index e1fce97067..51620c6e37 100644 --- a/Code/Sandbox/Editor/CMakeLists.txt +++ b/Code/Sandbox/Editor/CMakeLists.txt @@ -104,7 +104,6 @@ ly_add_target( 3rdParty::Qt::Gui 3rdParty::Qt::Widgets 3rdParty::Qt::Concurrent - 3rdParty::Qt::WebEngineWidgets 3rdParty::tiff 3rdParty::squish-ccr 3rdParty::zlib diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index 57484da9eb..10fcae6297 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -113,12 +113,13 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) set(imported_property IMPORTED_LOCATION) endif() - set(target_locations) - get_target_property(current_target_locations ${ly_TARGET} ${imported_property}) - if(current_target_locations) - string(APPEND target_locations ${current_target_locations}) + unset(target_locations) + get_target_property(target_locations ${ly_TARGET} ${imported_property}) + if(target_locations) + list(APPEND all_runtime_dependencies ${target_locations}) else() # Check if the property exists for configurations + unset(target_locations) foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES) string(TOUPPER ${conf} UCONF) unset(current_target_locations) @@ -129,6 +130,7 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) # try to use the mapping get_target_property(mapped_conf ${ly_TARGET} MAP_IMPORTED_CONFIG_${UCONF}) if(mapped_conf) + unset(current_target_locations) get_target_property(current_target_locations ${ly_TARGET} ${imported_property}_${mapped_conf}) if(current_target_locations) string(APPEND target_locations $<$:${current_target_locations}>) @@ -136,10 +138,11 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET) endif() endif() endforeach() + if(target_locations) + list(APPEND all_runtime_dependencies ${target_locations}) + endif() endif() - if(target_locations) - list(APPEND all_runtime_dependencies ${target_locations}) - endif() + endif() endif() From b5c7a3544205fb7e41a29da806308e42b03bcca0 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Thu, 10 Jun 2021 19:22:40 -0700 Subject: [PATCH 16/93] working with fixup bundle and incrementals of 1s --- cmake/CommandExecution.cmake | 5 -- .../Android/RuntimeDependencies_android.cmake | 15 +++++ .../Common/RuntimeDependencies_common.cmake | 19 +------ .../Linux/RuntimeDependencies_linux.cmake | 15 +++++ .../Mac/RuntimeDependencies_mac.cmake | 57 +++++++++++++++++++ .../Windows/RuntimeDependencies_windows.cmake | 15 +++++ 6 files changed, 105 insertions(+), 21 deletions(-) diff --git a/cmake/CommandExecution.cmake b/cmake/CommandExecution.cmake index a10e30eb26..3ed084bb42 100644 --- a/cmake/CommandExecution.cmake +++ b/cmake/CommandExecution.cmake @@ -88,8 +88,3 @@ if(LY_TIMESTAMP_REFERENCE) # Touch the timestamp file file(TOUCH ${LY_TIMESTAMP_FILE}) endif() - -if(LY_LOCK_FILE) - file(LOCK ${LY_LOCK_FILE} RELEASE) - file(REMOVE ${LY_LOCK_FILE}) -endif() \ No newline at end of file diff --git a/cmake/Platform/Android/RuntimeDependencies_android.cmake b/cmake/Platform/Android/RuntimeDependencies_android.cmake index 8b50ec465d..f90ff23b8d 100644 --- a/cmake/Platform/Android/RuntimeDependencies_android.cmake +++ b/cmake/Platform/Android/RuntimeDependencies_android.cmake @@ -9,4 +9,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +set(LY_RUNTIME_DEPENDENCIES_HEADER +"function(ly_copy source_file target_directory) + get_filename_component(target_filename \"\${source_file}\" NAME) + if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") + if(NOT EXISTS \"\${target_directory}\") + file(MAKE_DIRECTORY \"\${target_directory}\") + endif() + if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") + file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) + file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) + endif() + endif() +endfunction() +\n") + include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index 10fcae6297..bab3f72265 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -247,22 +247,7 @@ function(ly_delayed_generate_runtime_dependencies) endif() unset(runtime_dependencies) - set(runtime_commands " -function(ly_copy source_file target_directory) - get_filename_component(target_filename \"\${source_file}\" NAME) - if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") - if(NOT EXISTS \"\${target_directory}\") - file(MAKE_DIRECTORY \"\${target_directory}\") - endif() - if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") - file(LOCK \"\${target_directory}/\${target_filename}.lock\" GUARD FUNCTION TIMEOUT 30) - file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) - file(LOCK \"\${target_directory}/\${target_filename}.lock\" RELEASE) - file(REMOVE \"\${target_directory}/\${target_filename}.lock\") - endif() - endif() -endfunction() - \n") + set(runtime_commands ${LY_RUNTIME_DEPENDENCIES_HEADER}) ly_get_runtime_dependencies(runtime_dependencies ${target}) foreach(runtime_dependency ${runtime_dependencies}) @@ -270,6 +255,8 @@ endfunction() ly_get_runtime_dependency_command(runtime_command ${runtime_dependency}) string(APPEND runtime_commands ${runtime_command}) endforeach() + + string(APPEND runtime_commands ${LY_RUNTIME_DEPENDENCIES_FOOTER}) # Generate the output file set(target_file_dir "$") diff --git a/cmake/Platform/Linux/RuntimeDependencies_linux.cmake b/cmake/Platform/Linux/RuntimeDependencies_linux.cmake index 8b50ec465d..6483250ab2 100644 --- a/cmake/Platform/Linux/RuntimeDependencies_linux.cmake +++ b/cmake/Platform/Linux/RuntimeDependencies_linux.cmake @@ -9,4 +9,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +set(LY_RUNTIME_DEPENDENCIES_HEADER +"function(ly_copy source_file target_directory) + get_filename_component(target_filename \"\${source_file}\" NAME) + if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") + if(NOT EXISTS \"\${target_directory}\") + file(MAKE_DIRECTORY \"\${target_directory}\") + endif() + if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") + file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) + file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS} FOLLOW_SYMLINK_CHAIN) + endif() + endif() +endfunction() +\n") + include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake index 8b50ec465d..169b6d2764 100644 --- a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake +++ b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake @@ -9,4 +9,61 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +set(LY_RUNTIME_DEPENDENCIES_HEADER +" +set(anything_new FALSE) + +function(ly_copy source_file target_directory) + # If source_file is a Framework and target_directory is a bundle + if(\"\${source_file}\" MATCHES \".[Ff]ramework\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") + return() # skip, it will be fixed with fixup_bundle + elseif(\"\${source_file}\" MATCHES \"qt/plugins\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") + # fixup the destination so it ends up in Contents/Plugins + string(REGEX REPLACE \"(.*.app/Contents)/MacOS(.*)\" \"\\\\1/plugins\\\\2\" target_directory \"\${target_directory}\") + elseif(\"\${source_file}\" MATCHES \"qt/translations\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") + return() # skip + endif() + get_filename_component(target_filename \"\${source_file}\" NAME) + if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") + if(NOT EXISTS \"\${target_directory}\") + file(MAKE_DIRECTORY \"\${target_directory}\") + endif() + if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") + file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) + file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS} FOLLOW_SYMLINK_CHAIN) + set(anything_new TRUE) + endif() + endif() +endfunction() +\n") + +set(LY_RUNTIME_DEPENDENCIES_FOOTER +" +if(@target_file_dir@ MATCHES \".app/Contents/MacOS\") + if(NOT anything_new) + string(REGEX REPLACE \"(.*.app)/Contents/MacOS.*\" \"\\\\1\" bundle_path \"@target_file_dir@\") + set(timestamp_file \"\${bundle_path}.fixup.stamp\") + if(NOT EXISTS \"\${timestamp_file}\") + set(anything_new TRUE) + else() + file(GLOB_RECURSE files_in_bundle FOLLOW_SYMLINKS \"\${bundle_path}\") + foreach(file \${files_in_bundle}) + if(\${file} IS_NEWER_THAN \"\${timestamp_file}\") + set(anything_new TRUE) + break() + endif() + endforeach() + endif() + endif() + if(anything_new) + include(BundleUtilities) + fixup_bundle(\"\${bundle_path}\" \"\" \"\") + file(TOUCH \"\${timestamp_file}\") + endif() +endif() +") + + + + include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Windows/RuntimeDependencies_windows.cmake b/cmake/Platform/Windows/RuntimeDependencies_windows.cmake index 8b50ec465d..f90ff23b8d 100644 --- a/cmake/Platform/Windows/RuntimeDependencies_windows.cmake +++ b/cmake/Platform/Windows/RuntimeDependencies_windows.cmake @@ -9,4 +9,19 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +set(LY_RUNTIME_DEPENDENCIES_HEADER +"function(ly_copy source_file target_directory) + get_filename_component(target_filename \"\${source_file}\" NAME) + if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") + if(NOT EXISTS \"\${target_directory}\") + file(MAKE_DIRECTORY \"\${target_directory}\") + endif() + if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") + file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) + file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) + endif() + endif() +endfunction() +\n") + include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file From e7d86992935176c7c6eb3770dad142e8a5cb7035 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Thu, 10 Jun 2021 20:23:22 -0700 Subject: [PATCH 17/93] passing plugin dirs --- cmake/Platform/Mac/RuntimeDependencies_mac.cmake | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake index 169b6d2764..e89dedfc8b 100644 --- a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake +++ b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake @@ -12,18 +12,25 @@ set(LY_RUNTIME_DEPENDENCIES_HEADER " set(anything_new FALSE) +set(plugin_libs) +set(plugin_dirs) function(ly_copy source_file target_directory) + get_filename_component(target_filename \"\${source_file}\" NAME) + get_filename_component(source_file_dir \"\${source_file}\" DIRECTORY) # If source_file is a Framework and target_directory is a bundle if(\"\${source_file}\" MATCHES \".[Ff]ramework\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") + set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) return() # skip, it will be fixed with fixup_bundle elseif(\"\${source_file}\" MATCHES \"qt/plugins\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") # fixup the destination so it ends up in Contents/Plugins - string(REGEX REPLACE \"(.*.app/Contents)/MacOS(.*)\" \"\\\\1/plugins\\\\2\" target_directory \"\${target_directory}\") + set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) + set(plugin_libs \"\${plugin_libs};\${target_directory}/\${target_filename}\" PARENT_SCOPE) elseif(\"\${source_file}\" MATCHES \"qt/translations\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") return() # skip + elseif(\"\${source_file}\" MATCHES \".dylib\") + set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) endif() - get_filename_component(target_filename \"\${source_file}\" NAME) if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") if(NOT EXISTS \"\${target_directory}\") file(MAKE_DIRECTORY \"\${target_directory}\") @@ -57,7 +64,9 @@ if(@target_file_dir@ MATCHES \".app/Contents/MacOS\") endif() if(anything_new) include(BundleUtilities) - fixup_bundle(\"\${bundle_path}\" \"\" \"\") + list(REMOVE_DUPLICATES plugin_libs) + list(REMOVE_DUPLICATES plugin_dirs) + fixup_bundle(\"\${bundle_path}\" \"\${plugin_libs}\" \"\${plugin_dirs}\") file(TOUCH \"\${timestamp_file}\") endif() endif() From 4a53d791585aea868e5cecc0d0ecddf80bae7fe8 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Fri, 11 Jun 2021 18:08:55 -0700 Subject: [PATCH 18/93] Fixup editor bundle working --- .../Android/RuntimeDependencies_android.cmake | 16 +- .../Common/RuntimeDependencies_common.cmake | 12 +- .../runtime_dependencies_common.cmake.in | 25 ++++ .../Linux/RuntimeDependencies_linux.cmake | 16 +- .../Mac/RuntimeDependencies_mac.cmake | 67 +-------- .../Mac/runtime_dependencies_mac.cmake.in | 139 ++++++++++++++++++ .../Windows/RuntimeDependencies_windows.cmake | 16 +- 7 files changed, 175 insertions(+), 116 deletions(-) create mode 100644 cmake/Platform/Common/runtime_dependencies_common.cmake.in create mode 100644 cmake/Platform/Mac/runtime_dependencies_mac.cmake.in diff --git a/cmake/Platform/Android/RuntimeDependencies_android.cmake b/cmake/Platform/Android/RuntimeDependencies_android.cmake index f90ff23b8d..add036a8b8 100644 --- a/cmake/Platform/Android/RuntimeDependencies_android.cmake +++ b/cmake/Platform/Android/RuntimeDependencies_android.cmake @@ -9,19 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_RUNTIME_DEPENDENCIES_HEADER -"function(ly_copy source_file target_directory) - get_filename_component(target_filename \"\${source_file}\" NAME) - if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") - if(NOT EXISTS \"\${target_directory}\") - file(MAKE_DIRECTORY \"\${target_directory}\") - endif() - if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") - file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) - file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) - endif() - endif() -endfunction() -\n") - +set(LY_RUNTIME_DEPENDENCIES_TEMPLATE ${LY_ROOT_FOLDER}/cmake/Platform/Common/runtime_dependencies_common.cmake.in) include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Common/RuntimeDependencies_common.cmake b/cmake/Platform/Common/RuntimeDependencies_common.cmake index bab3f72265..d00dd71f1e 100644 --- a/cmake/Platform/Common/RuntimeDependencies_common.cmake +++ b/cmake/Platform/Common/RuntimeDependencies_common.cmake @@ -247,23 +247,23 @@ function(ly_delayed_generate_runtime_dependencies) endif() unset(runtime_dependencies) - set(runtime_commands ${LY_RUNTIME_DEPENDENCIES_HEADER}) + unset(LY_COPY_COMMANDS) ly_get_runtime_dependencies(runtime_dependencies ${target}) foreach(runtime_dependency ${runtime_dependencies}) unset(runtime_command) ly_get_runtime_dependency_command(runtime_command ${runtime_dependency}) - string(APPEND runtime_commands ${runtime_command}) + string(APPEND LY_COPY_COMMANDS ${runtime_command}) endforeach() - string(APPEND runtime_commands ${LY_RUNTIME_DEPENDENCIES_FOOTER}) - # Generate the output file set(target_file_dir "$") - string(CONFIGURE "${runtime_commands}" generated_commands @ONLY) + file(READ ${LY_RUNTIME_DEPENDENCIES_TEMPLATE} template_file) + string(CONFIGURE "${LY_COPY_COMMANDS}" LY_COPY_COMMANDS @ONLY) + string(CONFIGURE "${template_file}" configured_template_file @ONLY) file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/runtime_dependencies/$/${target}.cmake - CONTENT "${generated_commands}" + CONTENT "${configured_template_file}" ) endforeach() diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in new file mode 100644 index 0000000000..b476b7d401 --- /dev/null +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -0,0 +1,25 @@ +# +# 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. +# + +function(ly_copy source_file target_directory) + get_filename_component(target_filename "${source_file}" NAME) + if(NOT "${source_file}" STREQUAL "${target_directory}/${target_filename}") + if(NOT EXISTS "${target_directory}") + file(MAKE_DIRECTORY "${target_directory}") + endif() + if("${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") + file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" GUARD FUNCTION TIMEOUT 30) + file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) + endif() + endif() +endfunction() + +@LY_COPY_COMMANDS@ diff --git a/cmake/Platform/Linux/RuntimeDependencies_linux.cmake b/cmake/Platform/Linux/RuntimeDependencies_linux.cmake index 6483250ab2..add036a8b8 100644 --- a/cmake/Platform/Linux/RuntimeDependencies_linux.cmake +++ b/cmake/Platform/Linux/RuntimeDependencies_linux.cmake @@ -9,19 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_RUNTIME_DEPENDENCIES_HEADER -"function(ly_copy source_file target_directory) - get_filename_component(target_filename \"\${source_file}\" NAME) - if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") - if(NOT EXISTS \"\${target_directory}\") - file(MAKE_DIRECTORY \"\${target_directory}\") - endif() - if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") - file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) - file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS} FOLLOW_SYMLINK_CHAIN) - endif() - endif() -endfunction() -\n") - +set(LY_RUNTIME_DEPENDENCIES_TEMPLATE ${LY_ROOT_FOLDER}/cmake/Platform/Common/runtime_dependencies_common.cmake.in) include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake index e89dedfc8b..383a3d5985 100644 --- a/cmake/Platform/Mac/RuntimeDependencies_mac.cmake +++ b/cmake/Platform/Mac/RuntimeDependencies_mac.cmake @@ -9,70 +9,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_RUNTIME_DEPENDENCIES_HEADER -" -set(anything_new FALSE) -set(plugin_libs) -set(plugin_dirs) - -function(ly_copy source_file target_directory) - get_filename_component(target_filename \"\${source_file}\" NAME) - get_filename_component(source_file_dir \"\${source_file}\" DIRECTORY) - # If source_file is a Framework and target_directory is a bundle - if(\"\${source_file}\" MATCHES \".[Ff]ramework\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") - set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) - return() # skip, it will be fixed with fixup_bundle - elseif(\"\${source_file}\" MATCHES \"qt/plugins\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") - # fixup the destination so it ends up in Contents/Plugins - set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) - set(plugin_libs \"\${plugin_libs};\${target_directory}/\${target_filename}\" PARENT_SCOPE) - elseif(\"\${source_file}\" MATCHES \"qt/translations\" AND \"\${target_directory}\" MATCHES \".app/Contents/MacOS\") - return() # skip - elseif(\"\${source_file}\" MATCHES \".dylib\") - set(plugin_dirs \"\${plugin_dirs};\${source_file_dir}\" PARENT_SCOPE) - endif() - if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") - if(NOT EXISTS \"\${target_directory}\") - file(MAKE_DIRECTORY \"\${target_directory}\") - endif() - if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") - file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) - file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS} FOLLOW_SYMLINK_CHAIN) - set(anything_new TRUE) - endif() - endif() -endfunction() -\n") - -set(LY_RUNTIME_DEPENDENCIES_FOOTER -" -if(@target_file_dir@ MATCHES \".app/Contents/MacOS\") - if(NOT anything_new) - string(REGEX REPLACE \"(.*.app)/Contents/MacOS.*\" \"\\\\1\" bundle_path \"@target_file_dir@\") - set(timestamp_file \"\${bundle_path}.fixup.stamp\") - if(NOT EXISTS \"\${timestamp_file}\") - set(anything_new TRUE) - else() - file(GLOB_RECURSE files_in_bundle FOLLOW_SYMLINKS \"\${bundle_path}\") - foreach(file \${files_in_bundle}) - if(\${file} IS_NEWER_THAN \"\${timestamp_file}\") - set(anything_new TRUE) - break() - endif() - endforeach() - endif() - endif() - if(anything_new) - include(BundleUtilities) - list(REMOVE_DUPLICATES plugin_libs) - list(REMOVE_DUPLICATES plugin_dirs) - fixup_bundle(\"\${bundle_path}\" \"\${plugin_libs}\" \"\${plugin_dirs}\") - file(TOUCH \"\${timestamp_file}\") - endif() -endif() -") - - - +set(LY_BUILD_FIXUP_BUNDLE TRUE CACHE BOOL "Fix bundles on build (deploys frameworks and calls fixup_bundle)") +set(LY_RUNTIME_DEPENDENCIES_TEMPLATE ${LY_ROOT_FOLDER}/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in) include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in new file mode 100644 index 0000000000..8a88df86cb --- /dev/null +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -0,0 +1,139 @@ +# +# 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(BundleUtilities) + +#set(BU_COPY_FULL_FRAMEWORK_CONTENTS ON) + +set(anything_new FALSE) +set(plugin_libs) +set(plugin_dirs) + +function(ly_copy source_file target_directory) + + get_filename_component(target_filename "${source_file}" NAME) + + # If source_file is a Framework and target_directory is a bundle + if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") + + if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) + return() + endif() + + # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks + string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/Frameworks" target_directory "${target_directory}") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + + elseif("${source_file}" MATCHES "qt/plugins" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") + + if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) + return() + endif() + + # fixup the destination so it ends up in Contents/Plugins + string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/plugins" target_directory "${target_directory}") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + set(local_plugin_libs ${plugin_libs}) + list(APPEND local_plugin_libs "${target_directory}/${target_filename}") + set(plugin_libs ${local_plugin_libs} PARENT_SCOPE) + + elseif("${source_file}" MATCHES "qt/translations" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") + + return() # skip, is this used? + + elseif("${source_file}" MATCHES ".dylib") + + set(local_plugin_dirs ${plugin_dirs}) + list(APPEND local_plugin_dirs "${target_directory}") + set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + + endif() + + if(NOT "${source_file}" STREQUAL "${target_directory}/${target_filename}") + if(NOT EXISTS "${target_directory}") + file(MAKE_DIRECTORY "${target_directory}") + endif() + if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") + file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" GUARD FUNCTION TIMEOUT 30) + message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") + file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) + set(anything_new TRUE PARENT_SCOPE) + endif() + endif() +endfunction() + +@LY_COPY_COMMANDS@ + +if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) + return() +endif() + +if(@target_file_dir@ MATCHES ".app/Contents/MacOS") + string(REGEX REPLACE "(.*\\.app)/Contents/MacOS.*" "\\1" bundle_path "@target_file_dir@") + if(NOT anything_new) + set(timestamp_file "${bundle_path}.fixup.stamp") + if(NOT EXISTS "${timestamp_file}") + set(anything_new TRUE) + else() + file(GLOB_RECURSE files_in_bundle FOLLOW_SYMLINKS "${bundle_path}") + foreach(file ${files_in_bundle}) + if(${file} IS_NEWER_THAN "${timestamp_file}") + set(anything_new TRUE) + break() + endif() + endforeach() + endif() + endif() + if(anything_new) + # LYN-4505: Patch dxc, is configured in the wrong folder in 3p + if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) + file(RENAME + ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/lib/libdxcompiler.3.7.dylib + ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/libdxcompiler.3.7.dylib + ) + endif() + if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) + # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has + # duplicated binaries between Versions/3.7 and Versions/Current. + file(GLOB exe_files + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/distutils/command/*.exe + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip/_vendor/distlib/*.exe + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/setuptools/*.exe + ) + foreach(exe_file ${exe_files}) + file(REMOVE ${exe_file}) + endforeach() + file(REMOVE_RECURSE + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Resources + ${bundle_path}/Contents/Frameworks/Python.framework/Python + ${bundle_path}/Contents/Frameworks/Python.framework/Resources/Python.app + ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Python + ) + file(REMOVE_RECURSE ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current + WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ + ) + endif() + list(REMOVE_DUPLICATES plugin_libs) + list(REMOVE_DUPLICATES plugin_dirs) + fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}") + file(TOUCH "${timestamp_file}") + endif() +endif() diff --git a/cmake/Platform/Windows/RuntimeDependencies_windows.cmake b/cmake/Platform/Windows/RuntimeDependencies_windows.cmake index f90ff23b8d..add036a8b8 100644 --- a/cmake/Platform/Windows/RuntimeDependencies_windows.cmake +++ b/cmake/Platform/Windows/RuntimeDependencies_windows.cmake @@ -9,19 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_RUNTIME_DEPENDENCIES_HEADER -"function(ly_copy source_file target_directory) - get_filename_component(target_filename \"\${source_file}\" NAME) - if(NOT \"\${source_file}\" STREQUAL \"\${target_directory}/\${target_filename}\") - if(NOT EXISTS \"\${target_directory}\") - file(MAKE_DIRECTORY \"\${target_directory}\") - endif() - if(\"\${source_file}\" IS_NEWER_THAN \"\${target_directory}/\${target_filename}\") - file(LOCK \"\${CMAKE_BINARY_DIR}/runtimedependencies.lock\" GUARD FUNCTION TIMEOUT 30) - file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) - endif() - endif() -endfunction() -\n") - +set(LY_RUNTIME_DEPENDENCIES_TEMPLATE ${LY_ROOT_FOLDER}/cmake/Platform/Common/runtime_dependencies_common.cmake.in) include(cmake/Platform/Common/RuntimeDependencies_common.cmake) \ No newline at end of file From 6e2e187e31c0f91eeee6cce5da7a8310a1696dd2 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Fri, 11 Jun 2021 18:52:03 -0700 Subject: [PATCH 19/93] improve incremental --- .../Mac/runtime_dependencies_mac.cmake.in | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 8a88df86cb..58bac188fd 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -72,6 +72,7 @@ function(ly_copy source_file target_directory) file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" GUARD FUNCTION TIMEOUT 30) message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) + file(TOUCH ${target_directory}/${target_filename}) set(anything_new TRUE PARENT_SCOPE) endif() endif() @@ -85,26 +86,18 @@ endif() if(@target_file_dir@ MATCHES ".app/Contents/MacOS") string(REGEX REPLACE "(.*\\.app)/Contents/MacOS.*" "\\1" bundle_path "@target_file_dir@") + set(fixup_timestamp_file "${bundle_path}.fixup.stamp") if(NOT anything_new) - set(timestamp_file "${bundle_path}.fixup.stamp") - if(NOT EXISTS "${timestamp_file}") + if(NOT EXISTS "${fixup_timestamp_file}" OR "${bundle_path}" IS_NEWER_THAN "${fixup_timestamp_file}") set(anything_new TRUE) - else() - file(GLOB_RECURSE files_in_bundle FOLLOW_SYMLINKS "${bundle_path}") - foreach(file ${files_in_bundle}) - if(${file} IS_NEWER_THAN "${timestamp_file}") - set(anything_new TRUE) - break() - endif() - endforeach() endif() endif() if(anything_new) # LYN-4505: Patch dxc, is configured in the wrong folder in 3p if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7) - file(RENAME - ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/lib/libdxcompiler.3.7.dylib - ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/libdxcompiler.3.7.dylib + # 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 ) endif() if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) @@ -134,6 +127,7 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") list(REMOVE_DUPLICATES plugin_libs) list(REMOVE_DUPLICATES plugin_dirs) fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}") - file(TOUCH "${timestamp_file}") + file(TOUCH "${bundle_path}") + file(TOUCH "${fixup_timestamp_file}") endif() endif() From 02dd2138cb36a69689863346eb764030dc55ee62 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Mon, 14 Jun 2021 13:46:51 -0700 Subject: [PATCH 20/93] improving the check so it doesnt have to be "FALSE" (and can be 0/Off/etc) --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 58bac188fd..e67702e902 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -24,7 +24,7 @@ function(ly_copy source_file target_directory) # If source_file is a Framework and target_directory is a bundle if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) + if(NOT @LY_BUILD_FIXUP_BUNDLE@) return() endif() @@ -38,7 +38,7 @@ function(ly_copy source_file target_directory) elseif("${source_file}" MATCHES "qt/plugins" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") - if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) + if(NOT @LY_BUILD_FIXUP_BUNDLE@) return() endif() @@ -68,8 +68,10 @@ function(ly_copy source_file target_directory) if(NOT EXISTS "${target_directory}") file(MAKE_DIRECTORY "${target_directory}") endif() - if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") - file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" GUARD FUNCTION TIMEOUT 30) + if(IS_DIRECTORY ${source_file}) + message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") + file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) + elseif(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) file(TOUCH ${target_directory}/${target_filename}) @@ -80,7 +82,7 @@ endfunction() @LY_COPY_COMMANDS@ -if("@LY_BUILD_FIXUP_BUNDLE@" STREQUAL FALSE) +if(NOT @LY_BUILD_FIXUP_BUNDLE@) return() endif() From 310f1b79dd6f711eef67435ef6439e029e55373e Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Mon, 14 Jun 2021 15:45:40 -0700 Subject: [PATCH 21/93] plugins should be handled by fixup_bundle --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index e67702e902..a0b418daff 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -35,6 +35,7 @@ function(ly_copy source_file target_directory) set(local_plugin_dirs ${plugin_dirs}) list(APPEND local_plugin_dirs "${target_directory}") set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) + return() elseif("${source_file}" MATCHES "qt/plugins" AND "${target_directory}" MATCHES "\\.app/Contents/MacOS") From 411bbc8e2fd1f35b074efae51e68abb06875c4c6 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Mon, 14 Jun 2021 17:03:09 -0700 Subject: [PATCH 22/93] removed the copy of bundles since fixup_bundle does a better job --- .../Mac/runtime_dependencies_mac.cmake.in | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index a0b418daff..a51260fd3f 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -11,8 +11,6 @@ include(BundleUtilities) -#set(BU_COPY_FULL_FRAMEWORK_CONTENTS ON) - set(anything_new FALSE) set(plugin_libs) set(plugin_dirs) @@ -30,10 +28,10 @@ function(ly_copy source_file target_directory) # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}") - string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/Frameworks" target_directory "${target_directory}") - + get_filename_component(source_file_folder "${source_file}" DIRECTORY) + set(local_plugin_dirs ${plugin_dirs}) - list(APPEND local_plugin_dirs "${target_directory}") + list(APPEND local_plugin_dirs "${source_file_folder}") set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE) return() @@ -69,10 +67,7 @@ function(ly_copy source_file target_directory) if(NOT EXISTS "${target_directory}") file(MAKE_DIRECTORY "${target_directory}") endif() - if(IS_DIRECTORY ${source_file}) - message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") - file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) - elseif(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") + if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...") file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) file(TOUCH ${target_directory}/${target_filename}) @@ -103,30 +98,31 @@ if(@target_file_dir@ MATCHES ".app/Contents/MacOS") DESTINATION ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin ) endif() - if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) - # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has - # duplicated binaries between Versions/3.7 and Versions/Current. - file(GLOB exe_files - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/distutils/command/*.exe - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip/_vendor/distlib/*.exe - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/setuptools/*.exe - ) - foreach(exe_file ${exe_files}) - file(REMOVE ${exe_file}) - endforeach() - file(REMOVE_RECURSE - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Resources - ${bundle_path}/Contents/Frameworks/Python.framework/Python - ${bundle_path}/Contents/Frameworks/Python.framework/Resources/Python.app - ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Python - ) - file(REMOVE_RECURSE ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current) - execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current - WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ - ) - endif() + # Python.framework being copied by fixup_bundle + #if(EXISTS ${bundle_path}/Contents/Frameworks/Python.framework) + # # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has + # # duplicated binaries between Versions/3.7 and Versions/Current. + # file(GLOB exe_files + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/distutils/command/*.exe + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip/_vendor/distlib/*.exe + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/setuptools/*.exe + # ) + # foreach(exe_file ${exe_files}) + # file(REMOVE ${exe_file}) + # endforeach() + # file(REMOVE_RECURSE + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Resources + # ${bundle_path}/Contents/Frameworks/Python.framework/Python + # ${bundle_path}/Contents/Frameworks/Python.framework/Resources/Python.app + # ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Python + # ) + # file(REMOVE_RECURSE ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current) + # execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current + # WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/ + # ) + #endif() list(REMOVE_DUPLICATES plugin_libs) list(REMOVE_DUPLICATES plugin_dirs) fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}") From 6ea80176464db9a2c9bdcf6c799454da25e8fd80 Mon Sep 17 00:00:00 2001 From: pappeste Date: Tue, 15 Jun 2021 17:09:49 -0700 Subject: [PATCH 23/93] Update qt versions and add missing dependency --- Code/Framework/AzToolsFramework/CMakeLists.txt | 2 ++ cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake | 2 +- cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake | 2 +- cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzToolsFramework/CMakeLists.txt b/Code/Framework/AzToolsFramework/CMakeLists.txt index 53dba8eb48..661cb43302 100644 --- a/Code/Framework/AzToolsFramework/CMakeLists.txt +++ b/Code/Framework/AzToolsFramework/CMakeLists.txt @@ -85,6 +85,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) AZ::AzManipulatorTestFramework.Static AZ::AzTest AZ::AzQtComponents + RUNTIME_DEPENDENCIES + 3rdParty::Qt::Test ) ly_add_googletest( NAME AZ::AzToolsFramework.Tests diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index 3220271b42..fcc2ef4fe6 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -44,7 +44,7 @@ ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-linux ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-linux TARGETS googletest PACKAGE_HASH 7b7ad330f369450c316a4c4592d17fbb4c14c731c95bd8f37757203e8c2bbc1b) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-linux TARGETS GoogleBenchmark PACKAGE_HASH 4038878f337fc7e0274f0230f71851b385b2e0327c495fc3dd3d1c18a807928d) ly_associate_package(PACKAGE_NAME unwind-1.2.1-linux TARGETS unwind PACKAGE_HASH 3453265fb056e25432f611a61546a25f60388e315515ad39007b5925dd054a77) -ly_associate_package(PACKAGE_NAME qt-5.15.2-rev3-linux TARGETS Qt PACKAGE_HASH b7d9932647f4b138b3f0b124d70debd250d2a8a6dca52b04dcbe82c6369d48ca) +ly_associate_package(PACKAGE_NAME qt-5.15.2-rev4-linux TARGETS Qt PACKAGE_HASH 1122e0ec19b01cb02a11fcf34dbf884bc9049ba5ff04fb692bfb09d4e5ee1e6b) ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-linux TARGETS libsamplerate PACKAGE_HASH 41643c31bc6b7d037f895f89d8d8d6369e906b92eff42b0fe05ee6a100f06261) ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev2-linux TARGETS OpenSSL PACKAGE_HASH b779426d1e9c5ddf71160d5ae2e639c3b956e0fb5e9fcaf9ce97c4526024e3bc) ly_associate_package(PACKAGE_NAME DirectXShaderCompilerDxc-1.6.2104-o3de-rev2-linux TARGETS DirectXShaderCompilerDxc PACKAGE_HASH 235606f98512c076a1ba84a8402ad24ac21945998abcea264e8e204678efc0ba) diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index 3908d21ecf..b97209e8f7 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -46,5 +46,5 @@ ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-mac ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-mac TARGETS googletest PACKAGE_HASH cbf020d5ef976c5db8b6e894c6c63151ade85ed98e7c502729dd20172acae5a8) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-mac TARGETS GoogleBenchmark PACKAGE_HASH ad25de0146769c91e179953d845de2bec8ed4a691f973f47e3eb37639381f665) ly_associate_package(PACKAGE_NAME OpenSSL-1.1.1b-rev1-mac TARGETS OpenSSL PACKAGE_HASH 28adc1c0616ac0482b2a9d7b4a3a3635a1020e87b163f8aba687c501cf35f96c) -ly_associate_package(PACKAGE_NAME qt-5.15.2-rev3-mac TARGETS Qt PACKAGE_HASH 4723ac43b19d4633c3fa4b9642f27c992d30cdc689f769f82869786f1c22a728) +ly_associate_package(PACKAGE_NAME qt-5.15.2-rev4-mac TARGETS Qt PACKAGE_HASH 08790d03a0e6ad808ad64cf25c3d75abd69a343f3d224fc39927e5c6e8738b98) ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-mac TARGETS libsamplerate PACKAGE_HASH b912af40c0ac197af9c43d85004395ba92a6a859a24b7eacd920fed5854a97fe) diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 19e71f726c..eb1047c20a 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -50,7 +50,7 @@ ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-windows ly_associate_package(PACKAGE_NAME d3dx12-headers-rev1-windows TARGETS d3dx12 PACKAGE_HASH 088c637159fba4a3e4c0cf08fb4921906fd4cca498939bd239db7c54b5b2f804) ly_associate_package(PACKAGE_NAME pyside2-qt-5.15.1-rev2-windows TARGETS pyside2 PACKAGE_HASH c90f3efcc7c10e79b22a33467855ad861f9dbd2e909df27a5cba9db9fa3edd0f) ly_associate_package(PACKAGE_NAME openimageio-2.1.16.0-rev2-windows TARGETS OpenImageIO PACKAGE_HASH 85a2a6cf35cbc4c967c56ca8074babf0955c5b490c90c6e6fd23c78db99fc282) -ly_associate_package(PACKAGE_NAME qt-5.15.2-rev2-windows TARGETS Qt PACKAGE_HASH 29966f22ec253dc9904e88ad48fe6b6a669302b2dc7049f2e2bbd4949e79e595) +ly_associate_package(PACKAGE_NAME qt-5.15.2-rev4-windows TARGETS Qt PACKAGE_HASH a4634caaf48192cad5c5f408504746e53d338856148285057274f6a0ccdc071d) ly_associate_package(PACKAGE_NAME libsamplerate-0.2.1-rev2-windows TARGETS libsamplerate PACKAGE_HASH dcf3c11a96f212a52e2c9241abde5c364ee90b0f32fe6eeb6dcdca01d491829f) ly_associate_package(PACKAGE_NAME OpenMesh-8.1-rev1-windows TARGETS OpenMesh PACKAGE_HASH 1c1df639358526c368e790dfce40c45cbdfcfb1c9a041b9d7054a8949d88ee77) ly_associate_package(PACKAGE_NAME civetweb-1.8-rev1-windows TARGETS civetweb PACKAGE_HASH 36d0e58a59bcdb4dd70493fb1b177aa0354c945b06c30416348fd326cf323dd4) From 3c10db99e0e10d6a53f9fd5cf8fa7c3a4f68acac Mon Sep 17 00:00:00 2001 From: pappeste Date: Tue, 15 Jun 2021 17:45:29 -0700 Subject: [PATCH 24/93] Review cleanup --- .../Code/Platform/Windows/lrelease_windows.cmake | 16 ++++++++++++++++ cmake/Platform/iOS/PAL_ios.cmake | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake b/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake index 4d5680a30d..73e1fb82c1 100644 --- a/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake +++ b/Gems/LmbrCentral/Code/Platform/Windows/lrelease_windows.cmake @@ -8,3 +8,19 @@ # 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/cmake/Platform/iOS/PAL_ios.cmake b/cmake/Platform/iOS/PAL_ios.cmake index e9e38ac494..981bb9cab1 100644 --- a/cmake/Platform/iOS/PAL_ios.cmake +++ b/cmake/Platform/iOS/PAL_ios.cmake @@ -12,7 +12,6 @@ ly_set(PAL_EXECUTABLE_APPLICATION_FLAG MACOSX_BUNDLE) ly_set(PAL_LINKOPTION_MODULE SHARED) # For iOS, 'MODULE' creates a tool/bundle, but we treat it as a shared library -ly_set(PAL_TRAIT_BUILD_HOST_QT_SUPPORTED FALSE) ly_set(PAL_TRAIT_BUILD_HOST_GUI_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_HOST_TOOLS FALSE) ly_set(PAL_TRAIT_BUILD_SERVER_SUPPORTED FALSE) From 1121299efca512aab3c8499590e884baf085d78b Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Tue, 15 Jun 2021 18:58:23 -0700 Subject: [PATCH 25/93] Set policy to avoid warnings on runtime dependencies --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index a51260fd3f..f7e267eb2f 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -11,6 +11,8 @@ include(BundleUtilities) +cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of the LY_BUILD_FIXUP_BUNDLE expansion + set(anything_new FALSE) set(plugin_libs) set(plugin_dirs) From daacd25fc9a8a225176475a9074f7a8d9c2ef05b Mon Sep 17 00:00:00 2001 From: pappeste Date: Tue, 15 Jun 2021 19:24:13 -0700 Subject: [PATCH 26/93] change STREQUAL to cmake_path(COMPARE --- cmake/Platform/Common/runtime_dependencies_common.cmake.in | 5 ++++- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in index b476b7d401..032a6726bd 100644 --- a/cmake/Platform/Common/runtime_dependencies_common.cmake.in +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -9,9 +9,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of "if(NOT ${same_location})" + function(ly_copy source_file target_directory) get_filename_component(target_filename "${source_file}" NAME) - if(NOT "${source_file}" STREQUAL "${target_directory}/${target_filename}") + cmake_path(COMPARE "${source_file}" EQUAL "${target_directory}/${target_filename}" same_location) + if(NOT ${same_location}) if(NOT EXISTS "${target_directory}") file(MAKE_DIRECTORY "${target_directory}") endif() diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index f7e267eb2f..0a5ab59823 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -65,7 +65,8 @@ function(ly_copy source_file target_directory) endif() - if(NOT "${source_file}" STREQUAL "${target_directory}/${target_filename}") + cmake_path(COMPARE "${source_file}" EQUAL "${target_directory}/${target_filename}" same_location) + if(NOT ${same_location}) if(NOT EXISTS "${target_directory}") file(MAKE_DIRECTORY "${target_directory}") endif() From 009e96d601dec262c2c9564bf01c00be9bdc3eea Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 16 Jun 2021 10:02:36 -0700 Subject: [PATCH 27/93] fixing ly_test_tools function and unit tests --- .../managers/abstract_resource_locator.py | 39 ++++++++++++++++--- .../unit/test_abstract_resource_locator.py | 23 ++++++++--- .../tests/unit/test_builtin_helpers.py | 2 + .../tests/unit/test_manager_platforms_mac.py | 28 +++++++------ .../unit/test_manager_platforms_windows.py | 31 +++++++++------ 5 files changed, 90 insertions(+), 33 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py index ec4b43b023..c1a22e5641 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py @@ -14,7 +14,9 @@ Utility class to resolve Lumberyard directory paths & file mappings. import os import pathlib import warnings +import json from abc import ABCMeta, abstractmethod +from weakref import KeyedRef import ly_test_tools._internal.pytest_plugin from ly_test_tools.environment.file_system import find_ancestor_file @@ -50,11 +52,38 @@ def _find_project_json(engine_root, project): Find the project.json file for this project. :return: Full path to the project.json file """ - # First check relative to defined build directory, for external projects which configure through SDK settings - project_json = find_ancestor_file(target_file_name='project.json', - start_path=ly_test_tools._internal.pytest_plugin.build_directory) - if not project_json: # check internally for a project bundled with the engine - project_json = os.path.join(engine_root, project, 'project.json') + project_json = None + + # Check the o3de_manifest.json and for the "projects" key + manifest_json = os.path.join(os.path.expanduser('~'), '.o3de', 'o3de_manifest.json') + if os.path.isfile(manifest_json): + # Read the o3de_manifest.json + with open(manifest_json, "r") as manifest_file: + json_data = json.load(manifest_file) + # Look at the "projects" key for registered project paths + try: + for projects_path in json_data["projects"]: + # Only look at project directories that match our project + if project == os.path.basename(projects_path): + check_project_json = os.path.join(projects_path, 'project.json') + # Check for the project.json file inside of the project directory + if os.path.isfile(check_project_json): + project_json = check_project_json + except KeyError: + pass # No projects found in the manifest json + + # Check relative to defined build directory, for external projects which configure through SDK settings + if not project_json: + project_json = find_ancestor_file(target_file_name='project.json', + start_path=ly_test_tools._internal.pytest_plugin.build_directory) + # Check internally for a project bundled with the engine + if not project_json: + check_project_json = os.path.join(engine_root, project, 'project.json') + if os.path.isfile(check_project_json): + project_json = check_project_json + + if not project_json: + raise OSError(f"Unable to find the project directory for project: ${project}") return project_json diff --git a/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py b/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py index 12286b3dd7..a96f2a0699 100755 --- a/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py +++ b/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py @@ -24,6 +24,8 @@ mock_engine_root = "mock_engine_root" mock_dev_path = "mock_dev_path" mock_build_directory = 'mock_build_directory' mock_project = 'mock_project' +mock_manifest_json = {'projects': [mock_project]} +mock_project_json = os.path.join(mock_project, 'project.json') class TestFindEngineRoot(object): @@ -47,11 +49,24 @@ class TestFindEngineRoot(object): with pytest.raises(OSError): abstract_resource_locator._find_engine_root(mock_initial_path) +@mock.patch('builtins.open', mock.MagicMock()) +class TestFindProjectJson(object): + + @mock.patch('os.path.isfile', mock.MagicMock(return_value=True)) + @mock.patch('os.path.basename', mock.MagicMock(return_value=mock_project)) + @mock.patch('json.load', mock.MagicMock(return_value=mock_manifest_json)) + def test_FindProjectJson_ManifestJson_ReturnsProjectJson(self): + project = abstract_resource_locator._find_project_json(mock_engine_root, mock_project) + + assert project == mock_project_json + @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator.os.path.abspath', mock.MagicMock(return_value=mock_initial_path)) @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root', mock.MagicMock(return_value=mock_engine_root)) +@mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', + mock.MagicMock(return_value=os.path.join(mock_project, 'project.json'))) class TestAbstractResourceLocator(object): def test_Init_HasEngineRoot_SetsAttrs(self): @@ -93,12 +108,11 @@ class TestAbstractResourceLocator(object): assert mock_abstract_resource_locator.build_directory() == mock_build_directory - def test_Project_IsCalled_ReturnsProjectPath(self): + def test_Project_IsCalled_ReturnsProjectDir(self): mock_abstract_resource_locator = abstract_resource_locator.AbstractResourceLocator( mock_build_directory, mock_project) - expected_path = os.path.join(mock_abstract_resource_locator.engine_root(), mock_project) - assert mock_abstract_resource_locator.project() == expected_path + assert mock_abstract_resource_locator.project() == os.path.dirname(mock_project_json) def test_AssetProcessor_IsCalled_ReturnsAssetProcessorPath(self): mock_abstract_resource_locator = abstract_resource_locator.AbstractResourceLocator( @@ -168,8 +182,7 @@ class TestAbstractResourceLocator(object): def test_AutoexecFile_IsCalled_ReturnsAutoexecFilePath(self): mock_abstract_resource_locator = abstract_resource_locator.AbstractResourceLocator( mock_build_directory, mock_project) - expected_path = os.path.join(mock_abstract_resource_locator.engine_root(), - mock_abstract_resource_locator._project, + expected_path = os.path.join(mock_abstract_resource_locator._project, 'autoexec.cfg') assert mock_abstract_resource_locator.autoexec_file() == expected_path diff --git a/Tools/LyTestTools/tests/unit/test_builtin_helpers.py b/Tools/LyTestTools/tests/unit/test_builtin_helpers.py index a4ebf5acec..23a5a10bf3 100755 --- a/Tools/LyTestTools/tests/unit/test_builtin_helpers.py +++ b/Tools/LyTestTools/tests/unit/test_builtin_helpers.py @@ -68,6 +68,8 @@ class TestBuiltinHelpers(object): assert type(under_test) == expected_workspace + @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', + mock.MagicMock(return_value='mock_project')) @mock.patch('ly_test_tools._internal.managers.workspace.AbstractWorkspaceManager', mock.MagicMock(return_value=MockedWorkspaceManager)) @mock.patch('ly_test_tools.builtin.helpers.MAC', True) diff --git a/Tools/LyTestTools/tests/unit/test_manager_platforms_mac.py b/Tools/LyTestTools/tests/unit/test_manager_platforms_mac.py index bbd8fbf9ae..0acf6457d9 100755 --- a/Tools/LyTestTools/tests/unit/test_manager_platforms_mac.py +++ b/Tools/LyTestTools/tests/unit/test_manager_platforms_mac.py @@ -14,6 +14,7 @@ Unit tests for ly_test_tools._internal.managers.platforms.mac import unittest.mock as mock import os import pytest +import ly_test_tools from ly_test_tools._internal.managers.platforms.mac import ( _MacResourceLocator, MacWorkspaceManager, @@ -22,11 +23,6 @@ from ly_test_tools import MAC pytestmark = pytest.mark.SUITE_smoke -if not MAC: - pytestmark = pytest.mark.skipif( - not MAC, - reason="test_manager_platforms_mac.py only runs on Mac") - mock_engine_root = 'mock_engine_root' mock_dev_path = 'mock_dev_path' mock_build_directory = 'mock_build_directory' @@ -34,16 +30,16 @@ mock_project = 'mock_project' mock_tmp_path = 'mock_tmp_path' mock_output_path = 'mock_output_path' -mac_resource_locator = _MacResourceLocator( - build_directory=mock_build_directory, - project=mock_project) - @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root', - mock.MagicMock(return_value=(mock_engine_root, mock_dev_path))) + mock.MagicMock(return_value=mock_engine_root)) +@mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', + mock.MagicMock(return_value=mock_project)) class TestMacResourceLocator(object): def test_PlatformConfigFile_HasPath_ReturnsPath(self): + mac_resource_locator = ly_test_tools._internal.managers.platforms.mac._MacResourceLocator(mock_build_directory, + mock_project) expected = os.path.join( mac_resource_locator.engine_root(), CONFIG_FILE) @@ -51,6 +47,8 @@ class TestMacResourceLocator(object): assert mac_resource_locator.platform_config_file() == expected def test_PlatformCache_HasPath_ReturnsPath(self): + mac_resource_locator = ly_test_tools._internal.managers.platforms.mac._MacResourceLocator(mock_build_directory, + mock_project) expected = os.path.join( mac_resource_locator.project_cache(), CACHE_DIR) @@ -58,6 +56,8 @@ class TestMacResourceLocator(object): assert mac_resource_locator.platform_cache() == expected def test_ProjectLog_HasPath_ReturnsPath(self): + mac_resource_locator = ly_test_tools._internal.managers.platforms.mac._MacResourceLocator(mock_build_directory, + mock_project) expected = os.path.join( mac_resource_locator.project(), 'user', @@ -66,6 +66,8 @@ class TestMacResourceLocator(object): assert mac_resource_locator.project_log() == expected def test_ProjectScreenshots_HasPath_ReturnsPath(self): + mac_resource_locator = ly_test_tools._internal.managers.platforms.mac._MacResourceLocator(mock_build_directory, + mock_project) expected = os.path.join( mac_resource_locator.project(), 'user', @@ -74,6 +76,8 @@ class TestMacResourceLocator(object): assert mac_resource_locator.project_screenshots() == expected def test_EditorLog_HasPath_ReturnsPath(self): + mac_resource_locator = ly_test_tools._internal.managers.platforms.mac._MacResourceLocator(mock_build_directory, + mock_project) expected = os.path.join( mac_resource_locator.project_log(), 'editor.log') @@ -82,7 +86,9 @@ class TestMacResourceLocator(object): @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root', - mock.MagicMock(return_value=(mock_engine_root, mock_dev_path))) + mock.MagicMock(return_value=mock_engine_root)) +@mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', + mock.MagicMock(return_value=mock_project)) class TestMacWorkspaceManager(object): def test_Init_SetDummyParams_ReturnsMacWorkspaceManager(self): diff --git a/Tools/LyTestTools/tests/unit/test_manager_platforms_windows.py b/Tools/LyTestTools/tests/unit/test_manager_platforms_windows.py index aaf34367e7..93ca9e3c07 100755 --- a/Tools/LyTestTools/tests/unit/test_manager_platforms_windows.py +++ b/Tools/LyTestTools/tests/unit/test_manager_platforms_windows.py @@ -14,6 +14,7 @@ Unit tests for ly_test_tools._internal.managers.platforms.windows import unittest.mock as mock import os import pytest +import ly_test_tools from ly_test_tools._internal.managers.platforms.windows import ( _WindowsResourceLocator, WindowsWorkspaceManager, @@ -34,22 +35,16 @@ mock_project = 'mock_project' mock_tmp_path = 'mock_tmp_path' mock_output_path = 'mock_output_path' -windows_resource_locator = _WindowsResourceLocator( - build_directory=mock_build_directory, - project=mock_project) - -windows_workspace_manager = WindowsWorkspaceManager( - build_directory=mock_build_directory, - project=mock_project, - tmp_path=mock_tmp_path, - output_path=mock_output_path) - @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root', - mock.MagicMock(return_value=(mock_engine_root, mock_dev_path))) + mock.MagicMock(return_value=mock_engine_root)) +@mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', mock.MagicMock( + return_value=mock_project)) class TestWindowsResourceLocator(object): def test_PlatformConfigFile_HasPath_ReturnsPath(self): + windows_resource_locator = ly_test_tools._internal.managers.platforms.windows._WindowsResourceLocator( + mock_build_directory, mock_project) expected = os.path.join( windows_resource_locator.engine_root(), CONFIG_FILE) @@ -57,12 +52,16 @@ class TestWindowsResourceLocator(object): assert windows_resource_locator.platform_config_file() == expected def test_PlatformCache_HasPath_ReturnsPath(self): + windows_resource_locator = ly_test_tools._internal.managers.platforms.windows._WindowsResourceLocator( + mock_build_directory, mock_project) expected = os.path.join( windows_resource_locator.project_cache(), CACHE_DIR) assert windows_resource_locator.platform_cache() == expected def test_ProjectLog_HasPath_ReturnsPath(self): + windows_resource_locator = ly_test_tools._internal.managers.platforms.windows._WindowsResourceLocator( + mock_build_directory, mock_project) expected = os.path.join( windows_resource_locator.project(), 'user', @@ -71,6 +70,8 @@ class TestWindowsResourceLocator(object): assert windows_resource_locator.project_log() == expected def test_ProjectScreenshots_HasPath_ReturnsPath(self): + windows_resource_locator = ly_test_tools._internal.managers.platforms.windows._WindowsResourceLocator( + mock_build_directory, mock_project) expected = os.path.join( windows_resource_locator.project(), 'user', @@ -79,6 +80,8 @@ class TestWindowsResourceLocator(object): assert windows_resource_locator.project_screenshots() == expected def test_EditorLog_HasPath_ReturnsPath(self): + windows_resource_locator = ly_test_tools._internal.managers.platforms.windows._WindowsResourceLocator( + mock_build_directory, mock_project) expected = os.path.join( windows_resource_locator.project_log(), 'editor.log') @@ -87,17 +90,21 @@ class TestWindowsResourceLocator(object): @mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_engine_root', - mock.MagicMock(return_value=(mock_engine_root, mock_dev_path))) + mock.MagicMock(return_value=mock_engine_root)) +@mock.patch('ly_test_tools._internal.managers.abstract_resource_locator._find_project_json', mock.MagicMock( + return_value=mock_project)) class TestWindowsWorkspaceManager(object): @mock.patch('ly_test_tools.environment.reg_cleaner.create_ly_keys') def test_SetRegistryKeys_NewWorkspaceManager_KeyCreateCalled(self, mock_create_keys): + windows_workspace_manager = ly_test_tools._internal.managers.platforms.windows.WindowsWorkspaceManager() windows_workspace_manager.set_registry_keys() mock_create_keys.assert_called_once() @mock.patch('ly_test_tools.environment.reg_cleaner.clean_ly_keys') def test_ClearSettings_NewWorkspaceManager_KeyClearCalled(self, mock_clear_keys): + windows_workspace_manager = ly_test_tools._internal.managers.platforms.windows.WindowsWorkspaceManager() windows_workspace_manager.clear_settings() mock_clear_keys.assert_called_with(exception_list=r"SOFTWARE\Amazon\Lumberyard\Identity") From 017845e285e7fb58996abac4164ddcaf9d007541 Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 16 Jun 2021 11:29:14 -0700 Subject: [PATCH 28/93] fixing project() func to read project.json --- .../managers/abstract_resource_locator.py | 15 +++++++++------ .../tests/unit/test_abstract_resource_locator.py | 5 +++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py index c1a22e5641..a7a1c867f6 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py @@ -63,12 +63,15 @@ def _find_project_json(engine_root, project): # Look at the "projects" key for registered project paths try: for projects_path in json_data["projects"]: - # Only look at project directories that match our project - if project == os.path.basename(projects_path): - check_project_json = os.path.join(projects_path, 'project.json') - # Check for the project.json file inside of the project directory - if os.path.isfile(check_project_json): - project_json = check_project_json + check_project_json = os.path.join(projects_path, 'project.json') + # Check for the project.json file inside of the project directory + if os.path.isfile(check_project_json): + # Check if the "project_name" key matches our project + with open(check_project_json, "r") as project_json_file: + project_json_data = json.load(project_json_file) + if project == project_json_data["project_name"]: + project_json = check_project_json + break except KeyError: pass # No projects found in the manifest json diff --git a/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py b/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py index a96f2a0699..d8e4e5a14a 100755 --- a/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py +++ b/Tools/LyTestTools/tests/unit/test_abstract_resource_locator.py @@ -24,7 +24,8 @@ mock_engine_root = "mock_engine_root" mock_dev_path = "mock_dev_path" mock_build_directory = 'mock_build_directory' mock_project = 'mock_project' -mock_manifest_json = {'projects': [mock_project]} +mock_manifest_json_file = {'projects': [mock_project]} +mock_project_json_file = {'project_name': mock_project} mock_project_json = os.path.join(mock_project, 'project.json') @@ -54,7 +55,7 @@ class TestFindProjectJson(object): @mock.patch('os.path.isfile', mock.MagicMock(return_value=True)) @mock.patch('os.path.basename', mock.MagicMock(return_value=mock_project)) - @mock.patch('json.load', mock.MagicMock(return_value=mock_manifest_json)) + @mock.patch('json.load', mock.MagicMock(side_effect=[mock_manifest_json_file, mock_project_json_file])) def test_FindProjectJson_ManifestJson_ReturnsProjectJson(self): project = abstract_resource_locator._find_project_json(mock_engine_root, mock_project) From 5e64586030ce17956921c3557492b8c67a52fb73 Mon Sep 17 00:00:00 2001 From: Esteban Papp Date: Wed, 16 Jun 2021 13:39:31 -0700 Subject: [PATCH 29/93] Handle a bug where gp_resolve_item picks up a header file instead of the binary for qt frameworks --- cmake/Platform/Mac/runtime_dependencies_mac.cmake.in | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in index 0a5ab59823..6ad428c08d 100644 --- a/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in +++ b/cmake/Platform/Mac/runtime_dependencies_mac.cmake.in @@ -9,6 +9,17 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +function(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var) + # Qt frameworks could resolve the binary to eg qt/lib/QtCore.framework/Headers/QtCore instead of qt/lib/QtCore.framework/Versions/5/QtCore + # This is because GetPrerequisites.cmake gp_resolve_item function searches for the first file that matches the "frameworks name" + if(${${resolved_var}} AND ${item} MATCHES "/(Qt[^\\.]+\\.framework)/(.*)") + set(qt_framework ${CMAKE_MATCH_1}) + set(qt_framework_subpath ${CMAKE_MATCH_2}) + string(REGEX REPLACE "(.*)/(Qt[^\\.]+\\.framework)/(.*)" "\\1/\\2/${qt_framework_subpath}" new_resolved_item "${${resolved_item_var}}") + set(${resolved_item_var} ${new_resolved_item} PARENT_SCOPE) + endif() +endfunction() + include(BundleUtilities) cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of the LY_BUILD_FIXUP_BUNDLE expansion From c7a0e7b930cc78a71e6e583c6d26b190da0ccc89 Mon Sep 17 00:00:00 2001 From: stramer Date: Mon, 31 May 2021 14:52:50 -0700 Subject: [PATCH 30/93] [LYN-4366] Add API documentation for AzNetworking, Mutiplayer Gem, and Multiplayer Compression Gem classes. Signed-off-by: stramer --- .../ConnectionLayer/IConnection.h | 6 +++ .../ConnectionLayer/IConnectionListener.h | 6 +++ .../ConnectionLayer/IConnectionSet.h | 5 ++ .../AzNetworking/Framework/ICompressor.h | 26 +++++++--- .../Framework/INetworkInterface.h | 11 +++- .../AzNetworking/Framework/INetworking.h | 11 ++++ .../AzNetworking/PacketLayer/IPacket.h | 9 ++++ .../AzNetworking/PacketLayer/IPacketHeader.h | 13 +++++ .../AzNetworking/Serialization/ISerializer.h | 12 +++++ .../TcpTransport/TcpNetworkInterface.h | 38 ++++++++++++++ .../UdpTransport/UdpNetworkInterface.h | 52 +++++++++++++++++-- .../Code/Include/Multiplayer/IMultiplayer.h | 27 +++++++--- .../Include/Multiplayer/IMultiplayerTools.h | 10 ++-- 13 files changed, 207 insertions(+), 19 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 4ef8ca44d4..53505c556f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -44,6 +44,12 @@ namespace AzNetworking //! @class IConnection //! @brief interface class for network connections. + //! + //! IConnection provides a pure-virtual interface for all network connection types. The two child classes are TcpConnection + //! and UdpConnection, though the pure-virtual interface operates largely the same for both. 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..80f4aa153b 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 currently supported on Udp and Tcp 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..4669187906 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 exempted 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/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 579ca195e5..50d52abf54 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; @@ -49,7 +49,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 + //! MultiplayerSystemsComponent 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: From c360e29fbf32e738b4e549a7444b12edc5ef86d8 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 16 Jun 2021 13:57:17 -0700 Subject: [PATCH 31/93] Fixed compile errors from Clang. --- .../Json/JsonSerializerConformityTests.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index f45e0a3658..1dcf8e29c6 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -200,7 +200,7 @@ namespace JsonSerializationTests descriptor->ConfigureFeatures(this->m_features); descriptor->Reflect(this->m_serializeContext); descriptor->Reflect(this->m_jsonRegistrationContext); - this->m_serializeContext->Class()->Field("Value", &PointerWrapper::m_value); + this->m_serializeContext->template Class()->Field("Value", &PointerWrapper::m_value); this->m_deserializationSettings->m_reporting = &Internal::VerifyCallback; this->m_serializationSettings->m_reporting = &Internal::VerifyCallback; @@ -221,7 +221,7 @@ namespace JsonSerializationTests this->m_jsonRegistrationContext->DisableRemoveReflection(); this->m_serializeContext->EnableRemoveReflection(); - this->m_serializeContext->Class()->Field("Value", &PointerWrapper::m_value); + this->m_serializeContext->template Class()->Field("Value", &PointerWrapper::m_value); descriptor->Reflect(this->m_serializeContext); this->m_serializeContext->DisableRemoveReflection(); @@ -731,13 +731,13 @@ namespace JsonSerializationTests if (this->m_features.m_enableNewInstanceTests) { AZ::SerializeContext* serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); - const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid()); + const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid()); ASSERT_NE(nullptr, classData); // Skip this test if the target type doesn't have a factor to create a new instance with or if the factor explicit // prohibits construction. if (classData->m_factory && classData->m_factory != AZ::Internal::NullFactory::GetInstance()) { - PointerWrapper instance; + typename JsonSerializerConformityTests::PointerWrapper instance; auto compare = this->m_description.CreateDefaultInstance(); this->m_jsonDocument->Parse(R"({ "Value": {}})"); @@ -767,7 +767,7 @@ namespace JsonSerializationTests if ((serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) == BaseJsonSerializer::OperationFlags::InitializeNewInstance) { - Type instance; + typename TypeParam::Type instance; auto compare = this->m_description.CreateDefaultInstance(); this->m_jsonDocument->SetObject(); @@ -1206,7 +1206,7 @@ namespace JsonSerializationTests if (this->m_features.m_enableInitializationTest) { auto instance = this->m_description.CreateDefaultInstance(); - Type compare; + typename TypeParam::Type compare; if (!this->m_description.AreEqual(*instance, compare)) { auto serializer = this->m_description.CreateSerializer(); From cf7f1defebad748776b1f7d3e4cafd1eaf19bdec Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 16 Jun 2021 14:45:11 -0700 Subject: [PATCH 32/93] added warning message --- .../_internal/managers/abstract_resource_locator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py index a7a1c867f6..48afeb8219 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/managers/abstract_resource_locator.py @@ -15,12 +15,14 @@ import os import pathlib import warnings import json +import logging from abc import ABCMeta, abstractmethod from weakref import KeyedRef import ly_test_tools._internal.pytest_plugin from ly_test_tools.environment.file_system import find_ancestor_file +logger = logging.getLogger(__name__) def _find_engine_root(initial_path): # type: (str) -> str @@ -72,8 +74,8 @@ def _find_project_json(engine_root, project): if project == project_json_data["project_name"]: project_json = check_project_json break - except KeyError: - pass # No projects found in the manifest json + except KeyError as err: + logger.warning(f"Project key could not be found due to error: {err}") # Check relative to defined build directory, for external projects which configure through SDK settings if not project_json: From 8921edb954f93adf51f8186d205f375e816c01fd Mon Sep 17 00:00:00 2001 From: pereslav Date: Wed, 16 Jun 2021 23:58:07 +0100 Subject: [PATCH 33/93] Fixed crash when BlastFamilyComponent is used on an entity with no render mesh data --- .../Components/BlastFamilyComponent.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp index 1da9663b8f..bf1f3bc5af 100644 --- a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp +++ b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp @@ -286,9 +286,13 @@ namespace Blast // Create damage and actor render managers m_damageManager = AZStd::make_unique(blastMaterial, m_family->GetActorTracker()); - m_actorRenderManager = AZStd::make_unique( - AZ::RPI::Scene::GetFeatureProcessorForEntity(GetEntityId()), - m_meshDataComponent, GetEntityId(), m_blastAsset->GetPxAsset()->getChunkCount(), AZ::Vector3(transform.GetUniformScale())); + + if (m_meshDataComponent) + { + m_actorRenderManager = AZStd::make_unique( + AZ::RPI::Scene::GetFeatureProcessorForEntity(GetEntityId()), + m_meshDataComponent, GetEntityId(), m_blastAsset->GetPxAsset()->getChunkCount(), AZ::Vector3(transform.GetUniformScale())); + } // Spawn the family m_family->Spawn(transform); @@ -540,7 +544,11 @@ namespace Blast void BlastFamilyComponent::OnActorCreated([[maybe_unused]] const BlastFamily& family, const BlastActor& actor) { - m_actorRenderManager->OnActorCreated(actor); + if (m_actorRenderManager) + { + m_actorRenderManager->OnActorCreated(actor); + } + m_solver->notifyActorCreated(*actor.GetTkActor().getActorLL()); if (auto* physicsSystem = AZ::Interface::Get()) @@ -576,7 +584,11 @@ namespace Blast } m_solver->notifyActorDestroyed(*actor.GetTkActor().getActorLL()); - m_actorRenderManager->OnActorDestroyed(actor); + + if (m_actorRenderManager) + { + m_actorRenderManager->OnActorDestroyed(actor); + } } // Update positions of entities with render meshes corresponding to their right dynamic bodies. From ddc60041d345e97ebd2a62683cd99166ed7295db Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 16 Jun 2021 16:40:46 -0700 Subject: [PATCH 34/93] Addressing PR feedback --- .../Json/BasicContainerSerializer.cpp | 2 +- .../AzCore/Serialization/Json/DoubleSerializer.cpp | 2 +- .../AzCore/Serialization/Json/TupleSerializer.cpp | 14 +++++++------- .../AzCore/Tests/AssetJsonSerializerTests.cpp | 6 +++--- .../Serialization/Json/ArraySerializerTests.cpp | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index 4eb4748eb5..d61366413f 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -255,7 +255,7 @@ namespace AZ size_t addedCount = container->Size(outputValue) - containerSize; if (addedCount > 0) { - // Values were added which means the container is no longer in its default state of being emtpy. + // Values were added which means the container is no longer in its default state of being empty. retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); } AZStd::string_view message = diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp index 14f2eaae6f..be885dfaa9 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp @@ -73,7 +73,7 @@ namespace AZ if (isExplicitDefault) { *outputValue = 0.0f; - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Double value set to default of 0.0."); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Floating point value set to default of 0.0."); } switch (inputValue.GetType()) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp index fd8951517a..e8a6f549a7 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp @@ -170,13 +170,6 @@ namespace AZ }; container->EnumTypes(typeCountCallback); - rapidjson::SizeType arraySize = isNewInstance ? typeCount : inputValue.Size(); - if (arraySize < typeCount) - { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, - "Not enough entries in array to load an AZStd::pair or AZStd::tuple from."); - } - AZStd::vector classElements; classElements.reserve(typeCount); auto typeEnumCallback = [&classElements](const Uuid&, const SerializeContext::ClassElement* genericClassElement) @@ -214,6 +207,13 @@ namespace AZ } else { + if (inputValue.Size() < typeCount) + { + return context.Report( + JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, + "Not enough entries in array to load an AZStd::pair or AZStd::tuple from."); + } + rapidjson::SizeType arrayIndex = 0; size_t numElementsWritten = 0; for (size_t i = 0; i < typeCount; ++i) diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index ceff314c81..47dba62ec8 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -168,9 +168,9 @@ namespace JsonSerializationTests { features.EnableJsonType(rapidjson::kObjectType); features.m_typeToInject = rapidjson::kNullType; - // The type information in the Serialize Context is incomplete so this test will fail. - // This is because assets have traditionally been treated as a special case, so there's - // information missing in the Json Serialization to deal with these. + // Assets are not fully registered with the Serialize Context for historical reasons. Due to the missing + // information the Json Serializer Conformity Tests can't run the subsection of tests that explicitly + // require the missing information. features.m_enableNewInstanceTests = false; } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp index 1f39feccbd..f696a9d270 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp @@ -257,7 +257,7 @@ namespace JsonSerializationTests { Base::ConfigureFeatures(features); // These tests don't work with pointers because there'll be a random value in the pointer - // which the Json Serialization try to delete. The POD version of these tests already cover + // which the Json Serialization will try to delete. The POD version of these tests already cover // these cases. features.m_enableNewInstanceTests = false; } From 62c70035f4e49eeda9b6f60abaec77ac5c27fd34 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Wed, 16 Jun 2021 16:48:25 -0700 Subject: [PATCH 36/93] Change Editor Window name for Developer Preview (#1371) --- Code/Sandbox/Editor/CryEdit.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index 67e228a3ce..fdeb8ce28e 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -4060,17 +4060,10 @@ void CCryEditApp::SetEditorWindowTitle(QString sTitleStr, QString sPreTitleStr, { if (MainWindow::instance() || m_pConsoleDialog) { - QString platform = ""; - -#ifdef WIN64 - platform = "[x64]"; -#else - platform = "[x86]"; -#endif //WIN64 if (sTitleStr.isEmpty()) { - sTitleStr = QObject::tr("Open 3D Engine Editor Beta %1 - Build %2").arg(platform).arg(LY_BUILD); + sTitleStr = QObject::tr("O3DE Editor [Developer Preview]"); } if (!sPreTitleStr.isEmpty()) From 7b0d2aac03c4d78b53e109a5203afbcd4b676af8 Mon Sep 17 00:00:00 2001 From: Qing Tao <55564570+VickyAtAZ@users.noreply.github.com> Date: Wed, 16 Jun 2021 17:00:41 -0700 Subject: [PATCH 37/93] Fixed potential crash if an attachment binding doesn't connect to an attachment. (#1373) --- Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp index 3e52130f6f..fa10e1a454 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/RenderPass.cpp @@ -61,6 +61,11 @@ namespace AZ { const PassAttachmentBinding& binding = m_attachmentBindings[slotIndex]; + if (!binding.m_attachment) + { + continue; + } + // Handle the depth-stencil attachment. There should be only one. if (binding.m_scopeAttachmentUsage == RHI::ScopeAttachmentUsage::DepthStencil) { @@ -98,6 +103,10 @@ namespace AZ { continue; } + if (!binding.m_attachment) + { + continue; + } if (binding.m_scopeAttachmentUsage == RHI::ScopeAttachmentUsage::RenderTarget || binding.m_scopeAttachmentUsage == RHI::ScopeAttachmentUsage::DepthStencil) From b176697ce9b18d009a2a06fe0199c82ba8c54e0b Mon Sep 17 00:00:00 2001 From: Chris Santora Date: Wed, 16 Jun 2021 17:04:49 -0700 Subject: [PATCH 38/93] Fixed ATOM-14613 Baseviewer MatertialHotReloadTest fails to change the color after turning blending on and off The problem was... After a MaterialAsset reload, there could be two different versions of the MaterialAsset in memory: the old one and the reloaded one. The old one is still connected to buses and can send reinitialization messages when other things reload or reinitialize. So when the shader asset reloaded, both the old and new MaterialAsset were sending reinitialization messages. Material::OnMaterialAssetReinitialized was using the materialAsset parameter to initialize the Material, and the latest call to OnMaterialAssetReinitialized was for the *old* MaterialAsset. The solution is to use the m_materialAsset member when reinitializing the Material. I also added checks in a couple places to skip unnecessary reinitialization, and added comments in the bus headers to warn developers about this issue. Testing: Added a new step to ASV's MaterialHotReloadTest.bv.lua script for the error scenario, and this now passes. Ran ASV full test suite, both dx12 and vulkan, only known issues occurred. --- .../Material/MaterialReloadNotificationBus.h | 5 +++++ .../Shader/ShaderReloadNotificationBus.h | 5 +++++ .../Source/RPI.Public/Material/Material.cpp | 14 ++++++++++---- .../Code/Source/RPI.Public/Shader/Shader.cpp | 11 ++++++++--- .../RPI.Reflect/Material/MaterialAsset.cpp | 17 ++++++++++++----- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h index c28f6a3233..881b40b785 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h @@ -24,6 +24,11 @@ namespace AZ //! Connect to this EBus to get notifications whenever material objects reload. //! The bus address is the AssetId of the MaterialAsset or MaterialTypeAsset. + //! + //! Be careful when using the parameters provided by these functions. The bus ID is an AssetId, and it's possible for the system to have + //! both *old* versions and *new reloaded* versions of the asset in memory at the same time, and they will have the same AssetId. Therefore + //! your bus Handlers could receive Reinitialized messages from multiple sources. It may be necessary to check the memory addresses of these + //! parameters against local members before using this data. class MaterialReloadNotifications : public EBusTraits { diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h index c63ba8f5b5..8ea34187ff 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h @@ -27,6 +27,11 @@ namespace AZ /** * Connect to this EBus to get notifications whenever a shader system class reinitializes itself. * The bus address is the AssetId of the ShaderAsset, even when the thing being reinitialized is a ShaderVariant or other shader related class. + * + * Be careful when using the parameters provided by these functions. The bus ID is an AssetId, and it's possible for the system to have + * both *old* versions and *new reloaded* versions of the asset in memory at the same time, and they will have the same AssetId. Therefore + * your bus Handlers could receive Reinitialized messages from multiple sources. It may be necessary to check the memory addresses of these + * parameters against local members before using this data. */ class ShaderReloadNotifications : public EBusTraits diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp index e134b701ac..3302190156 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Material/Material.cpp @@ -242,8 +242,16 @@ namespace AZ // MaterialReloadNotificationBus overrides... void Material::OnMaterialAssetReinitialized(const Data::Asset& materialAsset) { - ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Material::OnMaterialAssetReinitialized %s", this, materialAsset.GetHint().c_str()); - OnAssetReloaded(materialAsset); + // It's important that we don't just pass materialAsset to Init() because when reloads occur, + // it's possible for old Asset objects to hang around and report reinitialization, so materialAsset + // might be stale data. + + if (materialAsset.Get() == m_materialAsset.Get()) + { + ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Material::OnMaterialAssetReinitialized %s", this, materialAsset.GetHint().c_str()); + + OnAssetReloaded(m_materialAsset); + } } /////////////////////////////////////////////////////////////////// @@ -259,8 +267,6 @@ namespace AZ void Material::OnShaderAssetReinitialized(const Data::Asset& shaderAsset) { - // TODO: I think we should make Shader handle OnShaderAssetReinitialized and treat it just like the shader reloaded. - ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Material::OnShaderAssetReinitialized %s", this, shaderAsset.GetHint().c_str()); // Note that it might not be strictly necessary to reinitialize the entire material, we might be able to get away with // just bumping the m_currentChangeId or some other minor updates. But it's pretty hard to know what exactly needs to be diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp index 6f65bd75c9..f451064450 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Shader.cpp @@ -213,10 +213,15 @@ namespace AZ // ShaderReloadNotificationBus overrides... void Shader::OnShaderAssetReinitialized(const Data::Asset& shaderAsset) { - ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Shader::OnShaderAssetReinitialized %s", this, shaderAsset.GetHint().c_str()); + // When reloads occur, it's possible for old Asset objects to hang around and report reinitialization, + // so we can reduce unnecessary reinitialization in that case. + if (shaderAsset.Get() == m_asset.Get()) + { + ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->Shader::OnShaderAssetReinitialized %s", this, shaderAsset.GetHint().c_str()); - Init(*m_asset.Get()); - ShaderReloadNotificationBus::Event(shaderAsset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this); + Init(*m_asset.Get()); + ShaderReloadNotificationBus::Event(shaderAsset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderReinitialized, *this); + } } /////////////////////////////////////////////////////////////////// diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index b8567b12c5..7446c498cd 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -115,12 +115,19 @@ namespace AZ } } - void MaterialAsset::OnMaterialTypeAssetReinitialized(const Data::Asset&) + void MaterialAsset::OnMaterialTypeAssetReinitialized(const Data::Asset& materialTypeAsset) { - // MaterialAsset doesn't need to reinitialize any of its own data when MaterialTypeAsset reinitializes, - // because all it depends on is the MaterialTypeAsset reference, rather than the data inside it. - // Ultimately it's the Material that cares about these changes, so we just forward any signal we get. - MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialAssetReinitialized, Data::Asset{this, AZ::Data::AssetLoadBehavior::PreLoad}); + // When reloads occur, it's possible for old Asset objects to hang around and report reinitialization, + // so we can reduce unnecessary reinitialization in that case. + if (materialTypeAsset.Get() == m_materialTypeAsset.Get()) + { + ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnMaterialTypeAssetReinitialized %s", this, materialTypeAsset.GetHint().c_str()); + + // MaterialAsset doesn't need to reinitialize any of its own data when MaterialTypeAsset reinitializes, + // because all it depends on is the MaterialTypeAsset reference, rather than the data inside it. + // Ultimately it's the Material that cares about these changes, so we just forward any signal we get. + MaterialReloadNotificationBus::Event(GetId(), &MaterialReloadNotifications::OnMaterialAssetReinitialized, Data::Asset{this, AZ::Data::AssetLoadBehavior::PreLoad}); + } } void MaterialAsset::ReinitializeMaterialTypeAsset(Data::Asset asset) From c482c17c9ec97e2855c945e7ace7dde9a24afdab Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 16 Jun 2021 17:14:44 -0700 Subject: [PATCH 39/93] Fixed an issue with the new Json Serializer Conformity tests and Atom's materials --- .../Serialization/Json/JsonSerializerConformityTests.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index 1dcf8e29c6..4931c203cf 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -68,7 +68,7 @@ namespace JsonSerializationTests bool m_enableInitializationTest{ true }; //! Enable the test that creates a new instance of the provided test type through the factory that's found in //! the Serialize Context. This test is automatically disabled for classes that don't have a factory or - //! have a null factory. + //! have a null factory as well as for classes that have mandatory fields. bool m_enableNewInstanceTests{ true }; private: @@ -728,7 +728,7 @@ namespace JsonSerializationTests { using namespace AZ::JsonSerializationResult; - if (this->m_features.m_enableNewInstanceTests) + if (this->m_features.m_enableNewInstanceTests && this->m_features.m_mandatoryFields.empty()) { AZ::SerializeContext* serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid()); @@ -761,7 +761,7 @@ namespace JsonSerializationTests using namespace AZ; using namespace AZ::JsonSerializationResult; - if (this->m_features.m_enableNewInstanceTests) + if (this->m_features.m_enableNewInstanceTests && this->m_features.m_mandatoryFields.empty()) { auto serializer = this->m_description.CreateSerializer(); if ((serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) == From 1b1a5a28f46689552c7d09b327f5665bb06f878f Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 16 Jun 2021 17:26:14 -0700 Subject: [PATCH 40/93] Using zero-initializer for defaults in the Json Serializer instead of explicit values --- .../AzCore/AzCore/Serialization/Json/BoolSerializer.cpp | 2 +- .../AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp | 2 +- .../AzCore/AzCore/Serialization/Json/IntSerializer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp index defe470bcf..3a9b5323b0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp @@ -84,7 +84,7 @@ namespace AZ if (IsExplicitDefault(inputValue)) { - *valAsBool = false; + *valAsBool = {}; return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Boolean value set to default of 'false'."); } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp index be885dfaa9..0921587041 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp @@ -72,7 +72,7 @@ namespace AZ if (isExplicitDefault) { - *outputValue = 0.0f; + *outputValue = {}; return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Floating point value set to default of 0.0."); } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp index ebc99fd8c4..a6b1118ac1 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp @@ -67,7 +67,7 @@ namespace AZ if (isDefaultValue) { - *outputValue = 0; + *outputValue = {}; return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Integer value set to default of zero."); } From 1097cb7ce386c0c331f61060402fa9091695f64d Mon Sep 17 00:00:00 2001 From: galibzon <66021303+galibzon@users.noreply.github.com> Date: Wed, 16 Jun 2021 20:56:39 -0500 Subject: [PATCH 41/93] [ATOM-14935] MaterialHotReloadTest Fails On Second Try (#1384) [ATOM-14544] Add Reset() function to IShaderVariantFinder ShaderVariantAsyncLoader::Reset() now Shutdown and Init(). It clears the cache of ShaderVariantAssets it keeps in memory. Signed-off-by: garrieta --- .../Source/RPI.Public/Shader/ShaderVariantAsyncLoader.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariantAsyncLoader.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariantAsyncLoader.cpp index 3fc2bbd197..24f6fa60fa 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariantAsyncLoader.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariantAsyncLoader.cpp @@ -323,9 +323,8 @@ namespace AZ void ShaderVariantAsyncLoader::Reset() { - // [GFX TODO ATOM-14544] Idealy we want to be able to reset the ShaderVariantAsyncLoader but this is causing some problems that need to be worked out first. - //Shutdown(); - //Init(); + Shutdown(); + Init(); } /////////////////////////////////////////////////////////////////// From 709bca5849f2d06dc6611dee6babf1640e1f491b Mon Sep 17 00:00:00 2001 From: mriegger Date: Wed, 16 Jun 2021 20:15:08 -0700 Subject: [PATCH 42/93] Adding code that prevents nans occuring due to precision issues --- .../Common/Assets/ShaderLib/Atom/Features/Shadow/Shadow.azsli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/Shadow.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/Shadow.azsli index d267a74b36..138ea38562 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/Shadow.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/Shadow.azsli @@ -79,9 +79,9 @@ float4 Shadow::GetJitterUnitVectorDepthDiffBase( return float4(0., 0., 0., 0.); } const float3 v_M = v_M0 / v_M0_length; - const float cosTheta = dot(normalVector, v_M); + const float cosTheta = saturate(dot(normalVector, v_M)); const float sinTheta = sqrt(1 - cosTheta * cosTheta); - if (sinTheta == 0.) + if (sinTheta < 0.001) { return float4(0., 0., 0., 0.); } From 58d516688f31da9751ff26687aad725ed7e8ae25 Mon Sep 17 00:00:00 2001 From: guthadam Date: Wed, 16 Jun 2021 22:57:20 -0500 Subject: [PATCH 43/93] LYN-4251 fix confusing material component menu options --- .../Material/EditorMaterialComponent.cpp | 5 +++- .../EditorMaterialComponentExporter.cpp | 2 +- .../Material/EditorMaterialComponentSlot.cpp | 24 +++++++------------ 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponent.cpp index e307bfcd07..80de8b03e4 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponent.cpp @@ -32,7 +32,7 @@ namespace AZ { namespace Render { - const char* EditorMaterialComponent::GenerateMaterialsButtonText = "Generate Source Materials..."; + const char* EditorMaterialComponent::GenerateMaterialsButtonText = "Generate/Manage Source Materials..."; const char* EditorMaterialComponent::GenerateMaterialsToolTipText = "Generate editable source material files from materials provided by the model."; const char* EditorMaterialComponent::ResetMaterialsButtonText = "Reset Materials"; @@ -228,10 +228,13 @@ namespace AZ action = menu->addAction(GenerateMaterialsButtonText, [this]() { OpenMaterialExporter(); }); action->setToolTip(GenerateMaterialsToolTipText); + menu->addSeparator(); + action = menu->addAction(ResetMaterialsButtonText, [this]() { ResetMaterialSlots(); }); action->setToolTip(ResetMaterialsToolTipText); menu->addSeparator(); + action = menu->addAction("Clear Model Materials", [this]() { AzToolsFramework::ScopedUndoBatch undoBatch("Clearing model materials."); SetDirty(); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp index 34cc53a326..3a23c9be55 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentExporter.cpp @@ -104,7 +104,7 @@ namespace AZ // Constructing a dialog with a table to display all configurable material export items QDialog dialog(activeWindow); - dialog.setWindowTitle("Generate Source Materials"); + dialog.setWindowTitle("Generate/Manage Source Materials"); const QStringList headerLabels = { "Material Slot", "Material Filename", "Overwrite" }; const int MaterialSlotColumn = 0; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp index 65fa7bc286..cbde73962d 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/EditorMaterialComponentSlot.cpp @@ -273,32 +273,24 @@ namespace AZ QAction* action = nullptr; - action = menu.addAction("Open Material Editor...", [this]() { EditorMaterialSystemComponentRequestBus::Broadcast(&EditorMaterialSystemComponentRequestBus::Events::OpenInMaterialEditor, ""); }); - action->setVisible(!m_materialAsset.GetId().IsValid()); - - action = menu.addAction("Clear", [this]() { Clear(); }); - action->setEnabled(m_materialAsset.GetId().IsValid() || !m_propertyOverrides.empty() || !m_matModUvOverrides.empty()); - - action = menu.addAction("Set Default Asset", [this]() { SetDefaultAsset(); }); + action = menu.addAction("Generate/Manage Source Material...", [this]() { OpenMaterialExporter(); }); action->setEnabled(m_id.m_materialAssetId.IsValid()); menu.addSeparator(); - action = menu.addAction("Generate Source Material...", [this]() { OpenMaterialExporter(); }); - action->setEnabled(m_id.m_materialAssetId.IsValid()); - - menu.addSeparator(); - - const auto instanceAssetId = m_materialAsset.GetId().IsValid() ? m_materialAsset.GetId() : m_id.m_materialAssetId; + action = menu.addAction("Edit Source Material...", [this]() { OpenMaterialEditor(); }); + action->setEnabled(HasSourceData()); action = menu.addAction("Edit Material Instance...", [this]() { OpenMaterialInspector(); }); action->setEnabled(m_materialAsset.GetId().IsValid()); - action = menu.addAction("Edit Material Model UV Map...", [this]() { OpenUvNameMapInspector(); }); + action = menu.addAction("Edit Material Instance UV Map...", [this]() { OpenUvNameMapInspector(); }); action->setEnabled(m_materialAsset.GetId().IsValid()); - action = menu.addAction("Edit Material in Material Editor...", [this]() { OpenMaterialEditor(); }); - action->setEnabled(HasSourceData()); + menu.addSeparator(); + + action = menu.addAction("Clear Material Instance Overrides", [this]() { m_propertyOverrides = {}; m_matModUvOverrides = {}; }); + action->setEnabled(!m_propertyOverrides.empty() || !m_matModUvOverrides.empty()); menu.exec(QCursor::pos()); } From 7e231c8e362b3134f5a3da86356937ccec80d455 Mon Sep 17 00:00:00 2001 From: guthadam Date: Wed, 16 Jun 2021 23:37:43 -0500 Subject: [PATCH 44/93] LYN-4547 prepending O3DE to the material editor application name --- .../Code/Source/Window/MaterialEditorWindow.cpp | 4 ++-- Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp index 64b6e01b61..6264a2aa2b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialEditorWindow.cpp @@ -78,13 +78,13 @@ namespace MaterialEditor AZ::Name apiName = AZ::RHI::Factory::Get().GetName(); if (!apiName.IsEmpty()) { - QString title = QString{ "Material Editor (%1)" }.arg(apiName.GetCStr()); + QString title = QString{ "%1 (%2)" }.arg(QApplication::applicationName()).arg(apiName.GetCStr()); setWindowTitle(title); } else { AZ_Assert(false, "Render API name not found"); - setWindowTitle("Material Editor"); + setWindowTitle(QApplication::applicationName()); } m_advancedDockManager = new AzQtComponents::FancyDocking(this); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp index 8c55adba46..ce44d9c640 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char** argv) { QApplication::setOrganizationName("Amazon"); QApplication::setOrganizationDomain("amazon.com"); - QApplication::setApplicationName("MaterialEditor"); + QApplication::setApplicationName("O3DE Material Editor"); AzQtComponents::PrepareQtPaths(); From 7bd42e1f8d7d769a35eb81648882c3d06f8bd3ef Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Wed, 16 Jun 2021 21:55:28 -0700 Subject: [PATCH 45/93] [LYN-4410] Back buttons should preserve selected gems (#1359) --- Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp | 9 ++++++--- Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp index c8ed3954ac..0e3a4ba95d 100644 --- a/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/CreateProjectCtrl.cpp @@ -77,6 +77,7 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::CreateProject; } + // Called when pressing "Create New Project" void CreateProjectCtrl::NotifyCurrentScreen() { ScreenWidget* currentScreen = reinterpret_cast(m_stack->currentWidget()); @@ -84,6 +85,11 @@ namespace O3DE::ProjectManager { currentScreen->NotifyCurrentScreen(); } + + // Gather the gems from the project template. When we will have multiple project templates, we need to re-gather them + // on changing the template and let the user know that any further changes on top of the template will be lost. + QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); + m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); } void CreateProjectCtrl::HandleBackButton() @@ -151,9 +157,6 @@ namespace O3DE::ProjectManager { m_stack->setCurrentIndex(m_stack->currentIndex() + 1); - QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath(); - m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true); - Update(); } else diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp index 65f73accd1..409c51315d 100644 --- a/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp +++ b/Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp @@ -89,17 +89,18 @@ namespace O3DE::ProjectManager return ProjectManagerScreen::UpdateProject; } + // Called when pressing "Edit Project Settings..." void UpdateProjectCtrl::NotifyCurrentScreen() { m_stack->setCurrentIndex(ScreenOrder::Settings); Update(); + + // Gather the available gems that will be shown in the gem catalog. + m_gemCatalogScreen->ReinitForProject(m_projectInfo.m_path, /*isNewProject=*/false); } void UpdateProjectCtrl::HandleGemsButton() { - // The next page is the gem catalog. Gather the available gems that will be shown in the gem catalog. - m_gemCatalogScreen->ReinitForProject(m_projectInfo.m_path, /*isNewProject=*/false); - m_stack->setCurrentWidget(m_gemCatalogScreen); Update(); } From c0d9db6739ca36806759587b3a9432fea3998ed4 Mon Sep 17 00:00:00 2001 From: Eric Phister <52085794+amzn-phist@users.noreply.github.com> Date: Thu, 17 Jun 2021 10:29:28 -0500 Subject: [PATCH 46/93] Fixes for SDK include directory structure (#1319) * Updates the install of SDK includes Needs some fixes so that public include paths that were going up directories or had multiple path components would resolve to correct destination paths during install. * Updates the logic to fix AutoGen includes AutoGen headers were a special case because matching relative paths failed due to the headers existing under the build path. * Removes trailling slashes from inc dirs This addresses a quirk in CMake where installing a directory with a trailing slash has different behavior than one without. The include paths being processed had a wide mix of slash or not. * Update cmake/Platform/Common/Install_common.cmake Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixes fatal errors in the last change The call to cmake_path IS_PREFIX was ill-formed. Also the trailing directory separator was being removed from the DESTINATION but really needed to be removed from the DIRECTORY. Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- cmake/Platform/Common/Install_common.cmake | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 933d64149b..bf7134d470 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -42,8 +42,20 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME) string(GENEX_STRIP ${include_directory} include_genex_expr) if(include_genex_expr STREQUAL include_directory) # only for cases where there are no generation expressions unset(current_public_headers) + + cmake_path(NORMAL_PATH include_directory) + string(REGEX REPLACE "/$" "" include_directory "${include_directory}") + cmake_path(IS_PREFIX LY_ROOT_FOLDER ${absolute_target_source_dir} NORMALIZE include_directory_child_of_o3de_root) + if(NOT include_directory_child_of_o3de_root) + message(FATAL_ERROR "Include directory of \"${include_directory}\" is outside of the O3DE root folder of \"${LY_ROOT_FOLDER}\". For the INSTALL step, the O3DE root folder must be a prefix of all include directories") + endif() + + cmake_path(RELATIVE_PATH include_directory BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE rel_include_dir) + cmake_path(APPEND include_location "${rel_include_dir}" ".." OUTPUT_VARIABLE destination_dir) + cmake_path(NORMAL_PATH destination_dir) + install(DIRECTORY ${include_directory} - DESTINATION ${include_location}/${target_source_dir} + DESTINATION ${destination_dir} COMPONENT ${install_component} FILES_MATCHING PATTERN *.h @@ -116,7 +128,9 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME) string(GENEX_STRIP ${include} include_genex_expr) if(include_genex_expr STREQUAL include) # only for cases where there are no generation expressions file(RELATIVE_PATH relative_include ${absolute_target_source_dir} ${include}) - string(APPEND INCLUDE_DIRECTORIES_PLACEHOLDER "\${LY_ROOT_FOLDER}/include/${target_source_dir}/${relative_include}\n") + cmake_path(APPEND include_location "${target_source_dir}" "${relative_include}" OUTPUT_VARIABLE target_include) + cmake_path(NORMAL_PATH target_include) + string(APPEND INCLUDE_DIRECTORIES_PLACEHOLDER "\${LY_ROOT_FOLDER}/${target_include}\n") endif() endforeach() endif() From 705fd9bfa0d1189d7380dd0499a45579e57ffbfe Mon Sep 17 00:00:00 2001 From: gallowj Date: Thu, 17 Jun 2021 10:33:22 -0500 Subject: [PATCH 47/93] Update to modernize the Sponza asset gem to best practices and consistency --- Gems/AtomContent/Sponza/.gitignore | 3 +- .../AtomContent/Sponza/.src/objects/sponza.ma | 3 + .../Sponza/.src/objects/sponza_cleanup.mb | 3 + .../Sponza/{ArtSource => .src}/stub | 0 .../Sponza/ArtSource/objects/sponza.ma | 3 - .../ArtSource/objects/sponza_cleanup.mb | 3 - .../Sponza/Assets/objects/sponza.fbx | 4 +- Gems/AtomContent/Sponza/CMakeLists.txt | 11 +++ .../AtomContent/Sponza/Launch_WingIDE-7-1.bat | 82 ------------------- Gems/AtomContent/Sponza/Project_Env.bat | 4 + .../AssetProcessorPlatformConfig.setreg | 14 ++++ .../Sponza/{ => Tools}/Launch_Cmd.bat | 18 +--- .../{ => Tools/Maya}/Launch_Maya_2020.bat | 20 ++--- .../Maya/Scripts/stub} | 0 Gems/AtomContent/Sponza/User_env.bat.template | 1 + 15 files changed, 50 insertions(+), 119 deletions(-) create mode 100644 Gems/AtomContent/Sponza/.src/objects/sponza.ma create mode 100644 Gems/AtomContent/Sponza/.src/objects/sponza_cleanup.mb rename Gems/AtomContent/Sponza/{ArtSource => .src}/stub (100%) delete mode 100644 Gems/AtomContent/Sponza/ArtSource/objects/sponza.ma delete mode 100644 Gems/AtomContent/Sponza/ArtSource/objects/sponza_cleanup.mb create mode 100644 Gems/AtomContent/Sponza/CMakeLists.txt delete mode 100644 Gems/AtomContent/Sponza/Launch_WingIDE-7-1.bat create mode 100644 Gems/AtomContent/Sponza/Registry/AssetProcessorPlatformConfig.setreg rename Gems/AtomContent/Sponza/{ => Tools}/Launch_Cmd.bat (54%) rename Gems/AtomContent/Sponza/{ => Tools/Maya}/Launch_Maya_2020.bat (64%) rename Gems/AtomContent/Sponza/{LyProjectRootStub => Tools/Maya/Scripts/stub} (100%) create mode 100644 Gems/AtomContent/Sponza/User_env.bat.template diff --git a/Gems/AtomContent/Sponza/.gitignore b/Gems/AtomContent/Sponza/.gitignore index c58f3de65f..8bbb0be455 100644 --- a/Gems/AtomContent/Sponza/.gitignore +++ b/Gems/AtomContent/Sponza/.gitignore @@ -1,3 +1,4 @@ /.maya_data/* /.mayaSwatches/* -*.swatch \ No newline at end of file +*.swatch +[Uu]ser_env.bat \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/.src/objects/sponza.ma b/Gems/AtomContent/Sponza/.src/objects/sponza.ma new file mode 100644 index 0000000000..fabe9dd9ee --- /dev/null +++ b/Gems/AtomContent/Sponza/.src/objects/sponza.ma @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c95e08274ea0051ee35f415918eaf1530f05475d6265f2ad7ec7c1ff79d29f2b +size 40549297 diff --git a/Gems/AtomContent/Sponza/.src/objects/sponza_cleanup.mb b/Gems/AtomContent/Sponza/.src/objects/sponza_cleanup.mb new file mode 100644 index 0000000000..bdd51c6f8c --- /dev/null +++ b/Gems/AtomContent/Sponza/.src/objects/sponza_cleanup.mb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b77710f70b80578339c826f51eef4d964e1136f27e67ff26a348542feec16dfa +size 22804176 diff --git a/Gems/AtomContent/Sponza/ArtSource/stub b/Gems/AtomContent/Sponza/.src/stub similarity index 100% rename from Gems/AtomContent/Sponza/ArtSource/stub rename to Gems/AtomContent/Sponza/.src/stub diff --git a/Gems/AtomContent/Sponza/ArtSource/objects/sponza.ma b/Gems/AtomContent/Sponza/ArtSource/objects/sponza.ma deleted file mode 100644 index 5bea07b7d6..0000000000 --- a/Gems/AtomContent/Sponza/ArtSource/objects/sponza.ma +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7250488d0ba6115089c5f83d6c352826b41d711550ca828853a139129ffcff9f -size 40549260 diff --git a/Gems/AtomContent/Sponza/ArtSource/objects/sponza_cleanup.mb b/Gems/AtomContent/Sponza/ArtSource/objects/sponza_cleanup.mb deleted file mode 100644 index 882496f2b0..0000000000 --- a/Gems/AtomContent/Sponza/ArtSource/objects/sponza_cleanup.mb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d3c18d76f00688d15c54736ef3d8c953df08baf46a796fa71627de18bdb3c0f -size 22804332 diff --git a/Gems/AtomContent/Sponza/Assets/objects/sponza.fbx b/Gems/AtomContent/Sponza/Assets/objects/sponza.fbx index 9061666968..38752bf32a 100644 --- a/Gems/AtomContent/Sponza/Assets/objects/sponza.fbx +++ b/Gems/AtomContent/Sponza/Assets/objects/sponza.fbx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35a880abc018520d4b30d21a64f7a14fca74d936593320d5afd03ddf25771bf3 -size 9176416 +oid sha256:e24948f9f477a3a167e50a80b04148d0a598d8c40bed86d51870daa8842ce5dd +size 9175808 diff --git a/Gems/AtomContent/Sponza/CMakeLists.txt b/Gems/AtomContent/Sponza/CMakeLists.txt new file mode 100644 index 0000000000..d65c7234cb --- /dev/null +++ b/Gems/AtomContent/Sponza/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# 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. +# +ly_create_alias(NAME Sponza.Builders NAMESPACE Gem) \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Launch_WingIDE-7-1.bat b/Gems/AtomContent/Sponza/Launch_WingIDE-7-1.bat deleted file mode 100644 index f73fb640d5..0000000000 --- a/Gems/AtomContent/Sponza/Launch_WingIDE-7-1.bat +++ /dev/null @@ -1,82 +0,0 @@ -@echo off -REM -REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -REM its licensors. -REM -REM For complete copyright and license terms please see the LICENSE at the root of this -REM distribution (the "License"). All use of this software is governed by the License, -REM or, if provided, by the license below or the license accompanying this file. Do not -REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM - -:: Launches Wing IDE and the DccScriptingInterface Project Files - -echo. -echo _____________________________________________________________________ -echo. -echo ~ Setting up LY DCCsi WingIDE Dev Env... -echo _____________________________________________________________________ -echo. - -:: Store current dir -%~d0 -cd %~dp0 -PUSHD %~dp0 - -:: Keep changes local -SETLOCAL enableDelayedExpansion - -SET ABS_PATH=%~dp0 -echo Current Dir, %ABS_PATH% - -:: WingIDE version Major -SET WING_VERSION_MAJOR=7 -echo WING_VERSION_MAJOR = %WING_VERSION_MAJOR% - -:: WingIDE version Major -SET WING_VERSION_MINOR=1 -echo WING_VERSION_MINOR = %WING_VERSION_MINOR% - -:: note the changed path from IDE to Pro -set WINGHOME=%PROGRAMFILES(X86)%\Wing Pro %WING_VERSION_MAJOR%.%WING_VERSION_MINOR% -echo WINGHOME = %WINGHOME% - -CALL %~dp0\Project_Env.bat - -echo. -echo _____________________________________________________________________ -echo. -echo ~ WingIDE Version %WING_VERSION_MAJOR%.%WING_VERSION_MINOR% -echo _____________________________________________________________________ -echo. - -SET WING_PROJ=%DCCSIG_PATH%\Solutions\.wing\DCCsi_%WING_VERSION_MAJOR%x.wpr -echo WING_PROJ = %WING_PROJ% - -echo. -echo _____________________________________________________________________ -echo. -echo ~ Launching %LY_PROJECT% project in WingIDE %WING_VERSION_MAJOR%.%WING_VERSION_MINOR% ... -echo _____________________________________________________________________ -echo. - - -IF EXIST "%WINGHOME%\bin\wing.exe" ( - start "" "%WINGHOME%\bin\wing.exe" "%WING_PROJ%" -) ELSE ( - Where wing.exe 2> NUL - IF ERRORLEVEL 1 ( - echo wing.exe could not be found - pause - ) ELSE ( - start "" wing.exe "%WING_PROJ%" - ) -) - -ENDLOCAL - -:: Return to starting directory -POPD - -:END_OF_FILE diff --git a/Gems/AtomContent/Sponza/Project_Env.bat b/Gems/AtomContent/Sponza/Project_Env.bat index b06acfaa9a..7df40049f3 100644 --- a/Gems/AtomContent/Sponza/Project_Env.bat +++ b/Gems/AtomContent/Sponza/Project_Env.bat @@ -15,6 +15,7 @@ REM cd %~dp0 PUSHD %~dp0 +:: This is a legacy envar which is being migrated to LY_PROJECT_NAME for %%a in (.) do set LY_PROJECT=%%~na echo. @@ -26,6 +27,9 @@ echo. echo LY_PROJECT = %LY_PROJECT% +set LY_PROJECT_NAME=%LY_PROJECT% +echo LY_PROJECT_NAME = %LY_PROJECT_NAME% + :: Put you project env vars and overrides here :: chanhe the relative path up to dev diff --git a/Gems/AtomContent/Sponza/Registry/AssetProcessorPlatformConfig.setreg b/Gems/AtomContent/Sponza/Registry/AssetProcessorPlatformConfig.setreg new file mode 100644 index 0000000000..778d05dee9 --- /dev/null +++ b/Gems/AtomContent/Sponza/Registry/AssetProcessorPlatformConfig.setreg @@ -0,0 +1,14 @@ +{ + "Amazon": { + "AssetProcessor": { + "Settings": { + // ------------------------------------------------------------------------------ + // Sample Gems, Block source folders + // ------------------------------------------------------------------------------ + "Exclude Work In Progress Folders": { + "pattern": ".*\\\\/.[Ss]rc\\\\/.*" + } + } + } + } +} diff --git a/Gems/AtomContent/Sponza/Launch_Cmd.bat b/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat similarity index 54% rename from Gems/AtomContent/Sponza/Launch_Cmd.bat rename to Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat index f69d4ef49c..f5d436b215 100644 --- a/Gems/AtomContent/Sponza/Launch_Cmd.bat +++ b/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat @@ -1,16 +1,6 @@ +:: Need to set up + @echo off - -REM -REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -REM its licensors. -REM -REM For complete copyright and license terms please see the LICENSE at the root of this -REM distribution (the "License"). All use of this software is governed by the License, -REM or, if provided, by the license below or the license accompanying this file. Do not -REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM - :: Set up and run LY Python CMD prompt :: Sets up the DccScriptingInterface_Env, :: Puts you in the CMD within the dev environment @@ -27,7 +17,7 @@ PUSHD %~dp0 :: Keep changes local SETLOCAL enableDelayedExpansion -CALL %~dp0\Project_Env.bat +CALL %~dp0\..\Project_Env.bat echo. echo _____________________________________________________________________ @@ -44,4 +34,4 @@ ENDLOCAL :: Return to starting directory POPD -:END_OF_FILE +:END_OF_FILE \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/Launch_Maya_2020.bat b/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat similarity index 64% rename from Gems/AtomContent/Sponza/Launch_Maya_2020.bat rename to Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat index 224d8c15d0..8fb283d6d8 100644 --- a/Gems/AtomContent/Sponza/Launch_Maya_2020.bat +++ b/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat @@ -1,15 +1,7 @@ -@echo off +:: Launches maya wityh a bunch of local hooks for Lumberyard +:: ToDo: move all of this to a .json data driven boostrapping system -REM -REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -REM its licensors. -REM -REM For complete copyright and license terms please see the LICENSE at the root of this -REM distribution (the "License"). All use of this software is governed by the License, -REM or, if provided, by the license below or the license accompanying this file. Do not -REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -REM +@echo off %~d0 cd %~dp0 @@ -34,7 +26,7 @@ set MAYA_VERSION=2020 echo MAYA_VERSION = %MAYA_VERSION% :: if a local customEnv.bat exists, run it -IF EXIST "%~dp0Project_Env.bat" CALL %~dp0Project_Env.bat +IF EXIST "%~dp0..\..\Project_Env.bat" CALL %~dp0..\..\Project_Env.bat echo ________________________________ echo Launching Maya %MAYA_VERSION% for Lumberyard... @@ -53,7 +45,7 @@ IF EXIST "%MAYA_LOCATION%\bin\Maya.exe" ( Where maya.exe 2> NUL IF ERRORLEVEL 1 ( echo Maya.exe could not be found - pause + pause ) ELSE ( start "" Maya.exe %* ) @@ -64,4 +56,4 @@ POPD :END_OF_FILE -exit /b 0 +exit /b 0 \ No newline at end of file diff --git a/Gems/AtomContent/Sponza/LyProjectRootStub b/Gems/AtomContent/Sponza/Tools/Maya/Scripts/stub similarity index 100% rename from Gems/AtomContent/Sponza/LyProjectRootStub rename to Gems/AtomContent/Sponza/Tools/Maya/Scripts/stub diff --git a/Gems/AtomContent/Sponza/User_env.bat.template b/Gems/AtomContent/Sponza/User_env.bat.template new file mode 100644 index 0000000000..99bc7a951d --- /dev/null +++ b/Gems/AtomContent/Sponza/User_env.bat.template @@ -0,0 +1 @@ +set LY_DEV=C:\Depot\o3de-engine \ No newline at end of file From eadbb1703492a76e7d0e519b4c7f3b26913079ab Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 17 Jun 2021 09:04:22 -0700 Subject: [PATCH 48/93] Cherry picking fff7cc0e10aff9478a76e37d0604b176ee74ed0d. Redcoding parts of old Networking that used Bullet external physics code --- .../Replica/Interest/BvDynamicTree.cpp | 1277 ------------ .../GridMate/Replica/Interest/BvDynamicTree.h | 878 -------- .../Interest/ProximityInterestHandler.cpp | 597 ------ .../Interest/ProximityInterestHandler.h | 314 --- .../GridMate/GridMate/gridmate_files.cmake | 4 - Code/Framework/GridMate/Tests/Interest.cpp | 1823 ----------------- .../GridMate/Tests/gridmate_test_files.cmake | 1 - 7 files changed, 4894 deletions(-) delete mode 100644 Code/Framework/GridMate/GridMate/Replica/Interest/BvDynamicTree.cpp delete mode 100644 Code/Framework/GridMate/GridMate/Replica/Interest/BvDynamicTree.h delete mode 100644 Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp delete mode 100644 Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.h delete mode 100644 Code/Framework/GridMate/Tests/Interest.cpp diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/BvDynamicTree.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/BvDynamicTree.cpp deleted file mode 100644 index e72bd9b12c..0000000000 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/BvDynamicTree.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -// Modifications copyright Amazon.com, Inc. or its affiliates. - -///BvDynamicTree implementation by Nathanael Presson -#include - -namespace GridMate -{ - // - struct btDbvtNodeEnumerator : BvDynamicTree::ICollideCollector - { - BvDynamicTree::ConstNodeArrayType nodes; - void Process(const BvDynamicTree::NodeType* n) { nodes.push_back(n); } - }; - - // - static AZ_FORCE_INLINE int indexof(const BvDynamicTree::NodeType* node) - { - return (node->m_parent->m_childs[1]==node); - } - - // - static AZ_FORCE_INLINE BvDynamicTree::VolumeType merge( const BvDynamicTree::VolumeType& a, const BvDynamicTree::VolumeType& b) - { - BvDynamicTree::VolumeType res; - Merge(a,b,res); - return res; - } - - // volume+edge lengths - static AZ_FORCE_INLINE float size(const BvDynamicTree::VolumeType& a) - { - const AZ::Vector3 edges = a.GetExtents(); - return edges.GetX()*edges.GetY()*edges.GetZ() + edges.Dot(AZ::Vector3::CreateOne()); - } - - // - static void getmaxdepth(const BvDynamicTree::NodeType* node,int depth,int& maxdepth) - { - if(node->IsInternal()) - { - getmaxdepth(node->m_childs[0],depth+1,maxdepth); - getmaxdepth(node->m_childs[0],depth+1,maxdepth); - } - else - maxdepth= AZ::GetMax(maxdepth,depth); - } - - - - //========================================================================= - // insertleaf - // [3/4/2009] - //========================================================================= - void - BvDynamicTree::insertleaf( NodeType* root, NodeType* leaf) - { - if(!m_root) - { - m_root = leaf; - leaf->m_parent = 0; - } - else - { - if(!root->IsLeaf()) - { - do { - root=root->m_childs[Select( leaf->m_volume, - root->m_childs[0]->m_volume, - root->m_childs[1]->m_volume)]; - } while(!root->IsLeaf()); - } - NodeType* prev = root->m_parent; - NodeType* node = createnode(prev,leaf->m_volume,root->m_volume,0); - if(prev) - { - prev->m_childs[indexof(root)] = node; - node->m_childs[0] = root;root->m_parent=node; - node->m_childs[1] = leaf;leaf->m_parent=node; - do { - if(!prev->m_volume.Contains(node->m_volume)) - Merge(prev->m_childs[0]->m_volume,prev->m_childs[1]->m_volume,prev->m_volume); - else - break; - node=prev; - } while(0!=(prev=node->m_parent)); - } - else - { - node->m_childs[0] = root;root->m_parent=node; - node->m_childs[1] = leaf;leaf->m_parent=node; - m_root = node; - } - } - } - - //========================================================================= - // removeleaf - // [3/4/2009] - //========================================================================= - BvDynamicTree::NodeType* - BvDynamicTree::removeleaf( NodeType* leaf) - { - if(leaf==m_root) - { - m_root=0; - return 0; - } - else - { - NodeType* parent=leaf->m_parent; - NodeType* prev=parent->m_parent; - NodeType* sibling=parent->m_childs[1-indexof(leaf)]; - if(prev) - { - prev->m_childs[indexof(parent)]=sibling; - sibling->m_parent=prev; - deletenode(parent); - while(prev) - { - const VolumeType pb=prev->m_volume; - Merge(prev->m_childs[0]->m_volume,prev->m_childs[1]->m_volume,prev->m_volume); - if(NotEqual(pb,prev->m_volume)) - { - prev=prev->m_parent; - } else break; - } - return prev?prev:m_root; - } - else - { - m_root=sibling; - sibling->m_parent=0; - deletenode(parent); - return m_root; - } - } - } - - - //========================================================================= - // fetchleaves - // [3/4/2009] - //========================================================================= - void - BvDynamicTree::fetchleaves(NodeType* root,NodeArrayType& leaves,int depth) - { - if(root->IsInternal()&&depth) - { - fetchleaves(root->m_childs[0],leaves,depth-1); - fetchleaves(root->m_childs[1],leaves,depth-1); - deletenode(root); - } - else - { - leaves.push_back(root); - } - } - - //========================================================================= - // split - // [3/4/2009] - //========================================================================= - void - BvDynamicTree::split(const NodeArrayType& leaves, NodeArrayType& left, NodeArrayType& right, const AZ::Vector3& org, const AZ::Vector3& axis) - { - left.resize(0); - right.resize(0); - for(size_t i = 0, ni = leaves.size(); i < ni; ++i) - { - if (axis.Dot(leaves[i]->m_volume.GetCenter() - org) < 0.0f) - { - left.push_back(leaves[i]); - } - else - { - right.push_back(leaves[i]); - } - } - } - - //========================================================================= - // bounds - // [3/4/2009] - //========================================================================= - BvDynamicTree::VolumeType - BvDynamicTree::bounds(const NodeArrayType& leaves) - { - VolumeType volume=leaves[0]->m_volume; - for(size_t i=1,ni=leaves.size();im_volume,volume); - } - return volume; - } - - //========================================================================= - // bottomup - // [3/4/2009] - //========================================================================= - void - BvDynamicTree::bottomup( NodeArrayType& leaves ) - { - while(leaves.size()>1) - { - float minsize = std::numeric_limits::max(); - int minidx[2]={-1,-1}; - for(unsigned int i=0;im_volume,leaves[j]->m_volume)); - if(szm_volume,n[1]->m_volume,0); - p->m_childs[0] = n[0]; - p->m_childs[1] = n[1]; - n[0]->m_parent = p; - n[1]->m_parent = p; - leaves[minidx[0]] = p; - //leaves.swap(minidx[1],leaves.size()-1); - leaves[minidx[1]] = leaves.back(); - leaves.pop_back(); - } - } - - //========================================================================= - // topdown - // [3/4/2009] - //========================================================================= - BvDynamicTree::NodeType* - BvDynamicTree::topdown(NodeArrayType& leaves,int bu_treshold) - { - static const AZ::Vector3 axis[]= { AZ::Vector3(1.0f,0.0f,0.0f), AZ::Vector3(0.0f,1.0f,0.0f), AZ::Vector3(0.0f,0.0f,1.0f)}; - if(leaves.size()>1) - { - if(leaves.size()>(unsigned int)bu_treshold) - { - const VolumeType vol=bounds(leaves); - const AZ::Vector3 org=vol.GetCenter(); - NodeArrayType sets[2]; - int bestaxis=-1; - int bestmidp=(int)leaves.size(); - int splitcount[3][2]={{0,0},{0,0},{0,0}}; - - for(unsigned int i=0;im_volume.GetCenter()-org; - for(int j=0;j<3;++j) - { - ++splitcount[j][x.Dot(axis[j]) > 0.0f ? 1 : 0]; - } - } - for(unsigned int i=0;i<3;++i) - { - if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) - { - // todo just remove the sign bit... - const int midp = (int)fabsf((float)(splitcount[i][0]-splitcount[i][1])); - if(midp=0) - { - sets[0].reserve(splitcount[bestaxis][0]); - sets[1].reserve(splitcount[bestaxis][1]); - split(leaves,sets[0],sets[1],org,axis[bestaxis]); - } - else - { - sets[0].reserve(leaves.size()/2+1); - sets[1].reserve(leaves.size()/2); - for(size_t i=0,ni=leaves.size();im_childs[0] = topdown(sets[0],bu_treshold); - node->m_childs[1] = topdown(sets[1],bu_treshold); - node->m_childs[0]->m_parent=node; - node->m_childs[1]->m_parent=node; - return(node); - } - else - { - bottomup(leaves); - return(leaves[0]); - } - } - return(leaves[0]); - } - - //========================================================================= - // sort - // [3/4/2009] - //========================================================================= - AZ_FORCE_INLINE BvDynamicTree::NodeType* - BvDynamicTree::sort(NodeType* n,NodeType*& r) - { - BvDynamicTree::NodeType* p=n->m_parent; - AZ_Assert(n->IsInternal(), "We can call this only for internal nodes!"); - if(p>n) - { - const int i=indexof(n); - const int j=1-i; - NodeType* s=p->m_childs[j]; - NodeType* q=p->m_parent; - AZ_Assert(n==p->m_childs[i], ""); - if(q) q->m_childs[indexof(p)]=n; else r=n; - s->m_parent=n; - p->m_parent=n; - n->m_parent=q; - p->m_childs[0]=n->m_childs[0]; - p->m_childs[1]=n->m_childs[1]; - n->m_childs[0]->m_parent=p; - n->m_childs[1]->m_parent=p; - n->m_childs[i]=p; - n->m_childs[j]=s; - AZStd::swap(p->m_volume,n->m_volume); - return(p); - } - return(n); - } - - #if 0 - static DBVT_INLINE NodeType* walkup(NodeType* n,int count) - { - while(n&&(count--)) n=n->parent; - return(n); - } - #endif - - // - // Api - // - - // - BvDynamicTree::BvDynamicTree() - { - m_root = 0; - m_free = 0; - m_lkhd = -1; - m_leaves = 0; - m_opath = 0; - } - - // - BvDynamicTree::~BvDynamicTree() - { - Clear(); - } - - // - void BvDynamicTree::Clear() - { - if(m_root) recursedeletenode(m_root); - delete m_free; - m_free=0; - } - - // - void BvDynamicTree::OptimizeBottomUp() - { - if(m_root) - { - NodeArrayType leaves; - leaves.reserve(m_leaves); - fetchleaves(m_root,leaves); - bottomup(leaves); - m_root=leaves[0]; - } - } - - // - void - BvDynamicTree::OptimizeTopDown(int bu_treshold) - { - if(m_root) - { - NodeArrayType leaves; - leaves.reserve(m_leaves); - fetchleaves(m_root,leaves); - m_root=topdown(leaves,bu_treshold); - } - } - - // - void - BvDynamicTree::OptimizeIncremental(int passes) - { - if(passes<0) passes=m_leaves; - if(m_root&&(passes>0)) - { - do { - NodeType* node=m_root; - unsigned bit=0; - while(node->IsInternal()) - { - node=sort(node,m_root)->m_childs[(m_opath>>bit)&1]; - bit=(bit+1)&(sizeof(unsigned)*8-1); - } - Update(node); - ++m_opath; - } while(--passes); - } - } - - // - BvDynamicTree::NodeType* - BvDynamicTree::Insert(const VolumeType& volume,void* data) - { - NodeType* leaf=createnode(0,volume,data); - insertleaf(m_root,leaf); - ++m_leaves; - return(leaf); - } - - // - void - BvDynamicTree::Update(NodeType* leaf,int lookahead) - { - NodeType* root=removeleaf(leaf); - if(root) - { - if(lookahead>=0) - { - for(int i=0;(im_parent;++i) - { - root=root->m_parent; - } - } else root=m_root; - } - insertleaf(root,leaf); - } - - // - void - BvDynamicTree::Update(NodeType* leaf,VolumeType& volume) - { - NodeType* root=removeleaf(leaf); - if(root) - { - if(m_lkhd>=0) - { - for(int i=0;(im_parent;++i) - { - root=root->m_parent; - } - } else root=m_root; - } - leaf->m_volume=volume; - insertleaf(root,leaf); - } - - // - bool - BvDynamicTree::Update(NodeType* leaf,VolumeType& volume,const AZ::Vector3& velocity,const float margin) - { - if(leaf->m_volume.Contains(volume)) return(false); - volume.Expand(AZ::Vector3(margin)); - volume.SignedExpand(velocity); - Update(leaf,volume); - return(true); - } - - // - bool - BvDynamicTree::Update(NodeType* leaf,VolumeType& volume,const AZ::Vector3& velocity) - { - if(leaf->m_volume.Contains(volume)) return(false); - volume.SignedExpand(velocity); - Update(leaf,volume); - return(true); - } - - // - bool - BvDynamicTree::Update(NodeType* leaf,VolumeType& volume,const float margin) - { - if(leaf->m_volume.Contains(volume)) return(false); - volume.Expand(AZ::Vector3(margin)); - Update(leaf,volume); - return(true); - } - - // - void - BvDynamicTree::Remove(NodeType* leaf) - { - removeleaf(leaf); - deletenode(leaf); - --m_leaves; - } - - template - int findLinearSearch(BvDynamicTree::ConstNodeArrayType& arr, const T& key) - { - size_t numElements = arr.size(); - int index = (int)numElements; - - for(size_t i=0;iPrepare(m_root,(unsigned int)nodes.nodes.size()); - for(unsigned int i=0;i<(unsigned int)nodes.nodes.size();++i) - { - const NodeType* n=nodes.nodes[i]; - int p=-1; - if(n->m_parent) p = findLinearSearch(nodes.nodes,n->m_parent); - if(n->IsInternal()) - { - const int c0=findLinearSearch(nodes.nodes,n->m_childs[0]); - const int c1=findLinearSearch(nodes.nodes,n->m_childs[1]); - iwriter->WriteNode(n,i,p,c0,c1); - } - else - { - iwriter->WriteLeaf(n,i,p); - } - } - } - - // - void - BvDynamicTree::Clone(BvDynamicTree& dest,IClone* iclone) const - { - dest.Clear(); - if(m_root!=0) - { - vector stack; - stack.reserve(m_leaves); - stack.push_back(sStkCLN(m_root,0)); - do { - const size_t i=stack.size()-1; - const sStkCLN e=stack[i]; - NodeType* n= dest.createnode(e.parent,e.node->m_volume,e.node->m_data); - stack.pop_back(); - if(e.parent!=0) - e.parent->m_childs[i&1]=n; - else - dest.m_root=n; - if(e.node->IsInternal()) - { - stack.push_back(sStkCLN(e.node->m_childs[0],n)); - stack.push_back(sStkCLN(e.node->m_childs[1],n)); - } - else - { - iclone->CloneLeaf(n); - } - } while(!stack.empty()); - } - } - - // - int - BvDynamicTree::GetMaxDepth(const NodeType* node) - { - int depth=0; - if(node) getmaxdepth(node,1,depth); - return depth ; - } - - // - int - BvDynamicTree::CountLeaves(const NodeType* node) - { - if(node->IsInternal()) - return(CountLeaves(node->m_childs[0])+CountLeaves(node->m_childs[1])); - else - return(1); - } - - // - void - BvDynamicTree::ExtractLeaves(const NodeType* node,vector& leaves) - { - if(node->IsInternal()) - { - ExtractLeaves(node->m_childs[0],leaves); - ExtractLeaves(node->m_childs[1],leaves); - } - else - { - leaves.push_back(node); - } - } - - // - #if DBVT_ENABLE_BENCHMARK - - #include - #include - #include - - /* - q6600,2.4ghz - - /Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32" - /GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch" - /Fo"..\..\out\release8\build\libbulletcollision\\" - /Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb" - /W3 /nologo /c /Wp64 /Zi /errorReport:prompt - - Benchmarking dbvt... - World scale: 100.000000 - Extents base: 1.000000 - Extents range: 4.000000 - Leaves: 8192 - sizeof(VolumeType): 32 bytes - sizeof(NodeType): 44 bytes - [1] VolumeType intersections: 3499 ms (-1%) - [2] VolumeType merges: 1934 ms (0%) - [3] BvDynamicTree::collideTT: 5485 ms (-21%) - [4] BvDynamicTree::collideTT self: 2814 ms (-20%) - [5] BvDynamicTree::collideTT xform: 7379 ms (-1%) - [6] BvDynamicTree::collideTT xform,self: 7270 ms (-2%) - [7] BvDynamicTree::rayTest: 6314 ms (0%),(332143 r/s) - [8] insert/remove: 2093 ms (0%),(1001983 ir/s) - [9] updates (teleport): 1879 ms (-3%),(1116100 u/s) - [10] updates (jitter): 1244 ms (-4%),(1685813 u/s) - [11] optimize (incremental): 2514 ms (0%),(1668000 o/s) - [12] VolumeType notequal: 3659 ms (0%) - [13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s) - [14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s) - [15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s) - [16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s) - [17] VolumeType select: 3419 ms (0%) - */ - - struct btDbvtBenchmark - { - struct NilPolicy : BvDynamicTree::ICollide - { - NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {} - void Process(const NodeType*,const NodeType*) { ++m_pcount; } - void Process(const NodeType*) { ++m_pcount; } - void Process(const NodeType*,btScalar depth) - { - ++m_pcount; - if(m_checksort) - { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } - } - int m_pcount; - btScalar m_depth; - bool m_checksort; - }; - struct P14 : BvDynamicTree::ICollide - { - struct Node - { - const NodeType* leaf; - btScalar depth; - }; - void Process(const NodeType* leaf,btScalar depth) - { - Node n; - n.leaf = leaf; - n.depth = depth; - } - static int sortfnc(const Node& a,const Node& b) - { - if(a.depthb.depth) return(-1); - return(0); - } - btAlignedObjectArray m_nodes; - }; - struct P15 : BvDynamicTree::ICollide - { - struct Node - { - const NodeType* leaf; - btScalar depth; - }; - void Process(const NodeType* leaf) - { - Node n; - n.leaf = leaf; - n.depth = dot(leaf->volume.GetCenter(),m_axis); - } - static int sortfnc(const Node& a,const Node& b) - { - if(a.depthb.depth) return(-1); - return(0); - } - btAlignedObjectArray m_nodes; - btAZ::Vector3 m_axis; - }; - static btScalar RandUnit() - { - return(rand()/(btScalar)RAND_MAX); - } - static btAZ::Vector3 RandAZ::Vector3() - { - return(btAZ::Vector3(RandUnit(),RandUnit(),RandUnit())); - } - static btAZ::Vector3 RandAZ::Vector3(btScalar cs) - { - return(RandAZ::Vector3()*cs-btAZ::Vector3(cs,cs,cs)/2); - } - static VolumeType RandVolume(btScalar cs,btScalar eb,btScalar es) - { - return(VolumeType::FromCE(RandAZ::Vector3(cs),btAZ::Vector3(eb,eb,eb)+RandAZ::Vector3()*es)); - } - static btTransform RandTransform(btScalar cs) - { - btTransform t; - t.setOrigin(RandAZ::Vector3(cs)); - t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized()); - return(t); - } - static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,BvDynamicTree& dbvt) - { - dbvt.clear(); - for(int i=0;i volumes; - btAlignedObjectArray results; - volumes.resize(cfgLeaves); - results.resize(cfgLeaves); - for(int i=0;i volumes; - btAlignedObjectArray results; - volumes.resize(cfgLeaves); - results.resize(cfgLeaves); - for(int i=0;i transforms; - btDbvtBenchmark::NilPolicy policy; - transforms.resize(cfgBenchmark5_Iterations); - for(int i=0;i transforms; - btDbvtBenchmark::NilPolicy policy; - transforms.resize(cfgBenchmark6_Iterations); - for(int i=0;i rayorg; - btAlignedObjectArray raydir; - btDbvtBenchmark::NilPolicy policy; - rayorg.resize(cfgBenchmark7_Iterations); - raydir.resize(cfgBenchmark7_Iterations); - for(int i=0;i leaves; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); - dbvt.optimizeTopDown(); - dbvt.extractLeaves(dbvt.m_root,leaves); - printf("[9] updates (teleport): "); - wallclock.reset(); - for(int i=0;i(leaves[rand()%cfgLeaves]), - btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); - } - } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); - } - if(cfgBenchmark10_Enable) - {// Benchmark 10 - srand(380843); - BvDynamicTree dbvt; - btAlignedObjectArray leaves; - btAlignedObjectArray vectors; - vectors.resize(cfgBenchmark10_Iterations); - for(int i=0;i(leaves[rand()%cfgLeaves]); - VolumeType v=VolumeType::FromMM(l->volume.GetMin()+d,l->volume.GetMax()+d); - dbvt.update(l,v); - } - } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); - } - if(cfgBenchmark11_Enable) - {// Benchmark 11 - srand(380843); - BvDynamicTree dbvt; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); - dbvt.optimizeTopDown(); - printf("[11] optimize (incremental): "); - wallclock.reset(); - for(int i=0;i volumes; - btAlignedObjectArray results; - volumes.resize(cfgLeaves); - results.resize(cfgLeaves); - for(int i=0;i vectors; - btDbvtBenchmark::NilPolicy policy; - vectors.resize(cfgBenchmark13_Iterations); - for(int i=0;i vectors; - btDbvtBenchmark::P14 policy; - vectors.resize(cfgBenchmark14_Iterations); - for(int i=0;i vectors; - btDbvtBenchmark::P15 policy; - vectors.resize(cfgBenchmark15_Iterations); - for(int i=0;i batch; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); - dbvt.optimizeTopDown(); - batch.reserve(cfgBenchmark16_BatchCount); - printf("[16] Insert/remove batch(%u): ",cfgBenchmark16_BatchCount); - wallclock.reset(); - for(int i=0;i volumes; - btAlignedObjectArray results; - btAlignedObjectArray indices; - volumes.resize(cfgLeaves); - results.resize(cfgLeaves); - indices.resize(cfgLeaves); - for(int i=0;i -#include -#include - -#include -#include - -namespace GridMate -{ - namespace Internal - { - /** - * - */ - class DynamicTreeAabb : public AZ::Aabb - { - public: - GM_CLASS_ALLOCATOR(DynamicTreeAabb); - - AZ_FORCE_INLINE explicit DynamicTreeAabb() {} - AZ_FORCE_INLINE DynamicTreeAabb(const AZ::Aabb& aabb) : AZ::Aabb(aabb) {} - AZ_FORCE_INLINE explicit DynamicTreeAabb(const AZ::Vector3& min,const AZ::Vector3& max) : AZ::Aabb(AZ::Aabb::CreateFromMinMax(min,max)) {} - - AZ_FORCE_INLINE static DynamicTreeAabb CreateFromFacePoints(const AZ::Vector3& a, const AZ::Vector3& b, const AZ::Vector3& c) - { - DynamicTreeAabb vol(a,a); - vol.AddPoint(b); - vol.AddPoint(c); - return vol; - } - - AZ_FORCE_INLINE void SignedExpand(const AZ::Vector3& e) - { - AZ::Vector3 zero = AZ::Vector3::CreateZero(); - AZ::Vector3 mxE = m_max + e; - AZ::Vector3 miE = m_min + e; - m_max = AZ::Vector3::CreateSelectCmpGreater(e,zero,mxE,m_max ); - m_min = AZ::Vector3::CreateSelectCmpGreater(e,zero,m_min,miE); - } - AZ_FORCE_INLINE int Classify(const AZ::Vector3& n,const float o,int s) const - { - AZ::Vector3 pi, px; - switch(s) - { - case (0+0+0): px=m_min; - pi=m_max; break; - case (1+0+0): px=AZ::Vector3(m_max.GetX(),m_min.GetY(),m_min.GetZ()); - pi=AZ::Vector3(m_min.GetX(),m_max.GetY(),m_max.GetZ());break; - case (0+2+0): px=AZ::Vector3(m_min.GetX(),m_max.GetY(),m_min.GetZ()); - pi=AZ::Vector3(m_max.GetX(),m_min.GetY(),m_max.GetZ());break; - case (1+2+0): px=AZ::Vector3(m_max.GetX(),m_max.GetY(),m_min.GetZ()); - pi=AZ::Vector3(m_min.GetX(),m_min.GetY(),m_max.GetZ());break; - case (0+0+4): px=AZ::Vector3(m_min.GetX(),m_min.GetY(),m_max.GetZ()); - pi=AZ::Vector3(m_max.GetX(),m_max.GetY(),m_min.GetZ());break; - case (1+0+4): px=AZ::Vector3(m_max.GetX(),m_min.GetY(),m_max.GetZ()); - pi=AZ::Vector3(m_min.GetX(),m_max.GetY(),m_min.GetZ());break; - case (0+2+4): px=AZ::Vector3(m_min.GetX(),m_max.GetY(),m_max.GetZ()); - pi=AZ::Vector3(m_max.GetX(),m_min.GetY(),m_min.GetZ());break; - case (1+2+4): px=m_max; - pi=m_min;break; - } - - if (n.Dot(px) + o < 0.0f) - { - return -1; - } - if (n.Dot(pi) + o > 0.0f) - { - return 1; - } - - return 0; - } - AZ_FORCE_INLINE float ProjectMinimum(const AZ::Vector3& v, unsigned signs) const - { - const AZ::Vector3* b[]={&m_max,&m_min}; - const AZ::Vector3 p( b[(signs>>0)&1]->GetX(),b[(signs>>1)&1]->GetY(),b[(signs>>2)&1]->GetZ()); - return p.Dot(v); - } - - // Move the code here - AZ_FORCE_INLINE friend bool IntersectAabbAabb(const DynamicTreeAabb& a,const DynamicTreeAabb& b); - AZ_FORCE_INLINE friend bool IntersectAabbPoint(const DynamicTreeAabb& a, const AZ::Vector3& b); - AZ_FORCE_INLINE friend bool IntersectAabbPlane(const DynamicTreeAabb& a, const AZ::Plane& b); - AZ_FORCE_INLINE friend float Proximity(const DynamicTreeAabb& a, const DynamicTreeAabb& b); - AZ_FORCE_INLINE friend int Select(const DynamicTreeAabb& o, const DynamicTreeAabb& a, const DynamicTreeAabb& b); - AZ_FORCE_INLINE friend void Merge(const DynamicTreeAabb& a, const DynamicTreeAabb& b, DynamicTreeAabb& r); - AZ_FORCE_INLINE friend bool NotEqual(const DynamicTreeAabb& a, const DynamicTreeAabb& b); - private: - AZ_FORCE_INLINE void AddSpan(const AZ::Vector3& d, float& smi, float& smx) const - { - AZ::Vector3 vecZero = AZ::Vector3::CreateZero(); - AZ::Vector3 mxD = m_max*d; - AZ::Vector3 miD = m_min*d; - AZ::Vector3 smiAdd = AZ::Vector3::CreateSelectCmpGreater(vecZero,d,mxD,miD); - AZ::Vector3 smxAdd = AZ::Vector3::CreateSelectCmpGreater(vecZero,d,miD,mxD); - AZ::Vector3 vecOne = AZ::Vector3::CreateOne(); - // sum components - smi += smiAdd.Dot(vecOne); - smx += smxAdd.Dot(vecOne); - } - }; - - // - AZ_FORCE_INLINE bool IntersectAabbAabb(const DynamicTreeAabb& a, const DynamicTreeAabb& b) - { - return a.Overlaps(b); - } - - AZ_FORCE_INLINE bool IntersectAabbPlane(const DynamicTreeAabb& a, const AZ::Plane& b) - { - //use plane normal to quickly select the nearest corner of the aabb - AZ::Vector3 testPoint = AZ::Vector3::CreateSelectCmpGreater(b.GetNormal(), AZ::Vector3::CreateZero(), a.GetMin(), a.GetMax()); - //test if nearest point is inside the plane - return b.GetPointDist(testPoint) <= 0.0f; - } - - // - AZ_FORCE_INLINE float Proximity(const DynamicTreeAabb& a, const DynamicTreeAabb& b) - { - const AZ::Vector3 d=(a.m_min+a.m_max)-(b.m_min+b.m_max); - // get abs and sum - return d.GetAbs().Dot(AZ::Vector3::CreateOne()); - } - - // - AZ_FORCE_INLINE int Select( const DynamicTreeAabb& o, const DynamicTreeAabb& a, const DynamicTreeAabb& b) - { - return Proximity(o,a) < Proximity(o,b); - } - - // - AZ_FORCE_INLINE void Merge(const DynamicTreeAabb& a, const DynamicTreeAabb& b, DynamicTreeAabb& r) - { - r.m_min = AZ::Vector3::CreateSelectCmpGreater(b.m_min,a.m_min,a.m_min,b.m_min); - r.m_max = AZ::Vector3::CreateSelectCmpGreater(a.m_max,b.m_max,a.m_max,b.m_max); - } - - // - AZ_FORCE_INLINE bool NotEqual( const DynamicTreeAabb& a, const DynamicTreeAabb& b) - { - return (a.m_min != b.m_min || a.m_max != b.m_max); - } - - - /* NodeType */ - struct DynamicTreeNode - { - GM_CLASS_ALLOCATOR(DynamicTreeNode); - - DynamicTreeAabb m_volume; - DynamicTreeNode* m_parent; - AZ_FORCE_INLINE bool IsLeaf() const { return(m_childs[1]==0); } - AZ_FORCE_INLINE bool IsInternal() const { return(!IsLeaf()); } - union - { - DynamicTreeNode* m_childs[2]; - void* m_data; - int m_dataAsInt; - }; - }; - } - - /** - * Implementation of dynamic aabb tree, based on the bullet dynamic tree (btDbvt). - * - * The BvDynamicTree class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree). - * This BvDynamicTree is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes. - * Unlike the BvTreeQuantized, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. - */ - class BvDynamicTree - { - public: - using Ptr = AZStd::intrusive_ptr; - - GM_CLASS_ALLOCATOR(BvDynamicTree); - - typedef Internal::DynamicTreeAabb VolumeType; - typedef Internal::DynamicTreeNode NodeType; - - typedef vector NodeArrayType; - typedef vector ConstNodeArrayType; - - private: - - /* Stack element */ - struct sStkNN - { - const NodeType* a; - const NodeType* b; - sStkNN() {} - sStkNN(const NodeType* na,const NodeType* nb) : a(na), b(nb) {} - }; - struct sStkNP - { - const NodeType* node; - int mask; - sStkNP(const NodeType* n, unsigned m) : node(n), mask(m) {} - }; - struct sStkNPS - { - const NodeType* node; - int mask; - float value; - sStkNPS() {} - sStkNPS(const NodeType* n, unsigned m, const float v) : node(n), mask(m), value(v) {} - }; - struct sStkCLN - { - const NodeType* node; - NodeType* parent; - sStkCLN(const NodeType* n, NodeType* p) : node(n), parent(p) {} - }; - - public: - /* ICollideCollector templated collectors should implement this functions or inherit from this class */ - struct ICollideCollector - { - void Process(const NodeType*, const NodeType*) {} - void Process(const NodeType*) {} - void Process(const NodeType* n, const float) { Process(n); } - bool Descent(const NodeType*) { return true; } - bool AllLeaves(const NodeType*) { return true; } - }; - - /* IWriter */ - struct IWriter - { - virtual ~IWriter() {} - virtual void Prepare(const NodeType* root,int numnodes) = 0; - virtual void WriteNode(const NodeType*, int index, int parent, int child0, int child1) = 0; - virtual void WriteLeaf(const NodeType*, int index, int parent) = 0; - }; - /* IClone */ - struct IClone - { - virtual ~IClone() {} - virtual void CloneLeaf(NodeType*) {} - }; - - // Constants - enum - { - SIMPLE_STACKSIZE = 64, - DOUBLE_STACKSIZE = SIMPLE_STACKSIZE * 2 - }; - - // Methods - BvDynamicTree(); - ~BvDynamicTree(); - - NodeType* GetRoot() const { return m_root; } - void Clear(); - bool Empty() const { return 0 == m_root; } - int GetNumLeaves() const { return m_leaves; } - void OptimizeBottomUp(); - void OptimizeTopDown(int bu_treshold = 128); - void OptimizeIncremental(int passes); - NodeType* Insert(const VolumeType& box,void* data); - void Update(NodeType* leaf, int lookahead=-1); - void Update(NodeType* leaf, VolumeType& volume); - bool Update(NodeType* leaf, VolumeType& volume, const AZ::Vector3& velocity, const float margin); - bool Update(NodeType* leaf, VolumeType& volume, const AZ::Vector3& velocity); - bool Update(NodeType* leaf, VolumeType& volume, const float margin); - void Remove(NodeType* leaf); - void Write(IWriter* iwriter) const; - void Clone(BvDynamicTree& dest, IClone* iclone=0) const; - static int GetMaxDepth(const NodeType* node); - static int CountLeaves(const NodeType* node); - static void ExtractLeaves(const NodeType* node, /*btAlignedObjectArray&*/vector& leaves); - #if DBVT_ENABLE_BENCHMARK - static void Benchmark(); - #else - static void Benchmark(){} - #endif - /** - * Collector should inherit from ICollide - */ - template - static inline void enumNodes( const NodeType* root, Collector& collector) - { - collector.Process(root); - if(root->IsInternal()) - { - enumNodes(root->m_childs[0],collector); - enumNodes(root->m_childs[1],collector); - } - } - template - static void enumLeaves( const NodeType* root,Collector& collector) - { - if(root->IsInternal()) - { - enumLeaves(root->m_childs[0],collector); - enumLeaves(root->m_childs[1],collector); - } - else - { - collector.Process(root); - } - } - template - void collideTT( const NodeType* root0,const NodeType* root1,Collector& collector) const - { - if(root0&&root1) - { - size_t depth=1; - size_t treshold=DOUBLE_STACKSIZE-4; - vector stkStack; - stkStack.resize(DOUBLE_STACKSIZE); - stkStack[0]=sStkNN(root0,root1); - do { - sStkNN p=stkStack[--depth]; - if(depth>treshold) - { - stkStack.resize(stkStack.size()*2); - treshold=stkStack.size()-4; - } - if(p.a==p.b) - { - if(p.a->IsInternal()) - { - stkStack[depth++]=sStkNN(p.a->m_childs[0],p.a->m_childs[0]); - stkStack[depth++]=sStkNN(p.a->m_childs[1],p.a->m_childs[1]); - stkStack[depth++]=sStkNN(p.a->m_childs[0],p.a->m_childs[1]); - } - } - else if(IntersectAabbAabb(p.a->m_volume,p.b->m_volume)) - { - if(p.a->IsInternal()) - { - if(p.b->IsInternal()) - { - stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b->m_childs[0]); - stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b->m_childs[0]); - stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b->m_childs[1]); - stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b->m_childs[1]); - } - else - { - stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b); - stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b); - } - } - else - { - if(p.b->IsInternal()) - { - stkStack[depth++]=sStkNN(p.a,p.b->m_childs[0]); - stkStack[depth++]=sStkNN(p.a,p.b->m_childs[1]); - } - else - { - collector.Process(p.a,p.b); - } - } - } - } while(depth); - } - } - template - void collideTTpersistentStack( const NodeType* root0, const NodeType* root1,Collector& collector) - { - if(root0&&root1) - { - size_t depth=1; - size_t treshold=DOUBLE_STACKSIZE-4; - - m_stkStack.resize(DOUBLE_STACKSIZE); - m_stkStack[0]=sStkNN(root0,root1); - do - { - sStkNN p=m_stkStack[--depth]; - if(depth>treshold) - { - m_stkStack.resize(m_stkStack.size()*2); - treshold=m_stkStack.size()-4; - } - if(p.a==p.b) - { - if(p.a->IsInternal()) - { - m_stkStack[depth++]=sStkNN(p.a->m_childs[0],p.a->m_childs[0]); - m_stkStack[depth++]=sStkNN(p.a->m_childs[1],p.a->m_childs[1]); - m_stkStack[depth++]=sStkNN(p.a->m_childs[0],p.a->m_childs[1]); - } - } - else if(IntersectAabbAabb(p.a->m_volume,p.b->m_volume)) - { - if(p.a->IsInternal()) - { - if(p.b->IsInternal()) - { - m_stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b->m_childs[0]); - m_stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b->m_childs[0]); - m_stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b->m_childs[1]); - m_stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b->m_childs[1]); - } - else - { - m_stkStack[depth++]=sStkNN(p.a->m_childs[0],p.b); - m_stkStack[depth++]=sStkNN(p.a->m_childs[1],p.b); - } - } - else - { - if(p.b->IsInternal()) - { - m_stkStack[depth++]=sStkNN(p.a,p.b->m_childs[0]); - m_stkStack[depth++]=sStkNN(p.a,p.b->m_childs[1]); - } - else - { - collector.Process(p.a,p.b); - } - } - } - } while(depth); - } - } - template - void collideTV( const NodeType* root, const VolumeType& volume, Collector& collector) const - { - if(root) - { -// ATTRIBUTE_ALIGNED16(VolumeType) volume(vol); -// btAlignedObjectArray stack; - AZStd::fixed_vector stack; - //stack.reserve(SIMPLE_STACKSIZE); - stack.push_back(root); - do { - const NodeType* n=stack[stack.size()-1]; - stack.pop_back(); - if(IntersectAabbAabb(n->m_volume,volume)) - { - if(n->IsInternal()) - { - stack.push_back(n->m_childs[0]); - stack.push_back(n->m_childs[1]); - } - else - { - collector.Process(n); - } - } - } while(!stack.empty()); - } - } - - template - void collideTP(const NodeType* root, const AZ::Plane& plane, Collector& collector) const - { - if (root) - { - AZStd::fixed_vector stack; - stack.push_back(root); - do - { - const NodeType* n=stack[stack.size()-1]; - stack.pop_back(); - if (IntersectAabbPlane(n->m_volume, plane)) - { - if(n->IsInternal()) - { - stack.push_back(n->m_childs[0]); - stack.push_back(n->m_childs[1]); - } - else - { - collector.Process(n); - } - } - } while (!stack.empty()); - } - } - - ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc) - ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time - template - static void rayTest( const NodeType* root, const AZ::Vector3& rayFrom, const AZ::Vector3& rayTo, Collector& collector) - { - if(root) - { - AZ::Vector3 ray = rayTo-rayFrom; - AZ::Vector3 rayDir = ray.GetNormalized(); - - ///what about division by zero? --> just set rayDirection[i] to INF/1e30 - AZ::Vector3 rayDirectionInverse = AZ::Vector3::CreateSelectCmpEqual(rayDir,AZ::Vector3::CreateZero(),AZ::Vector3(1e30),rayDir.GetReciprocal()); - - unsigned int signs[3];// = { rayDirectionInverse[0] < 0.0f, rayDirectionInverse[1] < 0.0f, rayDirectionInverse[2] < 0.0f }; - signs[0] = rayDirectionInverse.GetX() < 0.0f; - signs[1] = rayDirectionInverse.GetY() < 0.0f; - signs[2] = rayDirectionInverse.GetZ() < 0.0f; - - //float lambda_max = rayDir.Dot(ray); - - AZ::Vector3 resultNormal; - - //btAlignedObjectArray stack; - vector stack; - - int depth=1; - int treshold=DOUBLE_STACKSIZE-2; - - stack.resize(DOUBLE_STACKSIZE); - stack[0]=root; - AZ::Vector3 bounds[2]; - do { - const NodeType* node=stack[--depth]; - - bounds[0] = node->m_volume.GetMin(); - bounds[1] = node->m_volume.GetMax(); - - //float tmin = 1.0f; - //float lambda_min = 0.0f; - // todo.. - unsigned int result1 = /*btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max)*/0; -#ifdef COMPARE_BTRAY_AABB2 - float param = 1.0f; - bool result2 = /*btRayAabb(rayFrom,rayTo,node->volume.GetMin(),node->volume.GetMax(),param,resultNormal)*/0; - AZ_Assert(result1 == result2, ""); -#endif //TEST_BTRAY_AABB2 - if(result1) - { - if(node->IsInternal()) - { - if(depth>treshold) - { - stack.resize(stack.size()*2); - treshold=stack.size()-2; - } - stack[depth++]=node->m_childs[0]; - stack[depth++]=node->m_childs[1]; - } - else - { - collector.Process(node); - } - } - } while(depth); - - } - } - - ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections - ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts - template - void rayTestInternal(const NodeType* root, const AZ::Vector3& rayFrom, const AZ::Vector3& rayTo, const AZ::Vector3& rayDirectionInverse, unsigned int signs[3], const float lambda_max, const AZ::Vector3& aabbMin, const AZ::Vector3& aabbMax, Collector& collector) const - { - (void)rayFrom;(void)rayTo;(void)rayDirectionInverse;(void)signs;(void)lambda_max; - if(root) - { - AZ::Vector3 resultNormal; - - int depth=1; - int treshold=DOUBLE_STACKSIZE-2; - vector stack; - stack.resize(DOUBLE_STACKSIZE); - stack[0]=root; - AZ::Vector3 bounds[2]; - do - { - const NodeType* node=stack[--depth]; - bounds[0] = node->m_volume.GetMin()+aabbMin; - bounds[1] = node->m_volume.GetMax()+aabbMax; - - //float tmin = 1.0f; - //float lambda_min = 0.0f; - unsigned int result1=false; - // todo... - result1 = /*btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max)*/false; - if(result1) - { - if(node->IsInternal()) - { - if(depth>treshold) - { - stack.resize(stack.size()*2); - treshold=stack.size()-2; - } - stack[depth++]=node->m_childs[0]; - stack[depth++]=node->m_childs[1]; - } - else - { - collector.Process(node); - } - } - } while(depth); - } - } - - template - static void collideKDOP(const NodeType* root, const AZ::Vector3* normals, const float* offsets, int count, Collector& collector) - { - (void)root;(void)normals;(void)offsets;(void)count;(void)collector; -/* if(root) - { - const int inside=(1< stack; - int signs[sizeof(unsigned)*8]; - btAssert(count=0)?1:0)+ - ((normals[i].y()>=0)?2:0)+ - ((normals[i].z()>=0)?4:0); - } - stack.reserve(SIMPLE_STACKSIZE); - stack.push_back(sStkNP(root,0)); - do { - sStkNP se=stack[stack.size()-1]; - bool out=false; - stack.pop_back(); - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(!out) - { - if((se.mask!=inside)&&(se.node->isinternal())) - { - stack.push_back(sStkNP(se.node->childs[0],se.mask)); - stack.push_back(sStkNP(se.node->childs[1],se.mask)); - } - else - { - if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); - } - } - } while(!stack.empty()); - }*/ - } - template - static void collideOCL( const NodeType* root, const AZ::Vector3* normals, const float* offsets, const AZ::Vector3& sortaxis, int count, Collector& collector, bool fullsort=true) - { - (void)root;(void)normals;(void)offsets;(void)sortaxis;(void)count;(void)offsets;(void)collector;(void)fullsort; -/* if(root) - { - const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ - (sortaxis[1]>=0?2:0)+ - (sortaxis[2]>=0?4:0); - const int inside=(1< stock; - btAlignedObjectArray ifree; - btAlignedObjectArray stack; - int signs[sizeof(unsigned)*8]; - btAssert(count=0)?1:0)+ - ((normals[i].y()>=0)?2:0)+ - ((normals[i].z()>=0)?4:0); - } - stock.reserve(SIMPLE_STACKSIZE); - stack.reserve(SIMPLE_STACKSIZE); - ifree.reserve(SIMPLE_STACKSIZE); - stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); - do { - const int id=stack[stack.size()-1]; - sStkNPS se=stock[id]; - stack.pop_back();ifree.push_back(id); - if(se.mask!=inside) - { - bool out=false; - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(out) continue; - } - if(policy.Descent(se.node)) - { - if(se.node->isinternal()) - { - const NodeType* pns[]={ se.node->childs[0],se.node->childs[1]}; - sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), - sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; - const int q=nes[0].value0)) - { - // Insert 0 - j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); - stack.push_back(0); -#if DBVT_USE_MEMMOVE - memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); -#else - for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; -#endif - stack[j]=allocate(ifree,stock,nes[q]); - // Insert 1 - j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); - stack.push_back(0); -#if DBVT_USE_MEMMOVE - memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); -#else - for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; -#endif - stack[j]=allocate(ifree,stock,nes[1-q]); - } - else - { - stack.push_back(allocate(ifree,stock,nes[q])); - stack.push_back(allocate(ifree,stock,nes[1-q])); - } - } - else - { - policy.Process(se.node,se.value); - } - } - } while(stack.size()); - }*/ - } - - template - static void collideTU(const NodeType* root, Collector& collector) - { - (void)root;(void)collector; -/* if(root) - { - btAlignedObjectArray stack; - stack.reserve(SIMPLE_STACKSIZE); - stack.push_back(root); - do { - const NodeType* n=stack[stack.size()-1]; - stack.pop_back(); - if(policy.Descent(n)) - { - if(n->isinternal()) - { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } - else - { policy.Process(n); } - } - } while(stack.size()>0); - }*/ - } - - private: - BvDynamicTree(const BvDynamicTree&) {} - - // Helpers - //static AZ_FORCE_INLINE int nearest(const int* i,const BvDynamicTree::sStkNPS* a,const float& v,int l,int h) - //{ - // int m=0; - // while(l>1; - // if(a[i[m]].value>=v) l=m+1; else h=m; - // } - // return h; - //} - //static AZ_FORCE_INLINE int allocate( int_fixed_stack_type& ifree, stknps_fixed_stack_type& stock, const sStkNPS& value) - //{ - // int i; - // if( !ifree.empty() ) - // { - // i=ifree[ifree.size()-1]; - // ifree.pop_back(); - // stock[i]=value; - // } - // else - // { - // i=stock.size(); - // stock.push_back(value); - // } - // return i; - //} - // - - AZ_FORCE_INLINE void deletenode( NodeType* node) - { - //btAlignedFree(pdbvt->m_free); - delete m_free; - m_free=node; - } - - void recursedeletenode( NodeType* node) - { - if(!node->IsLeaf()) - { - recursedeletenode(node->m_childs[0]); - recursedeletenode(node->m_childs[1]); - } - - if( node == m_root ) m_root=0; - deletenode(node); - } - - - AZ_FORCE_INLINE NodeType* createnode( NodeType* parent, void* data) - { - NodeType* node; - if(m_free) - { node=m_free;m_free=0; } - else - { node = aznew NodeType(); } - node->m_parent = parent; - node->m_data = data; - node->m_childs[1] = 0; - return node; - } - AZ_FORCE_INLINE NodeType* createnode( BvDynamicTree::NodeType* parent, const VolumeType& volume, void* data) - { - NodeType* node = createnode(parent,data); - node->m_volume=volume; - return node; - } - // - AZ_FORCE_INLINE NodeType* createnode( BvDynamicTree::NodeType* parent, const VolumeType& volume0, const VolumeType& volume1, void* data) - { - NodeType* node = createnode(parent,data); - Merge(volume0,volume1,node->m_volume); - return node; - } - void insertleaf( NodeType* root, NodeType* leaf); - NodeType* removeleaf( NodeType* leaf); - void fetchleaves(NodeType* root,NodeArrayType& leaves,int depth=-1); - void split(const NodeArrayType& leaves,NodeArrayType& left,NodeArrayType& right,const AZ::Vector3& org,const AZ::Vector3& axis); - VolumeType bounds(const NodeArrayType& leaves); - void bottomup( NodeArrayType& leaves ); - NodeType* topdown(NodeArrayType& leaves,int bu_treshold); - AZ_FORCE_INLINE NodeType* sort(NodeType* n,NodeType*& r); - - NodeType* m_root; - NodeType* m_free; - int m_lkhd; - int m_leaves; - unsigned m_opath; - - //btAlignedObjectArray m_stkStack; - // Profile and choose static or dynamic vector. - typedef AZStd::fixed_vector stknn_fixed_stack_type; - typedef AZStd::fixed_vector int_fixed_stack_type; - typedef AZStd::fixed_vector stknps_fixed_stack_type; - - stknn_fixed_stack_type m_stkStack; - }; -} - -#endif // RR_DYNAMIC_BOUNDING_VOLUME_TREE_H -#pragma once diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp deleted file mode 100644 index 13a0151bc7..0000000000 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp +++ /dev/null @@ -1,597 +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. -* -*/ - -#include - -#include -#include -#include - -#include -#include - -// for highly verbose internal debugging -//#define INTERNAL_DEBUG_PROXIMITY - -namespace GridMate -{ - - void ProximityInterestChunk::OnReplicaActivate(const ReplicaContext& rc) - { - m_interestHandler = static_cast(rc.m_rm->GetUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4))); - AZ_Warning("GridMate", m_interestHandler, "No proximity interest handler in the user context"); - - if (m_interestHandler) - { - m_interestHandler->OnNewRulesChunk(this, rc.m_peer); - } - } - - void ProximityInterestChunk::OnReplicaDeactivate(const ReplicaContext& rc) - { - if (rc.m_peer && m_interestHandler) - { - m_interestHandler->OnDeleteRulesChunk(this, rc.m_peer); - } - } - - bool ProximityInterestChunk::AddRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext& ctx) - { - if (IsProxy()) - { - auto rulePtr = m_interestHandler->CreateRule(ctx.m_sourcePeer); - rulePtr->Set(bbox); - m_rules.insert(AZStd::make_pair(netId, rulePtr)); - } - - return true; - } - - bool ProximityInterestChunk::RemoveRuleFn(RuleNetworkId netId, const RpcContext&) - { - if (IsProxy()) - { - m_rules.erase(netId); - } - - return true; - } - - bool ProximityInterestChunk::UpdateRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext&) - { - if (IsProxy()) - { - auto it = m_rules.find(netId); - if (it != m_rules.end()) - { - it->second->Set(bbox); - } - } - - return true; - } - - bool ProximityInterestChunk::AddRuleForPeerFn(RuleNetworkId netId, PeerId peerId, AZ::Aabb bbox, const RpcContext&) - { - ProximityInterestChunk* peerChunk = m_interestHandler->FindRulesChunkByPeerId(peerId); - if (peerChunk) - { - auto it = peerChunk->m_rules.find(netId); - if (it == peerChunk->m_rules.end()) - { - auto rulePtr = m_interestHandler->CreateRule(peerId); - peerChunk->m_rules.insert(AZStd::make_pair(netId, rulePtr)); - rulePtr->Set(bbox); - } - } - return false; - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterest - */ - ProximityInterest::ProximityInterest(ProximityInterestHandler* handler) - : m_handler(handler) - , m_bbox(AZ::Aabb::CreateNull()) - { - AZ_Assert(m_handler, "Invalid interest handler"); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestRule - */ - void ProximityInterestRule::Set(const AZ::Aabb& bbox) - { - m_bbox = bbox; - m_handler->UpdateRule(this); - } - - void ProximityInterestRule::Destroy() - { - m_handler->DestroyRule(this); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestAttribute - */ - void ProximityInterestAttribute::Set(const AZ::Aabb& bbox) - { - m_bbox = bbox; - m_handler->UpdateAttribute(this); - } - - void ProximityInterestAttribute::Destroy() - { - m_handler->DestroyAttribute(this); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestHandler - */ - ProximityInterestHandler::ProximityInterestHandler() - : m_im(nullptr) - , m_rm(nullptr) - , m_lastRuleNetId(0) - , m_rulesReplica(nullptr) - { - m_attributeWorld = AZStd::make_unique(); - AZ_Assert(m_attributeWorld, "Out of memory"); - } - - ProximityInterestRule::Ptr ProximityInterestHandler::CreateRule(PeerId peerId) - { - ProximityInterestRule* rulePtr = aznew ProximityInterestRule(this, peerId, GetNewRuleNetId()); - if (m_rm && peerId == m_rm->GetLocalPeerId()) - { - m_rulesReplica->AddRuleRpc(rulePtr->GetNetworkId(), rulePtr->Get()); - } - - CreateAndInsertIntoSpatialStructure(rulePtr); - - return rulePtr; - } - - ProximityInterestAttribute::Ptr ProximityInterestHandler::CreateAttribute(ReplicaId replicaId) - { - auto newAttribute = aznew ProximityInterestAttribute(this, replicaId); - AZ_Assert(newAttribute, "Out of memory"); - - CreateAndInsertIntoSpatialStructure(newAttribute); - - return newAttribute; - } - - void ProximityInterestHandler::FreeRule(ProximityInterestRule* rule) - { - //TODO: should be pool-allocated - delete rule; - } - - void ProximityInterestHandler::DestroyRule(ProximityInterestRule* rule) - { - if (m_rm && rule->GetPeerId() == m_rm->GetLocalPeerId()) - { - m_rulesReplica->RemoveRuleRpc(rule->GetNetworkId()); - } - - MarkAttributesDirtyInRule(rule); - - rule->m_bbox = AZ::Aabb::CreateNull(); - m_removedRules.insert(rule); - m_localRules.erase(rule); - } - - void ProximityInterestHandler::UpdateRule(ProximityInterestRule* rule) - { - if (m_rm && rule->GetPeerId() == m_rm->GetLocalPeerId()) - { - m_rulesReplica->UpdateRuleRpc(rule->GetNetworkId(), rule->Get()); - } - - m_dirtyRules.insert(rule); - } - - void ProximityInterestHandler::FreeAttribute(ProximityInterestAttribute* attrib) - { - delete attrib; - } - - void ProximityInterestHandler::DestroyAttribute(ProximityInterestAttribute* attrib) - { - RemoveFromSpatialStructure(attrib); - - m_attributes.erase(attrib); - m_removedAttributes.insert(attrib); - } - - void ProximityInterestHandler::RemoveFromSpatialStructure(ProximityInterestAttribute* attribute) - { - attribute->m_bbox = AZ::Aabb::CreateNull(); - m_attributeWorld->Remove(attribute->GetNode()); - attribute->SetNode(nullptr); - } - - void ProximityInterestHandler::UpdateAttribute(ProximityInterestAttribute* attrib) - { - auto node = attrib->GetNode(); - AZ_Assert(node, "Attribute wasn't created correctly"); - node->m_volume = attrib->Get(); - m_attributeWorld->Update(node); - - m_dirtyAttributes.insert(attrib); - } - - void ProximityInterestHandler::OnNewRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer) - { - if (chunk != m_rulesReplica) // non-local - { - m_peerChunks.insert(AZStd::make_pair(peer->GetId(), chunk)); - - for (auto& rule : m_localRules) - { - chunk->AddRuleForPeerRpc(rule->GetNetworkId(), rule->GetPeerId(), rule->Get()); - } - } - } - - void ProximityInterestHandler::OnDeleteRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer) - { - (void)chunk; - m_peerChunks.erase(peer->GetId()); - } - - RuleNetworkId ProximityInterestHandler::GetNewRuleNetId() - { - ++m_lastRuleNetId; - - if (m_rulesReplica) - { - return m_rulesReplica->GetReplicaId() | (static_cast(m_lastRuleNetId) << 32); - } - - return (static_cast(m_lastRuleNetId) << 32); - } - - ProximityInterestChunk* ProximityInterestHandler::FindRulesChunkByPeerId(PeerId peerId) - { - auto it = m_peerChunks.find(peerId); - if (it == m_peerChunks.end()) - { - return nullptr; - } - - return it->second; - } - - const InterestMatchResult& ProximityInterestHandler::GetLastResult() - { - return m_resultCache; - } - - ProximityInterestHandler::RuleSet& ProximityInterestHandler::GetAffectedRules() - { - /* - * The expectation that lots of attributes will change frequently, - * so there is no point in trying to optimize cases - * where only a few attributes have changed. - */ - if (m_dirtyAttributes.empty() && !m_dirtyRules.empty()) - { - return m_dirtyRules; - } - - /* - * Assuming all rules might have been affected. - * - * There is an optimization chance here if the number of rules is large, as in 1,000+ rules. - * To handle such scale we would need another spatial structure for rules. - */ - return m_localRules; - } - - void ProximityInterestHandler::GetAttributesWithinRule(ProximityInterestRule* rule, SpatialIndex::NodeCollector& nodes) - { - m_attributeWorld->Query(rule->Get(), nodes); - } - - void ProximityInterestHandler::ClearDirtyState() - { - m_dirtyAttributes.clear(); - m_dirtyRules.clear(); - } - - void ProximityInterestHandler::CreateAndInsertIntoSpatialStructure(ProximityInterestAttribute* attribute) - { - m_attributes.insert(attribute); - SpatialIndex::Node* node = m_attributeWorld->Insert(attribute->Get(), attribute); - attribute->SetNode(node); - } - - void ProximityInterestHandler::CreateAndInsertIntoSpatialStructure(ProximityInterestRule* rule) - { - m_localRules.insert(rule); - } - - void ProximityInterestHandler::UpdateInternal(InterestMatchResult& result) - { - /* - * The goal is to return all dirty attributes that were either dirty because: - * 1) they changed which rules have apply to - * 2) rules have changed and no longer apply to those attributes - * and thus resulted in different peer(s) associated with a given replica. - */ - - const RuleSet& rules = GetAffectedRules(); - - for (auto& dirtyAttribute : m_dirtyAttributes) - { - result.insert(dirtyAttribute->GetReplicaId()); - } - - /* - * The exectation is to have a lot more attributes than rules. - * The amount of rules should grow linear with amount of peers, - * so it should be OK to iterate through all rules each update. - */ - for (auto& rule : rules) - { - CheckChangesForRule(rule, result); - } - - for (auto& removedRule : m_removedRules) - { - FreeRule(removedRule); - } - m_removedRules.clear(); - - // mark removed attribute as having no peers - for (auto& removedAttribute : m_removedAttributes) - { - result.insert(removedAttribute->GetReplicaId()); - FreeAttribute(removedAttribute); - } - m_removedAttributes.clear(); - } - - void ProximityInterestHandler::CheckChangesForRule(ProximityInterestRule* rule, InterestMatchResult& result) - { - SpatialIndex::NodeCollector collector; - GetAttributesWithinRule(rule, collector); - - auto peerId = rule->GetPeerId(); - for (ProximityInterestAttribute* attr : collector.GetNodes()) - { - AZ_Assert(attr, "bad node?"); - - auto findIt = result.find(attr->GetReplicaId()); - if (findIt != result.end()) - { - findIt->second.insert(peerId); - } - else - { - auto resultIt = result.insert(attr->GetReplicaId()); - AZ_Assert(resultIt.second, "Successfully inserted"); - resultIt.first->second.insert(peerId); - } - } - } - - void ProximityInterestHandler::MarkAttributesDirtyInRule(ProximityInterestRule* rule) - { - SpatialIndex::NodeCollector collector; - GetAttributesWithinRule(rule, collector); - - for (ProximityInterestAttribute* attr : collector.GetNodes()) - { - AZ_Assert(attr, "bad node?"); - - UpdateAttribute(attr); - } - } - - void ProximityInterestHandler::ProduceChanges(const InterestMatchResult& before, const InterestMatchResult& after) - { - m_resultCache.clear(); - -#if defined(INTERNAL_DEBUG_PROXIMITY) - before.PrintMatchResult("before"); - after.PrintMatchResult("after"); -#endif - - /* - * 'after' contains only the stuff that might have changed - */ - for (auto& possiblyDirty : after) - { - ReplicaId repId = possiblyDirty.first; - const InterestPeerSet& peerSet = possiblyDirty.second; - - auto foundInBefore = before.find(repId); - if (foundInBefore != before.end()) - { - if (!HasSamePeers(foundInBefore->second, peerSet)) - { - // was in the last calculation but has a different peer set now - m_resultCache.insert(AZStd::make_pair(repId, peerSet)); - } - } - else - { - // since it wasn't present during last calculation - m_resultCache.insert(AZStd::make_pair(repId, peerSet)); - } - } - - // Mark attributes (replicas) for removal that have not moved but a rule (clients) no longer sees it - for (auto& possiblyDirty : before) - { - ReplicaId repId = possiblyDirty.first; - - const auto foundInAfter = after.find(repId); - /* - * If the prior state was a replica A present on peer X: "A{X}", and now A should no longer be present on any peer: "A{}" - * then by the rules of InterestHandlers interacting with InterestManager, we should return in @m_resultCache the following: - * - * A{} - indicating that replica A must be removed all peers. - * - * On the next pass, the prior state would be: "A{}" and the current state would be "A{}" as well. At that point, we have - * already sent the update to remove A from X, so @m_resultCache should no longer mention A at all. - */ - if (foundInAfter == after.end() && !possiblyDirty.second.empty() /* "not A{}" see the above comment */) - { - m_resultCache.insert(AZStd::make_pair(repId, InterestPeerSet())); - } - } - -#if defined(INTERNAL_DEBUG_PROXIMITY) - m_resultCache.PrintMatchResult("changes"); -#endif - - } - - bool ProximityInterestHandler::HasSamePeers(const InterestPeerSet& one, const InterestPeerSet& another) - { - if (one.size() != another.size()) - { - return false; - } - - for (auto& peerFromOne : one) - { - if (another.find(peerFromOne) == another.end()) - { - return false; - } - } - - // Safe to assume it's the same sets since all entries are unique in a peer sets - return true; - } - - void ProximityInterestHandler::Update() - { - InterestMatchResult newResult; - - UpdateInternal(newResult); - ProduceChanges(m_lastResult, newResult); - - m_lastResult = std::move(newResult); - ClearDirtyState(); - } - - void ProximityInterestHandler::OnRulesHandlerRegistered(InterestManager* manager) - { - AZ_Assert(m_im == nullptr, "Handler is already registered with manager %p (%p)\n", m_im, manager); - AZ_Assert(m_rulesReplica == nullptr, "Rules replica is already created\n"); - AZ_TracePrintf("GridMate", "Proximity interest handler is registered\n"); - m_im = manager; - m_rm = m_im->GetReplicaManager(); - m_rm->RegisterUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4), this); - - auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); - m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddPrimary(replica); - } - - void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) - { - (void)manager; - AZ_Assert(m_im == manager, "Handler was not registered with manager %p (%p)\n", manager, m_im); - AZ_TracePrintf("GridMate", "Proximity interest handler is unregistered\n"); - m_rulesReplica = nullptr; - m_im = nullptr; - m_rm->UnregisterUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4)); - m_rm = nullptr; - - for (auto& chunk : m_peerChunks) - { - chunk.second->m_interestHandler = nullptr; - } - m_peerChunks.clear(); - - ClearDirtyState(); - DestroyAll(); - - m_resultCache.clear(); - } - - void ProximityInterestHandler::DestroyAll() - { - for (ProximityInterestRule* rule : m_localRules) - { - FreeRule(rule); - } - m_localRules.clear(); - - for (ProximityInterestAttribute* attr : m_attributes) - { - FreeAttribute(attr); - } - m_attributes.clear(); - - for (auto& removedRule : m_removedRules) - { - FreeRule(removedRule); - } - m_removedRules.clear(); - - for (auto& removedAttribute : m_removedAttributes) - { - FreeAttribute(removedAttribute); - } - m_removedAttributes.clear(); - } - - /////////////////////////////////////////////////////////////////////////// - ProximityInterestHandler::~ProximityInterestHandler() - { - /* - * If a handler was registered with a InterestManager, then InterestManager ought to have called OnRulesHandlerUnregistered - * but this is a safety pre-caution. - */ - DestroyAll(); - } - - SpatialIndex::SpatialIndex() - { - m_tree.reset(aznew GridMate::BvDynamicTree()); - } - - void SpatialIndex::Remove(Node* node) - { - m_tree->Remove(node); - } - - void SpatialIndex::Update(Node* node) - { - m_tree->Update(node); - } - - SpatialIndex::Node* SpatialIndex::Insert(const AZ::Aabb& get, ProximityInterestAttribute* attribute) - { - return m_tree->Insert(get, attribute); - } - - void SpatialIndex::Query(const AZ::Aabb& shape, NodeCollector& nodes) - { - m_tree->collideTV(m_tree->GetRoot(), shape, nodes); - } -} diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.h b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.h deleted file mode 100644 index 6659d44f44..0000000000 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.h +++ /dev/null @@ -1,314 +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. -* -*/ - -#ifndef GM_REPLICA_PROXIMITYINTERESTHANDLER_H -#define GM_REPLICA_PROXIMITYINTERESTHANDLER_H - -#include -#include -#include -#include -#include - -#include -#include - -namespace GridMate -{ - class ProximityInterestHandler; - class ProximityInterestAttribute; - - /* - * Base interest - */ - class ProximityInterest - { - friend class ProximityInterestHandler; - - public: - const AZ::Aabb& Get() const { return m_bbox; } - - protected: - explicit ProximityInterest(ProximityInterestHandler* handler); - - ProximityInterestHandler* m_handler; - AZ::Aabb m_bbox; - }; - /////////////////////////////////////////////////////////////////////////// - - - /* - * Proximity rule - */ - class ProximityInterestRule - : public InterestRule - , public ProximityInterest - { - friend class ProximityInterestHandler; - - public: - using Ptr = AZStd::intrusive_ptr; - - GM_CLASS_ALLOCATOR(ProximityInterestRule); - - void Set(const AZ::Aabb& bbox); - - private: - - // Intrusive ptr - template - friend struct AZStd::IntrusivePtrCountPolicy; - unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() { --m_refCount; if (!m_refCount) Destroy(); } - AZ_FORCE_INLINE bool IsDeleted() const { return m_refCount == 0; } - /////////////////////////////////////////////////////////////////////////// - - ProximityInterestRule(ProximityInterestHandler* handler, PeerId peerId, RuleNetworkId netId) - : InterestRule(peerId, netId) - , ProximityInterest(handler) - {} - - void Destroy(); - }; - /////////////////////////////////////////////////////////////////////////// - - class SpatialIndex - { - public: - typedef Internal::DynamicTreeNode Node; - - class NodeCollector - { - typedef AZStd::vector Type; - - public: - void Process(const Internal::DynamicTreeNode* node) - { - m_nodes.push_back(reinterpret_cast(node->m_data)); - } - - const Type& GetNodes() const - { - return m_nodes; - } - - private: - Type m_nodes; - }; - - SpatialIndex(); - ~SpatialIndex() = default; - - AZ_FORCE_INLINE void Remove(Node* node); - AZ_FORCE_INLINE void Update(Node* node); - AZ_FORCE_INLINE Node* Insert(const AZ::Aabb& get, ProximityInterestAttribute* attribute); - AZ_FORCE_INLINE void Query(const AZ::Aabb& get, NodeCollector& nodes); - - private: - AZStd::unique_ptr m_tree; - }; - - /* - * Proximity attribute - */ - class ProximityInterestAttribute - : public InterestAttribute - , public ProximityInterest - { - friend class ProximityInterestHandler; - template friend class InterestPtr; - - public: - using Ptr = AZStd::intrusive_ptr; - - GM_CLASS_ALLOCATOR(ProximityInterestAttribute); - - void Set(const AZ::Aabb& bbox); - - private: - - // Intrusive ptr - template - friend struct AZStd::IntrusivePtrCountPolicy; - unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() { Destroy(); } - AZ_FORCE_INLINE bool IsDeleted() const { return m_refCount == 0; } - /////////////////////////////////////////////////////////////////////////// - - ProximityInterestAttribute(ProximityInterestHandler* handler, ReplicaId repId) - : InterestAttribute(repId) - , ProximityInterest(handler) - , m_worldNode(nullptr) - {} - - void Destroy(); - - void SetNode(SpatialIndex::Node* node) { m_worldNode = node; } - SpatialIndex::Node* GetNode() const { return m_worldNode; } - SpatialIndex::Node* m_worldNode; ///< non-owning pointer - }; - /////////////////////////////////////////////////////////////////////////// - - class ProximityInterestChunk - : public ReplicaChunk - { - public: - GM_CLASS_ALLOCATOR(ProximityInterestChunk); - - // ReplicaChunk - typedef AZStd::intrusive_ptr Ptr; - bool IsReplicaMigratable() override { return false; } - bool IsBroadcast() override { return true; } - static const char* GetChunkName() { return "ProximityInterestChunk"; } - - ProximityInterestChunk() - : AddRuleRpc("AddRule") - , RemoveRuleRpc("RemoveRule") - , UpdateRuleRpc("UpdateRule") - , AddRuleForPeerRpc("AddRuleForPeerRpc") - , m_interestHandler(nullptr) - { - } - - void OnReplicaActivate(const ReplicaContext& rc) override; - void OnReplicaDeactivate(const ReplicaContext& rc) override; - - bool AddRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext& ctx); - bool RemoveRuleFn(RuleNetworkId netId, const RpcContext&); - bool UpdateRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext&); - bool AddRuleForPeerFn(RuleNetworkId netId, PeerId peerId, AZ::Aabb bbox, const RpcContext&); - - Rpc, RpcArg>::BindInterface AddRuleRpc; - Rpc>::BindInterface RemoveRuleRpc; - Rpc, RpcArg>::BindInterface UpdateRuleRpc; - - Rpc, RpcArg, RpcArg>::BindInterface AddRuleForPeerRpc; - - unordered_map m_rules; - ProximityInterestHandler* m_interestHandler; - }; - - /* - * Rules handler - */ - class ProximityInterestHandler - : public BaseRulesHandler - { - friend class ProximityInterestRule; - friend class ProximityInterestAttribute; - friend class ProximityInterestChunk; - - public: - - typedef unordered_set AttributeSet; - typedef unordered_set RuleSet; - - GM_CLASS_ALLOCATOR(ProximityInterestHandler); - - ProximityInterestHandler(); - ~ProximityInterestHandler(); - - /* - * Creates new proximity rule and binds it to the peer. - * Note: the lifetime of the created rule is tied to the lifetime of this handler. - */ - ProximityInterestRule::Ptr CreateRule(PeerId peerId); - - /* - * Creates new proximity attribute and binds it to the replica. - * Note: the lifetime of the created attribute is tied to the lifetime of this handler. - */ - ProximityInterestAttribute::Ptr CreateAttribute(ReplicaId replicaId); - - // Calculates rules and attributes matches - void Update() override; - - // Returns last recalculated results - const InterestMatchResult& GetLastResult() override; - - // Returns the manager it's bound to - InterestManager* GetManager() override { return m_im; } - - // Rules that this handler is aware of - const RuleSet& GetLocalRules() const { return m_localRules; } - - private: - - // BaseRulesHandler - void OnRulesHandlerRegistered(InterestManager* manager) override; - void OnRulesHandlerUnregistered(InterestManager* manager) override; - - void DestroyRule(ProximityInterestRule* rule); - void FreeRule(ProximityInterestRule* rule); - void UpdateRule(ProximityInterestRule* rule); - - void DestroyAttribute(ProximityInterestAttribute* attrib); - void FreeAttribute(ProximityInterestAttribute* attrib); - void UpdateAttribute(ProximityInterestAttribute* attrib); - - void OnNewRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer); - void OnDeleteRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer); - - RuleNetworkId GetNewRuleNetId(); - - ProximityInterestChunk* FindRulesChunkByPeerId(PeerId peerId); - - void DestroyAll(); - - InterestManager* m_im; - ReplicaManager* m_rm; - - AZ::u32 m_lastRuleNetId; - - unordered_map m_peerChunks; - - RuleSet m_localRules; - RuleSet m_removedRules; - RuleSet m_dirtyRules; - - AttributeSet m_attributes; - AttributeSet m_removedAttributes; - AttributeSet m_dirtyAttributes; - - ProximityInterestChunk* m_rulesReplica; - - // collection of all known attributes - AZStd::unique_ptr m_attributeWorld; - - InterestMatchResult m_resultCache; - - /////////////////////////////////////////////////////////////////////////////////////////////////// - // internal processing helpers - AZ_FORCE_INLINE RuleSet& GetAffectedRules(); - AZ_FORCE_INLINE void GetAttributesWithinRule(ProximityInterestRule* rule, SpatialIndex::NodeCollector& nodes); - AZ_FORCE_INLINE void ClearDirtyState(); - - AZ_FORCE_INLINE void CreateAndInsertIntoSpatialStructure(ProximityInterestAttribute* attribute); - AZ_FORCE_INLINE void RemoveFromSpatialStructure(ProximityInterestAttribute* attribute); - AZ_FORCE_INLINE void CreateAndInsertIntoSpatialStructure(ProximityInterestRule* rule); - - void UpdateInternal(InterestMatchResult& result); - void CheckChangesForRule(ProximityInterestRule* rule, InterestMatchResult& result); - void MarkAttributesDirtyInRule(ProximityInterestRule* rule); - - static bool HasSamePeers(const InterestPeerSet& one, const InterestPeerSet& another); - void ProduceChanges(const InterestMatchResult& before, const InterestMatchResult& after); - - InterestMatchResult m_lastResult; - /////////////////////////////////////////////////////////////////////////////////////////////////// - }; - /////////////////////////////////////////////////////////////////////////// -} - -#endif // GM_REPLICA_PROXIMITYINTERESTHANDLER_H diff --git a/Code/Framework/GridMate/GridMate/gridmate_files.cmake b/Code/Framework/GridMate/GridMate/gridmate_files.cmake index 7cc65ff69a..615ce53027 100644 --- a/Code/Framework/GridMate/GridMate/gridmate_files.cmake +++ b/Code/Framework/GridMate/GridMate/gridmate_files.cmake @@ -100,14 +100,10 @@ set(FILES Replica/Tasks/ReplicaPriorityPolicy.h Replica/Interest/BitmaskInterestHandler.cpp Replica/Interest/BitmaskInterestHandler.h - Replica/Interest/ProximityInterestHandler.cpp - Replica/Interest/ProximityInterestHandler.h Replica/Interest/InterestDefs.h Replica/Interest/InterestManager.cpp Replica/Interest/InterestManager.h Replica/Interest/InterestQueryResult.h - Replica/Interest/BvDynamicTree.cpp - Replica/Interest/BvDynamicTree.h Replica/Interest/RulesHandler.h Serialize/Buffer.cpp Serialize/Buffer.h diff --git a/Code/Framework/GridMate/Tests/Interest.cpp b/Code/Framework/GridMate/Tests/Interest.cpp deleted file mode 100644 index c449c92083..0000000000 --- a/Code/Framework/GridMate/Tests/Interest.cpp +++ /dev/null @@ -1,1823 +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. -* -*/ -#include "Tests.h" -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace GridMate; - -// An easy switch to use an old brute force ProximityInterestHandler for performance comparison. -#if 0 -namespace GridMate -{ - /* - * Base interest - */ - class ProximityInterest - { - friend class ProximityInterestHandler; - - public: - const AZ::Aabb& Get() const { return m_bbox; } - - protected: - explicit ProximityInterest(ProximityInterestHandler* handler); - - ProximityInterestHandler* m_handler; - AZ::Aabb m_bbox; - }; - /////////////////////////////////////////////////////////////////////////// - - - /* - * Proximity rule - */ - class ProximityInterestRule - : public InterestRule - , public ProximityInterest - { - friend class ProximityInterestHandler; - - public: - using Ptr = AZStd::intrusive_ptr; - - GM_CLASS_ALLOCATOR(ProximityInterestRule); - - void Set(const AZ::Aabb& bbox); - - private: - - // Intrusive ptr - template - friend struct AZStd::IntrusivePtrCountPolicy; - unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() { --m_refCount; if (!m_refCount) Destroy(); } - AZ_FORCE_INLINE bool IsDeleted() const { return m_refCount == 0; } - /////////////////////////////////////////////////////////////////////////// - - ProximityInterestRule(ProximityInterestHandler* handler, PeerId peerId, RuleNetworkId netId) - : InterestRule(peerId, netId) - , ProximityInterest(handler) - {} - - void Destroy(); - }; - /////////////////////////////////////////////////////////////////////////// - - - /* - * Proximity attribute - */ - class ProximityInterestAttribute - : public InterestAttribute - , public ProximityInterest - { - friend class ProximityInterestHandler; - template friend class InterestPtr; - - public: - using Ptr = AZStd::intrusive_ptr; - - GM_CLASS_ALLOCATOR(ProximityInterestAttribute); - - void Set(const AZ::Aabb& bbox); - - private: - - // Intrusive ptr - template - friend struct AZStd::IntrusivePtrCountPolicy; - unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() { Destroy(); } - AZ_FORCE_INLINE bool IsDeleted() const { return m_refCount == 0; } - /////////////////////////////////////////////////////////////////////////// - - ProximityInterestAttribute(ProximityInterestHandler* handler, ReplicaId repId) - : InterestAttribute(repId) - , ProximityInterest(handler) - {} - - void Destroy(); - }; - /////////////////////////////////////////////////////////////////////////// - - - /* - * Rules handler - */ - class ProximityInterestHandler - : public BaseRulesHandler - { - friend class ProximityInterestRule; - friend class ProximityInterestAttribute; - friend class ProximityInterestChunk; - - public: - - typedef unordered_set AttributeSet; - typedef unordered_set RuleSet; - - GM_CLASS_ALLOCATOR(ProximityInterestHandler); - - ProximityInterestHandler(); - - // Creates new proximity rule and binds it to the peer - ProximityInterestRule::Ptr CreateRule(PeerId peerId); - - // Creates new proximity attribute and binds it to the replica - ProximityInterestAttribute::Ptr CreateAttribute(ReplicaId replicaId); - - // Calculates rules and attributes matches - void Update() override; - - // Returns last recalculated results - const InterestMatchResult& GetLastResult() override; - - // Returns manager its bound with - InterestManager* GetManager() override { return m_im; } - - const RuleSet& GetLocalRules() { return m_localRules; } - - private: - void UpdateInternal(InterestMatchResult& result); - - // BaseRulesHandler - void OnRulesHandlerRegistered(InterestManager* manager) override; - void OnRulesHandlerUnregistered(InterestManager* manager) override; - - void DestroyRule(ProximityInterestRule* rule); - void FreeRule(ProximityInterestRule* rule); - void UpdateRule(ProximityInterestRule* rule); - - void DestroyAttribute(ProximityInterestAttribute* attrib); - void FreeAttribute(ProximityInterestAttribute* attrib); - void UpdateAttribute(ProximityInterestAttribute* attrib); - - - void OnNewRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer); - void OnDeleteRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer); - - RuleNetworkId GetNewRuleNetId(); - - ProximityInterestChunk* FindRulesChunkByPeerId(PeerId peerId); - - InterestManager* m_im; - ReplicaManager* m_rm; - - AZ::u32 m_lastRuleNetId; - - unordered_map m_peerChunks; - RuleSet m_localRules; - - AttributeSet m_attributes; - RuleSet m_rules; - - ProximityInterestChunk* m_rulesReplica; - - InterestMatchResult m_resultCache; - }; - /////////////////////////////////////////////////////////////////////////// - - class ProximityInterestChunk - : public ReplicaChunk - { - public: - GM_CLASS_ALLOCATOR(ProximityInterestChunk); - - // ReplicaChunk - typedef AZStd::intrusive_ptr Ptr; - bool IsReplicaMigratable() override { return false; } - static const char* GetChunkName() { return "ProximityInterestChunk"; } - bool IsBroadcast() { return true; } - /////////////////////////////////////////////////////////////////////////// - - - ProximityInterestChunk() - : m_interestHandler(nullptr) - , AddRuleRpc("AddRule") - , RemoveRuleRpc("RemoveRule") - , UpdateRuleRpc("UpdateRule") - , AddRuleForPeerRpc("AddRuleForPeerRpc") - { - - } - - void OnReplicaActivate(const ReplicaContext& rc) override - { - m_interestHandler = static_cast(rc.m_rm->GetUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4))); - AZ_Assert(m_interestHandler, "No proximity interest handler in the user context"); - - if (m_interestHandler) - { - m_interestHandler->OnNewRulesChunk(this, rc.m_peer); - } - } - - void OnReplicaDeactivate(const ReplicaContext& rc) override - { - if (rc.m_peer && m_interestHandler) - { - m_interestHandler->OnDeleteRulesChunk(this, rc.m_peer); - } - } - - bool AddRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext& ctx) - { - if (IsProxy()) - { - auto rulePtr = m_interestHandler->CreateRule(ctx.m_sourcePeer); - rulePtr->Set(bbox); - m_rules.insert(AZStd::make_pair(netId, rulePtr)); - } - - return true; - } - - bool RemoveRuleFn(RuleNetworkId netId, const RpcContext&) - { - if (IsProxy()) - { - m_rules.erase(netId); - } - - return true; - } - - bool UpdateRuleFn(RuleNetworkId netId, AZ::Aabb bbox, const RpcContext&) - { - if (IsProxy()) - { - auto it = m_rules.find(netId); - if (it != m_rules.end()) - { - it->second->Set(bbox); - } - } - - return true; - } - - bool AddRuleForPeerFn(RuleNetworkId netId, PeerId peerId, AZ::Aabb bbox, const RpcContext&) - { - ProximityInterestChunk* peerChunk = m_interestHandler->FindRulesChunkByPeerId(peerId); - if (peerChunk) - { - auto it = peerChunk->m_rules.find(netId); - if (it == peerChunk->m_rules.end()) - { - auto rulePtr = m_interestHandler->CreateRule(peerId); - peerChunk->m_rules.insert(AZStd::make_pair(netId, rulePtr)); - rulePtr->Set(bbox); - } - } - return false; - } - - Rpc, RpcArg>::BindInterface AddRuleRpc; - Rpc>::BindInterface RemoveRuleRpc; - Rpc, RpcArg>::BindInterface UpdateRuleRpc; - - Rpc, RpcArg, RpcArg>::BindInterface AddRuleForPeerRpc; - - ProximityInterestHandler* m_interestHandler; - unordered_map m_rules; - }; - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterest - */ - ProximityInterest::ProximityInterest(ProximityInterestHandler* handler) - : m_bbox(AZ::Aabb::CreateNull()) - , m_handler(handler) - { - AZ_Assert(m_handler, "Invalid interest handler"); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestRule - */ - void ProximityInterestRule::Set(const AZ::Aabb& bbox) - { - m_bbox = bbox; - m_handler->UpdateRule(this); - } - - void ProximityInterestRule::Destroy() - { - m_handler->DestroyRule(this); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestAttribute - */ - void ProximityInterestAttribute::Set(const AZ::Aabb& bbox) - { - m_bbox = bbox; - m_handler->UpdateAttribute(this); - } - - void ProximityInterestAttribute::Destroy() - { - m_handler->DestroyAttribute(this); - } - /////////////////////////////////////////////////////////////////////////// - - - /* - * ProximityInterestHandler - */ - ProximityInterestHandler::ProximityInterestHandler() - : m_im(nullptr) - , m_rm(nullptr) - , m_lastRuleNetId(0) - , m_rulesReplica(nullptr) - { - if (!ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(ReplicaChunkClassId(ProximityInterestChunk::GetChunkName()))) - { - ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - - ProximityInterestRule::Ptr ProximityInterestHandler::CreateRule(PeerId peerId) - { - ProximityInterestRule* rulePtr = aznew ProximityInterestRule(this, peerId, GetNewRuleNetId()); - if (peerId == m_rm->GetLocalPeerId()) - { - m_rulesReplica->AddRuleRpc(rulePtr->GetNetworkId(), rulePtr->Get()); - m_localRules.insert(rulePtr); - } - - return rulePtr; - } - - void ProximityInterestHandler::FreeRule(ProximityInterestRule* rule) - { - //TODO: should be pool-allocated - delete rule; - } - - void ProximityInterestHandler::DestroyRule(ProximityInterestRule* rule) - { - if (m_rm && rule->GetPeerId() == m_rm->GetLocalPeerId()) - { - m_rulesReplica->RemoveRuleRpc(rule->GetNetworkId()); - } - - rule->m_bbox = AZ::Aabb::CreateNull(); - m_rules.insert(rule); - m_localRules.erase(rule); - } - - void ProximityInterestHandler::UpdateRule(ProximityInterestRule* rule) - { - if (rule->GetPeerId() == m_rm->GetLocalPeerId()) - { - m_rulesReplica->UpdateRuleRpc(rule->GetNetworkId(), rule->Get()); - } - - m_rules.insert(rule); - } - - ProximityInterestAttribute::Ptr ProximityInterestHandler::CreateAttribute(ReplicaId replicaId) - { - return aznew ProximityInterestAttribute(this, replicaId); - } - - void ProximityInterestHandler::FreeAttribute(ProximityInterestAttribute* attrib) - { - //TODO: should be pool-allocated - delete attrib; - } - - void ProximityInterestHandler::DestroyAttribute(ProximityInterestAttribute* attrib) - { - attrib->m_bbox = AZ::Aabb::CreateNull(); - m_attributes.insert(attrib); - } - - void ProximityInterestHandler::UpdateAttribute(ProximityInterestAttribute* attrib) - { - m_attributes.insert(attrib); - } - - void ProximityInterestHandler::OnNewRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer) - { - if (chunk != m_rulesReplica) // non-local - { - m_peerChunks.insert(AZStd::make_pair(peer->GetId(), chunk)); - - for (auto& rule : m_localRules) - { - chunk->AddRuleForPeerRpc(rule->GetNetworkId(), rule->GetPeerId(), rule->Get()); - } - } - } - - void ProximityInterestHandler::OnDeleteRulesChunk(ProximityInterestChunk* chunk, ReplicaPeer* peer) - { - (void)chunk; - m_peerChunks.erase(peer->GetId()); - } - - RuleNetworkId ProximityInterestHandler::GetNewRuleNetId() - { - ++m_lastRuleNetId; - return m_rulesReplica->GetReplicaId() | (static_cast(m_lastRuleNetId) << 32); - } - - ProximityInterestChunk* ProximityInterestHandler::FindRulesChunkByPeerId(PeerId peerId) - { - auto it = m_peerChunks.find(peerId); - if (it == m_peerChunks.end()) - { - return nullptr; - } - else - { - return it->second; - } - } - - const InterestMatchResult& ProximityInterestHandler::GetLastResult() - { - return m_resultCache; - } - - void ProximityInterestHandler::UpdateInternal(InterestMatchResult& result) - { - ////////////////////////////////////////////// - // just recalculating the whole state for now - for (auto attrIt = m_attributes.begin(); attrIt != m_attributes.end(); ) - { - ProximityInterestAttribute* attr = *attrIt; - - auto resultIt = result.insert(attr->GetReplicaId()); - for (auto ruleIt = m_rules.begin(); ruleIt != m_rules.end(); ++ruleIt) - { - ProximityInterestRule* rule = *ruleIt; - if (rule->m_bbox.Overlaps(attr->m_bbox)) - { - resultIt.first->second.insert(rule->GetPeerId()); - } - } - - if ((*attrIt)->IsDeleted()) - { - attrIt = m_attributes.erase(attrIt); - delete attr; - } - else - { - ++attrIt; - } - } - - for (auto ruleIt = m_rules.begin(); ruleIt != m_rules.end(); ) - { - ProximityInterestRule* rule = *ruleIt; - - if (rule->IsDeleted()) - { - ruleIt = m_rules.erase(ruleIt); - delete rule; - } - else - { - ++ruleIt; - } - } - ////////////////////////////////////////////// - } - - void ProximityInterestHandler::Update() - { - m_resultCache.clear(); - - UpdateInternal(m_resultCache); - } - - void ProximityInterestHandler::OnRulesHandlerRegistered(InterestManager* manager) - { - AZ_Assert(m_im == nullptr, "Handler is already registered with manager %p (%p)\n", m_im, manager); - AZ_Assert(m_rulesReplica == nullptr, "Rules replica is already created\n"); - AZ_TracePrintf("GridMate", "Proximity interest handler is registered\n"); - m_im = manager; - m_rm = m_im->GetReplicaManager(); - m_rm->RegisterUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4), this); - - auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); - m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddPrimary(replica); - } - - void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) - { - (void)manager; - AZ_Assert(m_im == manager, "Handler was not registered with manager %p (%p)\n", manager, m_im); - AZ_TracePrintf("GridMate", "Proximity interest handler is unregistered\n"); - m_rulesReplica = nullptr; - m_im = nullptr; - m_rm->UnregisterUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4)); - m_rm = nullptr; - - for (auto& chunk : m_peerChunks) - { - chunk.second->m_interestHandler = nullptr; - } - m_peerChunks.clear(); - m_localRules.clear(); - - for (ProximityInterestRule* rule : m_rules) - { - delete rule; - } - - for (ProximityInterestAttribute* attr : m_attributes) - { - delete attr; - } - - m_attributes.clear(); - m_rules.clear(); - - m_resultCache.clear(); - } - /////////////////////////////////////////////////////////////////////////// -} -#else -// Optimized spatial handler. -#include "GridMate/Replica/Interest/ProximityInterestHandler.h" -#endif - -namespace UnitTest { - -/* - * Helper class to capture performance of various Interest Managers - */ -class PerfForInterestManager -{ -public: - void Reset(); - - void PreUpdate(); - void PostUpdate(); - - AZ::u32 GetTotalFrames() const; - float GetAverageFrame() const; - float GetWorstFrame() const; - float GetBestFrame() const; - -private: - AZ::Debug::Timer m_timer; - AZ::u32 m_frameCount = 0; - float m_totalUpdateTime = 0.f; - float m_fastestFrame = 100.f; - float m_slowestFrame = 0.f; -}; - -PerfForInterestManager g_PerfIM = PerfForInterestManager(); -PerfForInterestManager g_PerfUpdatingAttributes = PerfForInterestManager(); - -/* -* Utility function to tick the replica manager -*/ -static void UpdateReplicas(ReplicaManager* replicaManager, InterestManager* interestManager) -{ - if (interestManager) - { - // Measuring time it takes to execute an update. - g_PerfIM.PreUpdate(); - interestManager->Update(); - g_PerfIM.PostUpdate(); - } - - if (replicaManager) - { - replicaManager->Unmarshal(); - replicaManager->UpdateFromReplicas(); - replicaManager->UpdateReplicas(); - replicaManager->Marshal(); - } -} - -class Integ_InterestTest - : public GridMateMPTestFixture -{ - /////////////////////////////////////////////////////////////////// - class InterestTestChunk - : public ReplicaChunk - { - public: - GM_CLASS_ALLOCATOR(InterestTestChunk); - - InterestTestChunk() - : m_data("Data", 0) - , m_bitmaskAttributeData("BitmaskAttributeData") - , m_attribute(nullptr) - { - } - - /////////////////////////////////////////////////////////////////// - typedef AZStd::intrusive_ptr Ptr; - static const char* GetChunkName() { return "InterestTestChunk"; } - bool IsReplicaMigratable() override { return false; } - bool IsBroadcast() override - { - return false; - } - /////////////////////////////////////////////////////////////////// - - void OnReplicaActivate(const ReplicaContext& rc) override - { - AZ_Printf("GridMate", "InterestTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", - GetReplicaId(), - IsPrimary() ? "primary" : "proxy", - rc.m_peer ? rc.m_peer->GetId() : 0, - rc.m_rm->GetLocalPeerId()); - - BitmaskInterestHandler* ih = static_cast(rc.m_rm->GetUserContext(AZ_CRC("BitmaskInterestHandler", 0x5bf5d75b))); - if (ih) - { - m_attribute = ih->CreateAttribute(GetReplicaId()); - m_attribute->Set(m_bitmaskAttributeData.Get()); - } - } - - void OnReplicaDeactivate(const ReplicaContext& rc) override - { - AZ_Printf("GridMate", "InterestTestChunk::OnReplicaDeactivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", - GetReplicaId(), - IsPrimary() ? "primary" : "proxy", - rc.m_peer ? rc.m_peer->GetId() : 0, - rc.m_rm->GetLocalPeerId()); - - m_attribute = nullptr; - } - - void BitmaskHandler(const InterestBitmask& bitmask, const TimeContext&) - { - if (m_attribute) - { - m_attribute->Set(bitmask); - } - } - - DataSet m_data; - DataSet::BindInterface m_bitmaskAttributeData; - BitmaskInterestAttribute::Ptr m_attribute; - }; - /////////////////////////////////////////////////////////////////// - - class TestPeerInfo - : public SessionEventBus::Handler - { - public: - TestPeerInfo() - : m_gridMate(nullptr) - , m_lanSearch(nullptr) - , m_session(nullptr) - , m_im(nullptr) - , m_bitmaskHandler(nullptr) - , m_num(0) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - void CreateTestReplica() - { - m_im = aznew InterestManager(); - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - - m_im->Init(desc); - - m_bitmaskHandler = aznew BitmaskInterestHandler(); - m_im->RegisterHandler(m_bitmaskHandler); - - m_rule = m_bitmaskHandler->CreateRule(m_session->GetReplicaMgr()->GetLocalPeerId()); - m_rule->Set(1 << m_num); - - auto r = Replica::CreateReplica("InterestTestReplica"); - m_replica = CreateAndAttachReplicaChunk(r); - - // Initializing attribute - // Shifing all by one - peer0 will recv from peer1, peer2 will recv from peer2, peer2 will recv from peer0 - unsigned i = (m_num + 2) % Integ_InterestTest::k_numMachines; - m_replica->m_data.Set(m_num); - m_replica->m_bitmaskAttributeData.Set(1 << i); - - m_session->GetReplicaMgr()->AddPrimary(r); - } - - void UpdateAttribute() - { - // Shifing all by one - peer0 will recv from peer2, peer1 will recv from peer0, peer2 will recv from peer1 - unsigned i = (m_num + 1) % Integ_InterestTest::k_numMachines; - m_replica->m_bitmaskAttributeData.Set(1 << i); - m_replica->m_attribute->Set(1 << i); - } - - void DeleteAttribute() - { - m_replica->m_attribute = nullptr; - } - - void UpdateRule() - { - m_rule->Set(0xffff); - } - - void DeleteRule() - { - m_rule = nullptr; - } - - void CreateRule() - { - m_rule = m_bitmaskHandler->CreateRule(m_session->GetReplicaMgr()->GetLocalPeerId()); - m_rule->Set(0xffff); - } - - void OnSessionCreated(GridSession* session) override - { - m_session = session; - if (m_session->IsHost()) - { - CreateTestReplica(); - } - } - - void OnSessionJoined(GridSession* session) override - { - m_session = session; - CreateTestReplica(); - } - - void OnSessionDelete(GridSession* session) override - { - if (session == m_session) - { - m_rule = nullptr; - m_session = nullptr; - m_im->UnregisterHandler(m_bitmaskHandler); - delete m_bitmaskHandler; - delete m_im; - m_im = nullptr; - m_bitmaskHandler = nullptr; - } - } - - void OnSessionError(GridSession* session, const string& errorMsg) override - { - (void)session; - (void)errorMsg; - AZ_TracePrintf("GridMate", "Session error: %s\n", errorMsg.c_str()); - } - - IGridMate* m_gridMate; - GridSearch* m_lanSearch; - GridSession* m_session; - InterestManager* m_im; - BitmaskInterestHandler* m_bitmaskHandler; - - BitmaskInterestRule::Ptr m_rule; - unsigned m_num; - InterestTestChunk::Ptr m_replica; - }; - -public: - Integ_InterestTest() - { - ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - - ////////////////////////////////////////////////////////////////////////// - // Create all grid mates - m_peers[0].m_gridMate = m_gridMate; - m_peers[0].SessionEventBus::Handler::BusConnect(m_peers[0].m_gridMate); - m_peers[0].m_num = 0; - for (int i = 1; i < k_numMachines; ++i) - { - GridMateDesc desc; - m_peers[i].m_gridMate = GridMateCreate(desc); - AZ_TEST_ASSERT(m_peers[i].m_gridMate); - - m_peers[i].m_num = i; - m_peers[i].SessionEventBus::Handler::BusConnect(m_peers[i].m_gridMate); - } - ////////////////////////////////////////////////////////////////////////// - - for (int i = 0; i < k_numMachines; ++i) - { - // start the multiplayer service (session mgr, extra allocator, etc.) - StartGridMateService(m_peers[i].m_gridMate, SessionServiceDesc()); - AZ_TEST_ASSERT(LANSessionServiceBus::FindFirstHandler(m_peers[i].m_gridMate) != nullptr); - } - } - virtual ~Integ_InterestTest() - { - StopGridMateService(m_peers[0].m_gridMate); - - for (int i = 1; i < k_numMachines; ++i) - { - if (m_peers[i].m_gridMate) - { - m_peers[i].SessionEventBus::Handler::BusDisconnect(); - GridMateDestroy(m_peers[i].m_gridMate); - } - } - - // this will stop the first IGridMate which owns the memory allocators. - m_peers[0].SessionEventBus::Handler::BusDisconnect(); - } - - void run() - { - TestCarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = false;// true; - carrierDesc.m_threadUpdateTimeMS = 10; - carrierDesc.m_familyType = Driver::BSD_AF_INET; - - - LANSessionParams sp; - sp.m_topology = ST_PEER_TO_PEER; - sp.m_numPublicSlots = 64; - sp.m_port = k_hostPort; - EBUS_EVENT_ID_RESULT(m_peers[k_host].m_session, m_peers[k_host].m_gridMate, LANSessionServiceBus, HostSession, sp, carrierDesc); - m_peers[k_host].m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - int listenPort = k_hostPort; - for (int i = 0; i < k_numMachines; ++i) - { - if (i == k_host) - { - continue; - } - - LANSearchParams searchParams; - searchParams.m_serverPort = k_hostPort; - searchParams.m_listenPort = listenPort == k_hostPort ? 0 : ++listenPort; // first client will use ephemeral port, the rest specify return ports - searchParams.m_familyType = Driver::BSD_AF_INET; - EBUS_EVENT_ID_RESULT(m_peers[i].m_lanSearch, m_peers[i].m_gridMate, LANSessionServiceBus, StartGridSearch, searchParams); - } - - - static const int maxNumUpdates = 300; - int numUpdates = 0; - TimeStamp time = AZStd::chrono::system_clock::now(); - - while (numUpdates <= maxNumUpdates) - { - if (numUpdates == 100) - { - // Checking everybody received only one replica: - // peer0 -> rep1, peer1 -> rep2, peer2 -> rep0 - for (int i = 0; i < k_numMachines; ++i) - { - ReplicaId repId = m_peers[(i + 1) % k_numMachines].m_replica->GetReplicaId(); - auto repRecv = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(repRecv != nullptr); - - repId = m_peers[(i + 2) % k_numMachines].m_replica->GetReplicaId(); - auto repNotRecv = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(repNotRecv == nullptr); - - // rotating mask left - m_peers[i].UpdateAttribute(); - } - } - - if (numUpdates == 150) - { - // Checking everybody received only one replica: - // peer0 -> rep2, peer1 -> rep0, peer2 -> rep1 - for (int i = 0; i < k_numMachines; ++i) - { - ReplicaId repId = m_peers[(i + 2) % k_numMachines].m_replica->GetReplicaId(); - auto repRecv = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(repRecv != nullptr); - - repId = m_peers[(i + 1) % k_numMachines].m_replica->GetReplicaId(); - auto repNotRecv = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(repNotRecv == nullptr); - - // setting rules to accept all replicas - m_peers[i].UpdateRule(); - } - } - - if (numUpdates == 200) - { - // Checking everybody received all replicas - for (int i = 0; i < k_numMachines; ++i) - { - for (int j = 0; j < k_numMachines; ++j) - { - ReplicaId repId = m_peers[j].m_replica->GetReplicaId(); - auto rep = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(rep); - } - - // Deleting all attributes - m_peers[i].DeleteAttribute(); - } - } - - if (numUpdates == 250) - { - // Checking everybody lost all replicas (except primary) - for (int i = 0; i < k_numMachines; ++i) - { - for (int j = 0; j < k_numMachines; ++j) - { - if (i == j) - { - continue; - } - - ReplicaId repId = m_peers[j].m_replica->GetReplicaId(); - auto rep = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(rep == nullptr); - } - - // deleting all rules - m_peers[i].DeleteRule(); - } - } - - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_gridMate) - { - m_peers[i].m_gridMate->Update(); - if (m_peers[i].m_session) - { - UpdateReplicas(m_peers[i].m_session->GetReplicaMgr(), m_peers[i].m_im); - } - } - } - Update(); - ////////////////////////////////////////////////////////////////////////// - - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_lanSearch && m_peers[i].m_lanSearch->IsDone()) - { - AZ_TEST_ASSERT(m_peers[i].m_lanSearch->GetNumResults() == 1); - JoinParams jp; - EBUS_EVENT_ID_RESULT(m_peers[i].m_session, m_peers[i].m_gridMate, LANSessionServiceBus, JoinSessionBySearchInfo, static_cast(*m_peers[i].m_lanSearch->GetResult(0)), jp, carrierDesc); - m_peers[i].m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - m_peers[i].m_lanSearch->Release(); - m_peers[i].m_lanSearch = nullptr; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Debug Info - TimeStamp now = AZStd::chrono::system_clock::now(); - if (AZStd::chrono::milliseconds(now - time).count() > 1000) - { - time = now; - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_session == nullptr) - { - continue; - } - - if (m_peers[i].m_session->IsHost()) - { - AZ_Printf("GridMate", "------ Host %d ------\n", i); - } - else - { - AZ_Printf("GridMate", "------ Client %d ------\n", i); - } - - AZ_Printf("GridMate", "Session %s Members: %d Host: %s Clock: %d\n", m_peers[i].m_session->GetId().c_str(), m_peers[i].m_session->GetNumberOfMembers(), m_peers[i].m_session->IsHost() ? "yes" : "no", m_peers[i].m_session->GetTime()); - for (unsigned int iMember = 0; iMember < m_peers[i].m_session->GetNumberOfMembers(); ++iMember) - { - GridMember* member = m_peers[i].m_session->GetMemberByIndex(iMember); - AZ_Printf("GridMate", " Member: %s(%s) Host: %s Local: %s\n", member->GetName().c_str(), member->GetId().ToString().c_str(), member->IsHost() ? "yes" : "no", member->IsLocal() ? "yes" : "no"); - } - AZ_Printf("GridMate", "\n"); - } - } - ////////////////////////////////////////////////////////////////////////// - - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(30)); - numUpdates++; - } - } - - static const int k_numMachines = 3; - static const int k_host = 0; - static const int k_hostPort = 5450; - - TestPeerInfo m_peers[k_numMachines]; -}; - -/* - * Testing worse case performance of thousands of replicas and a few peers where all replicas/attributes change every frame - * and peers/rules change every frame as well. - */ -class LargeWorldTest - : public GridMateMPTestFixture -{ - /////////////////////////////////////////////////////////////////// - class LargeWorldTestChunk - : public ReplicaChunk - { - public: - GM_CLASS_ALLOCATOR(LargeWorldTestChunk); - - LargeWorldTestChunk() - : m_data("Data", 0) - , m_proximityAttributeData("LargeWorldAttributeData") - , m_attribute(nullptr) - { - } - - /////////////////////////////////////////////////////////////////// - typedef AZStd::intrusive_ptr Ptr; - static const char* GetChunkName() { return "LargeWorldTestChunk"; } - bool IsReplicaMigratable() override { return false; } - bool IsBroadcast() override - { - return false; - } - /////////////////////////////////////////////////////////////////// - - void OnReplicaActivate(const ReplicaContext& rc) override - { - /*if (!IsPrimary())*/ - /*{ - AZ_Printf("GridMate", "LargeWorldTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", - GetReplicaId(), - IsPrimary() ? "primary" : "proxy", - rc.m_peer ? rc.m_peer->GetId() : 0, - rc.m_rm->GetLocalPeerId()); - }*/ - - if (ProximityInterestHandler* ih = static_cast(rc.m_rm->GetUserContext(AZ_CRC("ProximityInterestHandler", 0x3a90b3e4)))) - { - m_attribute = ih->CreateAttribute(GetReplicaId()); - m_attribute->Set(m_proximityAttributeData.Get()); - } - } - - void OnReplicaDeactivate(const ReplicaContext& /*rc*/) override - { - m_attribute = nullptr; - } - - void ProximityHandler(const AZ::Aabb& bounds, const TimeContext&) - { - if (m_attribute) - { - m_attribute->Set(bounds); - } - } - - DataSet m_data; - DataSet::BindInterface m_proximityAttributeData; - ProximityInterestAttribute::Ptr m_attribute; - }; - /////////////////////////////////////////////////////////////////// - - struct LargeWorldParams - { - AZ::u32 index = 0; - - const float commonSize = 50; - const AZ::Aabb box = AZ::Aabb::CreateFromMinMax( - AZ::Vector3::CreateZero(), - AZ::Vector3::CreateOne() * commonSize); - const float commonStep = commonSize + 1; - }; - - static LargeWorldParams& GetWorldParams() - { - static LargeWorldParams worldParams; - return worldParams; - } - - /* - * Create a chain of boxes in spaces along X axis - */ - static AZ::Aabb CreateNextRuleSpace() - { - auto offset = GetWorldParams().commonStep * aznumeric_cast(GetWorldParams().index); - - float min[] = { offset, 0, 0 }; - float max[] = { - GetWorldParams().commonSize + offset, - GetWorldParams().commonSize, - GetWorldParams().commonSize }; - - auto bounds = AZ::Aabb::CreateFromMinMax( - AZ::Vector3::CreateFromFloat3(min), - AZ::Vector3::CreateFromFloat3(max)); - - GetWorldParams().index++; - return bounds; - } - - class LargeWorldTestPeerInfo - : public SessionEventBus::Handler - { - public: - LargeWorldTestPeerInfo() - : m_gridMate(nullptr) - , m_lanSearch(nullptr) - , m_session(nullptr) - , m_im(nullptr) - , m_proximityHandler(nullptr) - , m_num(0) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - ~LargeWorldTestPeerInfo() - { - SessionEventBus::Handler::BusDisconnect(); - } - - void CreateHostRuleHandler() - { - m_im = aznew InterestManager(); - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - - m_im->Init(desc); - - m_proximityHandler = aznew ProximityInterestHandler(); - m_im->RegisterHandler(m_proximityHandler); - - m_rule = m_proximityHandler->CreateRule(m_session->GetReplicaMgr()->GetLocalPeerId()); - m_rule->Set(AZ::Aabb::CreateNull()); // host rule doesn't matter in this test - } - - void CreateRuleHandler() - { - m_im = aznew InterestManager(); - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - - m_im->Init(desc); - - m_proximityHandler = aznew ProximityInterestHandler(); - m_im->RegisterHandler(m_proximityHandler); - - m_rule = m_proximityHandler->CreateRule(m_session->GetReplicaMgr()->GetLocalPeerId()); - m_rule->Set(CreateNextRuleSpace()); - } - - void CreateTestReplica(const AZ::Aabb& bounds) - { - auto r = Replica::CreateReplica("LargeWorldTestReplica"); - auto replica = CreateAndAttachReplicaChunk(r); - - // Initializing attribute - replica->m_data.Set(m_num); - replica->m_proximityAttributeData.Set(bounds); - - m_replicas.push_back(replica); - - m_session->GetReplicaMgr()->AddPrimary(r); - } - - void PopulateWorld() - { - AZ_Printf("GridMate", "LargeWorldTestChunk::PopulateWorld() starting...\n"); - - const float worldSizeInBoxes = 50; - const auto oneBox = AZ::Vector3::CreateOne(); - const auto thickness = 1; - for (float dx = 0; dx < worldSizeInBoxes; ++dx) - { - for (float dy = 0; dy < thickness; ++dy) - { - for (float dz = 0; dz < thickness; ++dz) - { - auto aabb = AZ::Aabb::CreateFromMinMax( - AZ::Vector3(50 * dx + 5, dy, dz), - AZ::Vector3(50 * dx + 5, dy, dz) + oneBox); - - CreateTestReplica(aabb); - } - } - } - - AZ_Printf("GridMate", "LargeWorldTestChunk::PopulateWorld() ... DONE\n"); - } - - void UpdateAttribute(LargeWorldTestChunk::Ptr replica) - { - if (replica && replica->m_attribute) - { - auto sameValue = replica->m_attribute->Get(); - - replica->m_proximityAttributeData.Set(sameValue); - replica->m_attribute->Set(sameValue); - } - } - - void UpdateRule() - { - // just make it dirty for now - if (m_rule) - { - auto sameValue = m_rule->Get(); - m_rule->Set(sameValue); - } - } - - void DeleteRule() - { - m_rule = nullptr; - } - - void OnSessionCreated(GridSession* session) override - { - m_session = session; - if (m_session->IsHost()) - { - CreateHostRuleHandler(); - PopulateWorld(); - } - } - - void OnSessionJoined(GridSession* session) override - { - m_session = session; - CreateRuleHandler(); - } - - void OnSessionDelete(GridSession* session) override - { - if (session == m_session) - { - m_rule = nullptr; - m_session = nullptr; - m_im->UnregisterHandler(m_proximityHandler); - delete m_proximityHandler; - delete m_im; - m_im = nullptr; - m_proximityHandler = nullptr; - } - } - - void OnSessionError(GridSession* session, const string& errorMsg) override - { - (void)session; - (void)errorMsg; - AZ_TracePrintf("GridMate", "Session error: %s\n", errorMsg.c_str()); - } - - IGridMate* m_gridMate; - GridSearch* m_lanSearch; - GridSession* m_session; - InterestManager* m_im; - ProximityInterestHandler* m_proximityHandler; - - ProximityInterestRule::Ptr m_rule; - unsigned m_num; - - AZStd::vector m_replicas; - }; - -public: - LargeWorldTest() : UnitTest::GridMateMPTestFixture(500u * 1024u * 1024u) // 500Mb - { - ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - - ////////////////////////////////////////////////////////////////////////// - // Create all grid mates - m_peers[0].m_gridMate = m_gridMate; - m_peers[0].SessionEventBus::Handler::BusConnect(m_peers[0].m_gridMate); - m_peers[0].m_num = 0; - for (int i = 1; i < k_numMachines; ++i) - { - GridMateDesc desc; - m_peers[i].m_gridMate = GridMateCreate(desc); - AZ_TEST_ASSERT(m_peers[i].m_gridMate); - - m_peers[i].m_num = i; - m_peers[i].SessionEventBus::Handler::BusConnect(m_peers[i].m_gridMate); - } - ////////////////////////////////////////////////////////////////////////// - - for (int i = 0; i < k_numMachines; ++i) - { - // start the multiplayer service (session mgr, extra allocator, etc.) - StartGridMateService(m_peers[i].m_gridMate, SessionServiceDesc()); - AZ_TEST_ASSERT(LANSessionServiceBus::FindFirstHandler(m_peers[i].m_gridMate) != nullptr); - } - } - virtual ~LargeWorldTest() - { - StopGridMateService(m_peers[0].m_gridMate); - - for (int i = 1; i < k_numMachines; ++i) - { - if (m_peers[i].m_gridMate) - { - m_peers[i].SessionEventBus::Handler::BusDisconnect(); - GridMateDestroy(m_peers[i].m_gridMate); - } - } - - // this will stop the first IGridMate which owns the memory allocators. - m_peers[0].SessionEventBus::Handler::BusDisconnect(); - } - - void run() - { - g_PerfIM.Reset(); - g_PerfUpdatingAttributes.Reset(); - - TestCarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = false; - carrierDesc.m_threadUpdateTimeMS = 10; - carrierDesc.m_familyType = Driver::BSD_AF_INET; - - LANSessionParams sp; - sp.m_topology = ST_PEER_TO_PEER; - sp.m_numPublicSlots = 64; - sp.m_port = k_hostPort; - EBUS_EVENT_ID_RESULT(m_peers[k_host].m_session, m_peers[k_host].m_gridMate, LANSessionServiceBus, HostSession, sp, carrierDesc); - m_peers[k_host].m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - int listenPort = k_hostPort; - for (int i = 0; i < k_numMachines; ++i) - { - if (i == k_host) - { - continue; - } - - LANSearchParams searchParams; - searchParams.m_serverPort = k_hostPort; - searchParams.m_listenPort = listenPort == k_hostPort ? 0 : ++listenPort; // first client will use ephemeral port, the rest specify return ports - searchParams.m_familyType = Driver::BSD_AF_INET; - EBUS_EVENT_ID_RESULT(m_peers[i].m_lanSearch, m_peers[i].m_gridMate, LANSessionServiceBus, StartGridSearch, searchParams); - } - - - static const int maxNumUpdates = 300; - int numUpdates = 0; - TimeStamp time = AZStd::chrono::system_clock::now(); - - while (numUpdates <= maxNumUpdates) - { - g_PerfUpdatingAttributes.PreUpdate(); - for (LargeWorldTestChunk::Ptr replica : m_peers[0].m_replicas) - { - m_peers[0].UpdateAttribute(replica); - } - g_PerfUpdatingAttributes.PostUpdate(); - - for (auto peer : m_peers) - { - peer.UpdateRule(); - } - - //if (numUpdates == 100) - //{ - // // check how many replicas each client got - // for (AZ::u32 i = 1; i < k_numMachines; ++i) - // { - // AZ::u32 count = 0; - // for (auto& replica : m_peers[0].m_replicas) - // { - // ReplicaId repId = replica->GetReplicaId(); - // if (auto rep = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId)) - // { - // count++; - // } - // } - - // const AZ::Aabb& bounds = m_peers[i].m_rule->Get(); - - // AZ_Printf("GridMate", "Session %s Members: %d Bounds: %f.%f.%f-%f.%f.%f Replicas: %d\n", m_peers[i].m_session->GetId().c_str(), m_peers[i].m_session->GetNumberOfMembers(), - // static_cast(bounds.GetMin().GetX()), - // static_cast(bounds.GetMin().GetY()), - // static_cast(bounds.GetMin().GetZ()), - // static_cast(bounds.GetMax().GetX()), - // static_cast(bounds.GetMax().GetY()), - // static_cast(bounds.GetMax().GetZ()), count); - - // AZ_Assert(count == 1, "Should have at least some replicas to start with"); - // } - //} - - if (numUpdates == 200) - { - // Deleting all attributes - for (auto& replica : m_peers[0].m_replicas) - { - replica->m_attribute = nullptr; - } - } - - if (numUpdates == 250) - { - // Checking everybody lost all replicas (except primary) - for (int i = 0; i < k_numMachines; ++i) - { - /*for (int j = 0; j < k_numMachines; ++j) - { - if (i == j) - { - continue; - } - - ReplicaId repId = m_peers[j].m_replica->GetReplicaId(); - auto rep = m_peers[i].m_session->GetReplicaMgr()->FindReplica(repId); - AZ_TEST_ASSERT(rep == nullptr); - }*/ - - // deleting all rules - m_peers[i].DeleteRule(); - } - } - - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_gridMate) - { - m_peers[i].m_gridMate->Update(); - if (m_peers[i].m_session) - { - UpdateReplicas(m_peers[i].m_session->GetReplicaMgr(), m_peers[i].m_im); - } - } - } - Update(); - ////////////////////////////////////////////////////////////////////////// - - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_lanSearch && m_peers[i].m_lanSearch->IsDone()) - { - AZ_TEST_ASSERT(m_peers[i].m_lanSearch->GetNumResults() == 1); - JoinParams jp; - EBUS_EVENT_ID_RESULT(m_peers[i].m_session, m_peers[i].m_gridMate, LANSessionServiceBus, JoinSessionBySearchInfo, static_cast(*m_peers[i].m_lanSearch->GetResult(0)), jp, carrierDesc); - m_peers[i].m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - m_peers[i].m_lanSearch->Release(); - m_peers[i].m_lanSearch = nullptr; - } - } - - ////////////////////////////////////////////////////////////////////////// - // Debug Info - TimeStamp now = AZStd::chrono::system_clock::now(); - if (AZStd::chrono::milliseconds(now - time).count() > 1000) - { - time = now; - for (int i = 0; i < k_numMachines; ++i) - { - if (m_peers[i].m_session == nullptr) - { - continue; - } - - if (m_peers[i].m_session->IsHost()) - { - AZ_Printf("GridMate", "------ Host %d ------\n", i); - } - else - { - AZ_Printf("GridMate", "------ Client %d ------\n", i); - } - - AZ_Printf("GridMate", "Session %s Members: %d Host: %s Clock: %d\n", m_peers[i].m_session->GetId().c_str(), m_peers[i].m_session->GetNumberOfMembers(), m_peers[i].m_session->IsHost() ? "yes" : "no", m_peers[i].m_session->GetTime()); - for (unsigned int iMember = 0; iMember < m_peers[i].m_session->GetNumberOfMembers(); ++iMember) - { - GridMember* member = m_peers[i].m_session->GetMemberByIndex(iMember); - AZ_Printf("GridMate", " Member: %s(%s) Host: %s Local: %s\n", member->GetName().c_str(), member->GetId().ToString().c_str(), member->IsHost() ? "yes" : "no", member->IsLocal() ? "yes" : "no"); - } - AZ_Printf("GridMate", "\n"); - } - } - ////////////////////////////////////////////////////////////////////////// - - //AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(30)); - numUpdates++; - } - - auto averageFrame = g_PerfIM.GetAverageFrame(); - auto bestFrame = g_PerfIM.GetBestFrame(); - auto worstFrame = g_PerfIM.GetWorstFrame(); - auto frames = g_PerfIM.GetTotalFrames(); - AZ_Printf("GridMate", "Interest manager performance: average_frame = %f sec, frames = %d, best= %f sec, worst= %f sec\n", - averageFrame, frames, bestFrame, worstFrame); - - AZ_Printf("GridMate", "Updating attributes: average_frame = %f sec, frames = %d, best= %f sec, worst= %f sec\n", - g_PerfUpdatingAttributes.GetAverageFrame(), - g_PerfUpdatingAttributes.GetTotalFrames(), - g_PerfUpdatingAttributes.GetBestFrame(), - g_PerfUpdatingAttributes.GetWorstFrame()); - } - - static const int k_numMachines = 3; - static const int k_host = 0; - static const int k_hostPort = 5450; - - LargeWorldTestPeerInfo m_peers[k_numMachines]; -}; - -void PerfForInterestManager::Reset() -{ - m_frameCount = 0; - m_totalUpdateTime = 0; - m_slowestFrame = 0; - m_fastestFrame = 100.f; -} - -void PerfForInterestManager::PreUpdate() -{ - m_timer.Stamp(); -} - -void PerfForInterestManager::PostUpdate() -{ - auto frameTime = m_timer.StampAndGetDeltaTimeInSeconds(); - m_totalUpdateTime += frameTime; - m_frameCount++; - - m_slowestFrame = AZStd::max(m_slowestFrame, frameTime); - m_fastestFrame = AZStd::min(m_fastestFrame, frameTime); -} - -AZ::u32 PerfForInterestManager::GetTotalFrames() const -{ - return m_frameCount; -} - -float PerfForInterestManager::GetAverageFrame() const -{ - if (m_frameCount > 0) - { - return m_totalUpdateTime / m_frameCount; - } - - return 0; -} - -float PerfForInterestManager::GetWorstFrame() const -{ - return m_slowestFrame; -} - -float PerfForInterestManager::GetBestFrame() const -{ - return m_fastestFrame; -} - -class ProximityHandlerTests - : public GridMateMPTestFixture -{ -public: - struct xyz - { - float x, y, z; - }; - - static AZ::Aabb CreateBox(xyz min, float size) - { - return AZ::Aabb::CreateFromMinMax( - AZ::Vector3::CreateFromFloat3(&min.x), - AZ::Vector3::CreateFromFloat3(&min.x) + AZ::Vector3::CreateOne() * size); - } - - static void run() - { - SimpleFirstUpdate(); - SecondUpdateAfterNoChanges(); - SimpleOutsideOfRule(); - AttributeMovingOutsideOfRule(); - RuleMovingAndAttributeIsOut(); - RuleDestroyed(); - AttributeDestroyed(); - } - - static void RuleMovingAndAttributeIsOut() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - InterestMatchResult results = handler->GetLastResult(); - //ProximityInterestHandler::DebugPrint(results, "1st"); - - AZ_TEST_ASSERT(results[1].size() == 1); - AZ_TEST_ASSERT(results[1].find(100) != results[1].end()); - - // now move the attribute outside of the rule - rule1->Set(CreateBox({ 1000, 0, 0 }, 100)); - - handler->Update(); - results = handler->GetLastResult(); - //ProximityInterestHandler::DebugPrint(results, "2nd"); - - AZ_TEST_ASSERT(results[1].size() == 0); - } - - static void AttributeMovingOutsideOfRule() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - InterestMatchResult results = handler->GetLastResult(); - //ProximityInterestHandler::DebugPrint(results, "1st"); - - AZ_TEST_ASSERT(results[1].size() == 1); - AZ_TEST_ASSERT(results[1].find(100) != results[1].end()); - - // now move the attribute outside of the rule - attribute1->Set(CreateBox({ -1000, 0, 0 }, 10)); - - handler->Update(); - results = handler->GetLastResult(); - //ProximityInterestHandler::DebugPrint(results, "2nd"); - - AZ_TEST_ASSERT(results[1].size() == 0); - } - - static void SimpleFirstUpdate() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - - InterestMatchResult results = handler->GetLastResult(); - - //ProximityInterestHandler::PrintMatchResult(results, "test"); - - AZ_TEST_ASSERT(results[1].size() == 1); - AZ_TEST_ASSERT(results[1].find(100) != results[1].end()); - } - - static void SecondUpdateAfterNoChanges() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - handler->Update(); - - InterestMatchResult results = handler->GetLastResult(); - - //ProximityInterestHandler::PrintMatchResult(results, "test"); - - AZ_TEST_ASSERT(results.size() == 0); - } - - static void SimpleOutsideOfRule() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ -1000, 0, 0 }, 10)); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - - InterestMatchResult results = handler->GetLastResult(); - - //ProximityInterestHandler::PrintMatchResult(results, "test"); - - AZ_TEST_ASSERT(results.size() == 1); - AZ_TEST_ASSERT(results[1].size() == 0); - } - - static void RuleDestroyed() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - { - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - handler->Update(); - - InterestMatchResult results = handler->GetLastResult(); - AZ_TEST_ASSERT(results.size() == 1); - AZ_TEST_ASSERT(results[1].size() == 1); - } - - // rule1 should have been destroyed by now - - handler->Update(); - InterestMatchResult results = handler->GetLastResult(); - //ProximityInterestHandler::PrintMatchResult(results, "last"); - - AZ_TEST_ASSERT(results.size() == 1); - AZ_TEST_ASSERT(results[1].size() == 0); - } - - static void AttributeDestroyed() - { - AZStd::unique_ptr handler(aznew ProximityInterestHandler()); - - auto rule1 = handler->CreateRule(100); - rule1->Set(CreateBox({ 0, 0, 0 }, 100)); - - { - auto attribute1 = handler->CreateAttribute(1); - attribute1->Set(CreateBox({ 0, 0, 0 }, 10)); - - handler->Update(); - - InterestMatchResult results = handler->GetLastResult(); - AZ_TEST_ASSERT(results.size() == 1); - AZ_TEST_ASSERT(results[1].size() == 1); - } - - // attribute1 should have been destroyed by now, but it will show up once to remove it from affected peers - handler->Update(); - InterestMatchResult results = handler->GetLastResult(); - results.PrintMatchResult("last"); - - AZ_TEST_ASSERT(results.size() == 1); - AZ_TEST_ASSERT(results[1].size() == 0); - - // and now attribute1 should not show up in the changes - handler->Update(); - results = handler->GetLastResult(); - results.PrintMatchResult("last"); - - AZ_TEST_ASSERT(results.size() == 0); - } -}; - -}; // namespace UnitTest - -GM_TEST_SUITE(InterestSuite) - GM_TEST(Integ_InterestTest); -#if AZ_TRAIT_GRIDMATE_TEST_EXCLUDE_LARGEWORLDTEST != 0 - GM_TEST(LargeWorldTest); -#endif - GM_TEST(ProximityHandlerTests); -GM_TEST_SUITE_END() diff --git a/Code/Framework/GridMate/Tests/gridmate_test_files.cmake b/Code/Framework/GridMate/Tests/gridmate_test_files.cmake index a8b1dbd120..90ccbbf9a9 100644 --- a/Code/Framework/GridMate/Tests/gridmate_test_files.cmake +++ b/Code/Framework/GridMate/Tests/gridmate_test_files.cmake @@ -24,5 +24,4 @@ set(FILES StreamSocketDriverTests.cpp CarrierStreamSocketDriverTests.cpp Carrier.cpp - Interest.cpp ) From f2b6ea7d8d3b5313b48732449603d54528841111 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 17 Jun 2021 09:07:37 -0700 Subject: [PATCH 49/93] Cherry picking a47b30c70867b371fce3ede83239f5bd9edc092a. Correcting the issue with processing of prefabs in Multiplayer projects --- Gems/Multiplayer/Code/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/Multiplayer/Code/CMakeLists.txt b/Gems/Multiplayer/Code/CMakeLists.txt index 430fe5ca4b..992d39c418 100644 --- a/Gems/Multiplayer/Code/CMakeLists.txt +++ b/Gems/Multiplayer/Code/CMakeLists.txt @@ -123,6 +123,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) BUILD_DEPENDENCIES PRIVATE Gem::Multiplayer.Builders.Static + RUNTIME_DEPENDENCIES + Gem::Multiplayer.Editor ) ly_add_target( From 0810f353c610f0f9d972584cf52cf65ea0fa82d5 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 17 Jun 2021 09:11:48 -0700 Subject: [PATCH 50/93] Cherrypick 7adf5ca5a5911997102017e2db7981e7b2926100. Fixed assert for network prefabs when asset path was empty --- Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp index 31884d4c94..ea966907d1 100644 --- a/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp +++ b/Gems/Multiplayer/Code/Source/Pipeline/NetworkPrefabProcessor.cpp @@ -130,6 +130,7 @@ namespace Multiplayer // Instance container for net entities AZStd::unique_ptr networkInstance(aznew Instance()); + networkInstance->SetTemplateSourcePath(AZ::IO::PathView(uniqueName)); // Create an asset for our future network spawnable: this allows us to put references to the asset in the components AZ::Data::Asset networkSpawnableAsset; From b9fbfac96703a6fb39f03b551e3cab3cf465f0cc Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Thu, 17 Jun 2021 17:19:50 +0100 Subject: [PATCH 51/93] Fixed Physics Materials periodic automated tests (#1396) --- .../PythonTests/physics/TestSuite_Periodic.py | 7 ++ ...ntrollerMaterialAssignment.setreg_override | 115 ++++++++++++++++++ ...al_FrictionCombinePriority.setreg_override | 115 ++++++++++++++++++ ...RestitutionCombinePriority.setreg_override | 115 ++++++++++++++++++ ...6_Material_FrictionCombine.setreg_override | 115 ++++++++++++++++++ ...aterial_RestitutionCombine.setreg_override | 115 ++++++++++++++++++ ...44461_Material_Restitution.setreg_override | 115 ++++++++++++++++++ ..._PerfaceMaterialValidation.setreg_override | 115 ++++++++++++++++++ 8 files changed, 812 insertions(+) create mode 100644 AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override create mode 100644 AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override create mode 100644 AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override create mode 100644 AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override create mode 100644 AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override create mode 100644 AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override create mode 100644 AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py index 2b82c3e596..291bb96627 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py @@ -93,11 +93,13 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C4044457_Material_RestitutionCombine.setreg_override', 'AutomatedTesting/Registry') def test_C4044457_Material_RestitutionCombine(self, request, workspace, editor, launcher_platform): from . import C4044457_Material_RestitutionCombine as test_module self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C4044456_Material_FrictionCombine.setreg_override', 'AutomatedTesting/Registry') def test_C4044456_Material_FrictionCombine(self, request, workspace, editor, launcher_platform): from . import C4044456_Material_FrictionCombine as test_module self._run_test(request, workspace, editor, test_module) @@ -194,6 +196,7 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C18981526_Material_RestitutionCombinePriority.setreg_override', 'AutomatedTesting/Registry') def test_C18981526_Material_RestitutionCombinePriority(self, request, workspace, editor, launcher_platform): from . import C18981526_Material_RestitutionCombinePriority as test_module self._run_test(request, workspace, editor, test_module) @@ -229,6 +232,7 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C18977601_Material_FrictionCombinePriority.setreg_override', 'AutomatedTesting/Registry') def test_C18977601_Material_FrictionCombinePriority(self, request, workspace, editor, launcher_platform): from . import C18977601_Material_FrictionCombinePriority as test_module self._run_test(request, workspace, editor, test_module) @@ -250,6 +254,7 @@ class TestAutomation(TestAutomationBase): @pytest.mark.xfail( reason="This test needs new physics asset with multiple materials to be more stable.") @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C4044697_Material_PerfaceMaterialValidation.setreg_override', 'AutomatedTesting/Registry') def test_C4044697_Material_PerfaceMaterialValidation(self, request, workspace, editor, launcher_platform): from . import C4044697_Material_PerfaceMaterialValidation as test_module self._run_test(request, workspace, editor, test_module) @@ -282,6 +287,7 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override', 'AutomatedTesting/Registry') def test_C15556261_PhysXMaterials_CharacterControllerMaterialAssignment(self, request, workspace, editor, launcher_platform): from . import C15556261_PhysXMaterials_CharacterControllerMaterialAssignment as test_module self._run_test(request, workspace, editor, test_module) @@ -326,6 +332,7 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C4044461_Material_Restitution.setreg_override', 'AutomatedTesting/Registry') def test_C4044461_Material_Restitution(self, request, workspace, editor, launcher_platform): from . import C4044461_Material_Restitution as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override b/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override new file mode 100644 index 0000000000..a329434623 --- /dev/null +++ b/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{70D4A444-AFD4-57C4-9885-63F25AC3C281}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c15556261_physxmaterials_charactercontrollermaterialassignment/library.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override b/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override new file mode 100644 index 0000000000..44a91c67cb --- /dev/null +++ b/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{B8749DAB-15DA-5A61-B565-C853673604CD}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c18977601_material_frictioncombinepriority/friction_combine.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override b/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override new file mode 100644 index 0000000000..8de10787f1 --- /dev/null +++ b/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{AED48B18-0F3F-5E59-A8FF-30DB134B307B}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c18981526_material_restitutioncombinepriority/restitution_combine.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override b/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override new file mode 100644 index 0000000000..83f7079e1f --- /dev/null +++ b/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{8D2C4A29-E0FC-564F-82C9-24BBA30C5A90}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c4044456_material_frictioncombine/friction_combine.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override b/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override new file mode 100644 index 0000000000..96836b6ae4 --- /dev/null +++ b/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{D5D6A6DE-E636-5638-B30D-6CE2FDC321F8}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c4044457_material_restitutioncombine/restitution_combine.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override b/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override new file mode 100644 index 0000000000..21b285506b --- /dev/null +++ b/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{E4117B5B-8D9A-5C1D-BA1E-C36542A6588D}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c4044461_material_restitution/restitution.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override b/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override new file mode 100644 index 0000000000..d585a4c468 --- /dev/null +++ b/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override @@ -0,0 +1,115 @@ +{ + "Amazon": { + "Gems": { + "PhysX": { + "PhysXSystemConfiguration": { + "CollisionConfig": { + "Layers": { + "LayerNames": [ + "Default", + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + "TouchBend" + ] + }, + "Groups": { + "GroupPresets": [ + { + "Name": "All", + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}" + }, + "Name": "None", + "Group": { + "Mask": 0 + }, + "ReadOnly": true + }, + { + "Id": { + "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}" + }, + "Name": "All_NoTouchBend", + "Group": { + "Mask": 9223372036854775807 + }, + "ReadOnly": true + } + ] + } + }, + "MaterialLibrary": { + "assetId": { + "guid": "{2E85B457-ED19-5FE3-90B4-6EFFB4D0E682}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c4044697_material_perfacematerialvalidation/test_library.physmaterial" + } + } + } + } + } +} \ No newline at end of file From 7781307afe61d8f1c2eb3f0ecefd03939936b64c Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Thu, 17 Jun 2021 19:23:12 +0100 Subject: [PATCH 52/93] Fixed cloth automated tests. (#1400) Bone transforms buffer is not valid when using Null renderer, which caused the test to fail since it reported an error and ultimately crashing as well. For now it's been worked around by checking the pointer is valid and not printing the error when null renderer is used, a task for the Atom team has been created to fix this properly in the future (ATOM-15807). --- AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py | 3 +-- .../C18977329_NvCloth_AddClothSimulationToMesh.ly | 4 ++-- .../C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml | 2 +- .../C18977329_NvCloth_AddClothSimulationToMesh/level.pak | 4 ++-- .../C18977330_NvCloth_AddClothSimulationToActor.ly | 4 ++-- .../C18977330_NvCloth_AddClothSimulationToActor/filelist.xml | 2 +- .../C18977330_NvCloth_AddClothSimulationToActor/level.pak | 4 ++-- .../Code/Source/SkinnedMesh/SkinnedMeshRenderProxy.cpp | 5 ++++- .../EMotionFXAtom/Code/Source/AtomActorInstance.cpp | 4 +++- .../Components/ClothComponentMesh/ClothComponentMesh.cpp | 3 ++- 10 files changed, 20 insertions(+), 15 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py index 86bfc48636..aae01e4652 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py @@ -24,12 +24,11 @@ from base import TestAutomationBase @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): - @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail") + def test_C18977329_NvCloth_AddClothSimulationToMesh(self, request, workspace, editor, launcher_platform): from . import C18977329_NvCloth_AddClothSimulationToMesh as test_module self._run_test(request, workspace, editor, test_module) - @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail") def test_C18977330_NvCloth_AddClothSimulationToActor(self, request, workspace, editor, launcher_platform): from . import C18977330_NvCloth_AddClothSimulationToActor as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly index 1afbf787db..9a1b1fe59a 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e15d484113e8151072b410924747a8ad304f6f12457fad577308c0491693ab34 -size 5472 +oid sha256:6517300fb1ce70c4696286e14715c547cfd175eabbb2042f7f2a456b15054224 +size 5253 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml index 9775a35c53..2cf4d55bf0 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml @@ -1,6 +1,6 @@ - + diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak index 08a775b6c8..954bb1912f 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64de37c805b0be77cdb7a85b5406af58b7f845e7d97fec1721ac5d789bb641db -size 38856 +oid sha256:ce32a7cdf3ed37751385b3bb18f05206702978363f325d06727b5eb20d40b7eb +size 38563 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly index 385027c479..9ef8bc0525 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b595323d4d51211463dea0338abb6ce2a4a0a8d41efb12ac3c9dccd1f972171 -size 5504 +oid sha256:89dbcec013cb819e52ec0f8fed0a9e417fd32eac8aeb67d3958266bb6089ec21 +size 5505 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml index 7ccc1d51eb..a7de99a91c 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml @@ -1,6 +1,6 @@ - + diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak index 12ce03fa87..ad10c72b31 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:617c455668fc41cb7fd69de690e4aa3c80f2cb36deaa371902b79de18fcd1cb2 -size 39233 +oid sha256:622c2624b04e07b704520f32c458b50d5a50de1ef116b7bc9c3c0ccb6f4a4ecc +size 3606 diff --git a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshRenderProxy.cpp b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshRenderProxy.cpp index 090b720406..0832bd0a25 100644 --- a/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshRenderProxy.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/SkinnedMesh/SkinnedMeshRenderProxy.cpp @@ -134,7 +134,10 @@ namespace AZ void SkinnedMeshRenderProxy::SetSkinningMatrices(const AZStd::vector& data) { - WriteToBuffer(m_boneTransforms->GetRHIBuffer(), data); + if (m_boneTransforms) + { + WriteToBuffer(m_boneTransforms->GetRHIBuffer(), data); + } } void SkinnedMeshRenderProxy::SetMorphTargetWeights(uint32_t lodIndex, const AZStd::vector& weights) diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp index 18a21c93a6..6eadabe44d 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.cpp @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -461,7 +463,7 @@ namespace AZ if (m_skinnedMeshInputBuffers) { m_boneTransforms = CreateBoneTransformBufferFromActorInstance(m_actorInstance, GetSkinningMethod()); - AZ_Error("AtomActorInstance", m_boneTransforms, "Failed to create bone transform buffer."); + AZ_Error("AtomActorInstance", m_boneTransforms || AZ::RHI::IsNullRenderer(), "Failed to create bone transform buffer."); // If the instance is created before the default materials on the model have finished loading, the mesh feature processor will ignore it. // Wait for them all to be ready before creating the instance diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp index 0914e26cb7..b91fdc7094 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -552,7 +553,7 @@ namespace NvCloth if (!destVerticesBuffer) { - AZ_Error("ClothComponentMesh", false, + AZ_Error("ClothComponentMesh", AZ::RHI::IsNullRenderer(), "Invalid vertex position buffer obtained from the render mesh to be modified."); continue; } From 7dabe8b6e966273940e7d98284966104064b783e Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Thu, 17 Jun 2021 13:58:20 -0500 Subject: [PATCH 53/93] Updated Several Engine Gem's CMakeLists.txt to add themselves as required Gems (#1262) * Fixed organization of the AssetProcessor SourceAssetBrowser Assets within the Engine Root were grouped under a '/' entry. That has been fixed to use the relative path within the engine root for those assets Assets outside of the Engine Root, but on the same drive were using absolute paths before. Now there are child entries that navigate up the directory hierarchy to those asset locations * Added ly_enable_gems call to Atom gems targets that are required The DefaultLevel.prefab contains several Atom components, that require the Atom RHI, RPI, Common_Feature, ShaderBuilder and AtomLyIntegration CommonFeatures gems to be enabled in order to successfully process in the AssetProcessor. * Added ly_enable_gems call to make the Camera gem required in Tools, Builders and Clients. This is needed as the DefaultLevel.prefab contains an Editor Camera Component * Adding the ly_enable_gem call to make the Maestro gem required CrySystem currently requires Maestro to be enabled in order to initialize * Added ly_enable_gems call to the SceneProcessing gem to make it required The SceneCore and SceneData libraries that are part of the core engine Code folder requires the SceneProcessing gem to be enabled in order to invoke the InitializeDynamicModule hooks in DllMain.cpp in order to initialize those libraries. * Fixed bad argument in comment for Prefab CMakeLists.txt * Fixed Assert in Asset Builders due to the Atom RPI Builder The Atom RPI Builder was enabling the Asset Catalog for the ScriptAsset a second time The Atom Feature Common EditorSystemCommonComponent.cpp which also loads in the AssetBuilder is enabling the Asset Catalog for the ScriptAsset Added BehaviorContext reflection to the OutputDeviceTransformType enum to fix the BehaviorContext errors about reflecting a method that returns such an enum * Added TypeId output to the JsonDeserializer report message about missing ClassData Previously the report callback would indicate that the target type was missing Serialization class data, but didn't indicate the TypeId of the target type * Added support to the ly_enable_gems function to be able to support 0 gems being enabled. Updated the Install step for CMake to propagate any ly_enable_gems within a CMakeLists.txt for a target into the generated CMakeLists.txt that is made for each installed IMPORTED target * Adding newline to the end of the Camera Gem CMakeLists.txt * Fixing target TYPE parameter for actual Gem Modules to use the GEM_MODULE tag instead of MODULE * Reverting change to the DESTINATION directory for the installed CMakeLists.txt to use the relative path to the installed directory * Adding the Atom_Bootstrap gem as a required gem The Client and GameLaunchers required the Atom_Bootstrap gem in order to create the NativeWindow Added Atom_Feature_Common client module as a runtime dependency of the AtomLyIntegration CommonsFeature client module * Fixed register.py --all-projects-path and --all-gems-path arguments to NOT register projects or gems that are within a template folder Fixed reading of old pre-1.0 o3de_manifest.json files where the "engines" key was a json array * Changed how the relative target source directory is calculated when that source directroy resides outside of the engine root. The final dirname component is used with a unique SHA256 has to form a -<8 char SHA256> folder for installing files into * Adding newline to the end of Atom_Bootstrap CMakeLists.txt * Moving ly_enable_gems variants for Tools and Builders inside of PAL_TRAIT_BUILD_HOST_TOOLS block * Adding a comment to AWSCore.ResourceMappingTool target to indicate that it is not a GEM_MODULE. Furthermore it cannot be loaded with the Gem system because the library is in a different directory the executable --- .../Serialization/Json/JsonDeserializer.cpp | 5 +- .../tests/DummyProject/project.json | 3 +- .../native/ui/SourceAssetTreeModel.cpp | 13 +- Gems/AWSCore/Code/CMakeLists.txt | 4 +- Gems/Atom/Asset/Shader/Code/CMakeLists.txt | 5 + Gems/Atom/Bootstrap/Code/CMakeLists.txt | 17 ++ .../Features/Shadow/ProjectedShadow.azsli | 8 +- .../Shaders/Shadow/DepthExponentiation.azsl | 2 +- Gems/Atom/Feature/Common/Code/CMakeLists.txt | 8 + .../DisplayMapperConfigurationDescriptor.cpp | 13 ++ .../runtime_dependencies_clients.cmake | 14 ++ .../Android/runtime_dependencies_tools.cmake} | 4 +- .../Linux/runtime_dependencies_clients.cmake | 14 ++ .../Linux/runtime_dependencies_tools.cmake | 19 ++ .../Mac/runtime_dependencies_clients.cmake | 14 ++ .../Mac/runtime_dependencies_tools.cmake | 19 ++ .../runtime_dependencies_clients.cmake | 16 ++ .../Windows/runtime_dependencies_tools.cmake | 19 ++ .../iOS/runtime_dependencies_clients.cmake | 14 ++ .../iOS/runtime_dependencies_tools.cmake} | 4 +- .../ProfilingCaptureSystemComponent.cpp | 4 +- Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp | 2 +- Gems/Atom/RPI/Code/CMakeLists.txt | 4 + .../Material/MaterialReloadNotificationBus.h | 2 +- .../Shader/ShaderReloadNotificationBus.h | 2 +- .../Atom/RPI.Public/Shader/ShaderVariant.h | 6 +- .../Source/RPI.Builders/BuilderComponent.cpp | 14 -- .../RPI.Public/Shader/ShaderVariant.cpp | 4 +- .../RPI.Reflect/Material/MaterialAsset.cpp | 2 +- .../Include/Atom/Utils/ImGuiCpuProfiler.inl | 10 +- .../CommonFeatures/Code/CMakeLists.txt | 54 ++++++ .../CoreLights/EditorAreaLightComponent.cpp | 12 +- Gems/Camera/Code/CMakeLists.txt | 18 ++ Gems/Maestro/Code/CMakeLists.txt | 17 ++ Gems/Prefab/PrefabBuilder/CMakeLists.txt | 4 +- Gems/QtForPython/Code/CMakeLists.txt | 2 +- Gems/SceneProcessing/Code/CMakeLists.txt | 6 + .../DefaultGem/Template/Code/CMakeLists.txt | 2 +- cmake/Gems.cmake | 30 ++- cmake/Platform/Common/Install_common.cmake | 121 +++++++----- scripts/o3de/o3de/register.py | 176 ++++++++++-------- 41 files changed, 521 insertions(+), 186 deletions(-) create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_clients.cmake rename Gems/Atom/Feature/Common/Code/{Platform/Common/atom_feature_common_msvc.cmake => Source/Platform/Android/runtime_dependencies_tools.cmake} (91%) create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_clients.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_tools.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_clients.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_tools.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_clients.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_tools.cmake create mode 100644 Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_clients.cmake rename Gems/Atom/Feature/Common/Code/{Platform/Common/atom_feature_common_clang.cmake => Source/Platform/iOS/runtime_dependencies_tools.cmake} (90%) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index d948966b4b..a0a2ea6c37 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace AZ @@ -595,7 +596,9 @@ namespace AZ } else { - status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, "Serialization information for target type not found."); + using ReporterString = AZStd::fixed_string<1024>; + status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, + ReporterString::format("Serialization information for target type %s not found.", loadedTypeId.m_typeId.ToString().c_str())); return ResolvePointerResult::FullyProcessed; } objectType = loadedTypeId.m_typeId; diff --git a/Code/Tools/AssetBundler/tests/DummyProject/project.json b/Code/Tools/AssetBundler/tests/DummyProject/project.json index 0fa6ec7011..84edbe781b 100644 --- a/Code/Tools/AssetBundler/tests/DummyProject/project.json +++ b/Code/Tools/AssetBundler/tests/DummyProject/project.json @@ -10,5 +10,6 @@ "version_number" : 1, "version_name" : "1.0.0.0", "orientation" : "landscape" - } + }, + "engine" : "o3de" } diff --git a/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp b/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp index 69e60f6733..74562f5af1 100644 --- a/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp +++ b/Code/Tools/AssetProcessor/native/ui/SourceAssetTreeModel.cpp @@ -63,7 +63,7 @@ namespace AssetProcessor } - AZ::IO::Path fullPath = AZ::IO::Path(scanFolder.m_scanFolder, AZ::IO::PosixPathSeparator) / source.m_sourceName; + AZ::IO::Path fullPath = AZ::IO::Path(scanFolder.m_scanFolder) / source.m_sourceName; // It's common for Open 3D Engine game projects and scan folders to be in a subfolder // of the engine install. To improve readability of the source files, strip out @@ -74,7 +74,7 @@ namespace AssetProcessor } if (m_assetRootSet) { - AzFramework::StringFunc::Replace(fullPath.Native(), m_assetRoot.absolutePath().toUtf8(), ""); + fullPath = fullPath.LexicallyProximate(m_assetRoot.absolutePath().toUtf8().constData()); } if (fullPath.empty()) @@ -88,11 +88,12 @@ namespace AssetProcessor QModelIndex newIndicesStart; AssetTreeItem* parentItem = m_root.get(); - AZ::IO::Path currentFullFolderPath; - const AZ::IO::PathView filename = fullPath.Filename(); - const AZ::IO::PathView fullPathWithoutFilename = fullPath.RemoveFilename(); + // Use posix path separator for each child item + AZ::IO::Path currentFullFolderPath(AZ::IO::PosixPathSeparator); + const AZ::IO::FixedMaxPath filename = fullPath.Filename(); + fullPath.RemoveFilename(); AZStd::fixed_string currentPath; - for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt) + for (auto pathIt = fullPath.begin(); pathIt != fullPath.end(); ++pathIt) { currentPath = pathIt->FixedMaxPathString(); currentFullFolderPath /= currentPath; diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index d6cd57355f..4ade4b5e54 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -74,7 +74,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_target( - NAME AWSCore.Editor MODULE + NAME AWSCore.Editor GEM_MODULE NAMESPACE Gem FILES_CMAKE awscore_editor_shared_files.cmake @@ -89,6 +89,8 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) Gem::AWSCore ) + # This target is not a real gem module + # It is not meant to be loaded by the ModuleManager in C++ ly_add_target( NAME AWSCore.ResourceMappingTool MODULE NAMESPACE Gem diff --git a/Gems/Atom/Asset/Shader/Code/CMakeLists.txt b/Gems/Atom/Asset/Shader/Code/CMakeLists.txt index dd8afec534..8bc032537d 100644 --- a/Gems/Atom/Asset/Shader/Code/CMakeLists.txt +++ b/Gems/Atom/Asset/Shader/Code/CMakeLists.txt @@ -102,6 +102,11 @@ ly_add_target( 3rdParty::azslc ) +# The Atom_Asset_Shader is a required gem for Builders in order to process the assets that come WITHOUT +# the Atom_Feature_Common required gem +ly_enable_gems(GEMS Atom_Asset_Shader VARIANTS Builders + TARGETS AssetBuilder AssetProcessor AssetProcessorBatch) + ################################################################################ # Tests ################################################################################ diff --git a/Gems/Atom/Bootstrap/Code/CMakeLists.txt b/Gems/Atom/Bootstrap/Code/CMakeLists.txt index 5e5a8c96d9..e2147f0bf3 100644 --- a/Gems/Atom/Bootstrap/Code/CMakeLists.txt +++ b/Gems/Atom/Bootstrap/Code/CMakeLists.txt @@ -37,3 +37,20 @@ ly_add_target( Legacy::CryCommon Gem::Atom_RPI.Public ) + +# Atom_Bootstrap is only used in Launchers +ly_create_alias(NAME Atom_Bootstrap.Clients NAMESPACE Gem TARGETS Gem::Atom_Bootstrap) +ly_create_alias(NAME Atom_Bootstrap.Servers NAMESPACE Gem TARGETS Gem::Atom_Bootstrap) + +# The Atom_Bootstrap gem is responsible for making the NativeWindow handle in the launcher applications +# Loop over each Project name to allow the ${ProjectName}.GameLauncher and ${ProjectName}.ServerLauncher +# target to add the gem the Clients and Servers variant +get_property(LY_PROJECTS_TARGET_NAME GLOBAL PROPERTY LY_PROJECTS_TARGET_NAME) +foreach(project_name IN LISTS LY_PROJECTS_TARGET_NAME) + # Add gem as a dependency of the Clients Launcher + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Atom_Bootstrap VARIANTS Clients TARGETS ${project_name}.GameLauncher) + # Add gem as a dependency of the Servers Launcher + if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Atom_Bootstrap VARIANTS Servers TARGETS ${project_name}.ServerLauncher) + endif() +endforeach() diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli index 8668ac10d8..b8e5c485aa 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli @@ -246,8 +246,8 @@ float ProjectedShadow::GetVisibilityEsm() const float occluder = shadowmap.Sample( PassSrg::LinearSampler, float3(atlasPosition.xy * invAtlasSize, atlasPosition.z)).r; - - const float exponent = -ViewSrg::m_projectedShadows[m_shadowIndex].m_esmExponent * (depth - occluder); + + const float exponent = -ViewSrg::m_projectedShadows[m_shadowIndex].m_esmExponent * (depth - occluder); const float ratio = exp(exponent); // pow() mitigates light bleeding to shadows from near shadow casters. return saturate( pow(ratio, 8) ); @@ -287,8 +287,8 @@ float ProjectedShadow::GetVisibilityEsmPcf() const float occluder = shadowmap.Sample( PassSrg::LinearSampler, float3(atlasPosition.xy * invAtlasSize, atlasPosition.z)).r; - - const float exponent = -ViewSrg::m_projectedShadows[m_shadowIndex].m_esmExponent * (depth - occluder); + + const float exponent = -ViewSrg::m_projectedShadows[m_shadowIndex].m_esmExponent * (depth - occluder); float ratio = exp(exponent); static const float pcfFallbackThreshold = 1.04; diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/Shadow/DepthExponentiation.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/Shadow/DepthExponentiation.azsl index 1954605656..5012f85c54 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/Shadow/DepthExponentiation.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/Shadow/DepthExponentiation.azsl @@ -71,7 +71,7 @@ void MainCS(uint3 dispatchId: SV_DispatchThreadID) // Todo: Expose Esm exponent slider for directional lights // This would remove the exp calculation below, collapsing it into a subtraction in DirectionalLightShadow.azsli - // ATOM-15775 + // ATOM-15775 const float outValue = exp(EsmExponentialShift * depth); PassSrg::m_outputShadowmap[dispatchId].r = outValue; break; diff --git a/Gems/Atom/Feature/Common/Code/CMakeLists.txt b/Gems/Atom/Feature/Common/Code/CMakeLists.txt index 6f087edefe..da092c3f8a 100644 --- a/Gems/Atom/Feature/Common/Code/CMakeLists.txt +++ b/Gems/Atom/Feature/Common/Code/CMakeLists.txt @@ -76,6 +76,8 @@ ly_add_target( FILES_CMAKE atom_feature_common_shared_files.cmake ../Assets/atom_feature_common_asset_files.cmake + PLATFORM_INCLUDE_FILES + ${pal_source_dir}/runtime_dependencies_clients.cmake INCLUDE_DIRECTORIES PRIVATE Source @@ -99,6 +101,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) NAMESPACE Gem FILES_CMAKE atom_feature_common_editor_files.cmake + PLATFORM_INCLUDE_FILES + ${pal_source_dir}/runtime_dependencies_tools.cmake INCLUDE_DIRECTORIES PRIVATE . @@ -130,12 +134,16 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) NAMESPACE Gem FILES_CMAKE atom_feature_common_builders_files.cmake + PLATFORM_INCLUDE_FILES + ${pal_source_dir}/runtime_dependencies_tools.cmake INCLUDE_DIRECTORIES PRIVATE Source/Builders BUILD_DEPENDENCIES PRIVATE AZ::AzCore + RUNTIME_DEPENDENCIES + Gem::Atom_RHI.Private ) endif() diff --git a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp index a064b61a1a..95f2046fe5 100644 --- a/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/DisplayMapper/DisplayMapperConfigurationDescriptor.cpp @@ -50,6 +50,19 @@ namespace AZ if (auto behaviorContext = azrtti_cast(context)) { + behaviorContext->Class() + ->Enum("OutputDeviceTransformType_48Nits") + ->Attribute(AZ::Script::Attributes::Module, "atom") + ->Enum("OutputDeviceTransformType_100Nits") + ->Attribute(AZ::Script::Attributes::Module, "atom") + ->Enum("OutputDeviceTransformType_2000Nits") + ->Attribute(AZ::Script::Attributes::Module, "atom") + ->Enum("OutputDeviceTransformType_4000Nits") + ->Attribute(AZ::Script::Attributes::Module, "atom") + ->Enum("OutputDeviceTransformType_NumOutputDeviceTransformTypes") + ->Attribute(AZ::Script::Attributes::Module, "atom") + ; + behaviorContext->Class("AcesParameterOverrides") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Category, "render") diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_clients.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_clients.cmake new file mode 100644 index 0000000000..31c0cab74b --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_clients.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private +) diff --git a/Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_msvc.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_tools.cmake similarity index 91% rename from Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_msvc.cmake rename to Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_tools.cmake index 74ca22aaea..99eec9a733 100644 --- a/Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_msvc.cmake +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Android/runtime_dependencies_tools.cmake @@ -9,7 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_COMPILE_OPTIONS - PRIVATE - /EHsc +set(LY_RUNTIME_DEPENDENCIES ) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_clients.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_clients.cmake new file mode 100644 index 0000000000..31c0cab74b --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_clients.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_tools.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_tools.cmake new file mode 100644 index 0000000000..c76527afa0 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Linux/runtime_dependencies_tools.cmake @@ -0,0 +1,19 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Metal.Builders +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_clients.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_clients.cmake new file mode 100644 index 0000000000..a0aa67c703 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_clients.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_tools.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_tools.cmake new file mode 100644 index 0000000000..81046d3071 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Mac/runtime_dependencies_tools.cmake @@ -0,0 +1,19 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Metal.Builders + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Builders +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_clients.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_clients.cmake new file mode 100644 index 0000000000..dfd0319c05 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_clients.cmake @@ -0,0 +1,16 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Null.Private +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_tools.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_tools.cmake new file mode 100644 index 0000000000..c76527afa0 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/Windows/runtime_dependencies_tools.cmake @@ -0,0 +1,19 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Vulkan.Private + Gem::Atom_RHI_DX12.Private + Gem::Atom_RHI_Metal.Private + Gem::Atom_RHI_Vulkan.Builders + Gem::Atom_RHI_DX12.Builders + Gem::Atom_RHI_Metal.Builders +) diff --git a/Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_clients.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_clients.cmake new file mode 100644 index 0000000000..a0aa67c703 --- /dev/null +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_clients.cmake @@ -0,0 +1,14 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(LY_RUNTIME_DEPENDENCIES + Gem::Atom_RHI_Metal.Private +) diff --git a/Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_clang.cmake b/Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_tools.cmake similarity index 90% rename from Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_clang.cmake rename to Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_tools.cmake index 5963f882c3..99eec9a733 100644 --- a/Gems/Atom/Feature/Common/Code/Platform/Common/atom_feature_common_clang.cmake +++ b/Gems/Atom/Feature/Common/Code/Source/Platform/iOS/runtime_dependencies_tools.cmake @@ -9,7 +9,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(LY_COMPILE_OPTIONS - PRIVATE - -fexceptions +set(LY_RUNTIME_DEPENDENCIES ) diff --git a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp index 295e10a53f..4fa466589c 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp @@ -486,7 +486,7 @@ namespace AZ AZ_Warning("ProfilingCaptureSystemComponent", false, captureInfo.c_str()); } else - { + { AZ_Printf("ProfilingCaptureSystemComponent", "Cpu profiling statistics was saved to file [%s]\n", outputFilePath.c_str()); } @@ -500,7 +500,7 @@ namespace AZ ProfilingCaptureNotificationBus::Broadcast(&ProfilingCaptureNotificationBus::Events::OnCaptureCpuProfilingStatisticsFinished, saveResult.IsSuccess(), captureInfo); - + }); // Start the TickBus. diff --git a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp index e1666549c9..16ddc8599d 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/RHISystem.cpp @@ -219,7 +219,7 @@ namespace AZ { AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzRender, "main per-frame work"); m_frameScheduler.BeginFrame(); - + frameGraphCallback(m_frameScheduler); /** diff --git a/Gems/Atom/RPI/Code/CMakeLists.txt b/Gems/Atom/RPI/Code/CMakeLists.txt index 8a2684347e..bd2af88816 100644 --- a/Gems/Atom/RPI/Code/CMakeLists.txt +++ b/Gems/Atom/RPI/Code/CMakeLists.txt @@ -66,6 +66,8 @@ ly_add_target( Gem::Atom_RPI.Public Gem::Atom_RHI.Public Gem::Atom_RHI.Reflect + RUNTIME_DEPENDENCIES + Gem::Atom_RHI.Private ) if(PAL_TRAIT_BUILD_HOST_TOOLS) @@ -129,6 +131,8 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Gem::Atom_RPI.Editor.Static Gem::Atom_RPI.Edit Gem::Atom_RPI.Public + RUNTIME_DEPENDENCIES + Gem::Atom_RHI.Private ) endif() diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h index 881b40b785..d62acab369 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Material/MaterialReloadNotificationBus.h @@ -24,7 +24,7 @@ namespace AZ //! Connect to this EBus to get notifications whenever material objects reload. //! The bus address is the AssetId of the MaterialAsset or MaterialTypeAsset. - //! + //! //! Be careful when using the parameters provided by these functions. The bus ID is an AssetId, and it's possible for the system to have //! both *old* versions and *new reloaded* versions of the asset in memory at the same time, and they will have the same AssetId. Therefore //! your bus Handlers could receive Reinitialized messages from multiple sources. It may be necessary to check the memory addresses of these diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h index 8ea34187ff..ec90b5d790 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h @@ -27,7 +27,7 @@ namespace AZ /** * Connect to this EBus to get notifications whenever a shader system class reinitializes itself. * The bus address is the AssetId of the ShaderAsset, even when the thing being reinitialized is a ShaderVariant or other shader related class. - * + * * Be careful when using the parameters provided by these functions. The bus ID is an AssetId, and it's possible for the system to have * both *old* versions and *new reloaded* versions of the asset in memory at the same time, and they will have the same AssetId. Therefore * your bus Handlers could receive Reinitialized messages from multiple sources. It may be necessary to check the memory addresses of these diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderVariant.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderVariant.h index 7363ab4d1a..72953bd153 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderVariant.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/Shader/ShaderVariant.h @@ -56,7 +56,7 @@ namespace AZ bool IsRootVariant() const { return m_shaderVariantAsset->IsRootVariant(); } ShaderVariantStableId GetStableId() const { return m_shaderVariantAsset->GetStableId(); } - + const Data::Asset& GetShaderAsset() const { return m_shaderAsset; } const Data::Asset& GetShaderVariantAsset() const { return m_shaderVariantAsset; } @@ -65,10 +65,10 @@ namespace AZ bool Init( const Data::Asset& shaderAsset, const Data::Asset& shaderVariantAsset); - + // AssetBus overrides... void OnAssetReloaded(Data::Asset asset) override; - + //! A reference to the shader asset that this is a variant of. Data::Asset m_shaderAsset; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/BuilderComponent.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/BuilderComponent.cpp index 70752bf02b..ac641d67fc 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/BuilderComponent.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/BuilderComponent.cpp @@ -105,20 +105,6 @@ namespace AZ m_assetHandlers.emplace_back(MakeAssetHandler()); m_assetHandlers.emplace_back(MakeAssetHandler()); m_assetHandlers.emplace_back(MakeAssetHandler()); - - RPI::MaterialFunctorSourceDataRegistration* materialFunctorRegistration = RPI::MaterialFunctorSourceDataRegistration::Get(); - AZ_Assert(materialFunctorRegistration, - "MaterialFunctorSourceDataRegistration must be added to a component of the current module, " - "and initialize it in the component's Init() call."); - materialFunctorRegistration->RegisterMaterialFunctor("Lua", azrtti_typeid()); - - - // Add asset types and extensions to AssetCatalog. Uses "AssetCatalogService". - auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); - if (assetCatalog) - { - assetCatalog->EnableCatalogForAsset(AZ::AzTypeInfo::Uuid()); - } } void BuilderComponent::Deactivate() diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariant.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariant.cpp index acd9922b68..3ef6f76333 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariant.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderVariant.cpp @@ -91,7 +91,7 @@ namespace AZ { return m_shaderVariantAsset->GetOutputContract(); } - + void ShaderVariant::OnAssetReloaded(Data::Asset asset) { ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->ShaderVariant::OnAssetReloaded %s", this, asset.GetHint().c_str()); @@ -102,7 +102,7 @@ namespace AZ Init(m_shaderAsset, shaderVariantAsset); ShaderReloadNotificationBus::Event(m_shaderAsset.GetId(), &ShaderReloadNotificationBus::Events::OnShaderVariantReinitialized, *this); } - + if (asset.GetAs()) { Data::Asset shaderAsset = { asset.GetAs(), AZ::Data::AssetLoadBehavior::PreLoad }; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp index 7446c498cd..bb0de1b3c6 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Reflect/Material/MaterialAsset.cpp @@ -119,7 +119,7 @@ namespace AZ { // When reloads occur, it's possible for old Asset objects to hang around and report reinitialization, // so we can reduce unnecessary reinitialization in that case. - if (materialTypeAsset.Get() == m_materialTypeAsset.Get()) + if (materialTypeAsset.Get() == m_materialTypeAsset.Get()) { ShaderReloadDebugTracker::ScopedSection reloadSection("{%p}->MaterialAsset::OnMaterialTypeAssetReinitialized %s", this, materialTypeAsset.GetHint().c_str()); diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl index 50ef1a8e66..72e313157d 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl @@ -12,7 +12,7 @@ #include #include -#include // For AZ_MAX_PATH_LEN +#include #include namespace AZ @@ -48,10 +48,10 @@ namespace AZ if (ImGui::Begin("Cpu Profiler", &keepDrawing, ImGuiWindowFlags_None)) { m_paused = !AZ::RHI::CpuProfiler::Get()->IsProfilerEnabled(); - if (ImGui::Button(m_paused?"Resume":"Pause")) + if (ImGui::Button(m_paused ? "Resume" : "Pause")) { m_paused = !m_paused; - AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(!m_paused); + AZ::RHI::CpuProfiler::Get()->SetProfilerEnabled(!m_paused); } // Update region map and cache the input cpu timing statistics when the profiling is not paused @@ -194,8 +194,8 @@ namespace AZ AZStd::to_string(timeString, timeNow); u64 currentTick = AZ::RPI::RPISystemInterface::Get()->GetCurrentTick(); AZStd::string frameDataFilePath = AZStd::string::format("@user@/CpuProfiler/%s_%llu.json", timeString.c_str(), currentTick); - char resolvedPath[AZ_MAX_PATH_LEN]; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(frameDataFilePath.c_str(), resolvedPath, AZ_MAX_PATH_LEN); + char resolvedPath[AZ::IO::MaxPathLength]; + AZ::IO::FileIOBase::GetInstance()->ResolvePath(frameDataFilePath.c_str(), resolvedPath, AZ::IO::MaxPathLength); m_lastCapturedFilePath = resolvedPath; AZ::Render::ProfilingCaptureRequestBus::Broadcast(&AZ::Render::ProfilingCaptureRequestBus::Events::CaptureCpuProfilingStatistics, frameDataFilePath); diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt b/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt index 33fad00cbe..ea4f4259da 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/CMakeLists.txt @@ -61,6 +61,21 @@ ly_add_target( BUILD_DEPENDENCIES PRIVATE Gem::AtomLyIntegration_CommonFeatures.Static + RUNTIME_DEPENDENCIES + Gem::Atom_RPI.Private + Gem::Atom_Feature_Common +) + +# The AtomLyIntegration_CommonFeatures module is used for Clients and Servers +ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Clients NAMESPACE Gem + TARGETS + Gem::AtomLyIntegration_CommonFeatures + Gem::GradientSignal.Clients +) +ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Servers NAMESPACE Gem + TARGETS + Gem::AtomLyIntegration_CommonFeatures + Gem::GradientSignal.Servers ) if(PAL_TRAIT_BUILD_HOST_TOOLS) @@ -94,5 +109,44 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) Legacy::Editor.Headers Legacy::EditorCommon Legacy::CryCommon + RUNTIME_DEPENDENCIES + Gem::Atom_RPI.Editor + Gem::Atom_Feature_Common.Editor ) + + # The AtomLyIntegration_CommonFeatures.Editor module is used for Builders and Tools + ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Builders NAMESPACE Gem + TARGETS + Gem::AtomLyIntegration_CommonFeatures.Editor + Gem::Atom_RPI.Builders + Gem::GradientSignal.Builders + ) + ly_create_alias(NAME AtomLyIntegration_CommonFeatures.Tools NAMESPACE Gem + TARGETS + Gem::AtomLyIntegration_CommonFeatures.Editor + Gem::GradientSignal.Tools + ) + + # AtomLyIntergration_CommonFeatures gem targets are required as part of the Editor and AssetProcessor + # due to the AZ::Render::EditorDirectionalLightComponent, AZ::Render::EditorMeshComponent, + # AZ::Render::EditorGridComponent, AZ::Render::EditorHDRiSkyboxComponent, + # AZ::Render::EditorImageBasedLightComponent being saved as part of the DefaultLevel.prefab + ly_enable_gems(GEMS AtomLyIntegration_CommonFeatures VARIANTS Tools + TARGETS Editor) + ly_enable_gems(GEMS AtomLyIntegration_CommonFeatures VARIANTS Builders + TARGETS AssetBuilder AssetProcessor AssetProcessorBatch) endif() + + +# Added dependencies to the Client and Server Launchers +get_property(LY_PROJECTS_TARGET_NAME GLOBAL PROPERTY LY_PROJECTS_TARGET_NAME) +foreach(project_name IN LISTS LY_PROJECTS_TARGET_NAME) + # Add gem as a dependency of the Clients Launcher + ly_enable_gems(PROJECT_NAME ${project_name} GEMS AtomLyIntegration_CommonFeatures VARIANTS Clients + TARGETS ${project_name}.GameLauncher) + # Add gem as a dependency of the Servers Launcher + if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) + ly_enable_gems(PROJECT_NAME ${project_name} GEMS AtomLyIntegration_CommonFeatures VARIANTS Servers + TARGETS ${project_name}.ServerLauncher) + endif() +endforeach() diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp index 91a909e809..378059b766 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp @@ -179,18 +179,18 @@ namespace AZ ->EnumAttribute(PcfMethod::BoundarySearch, "Boundary search") ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) - ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) + ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled) ->DataElement( Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_esmExponent, "Esm Exponent", - "Exponent used by Esm shadows. " - "Larger values increase the sharpness of the border between lit and unlit areas.") + "Exponent used by Esm shadows. " + "Larger values increase the sharpness of the border between lit and unlit areas.") ->Attribute(Edit::Attributes::Min, 50.0f) - ->Attribute(Edit::Attributes::Max, 5000.0f) + ->Attribute(Edit::Attributes::Max, 5000.0f) ->Attribute(AZ::Edit::Attributes::Decimals, 0) ->Attribute(AZ::Edit::Attributes::SliderCurveMidpoint, 0.05f) - ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) - ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsEsmDisabled) + ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsEsmDisabled) ; } } diff --git a/Gems/Camera/Code/CMakeLists.txt b/Gems/Camera/Code/CMakeLists.txt index 703424416b..b45f768cb7 100644 --- a/Gems/Camera/Code/CMakeLists.txt +++ b/Gems/Camera/Code/CMakeLists.txt @@ -69,4 +69,22 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) # tools and builders use the above module. ly_create_alias(NAME Camera.Tools NAMESPACE Gem TARGETS Gem::Camera.Editor) ly_create_alias(NAME Camera.Builders NAMESPACE Gem TARGETS Gem::Camera.Editor) + + # The DefaultPrefab contains an EditorCameraComponent which makes this gem required + ly_enable_gems(GEMS Camera VARIANTS Tools TARGETS Editor) + ly_enable_gems(GEMS Camera VARIANTS Builders TARGETS AssetBuilder AssetProcessor AssetProcessorBatch) endif() + + +# Added dependencies to the Client and Server Launchers +get_property(LY_PROJECTS_TARGET_NAME GLOBAL PROPERTY LY_PROJECTS_TARGET_NAME) +foreach(project_name IN LISTS LY_PROJECTS_TARGET_NAME) + # Add gem as a dependency of the Clients Launcher + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Camera VARIANTS Clients + TARGETS ${project_name}.GameLauncher) + # Add gem as a dependency of the Servers Launcher + if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Camera VARIANTS Servers + TARGETS ${project_name}.ServerLauncher) + endif() +endforeach() diff --git a/Gems/Maestro/Code/CMakeLists.txt b/Gems/Maestro/Code/CMakeLists.txt index 01b22b1abf..d92f2ab643 100644 --- a/Gems/Maestro/Code/CMakeLists.txt +++ b/Gems/Maestro/Code/CMakeLists.txt @@ -78,8 +78,25 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_create_alias(NAME Maestro.Tools NAMESPACE Gem TARGETS Gem::Maestro.Editor) ly_create_alias(NAME Maestro.Builders NAMESPACE Gem TARGETS Gem::Maestro.Editor) + # Maestro is still used by the CrySystem Level System and SystemInit and TrackView + # It is required by the GameLauncher, ServerLauncher and Editor applications + ly_enable_gems(GEMS Maestro VARIANTS Tools TARGETS Editor) + endif() +# Loop over each Project name to allow the ${ProjectName}.GameLauncher and ${ProjectName}.ServerLauncher +# target to add the gem the Clients and Servers variant +get_property(LY_PROJECTS_TARGET_NAME GLOBAL PROPERTY LY_PROJECTS_TARGET_NAME) +foreach(project_name IN LISTS LY_PROJECTS_TARGET_NAME) + # Add gem as a dependency of the Clients Launcher + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Maestro VARIANTS Clients TARGETS ${project_name}.GameLauncher) + # Add gem as a dependency of the Servers Launcher + if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) + ly_enable_gems(PROJECT_NAME ${project_name} GEMS Maestro VARIANTS Servers TARGETS ${project_name}.ServerLauncher) + endif() +endforeach() + + ################################################################################ # Tests ################################################################################ diff --git a/Gems/Prefab/PrefabBuilder/CMakeLists.txt b/Gems/Prefab/PrefabBuilder/CMakeLists.txt index dbd3c2281b..f6de132dcb 100644 --- a/Gems/Prefab/PrefabBuilder/CMakeLists.txt +++ b/Gems/Prefab/PrefabBuilder/CMakeLists.txt @@ -26,7 +26,7 @@ ly_add_target( ) ly_add_target( - NAME PrefabBuilder MODULE + NAME PrefabBuilder GEM_MODULE NAMESPACE Gem INCLUDE_DIRECTORIES PRIVATE @@ -47,7 +47,7 @@ ly_enable_gems(GEMS PrefabBuilder VARIANTS Builders TARGETS AssetProcessor Asset # if you have a custom builder application in your project, then use ly_enable_gems() to # add it to that application for your project, like this to make YOUR_TARGET_NAME load it automatically -# ly_enable_gems(PROJECT (YOUR_PROJECT_NAME) GEMS PrefabBuilder VARIANTS Builders TARGETS (YOUR_TARGET_NAME) ) +# ly_enable_gems(PROJECT_NAME (YOUR_PROJECT_NAME) GEMS PrefabBuilder VARIANTS Builders TARGETS (YOUR_TARGET_NAME) ) if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_target( diff --git a/Gems/QtForPython/Code/CMakeLists.txt b/Gems/QtForPython/Code/CMakeLists.txt index c11d93634e..f0d82a1464 100644 --- a/Gems/QtForPython/Code/CMakeLists.txt +++ b/Gems/QtForPython/Code/CMakeLists.txt @@ -45,7 +45,7 @@ ly_add_target( ) ly_add_target( - NAME QtForPython.Editor MODULE + NAME QtForPython.Editor GEM_MODULE NAMESPACE Gem FILES_CMAKE qtforpython_shared_files.cmake diff --git a/Gems/SceneProcessing/Code/CMakeLists.txt b/Gems/SceneProcessing/Code/CMakeLists.txt index 4b0dfbab27..6a26a176b5 100644 --- a/Gems/SceneProcessing/Code/CMakeLists.txt +++ b/Gems/SceneProcessing/Code/CMakeLists.txt @@ -70,8 +70,14 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_create_alias(NAME SceneProcessing.Builders NAMESPACE Gem TARGETS Gem::SceneProcessing.Editor) ly_create_alias(NAME SceneProcessing.Tools NAMESPACE Gem TARGETS Gem::SceneProcessing.Editor) +# SceneProcessing Gem is only used in Tools and builders and is a requirement for the Editor +ly_enable_gems(GEMS SceneProcessing VARIANTS Tools + TARGETS Editor) +ly_enable_gems(GEMS SceneProcessing VARIANTS Builders + TARGETS AssetBuilder AssetProcessor AssetProcessorBatch) endif() + ################################################################################ # Tests ################################################################################ diff --git a/Templates/DefaultGem/Template/Code/CMakeLists.txt b/Templates/DefaultGem/Template/Code/CMakeLists.txt index b0e52dd79f..25b393302c 100644 --- a/Templates/DefaultGem/Template/Code/CMakeLists.txt +++ b/Templates/DefaultGem/Template/Code/CMakeLists.txt @@ -85,7 +85,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_target( - NAME ${Name}.Editor MODULE + NAME ${Name}.Editor GEM_MODULE NAMESPACE Gem AUTOMOC OUTPUT_NAME Gem.${Name}.Editor diff --git a/cmake/Gems.cmake b/cmake/Gems.cmake index 169210d991..b9c47fd54d 100644 --- a/cmake/Gems.cmake +++ b/cmake/Gems.cmake @@ -84,7 +84,7 @@ function(ly_create_alias) # now add the final alias: add_library(${ly_create_alias_NAMESPACE}::${ly_create_alias_NAME} ALIAS ${ly_create_alias_NAME}) - # Store off the arguments needed used ly_create_alias into a DIRECTORY property + # Store off the arguments used by ly_create_alias into a DIRECTORY property # This will be used to re-create the calls in the generated CMakeLists.txt in the INSTALL step # Replace the CMake list separator with a space to replicate the space separated TARGETS arguments @@ -136,8 +136,8 @@ function(ly_enable_gems) if(NOT was_able_to_load_the_file) message(FATAL_ERROR "could not load the GEM_FILE ${ly_enable_gems_GEM_FILE}") endif() - if(NOT ENABLED_GEMS) - message(FATAL_ERROR "GEM_FILE ${ly_enable_gems_GEM_FILE} did not set the value of ENABLED_GEMS.\n" + if(NOT DEFINED ENABLED_GEMS) + message(WARNING "GEM_FILE ${ly_enable_gems_GEM_FILE} did not set the value of ENABLED_GEMS.\n" "Gem Files should contain set(ENABLED_GEMS ... )") endif() set(ly_enable_gems_GEMS ${ENABLED_GEMS}) @@ -148,9 +148,19 @@ function(ly_enable_gems) foreach(target_name ${ly_enable_gems_TARGETS}) foreach(variant_name ${ly_enable_gems_VARIANTS}) set_property(GLOBAL APPEND PROPERTY LY_DELAYED_ENABLE_GEMS "${ly_enable_gems_PROJECT_NAME},${target_name},${variant_name}") + define_property(GLOBAL PROPERTY LY_DELAYED_ENABLE_GEMS_"${ly_enable_gems_PROJECT_NAME},${target_name},${variant_name}" + BRIEF_DOCS "List of gem names to evaluate variants against" FULL_DOCS "Names of gems that will be paired with the variant name + to determine if it is valid target that should be added as an application dynamic load dependency") set_property(GLOBAL APPEND PROPERTY LY_DELAYED_ENABLE_GEMS_"${ly_enable_gems_PROJECT_NAME},${target_name},${variant_name}" ${ly_enable_gems_GEMS}) endforeach() endforeach() + + # Store off the arguments used by ly_enable_gems into a DIRECTORY property + # This will be used to re-create the ly_enable_gems call in the generated CMakeLists.txt at the INSTALL step + + # Replace the CMake list separator with a space to replicate the space separated TARGETS arguments + string(REPLACE ";" " " enable_gems_args "${ly_enable_gems_PROJECT_NAME},${ly_enable_gems_GEMS},${ly_enable_gems_GEM_FILE},${ly_enable_gems_VARIANTS},${ly_enable_gems_TARGETS}") + set_property(DIRECTORY APPEND PROPERTY LY_ENABLE_GEMS_ARGUMENTS "${enable_gems_args}") endfunction() # call this before runtime dependencies are used to add any relevant targets @@ -176,6 +186,20 @@ function(ly_enable_gems_delayed) get_property(gem_dependencies GLOBAL PROPERTY LY_DELAYED_ENABLE_GEMS_"${project_target_variant}") if (NOT gem_dependencies) + get_property(gem_dependencies_defined GLOBAL PROPERTY LY_DELAYED_ENABLE_GEMS_"${project_target_variant}" DEFINED) + if (gem_dependencies_defined) + # special case, if the LY_DELAYED_ENABLE_GEMS_"${project_target_variant}" property is DEFINED + # but empty, add an entry to the LY_DELAYED_LOAD_DEPENDENCIES to have the + # cmake_dependencies.*.setreg file for the (project, target) tuple to be regenerated + # This is needed if the ENABLED_GEMS list for a project goes from >0 to 0. In this case + # the cmake_dependencies would have a stale list of gems to load unless it is regenerated + get_property(delayed_load_target_set GLOBAL PROPERTY LY_DELAYED_LOAD_"${project},${target}" SET) + if(NOT delayed_load_target_set) + set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_DEPENDENCIES "${project},${target}") + set_property(GLOBAL APPEND PROPERTY LY_DELAYED_LOAD_"${project},${target}" "") + endif() + endif() + # Continue to the next iteration loop regardless as there are no gem dependencies continue() endif() diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index bf7134d470..6998c260b7 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -13,8 +13,8 @@ set(CMAKE_INSTALL_MESSAGE NEVER) # Simplify messages to reduce output noise ly_set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Core) -file(RELATIVE_PATH runtime_output_directory ${CMAKE_BINARY_DIR} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -file(RELATIVE_PATH library_output_directory ${CMAKE_BINARY_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) +cmake_path(RELATIVE_PATH CMAKE_RUNTIME_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE runtime_output_directory) +cmake_path(RELATIVE_PATH CMAKE_LIBRARY_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE library_output_directory) # Anywhere CMAKE_INSTALL_PREFIX is used, it has to be escaped so it is baked into the cmake_install.cmake script instead # of baking the path. This is needed so `cmake --install --prefix ` works regardless of the CMAKE_INSTALL_PREFIX # used to generate the solution. @@ -22,11 +22,34 @@ file(RELATIVE_PATH library_output_directory ${CMAKE_BINARY_DIR} ${CMAKE_LIBRARY_ set(install_output_folder "\${CMAKE_INSTALL_PREFIX}/${runtime_output_directory}/${PAL_PLATFORM_NAME}/$") +function(ly_get_engine_relative_source_dir absolute_target_source_dir output_source_dir) + # Get a relative target source directory to the LY root folder if possible + # Otherwise use the final component name + cmake_path(IS_PREFIX LY_ROOT_FOLDER ${absolute_target_source_dir} is_target_prefix_of_engine_root) + if(is_target_prefix_of_engine_root) + cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_source_dir) + else() + # In this case the target source directory is outside of the engine root of the target source directory and concatenate the first + # is used first 8 characters of the absolute path SHA256 hash to make a unique relative directory + # that can be used to install the generated CMakeLists.txt + # of a SHA256 hash + string(SHA256 target_source_hash ${absolute_target_source_dir}) + string(SUBSTRING ${target_source_hash} 0 8 target_source_hash) + cmake_path(GET absolute_target_source_dir FILENAME target_source_dirname) + cmake_path(SET relative_target_source_dir "${target_source_dirname}-${target_source_hash}") + endif() + + set(${output_source_dir} ${relative_target_source_dir} PARENT_SCOPE) +endfunction() + #! ly_setup_target: Setup the data needed to re-create the cmake target commands for a single target -function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME) +function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_target_source_dir) # De-alias target name ly_de_alias_target(${ALIAS_TARGET_NAME} TARGET_NAME) + # Get the target source directory relative to the LY root folder + ly_get_engine_relative_source_dir(${absolute_target_source_dir} relative_target_source_dir) + # get the component ID. if the property isn't set for the target, it will auto fallback to use CMAKE_INSTALL_DEFAULT_COMPONENT_NAME get_property(install_component TARGET ${TARGET_NAME} PROPERTY INSTALL_COMPONENT) @@ -67,16 +90,16 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME) endif() # Get the output folders, archive is always the same, but runtime/library can be in subfolders defined per target - file(RELATIVE_PATH archive_output_directory ${CMAKE_BINARY_DIR} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) + cmake_path(RELATIVE_PATH CMAKE_ARCHIVE_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE archive_output_directory) get_target_property(target_runtime_output_directory ${TARGET_NAME} RUNTIME_OUTPUT_DIRECTORY) if(target_runtime_output_directory) - file(RELATIVE_PATH target_runtime_output_subdirectory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${target_runtime_output_directory}) + cmake_path(RELATIVE_PATH target_runtime_output_directory BASE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} OUTPUT_VARIABLE target_runtime_output_subdirectory) endif() get_target_property(target_library_output_directory ${TARGET_NAME} LIBRARY_OUTPUT_DIRECTORY) if(target_library_output_directory) - file(RELATIVE_PATH target_library_output_subdirectory ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${target_library_output_directory}) + cmake_path(RELATIVE_PATH target_library_output_directory BASE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} OUTPUT_VARIABLE target_library_output_subdirectory) endif() install( @@ -127,9 +150,9 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME) foreach(include ${include_directories}) string(GENEX_STRIP ${include} include_genex_expr) if(include_genex_expr STREQUAL include) # only for cases where there are no generation expressions - file(RELATIVE_PATH relative_include ${absolute_target_source_dir} ${include}) - cmake_path(APPEND include_location "${target_source_dir}" "${relative_include}" OUTPUT_VARIABLE target_include) + cmake_path(RELATIVE_PATH include BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE target_include) cmake_path(NORMAL_PATH target_include) + # Escape the LY_ROOT_FOLDER variable so that it isn't resolved during the install step string(APPEND INCLUDE_DIRECTORIES_PLACEHOLDER "\${LY_ROOT_FOLDER}/${target_include}\n") endif() endforeach() @@ -207,21 +230,10 @@ set_property(TARGET ${TARGET_NAME} endif() endif() - if(IS_ABSOLUTE ${target_source_dir}) - # This normally applies the target_source_dir is outside of the engine root - # such as when invoking ly_setup_subdirectory from the project - # Therefore the final directory component of the target source directory is used first 8 characters - # of a SHA256 hash - string(SHA256 target_source_hash ${target_source_dir}) - string(SUBSTRING ${target_source_hash} 0 8 target_source_hash) - get_filename_component(target_source_folder_name ${target_source_dir} NAME) - set(target_source_dir "${target_source_folder_name}-${target_source_hash}") - endif() - - set(target_install_source_dir ${CMAKE_CURRENT_BINARY_DIR}/install/${target_source_dir}) + set(target_install_source_dir ${CMAKE_CURRENT_BINARY_DIR}/install/${relative_target_source_dir}) file(GENERATE OUTPUT "${target_install_source_dir}/${NAME_PLACEHOLDER}_$.cmake" CONTENT "${target_file_contents}") install(FILES "${target_install_source_dir}/${NAME_PLACEHOLDER}_$.cmake" - DESTINATION ${target_source_dir} + DESTINATION ${relative_target_source_dir} COMPONENT ${install_component} ) @@ -231,24 +243,26 @@ set_property(TARGET ${TARGET_NAME} set(${OUTPUT_CONFIGURED_TARGET} ${output_cmakelists_data} PARENT_SCOPE) endfunction() + #! ly_setup_subdirectories: setups all targets on a per directory basis function(ly_setup_subdirectories) get_property(all_subdirectories GLOBAL PROPERTY LY_ALL_TARGET_DIRECTORIES) - foreach(target IN LISTS all_subdirectories) - ly_setup_subdirectory(${target}) + foreach(target_subdirectory IN LISTS all_subdirectories) + ly_setup_subdirectory(${target_subdirectory}) endforeach() endfunction() -#! ly_setup_subdirectory: setup all targets in the subdirectory +#! ly_setup_subdirectory: setup all targets in the subdirectory function(ly_setup_subdirectory absolute_target_source_dir) + # Get the target source directory relative to the LY roo folder + ly_get_engine_relative_source_dir(${absolute_target_source_dir} relative_target_source_dir) # The builtin BUILDSYSTEM_TARGETS property isn't being used here as that returns the de-alised # TARGET and we need the alias namespace for recreating the CMakeLists.txt in the install layout get_property(ALIAS_TARGETS_NAME DIRECTORY ${absolute_target_source_dir} PROPERTY LY_DIRECTORY_TARGETS) - file(RELATIVE_PATH target_source_dir ${LY_ROOT_FOLDER} ${absolute_target_source_dir}) foreach(ALIAS_TARGET_NAME IN LISTS ALIAS_TARGETS_NAME) - ly_setup_target(configured_target ${ALIAS_TARGET_NAME}) + ly_setup_target(configured_target ${ALIAS_TARGET_NAME} ${absolute_target_source_dir}) string(APPEND all_configured_targets "${configured_target}") endforeach() @@ -271,34 +285,55 @@ function(ly_setup_subdirectory absolute_target_source_dir) string(APPEND CREATE_ALIASES_PLACEHOLDER ${create_alias_command}) endforeach() + + # Reproduce the ly_enable_gems() calls made in the the SOURCE_DIR for this target into the CMakeLists.txt that + # is about to be generated + string(JOIN "\n" enable_gems_template + " ly_enable_gems(@enable_gem_PROJECT_NAME@ @enable_gem_GEM@ @enable_gem_GEM_FILE@ @enable_gem_VARIANTS@ @enable_gem_TARGETS@)" + "endif()" + "" + ) + get_property(enable_gems_commands_arg_list DIRECTORY ${absolute_target_source_dir} PROPERTY LY_ENABLE_GEMS_ARGUMENTS) + foreach(enable_gems_single_command_arg_list ${enable_gems_commands_arg_list}) + # Split the ly_enable_gems arguments back out based on commas + string(REPLACE "," ";" ly_enable_gems_single_command_arg_list "${enable_gems_single_command_arg_list}") + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_PROJECT_NAME) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_GEM) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_GEM_FILE) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_GEM) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_VARIANTS) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_TARGETS) + foreach(enable_gem_arg_kw IN ITEMS PROJECT_NAME GEM GEM_FILE GEM VARIANTS TARGETS) + list(POP_FRONT enable_gems_single_command_arg_list enable_gem_${enable_gem_arg_kw}) + if(enable_gem_${enable_gem_arg_kw}) + # if the argument exist append to argument keyword to the front + string(PREPEND enable_gem_${enable_gem_arg_kw} "${enable_gem_arg_kw} ") + endif() + endforeach() + + string(CONFIGURE "${enable_gems_template}" enable_gems_command @ONLY) + string(APPEND ENABLE_GEMS_PLACEHOLDER ${enable_gems_command}) + endforeach() + + file(READ ${LY_ROOT_FOLDER}/cmake/install/Copyright.in cmake_copyright_comment) - if(IS_ABSOLUTE ${target_source_dir}) - # This normally applies the target_source_dir is outside of the engine root - # such as when invoking ly_setup_subdirectory from the project - # Therefore the final directory component of the target source directory is used first 8 characters - # of a SHA256 hash - string(SHA256 target_source_hash ${target_source_dir}) - string(SUBSTRING ${target_source_hash} 0 8 target_source_hash) - get_filename_component(target_source_folder_name ${target_source_dir} NAME) - set(target_source_dir "${target_source_folder_name}-${target_source_hash}") - endif() - # Initialize the target install source directory to path underneath the current binary directory - set(target_install_source_dir ${CMAKE_CURRENT_BINARY_DIR}/install/${target_source_dir}) + set(target_install_source_dir ${CMAKE_CURRENT_BINARY_DIR}/install/${relative_target_source_dir}) # Write out all the aggregated ly_add_target function calls and the final ly_create_alias() calls to the target CMakeLists.txt file(WRITE ${target_install_source_dir}/CMakeLists.txt "${cmake_copyright_comment}" "${all_configured_targets}" "\n" "${CREATE_ALIASES_PLACEHOLDER}" + "${ENABLE_GEMS_PLACEHOLDER}" ) # get the component ID. if the property isn't set for the directory, it will auto fallback to use CMAKE_INSTALL_DEFAULT_COMPONENT_NAME get_property(install_component DIRECTORY ${absolute_target_source_dir} PROPERTY INSTALL_COMPONENT) install(FILES "${target_install_source_dir}/CMakeLists.txt" - DESTINATION ${target_source_dir} + DESTINATION ${relative_target_source_dir} COMPONENT ${install_component} ) @@ -328,7 +363,7 @@ function(ly_setup_cmake_install) # Transform the LY_EXTERNAL_SUBDIRS list into a json array set(indent " ") foreach(external_subdir ${LY_EXTERNAL_SUBDIRS}) - file(RELATIVE_PATH engine_rel_external_subdir ${LY_ROOT_FOLDER} ${external_subdir}) + cmake_path(RELATIVE_PATH external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE engine_rel_external_subdir) list(APPEND relative_external_subdirs "\"${engine_rel_external_subdir}\"") endforeach() list(JOIN relative_external_subdirs ",\n${indent}" LY_INSTALL_EXTERNAL_SUBDIRS) @@ -368,8 +403,8 @@ function(ly_setup_cmake_install) # Add to the FIND_PACKAGES_PLACEHOLDER all directories in which ly_add_target were called in get_property(all_subdirectories GLOBAL PROPERTY LY_ALL_TARGET_DIRECTORIES) foreach(target_subdirectory IN LISTS all_subdirectories) - file(RELATIVE_PATH target_source_dir_relative ${LY_ROOT_FOLDER} ${target_subdirectory}) - string(APPEND FIND_PACKAGES_PLACEHOLDER " add_subdirectory(${target_source_dir_relative})\n") + cmake_path(RELATIVE_PATH target_subdirectory BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_subdirectory) + string(APPEND FIND_PACKAGES_PLACEHOLDER " add_subdirectory(${relative_target_subdirectory})\n") endforeach() configure_file(${LY_ROOT_FOLDER}/cmake/install/Findo3de.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/Findo3de.cmake @ONLY) @@ -430,7 +465,7 @@ endfunction()" get_target_property(target_runtime_output_directory ${target} RUNTIME_OUTPUT_DIRECTORY) if(target_runtime_output_directory) - file(RELATIVE_PATH target_runtime_output_subdirectory ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${target_runtime_output_directory}) + cmake_path(RELATIVE_PATH target_runtime_output_directory BASE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} OUTPUT_VARIABLE target_runtime_output_subdirectory) endif() # Qt diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index b3a6a1e44c..37c572b6a4 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -64,9 +64,9 @@ def register_shipped_engine_o3de_objects(force: bool = False) -> int: return ret_val -def register_all_in_folder(folder_path: str or pathlib.Path, +def register_all_in_folder(folder_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None, + engine_path: pathlib.Path = None, exclude: list = None) -> int: if not folder_path: logger.error(f'Folder path cannot be empty.') @@ -136,10 +136,11 @@ def register_all_in_folder(folder_path: str or pathlib.Path, return ret_val -def register_all_o3de_objects_of_type_in_folder(o3de_object_path: str or pathlib.Path, +def register_all_o3de_objects_of_type_in_folder(o3de_object_path: pathlib.Path, o3de_object_type: str, remove: bool, force: bool, + stop_iteration_callable: callable, **register_kwargs) -> int: if not o3de_object_path: logger.error(f'Engines path cannot be empty.') @@ -155,8 +156,11 @@ def register_all_o3de_objects_of_type_in_folder(o3de_object_path: str or pathlib ret_val = 0 for root, dirs, files in os.walk(o3de_object_path): + # Skip subdirectories where the stop iteration callback is true + if stop_iteration_callable and stop_iteration_callable(dirs, files): + dirs[:] = [] if f'{o3de_object_type}.json' in files: - o3de_object_type_set.add(root) + o3de_object_type_set.add(pathlib.Path(root)) # Stop iteration of any subdirectories # Nested o3de objects of the same type aren't supported(i.e an engine cannot be inside of a engine). dirs[:] = [] @@ -170,41 +174,49 @@ def register_all_o3de_objects_of_type_in_folder(o3de_object_path: str or pathlib return ret_val -def register_all_engines_in_folder(engines_path: str or pathlib.Path, +def stop_on_template_folders(dirs: list, files: list) -> bool: + return 'template.json' in files + + +def register_all_engines_in_folder(engines_path: pathlib.Path, remove: bool = False, force: bool = False) -> int: - return register_all_o3de_objects_of_type_in_folder(engines_path, 'engine', remove, force) + return register_all_o3de_objects_of_type_in_folder(engines_path, 'engine', remove, force, None) -def register_all_projects_in_folder(projects_path: str or pathlib.Path, +def register_all_projects_in_folder(projects_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: - return register_all_o3de_objects_of_type_in_folder(projects_path, 'project', remove, False, engine_path=engine_path) + engine_path: pathlib.Path = None) -> int: + return register_all_o3de_objects_of_type_in_folder(projects_path, 'project', remove, False, + stop_on_template_folders, engine_path=engine_path) -def register_all_gems_in_folder(gems_path: str or pathlib.Path, +def register_all_gems_in_folder(gems_path: pathlib.Path, remove: bool = False, engine_path: pathlib.Path = None, project_path: pathlib.Path = None) -> int: - return register_all_o3de_objects_of_type_in_folder(gems_path, 'gem', remove, False, engine_path=engine_path) + return register_all_o3de_objects_of_type_in_folder(gems_path, 'gem', remove, False, stop_on_template_folders, + engine_path=engine_path) -def register_all_templates_in_folder(templates_path: str or pathlib.Path, +def register_all_templates_in_folder(templates_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: - return register_all_o3de_objects_of_type_in_folder(templates_path, 'template', remove, False, engine_path=engine_path) + engine_path: pathlib.Path = None) -> int: + return register_all_o3de_objects_of_type_in_folder(templates_path, 'template', remove, False, None, + engine_path=engine_path) -def register_all_restricted_in_folder(restricted_path: str or pathlib.Path, +def register_all_restricted_in_folder(restricted_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: - return register_all_o3de_objects_of_type_in_folder(restricted_path, 'restricted', remove, False, engine_path=engine_path) + engine_path: pathlib.Path = None) -> int: + return register_all_o3de_objects_of_type_in_folder(restricted_path, 'restricted', remove, False, None, + engine_path=engine_path) -def register_all_repos_in_folder(repos_path: str or pathlib.Path, +def register_all_repos_in_folder(repos_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: - return register_all_o3de_objects_of_type_in_folder(repos_path, 'repo', remove, force, engine_path=engine_path) + engine_path: pathlib.Path = None) -> int: + return register_all_o3de_objects_of_type_in_folder(repos_path, 'repo', remove, force, None, engine_path=engine_path) def remove_engine_name_to_path(json_data: dict, @@ -252,7 +264,7 @@ def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: b def register_engine_path(json_data: dict, - engine_path: str or pathlib.Path, + engine_path: pathlib.Path, remove: bool = False, force: bool = False) -> int: if not engine_path: @@ -260,8 +272,11 @@ def register_engine_path(json_data: dict, return 1 engine_path = pathlib.Path(engine_path).resolve() - for engine_object in json_data.get('engines', {}): - engine_object_path = pathlib.Path(engine_object['path']).resolve() + for engine_object in json_data.get('engines', []): + if isinstance(engine_object, dict): + engine_object_path = pathlib.Path(engine_object['path']).resolve() + else: + engine_object_path = pathlib.Path(engine_object).resolve() if engine_object_path == engine_path: json_data['engines'].remove(engine_object) @@ -362,7 +377,7 @@ def register_o3de_object_path(json_data: dict, def register_external_subdirectory(json_data: dict, - external_subdir_path: str or pathlib.Path, + external_subdir_path: pathlib.Path, remove: bool = False, engine_path: pathlib.Path = None, project_path: pathlib.Path = None) -> int: @@ -375,7 +390,7 @@ def register_external_subdirectory(json_data: dict, def register_gem_path(json_data: dict, - gem_path: str or pathlib.Path, + gem_path: pathlib.Path, remove: bool = False, engine_path: pathlib.Path = None, project_path: pathlib.Path = None) -> int: @@ -384,9 +399,9 @@ def register_gem_path(json_data: dict, def register_project_path(json_data: dict, - project_path: str or pathlib.Path, + project_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: + engine_path: pathlib.Path = None) -> int: result = register_o3de_object_path(json_data, project_path, 'projects', 'project.json', validation.valid_o3de_project_json, remove, engine_path, None) @@ -408,9 +423,10 @@ def register_project_path(json_data: dict, update_project_json = True if update_project_json: + project_json_path = project_path / 'project.json' project_json_data['engine'] = this_engine_json['engine_name'] - utils.backup_file(project_json) - if not manifest.save_o3de_manifest(project_json_data, project_path): + utils.backup_file(project_json_path) + if not manifest.save_o3de_manifest(project_json_data, project_json_path): return 1 @@ -418,17 +434,17 @@ def register_project_path(json_data: dict, def register_template_path(json_data: dict, - template_path: str or pathlib.Path, + template_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: + engine_path: pathlib.Path = None) -> int: return register_o3de_object_path(json_data, template_path, 'templates', 'template.json', validation.valid_o3de_template_json, remove, engine_path, None) def register_restricted_path(json_data: dict, - restricted_path: str or pathlib.Path, + restricted_path: pathlib.Path, remove: bool = False, - engine_path: str or pathlib.Path = None) -> int: + engine_path: pathlib.Path = None) -> int: return register_o3de_object_path(json_data, restricted_path, 'restricted', 'restricted.json', validation.valid_o3de_restricted_json, remove, engine_path, None) @@ -468,7 +484,7 @@ def register_repo(json_data: dict, def register_default_o3de_object_folder(json_data: dict, - default_o3de_object_folder: str or pathlib.Path, + default_o3de_object_folder: pathlib.Path, o3de_object_key: str) -> int: # make sure the path exists default_o3de_object_folder = pathlib.Path(default_o3de_object_folder).resolve() @@ -482,7 +498,7 @@ def register_default_o3de_object_folder(json_data: dict, def register_default_engines_folder(json_data: dict, - default_engines_folder: str or pathlib.Path, + default_engines_folder: pathlib.Path, remove: bool = False) -> int: return register_default_o3de_object_folder(json_data, manifest.get_o3de_engines_folder() if remove else default_engines_folder, @@ -490,7 +506,7 @@ def register_default_engines_folder(json_data: dict, def register_default_projects_folder(json_data: dict, - default_projects_folder: str or pathlib.Path, + default_projects_folder: pathlib.Path, remove: bool = False) -> int: return register_default_o3de_object_folder(json_data, manifest.get_o3de_projects_folder() if remove else default_projects_folder, @@ -498,7 +514,7 @@ def register_default_projects_folder(json_data: dict, def register_default_gems_folder(json_data: dict, - default_gems_folder: str or pathlib.Path, + default_gems_folder: pathlib.Path, remove: bool = False) -> int: return register_default_o3de_object_folder(json_data, manifest.get_o3de_gems_folder() if remove else default_gems_folder, @@ -506,7 +522,7 @@ def register_default_gems_folder(json_data: dict, def register_default_templates_folder(json_data: dict, - default_templates_folder: str or pathlib.Path, + default_templates_folder: pathlib.Path, remove: bool = False) -> int: return register_default_o3de_object_folder(json_data, manifest.get_o3de_templates_folder() if remove else default_templates_folder, @@ -514,7 +530,7 @@ def register_default_templates_folder(json_data: dict, def register_default_restricted_folder(json_data: dict, - default_restricted_folder: str or pathlib.Path, + default_restricted_folder: pathlib.Path, remove: bool = False) -> int: return register_default_o3de_object_folder(json_data, manifest.get_o3de_restricted_folder() if remove else default_restricted_folder, @@ -527,18 +543,18 @@ def register_default_third_party_folder(json_data: dict, manifest.get_o3de_third_party_folder() if remove else default_third_party_folder, 'default_third_party_folder') -def register(engine_path: str or pathlib.Path = None, - project_path: str or pathlib.Path = None, - gem_path: str or pathlib.Path = None, - external_subdir_path: str or pathlib.Path = None, - template_path: str or pathlib.Path = None, - restricted_path: str or pathlib.Path = None, +def register(engine_path: pathlib.Path = None, + project_path: pathlib.Path = None, + gem_path: pathlib.Path = None, + external_subdir_path: pathlib.Path = None, + template_path: pathlib.Path = None, + restricted_path: pathlib.Path = None, repo_uri: str or pathlib.Path = None, - default_engines_folder: str or pathlib.Path = None, - default_projects_folder: str or pathlib.Path = None, - default_gems_folder: str or pathlib.Path = None, - default_templates_folder: str or pathlib.Path = None, - default_restricted_folder: str or pathlib.Path = None, + default_engines_folder: pathlib.Path = None, + default_projects_folder: pathlib.Path = None, + default_gems_folder: pathlib.Path = None, + default_templates_folder: pathlib.Path = None, + default_restricted_folder: pathlib.Path = None, default_third_party_folder: pathlib.Path = None, external_subdir_engine_path: pathlib.Path = None, external_subdir_project_path: pathlib.Path = None, @@ -576,32 +592,32 @@ def register(engine_path: str or pathlib.Path = None, result = 0 # do anything that could require a engine context first - if isinstance(project_path, str) or isinstance(project_path, pathlib.PurePath): + if isinstance(project_path, pathlib.PurePath): if not project_path: logger.error(f'Project path cannot be empty.') return 1 result = result or register_project_path(json_data, project_path, remove, engine_path) - if isinstance(gem_path, str) or isinstance(gem_path, pathlib.PurePath): + if isinstance(gem_path, pathlib.PurePath): if not gem_path: logger.error(f'Gem path cannot be empty.') return 1 result = result or register_gem_path(json_data, gem_path, remove, external_subdir_engine_path, external_subdir_project_path) - if isinstance(external_subdir_path, str) or isinstance(external_subdir_path, pathlib.PurePath): + if isinstance(external_subdir_path, pathlib.PurePath): if not external_subdir_path: logger.error(f'External Subdirectory path is None.') return 1 result = result or register_external_subdirectory(json_data, external_subdir_path, remove, external_subdir_engine_path, external_subdir_project_path) - if isinstance(template_path, str) or isinstance(template_path, pathlib.PurePath): + if isinstance(template_path, pathlib.PurePath): if not template_path: logger.error(f'Template path cannot be empty.') return 1 result = result or register_template_path(json_data, template_path, remove, engine_path) - if isinstance(restricted_path, str) or isinstance(restricted_path, pathlib.PurePath): + if isinstance(restricted_path, pathlib.PurePath): if not restricted_path: logger.error(f'Restricted path cannot be empty.') return 1 @@ -613,28 +629,28 @@ def register(engine_path: str or pathlib.Path = None, return 1 result = result or register_repo(json_data, repo_uri, remove) - if isinstance(default_engines_folder, str) or isinstance(default_engines_folder, pathlib.PurePath): + if isinstance(default_engines_folder, pathlib.PurePath): result = result or register_default_engines_folder(json_data, default_engines_folder, remove) - if isinstance(default_projects_folder, str) or isinstance(default_projects_folder, pathlib.PurePath): + if isinstance(default_projects_folder, pathlib.PurePath): result = result or register_default_projects_folder(json_data, default_projects_folder, remove) - if isinstance(default_gems_folder, str) or isinstance(default_gems_folder, pathlib.PurePath): + if isinstance(default_gems_folder, pathlib.PurePath): result = result or register_default_gems_folder(json_data, default_gems_folder, remove) - if isinstance(default_templates_folder, str) or isinstance(default_templates_folder, pathlib.PurePath): + if isinstance(default_templates_folder, pathlib.PurePath): result = result or register_default_templates_folder(json_data, default_templates_folder, remove) - if isinstance(default_restricted_folder, str) or isinstance(default_restricted_folder, pathlib.PurePath): + if isinstance(default_restricted_folder, pathlib.PurePath): result = result or register_default_restricted_folder(json_data, default_restricted_folder, remove) - if isinstance(default_third_party_folder, str) or isinstance(default_third_party_folder, pathlib.PurePath): + if isinstance(default_third_party_folder, pathlib.PurePath): result = result or register_default_third_party_folder(json_data, default_third_party_folder, remove) # engine is done LAST # Now that everything that could have an engine context is done, if the engine is supplied that means this is # registering the engine itself - if isinstance(engine_path, str) or isinstance(engine_path, pathlib.PurePath): + if isinstance(engine_path, pathlib.PurePath): if not engine_path: logger.error(f'Engine path cannot be empty.') return 1 @@ -789,41 +805,41 @@ def add_parser_args(parser): group.add_argument('--this-engine', action='store_true', required=False, default=False, help='Registers the engine this script is running from.') - group.add_argument('-ep', '--engine-path', type=str, required=False, + group.add_argument('-ep', '--engine-path', type=pathlib.Path, required=False, help='Engine path to register/remove.') - group.add_argument('-pp', '--project-path', type=str, required=False, + group.add_argument('-pp', '--project-path', type=pathlib.Path, required=False, help='Project path to register/remove.') - group.add_argument('-gp', '--gem-path', type=str, required=False, + group.add_argument('-gp', '--gem-path', type=pathlib.Path, required=False, help='Gem path to register/remove.') - group.add_argument('-es', '--external-subdirectory', type=str, required=False, + group.add_argument('-es', '--external-subdirectory', type=pathlib.Path, required=False, help='External subdirectory path to register/remove.') - group.add_argument('-tp', '--template-path', type=str, required=False, + group.add_argument('-tp', '--template-path', type=pathlib.Path, required=False, help='Template path to register/remove.') - group.add_argument('-rp', '--restricted-path', type=str, required=False, + group.add_argument('-rp', '--restricted-path', type=pathlib.Path, required=False, help='A restricted folder to register/remove.') group.add_argument('-ru', '--repo-uri', type=str, required=False, help='A repo uri to register/remove.') - group.add_argument('-aep', '--all-engines-path', type=str, required=False, + group.add_argument('-aep', '--all-engines-path', type=pathlib.Path, required=False, help='All engines under this folder to register/remove.') - group.add_argument('-app', '--all-projects-path', type=str, required=False, + group.add_argument('-app', '--all-projects-path', type=pathlib.Path, required=False, help='All projects under this folder to register/remove.') - group.add_argument('-agp', '--all-gems-path', type=str, required=False, + group.add_argument('-agp', '--all-gems-path', type=pathlib.Path, required=False, help='All gems under this folder to register/remove.') - group.add_argument('-atp', '--all-templates-path', type=str, required=False, + group.add_argument('-atp', '--all-templates-path', type=pathlib.Path, required=False, help='All templates under this folder to register/remove.') - group.add_argument('-arp', '--all-restricted-path', type=str, required=False, + group.add_argument('-arp', '--all-restricted-path', type=pathlib.Path, required=False, help='All templates under this folder to register/remove.') - group.add_argument('-aru', '--all-repo-uri', type=str, required=False, + group.add_argument('-aru', '--all-repo-uri', type=pathlib.Path, required=False, help='All repos under this folder to register/remove.') - group.add_argument('-def', '--default-engines-folder', type=str, required=False, + group.add_argument('-def', '--default-engines-folder', type=pathlib.Path, required=False, help='The default engines folder to register/remove.') - group.add_argument('-dpf', '--default-projects-folder', type=str, required=False, + group.add_argument('-dpf', '--default-projects-folder', type=pathlib.Path, required=False, help='The default projects folder to register/remove.') - group.add_argument('-dgf', '--default-gems-folder', type=str, required=False, + group.add_argument('-dgf', '--default-gems-folder', type=pathlib.Path, required=False, help='The default gems folder to register/remove.') - group.add_argument('-dtf', '--default-templates-folder', type=str, required=False, + group.add_argument('-dtf', '--default-templates-folder', type=pathlib.Path, required=False, help='The default templates folder to register/remove.') - group.add_argument('-drf', '--default-restricted-folder', type=str, required=False, + group.add_argument('-drf', '--default-restricted-folder', type=pathlib.Path, required=False, help='The default restricted folder to register/remove.') group.add_argument('-dtpf', '--default-third-party-folder', type=pathlib.Path, required=False, help='The default 3rd Party folder to register/remove.') @@ -831,7 +847,7 @@ def add_parser_args(parser): default=False, help='Refresh the repo cache.') - parser.add_argument('-ohf', '--override-home-folder', type=str, required=False, + parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False, help='By default the home folder is the user folder, override it to this folder.') parser.add_argument('-r', '--remove', action='store_true', required=False, default=False, From 808d31ea3288ce42d9150a92fba3c4baa98b24df Mon Sep 17 00:00:00 2001 From: pappeste Date: Thu, 17 Jun 2021 12:44:49 -0700 Subject: [PATCH 54/93] change the lock to avoid the "IS_NEWER_THAN" check from failing in race conditions --- cmake/Platform/Common/runtime_dependencies_common.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Common/runtime_dependencies_common.cmake.in b/cmake/Platform/Common/runtime_dependencies_common.cmake.in index 032a6726bd..c245d185d7 100644 --- a/cmake/Platform/Common/runtime_dependencies_common.cmake.in +++ b/cmake/Platform/Common/runtime_dependencies_common.cmake.in @@ -19,10 +19,10 @@ function(ly_copy source_file target_directory) file(MAKE_DIRECTORY "${target_directory}") endif() if("${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}") - file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" GUARD FUNCTION TIMEOUT 30) file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN) endif() endif() endfunction() +file(LOCK "${CMAKE_BINARY_DIR}/runtimedependencies.lock" TIMEOUT 300) @LY_COPY_COMMANDS@ From 40b822e8b758805cffe4d669da18bcdb778d99af Mon Sep 17 00:00:00 2001 From: gallowj Date: Thu, 17 Jun 2021 15:25:25 -0500 Subject: [PATCH 55/93] fixed validation errors, also removed cmake file --- .../LookDevelopmentStudioPixar/CMakeLists.txt | 15 ---------- Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat | 12 +++++++- .../Sponza/Tools/Maya/Launch_Maya_2020.bat | 28 +++++++++++++------ 3 files changed, 31 insertions(+), 24 deletions(-) delete mode 100644 Gems/AtomContent/LookDevelopmentStudioPixar/CMakeLists.txt diff --git a/Gems/AtomContent/LookDevelopmentStudioPixar/CMakeLists.txt b/Gems/AtomContent/LookDevelopmentStudioPixar/CMakeLists.txt deleted file mode 100644 index 1eef04a86d..0000000000 --- a/Gems/AtomContent/LookDevelopmentStudioPixar/CMakeLists.txt +++ /dev/null @@ -1,15 +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. -# - -# This will export its "SourcePaths" to the generated "cmake_dependencies..assetbuilder.setreg" -if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_create_alias(NAME AtomContent_LookDevelopmentStudioPixar.Builders NAMESPACE Gem) -endif() diff --git a/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat b/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat index f5d436b215..570bc7c86d 100644 --- a/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat +++ b/Gems/AtomContent/Sponza/Tools/Launch_Cmd.bat @@ -1,4 +1,14 @@ -:: Need to set up +@echo off +REM +REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +REM its licensors. +REM +REM For complete copyright and license terms please see the LICENSE at the root of this +REM distribution (the "License"). All use of this software is governed by the License, +REM or, if provided, by the license below or the license accompanying this file. Do not +REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM @echo off :: Set up and run LY Python CMD prompt diff --git a/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat b/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat index 8fb283d6d8..3f53d90681 100644 --- a/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat +++ b/Gems/AtomContent/Sponza/Tools/Maya/Launch_Maya_2020.bat @@ -1,3 +1,15 @@ +@echo off +REM +REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +REM its licensors. +REM +REM For complete copyright and license terms please see the LICENSE at the root of this +REM distribution (the "License"). All use of this software is governed by the License, +REM or, if provided, by the license below or the license accompanying this file. Do not +REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM + :: Launches maya wityh a bunch of local hooks for Lumberyard :: ToDo: move all of this to a .json data driven boostrapping system @@ -40,15 +52,15 @@ Set MAYA_VP2_DEVICE_OVERRIDE = VirtualDeviceDx11 :: Default to the right version of Maya if we can detect it... and launch IF EXIST "%MAYA_LOCATION%\bin\Maya.exe" ( - start "" "%MAYA_LOCATION%\bin\Maya.exe" %* + start "" "%MAYA_LOCATION%\bin\Maya.exe" %* ) ELSE ( - Where maya.exe 2> NUL - IF ERRORLEVEL 1 ( - echo Maya.exe could not be found - pause - ) ELSE ( - start "" Maya.exe %* - ) + Where maya.exe 2> NUL + IF ERRORLEVEL 1 ( + echo Maya.exe could not be found + pause + ) ELSE ( + start "" Maya.exe %* + ) ) :: Return to starting directory From 35568d97e5fc03502bcf602e2bc342bd2581f41b Mon Sep 17 00:00:00 2001 From: Eric Phister <52085794+amzn-phist@users.noreply.github.com> Date: Thu, 17 Jun 2021 15:31:49 -0500 Subject: [PATCH 56/93] Fixes an issue configuring with external project (#1408) With engine-centric builds where LY_PROJECTS has paths that sit outside the engine, there was an erroneous fatal message that would occur. --- cmake/Platform/Common/Install_common.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 6998c260b7..59a38132bc 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -70,7 +70,9 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar string(REGEX REPLACE "/$" "" include_directory "${include_directory}") cmake_path(IS_PREFIX LY_ROOT_FOLDER ${absolute_target_source_dir} NORMALIZE include_directory_child_of_o3de_root) if(NOT include_directory_child_of_o3de_root) - message(FATAL_ERROR "Include directory of \"${include_directory}\" is outside of the O3DE root folder of \"${LY_ROOT_FOLDER}\". For the INSTALL step, the O3DE root folder must be a prefix of all include directories") + # Include directory is outside of the O3DE root folder ${LY_ROOT_FOLDER}. + # For the INSTALL step, the O3DE root folder must be a prefix of all include directories. + continue() endif() cmake_path(RELATIVE_PATH include_directory BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE rel_include_dir) From 8471d3cca44d846b9a1dc75d209d0f7278b24a3f Mon Sep 17 00:00:00 2001 From: gallowj Date: Thu, 17 Jun 2021 15:57:37 -0500 Subject: [PATCH 57/93] removed a gem reference, the gem was moved to an~other repo --- Gems/AtomContent/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gems/AtomContent/CMakeLists.txt b/Gems/AtomContent/CMakeLists.txt index 79842f462c..0e7057dd5a 100644 --- a/Gems/AtomContent/CMakeLists.txt +++ b/Gems/AtomContent/CMakeLists.txt @@ -8,7 +8,5 @@ # 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_subdirectory(LookDevelopmentStudioPixar) add_subdirectory(ReferenceMaterials) add_subdirectory(Sponza) From 0a119314220a6c71fac149a91213dcf96208727a Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Thu, 17 Jun 2021 16:10:37 -0500 Subject: [PATCH 58/93] Removing reference to non-existent parallax.invert property. (#1409) --- .../Common/Assets/Materials/Types/StandardPBR_ParallaxState.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ParallaxState.lua b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ParallaxState.lua index 771726aea7..c42f16c179 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ParallaxState.lua +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ParallaxState.lua @@ -49,7 +49,6 @@ function ProcessEditor(context) context:SetMaterialPropertyVisibility("parallax.factor", visibility) context:SetMaterialPropertyVisibility("parallax.offset", visibility) context:SetMaterialPropertyVisibility("parallax.showClipping", visibility) - context:SetMaterialPropertyVisibility("parallax.invert", visibility) context:SetMaterialPropertyVisibility("parallax.algorithm", visibility) context:SetMaterialPropertyVisibility("parallax.quality", visibility) context:SetMaterialPropertyVisibility("parallax.pdo", visibility) From c7399537e2529a9ee7afe1889d31b1ed323d618c Mon Sep 17 00:00:00 2001 From: stramer <169061+sptramer@users.noreply.github.com> Date: Thu, 17 Jun 2021 14:15:56 -0700 Subject: [PATCH 59/93] Address review feedback. Signed-off-by: stramer <169061+sptramer@users.noreply.github.com> --- .../AzNetworking/AzNetworking/ConnectionLayer/IConnection.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 53505c556f..6b8c599bd8 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -45,8 +45,7 @@ namespace AzNetworking //! @class IConnection //! @brief interface class for network connections. //! - //! IConnection provides a pure-virtual interface for all network connection types. The two child classes are TcpConnection - //! and UdpConnection, though the pure-virtual interface operates largely the same for both. IConnections provide access to + //! 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. From f6fc425a1ac3b14feae2243c8484a7cd5157ce82 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Thu, 17 Jun 2021 16:24:33 -0500 Subject: [PATCH 60/93] Prefab support for dynamic vegetation (#1374) * First version of prefab support for dynamic vegetation * Addressed PR feedback - Made MockSpawnableEntitiesInterface a proper GMock in AzFramework - Added Get/SetSpawnableAssetId - Added lots of comments to better explain things that were asked about in the PR * Exposed AzFrameworkTestShared on all platforms, not just host platforms --- Code/Framework/Tests/CMakeLists.txt | 72 ++-- .../Mocks/MockSpawnableEntitiesInterface.h | 84 ++++ .../Tests/framework_shared_tests_files.cmake | 1 + Gems/Vegetation/Code/CMakeLists.txt | 1 + .../Vegetation/PrefabInstanceSpawner.h | 101 +++++ .../Code/Source/PrefabInstanceSpawner.cpp | 401 ++++++++++++++++++ .../Code/Source/VegetationSystemComponent.cpp | 2 + .../Code/Tests/PrefabInstanceSpawnerTests.cpp | 347 +++++++++++++++ Gems/Vegetation/Code/vegetation_files.cmake | 2 + .../Code/vegetation_tests_files.cmake | 1 + 10 files changed, 977 insertions(+), 35 deletions(-) create mode 100644 Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h create mode 100644 Gems/Vegetation/Code/Include/Vegetation/PrefabInstanceSpawner.h create mode 100644 Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp create mode 100644 Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp diff --git a/Code/Framework/Tests/CMakeLists.txt b/Code/Framework/Tests/CMakeLists.txt index 491f6d8e14..7cb243d69b 100644 --- a/Code/Framework/Tests/CMakeLists.txt +++ b/Code/Framework/Tests/CMakeLists.txt @@ -9,7 +9,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) @@ -27,40 +27,42 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AzFramework ) - ly_add_target( - NAME ProcessLaunchTest EXECUTABLE - NAMESPACE AZ - FILES_CMAKE - process_launch_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzCore - AZ::AzFramework - ) + if(PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_target( + NAME ProcessLaunchTest EXECUTABLE + NAMESPACE AZ + FILES_CMAKE + process_launch_test_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + . + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzFramework + ) - ly_add_target( - NAME Framework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE AZ - FILES_CMAKE - frameworktests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - AZ::AzToolsFramework - AZ::AzTestShared - AZ::AzFrameworkTestShared - RUNTIME_DEPENDENCIES - AZ::ProcessLaunchTest - ) - ly_add_googletest( - NAME AZ::Framework.Tests - ) + ly_add_target( + NAME Framework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE AZ + FILES_CMAKE + frameworktests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + . + ${pal_dir} + BUILD_DEPENDENCIES + PRIVATE + AZ::AzTest + AZ::AzToolsFramework + AZ::AzTestShared + AZ::AzFrameworkTestShared + RUNTIME_DEPENDENCIES + AZ::ProcessLaunchTest + ) + ly_add_googletest( + NAME AZ::Framework.Tests + ) + endif() endif() diff --git a/Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h b/Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h new file mode 100644 index 0000000000..51063a49be --- /dev/null +++ b/Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h @@ -0,0 +1,84 @@ +/* + * 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 +#include +#include + +namespace AzFramework +{ + class MockSpawnableEntitiesInterface; + using NiceSpawnableEntitiesInterfaceMock = ::testing::NiceMock; + + class MockSpawnableEntitiesInterface : public SpawnableEntitiesDefinition + { + public: + AZ_RTTI(MockSpawnableEntitiesInterface, "{2A20FF73-C445-4F32-ABB9-5CF0A5778404}", SpawnableEntitiesDefinition); + + MockSpawnableEntitiesInterface() + { + AZ::Interface::Register(this); + } + + virtual ~MockSpawnableEntitiesInterface() + { + AZ::Interface::Unregister(this); + } + + MOCK_METHOD2(SpawnAllEntities, void(EntitySpawnTicket& ticket, SpawnAllEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD3( + SpawnEntities, + void(EntitySpawnTicket& ticket, AZStd::vector entityIndices, SpawnEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD2(DespawnAllEntities, void(EntitySpawnTicket& ticket, DespawnAllEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD3( + ReloadSpawnable, + void(EntitySpawnTicket& ticket, AZ::Data::Asset spawnable, ReloadSpawnableOptionalArgs optionalArgs)); + + MOCK_METHOD3( + ListEntities, void(EntitySpawnTicket& ticket, ListEntitiesCallback listCallback, ListEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD3( + ListIndicesAndEntities, + void(EntitySpawnTicket& ticket, ListIndicesEntitiesCallback listCallback, ListEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD3( + ClaimEntities, + void(EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback, ClaimEntitiesOptionalArgs optionalArgs)); + + MOCK_METHOD3(Barrier, void(EntitySpawnTicket& ticket, BarrierCallback completionCallback, BarrierOptionalArgs optionalArgs)); + + MOCK_METHOD1(CreateTicket, AZStd::pair(AZ::Data::Asset&& spawnable)); + MOCK_METHOD1(DestroyTicket, void(void* ticket)); + + /** Installs some default result values for the above functions. + * Note that you can always override these in scope of your test by adding additional ON_CALL / EXPECT_CALL + * statements in the body of your test or after calling this function, and yours will take precedence. + **/ + static void InstallDefaultReturns(NiceSpawnableEntitiesInterfaceMock& target) + { + using namespace ::testing; + + // The ID and pointer are completely arbitrary, they just need to both be non-zero to look like a valid ticket. + constexpr EntitySpawnTicket::Id ticketId(1); + static int ticketPayload = 0; + ON_CALL(target, CreateTicket(_)).WillByDefault( + Return(AZStd::make_pair(ticketId, &ticketPayload))); + } + + }; + +} // namespace AzFramework diff --git a/Code/Framework/Tests/framework_shared_tests_files.cmake b/Code/Framework/Tests/framework_shared_tests_files.cmake index 57345ee630..8cf1a2e3fd 100644 --- a/Code/Framework/Tests/framework_shared_tests_files.cmake +++ b/Code/Framework/Tests/framework_shared_tests_files.cmake @@ -10,6 +10,7 @@ # set(FILES + Mocks/MockSpawnableEntitiesInterface.h Utils/Utils.h Utils/Utils.cpp ) diff --git a/Gems/Vegetation/Code/CMakeLists.txt b/Gems/Vegetation/Code/CMakeLists.txt index 7283f53c97..10d54da78e 100644 --- a/Gems/Vegetation/Code/CMakeLists.txt +++ b/Gems/Vegetation/Code/CMakeLists.txt @@ -105,6 +105,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) BUILD_DEPENDENCIES PRIVATE AZ::AzTest + AZ::AzFrameworkTestShared Gem::Vegetation.Static ) ly_add_googletest( diff --git a/Gems/Vegetation/Code/Include/Vegetation/PrefabInstanceSpawner.h b/Gems/Vegetation/Code/Include/Vegetation/PrefabInstanceSpawner.h new file mode 100644 index 0000000000..3f65352abc --- /dev/null +++ b/Gems/Vegetation/Code/Include/Vegetation/PrefabInstanceSpawner.h @@ -0,0 +1,101 @@ +/* +* 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 +#include +#include + +namespace Vegetation +{ + /** + * Instance spawner of prefab instances. + */ + class PrefabInstanceSpawner + : public InstanceSpawner + , private AZ::Data::AssetBus::MultiHandler + { + public: + AZ_RTTI(PrefabInstanceSpawner, "{74BEEDB5-81CF-409F-B375-0D93D81EF2E3}", InstanceSpawner); + AZ_CLASS_ALLOCATOR(PrefabInstanceSpawner, AZ::SystemAllocator, 0); + static void Reflect(AZ::ReflectContext* context); + + PrefabInstanceSpawner(); + virtual ~PrefabInstanceSpawner(); + + //! Start loading any assets that the spawner will need. + void LoadAssets() override; + + //! Unload any assets that the spawner loaded. + void UnloadAssets() override; + + //! Perform any extra initialization needed at the point of registering with the vegetation system. + void OnRegisterUniqueDescriptor() override; + + //! Perform any extra cleanup needed at the point of unregistering with the vegetation system. + void OnReleaseUniqueDescriptor() override; + + //! Does this exist but have empty asset references? + bool HasEmptyAssetReferences() const override; + + //! Has this finished loading any assets that are needed? + bool IsLoaded() const override; + + //! Are the assets loaded, initialized, and spawnable? + bool IsSpawnable() const override; + + //! Display name of the instances that will be spawned. + AZStd::string GetName() const override; + + //! Create a single instance. + InstancePtr CreateInstance(const InstanceData& instanceData) override; + + //! Destroy a single instance. + void DestroyInstance(InstanceId id, InstancePtr instance) override; + + AZStd::string GetSpawnableAssetPath() const; + void SetSpawnableAssetPath(const AZStd::string& assetPath); + + AZ::Data::AssetId GetSpawnableAssetId() const; + void SetSpawnableAssetId(const AZ::Data::AssetId& assetId); + + private: + bool DataIsEquivalent(const InstanceSpawner& rhs) const override; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Data::AssetBus::Handler + void OnAssetReady(AZ::Data::Asset asset) override; + void OnAssetReloaded(AZ::Data::Asset asset) override; + + AZ::u32 SpawnableAssetChanged(); + void ResetSpawnableAsset(); + + void UpdateCachedValues(); + + //! Verify that the spawnable asset only contains data compatible with the dynamic vegetation system. + bool ValidateAssetContents(const AZ::Data::Asset asset) const; + + //! Despawn an instance of a spawnable asset + void DespawnAssetInstance(AzFramework::EntitySpawnTicket* ticket); + + //! Cached values so that asset isn't accessed on other threads + bool m_assetLoadedAndSpawnable = false; + + //! Collection of spawned instance tickets, needed for destroying the instances. + AZStd::unordered_set m_instanceTickets; + + //! asset data + AZ::Data::Asset m_spawnableAsset; + }; + +} // namespace Vegetation diff --git a/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp new file mode 100644 index 0000000000..f22dbb61aa --- /dev/null +++ b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp @@ -0,0 +1,401 @@ +/* +* 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 "Vegetation_precompiled.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +namespace Vegetation +{ + + PrefabInstanceSpawner::PrefabInstanceSpawner() + { + UnloadAssets(); + } + + PrefabInstanceSpawner::~PrefabInstanceSpawner() + { + UnloadAssets(); + AZ_Assert(m_instanceTickets.empty(), "Destroying spawner while %u spawn tickets still exist!", m_instanceTickets.size()); + } + + void PrefabInstanceSpawner::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(0)->Field( + "SpawnableAsset", &PrefabInstanceSpawner::m_spawnableAsset) + ; + + AZ::EditContext* edit = serialize->GetEditContext(); + if (edit) + { + edit->Class( + "Prefab", "Prefab Instance") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + + ->DataElement(AZ::Edit::UIHandlers::Default, &PrefabInstanceSpawner::m_spawnableAsset, "Prefab Asset", "Prefab asset") + ->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, false) + ->Attribute(AZ::Edit::Attributes::HideProductFilesInAssetPicker, true) + ->Attribute(AZ::Edit::Attributes::AssetPickerTitle, "a Prefab") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PrefabInstanceSpawner::SpawnableAssetChanged) + ; + } + } + if (auto behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Category, "Vegetation") + ->Attribute(AZ::Script::Attributes::Module, "vegetation") + ->Constructor() + ->Method("GetPrefabAssetPath", &PrefabInstanceSpawner::GetSpawnableAssetPath) + ->Method("SetPrefabAssetPath", &PrefabInstanceSpawner::SetSpawnableAssetPath) + ->Method("GetPrefabAssetId", &PrefabInstanceSpawner::GetSpawnableAssetId) + ->Method("SetPrefabAssetId", &PrefabInstanceSpawner::SetSpawnableAssetId); + } + } + + bool PrefabInstanceSpawner::DataIsEquivalent(const InstanceSpawner& baseRhs) const + { + if (const auto* rhs = azrtti_cast(&baseRhs)) + { + return m_spawnableAsset == rhs->m_spawnableAsset; + } + + // Not the same subtypes, so definitely not a data match. + return false; + } + + void PrefabInstanceSpawner::LoadAssets() + { + UnloadAssets(); + + // Note that the spawnable tickets manage and track asset loading as well. We *could* just rely on that and mark + // the spawner as immediately ready for use (i.e. always return "true" in IsLoaded() and IsSpawnable() ), but this + // would cause us to wait until the first instance is spawned to load the asset, creating a delay right at the point + // that the vegetation is becoming visible. It would also cause the asset to get auto-unloaded every time all the + // instances using it are despawned. By loading it *prior* to marking things as ready, we can ensure that we have the + // asset at the point that the first instance is spawned, and that it won't get auto-unloaded every time the instances + // are despawned. + m_spawnableAsset.QueueLoad(); + AZ::Data::AssetBus::MultiHandler::BusConnect(m_spawnableAsset.GetId()); + } + + void PrefabInstanceSpawner::UnloadAssets() + { + // It's possible under some circumstances that we might unload assets before destroying all spawned instances + // due to the way the vegetation system queues up delete requests and descriptor unregistrations. If so, + // despawn the actual spawned instances here, but leave the ticket entries in the instance ticket map and don't + // delete the ticket pointers. The tickets will get cleaned up when the vegetation system gets around to requesting + // the instance destroy. + if (!m_instanceTickets.empty()) + { + for (auto& ticket : m_instanceTickets) + { + DespawnAssetInstance(ticket); + } + } + ResetSpawnableAsset(); + NotifyOnAssetsUnloaded(); + } + + void PrefabInstanceSpawner::ResetSpawnableAsset() + { + AZ::Data::AssetBus::MultiHandler::BusDisconnect(); + + m_spawnableAsset.Release(); + UpdateCachedValues(); + m_spawnableAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::QueueLoad); + } + + void PrefabInstanceSpawner::UpdateCachedValues() + { + // Once our assets are loaded and at the point that they're getting registered, + // cache off the spawnable state for use from multiple threads. + + m_assetLoadedAndSpawnable = m_spawnableAsset.IsReady(); + } + + void PrefabInstanceSpawner::OnRegisterUniqueDescriptor() + { + UpdateCachedValues(); + } + + void PrefabInstanceSpawner::OnReleaseUniqueDescriptor() + { + } + + bool PrefabInstanceSpawner::HasEmptyAssetReferences() const + { + // If we don't have a valid Spawnable Asset, then that means we're expecting to spawn empty instances. + return !m_spawnableAsset.GetId().IsValid(); + } + + bool PrefabInstanceSpawner::IsLoaded() const + { + return m_assetLoadedAndSpawnable; + } + + bool PrefabInstanceSpawner::IsSpawnable() const + { + return m_assetLoadedAndSpawnable; + } + + AZStd::string PrefabInstanceSpawner::GetName() const + { + AZStd::string assetName; + if (!HasEmptyAssetReferences()) + { + // Get the asset file name + assetName = m_spawnableAsset.GetHint(); + if (!m_spawnableAsset.GetHint().empty()) + { + AzFramework::StringFunc::Path::GetFileName(m_spawnableAsset.GetHint().c_str(), assetName); + } + } + else + { + assetName = ""; + } + + return assetName; + } + + bool PrefabInstanceSpawner::ValidateAssetContents(const AZ::Data::Asset asset) const + { + bool validAsset = true; + + // Basic safety check: Make sure the asset is a spawnable. + auto spawnableAsset = azrtti_cast(asset.GetData()); + if (!spawnableAsset) + { + return false; + } + + // Loop through all the components on all the entities in the spawnable, looking for any type of Vegetation Area. + // If we try to dynamically spawn vegetation areas, as they spawn in they will non-deterministically start spawning + // (or blocking) other vegetation while we're in the midst of spawning the higher-level vegetation area. Threading + // and timing affects which one wins out. It may also cause other bugs. + + const AzFramework::Spawnable::EntityList& entities = spawnableAsset->GetEntities(); + for (auto& entity : entities) + { + auto components = entity->GetComponents(); + for (auto component : components) + { + if (azrtti_istypeof(component)) + { + validAsset = false; + AZ_Error("Vegetation", false, + "Vegetation system cannot spawn prefabs containing a component of type '%s'", + component->RTTI_GetTypeName()); + } + } + } + + return validAsset; + } + + void PrefabInstanceSpawner::OnAssetReady(AZ::Data::Asset asset) + { + if (m_spawnableAsset.GetId() == asset.GetId()) + { + // Make sure that the spawnable asset we're loading doesn't contain any data incompatible with + // the dynamic vegetation system. + // This check needs to be performed at asset loading time as opposed to authoring / configuration + // time because the spawnable asset can be changed independently from the authoring of this component. + bool validAsset = ValidateAssetContents(asset); + + ResetSpawnableAsset(); + if (validAsset) + { + m_spawnableAsset = asset; + } + UpdateCachedValues(); + NotifyOnAssetsLoaded(); + } + } + + void PrefabInstanceSpawner::OnAssetReloaded(AZ::Data::Asset asset) + { + OnAssetReady(asset); + } + + AZStd::string PrefabInstanceSpawner::GetSpawnableAssetPath() const + { + AZStd::string assetPathString; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetPathString, &AZ::Data::AssetCatalogRequests::GetAssetPathById, m_spawnableAsset.GetId()); + return assetPathString; + } + + void PrefabInstanceSpawner::SetSpawnableAssetPath(const AZStd::string& assetPath) + { + if (!assetPath.empty()) + { + AZ::Data::AssetId assetId; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, assetPath.c_str(), + AZ::Data::s_invalidAssetType, false); + if (assetId.IsValid()) + { + SetSpawnableAssetId(assetId); + } + else + { + AZ_Error("Vegetation", false, "Asset '%s' is invalid.", assetPath.c_str()); + } + } + else + { + SetSpawnableAssetId(AZ::Data::AssetId()); + } + } + + AZ::Data::AssetId PrefabInstanceSpawner::GetSpawnableAssetId() const + { + return m_spawnableAsset.GetId(); + } + + void PrefabInstanceSpawner::SetSpawnableAssetId(const AZ::Data::AssetId& assetId) + { + if (assetId.IsValid()) + { + AZ::Data::AssetInfo assetInfo; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId); + if (assetInfo.m_assetType == m_spawnableAsset.GetType()) + { + m_spawnableAsset.Create(assetId, false); + LoadAssets(); + } + else + { + AZ_Error( + "Vegetation", false, "Asset '%s' is of type %s, but expected a Spawnable type.", + assetId.ToString().c_str(), assetInfo.m_assetType.ToString().c_str()); + } + } + else + { + // An invalid asset ID is treated as a valid way to spawn "empty" instances, so don't print an error, just clear out + // the asset to that it has an invalid asset reference. (See also HasEmptyAssetReferences() above) + m_spawnableAsset = AZ::Data::Asset(); + LoadAssets(); + } + } + + AZ::u32 PrefabInstanceSpawner::SpawnableAssetChanged() + { + // Whenever we change the spawnable asset, force a refresh of the Entity Inspector + // since we want the Descriptor List to refresh the name of the entry. + NotifyOnAssetsUnloaded(); + return AZ::Edit::PropertyRefreshLevels::AttributesAndValues; + } + + InstancePtr PrefabInstanceSpawner::CreateInstance(const InstanceData& instanceData) + { + InstancePtr opaqueInstanceData = nullptr; + + // Create a Transform that represents our instance. + AZ::Transform world = AZ::Transform::CreateFromQuaternionAndTranslation( + instanceData.m_alignment * instanceData.m_rotation, instanceData.m_position); + world.MultiplyByUniformScale(instanceData.m_scale); + + // Create a callback for SpawnAllEntities that will set the transform of the root entity to the correct position / rotation / scale + // for our spawned instance. + auto preSpawnCB = [this, world]( + [[maybe_unused]] AzFramework::EntitySpawnTicket::Id ticketId, AzFramework::SpawnableEntityContainerView view) + { + AZ::Entity* rootEntity = *view.begin(); + + AzFramework::TransformComponent* entityTransform = rootEntity->FindComponent(); + + if (entityTransform) + { + entityTransform->SetWorldTM(world); + } + }; + + // Create the EntitySpawnTicket here. This pointer is going to get handed off to the vegetation system as opaque instance data, + // where it will be tracked and held onto for the lifetime of the vegetation instance. The vegetation system will pass it back + // in to DestroyInstance at the end of the lifetime, so that's the one place where we will delete the ticket pointers. + AzFramework::EntitySpawnTicket* ticket = new AzFramework::EntitySpawnTicket(m_spawnableAsset); + if (ticket->IsValid()) + { + // Track the ticket that we've created. + m_instanceTickets.emplace(ticket); + + AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; + optionalArgs.m_preInsertionCallback = AZStd::move(preSpawnCB); + AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(*ticket, AZStd::move(optionalArgs)); + + opaqueInstanceData = ticket; + } + else + { + // Something went wrong! + AZ_Assert(ticket->IsValid(), "Unable to instantiate spawnable asset"); + delete ticket; + } + + return opaqueInstanceData; + } + + void PrefabInstanceSpawner::DespawnAssetInstance(AzFramework::EntitySpawnTicket* ticket) + { + if (ticket->IsValid()) + { + AzFramework::SpawnableEntitiesInterface::Get()->DespawnAllEntities(*ticket); + } + } + + void PrefabInstanceSpawner::DestroyInstance([[maybe_unused]] InstanceId id, InstancePtr instance) + { + if (instance) + { + auto ticket = reinterpret_cast(instance); + + // If the spawnable asset instantiated successfully, we should have a record of it. + auto foundInstance = m_instanceTickets.find(ticket); + AZ_Assert(foundInstance != m_instanceTickets.end(), "Couldn't find CreateInstance entry for the EntitySpawnTicket."); + if (foundInstance != m_instanceTickets.end()) + { + // The call to DespawnAssetInstance above is technically redundant right now, because when we delete the ticket pointer + // below it will automatically despawn everything anyways. However, it's nice to have a single explicit call to despawn, + // in case we ever need a place to add logging, or have a callback when despawning is complete, etc. + DespawnAssetInstance(ticket); + m_instanceTickets.erase(foundInstance); + } + + // The vegetation system has stopped tracking this instance, so it's now safe to delete the ticket pointer. + delete ticket; + } + } +} // namespace Vegetation diff --git a/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp b/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp index 7cad51e025..a3a1ff4616 100644 --- a/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -73,6 +74,7 @@ namespace Vegetation InstanceSpawner::Reflect(context); EmptyInstanceSpawner::Reflect(context); DynamicSliceInstanceSpawner::Reflect(context); + PrefabInstanceSpawner::Reflect(context); Descriptor::Reflect(context); AreaConfig::Reflect(context); AreaComponentBase::Reflect(context); diff --git a/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp b/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp new file mode 100644 index 0000000000..368615ea42 --- /dev/null +++ b/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp @@ -0,0 +1,347 @@ +/* +* 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 "Vegetation_precompiled.h" + +#include "VegetationTest.h" +#include "VegetationMocks.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace UnitTest +{ + // Mock VegetationSystemComponent is needed to reflect only the PrefabInstanceSpawner. + class MockPrefabInstanceVegetationSystemComponent + : public AZ::Component + { + public: + AZ_COMPONENT(MockPrefabInstanceVegetationSystemComponent, "{5EC9AA35-2653-4326-853F-F2056F0DE36C}", AZ::Component); + + void Activate() override {} + void Deactivate() override {} + + static void Reflect(AZ::ReflectContext* reflect) + { + Vegetation::InstanceSpawner::Reflect(reflect); + Vegetation::PrefabInstanceSpawner::Reflect(reflect); + Vegetation::EmptyInstanceSpawner::Reflect(reflect); + } + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC_CE("VegetationSystemService")); + } + }; + + // To test prefab spawning, we need to mock up enough of the asset management system and the spawnable + // asset handling to pretend like we're loading/unloading spawnables successfully. + class PrefabInstanceSpawnerTests + : public VegetationComponentTests + , public UnitTest::SetRestoreFileIOBaseRAII + , public Vegetation::DescriptorNotificationBus::Handler + , public AZ::Data::AssetCatalogRequestBus::Handler + , public AZ::Data::AssetHandler + , public AZ::Data::AssetCatalog + { + public: + PrefabInstanceSpawnerTests() + : UnitTest::SetRestoreFileIOBaseRAII(m_fileIOMock) + { + AZ::IO::MockFileIOBase::InstallDefaultReturns(m_fileIOMock); + AzFramework::MockSpawnableEntitiesInterface::InstallDefaultReturns(m_spawnableEntitiesInterfaceMock); + } + + void RegisterComponentDescriptors() override + { + m_app.RegisterComponentDescriptor(MockPrefabInstanceVegetationSystemComponent::CreateDescriptor()); + } + + void SetUp() override + { + VegetationComponentTests::SetUp(); + + // Create a real Asset Mananger, and point to ourselves as the handler for Spawnable. + AZ::AllocatorInstance::Create(); + AZ::AllocatorInstance::Create(); + + + // Initialize the job manager with 1 thread for the AssetManager to use. + AZ::JobManagerDesc jobDesc; + AZ::JobManagerThreadDesc threadDesc; + jobDesc.m_workerThreads.push_back(threadDesc); + m_jobManager = aznew AZ::JobManager(jobDesc); + m_jobContext = aznew AZ::JobContext(*m_jobManager); + AZ::JobContext::SetGlobalContext(m_jobContext); + + AZ::Data::AssetManager::Descriptor descriptor; + AZ::Data::AssetManager::Create(descriptor); + AZ::Data::AssetManager::Instance().RegisterHandler(this, AZ::AzTypeInfo::Uuid()); + AZ::Data::AssetManager::Instance().RegisterCatalog(this, AZ::AzTypeInfo::Uuid()); + + // Intercept messages for finding assets by name. + AZ::Data::AssetCatalogRequestBus::Handler::BusConnect(); + } + + void TearDown() override + { + // Give the AssetManager a chance to fire off any lingering events and perform cleanup for any + // spawnable assets we loaded. + AZ::Data::AssetManager::Instance().DispatchEvents(); + + AZ::Data::AssetManager::Instance().UnregisterCatalog(this); + AZ::Data::AssetManager::Instance().UnregisterHandler(this); + + AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect(); + + AZ::Data::AssetManager::Destroy(); + + AZ::JobContext::SetGlobalContext(nullptr); + delete m_jobContext; + delete m_jobManager; + + AZ::AllocatorInstance::Destroy(); + AZ::AllocatorInstance::Destroy(); + + VegetationComponentTests::TearDown(); + } + + // Helper methods: + + // Set up a mock asset with the given name and id and direct the instance spawner to use it. + void CreateAndSetMockAsset(Vegetation::PrefabInstanceSpawner& instanceSpawner, AZ::Data::AssetId assetId, AZStd::string assetPath) + { + // Save these off for use from our mock AssetCatalogRequestBus + m_assetId = assetId; + m_assetPath = assetPath; + + Vegetation::DescriptorNotificationBus::Handler::BusConnect(&instanceSpawner); + + // Tell the spawner to use this asset. Note that this also triggers a LoadAssets() call internally. + instanceSpawner.SetSpawnableAssetPath(m_assetPath); + + // Our instance spawner should now have a valid asset reference. + // It may or may not be loaded already by the time we get here, + // depending on how quickly the Asset Processor job thread picks it up. + EXPECT_FALSE(instanceSpawner.HasEmptyAssetReferences()); + + // Since the asset load is going through the real AssetManager, there's a delay while a separate + // job thread executes and actually loads our mock spawnable asset. + // If our asset hasn't loaded successfully after 5 seconds, it's unlikely to succeed. + // This choice of delay should be *reasonably* safe because it's all CPU-based processing, + // no actual I/O occurs as a part of the test. + constexpr int sleepMs = 10; + constexpr int totalWaitTimeMs = 5000; + int numRetries = totalWaitTimeMs / sleepMs; + while ((m_numOnLoadedCalls < 1) && (numRetries >= 0)) + { + AZ::Data::AssetManager::Instance().DispatchEvents(); + AZ::SystemTickBus::Broadcast(&AZ::SystemTickBus::Events::OnSystemTick); + AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(sleepMs)); + numRetries--; + } + + ASSERT_TRUE(m_numOnLoadedCalls == 1); + EXPECT_TRUE(instanceSpawner.IsLoaded()); + EXPECT_TRUE(instanceSpawner.IsSpawnable()); + + Vegetation::DescriptorNotificationBus::Handler::BusDisconnect(); + } + + + // AssetHandler + // Minimalist mocks to look like a Spawnable has been created/loaded/destroyed successfully + AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override + { + AzFramework::Spawnable* spawnableAsset = new AzFramework::Spawnable(id); + MockAssetData* temp = reinterpret_cast(spawnableAsset); + temp->SetStatus(AZ::Data::AssetData::AssetStatus::NotLoaded); + + return spawnableAsset; + } + + void DestroyAsset(AZ::Data::AssetPtr ptr) override { delete ptr; } + void GetHandledAssetTypes(AZStd::vector& assetTypes) override + { + assetTypes.push_back(AZ::AzTypeInfo::Uuid()); + } + AZ::Data::AssetHandler::LoadResult LoadAssetData( + const AZ::Data::Asset& asset, + AZStd::shared_ptr stream, + [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB) + { + MockAssetData* temp = reinterpret_cast(asset.GetData()); + temp->SetStatus(AZ::Data::AssetData::AssetStatus::Ready); + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } + + // DescriptorNotificationBus + // Keep track of whether or not the Spawner successfully loaded the asset and notified listeners + void OnDescriptorAssetsLoaded() override { m_numOnLoadedCalls++; } + + // AssetCatalogRequestBus + // Minimalist mocks to provide our desired asset path or asset id + AZStd::string GetAssetPathById(const AZ::Data::AssetId& /*id*/) override { return m_assetPath; } + AZ::Data::AssetId GetAssetIdByPath(const char* /*path*/, const AZ::Data::AssetType& /*typeToRegister*/, bool /*autoRegisterIfNotFound*/) override { return m_assetId; } + AZ::Data::AssetInfo GetAssetInfoById(const AZ::Data::AssetId& /*id*/) override + { + AZ::Data::AssetInfo assetInfo; + assetInfo.m_assetId = m_assetId; + assetInfo.m_assetType = AZ::AzTypeInfo::Uuid(); + assetInfo.m_relativePath = m_assetPath; + return assetInfo; + } + + // AssetCatalog + // Minimalist mock to pretend like we've loaded a Spawnable asset + AZ::Data::AssetStreamInfo GetStreamInfoForLoad( + [[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override + { + EXPECT_TRUE(type == AZ::AzTypeInfo::Uuid()); + AZ::Data::AssetStreamInfo info; + info.m_dataOffset = 0; + info.m_streamName = m_assetPath; + info.m_dataLen = 0; + info.m_streamFlags = AZ::IO::OpenMode::ModeRead; + + return info; + } + + AZStd::string m_assetPath; + AZ::Data::AssetId m_assetId; + int m_numOnLoadedCalls = 0; + + AZ::JobManager* m_jobManager{ nullptr }; + AZ::JobContext* m_jobContext{ nullptr }; + ::testing::NiceMock m_fileIOMock; + ::testing::NiceMock m_spawnableEntitiesInterfaceMock; + }; + + TEST_F(PrefabInstanceSpawnerTests, BasicInitializationTest) + { + // Basic test to make sure we can construct / destroy without errors. + + Vegetation::PrefabInstanceSpawner instanceSpawner; + } + + TEST_F(PrefabInstanceSpawnerTests, DefaultSpawnersAreEqual) + { + // Two different instances of the default PrefabInstanceSpawner should be considered data-equivalent. + + Vegetation::PrefabInstanceSpawner instanceSpawner1; + Vegetation::PrefabInstanceSpawner instanceSpawner2; + + EXPECT_TRUE(instanceSpawner1 == instanceSpawner2); + } + + TEST_F(PrefabInstanceSpawnerTests, DifferentSpawnersAreNotEqual) + { + // Two spawners with different data should *not* be data-equivalent. + + Vegetation::PrefabInstanceSpawner instanceSpawner1; + Vegetation::PrefabInstanceSpawner instanceSpawner2; + + // Give the second instance spawner a non-default asset reference. + CreateAndSetMockAsset(instanceSpawner2, AZ::Uuid::CreateRandom(), "test"); + + // The test is written this way because only the == operator is overloaded. + EXPECT_TRUE(!(instanceSpawner1 == instanceSpawner2)); + } + + TEST_F(PrefabInstanceSpawnerTests, LoadAndUnloadAssets) + { + // The spawner should successfully load/unload assets without errors. + + Vegetation::PrefabInstanceSpawner instanceSpawner; + + // Our instance spawner should be empty before we set the assets. + EXPECT_TRUE(instanceSpawner.HasEmptyAssetReferences()); + + // This will test the asset load. + CreateAndSetMockAsset(instanceSpawner, AZ::Uuid::CreateRandom(), "test"); + + // Test the asset unload works too. + Vegetation::DescriptorNotificationBus::Handler::BusConnect(&instanceSpawner); + instanceSpawner.UnloadAssets(); + EXPECT_FALSE(instanceSpawner.IsLoaded()); + EXPECT_FALSE(instanceSpawner.IsSpawnable()); + Vegetation::DescriptorNotificationBus::Handler::BusDisconnect(); + } + + TEST_F(PrefabInstanceSpawnerTests, CreateAndDestroyInstance) + { + // The spawner should successfully create and destroy an instance without errors. + + Vegetation::PrefabInstanceSpawner instanceSpawner; + + CreateAndSetMockAsset(instanceSpawner, AZ::Uuid::CreateRandom(), "test"); + + instanceSpawner.OnRegisterUniqueDescriptor(); + + Vegetation::InstanceData instanceData; + Vegetation::InstancePtr instance = instanceSpawner.CreateInstance(instanceData); + EXPECT_TRUE(instance); + instanceSpawner.DestroyInstance(0, instance); + + instanceSpawner.OnReleaseUniqueDescriptor(); + } + + TEST_F(PrefabInstanceSpawnerTests, SpawnerRegisteredWithDescriptor) + { + // Validate that the Descriptor successfully gets PrefabInstanceSpawner registered with it, + // as long as InstanceSpawner and PrefabInstanceSpawner have been reflected. + + MockPrefabInstanceVegetationSystemComponent* component = nullptr; + auto entity = CreateEntity(&component); + + Vegetation::Descriptor descriptor; + descriptor.RefreshSpawnerTypeList(); + auto spawnerTypes = descriptor.GetSpawnerTypeList(); + EXPECT_TRUE(spawnerTypes.size() > 0); + const auto& prefabSpawnerEntry = AZStd::find( + spawnerTypes.begin(), spawnerTypes.end(), + AZStd::pair(Vegetation::PrefabInstanceSpawner::RTTI_Type(), "PrefabInstanceSpawner")); + EXPECT_NE(prefabSpawnerEntry, spawnerTypes.end()); + } + + TEST_F(PrefabInstanceSpawnerTests, DescriptorCreatesCorrectSpawner) + { + // Validate that the Descriptor successfully creates a new PrefabInstanceSpawner if we change + // the spawner type on the Descriptor. + + MockPrefabInstanceVegetationSystemComponent* component = nullptr; + auto entity = CreateEntity(&component); + + // We expect the Descriptor to start off with something other than Prefab spawner, but then should correctly get an + // PrefabInstanceSpawner after we change spawnerType. + Vegetation::Descriptor descriptor; + EXPECT_NE(azrtti_typeid(*(descriptor.GetInstanceSpawner())),Vegetation::PrefabInstanceSpawner::RTTI_Type()); + descriptor.m_spawnerType = Vegetation::PrefabInstanceSpawner::RTTI_Type(); + descriptor.RefreshSpawnerTypeList(); + descriptor.SpawnerTypeChanged(); + EXPECT_EQ(azrtti_typeid(*(descriptor.GetInstanceSpawner())), Vegetation::PrefabInstanceSpawner::RTTI_Type()); + } +} diff --git a/Gems/Vegetation/Code/vegetation_files.cmake b/Gems/Vegetation/Code/vegetation_files.cmake index abfd568862..d06a2d6927 100644 --- a/Gems/Vegetation/Code/vegetation_files.cmake +++ b/Gems/Vegetation/Code/vegetation_files.cmake @@ -17,6 +17,7 @@ set(FILES Include/Vegetation/InstanceSpawner.h Include/Vegetation/DynamicSliceInstanceSpawner.h Include/Vegetation/EmptyInstanceSpawner.h + Include/Vegetation/PrefabInstanceSpawner.h Include/Vegetation/AreaComponentBase.h Include/Vegetation/Ebuses/AreaSystemRequestBus.h Include/Vegetation/Ebuses/AreaNotificationBus.h @@ -104,6 +105,7 @@ set(FILES Source/Descriptor.cpp Source/DynamicSliceInstanceSpawner.cpp Source/EmptyInstanceSpawner.cpp + Source/PrefabInstanceSpawner.cpp Source/VegetationSystemComponent.cpp Source/VegetationSystemComponent.h Source/InstanceData.cpp diff --git a/Gems/Vegetation/Code/vegetation_tests_files.cmake b/Gems/Vegetation/Code/vegetation_tests_files.cmake index 2ce54d3033..08656de9d2 100644 --- a/Gems/Vegetation/Code/vegetation_tests_files.cmake +++ b/Gems/Vegetation/Code/vegetation_tests_files.cmake @@ -17,6 +17,7 @@ set(FILES Tests/VegetationComponentFilterTests.cpp Tests/DynamicSliceInstanceSpawnerTests.cpp Tests/EmptyInstanceSpawnerTests.cpp + Tests/PrefabInstanceSpawnerTests.cpp Tests/VegetationAreaSystemComponentTest.cpp Tests/VegetationTest.cpp Tests/VegetationTest.h From 28d0d0cce928de3bab365f110e2f21afd44a180e Mon Sep 17 00:00:00 2001 From: Jacob Hilliard <64656371+jcbhl@users.noreply.github.com> Date: Thu, 17 Jun 2021 14:36:42 -0700 Subject: [PATCH 61/93] Fix frame visualizer not closing (#1383) --- .../Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.h | 3 +-- .../Code/Include/Atom/Utils/ImGuiFrameVisualizer.inl | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.h b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.h index 7ce68c0cc7..0186f68282 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.h +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.h @@ -38,14 +38,13 @@ namespace AZ ~ImGuiFrameVisualizer() = default; AZStd::vector& GetFrameAttachments(); void Init(RHI::Device* device); - void Draw(bool draw); + void Draw(bool& draw); void DrawTreeView(); void Reset(); protected: AZStd::vector m_framesAttachments; RHI::Device* m_device = nullptr; bool m_deviceInit = false; - bool m_draw = false; ////////////////////////////////////////////////////////////////////////// // FrameEventBus::Handler void OnFrameCompileEnd(RHI::FrameGraph& frameGraph); diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.inl index b5cf2e8f6b..5230a6869b 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiFrameVisualizer.inl @@ -466,10 +466,10 @@ namespace ImGui } //!Draw the UI and all the nodes. - void Paint() + void Paint(bool& draw) { ImGui::SetNextWindowSize(ImVec2((float)m_windowWidth, (float)m_windowHeight), ImGuiCond_FirstUseEver); - if (!ImGui::Begin(m_windowName.c_str(), &m_open)) + if (!ImGui::Begin(m_windowName.c_str(), &draw)) { ImGui::End(); return; @@ -572,7 +572,6 @@ namespace ImGui AZStd::string m_windowName; unsigned int m_windowWidth = 1; unsigned int m_windowHeight = 1; - bool m_open = false; bool m_frameCapture = false; bool m_showGrid = true; }; @@ -581,7 +580,7 @@ static ImGui::ImGuiFrameVisualizerWindow* visualizerWindow = nullptr; namespace AZ::Render { //! Draw the frame graph. - inline void ImGuiFrameVisualizer::Draw([[maybe_unused]] bool draw) + inline void ImGuiFrameVisualizer::Draw(bool& draw) { if (!visualizerWindow) { @@ -595,7 +594,7 @@ namespace AZ::Render visualizerWindow->CaptureFrame(this); visualizerWindow->DisableCaptureFrame(); } - visualizerWindow->Paint(); + visualizerWindow->Paint(draw); } } From 32fb0e462795a6b4fd1ee646e2bac56c15de43c3 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Thu, 17 Jun 2021 16:51:26 -0500 Subject: [PATCH 62/93] [ATOM-15810] Removing maximum values from light intensity (#1414) Setting hard max values to float max. Also allowing EV100 values hard minimum to be lowest float. Soft min and max will remain the same for a consistent ux, but we will no longer keep people from manually entering really high or low values that are technically fine. --- .../CoreLights/AreaLightComponentConfig.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp index c9211e87a0..71bb17d6c0 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp @@ -11,6 +11,7 @@ */ #include +#include namespace AZ { @@ -135,23 +136,15 @@ namespace AZ case PhotometricUnit::Nit: return 0.0f; case PhotometricUnit::Ev100Luminance: - return -10.0f; + return AZStd::numeric_limits::lowest(); } return 0.0f; } float AreaLightComponentConfig::GetIntensityMax() const { - switch (m_intensityMode) - { - case PhotometricUnit::Candela: - case PhotometricUnit::Lumen: - case PhotometricUnit::Nit: - return 1'000'000.0f; - case PhotometricUnit::Ev100Luminance: - return 20.0f; - } - return 0.0f; + // While there is no hard-max, a max must be included when there is a hard min. + return AZStd::numeric_limits::max(); } float AreaLightComponentConfig::GetIntensitySoftMin() const From 273f4f89a1a55faa7d99ad72f67e412dc7e5f3cc Mon Sep 17 00:00:00 2001 From: Vincent Liu <5900509+onecent1101@users.noreply.github.com> Date: Thu, 17 Jun 2021 14:53:16 -0700 Subject: [PATCH 63/93] [LYN-3988] Remove session token cvar (#1407) --- .../Code/Source/Credential/AWSCVarCredentialHandler.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.cpp b/Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.cpp index f4315c41c2..30a810eb23 100644 --- a/Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.cpp +++ b/Gems/AWSCore/Code/Source/Credential/AWSCVarCredentialHandler.cpp @@ -18,7 +18,6 @@ namespace AWSCore { AZ_CVAR(AZ::CVarFixedString, cl_awsAccessKey, "", nullptr, AZ::ConsoleFunctorFlags::Null, "Override AWS access key"); AZ_CVAR(AZ::CVarFixedString, cl_awsSecretKey, "", nullptr, AZ::ConsoleFunctorFlags::Null, "Override AWS secret key"); - AZ_CVAR(AZ::CVarFixedString, cl_awsSessionToken, "", nullptr, AZ::ConsoleFunctorFlags::Null, "Override AWS session token"); static constexpr char AWSCVARCREDENTIALHANDLER_ALLOC_TAG[] = "AWSCVarCredentialHandler"; @@ -43,13 +42,12 @@ namespace AWSCore { auto accessKey = static_cast(cl_awsAccessKey); auto secretKey = static_cast(cl_awsSecretKey); - auto sessionToken = static_cast(cl_awsSessionToken); - // Session token is not always required + if (!accessKey.empty() && !secretKey.empty()) { AZStd::lock_guard credentialsLock{m_credentialMutex}; m_cvarCredentialsProvider = Aws::MakeShared( - AWSCVARCREDENTIALHANDLER_ALLOC_TAG, accessKey.c_str(), secretKey.c_str(), sessionToken.c_str()); + AWSCVARCREDENTIALHANDLER_ALLOC_TAG, accessKey.c_str(), secretKey.c_str()); return m_cvarCredentialsProvider; } return nullptr; From 609752b79e6f9a9253fcb23776c73e147c4c7ad5 Mon Sep 17 00:00:00 2001 From: Peng Date: Thu, 17 Jun 2021 14:55:13 -0700 Subject: [PATCH 64/93] ATOM-15808 [RHI][Vulkan] Take out the early memory check exit to let the developers decide what to do if device memory is less than the requirement. JIRA: https://jira.agscollab.com/browse/ATOM-15808 --- Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp index e3367b078a..694eac2da4 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp @@ -64,10 +64,7 @@ namespace AZ 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; From 8fb0007201215b7bfefd67e76c4119dc405f7675 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Thu, 17 Jun 2021 15:12:14 -0700 Subject: [PATCH 65/93] Remove Prefab System toggle from the Editor Preferences dialog. (#1415) --- .../Editor/EditorPreferencesPageGeneral.cpp | 22 ++----------------- .../Editor/EditorPreferencesPageGeneral.h | 4 ---- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/Code/Sandbox/Editor/EditorPreferencesPageGeneral.cpp b/Code/Sandbox/Editor/EditorPreferencesPageGeneral.cpp index a7420b79a4..d62ca741ce 100644 --- a/Code/Sandbox/Editor/EditorPreferencesPageGeneral.cpp +++ b/Code/Sandbox/Editor/EditorPreferencesPageGeneral.cpp @@ -28,8 +28,6 @@ #define EDITORPREFS_EVENTVALTOGGLE "operation" #define UNDOSLICESAVE_VALON "UndoSliceSaveValueOn" #define UNDOSLICESAVE_VALOFF "UndoSliceSaveValueOff" -#define EDITORUI10_ENABLED "EditorUI10On" -#define EDITORUI10_DISABLED "EditorUI10Off" void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize) { @@ -45,8 +43,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize) ->Field("StylusMode", &GeneralSettings::m_stylusMode) ->Field("ShowNews", &GeneralSettings::m_bShowNews) ->Field("EnableSceneInspector", &GeneralSettings::m_enableSceneInspector) - ->Field("RestoreViewportCamera", &GeneralSettings::m_restoreViewportCamera) - ->Field("PrefabSystem", &GeneralSettings::m_enablePrefabSystem); + ->Field("RestoreViewportCamera", &GeneralSettings::m_restoreViewportCamera); serialize.Class() ->Version(2) @@ -94,8 +91,7 @@ void CEditorPreferencesPage_General::Reflect(AZ::SerializeContext& serialize) ->EnumAttribute(AzQtComponents::ToolBar::ToolBarIconSize::IconLarge, "Large") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_stylusMode, "Stylus Mode", "Stylus Mode for tablets and other pointing devices") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_restoreViewportCamera, EditorPreferencesGeneralRestoreViewportCameraSettingName, "Keep the original editor viewport transform when exiting game mode.") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_enableSceneInspector, "Enable Scene Inspector (EXPERIMENTAL)", "Enable the option to inspect the internal data loaded from scene files like .fbx. This is an experimental feature. Restart the Scene Settings if the option is not visible under the Help menu.") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_enablePrefabSystem, "Enable Prefab System (EXPERIMENTAL)", "Enable this option to preview Open 3D Engine's new prefab system. Enabling this setting removes slice support for level entities; you will need to restart the Editor for the change to take effect."); + ->DataElement(AZ::Edit::UIHandlers::CheckBox, &GeneralSettings::m_enableSceneInspector, "Enable Scene Inspector (EXPERIMENTAL)", "Enable the option to inspect the internal data loaded from scene files like .fbx. This is an experimental feature. Restart the Scene Settings if the option is not visible under the Help menu."); editContext->Class("Messaging", "") ->DataElement(AZ::Edit::UIHandlers::CheckBox, &Messaging::m_showDashboard, "Show Welcome to Open 3D Engine at startup", "Show Welcome to Open 3D Engine at startup") @@ -159,8 +155,6 @@ void CEditorPreferencesPage_General::OnApply() gSettings.restoreViewportCamera = m_generalSettings.m_restoreViewportCamera; gSettings.enableSceneInspector = m_generalSettings.m_enableSceneInspector; - gSettings.prefabSystem = m_generalSettings.m_enablePrefabSystem; - if (static_cast(m_generalSettings.m_toolbarIconSize) != gSettings.gui.nToolbarIconSize) { gSettings.gui.nToolbarIconSize = static_cast(m_generalSettings.m_toolbarIconSize); @@ -178,16 +172,6 @@ void CEditorPreferencesPage_General::OnApply() //slices gSettings.sliceSettings.dynamicByDefault = m_sliceSettings.m_slicesDynamicByDefault; - - // if the user enabled/disabled the prefab context - notify them that a restart - // is required in order to see the effect of the change - if (gSettings.prefabSystem != m_generalSettings.m_enablePrefabSystemInitialValue) - { - QMessageBox::warning( - AzToolsFramework::GetActiveWindow(), QObject::tr("Restart required"), - QObject::tr("Restart the Editor in order for the Prefab/Slice system changes to take effect.") - ); - } } void CEditorPreferencesPage_General::InitializeSettings() @@ -202,8 +186,6 @@ void CEditorPreferencesPage_General::InitializeSettings() m_generalSettings.m_stylusMode = gSettings.stylusMode; m_generalSettings.m_restoreViewportCamera = gSettings.restoreViewportCamera; m_generalSettings.m_enableSceneInspector = gSettings.enableSceneInspector; - m_generalSettings.m_enablePrefabSystem = gSettings.prefabSystem; - m_generalSettings.m_enablePrefabSystemInitialValue = gSettings.prefabSystem; m_generalSettings.m_toolbarIconSize = static_cast(gSettings.gui.nToolbarIconSize); diff --git a/Code/Sandbox/Editor/EditorPreferencesPageGeneral.h b/Code/Sandbox/Editor/EditorPreferencesPageGeneral.h index 31776e9c10..6e7eeebd43 100644 --- a/Code/Sandbox/Editor/EditorPreferencesPageGeneral.h +++ b/Code/Sandbox/Editor/EditorPreferencesPageGeneral.h @@ -58,10 +58,6 @@ private: bool m_restoreViewportCamera; bool m_bShowNews; bool m_enableSceneInspector; - bool m_enablePrefabSystem; - - // Only used to tell if the user has changed this value since it requires a restart - bool m_enablePrefabSystemInitialValue; }; struct Messaging From 703c1856ec77b018e917216eadc8202d37697683 Mon Sep 17 00:00:00 2001 From: scottr Date: Thu, 17 Jun 2021 15:16:20 -0700 Subject: [PATCH 66/93] [cpack/stabilization/2106] updated start menu shortcuts generated by the installer --- cmake/Platform/Windows/Packaging/Shortcuts.wxs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) 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" /> From 2fa6883455d005c529682655420673abf9214443 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 17 Jun 2021 16:16:10 -0700 Subject: [PATCH 67/93] SPEC-6663 add file(READ files to tracking (#1416) * adding property to track files read by file(READ * code review comments * adding newline --- AutomatedTesting/EngineFinder.cmake | 3 +++ Code/LauncherUnified/launcher_generator.cmake | 2 +- Templates/DefaultProject/Template/EngineFinder.cmake | 3 +++ Templates/MinimalProject/Template/EngineFinder.cmake | 3 +++ cmake/EngineJson.cmake | 2 +- cmake/FileUtil.cmake | 11 ++++++++++- cmake/Findo3de.cmake | 2 ++ cmake/O3DEJson.cmake | 4 ++-- cmake/PAL.cmake | 8 ++++---- cmake/Platform/Common/Install_common.cmake | 5 ++--- cmake/TestImpactFramework/LYTestImpactFramework.cmake | 2 +- 11 files changed, 32 insertions(+), 13 deletions(-) diff --git a/AutomatedTesting/EngineFinder.cmake b/AutomatedTesting/EngineFinder.cmake index fbbe3d8cfe..eef3aa3cae 100644 --- a/AutomatedTesting/EngineFinder.cmake +++ b/AutomatedTesting/EngineFinder.cmake @@ -15,6 +15,8 @@ include_guard() # Read the engine name from the project_json file file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json) +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/project.json) + string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine) if(json_error) message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}") @@ -30,6 +32,7 @@ endif() # Find a key that matches LY_ENGINE_NAME_TO_USE and use that as the engine path. if(EXISTS ${manifest_path}) file(READ ${manifest_path} manifest_json) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${manifest_path}) string(JSON engines_path_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines_path) if(json_error) diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake index 5fa0f7a0e3..2180aff7d8 100644 --- a/Code/LauncherUnified/launcher_generator.cmake +++ b/Code/LauncherUnified/launcher_generator.cmake @@ -26,7 +26,7 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC message(FATAL_ERROR "The specified project path of ${project_real_path} does not contain a project.json file") else() # Add the project_name to global LY_PROJECTS_TARGET_NAME property - file(READ "${project_real_path}/project.json" project_json) + ly_file_read("${project_real_path}/project.json" project_json) string(JSON project_name ERROR_VARIABLE json_error GET ${project_json} "project_name") if(json_error) message(FATAL_ERROR "There is an error reading the \"project_name\" key from the '${project_real_path}/project.json' file: ${json_error}") diff --git a/Templates/DefaultProject/Template/EngineFinder.cmake b/Templates/DefaultProject/Template/EngineFinder.cmake index cac0f6215c..f058f6e037 100644 --- a/Templates/DefaultProject/Template/EngineFinder.cmake +++ b/Templates/DefaultProject/Template/EngineFinder.cmake @@ -17,6 +17,8 @@ include_guard() # Read the engine name from the project_json file file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json) +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/project.json) + string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine) if(json_error) message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}") @@ -32,6 +34,7 @@ endif() # Find a key that matches LY_ENGINE_NAME_TO_USE and use that as the engine path. if(EXISTS ${manifest_path}) file(READ ${manifest_path} manifest_json) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${manifest_path}) string(JSON engines_path_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines_path) if(json_error) diff --git a/Templates/MinimalProject/Template/EngineFinder.cmake b/Templates/MinimalProject/Template/EngineFinder.cmake index cac0f6215c..f058f6e037 100644 --- a/Templates/MinimalProject/Template/EngineFinder.cmake +++ b/Templates/MinimalProject/Template/EngineFinder.cmake @@ -17,6 +17,8 @@ include_guard() # Read the engine name from the project_json file file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json) +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/project.json) + string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine) if(json_error) message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}") @@ -32,6 +34,7 @@ endif() # Find a key that matches LY_ENGINE_NAME_TO_USE and use that as the engine path. if(EXISTS ${manifest_path}) file(READ ${manifest_path} manifest_json) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${manifest_path}) string(JSON engines_path_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines_path) if(json_error) diff --git a/cmake/EngineJson.cmake b/cmake/EngineJson.cmake index c3ab29d09e..7922cd1a1b 100644 --- a/cmake/EngineJson.cmake +++ b/cmake/EngineJson.cmake @@ -22,7 +22,7 @@ set(LY_EXTERNAL_SUBDIRS "" CACHE STRING "List of subdirectories to recurse into # Restricted folders(contains an additional restricted.json), etc... # \arg:output_external_subdirs name of output variable to store external subdirectories into function(read_engine_external_subdirs output_external_subdirs) - file(READ ${LY_ROOT_FOLDER}/engine.json engine_json_data) + ly_file_read(${LY_ROOT_FOLDER}/engine.json engine_json_data) string(JSON external_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${engine_json_data} "external_subdirectories") if(engine_json_error) diff --git a/cmake/FileUtil.cmake b/cmake/FileUtil.cmake index 96923537ed..e530fe133c 100644 --- a/cmake/FileUtil.cmake +++ b/cmake/FileUtil.cmake @@ -118,4 +118,13 @@ override_pak_root=${LY_OVERRIDE_PAK_FOLDER_ROOT} endfunction() - +#! ly_file_read: wrap to file(READ) that adds the file to configuration tracking +# +# file(READ) does not add file tracking. So changes to the file being read will not cause a cmake regeneration +# +function(ly_file_read path content) + unset(file_content) + file(READ ${path} file_content) + set(${content} ${file_content} PARENT_SCOPE) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${path}) +endfunction() diff --git a/cmake/Findo3de.cmake b/cmake/Findo3de.cmake index 0b4d0b75e7..f9eedf686c 100644 --- a/cmake/Findo3de.cmake +++ b/cmake/Findo3de.cmake @@ -22,6 +22,8 @@ o3de_current_file_path(current_path) # Make sure we are matching LY_ENGINE_NAME_TO_USE with the current engine file(READ ${current_path}/../engine.json engine_json) +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${current_path}/../engine.json) + string(JSON this_engine_name ERROR_VARIABLE json_error GET ${engine_json} engine_name) if(json_error) message(FATAL_ERROR "Unable to read key 'engine_name' from '${current_path}/../engine.json', error: ${json_error}") diff --git a/cmake/O3DEJson.cmake b/cmake/O3DEJson.cmake index ab5f95bc8c..500bd9a78c 100644 --- a/cmake/O3DEJson.cmake +++ b/cmake/O3DEJson.cmake @@ -30,7 +30,7 @@ endfunction() #! read_json_array # Reads the a json array field into a cmake list variable function(o3de_read_json_array read_output_array input_json_path array_key) - file(READ ${input_json_path} manifest_json_data) + ly_file_read(${input_json_path} manifest_json_data) string(JSON array_count ERROR_VARIABLE manifest_json_error LENGTH ${manifest_json_data} ${array_key}) if(manifest_json_error) @@ -53,7 +53,7 @@ function(o3de_read_json_array read_output_array input_json_path array_key) endfunction() function(o3de_read_json_key output_value input_json_path key) - file(READ ${input_json_path} manifest_json_data) + ly_file_read(${input_json_path} manifest_json_data) string(JSON value ERROR_VARIABLE manifest_json_error GET ${manifest_json_data} ${key}) if(manifest_json_error) message(FATAL_ERROR "Error reading field at key ${key} in file \"${input_json_path}\" : ${manifest_json_error}") diff --git a/cmake/PAL.cmake b/cmake/PAL.cmake index dca54e4731..4fe729f85a 100644 --- a/cmake/PAL.cmake +++ b/cmake/PAL.cmake @@ -30,7 +30,7 @@ endforeach() # \arg:restricted returns the restricted association element from an o3de json, otherwise engine 'o3de' is assumed # \arg:o3de_json_file name of the o3de json file function(o3de_restricted_id o3de_json_file restricted) - file(READ ${o3de_json_file} json_data) + ly_file_read(${o3de_json_file} json_data) string(JSON restricted_entry ERROR_VARIABLE json_error GET ${json_data} "restricted_name") if(json_error) message(WARNING "Unable to read restricted from '${o3de_json_file}', error: ${json_error}") @@ -46,7 +46,7 @@ endfunction() # \arg:restricted_name name of the restricted function(o3de_find_restricted_folder restricted_name restricted_path) # Read the restricted path from engine.json if one EXISTS - file(READ ${LY_ROOT_FOLDER}/engine.json engine_json_data) + ly_file_read(${LY_ROOT_FOLDER}/engine.json engine_json_data) string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${engine_json_data} "restricted") if(restricted_subdirs_count GREATER 0) string(JSON restricted_subdir ERROR_VARIABLE engine_json_error GET ${engine_json_data} "restricted" "0") @@ -66,7 +66,7 @@ function(o3de_find_restricted_folder restricted_name restricted_path) # Examine the o3de manifest file for the list of restricted directories set(o3de_manifest_path ${home_directory}/.o3de/o3de_manifest.json) if(EXISTS ${o3de_manifest_path}) - file(READ ${o3de_manifest_path} o3de_manifest_json_data) + ly_file_read(${o3de_manifest_path} o3de_manifest_json_data) string(JSON restricted_subdirs_count ERROR_VARIABLE engine_json_error LENGTH ${o3de_manifest_json_data} "restricted") if(restricted_subdirs_count GREATER 0) math(EXPR restricted_subdirs_range "${restricted_subdirs_count}-1") @@ -79,7 +79,7 @@ function(o3de_find_restricted_folder restricted_name restricted_path) # Iterate over the restricted directories from the manifest file foreach(restricted_entry ${restricted_subdirs}) set(restricted_json_file ${restricted_entry}/restricted.json) - file(READ ${restricted_json_file} restricted_json) + ly_file_read(${restricted_json_file} restricted_json) string(JSON this_restricted_name ERROR_VARIABLE json_error GET ${restricted_json} "restricted_name") if(json_error) message(WARNING "Unable to read restricted_name from '${restricted_json_file}', error: ${json_error}") diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 0948cf68dd..edce52288f 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -240,7 +240,7 @@ set_property(TARGET ${TARGET_NAME} ) # Since a CMakeLists.txt could contain multiple targets, we generate it in a folder per target - file(READ ${LY_ROOT_FOLDER}/cmake/install/InstalledTarget.in target_cmakelists_template) + ly_file_read(${LY_ROOT_FOLDER}/cmake/install/InstalledTarget.in target_cmakelists_template) string(CONFIGURE ${target_cmakelists_template} output_cmakelists_data @ONLY) set(${OUTPUT_CONFIGURED_TARGET} ${output_cmakelists_data} PARENT_SCOPE) endfunction() @@ -317,8 +317,7 @@ function(ly_setup_subdirectory absolute_target_source_dir) string(APPEND ENABLE_GEMS_PLACEHOLDER ${enable_gems_command}) endforeach() - - file(READ ${LY_ROOT_FOLDER}/cmake/install/Copyright.in cmake_copyright_comment) + ly_file_read(${LY_ROOT_FOLDER}/cmake/install/Copyright.in cmake_copyright_comment) # Initialize the target install source directory to path underneath the current binary directory set(target_install_source_dir ${CMAKE_CURRENT_BINARY_DIR}/install/${relative_target_source_dir}) diff --git a/cmake/TestImpactFramework/LYTestImpactFramework.cmake b/cmake/TestImpactFramework/LYTestImpactFramework.cmake index d46b16bca5..8a088bddab 100644 --- a/cmake/TestImpactFramework/LYTestImpactFramework.cmake +++ b/cmake/TestImpactFramework/LYTestImpactFramework.cmake @@ -334,7 +334,7 @@ function(ly_test_impact_write_config_file CONFIG_TEMPLATE_FILE PERSISTENT_DATA_D ) # Substitute config file template with above vars - file(READ "${CONFIG_TEMPLATE_FILE}" config_file) + ly_file_read("${CONFIG_TEMPLATE_FILE}" config_file) string(CONFIGURE ${config_file} config_file) # Write out entire config contents to a file in the build directory of the test impact framework console target From 2c7fc4e391f67b1900ca653db554393e494bd182 Mon Sep 17 00:00:00 2001 From: Peng Date: Thu, 17 Jun 2021 17:00:36 -0700 Subject: [PATCH 68/93] take out warning and un-used variable --- Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp index 694eac2da4..9fd38aab93 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/PhysicalDevice.cpp @@ -62,8 +62,6 @@ 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); physicalDeviceList.emplace_back(physicalDevice); } From 6d0ef1cf57110a9b36a2b274dbe1be5059e30e45 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Thu, 17 Jun 2021 17:54:10 -0700 Subject: [PATCH 69/93] Avoid reading from a destroyed variable (#1347) This code iterates over the items in a vector, and if one case is met, it mutates that same vector. This invalidates the object, as the place where that object used to be has been moved. --- .../AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp | 8 ++++++-- .../AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h | 8 ++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 2d2acd9d44..172a3697e4 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -816,7 +816,11 @@ namespace AZ::SettingsRegistryMergeUtils } } - void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands) + // This function intentionally copies `commandLine`. It looks like it only uses it as a const reference, but the + // code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy + // ensures that the iterators remain valid. + // NOLINTNEXTLINE(performance-unnecessary-value-param) + void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands) { // Iterate over all the command line options in order to parse the --regset and --regremove // arguments in the order they were supplied @@ -831,7 +835,7 @@ namespace AZ::SettingsRegistryMergeUtils continue; } } - if (commandArgument.m_option == "regremove") + else if (commandArgument.m_option == "regremove") { if (!registry.Remove(commandArgument.m_value)) { diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h index b482530d24..dbeb1bfe24 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h @@ -15,11 +15,7 @@ #include #include #include - -namespace AZ -{ - class CommandLine; -} +#include namespace AZ::IO { @@ -217,7 +213,7 @@ namespace AZ::SettingsRegistryMergeUtils //! example: --regdump /My/Array/With/Objects //! --regdumpall Dumps the entire settings registry to output. //! Note that this function is only called in development builds and is compiled out in release builds. - void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands); + void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands); //! Stores the command line settings into the Setting Registry //! The arguments can be used later anywhere the command line is needed From 673495c49dbbecbd14eb62ad8419b70501db405d Mon Sep 17 00:00:00 2001 From: stramer <169061+sptramer@users.noreply.github.com> Date: Thu, 17 Jun 2021 18:01:44 -0700 Subject: [PATCH 70/93] Address additional review comments. Signed-off-by: stramer <169061+sptramer@users.noreply.github.com> --- .../Framework/AzNetworking/AzNetworking/Framework/ICompressor.h | 2 +- .../AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h | 2 +- Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h index 80f4aa153b..abd38a392b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h +++ b/Code/Framework/AzNetworking/AzNetworking/Framework/ICompressor.h @@ -37,7 +37,7 @@ namespace AzNetworking //! //! 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 currently supported on Udp and Tcp connections. Instantiation of a compressor is controlled by the + //! 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 diff --git a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h index 4669187906..f51a959415 100644 --- a/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h +++ b/Code/Framework/AzNetworking/AzNetworking/PacketLayer/IPacketHeader.h @@ -38,7 +38,7 @@ namespace AzNetworking //! 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 exempted from most + //! 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 diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 50d52abf54..308fbf2ccb 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -54,7 +54,7 @@ namespace Multiplayer //! //! IMultiplayer is an AZ::Interface that provides applications access to //! multiplayer session information and events. IMultiplayer is implemented on the - //! MultiplayerSystemsComponent and is used to define and access information about + //! 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. From 79e510c7387f55d464697276a64a1dfdb66e907d Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Fri, 18 Jun 2021 10:50:28 +0100 Subject: [PATCH 71/93] Make white box mesh incompatible with atom render mesh (#1394) --- Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp index e8e03556e2..89b8035764 100644 --- a/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp +++ b/Gems/WhiteBox/Code/Source/EditorWhiteBoxComponent.cpp @@ -257,17 +257,18 @@ namespace WhiteBox void EditorWhiteBoxComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { - required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); + required.push_back(AZ_CRC_CE("TransformService")); } void EditorWhiteBoxComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { - provided.push_back(AZ_CRC("WhiteBoxService", 0x2f2f42b8)); + provided.push_back(AZ_CRC_CE("WhiteBoxService")); } void EditorWhiteBoxComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); + incompatible.push_back(AZ_CRC_CE("MeshService")); } EditorWhiteBoxComponent::EditorWhiteBoxComponent() = default; From ed186aff18239ef96b683da9241731fb97dd1891 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Fri, 18 Jun 2021 12:29:53 +0100 Subject: [PATCH 72/93] add missing disconnect SimulatedBodyBus to ragdoll destroy (#1404) --- .../Code/Source/PhysXCharacters/Components/RagdollComponent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp index 8da512647f..e5d1a8db47 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp @@ -407,6 +407,7 @@ namespace PhysX AzFramework::RagdollPhysicsRequestBus::Handler::BusDisconnect(); AzFramework::RagdollPhysicsNotificationBus::Event( GetEntityId(), &AzFramework::RagdollPhysicsNotifications::OnRagdollDeactivated); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); if (auto* sceneInterface = AZ::Interface::Get()) { From 108b6f8e0c2cb10b60191a877770d59b8773a3c4 Mon Sep 17 00:00:00 2001 From: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com> Date: Fri, 18 Jun 2021 12:44:34 +0100 Subject: [PATCH 73/93] Updates to ensure OnEntityTransformChanged is called correctly (LYN-2644) (#1405) --- .../Entity/EditorEntityTransformBus.h | 53 ++++++++----------- .../ToolsComponents/TransformComponent.cpp | 32 +++++++---- .../ToolsComponents/TransformComponent.h | 9 ++-- .../UnitTest/AzToolsFrameworkTestHelpers.cpp | 4 +- .../UnitTest/AzToolsFrameworkTestHelpers.h | 1 + .../EditorTransformComponentSelection.cpp | 45 +++++++++++----- ...EditorTransformComponentSelectionTests.cpp | 37 +++++++++++++ 7 files changed, 123 insertions(+), 58 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h index 3fd9b24e7d..b250abe410 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityTransformBus.h @@ -1,47 +1,36 @@ /* -* 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 + * 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 + namespace AzToolsFramework { using EntityIdList = AZStd::vector; - /*! - * Bus for notifications about entity transform changes from the editor viewport - */ - class EditorTransformChangeNotifications - : public AZ::EBusTraits + //! Notifications about entity transform changes from the editor. + class EditorTransformChangeNotifications : public AZ::EBusTraits { public: - virtual ~EditorTransformChangeNotifications() = default; + //! A notification that these entities had their transforms changed due to a user interaction in the editor. + //! @param entityIds Entities that had their transform changed. + virtual void OnEntityTransformChanged([[maybe_unused]] const AzToolsFramework::EntityIdList& entityIds) + { + } - /*! - * Notification that the specified entities are about to have their transforms changed due to user interaction in the editor viewport - * - * \param entityIds Entities about to be changed - */ - virtual void OnEntityTransformChanging(const AzToolsFramework::EntityIdList& /*entityIds*/) {}; - - /*! - * Notification that the specified entities had their transforms changed due to user interaction in the editor viewport - * - * \param entityIds Entities changed - */ - virtual void OnEntityTransformChanged(const AzToolsFramework::EntityIdList& /*entityIds*/) {}; + protected: + ~EditorTransformChangeNotifications() = default; }; using EditorTransformChangeNotificationBus = AZ::EBus; - } // namespace AzToolsFramework - diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index bcbe98c3a7..a911888028 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -944,7 +945,7 @@ namespace AzToolsFramework return AZ::Success(); } - AZ::u32 TransformComponent::ParentChanged() + AZ::u32 TransformComponent::ParentChangedInspector() { AZ::u32 refreshLevel = AZ::Edit::PropertyRefreshLevels::None; @@ -974,12 +975,23 @@ namespace AzToolsFramework return refreshLevel; } - AZ::u32 TransformComponent::TransformChanged() + AZ::u32 TransformComponent::TransformChangedInspector() + { + if (TransformChanged()) + { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + EntityIdList{ GetEntityId() }); + } + + return AZ::Edit::PropertyRefreshLevels::None; + } + + bool TransformComponent::TransformChanged() { if (!m_suppressTransformChangedEvent) { - auto parent = GetParentTransformComponent(); - if (parent) + if (auto parent = GetParentTransformComponent()) { OnTransformChanged(parent->GetLocalTM(), parent->GetWorldTM()); } @@ -987,13 +999,15 @@ namespace AzToolsFramework { OnTransformChanged(AZ::Transform::Identity(), AZ::Transform::Identity()); } + + return true; } - return AZ::Edit::PropertyRefreshLevels::None; + return false; } // This is called when our transform changes static state. - AZ::u32 TransformComponent::StaticChanged() + AZ::u32 TransformComponent::StaticChangedInspector() { AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( &AzToolsFramework::ToolsApplicationEvents::Bus::Events::InvalidatePropertyDisplay, @@ -1175,10 +1189,10 @@ namespace AzToolsFramework Attribute(AZ::Edit::Attributes::AutoExpand, true)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_parentEntityId, "Parent entity", "")-> Attribute(AZ::Edit::Attributes::ChangeValidate, &TransformComponent::ValidatePotentialParent)-> - Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::ParentChanged)-> + Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::ParentChangedInspector)-> Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::DontGatherReference | AZ::Edit::SliceFlags::NotPushableOnSliceRoot)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_editorTransform, "Values", "")-> - Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChanged)-> + Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::TransformChangedInspector)-> Attribute(AZ::Edit::Attributes::AutoExpand, true)-> DataElement(AZ::Edit::UIHandlers::Button, &TransformComponent::m_addNonUniformScaleButton, "", "")-> Attribute(AZ::Edit::Attributes::ButtonText, "Add non-uniform scale")-> @@ -1189,7 +1203,7 @@ namespace AzToolsFramework EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform, "Original relative transform")-> EnumAttribute(AZ::TransformConfig::ParentActivationTransformMode::MaintainCurrentWorldTransform, "Current world transform")-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_isStatic ,"Static", "Static entities are highly optimized and cannot be moved during runtime.")-> - Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::StaticChanged)-> + Attribute(AZ::Edit::Attributes::ChangeNotify, &TransformComponent::StaticChangedInspector)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_cachedWorldTransformParent, "Cached Parent Entity", "")-> Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::DontGatherReference | AZ::Edit::SliceFlags::NotPushable)-> Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h index 80db5e10fb..30608b9680 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.h @@ -182,9 +182,12 @@ namespace AzToolsFramework static void Reflect(AZ::ReflectContext* context); AZ::Outcome ValidatePotentialParent(void* newValue, const AZ::Uuid& valueType); - AZ::u32 ParentChanged(); - AZ::u32 TransformChanged(); - AZ::u32 StaticChanged(); + + AZ::u32 TransformChangedInspector(); + AZ::u32 ParentChangedInspector(); + AZ::u32 StaticChangedInspector(); + + bool TransformChanged(); AZ::Transform GetLocalTranslationTM() const; AZ::Transform GetLocalRotationTM() const; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp index 1a3bc0e5a3..84a58b1f79 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp @@ -165,11 +165,13 @@ namespace UnitTest void EditorEntityComponentChangeDetector::OnEntityTransformChanged( const AzToolsFramework::EntityIdList& entityIds) { + m_entityIds = entityIds; + for (const AZ::EntityId& entityId : entityIds) { if (const auto* entity = GetEntityById(entityId)) { - if (AZ::Component * transformComponent = entity->FindComponent()) + if (AZ::Component* transformComponent = entity->FindComponent()) { OnEntityComponentPropertyChanged(transformComponent->GetId()); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h index 276982d46d..6c146b3ac3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h @@ -239,6 +239,7 @@ namespace UnitTest bool PropertyDisplayInvalidated() const { return m_propertyDisplayInvalidated; } AZStd::vector m_componentIds; + AzToolsFramework::EntityIdList m_entityIds; private: // PropertyEditorEntityChangeNotificationBus ... diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index c503386ab5..cbf9e4ec28 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -999,7 +999,6 @@ namespace AzToolsFramework static void RefreshUiAfterChange(const EntityIdList& entitiyIds) { EditorTransformChangeNotificationBus::Broadcast(&EditorTransformChangeNotifications::OnEntityTransformChanged, entitiyIds); - ToolsApplicationNotificationBus::Broadcast(&ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, Refresh_Values); } @@ -1065,7 +1064,7 @@ namespace AzToolsFramework auto entityBoxSelectData = AZStd::make_shared(); m_boxSelect.InstallLeftMouseDown( - [this, entityBoxSelectData](const ViewportInteraction::MouseInteractionEvent& /*mouseInteraction*/) + [this, entityBoxSelectData]([[maybe_unused]] const ViewportInteraction::MouseInteractionEvent& mouseInteraction) { // begin selection undo/redo command entityBoxSelectData->m_boxSelectSelectionCommand = @@ -1263,8 +1262,12 @@ namespace AzToolsFramework }); translationManipulators->InstallLinearManipulatorMouseUpCallback( - [this]([[maybe_unused]] const LinearManipulator::Action& action) mutable + [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) mutable { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + EndRecordManipulatorCommand(); }); @@ -1293,8 +1296,12 @@ namespace AzToolsFramework }); translationManipulators->InstallPlanarManipulatorMouseUpCallback( - [this, manipulatorEntityIds](const PlanarManipulator::Action& /*action*/) + [this, manipulatorEntityIds]([[maybe_unused]] const PlanarManipulator::Action& action) { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + EndRecordManipulatorCommand(); }); @@ -1322,8 +1329,12 @@ namespace AzToolsFramework }); translationManipulators->InstallSurfaceManipulatorMouseUpCallback( - [this, manipulatorEntityIds](const SurfaceManipulator::Action& /*action*/) + [this, manipulatorEntityIds]([[maybe_unused]] const SurfaceManipulator::Action& action) { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + EndRecordManipulatorCommand(); }); @@ -1360,7 +1371,7 @@ namespace AzToolsFramework AZStd::shared_ptr sharedRotationState = AZStd::make_shared(); rotationManipulators->InstallLeftMouseDownCallback( - [this, sharedRotationState](const AngularManipulator::Action& /*action*/) mutable -> void + [this, sharedRotationState]([[maybe_unused]] const AngularManipulator::Action& action) mutable -> void { sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity(); sharedRotationState->m_referenceFrameAtMouseDown = m_referenceFrame; @@ -1486,8 +1497,12 @@ namespace AzToolsFramework }); rotationManipulators->InstallLeftMouseUpCallback( - [this](const AngularManipulator::Action& /*action*/) + [this, sharedRotationState]([[maybe_unused]] const AngularManipulator::Action& action) { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + sharedRotationState->m_entityIds); + EndRecordManipulatorCommand(); }); @@ -1533,6 +1548,10 @@ namespace AzToolsFramework auto uniformLeftMouseUpCallback = [this, manipulatorEntityIds]([[maybe_unused]] const LinearManipulator::Action& action) { + AzToolsFramework::EditorTransformChangeNotificationBus::Broadcast( + &AzToolsFramework::EditorTransformChangeNotificationBus::Events::OnEntityTransformChanged, + manipulatorEntityIds->m_entityIds); + m_entityIdManipulators.m_manipulators->SetLocalTransform(RecalculateAverageManipulatorTransform( m_entityIdManipulators.m_lookups, m_pivotOverrideFrame, m_pivotMode, m_referenceFrame)); }; @@ -2370,7 +2389,7 @@ namespace AzToolsFramework AddAction( m_actions, { QKeySequence(Qt::Key_U) }, - /*ID_VIEWPORTUI_VISIBLE=*/50040, "Toggle ViewportUI", "Hide/Unhide Viewport UI", + /*ID_VIEWPORTUI_VISIBLE=*/50040, "Toggle Viewport UI", "Hide/Show Viewport UI", [this]() { SetViewportUiClusterVisible(m_transformModeClusterId, !m_viewportUiVisible); @@ -3139,7 +3158,7 @@ namespace AzToolsFramework } void EditorTransformComponentSelection::AfterEntitySelectionChanged( - const EntityIdList& /*newlySelectedEntities*/, const EntityIdList& /*newlyDeselectedEntities*/) + [[maybe_unused]] const EntityIdList& newlySelectedEntities, [[maybe_unused]] const EntityIdList& newlyDeselectedEntities) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -3534,17 +3553,17 @@ namespace AzToolsFramework RegenerateManipulators(); } - void EditorTransformComponentSelection::OnEntityVisibilityChanged(const bool /*visibility*/) + void EditorTransformComponentSelection::OnEntityVisibilityChanged([[maybe_unused]] const bool visibility) { m_selectedEntityIdsAndManipulatorsDirty = true; } - void EditorTransformComponentSelection::OnEntityLockChanged(const bool /*locked*/) + void EditorTransformComponentSelection::OnEntityLockChanged([[maybe_unused]] const bool locked) { m_selectedEntityIdsAndManipulatorsDirty = true; } - void EditorTransformComponentSelection::EnteredComponentMode(const AZStd::vector& /*componentModeTypes*/) + void EditorTransformComponentSelection::EnteredComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { SetViewportUiClusterVisible(m_transformModeClusterId, false); @@ -3553,7 +3572,7 @@ namespace AzToolsFramework ToolsApplicationNotificationBus::Handler::BusDisconnect(); } - void EditorTransformComponentSelection::LeftComponentMode(const AZStd::vector& /*componentModeTypes*/) + void EditorTransformComponentSelection::LeftComponentMode([[maybe_unused]] const AZStd::vector& componentModeTypes) { SetViewportUiClusterVisible(m_transformModeClusterId, true); diff --git a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp index cbc81ba9b8..1d06dc9c33 100644 --- a/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EditorTransformComponentSelectionTests.cpp @@ -451,6 +451,43 @@ namespace UnitTest EXPECT_TRUE(finalEntityTransform.IsClose(finalTransformWorld, 0.01f)); } + TEST_F(EditorTransformComponentSelectionManipulatorTestFixture, TranslatingEntityWithLinearManipulatorNotifiesOnEntityTransformChanged) + { + EditorEntityComponentChangeDetector editorEntityChangeDetector(m_entity1); + + // the initial starting position of the entity (in front and to the left of the camera) + const auto initialTransformWorld = AZ::Transform::CreateTranslation(AZ::Vector3(-10.0f, 10.0f, 0.0f)); + // where the entity should end up (in front and to the right of the camera) + const auto finalTransformWorld = AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 10.0f, 0.0f)); + + // calculate the position in screen space of the initial position of the entity + const auto initialPositionScreen = AzFramework::WorldToScreen(initialTransformWorld.GetTranslation(), m_cameraState); + // calculate the position in screen space of the final position of the entity + const auto finalPositionScreen = AzFramework::WorldToScreen(finalTransformWorld.GetTranslation(), m_cameraState); + + // move the entity to its starting position + AzToolsFramework::SetWorldTransform(m_entity1, initialTransformWorld); + // select the entity (this will cause the manipulators to appear in EditorTransformComponentSelection) + AzToolsFramework::SelectEntity(m_entity1); + + // create an offset along the linear manipulator pointing along the x-axis (perpendicular to the camera view) + const auto mouseOffsetOnManipulator = AzFramework::ScreenVector(10, 0); + // store the mouse down position on the manipulator + const auto mouseDownPosition = initialPositionScreen + mouseOffsetOnManipulator; + // final position in screen space of the mouse + const auto mouseMovePosition = finalPositionScreen + mouseOffsetOnManipulator; + + m_actionDispatcher->CameraState(m_cameraState) + ->MousePosition(mouseDownPosition) + ->MouseLButtonDown() + ->MousePosition(mouseMovePosition) + ->MouseLButtonUp(); + + // verify a EditorTransformChangeNotificationBus::OnEntityTransformChanged occurred + using ::testing::UnorderedElementsAreArray; + EXPECT_THAT(editorEntityChangeDetector.m_entityIds, UnorderedElementsAreArray(m_entityIds)); + } + // simple widget to listen for a mouse wheel event and then forward it on to the ViewportSelectionRequestBus class WheelEventWidget : public QWidget From b17c5ca3e684fc1bb1a42adff141bd13e6993a08 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Fri, 18 Jun 2021 14:09:34 +0100 Subject: [PATCH 74/93] adding physics tick time to post simulate event (#1401) --- .../AzFramework/AzFramework/Physics/Common/PhysicsEvents.h | 3 ++- .../AzFramework/AzFramework/Physics/PhysicsSystem.cpp | 2 +- Gems/PhysX/Code/Source/System/PhysXSystem.cpp | 2 +- Gems/PhysX/Code/Tests/PhysXSystemTests.cpp | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h index a3a34dc1df..e0a89e14ac 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h @@ -48,7 +48,8 @@ namespace AzPhysics using OnPresimulateEvent = AZ::Event; //! Event triggers at the end of the SystemInterface::Simulate call. - using OnPostsimulateEvent = AZ::Event<>; + //! Parameter is the total time that the physics system will run for during the Simulate call. + using OnPostsimulateEvent = AZ::Event; //! Event trigger when a Scene is added to the simulation. //! When triggered will send the handle to the new Scene. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp index 289b5a940b..aa17b7ec83 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.cpp @@ -43,7 +43,7 @@ namespace AzPhysics const AZ::BehaviorAzEventDescription postsimulateEventDescription = { "Postsimulate event", - {} // Parameters + {"Tick time"} // Parameters }; behaviorContext->Class("System Interface") diff --git a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp index 92f68ea13b..0e4c72b77e 100644 --- a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp +++ b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp @@ -198,7 +198,7 @@ namespace PhysX simulateScenes(tickTime); } - m_postSimulateEvent.Signal(); + m_postSimulateEvent.Signal(tickTime); } AzPhysics::SceneHandle PhysXSystem::AddScene(const AzPhysics::SceneConfiguration& config) diff --git a/Gems/PhysX/Code/Tests/PhysXSystemTests.cpp b/Gems/PhysX/Code/Tests/PhysXSystemTests.cpp index 5c3636d040..910a421b65 100644 --- a/Gems/PhysX/Code/Tests/PhysXSystemTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSystemTests.cpp @@ -219,8 +219,9 @@ namespace PhysX preSimEventCount++; }); AzPhysics::SystemEvents::OnPostsimulateEvent::Handler postSimEvent( - [&postSimEventCount]() + [&expectedTickTime, &postSimEventCount](float deltaTime) { + EXPECT_NEAR(expectedTickTime, deltaTime, 0.001f); postSimEventCount++; }); physicsSystem->RegisterPreSimulateEvent(preSimEvent); From 13bf685661f1f15096e8d354ebefa3b228286f5f Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:28:31 -0500 Subject: [PATCH 75/93] Cleaned up vegetation_precompiled.h (#1418) * Removed vegetation_precompiled.h * Removed CryCommon dependency --- Gems/Vegetation/Code/CMakeLists.txt | 1 - Gems/Vegetation/Code/Source/AreaSystemComponent.cpp | 2 +- .../Code/Source/Components/AreaBlenderComponent.cpp | 2 +- Gems/Vegetation/Code/Source/Components/AreaComponentBase.cpp | 1 - Gems/Vegetation/Code/Source/Components/BlockerComponent.cpp | 1 - .../Source/Components/DescriptorListCombinerComponent.cpp | 1 - .../Code/Source/Components/DescriptorListComponent.cpp | 1 - .../Source/Components/DescriptorWeightSelectorComponent.cpp | 1 - .../Source/Components/DistanceBetweenFilterComponent.cpp | 2 +- .../Code/Source/Components/DistributionFilterComponent.cpp | 2 +- .../Code/Source/Components/LevelSettingsComponent.cpp | 1 - .../Code/Source/Components/MeshBlockerComponent.cpp | 1 - .../Code/Source/Components/PositionModifierComponent.cpp | 1 - .../Code/Source/Components/ReferenceShapeComponent.cpp | 1 - .../Code/Source/Components/RotationModifierComponent.cpp | 1 - .../Code/Source/Components/ScaleModifierComponent.cpp | 1 - .../Source/Components/ShapeIntersectionFilterComponent.cpp | 2 +- .../Source/Components/SlopeAlignmentModifierComponent.cpp | 1 - Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp | 2 +- .../Source/Components/SurfaceAltitudeFilterComponent.cpp | 2 +- .../Source/Components/SurfaceMaskDepthFilterComponent.cpp | 2 +- .../Code/Source/Components/SurfaceMaskFilterComponent.cpp | 2 +- .../Code/Source/Components/SurfaceSlopeFilterComponent.cpp | 2 +- Gems/Vegetation/Code/Source/DebugSystemComponent.cpp | 1 - Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.cpp | 1 - Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.h | 5 +++-- Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp | 2 +- Gems/Vegetation/Code/Source/Debugger/DebugComponent.h | 2 +- .../Code/Source/Debugger/EditorAreaDebugComponent.cpp | 1 - .../Vegetation/Code/Source/Debugger/EditorDebugComponent.cpp | 1 - Gems/Vegetation/Code/Source/Descriptor.cpp | 2 -- Gems/Vegetation/Code/Source/DescriptorListAsset.cpp | 2 -- Gems/Vegetation/Code/Source/DynamicSliceInstanceSpawner.cpp | 1 - .../Code/Source/Editor/EditorAreaBlenderComponent.cpp | 3 --- .../Vegetation/Code/Source/Editor/EditorBlockerComponent.cpp | 1 - .../Source/Editor/EditorDescriptorListCombinerComponent.cpp | 1 - .../Code/Source/Editor/EditorDescriptorListComponent.cpp | 1 - .../Editor/EditorDescriptorWeightSelectorComponent.cpp | 1 - .../Source/Editor/EditorDistanceBetweenFilterComponent.cpp | 1 - .../Code/Source/Editor/EditorDistributionFilterComponent.cpp | 1 - .../Code/Source/Editor/EditorLevelSettingsComponent.cpp | 2 -- .../Code/Source/Editor/EditorMeshBlockerComponent.cpp | 1 - .../Code/Source/Editor/EditorPositionModifierComponent.cpp | 1 - .../Code/Source/Editor/EditorReferenceShapeComponent.cpp | 1 - .../Code/Source/Editor/EditorRotationModifierComponent.cpp | 1 - .../Code/Source/Editor/EditorScaleModifierComponent.cpp | 1 - .../Source/Editor/EditorShapeIntersectionFilterComponent.cpp | 1 - .../Source/Editor/EditorSlopeAlignmentModifierComponent.cpp | 1 - .../Vegetation/Code/Source/Editor/EditorSpawnerComponent.cpp | 1 - .../Source/Editor/EditorSurfaceAltitudeFilterComponent.cpp | 1 - .../Source/Editor/EditorSurfaceMaskDepthFilterComponent.cpp | 1 - .../Code/Source/Editor/EditorSurfaceMaskFilterComponent.cpp | 1 - .../Code/Source/Editor/EditorSurfaceSlopeFilterComponent.cpp | 1 - .../Code/Source/Editor/EditorVegetationSystemComponent.cpp | 4 ---- Gems/Vegetation/Code/Source/EmptyInstanceSpawner.cpp | 1 - Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp | 2 +- Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp | 1 - Gems/Vegetation/Code/Source/VegetationEditorModule.cpp | 2 -- Gems/Vegetation/Code/Source/VegetationEditorModule.h | 1 - Gems/Vegetation/Code/Source/VegetationModule.cpp | 2 -- Gems/Vegetation/Code/Source/VegetationModule.h | 1 - .../{Vegetation_precompiled.h => VegetationProfiler.h} | 2 -- Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp | 3 --- .../Code/Tests/DynamicSliceInstanceSpawnerTests.cpp | 2 -- Gems/Vegetation/Code/Tests/EmptyInstanceSpawnerTests.cpp | 2 -- Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp | 2 -- .../Code/Tests/VegetationAreaSystemComponentTest.cpp | 2 -- .../Code/Tests/VegetationComponentDescriptorTests.cpp | 2 -- .../Vegetation/Code/Tests/VegetationComponentFilterTests.cpp | 2 -- .../Code/Tests/VegetationComponentModifierTests.cpp | 2 -- .../Code/Tests/VegetationComponentOperationTests.cpp | 2 -- Gems/Vegetation/Code/Tests/VegetationTest.cpp | 2 -- Gems/Vegetation/Code/vegetation_files.cmake | 1 - Gems/Vegetation/Code/vegetation_shared_files.cmake | 1 + 74 files changed, 17 insertions(+), 96 deletions(-) rename Gems/Vegetation/Code/Source/{Vegetation_precompiled.h => VegetationProfiler.h} (90%) diff --git a/Gems/Vegetation/Code/CMakeLists.txt b/Gems/Vegetation/Code/CMakeLists.txt index 10d54da78e..2b32368d5a 100644 --- a/Gems/Vegetation/Code/CMakeLists.txt +++ b/Gems/Vegetation/Code/CMakeLists.txt @@ -28,7 +28,6 @@ ly_add_target( Gem::LmbrCentral Gem::SurfaceData PUBLIC - Legacy::CryCommon Gem::AtomLyIntegration_CommonFeatures.Static RUNTIME_DEPENDENCIES Gem::GradientSignal diff --git a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp index e54f523b43..d6e4be6e9b 100644 --- a/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/AreaSystemComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "AreaSystemComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp b/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp index ff39f6321e..7c9d8013d0 100644 --- a/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/AreaBlenderComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "AreaBlenderComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/AreaComponentBase.cpp b/Gems/Vegetation/Code/Source/Components/AreaComponentBase.cpp index 056006f64a..46e214534a 100644 --- a/Gems/Vegetation/Code/Source/Components/AreaComponentBase.cpp +++ b/Gems/Vegetation/Code/Source/Components/AreaComponentBase.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include #include #include diff --git a/Gems/Vegetation/Code/Source/Components/BlockerComponent.cpp b/Gems/Vegetation/Code/Source/Components/BlockerComponent.cpp index fa876c5cf0..5219334fd6 100644 --- a/Gems/Vegetation/Code/Source/Components/BlockerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/BlockerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "BlockerComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/DescriptorListCombinerComponent.cpp b/Gems/Vegetation/Code/Source/Components/DescriptorListCombinerComponent.cpp index ffa57a0326..3a903399d1 100644 --- a/Gems/Vegetation/Code/Source/Components/DescriptorListCombinerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/DescriptorListCombinerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "DescriptorListCombinerComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/DescriptorListComponent.cpp b/Gems/Vegetation/Code/Source/Components/DescriptorListComponent.cpp index c6939d520a..bc5be7423b 100644 --- a/Gems/Vegetation/Code/Source/Components/DescriptorListComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/DescriptorListComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "DescriptorListComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/DescriptorWeightSelectorComponent.cpp b/Gems/Vegetation/Code/Source/Components/DescriptorWeightSelectorComponent.cpp index 840eec8dfa..19cf75e4d2 100644 --- a/Gems/Vegetation/Code/Source/Components/DescriptorWeightSelectorComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/DescriptorWeightSelectorComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "DescriptorWeightSelectorComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/DistanceBetweenFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/DistanceBetweenFilterComponent.cpp index 16b1bb5f7e..99050638b5 100644 --- a/Gems/Vegetation/Code/Source/Components/DistanceBetweenFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/DistanceBetweenFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "DistanceBetweenFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/DistributionFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/DistributionFilterComponent.cpp index 2ba07f95b3..aff560d7d4 100644 --- a/Gems/Vegetation/Code/Source/Components/DistributionFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/DistributionFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "DistributionFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/LevelSettingsComponent.cpp b/Gems/Vegetation/Code/Source/Components/LevelSettingsComponent.cpp index 748ba0506a..4196619ffc 100644 --- a/Gems/Vegetation/Code/Source/Components/LevelSettingsComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/LevelSettingsComponent.cpp @@ -9,7 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" #include "LevelSettingsComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/MeshBlockerComponent.cpp b/Gems/Vegetation/Code/Source/Components/MeshBlockerComponent.cpp index d37dc4a82d..8eedf4019b 100644 --- a/Gems/Vegetation/Code/Source/Components/MeshBlockerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/MeshBlockerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "MeshBlockerComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp b/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp index 5781e53b41..5c1c48aa39 100644 --- a/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/PositionModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "PositionModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/ReferenceShapeComponent.cpp b/Gems/Vegetation/Code/Source/Components/ReferenceShapeComponent.cpp index c5f99239d3..fc62eb39a7 100644 --- a/Gems/Vegetation/Code/Source/Components/ReferenceShapeComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/ReferenceShapeComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "ReferenceShapeComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/RotationModifierComponent.cpp b/Gems/Vegetation/Code/Source/Components/RotationModifierComponent.cpp index 9dda59463e..d88b606aa3 100644 --- a/Gems/Vegetation/Code/Source/Components/RotationModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/RotationModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "RotationModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/ScaleModifierComponent.cpp b/Gems/Vegetation/Code/Source/Components/ScaleModifierComponent.cpp index 63755e5325..6e0397b410 100644 --- a/Gems/Vegetation/Code/Source/Components/ScaleModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/ScaleModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "ScaleModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/ShapeIntersectionFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/ShapeIntersectionFilterComponent.cpp index b1512f89a4..b7f9f7fe9c 100644 --- a/Gems/Vegetation/Code/Source/Components/ShapeIntersectionFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/ShapeIntersectionFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "ShapeIntersectionFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/SlopeAlignmentModifierComponent.cpp b/Gems/Vegetation/Code/Source/Components/SlopeAlignmentModifierComponent.cpp index 3ff45bad74..78d4d4729c 100644 --- a/Gems/Vegetation/Code/Source/Components/SlopeAlignmentModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SlopeAlignmentModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "SlopeAlignmentModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp b/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp index 6c1db9037b..321613dd08 100644 --- a/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SpawnerComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "SpawnerComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceAltitudeFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/SurfaceAltitudeFilterComponent.cpp index 7e6737ecf7..ebc8896fe6 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceAltitudeFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SurfaceAltitudeFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "SurfaceAltitudeFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp index d8e8b47f7b..2a191245ee 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SurfaceMaskDepthFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "SurfaceMaskDepthFilterComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceMaskFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/SurfaceMaskFilterComponent.cpp index d18a7434ae..0749d9473a 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceMaskFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SurfaceMaskFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "SurfaceMaskFilterComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Components/SurfaceSlopeFilterComponent.cpp b/Gems/Vegetation/Code/Source/Components/SurfaceSlopeFilterComponent.cpp index f856e4bd8f..27938b9c74 100644 --- a/Gems/Vegetation/Code/Source/Components/SurfaceSlopeFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Components/SurfaceSlopeFilterComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "SurfaceSlopeFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/DebugSystemComponent.cpp b/Gems/Vegetation/Code/Source/DebugSystemComponent.cpp index c62905766e..984f8fd538 100644 --- a/Gems/Vegetation/Code/Source/DebugSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/DebugSystemComponent.cpp @@ -9,7 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" #include "DebugSystemComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.cpp index 12ba003cc0..91ab9279fe 100644 --- a/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include #include #include diff --git a/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.h b/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.h index 014e45249a..7bea99a2fa 100644 --- a/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.h +++ b/Gems/Vegetation/Code/Source/Debugger/AreaDebugComponent.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -31,13 +32,13 @@ namespace Vegetation { AZ_INLINE AZ::Color GetDebugColor() { - static uint32 debugColor = 0xff << 8; + static uint32_t debugColor = 0xff << 8; AZ::Color value; value.FromU32(debugColor | (0xff << 24)); // add in alpha 255 // use a golden ratio sequence to generate the next color // new color = fract(old color * 1.6) // Treat the 24 bits as normalized 0 - 1 - debugColor = (uint32)((((uint64)debugColor * 0x1999999ull) - 0xffffffull) & 0xffffffull); + debugColor = azlossy_cast(((aznumeric_cast(debugColor) * 0x1999999ull) - 0xffffffull) & 0xffffffull); return value; } diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp index 099bd2e90c..cb241c4fd2 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.cpp @@ -10,7 +10,7 @@ * */ -#include "Vegetation_precompiled.h" +#include #include "DebugComponent.h" #include "AreaSystemComponent.h" #include "InstanceSystemComponent.h" diff --git a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h index ae834b3632..9283c1da90 100644 --- a/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h +++ b/Gems/Vegetation/Code/Source/Debugger/DebugComponent.h @@ -167,7 +167,7 @@ namespace Vegetation using AreaData = AZStd::vector; AZStd::size_t MakeAreaSectorKey(AZ::EntityId areaId, SectorId sectorId); - AZStd::unordered_map m_currentAreasTiming; + AZStd::unordered_map m_currentAreasTiming; AreaData m_areaData; AZStd::vector m_currentSortedTimingList; diff --git a/Gems/Vegetation/Code/Source/Debugger/EditorAreaDebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/EditorAreaDebugComponent.cpp index bf942f78c4..2069dd66bb 100644 --- a/Gems/Vegetation/Code/Source/Debugger/EditorAreaDebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/EditorAreaDebugComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorAreaDebugComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Debugger/EditorDebugComponent.cpp b/Gems/Vegetation/Code/Source/Debugger/EditorDebugComponent.cpp index 533a1daf00..0dc66ee3b8 100644 --- a/Gems/Vegetation/Code/Source/Debugger/EditorDebugComponent.cpp +++ b/Gems/Vegetation/Code/Source/Debugger/EditorDebugComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDebugComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Descriptor.cpp b/Gems/Vegetation/Code/Source/Descriptor.cpp index d0075f2d7b..cb1a4e45b7 100644 --- a/Gems/Vegetation/Code/Source/Descriptor.cpp +++ b/Gems/Vegetation/Code/Source/Descriptor.cpp @@ -10,8 +10,6 @@ * */ -#include "Vegetation_precompiled.h" - #include #include #include diff --git a/Gems/Vegetation/Code/Source/DescriptorListAsset.cpp b/Gems/Vegetation/Code/Source/DescriptorListAsset.cpp index 90728718ed..4e0294c58c 100644 --- a/Gems/Vegetation/Code/Source/DescriptorListAsset.cpp +++ b/Gems/Vegetation/Code/Source/DescriptorListAsset.cpp @@ -10,8 +10,6 @@ * */ -#include "Vegetation_precompiled.h" - #include #include #include diff --git a/Gems/Vegetation/Code/Source/DynamicSliceInstanceSpawner.cpp b/Gems/Vegetation/Code/Source/DynamicSliceInstanceSpawner.cpp index a185c9a601..9ed23c7dd2 100644 --- a/Gems/Vegetation/Code/Source/DynamicSliceInstanceSpawner.cpp +++ b/Gems/Vegetation/Code/Source/DynamicSliceInstanceSpawner.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorAreaBlenderComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorAreaBlenderComponent.cpp index 7371a96ba1..7511d6b8be 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorAreaBlenderComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorAreaBlenderComponent.cpp @@ -10,14 +10,11 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorAreaBlenderComponent.h" #include #include #include #include -#include -#include #include #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorBlockerComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorBlockerComponent.cpp index bbd116b091..da0a2b5f53 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorBlockerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorBlockerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorBlockerComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListCombinerComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListCombinerComponent.cpp index ade8121b06..cbe62e0444 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListCombinerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListCombinerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDescriptorListCombinerComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListComponent.cpp index 51ecc03c5a..18c045346b 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorListComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDescriptorListComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorWeightSelectorComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorWeightSelectorComponent.cpp index 1c23745831..5ae65d3c21 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorDescriptorWeightSelectorComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorDescriptorWeightSelectorComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDescriptorWeightSelectorComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorDistanceBetweenFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorDistanceBetweenFilterComponent.cpp index ea6ab5eec1..e43be749bd 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorDistanceBetweenFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorDistanceBetweenFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDistanceBetweenFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorDistributionFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorDistributionFilterComponent.cpp index 8ea0acb78d..6b75ca73bc 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorDistributionFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorDistributionFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorDistributionFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorLevelSettingsComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorLevelSettingsComponent.cpp index 6f6a6f2ec4..5faae032a3 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorLevelSettingsComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorLevelSettingsComponent.cpp @@ -10,8 +10,6 @@ * */ -#include "Vegetation_precompiled.h" - #include "EditorLevelSettingsComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorMeshBlockerComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorMeshBlockerComponent.cpp index fe519877e2..63c63d3d87 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorMeshBlockerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorMeshBlockerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorMeshBlockerComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorPositionModifierComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorPositionModifierComponent.cpp index 14ae748168..e12444b83e 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorPositionModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorPositionModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorPositionModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorReferenceShapeComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorReferenceShapeComponent.cpp index 5f3225e23d..4240e4914c 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorReferenceShapeComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorReferenceShapeComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorReferenceShapeComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorRotationModifierComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorRotationModifierComponent.cpp index 8d81ff1dae..ab9d55f221 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorRotationModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorRotationModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorRotationModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorScaleModifierComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorScaleModifierComponent.cpp index d6dc70a523..1c1684f5d5 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorScaleModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorScaleModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorScaleModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorShapeIntersectionFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorShapeIntersectionFilterComponent.cpp index 93e5f41c75..b5a236bcee 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorShapeIntersectionFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorShapeIntersectionFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorShapeIntersectionFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSlopeAlignmentModifierComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSlopeAlignmentModifierComponent.cpp index 6002787404..ce036813d0 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSlopeAlignmentModifierComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSlopeAlignmentModifierComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSlopeAlignmentModifierComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSpawnerComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSpawnerComponent.cpp index 9dd393e124..6aad60f051 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSpawnerComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSpawnerComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSpawnerComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceAltitudeFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceAltitudeFilterComponent.cpp index 6e46241b83..3ea5760a46 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceAltitudeFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceAltitudeFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSurfaceAltitudeFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskDepthFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskDepthFilterComponent.cpp index f28d134dd0..b4a37f679b 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskDepthFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskDepthFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSurfaceMaskDepthFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskFilterComponent.cpp index 7567acdbde..7d64bc2423 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceMaskFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSurfaceMaskFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceSlopeFilterComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceSlopeFilterComponent.cpp index 5b0868566d..ae93cf3c0b 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorSurfaceSlopeFilterComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorSurfaceSlopeFilterComponent.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include "EditorSurfaceSlopeFilterComponent.h" #include #include diff --git a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp index 17174fa132..fc056de636 100644 --- a/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/Editor/EditorVegetationSystemComponent.cpp @@ -9,14 +9,10 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" #include "EditorVegetationSystemComponent.h" #include #include - -#include - #include namespace Vegetation diff --git a/Gems/Vegetation/Code/Source/EmptyInstanceSpawner.cpp b/Gems/Vegetation/Code/Source/EmptyInstanceSpawner.cpp index 9146ea1090..11ceecefc4 100644 --- a/Gems/Vegetation/Code/Source/EmptyInstanceSpawner.cpp +++ b/Gems/Vegetation/Code/Source/EmptyInstanceSpawner.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include #include #include diff --git a/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp b/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp index 4aaf0a0b49..cd50c1f898 100644 --- a/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/InstanceSystemComponent.cpp @@ -9,7 +9,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" +#include #include "InstanceSystemComponent.h" #include diff --git a/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp index f22dbb61aa..9ff66a875f 100644 --- a/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp +++ b/Gems/Vegetation/Code/Source/PrefabInstanceSpawner.cpp @@ -10,7 +10,6 @@ * */ -#include "Vegetation_precompiled.h" #include #include diff --git a/Gems/Vegetation/Code/Source/VegetationEditorModule.cpp b/Gems/Vegetation/Code/Source/VegetationEditorModule.cpp index ce1f129e1a..c044487704 100644 --- a/Gems/Vegetation/Code/Source/VegetationEditorModule.cpp +++ b/Gems/Vegetation/Code/Source/VegetationEditorModule.cpp @@ -10,8 +10,6 @@ * */ -#include "Vegetation_precompiled.h" - #include #include diff --git a/Gems/Vegetation/Code/Source/VegetationEditorModule.h b/Gems/Vegetation/Code/Source/VegetationEditorModule.h index 76e409f0b5..107d400d1e 100644 --- a/Gems/Vegetation/Code/Source/VegetationEditorModule.h +++ b/Gems/Vegetation/Code/Source/VegetationEditorModule.h @@ -12,7 +12,6 @@ #pragma once -#include "Vegetation_precompiled.h" #include namespace Vegetation diff --git a/Gems/Vegetation/Code/Source/VegetationModule.cpp b/Gems/Vegetation/Code/Source/VegetationModule.cpp index 90215e7996..7daa33b35c 100644 --- a/Gems/Vegetation/Code/Source/VegetationModule.cpp +++ b/Gems/Vegetation/Code/Source/VegetationModule.cpp @@ -10,8 +10,6 @@ * */ -#include "Vegetation_precompiled.h" - #include #include diff --git a/Gems/Vegetation/Code/Source/VegetationModule.h b/Gems/Vegetation/Code/Source/VegetationModule.h index 0b36eb3856..26d0a169aa 100644 --- a/Gems/Vegetation/Code/Source/VegetationModule.h +++ b/Gems/Vegetation/Code/Source/VegetationModule.h @@ -12,7 +12,6 @@ #pragma once -#include "Vegetation_precompiled.h" #include namespace Vegetation diff --git a/Gems/Vegetation/Code/Source/Vegetation_precompiled.h b/Gems/Vegetation/Code/Source/VegetationProfiler.h similarity index 90% rename from Gems/Vegetation/Code/Source/Vegetation_precompiled.h rename to Gems/Vegetation/Code/Source/VegetationProfiler.h index 92116dd175..fa8ff7865b 100644 --- a/Gems/Vegetation/Code/Source/Vegetation_precompiled.h +++ b/Gems/Vegetation/Code/Source/VegetationProfiler.h @@ -11,8 +11,6 @@ */ #pragma once -#include // Many CryCommon files require that this is included first. - // VEG_PROFILE_ENABLED is defined in the wscript // VEG_PROFILE_ENABLED is only defined in the Vegetation gem by default #if defined(VEG_PROFILE_ENABLED) diff --git a/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp b/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp index a3a1ff4616..78a6a4171d 100644 --- a/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp +++ b/Gems/Vegetation/Code/Source/VegetationSystemComponent.cpp @@ -9,7 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" #include "VegetationSystemComponent.h" #include @@ -27,8 +26,6 @@ #include #include -#include - namespace Vegetation { namespace Details diff --git a/Gems/Vegetation/Code/Tests/DynamicSliceInstanceSpawnerTests.cpp b/Gems/Vegetation/Code/Tests/DynamicSliceInstanceSpawnerTests.cpp index c3aa910b47..3ced558c3d 100644 --- a/Gems/Vegetation/Code/Tests/DynamicSliceInstanceSpawnerTests.cpp +++ b/Gems/Vegetation/Code/Tests/DynamicSliceInstanceSpawnerTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/EmptyInstanceSpawnerTests.cpp b/Gems/Vegetation/Code/Tests/EmptyInstanceSpawnerTests.cpp index 19ebca7602..dae9a692d5 100644 --- a/Gems/Vegetation/Code/Tests/EmptyInstanceSpawnerTests.cpp +++ b/Gems/Vegetation/Code/Tests/EmptyInstanceSpawnerTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp b/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp index 368615ea42..ed618278d2 100644 --- a/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp +++ b/Gems/Vegetation/Code/Tests/PrefabInstanceSpawnerTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/VegetationAreaSystemComponentTest.cpp b/Gems/Vegetation/Code/Tests/VegetationAreaSystemComponentTest.cpp index 8c72b01fd5..c06db1b9d8 100644 --- a/Gems/Vegetation/Code/Tests/VegetationAreaSystemComponentTest.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationAreaSystemComponentTest.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include #include #include diff --git a/Gems/Vegetation/Code/Tests/VegetationComponentDescriptorTests.cpp b/Gems/Vegetation/Code/Tests/VegetationComponentDescriptorTests.cpp index 6e2aa42c9b..a19a4f2516 100644 --- a/Gems/Vegetation/Code/Tests/VegetationComponentDescriptorTests.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationComponentDescriptorTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/VegetationComponentFilterTests.cpp b/Gems/Vegetation/Code/Tests/VegetationComponentFilterTests.cpp index cfd621b397..17e3626e32 100644 --- a/Gems/Vegetation/Code/Tests/VegetationComponentFilterTests.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationComponentFilterTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/VegetationComponentModifierTests.cpp b/Gems/Vegetation/Code/Tests/VegetationComponentModifierTests.cpp index 035e4efdc8..60a0e73250 100644 --- a/Gems/Vegetation/Code/Tests/VegetationComponentModifierTests.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationComponentModifierTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/VegetationComponentOperationTests.cpp b/Gems/Vegetation/Code/Tests/VegetationComponentOperationTests.cpp index c69024826b..b9dce45ccd 100644 --- a/Gems/Vegetation/Code/Tests/VegetationComponentOperationTests.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationComponentOperationTests.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include "VegetationTest.h" #include "VegetationMocks.h" diff --git a/Gems/Vegetation/Code/Tests/VegetationTest.cpp b/Gems/Vegetation/Code/Tests/VegetationTest.cpp index d570cd3386..b58b80a3a9 100644 --- a/Gems/Vegetation/Code/Tests/VegetationTest.cpp +++ b/Gems/Vegetation/Code/Tests/VegetationTest.cpp @@ -9,8 +9,6 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ -#include "Vegetation_precompiled.h" - #include #include #include "VegetationTest.h" diff --git a/Gems/Vegetation/Code/vegetation_files.cmake b/Gems/Vegetation/Code/vegetation_files.cmake index d06a2d6927..896720d30e 100644 --- a/Gems/Vegetation/Code/vegetation_files.cmake +++ b/Gems/Vegetation/Code/vegetation_files.cmake @@ -10,7 +10,6 @@ # set(FILES - Source/Vegetation_precompiled.h Include/Vegetation/DescriptorListAsset.h Include/Vegetation/Descriptor.h Include/Vegetation/InstanceData.h diff --git a/Gems/Vegetation/Code/vegetation_shared_files.cmake b/Gems/Vegetation/Code/vegetation_shared_files.cmake index 82b02b3881..4a49699f79 100644 --- a/Gems/Vegetation/Code/vegetation_shared_files.cmake +++ b/Gems/Vegetation/Code/vegetation_shared_files.cmake @@ -14,4 +14,5 @@ set(FILES Source/AreaSystemComponent.h Source/VegetationModule.cpp Source/VegetationModule.h + Source/VegetationProfiler.h ) From 84de2d2e12ac8351a52aa8dcb9fdd9f7c753a34b Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Fri, 18 Jun 2021 15:38:49 +0100 Subject: [PATCH 76/93] Fixed failing periodic physics tests (#1429) --- .../physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py | 2 +- .../C5340400_RigidBody_ManualMomentOfInertia.ly | 4 ++-- Code/Framework/AzFramework/AzFramework/Physics/Material.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py index 57cdc8f9c5..40291b2114 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py @@ -102,7 +102,7 @@ def C4044695_PhysXCollider_AddMultipleSurfaceFbx(): # 6) Check if multiple material slots show up under Materials section in the PhysX Collider component pte = collider_component.get_property_tree() def get_surface_count(): - count = pte.get_container_count("Collider Configuration|Physics Material|Mesh Surfaces") + count = pte.get_container_count("Collider Configuration|Physics Materials|Slots") return count.GetValue() Report.result( diff --git a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly index a649728997..87166a9d8d 100644 --- a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly +++ b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b6e408095c15a388768b7f70b6049f33c894aab3e51f2d744bc1ae1d18668ee4 -size 9694 +oid sha256:824a51a375f19274d5698ff08af0fdc3dc18204505c73a943de748455d108b01 +size 6181 diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp index d84d2739d0..82c5c5d071 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp @@ -402,7 +402,7 @@ namespace Physics ->Attribute(AZ_CRC_CE("EditButton"), "") ->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor") ->Attribute(AZ::Edit::Attributes::DefaultAsset, &MaterialSelection::GetMaterialLibraryId) - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "Slots", "") ->ElementAttribute(Attributes::MaterialLibraryAssetId, &MaterialSelection::GetMaterialLibraryId) ->Attribute(AZ::Edit::Attributes::IndexedChildNameLabelOverride, &MaterialSelection::GetMaterialSlotLabel) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) From aa583243f6b7db439cf6c797567657db24f2074e Mon Sep 17 00:00:00 2001 From: scottr Date: Fri, 18 Jun 2021 07:53:29 -0700 Subject: [PATCH 77/93] [cpack/stabilization/2106-vendor-name] update installer vendor name --- cmake/Packaging.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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") From 35a7ca718bc05d45108a8919fff6b0c17ca2cbac Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Fri, 18 Jun 2021 17:04:29 +0100 Subject: [PATCH 78/93] Fixed Physics script canvas assets failing in iOS (#1431) --- ...tCanvas_ShapeCastVerification.scriptcanvas | 2615 +- .../Weapons/Revolver/Tracer_FX.scriptcanvas | 21354 ++++++++-------- 2 files changed, 12019 insertions(+), 11950 deletions(-) diff --git a/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas b/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas index b24a477a2e..9b1357eebe 100644 --- a/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas @@ -3,34 +3,158 @@ - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -41,7 +165,7 @@ - + @@ -65,9 +189,374 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -75,7 +564,7 @@ - + @@ -278,21 +767,21 @@ - + - + - + @@ -335,7 +824,7 @@ - + @@ -378,7 +867,7 @@ - + @@ -416,227 +905,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -713,21 +982,12 @@ - + - - - - - - - - - - + @@ -1321,7 +1581,7 @@ - + @@ -1386,598 +1646,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -2020,7 +1703,7 @@ - + @@ -2063,7 +1746,7 @@ - + @@ -2101,7 +1784,7 @@ - + @@ -2178,125 +1861,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + @@ -2309,79 +2207,17 @@ - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2389,10 +2225,10 @@ - + - + @@ -2402,17 +2238,48 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -2420,7 +2287,7 @@ - + @@ -2433,28 +2300,152 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2470,7 +2461,7 @@ - + @@ -2478,49 +2469,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2528,7 +2477,7 @@ - + @@ -2545,37 +2494,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -2583,7 +2511,7 @@ - + @@ -2591,229 +2519,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2823,11 +2529,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2837,14 +2828,6 @@ - - - - - - - - @@ -2853,6 +2836,14 @@ + + + + + + + + @@ -2868,7 +2859,7 @@ - + diff --git a/Gems/PhysXSamples/Assets/ScriptCanvas/Weapons/Revolver/Tracer_FX.scriptcanvas b/Gems/PhysXSamples/Assets/ScriptCanvas/Weapons/Revolver/Tracer_FX.scriptcanvas index f0fff5e69f..40fcf77147 100644 --- a/Gems/PhysXSamples/Assets/ScriptCanvas/Weapons/Revolver/Tracer_FX.scriptcanvas +++ b/Gems/PhysXSamples/Assets/ScriptCanvas/Weapons/Revolver/Tracer_FX.scriptcanvas @@ -3,7 +3,7 @@ - + @@ -16,1429 +16,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -1481,7 +73,7 @@ - + @@ -1524,7 +116,7 @@ - + @@ -1567,7 +159,7 @@ - + @@ -1605,7 +197,7 @@ - + @@ -1694,825 +286,26 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -2550,7 +343,7 @@ - + @@ -2588,7 +381,7 @@ - + @@ -2626,7 +419,7 @@ - + @@ -2664,7 +457,7 @@ - + @@ -2702,7 +495,7 @@ - + @@ -2744,12 +537,12 @@ - + - + @@ -2759,7 +552,7 @@ - + @@ -2769,7 +562,7 @@ - + @@ -2785,1734 +578,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -5189,313 +1255,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + @@ -5505,8 +1284,8 @@ - - + + @@ -5533,7 +1312,7 @@ - + @@ -5543,257 +1322,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -5820,7 +1350,7 @@ - + @@ -5830,8 +1360,8 @@ - - + + @@ -5858,7 +1388,83 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5872,9 +1478,21 @@ + + + + + + + + + + + + - - + + @@ -5901,7 +1519,7 @@ - + @@ -5935,57 +1553,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -5995,10 +1567,10 @@ - + - + @@ -6006,90 +1578,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -6104,7 +1595,7 @@ - + @@ -6114,7 +1605,45 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6127,7 +1656,7 @@ - + @@ -6157,16 +1686,61 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + @@ -6174,21 +1748,59 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6203,7 +1815,7 @@ - + @@ -6231,136 +1843,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -6398,7 +1881,7 @@ - + @@ -6437,64 +1920,30 @@ - + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - + - + @@ -6502,595 +1951,21 @@ - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -7128,7 +2003,7 @@ - + @@ -7166,7 +2041,7 @@ - + @@ -7209,7 +2084,7 @@ - + @@ -7252,7 +2127,7 @@ - + @@ -7310,7 +2185,7 @@ - + @@ -7325,21 +2200,21 @@ - + - + - + - + @@ -7382,7 +2257,7 @@ - + @@ -7391,20 +2266,13 @@ - - - - - - - - + @@ -7432,7 +2300,7 @@ - + @@ -7470,7 +2338,7 @@ - + @@ -7523,20 +2391,20 @@ - + - + - + - + @@ -7552,1092 +2420,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -8677,22 +2460,6 @@ - - - - - - - - - - - - - - - - @@ -8705,6 +2472,22 @@ + + + + + + + + + + + + + + + + @@ -8762,22 +2545,6 @@ - - - - - - - - - - - - - - - - @@ -8790,6 +2557,22 @@ + + + + + + + + + + + + + + + + @@ -8836,22 +2619,6 @@ - - - - - - - - - - - - - - - - @@ -8864,6 +2631,22 @@ + + + + + + + + + + + + + + + + @@ -9060,445 +2843,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -9785,1024 +3130,163 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -10845,7 +3329,7 @@ - + @@ -10854,13 +3338,20 @@ + + + + + + + - + @@ -10888,7 +3379,7 @@ - + @@ -10926,7 +3417,7 @@ - + @@ -10979,20 +3470,20 @@ - + - + - + - + @@ -11008,689 +3499,294 @@ - + - + - - - - - - + + + + + + + + + + + - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -12449,15 +4545,33 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + @@ -12491,33 +4605,15 @@ - + - + - + - - - - - - - - - - - - - - - - - - - + @@ -12538,7 +4634,6501 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -12741,7 +11331,926 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -12883,21 +12392,21 @@ - + - + - + @@ -12935,7 +12444,7 @@ - + @@ -12973,7 +12482,7 @@ - + @@ -12983,10 +12492,124 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -13012,12 +12635,389 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -13027,7 +13027,7 @@ - + @@ -13037,7 +13037,7 @@ - + @@ -13045,7 +13045,7 @@ - + @@ -13058,7 +13058,7 @@ - + @@ -13068,7 +13068,7 @@ - + @@ -13076,7 +13076,7 @@ - + @@ -13089,7 +13089,7 @@ - + @@ -13099,7 +13099,7 @@ - + @@ -13107,7 +13107,7 @@ - + @@ -13120,7 +13120,7 @@ - + @@ -13130,7 +13130,7 @@ - + @@ -13138,7 +13138,7 @@ - + @@ -13151,7 +13151,7 @@ - + @@ -13161,7 +13161,7 @@ - + @@ -13169,7 +13169,7 @@ - + @@ -13182,7 +13182,7 @@ - + @@ -13192,7 +13192,7 @@ - + @@ -13200,7 +13200,7 @@ - + @@ -13213,7 +13213,7 @@ - + @@ -13223,7 +13223,7 @@ - + @@ -13231,7 +13231,7 @@ - + @@ -13244,7 +13244,7 @@ - + @@ -13254,7 +13254,7 @@ - + @@ -13262,7 +13262,7 @@ - + @@ -13275,7 +13275,7 @@ - + @@ -13285,7 +13285,7 @@ - + @@ -13293,7 +13293,7 @@ - + @@ -13306,7 +13306,7 @@ - + @@ -13316,7 +13316,7 @@ - + @@ -13324,7 +13324,7 @@ - + @@ -13337,7 +13337,7 @@ - + @@ -13347,7 +13347,7 @@ - + @@ -13355,7 +13355,7 @@ - + @@ -13368,7 +13368,7 @@ - + @@ -13378,7 +13378,7 @@ - + @@ -13386,7 +13386,7 @@ - + @@ -13399,7 +13399,7 @@ - + @@ -13409,7 +13409,7 @@ - + @@ -13417,7 +13417,7 @@ - + @@ -13430,7 +13430,7 @@ - + @@ -13440,7 +13440,7 @@ - + @@ -13448,7 +13448,7 @@ - + @@ -13461,7 +13461,7 @@ - + @@ -13471,7 +13471,7 @@ - + @@ -13479,7 +13479,7 @@ - + @@ -13492,7 +13492,7 @@ - + @@ -13502,7 +13502,7 @@ - + @@ -13510,7 +13510,7 @@ - + @@ -13523,7 +13523,7 @@ - + @@ -13533,7 +13533,7 @@ - + @@ -13541,7 +13541,7 @@ - + @@ -13554,7 +13554,7 @@ - + @@ -13564,7 +13564,7 @@ - + @@ -13572,7 +13572,7 @@ - + @@ -13585,7 +13585,7 @@ - + @@ -13595,7 +13595,7 @@ - + @@ -13603,7 +13603,7 @@ - + @@ -13616,7 +13616,7 @@ - + @@ -13626,7 +13626,7 @@ - + @@ -13634,7 +13634,7 @@ - + @@ -13647,7 +13647,7 @@ - + @@ -13657,7 +13657,7 @@ - + @@ -13665,7 +13665,7 @@ - + @@ -13678,7 +13678,7 @@ - + @@ -13688,7 +13688,7 @@ - + @@ -13696,7 +13696,7 @@ - + @@ -13709,7 +13709,7 @@ - + @@ -13719,7 +13719,7 @@ - + @@ -13727,7 +13727,7 @@ - + @@ -13740,7 +13740,7 @@ - + @@ -13750,7 +13750,7 @@ - + @@ -13758,7 +13758,7 @@ - + @@ -13771,7 +13771,7 @@ - + @@ -13781,7 +13781,7 @@ - + @@ -13789,7 +13789,7 @@ - + @@ -13802,7 +13802,7 @@ - + @@ -13812,7 +13812,7 @@ - + @@ -13820,7 +13820,7 @@ - + @@ -13833,7 +13833,7 @@ - + @@ -13843,7 +13843,7 @@ - + @@ -13851,7 +13851,7 @@ - + @@ -13864,7 +13864,7 @@ - + @@ -13874,7 +13874,7 @@ - + @@ -13882,7 +13882,7 @@ - + @@ -13895,7 +13895,7 @@ - + @@ -13905,7 +13905,7 @@ - + @@ -13913,7 +13913,7 @@ - + @@ -13926,7 +13926,7 @@ - + @@ -13936,7 +13936,7 @@ - + @@ -13944,7 +13944,7 @@ - + @@ -13957,7 +13957,7 @@ - + @@ -13967,7 +13967,7 @@ - + @@ -13975,7 +13975,7 @@ - + @@ -13988,7 +13988,7 @@ - + @@ -13998,7 +13998,7 @@ - + @@ -14006,7 +14006,7 @@ - + @@ -14019,7 +14019,7 @@ - + @@ -14029,7 +14029,7 @@ - + @@ -14037,7 +14037,7 @@ - + @@ -14050,7 +14050,7 @@ - + @@ -14060,7 +14060,7 @@ - + @@ -14068,7 +14068,7 @@ - + @@ -14081,7 +14081,7 @@ - + @@ -14091,7 +14091,7 @@ - + @@ -14099,7 +14099,7 @@ - + @@ -14112,7 +14112,7 @@ - + @@ -14122,7 +14122,7 @@ - + @@ -14130,7 +14130,7 @@ - + @@ -14143,7 +14143,7 @@ - + @@ -14153,7 +14153,7 @@ - + @@ -14161,7 +14161,7 @@ - + @@ -14174,7 +14174,7 @@ - + @@ -14184,7 +14184,7 @@ - + @@ -14192,7 +14192,7 @@ - + @@ -14205,38 +14205,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -14246,7 +14215,7 @@ - + @@ -14254,7 +14223,7 @@ - + @@ -14267,7 +14236,7 @@ - + @@ -14277,7 +14246,7 @@ - + @@ -14285,7 +14254,7 @@ - + @@ -14298,7 +14267,7 @@ - + @@ -14308,7 +14277,7 @@ - + @@ -14316,7 +14285,7 @@ - + @@ -14329,69 +14298,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -14401,7 +14308,7 @@ - + @@ -14409,7 +14316,7 @@ - + @@ -14422,7 +14329,7 @@ - + @@ -14432,7 +14339,7 @@ - + @@ -14440,7 +14347,7 @@ - + @@ -14453,7 +14360,7 @@ - + @@ -14463,7 +14370,7 @@ - + @@ -14471,7 +14378,7 @@ - + @@ -14484,7 +14391,7 @@ - + @@ -14494,7 +14401,7 @@ - + @@ -14502,7 +14409,7 @@ - + @@ -14515,7 +14422,7 @@ - + @@ -14525,7 +14432,7 @@ - + @@ -14533,7 +14440,7 @@ - + @@ -14546,7 +14453,7 @@ - + @@ -14556,7 +14463,7 @@ - + @@ -14564,7 +14471,7 @@ - + @@ -14577,7 +14484,7 @@ - + @@ -14587,7 +14494,7 @@ - + @@ -14595,7 +14502,7 @@ - + @@ -14608,7 +14515,7 @@ - + @@ -14618,7 +14525,7 @@ - + @@ -14626,7 +14533,7 @@ - + @@ -14639,7 +14546,7 @@ - + @@ -14649,7 +14556,7 @@ - + @@ -14657,7 +14564,7 @@ - + @@ -14670,38 +14577,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -14711,7 +14587,7 @@ - + @@ -14719,7 +14595,7 @@ - + @@ -14732,38 +14608,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -14773,7 +14618,7 @@ - + @@ -14781,7 +14626,7 @@ - + @@ -14794,7 +14639,7 @@ - + @@ -14804,7 +14649,7 @@ - + @@ -14812,7 +14657,7 @@ - + @@ -14825,7 +14670,7 @@ - + @@ -14835,7 +14680,7 @@ - + @@ -14843,7 +14688,7 @@ - + @@ -14856,7 +14701,7 @@ - + @@ -14866,7 +14711,7 @@ - + @@ -14874,7 +14719,7 @@ - + @@ -14887,7 +14732,7 @@ - + @@ -14897,7 +14742,7 @@ - + @@ -14905,7 +14750,7 @@ - + @@ -14918,7 +14763,7 @@ - + @@ -14928,7 +14773,7 @@ - + @@ -14936,7 +14781,7 @@ - + @@ -14949,7 +14794,7 @@ - + @@ -14959,7 +14804,7 @@ - + @@ -14967,7 +14812,7 @@ - + @@ -14980,7 +14825,7 @@ - + @@ -14990,7 +14835,7 @@ - + @@ -14998,7 +14843,7 @@ - + @@ -15011,7 +14856,7 @@ - + @@ -15021,7 +14866,7 @@ - + @@ -15029,7 +14874,7 @@ - + @@ -15042,7 +14887,7 @@ - + @@ -15052,7 +14897,7 @@ - + @@ -15060,7 +14905,7 @@ - + @@ -15073,7 +14918,7 @@ - + @@ -15083,7 +14928,7 @@ - + @@ -15091,7 +14936,7 @@ - + @@ -15104,7 +14949,7 @@ - + @@ -15114,7 +14959,7 @@ - + @@ -15122,7 +14967,7 @@ - + @@ -15135,7 +14980,7 @@ - + @@ -15145,7 +14990,7 @@ - + @@ -15153,7 +14998,7 @@ - + @@ -15166,7 +15011,7 @@ - + @@ -15176,7 +15021,7 @@ - + @@ -15184,7 +15029,7 @@ - + @@ -15197,7 +15042,7 @@ - + @@ -15207,7 +15052,7 @@ - + @@ -15215,7 +15060,7 @@ - + @@ -15228,7 +15073,7 @@ - + @@ -15238,7 +15083,7 @@ - + @@ -15246,7 +15091,7 @@ - + @@ -15259,7 +15104,7 @@ - + @@ -15269,7 +15114,7 @@ - + @@ -15277,7 +15122,7 @@ - + @@ -15288,12 +15133,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -15303,7 +15303,7 @@ - + @@ -15311,119 +15311,83 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + - + - - - + + + + + + + + + + + @@ -15431,30 +15395,98 @@ - + - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15464,10 +15496,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -15481,7 +15557,295 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15509,43 +15873,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -15559,7 +15887,825 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15595,7 +16741,85 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15655,9 +16879,9 @@ - - - + + + @@ -15667,169 +16891,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -15857,7 +16919,13 @@ - + + + + + + + @@ -15865,43 +16933,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -15929,43 +16961,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -15979,7 +16975,96 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16007,43 +17092,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -16057,745 +17106,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -16823,48 +17134,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -16878,29 +17148,14 @@ - + - - - - - - - - - - - - - - - - - - + + + @@ -16910,25 +17165,10 @@ - - - - - - - - - - - - - - - - - + + - + @@ -16938,173 +17178,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -17125,11 +17203,15 @@ - - + + - + + + + + @@ -17140,44 +17222,32 @@ + + + + + + + + - - - - - + - - - - - + - - - - - - - - - - - - - + - + @@ -17188,10 +17258,6 @@ - - - - @@ -17205,7 +17271,7 @@ - + @@ -17213,39 +17279,51 @@ - + - + - - - - - - - - - - - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + @@ -17261,7 +17339,75 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -17274,7 +17420,7 @@ - + @@ -17285,108 +17431,9 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -17459,7 +17506,7 @@ - + @@ -17472,7 +17519,7 @@ - + @@ -17483,16 +17530,49 @@ - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -17503,9 +17583,9 @@ - + - + @@ -17516,31 +17596,29 @@ - + - + - + - + - - - + - + @@ -17551,9 +17629,9 @@ - + - + From d97886116d00df9dd20115aa64fba66791456e8b Mon Sep 17 00:00:00 2001 From: gallowj Date: Fri, 18 Jun 2021 11:09:46 -0500 Subject: [PATCH 79/93] Adding reflection ang GI probe test data --- .../.src/objects/Test_Sponza_Materials.mb | 3 + .../test_sponza_material_conversion.prefab | 1240 +++++++++++++++++ .../Test_Sponza_Material_Conversion.fbx | 3 + ..._Sponza_Material_Conversion_black.material | 35 + ..._Sponza_Material_Conversion_green.material | 35 + ...onza_Material_Conversion_mat_arch.material | 49 + ...za_Material_Conversion_mat_bricks.material | 54 + ...nza_Material_Conversion_mat_floor.material | 51 + ...onza_Material_Conversion_mat_roof.material | 44 + ...Sponza_Material_Conversion_phong5.material | 35 + ...st_Sponza_Material_Conversion_red.material | 35 + ..._Sponza_Material_Conversion_white.material | 19 + .../TestData/white_latlong_iblskyboxcm.exr | 3 + 13 files changed, 1606 insertions(+) create mode 100644 Gems/AtomContent/Sponza/.src/objects/Test_Sponza_Materials.mb create mode 100644 Gems/AtomContent/Sponza/Assets/Prefabs/test_sponza_material_conversion.prefab create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion.fbx create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_black.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_green.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_arch.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_bricks.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_floor.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_mat_roof.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_phong5.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_red.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/Test_Sponza_Material_Conversion_white.material create mode 100644 Gems/AtomContent/Sponza/Assets/TestData/white_latlong_iblskyboxcm.exr 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 From d907c146824f87db63a575a1739a2d47ab23fcc1 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:11:36 -0700 Subject: [PATCH 80/93] Remove any null entries from AbstractCodeModel::ModAllRoots() LYN-4658 --- .../Grammar/AbstractCodeModel.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) 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; From 7486488b602a3cd27a2a990e90fcf940a0cc3bf8 Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Fri, 18 Jun 2021 09:53:22 -0700 Subject: [PATCH 81/93] Update to PhysX 4.1.2.29882248 (#1411) * Update to PhysX-4.1.2.29882248 * Add maybe_unused attribute for variable not used in the release config --- .../Source/Editor/Attribution/AWSCoreAttributionManager.cpp | 6 ++---- .../3rdParty/Platform/Android/BuiltInPackages_android.cmake | 2 +- cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake | 2 +- cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake | 2 +- .../3rdParty/Platform/Windows/BuiltInPackages_windows.cmake | 2 +- cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp index d667bfb2cf..6edb606a10 100644 --- a/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp +++ b/Gems/AWSCore/Code/Source/Editor/Attribution/AWSCoreAttributionManager.cpp @@ -263,15 +263,13 @@ namespace AWSCore SetApiEndpointAndRegion(config); ServiceAPI::AWSAttributionRequestJob* requestJob = ServiceAPI::AWSAttributionRequestJob::Create( - [this](ServiceAPI::AWSAttributionRequestJob* successJob) + [this]([[maybe_unused]] ServiceAPI::AWSAttributionRequestJob* successJob) { - AZ_UNUSED(successJob); - UpdateLastSend(); AZ_Printf("AWSAttributionManager", "AWSAttribution metric submit success"); }, - [this](ServiceAPI::AWSAttributionRequestJob* failJob) + [this]([[maybe_unused]] ServiceAPI::AWSAttributionRequestJob* failJob) { AZ_Error("AWSAttributionManager", false, "Metrics send error: %s", failJob->error.message.c_str()); }, diff --git a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake index 9f63185ab3..a0b2185190 100644 --- a/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake +++ b/cmake/3rdParty/Platform/Android/BuiltInPackages_android.cmake @@ -25,7 +25,7 @@ ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-android TARGETS fre 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 Lua-5.3.5-rev5-android TARGETS Lua PACKAGE_HASH 1f638e94a17a87fe9e588ea456d5893876094b4db191234380e4c4eb9e06c300) -ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-android TARGETS PhysX PACKAGE_HASH 9c494576c2d4ff04dee5a9e092fcd9d5af4b2845f15ffdfcaabb0dbc5b88a7a9) +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) ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-android TARGETS googletest PACKAGE_HASH 95671be75287a61c9533452835c3647e9c1b30f81b34b43bcb0ec1997cc23894) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-android TARGETS GoogleBenchmark PACKAGE_HASH 20b46e572211a69d7d94ddad1c89ec37bb958711d6ad4025368ac89ea83078fb) diff --git a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake index fcc2ef4fe6..303380a27a 100644 --- a/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake +++ b/cmake/3rdParty/Platform/Linux/BuiltInPackages_linux.cmake @@ -37,7 +37,7 @@ ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-linux ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-linux TARGETS tiff PACKAGE_HASH ae92b4d3b189c42ef644abc5cac865d1fb2eb7cb5622ec17e35642b00d1a0a76) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev4-linux TARGETS AWSNativeSDK PACKAGE_HASH b4db38de49d35a5f7500aed7f4aee5ec511dd3b584ee06fe9097885690191a5d) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-linux TARGETS Lua PACKAGE_HASH 1adc812abe3dd0dbb2ca9756f81d8f0e0ba45779ac85bf1d8455b25c531a38b0) -ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-linux TARGETS PhysX PACKAGE_HASH e3ca36106a8dbf1524709f8bb82d520920ebd3ff3a92672d382efff406c75ee3) +ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-linux TARGETS PhysX PACKAGE_HASH a110249cbef4f266b0002c4ee9a71f59f373040cefbe6b82f1e1510c811edde6) ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-linux TARGETS etc2comp PACKAGE_HASH 9283aa5db5bb7fb90a0ddb7a9f3895317c8ebe8044943124bbb3673a41407430) ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.1-rev1-linux TARGETS mcpp PACKAGE_HASH 0aa713f3f2c156cb2f17d9b800aed8acf9df5ab167c48b679853ecb040da9a67) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-linux TARGETS mikkelsen PACKAGE_HASH 5973b1e71a64633588eecdb5b5c06ca0081f7be97230f6ef64365cbda315b9c8) diff --git a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake index b97209e8f7..d8ab19e649 100644 --- a/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake +++ b/cmake/3rdParty/Platform/Mac/BuiltInPackages_mac.cmake @@ -39,7 +39,7 @@ ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-mac-ios ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-mac-ios TARGETS tiff PACKAGE_HASH a23ae1f8991a29f8e5df09d6d5b00d7768a740f90752cef465558c1768343709) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev3-mac TARGETS AWSNativeSDK PACKAGE_HASH 21920372e90355407578b45ac19580df1463a39a25a867bcd0ffd8b385c8254a) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev6-mac TARGETS Lua PACKAGE_HASH b9079fd35634774c9269028447562c6b712dbc83b9c64975c095fd423ff04c08) -ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-mac TARGETS PhysX PACKAGE_HASH 149f5e9b44bd27291b1c4772f5e89a1e0efa88eef73c7e0b188935ed4d0c4a70) +ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-mac TARGETS PhysX PACKAGE_HASH 5e092a11d5c0a50c4dd99bb681a04b566a4f6f29aa08443d9bffc8dc12c27c8e) ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-mac TARGETS etc2comp PACKAGE_HASH 1966ab101c89db7ecf30984917e0a48c0d02ee0e4d65b798743842b9469c0818) ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.1-rev1-mac TARGETS mcpp PACKAGE_HASH 48a9c5197bf72843fb9ac44825501ee16bbe3e72e086a32b8c9c05bf47db12ab) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-mac TARGETS mikkelsen PACKAGE_HASH 83af99ca8bee123684ad254263add556f0cf49486c0b3e32e6d303535714e505) diff --git a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake index 279731765a..c0b243ee2c 100644 --- a/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake +++ b/cmake/3rdParty/Platform/Windows/BuiltInPackages_windows.cmake @@ -41,7 +41,7 @@ ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-windows ly_associate_package(PACKAGE_NAME tiff-4.2.0.14-windows TARGETS tiff PACKAGE_HASH ab60d1398e4e1e375ec0f1a00cdb1d812a07c0096d827db575ce52dd6d714207) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev3-windows TARGETS AWSNativeSDK PACKAGE_HASH 929873d4252c464620a9d288e41bd5d47c0bd22750aeb3a1caa68a3da8247c48) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-windows TARGETS Lua PACKAGE_HASH 136faccf1f73891e3fa3b95f908523187792e56f5b92c63c6a6d7e72d1158d40) -ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev1-windows TARGETS PhysX PACKAGE_HASH 198bed89d1aae7caaf5dadba24cee56235fe41725d004b64040d4e50d0f3aa1a) +ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-windows TARGETS PhysX PACKAGE_HASH 0c5ffbd9fa588e5cf7643721a7cfe74d0fe448bf82252d39b3a96d06dfca2298) ly_associate_package(PACKAGE_NAME etc2comp-9cd0f9cae0-rev1-windows TARGETS etc2comp PACKAGE_HASH fc9ae937b2ec0d42d5e7d0e9e8c80e5e4d257673fb33bc9b7d6db76002117123) ly_associate_package(PACKAGE_NAME mcpp-2.7.2_az.1-rev1-windows TARGETS mcpp PACKAGE_HASH 511672598fa319bfb8db87f965b59abff1620bb7c1dcf7669e039a8acd8d3ff8) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-windows TARGETS mikkelsen PACKAGE_HASH 872c4d245a1c86139aa929f2b465b63ea4ea55b04ced50309135dd4597457a4e) diff --git a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake index e742f0c463..649780b28e 100644 --- a/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake +++ b/cmake/3rdParty/Platform/iOS/BuiltInPackages_ios.cmake @@ -26,7 +26,7 @@ ly_associate_package(PACKAGE_NAME freetype-2.10.4.14-mac-ios TARGETS freetyp ly_associate_package(PACKAGE_NAME tiff-4.2.0.15-mac-ios TARGETS tiff PACKAGE_HASH a23ae1f8991a29f8e5df09d6d5b00d7768a740f90752cef465558c1768343709) ly_associate_package(PACKAGE_NAME AWSNativeSDK-1.7.167-rev3-ios TARGETS AWSNativeSDK PACKAGE_HASH 1246219a213ccfff76b526011febf521586d44dbc1753e474f8fb5fd861654a4) ly_associate_package(PACKAGE_NAME Lua-5.3.5-rev5-ios TARGETS Lua PACKAGE_HASH c2d3c4e67046c293049292317a7d60fdb8f23effeea7136aefaef667163e5ffe) -ly_associate_package(PACKAGE_NAME PhysX-4.1.0.25992954-rev2-ios TARGETS PhysX PACKAGE_HASH 27e68bd90915dbd0bd5f26cae714e9a137f6b1aa8a8e0bf354a4a9176aa553d5) +ly_associate_package(PACKAGE_NAME PhysX-4.1.2.29882248-rev3-ios TARGETS PhysX PACKAGE_HASH b1bbc1fc068d2c6e1eb18eecd4e8b776adc516833e8da3dcb1970cef2a8f0cbd) ly_associate_package(PACKAGE_NAME mikkelsen-1.0.0.4-ios TARGETS mikkelsen PACKAGE_HASH 976aaa3ccd8582346132a10af253822ccc5d5bcc9ea5ba44d27848f65ee88a8a) ly_associate_package(PACKAGE_NAME googletest-1.8.1-rev4-ios TARGETS googletest PACKAGE_HASH 2f121ad9784c0ab73dfaa58e1fee05440a82a07cc556bec162eeb407688111a7) ly_associate_package(PACKAGE_NAME googlebenchmark-1.5.0-rev2-ios TARGETS GoogleBenchmark PACKAGE_HASH c2ffaed2b658892b1bcf81dee4b44cd1cb09fc78d55584ef5cb8ab87f2d8d1ae) From 2bc36aa6c67e6d7b59507baaa55f36aca05eed6d Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Fri, 18 Jun 2021 13:05:35 -0500 Subject: [PATCH 82/93] [SPEC-5991] Removing ImageHDR.h/.cpp. These files are no longer needed and created a licensing issue. (#1420) The only place this code was referenced was in using textured tooltips, if the texture used for that tooltip was a .hdr file. However, the few .hdr files in all of o3de are Atom material / lighting related - definitely not used for tooltips. It's likely bitmap tooltips in general are not used at all anymore, so more code could probably be ripped out, but this solves the immediate problem without making too many changes. --- Code/Sandbox/Editor/Util/ImageHDR.cpp | 460 --------------------- Code/Sandbox/Editor/Util/ImageHDR.h | 22 - Code/Sandbox/Editor/Util/ImageUtil.cpp | 5 - Code/Sandbox/Editor/editor_lib_files.cmake | 2 - 4 files changed, 489 deletions(-) delete mode 100644 Code/Sandbox/Editor/Util/ImageHDR.cpp delete mode 100644 Code/Sandbox/Editor/Util/ImageHDR.h 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/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index dc9d794021..6adbef72b1 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 From 4d90b7cfb60a206149c31bd6f875debb9fadfd20 Mon Sep 17 00:00:00 2001 From: srikappa Date: Fri, 18 Jun 2021 11:19:59 -0700 Subject: [PATCH 83/93] Fix bug with detachPrefab incorrectly replacing old entity aliases in patches --- .../Prefab/Instance/Instance.cpp | 10 +++++++ .../Prefab/Instance/Instance.h | 1 + .../Prefab/PrefabPublicHandler.cpp | 30 +++++++++---------- 3 files changed, 25 insertions(+), 16 deletions(-) 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/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 690d408007..3d02e797cc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -1211,25 +1211,23 @@ namespace AzToolsFramework const auto instanceTemplateId = instancePtr->GetTemplateId(); auto parentContainerEntityId = parentInstance.GetContainerEntityId(); - instancePtr->GetNestedInstances( - [&](AZStd::unique_ptr& nestedInstancePtr) + + instancePtr->DetachNestedInstances( + [&](AZStd::unique_ptr detachedNestedInstance) { - //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& nestedInstanceTemplateDom = + m_prefabSystemComponentInterface->FindTemplateDom(detachedNestedInstance->GetTemplateId()); - PrefabDom linkPatchesCopy; - linkPatchesCopy.CopyFrom(linkPatches->get(), linkPatchesCopy.GetAllocator()); - - RemoveLink(nestedInstancePtr, instanceTemplateId, undoBatch.GetUndoBatch()); - - UpdateLinkPatchesWithNewEntityAliases(linkPatchesCopy, oldEntityAliases, parentInstance); + Instance& nestedInstanceUnderNewParent = parentInstance.AddInstance(AZStd::move(detachedNestedInstance)); - CreateLink(*nestedInstancePtr, parentTemplateId, undoBatch.GetUndoBatch(), - AZStd::move(linkPatchesCopy), true); + PrefabDom nestedInstanceDomUnderNewParent; + m_instanceToTemplateInterface->GenerateDomForInstance( + nestedInstanceDomUnderNewParent, nestedInstanceUnderNewParent); + PrefabDom reparentPatch; + m_instanceToTemplateInterface->GeneratePatch( + reparentPatch, nestedInstanceTemplateDom, nestedInstanceDomUnderNewParent); + + CreateLink(nestedInstanceUnderNewParent, parentTemplateId, undoBatch.GetUndoBatch(), AZStd::move(reparentPatch), true); }); } From c02345fd7148483550d117d518ad8b1ff34d1f40 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 18 Jun 2021 11:57:37 -0700 Subject: [PATCH 84/93] LYN-4657 OSX: Building AutomatedTesting project fails (#1436) * LYN-4657 OSX: Building AutomatedTesting project fails * forgot this file --- .../Tests/Serialization/Json/JsonSerializerConformityTests.h | 2 +- cmake/Platform/Common/Clang/Configurations_clang.cmake | 2 ++ cmake/Platform/Linux/Configurations_linux.cmake | 2 -- cmake/Platform/Mac/Configurations_mac.cmake | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index 4931c203cf..9d7e58dd36 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; + typename TypeParam::Type compare = typename TypeParam::Type{}; if (!this->m_description.AreEqual(*instance, compare)) { auto serializer = this->m_description.CreateSerializer(); diff --git a/cmake/Platform/Common/Clang/Configurations_clang.cmake b/cmake/Platform/Common/Clang/Configurations_clang.cmake index 768b7dd4c2..3e01d5ab2d 100644 --- a/cmake/Platform/Common/Clang/Configurations_clang.cmake +++ b/cmake/Platform/Common/Clang/Configurations_clang.cmake @@ -55,6 +55,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 From 85af8475a5861df4bf2ea8d314f04478aea67498 Mon Sep 17 00:00:00 2001 From: hershey5045 <43485729+hershey5045@users.noreply.github.com> Date: Fri, 18 Jun 2021 11:59:36 -0700 Subject: [PATCH 85/93] Fix postfx camera tags (#1417) --- .../PostFxLayerComponentController.cpp | 18 +++++++++++++++++- .../PostFxLayerComponentController.h | 4 +++- 2 files changed, 20 insertions(+), 2 deletions(-) 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; From acd23698ea38a0c76bcd88f6a5ac0929af922f36 Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Fri, 18 Jun 2021 12:37:37 -0700 Subject: [PATCH 86/93] Prefab Serialization | Remove "Source" parameter from prefab source file (#1387) * When loading a template to memory, store the current Source (potentially overriding what was stored to disk) * Before storing the prefab disk, remove the Source parameter from the Dom (as it's no longer necessary to save it). --- .../AzToolsFramework/AzToolsFramework/Prefab/PrefabLoader.cpp | 4 ++++ .../AzToolsFramework/Prefab/Template/Template.cpp | 4 ++++ 2 files changed, 8 insertions(+) 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/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; } From 04f6c7b90fab686b8e815a53b8a5deec327e3ff5 Mon Sep 17 00:00:00 2001 From: amzn-hdoke <61443753+hdoke@users.noreply.github.com> Date: Fri, 18 Jun 2021 12:39:02 -0700 Subject: [PATCH 87/93] Enable AWSI Automation Tests (#1330) * Add AWS AutomatedTesting levels * Update AWSCoreConfiguration to use default profile * Update lambda name * Add cdk update command before tests run * Update global cdk version before runnign tests. * Add npm update command * More cdk changes * More cdk changes * Shortening project names for cdk * increase timeout for AWSTests * Add comments * Set AWSTests to periodic test suite * Update logic to re install cdk and deploy bootstrap * change version to list to catch version mismatch * Move AWS fixtures to module directory scope * Fixing issues with cdk utils * Add cdk setup to be called on cdk fixture function --- .../Gem/PythonTests/AWS/CMakeLists.txt | 1 + .../aws_metrics_automation_test.py | 62 +- .../AWS/Windows/cdk/{cdk.py => cdk_utils.py} | 163 +- .../client_auth/test_anonymous_credentials.py | 7 +- .../client_auth/test_password_signin.py | 5 +- .../Gem/PythonTests/AWS/common/aws_utils.py | 30 +- .../Gem/PythonTests/AWS/conftest.py | 87 + .../Gem/PythonTests/CMakeLists.txt | 3 +- .../Levels/AWS/ClientAuth/ClientAuth.ly | 3 + .../ConitoAnonymousAuthorization.scriptcanvas | 2358 ++++++ .../AWS/ClientAuth/LevelData/Environment.xml | 1 + .../AWS/ClientAuth/LevelData/TimeOfDay.xml | 1 + .../Levels/AWS/ClientAuth/filelist.xml | 6 + .../Levels/AWS/ClientAuth/level.pak | 3 + .../Levels/AWS/ClientAuth/tags.txt | 12 + .../ClientAuthPasswordSignIn.ly | 3 + .../PasswordSignIn.scriptcanvas | 6642 +++++++++++++++++ .../AWS/ClientAuthPasswordSignIn/filelist.xml | 6 + .../AWS/ClientAuthPasswordSignIn/level.pak | 3 + .../AWS/ClientAuthPasswordSignIn/tags.txt | 12 + .../ClientAuthPasswordSignUp.ly | 3 + .../PasswordSignUp.scriptcanvas | 4408 +++++++++++ .../AWS/ClientAuthPasswordSignUp/filelist.xml | 6 + .../AWS/ClientAuthPasswordSignUp/level.pak | 3 + .../AWS/ClientAuthPasswordSignUp/tags.txt | 12 + .../Levels/AWS/Metrics/Metrics.ly | 3 + .../Levels/AWS/Metrics/Script/Metrics.lua | 79 + .../Levels/AWS/Metrics/filelist.xml | 6 + AutomatedTesting/Levels/AWS/Metrics/level.pak | 3 + AutomatedTesting/Levels/AWS/Metrics/tags.txt | 12 + .../aws_metrics/real_time_data_processing.py | 2 +- 31 files changed, 13813 insertions(+), 132 deletions(-) rename AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/{cdk.py => cdk_utils.py} (59%) create mode 100644 AutomatedTesting/Gem/PythonTests/AWS/conftest.py create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/level.pak create mode 100644 AutomatedTesting/Levels/AWS/ClientAuth/tags.txt create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak create mode 100644 AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt create mode 100644 AutomatedTesting/Levels/AWS/Metrics/Metrics.ly create mode 100644 AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua create mode 100644 AutomatedTesting/Levels/AWS/Metrics/filelist.xml create mode 100644 AutomatedTesting/Levels/AWS/Metrics/level.pak create mode 100644 AutomatedTesting/Levels/AWS/Metrics/tags.txt 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 -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 +# fixture imports from AWS.Windows.resource_mappings.resource_mappings import resource_mappings -from AWS.Windows.cdk.cdk import cdk +from AWS.Windows.cdk.cdk_utils import Cdk +from AWS.common.aws_utils import AwsUtils +from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor +from AWS.common.aws_credentials import aws_credentials from .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"]}'] + 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) + 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/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/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 ) From 1ad6264d0df298b8007e2286741c35723a8e48bc Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Fri, 18 Jun 2021 21:37:15 +0100 Subject: [PATCH 88/93] Using newer version of NvCloth 3rdParty (#1435) --- Gems/NvCloth/Code/Platform/Android/PAL_android.cmake | 2 +- Gems/NvCloth/Code/Platform/Linux/PAL_linux.cmake | 2 +- Gems/NvCloth/Code/Platform/Mac/PAL_mac.cmake | 2 +- Gems/NvCloth/Code/Platform/Windows/PAL_windows.cmake | 2 +- Gems/NvCloth/Code/Platform/iOS/PAL_ios.cmake | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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) From c127a044d41df0c302464989f50db99d51050196 Mon Sep 17 00:00:00 2001 From: hershey5045 <43485729+hershey5045@users.noreply.github.com> Date: Fri, 18 Jun 2021 13:39:11 -0700 Subject: [PATCH 89/93] Enable fog in physical sky component to blend with deferred fog (#1320) --- .../SkyBox/SceneSrg.azsli | 5 ++ .../Common/Assets/Shaders/SkyBox/SkyBox.azsl | 12 +++ .../SkyBox/SkyBoxFeatureProcessorInterface.h | 11 ++- .../Atom/Feature/SkyBox/SkyBoxFogBus.h | 46 ++++++++++ .../Code/Source/CommonSystemComponent.cpp | 3 +- .../Source/SkyBox/SkyBoxFeatureProcessor.cpp | 44 +++++++++- .../Source/SkyBox/SkyBoxFeatureProcessor.h | 13 ++- .../Code/Source/SkyBox/SkyBoxFogSettings.cpp | 83 +++++++++++++++++++ .../Code/Source/SkyBox/SkyBoxFogSettings.h | 38 +++++++++ .../Code/atom_feature_common_files.cmake | 3 + .../SkyBox/PhysicalSkyComponentConfig.h | 5 ++ .../SkyBox/EditorPhysicalSkyComponent.cpp | 6 +- .../SkyBox/HDRiSkyboxComponentController.cpp | 2 +- .../Source/SkyBox/PhysicalSkyComponent.cpp | 4 +- .../SkyBox/PhysicalSkyComponentConfig.cpp | 1 + .../SkyBox/PhysicalSkyComponentController.cpp | 58 +++++++++++-- .../SkyBox/PhysicalSkyComponentController.h | 14 +++- 17 files changed, 335 insertions(+), 13 deletions(-) create mode 100644 Gems/Atom/Feature/Common/Code/Include/Atom/Feature/SkyBox/SkyBoxFogBus.h create mode 100644 Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.cpp create mode 100644 Gems/Atom/Feature/Common/Code/Source/SkyBox/SkyBoxFogSettings.h 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/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/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/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; From cbeafe29d324060e2ee3e1c4142250d28afed9ff Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Fri, 18 Jun 2021 14:14:42 -0700 Subject: [PATCH 90/93] Avoid serializing `size_t` in EMotionFX code (#1423) `size_t` is a typedef that is sized differently on different platforms. Instead, use `AZ::u64`, which is large enough to hold all platforms' `size_t` types but is a fixed size, to avoid size mismatches per platform. --- .../Code/EMotionFX/CommandSystem/Source/ColliderCommands.cpp | 3 ++- .../Code/EMotionFX/CommandSystem/Source/ColliderCommands.h | 2 +- .../EMotionFX/Pipeline/SceneAPIExt/Rules/MorphTargetRule.h | 2 +- .../EMotionFX/Pipeline/SceneAPIExt/Rules/MotionAdditiveRule.h | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) 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 From f91ba1a80b8a7a2aef3231a7c6737c7f805c75a1 Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Fri, 18 Jun 2021 16:09:18 -0700 Subject: [PATCH 91/93] Minor pre-license update cleanup of files (#1437) - Remove legacy CryEngine.tip file - Remove legacy WAF files - Renamed Lumberyard to O3DE - Updating "Amazon.com" to "Open 3D Foundation" --- Assets/Editor/Editor.tip | 34 ------------------- Code/Sandbox/Editor/EditorVersion.rc | 6 ++-- .../AtomFont/Code/Source/AtomFont.rc | 4 +-- .../Code/multiplayercompression.waf_files | 22 ------------ .../multiplayercompression_tests.waf_files | 7 ---- Gems/MultiplayerCompression/Code/wscript | 23 ------------- 6 files changed, 5 insertions(+), 91 deletions(-) delete mode 100644 Assets/Editor/Editor.tip delete mode 100644 Gems/MultiplayerCompression/Code/multiplayercompression.waf_files delete mode 100644 Gems/MultiplayerCompression/Code/multiplayercompression_tests.waf_files delete mode 100644 Gems/MultiplayerCompression/Code/wscript 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/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/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/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'], - ) From 556d607a5e3a833a1eb7f52ec38530f4b3bbd0bf Mon Sep 17 00:00:00 2001 From: amzn-hdoke <61443753+hdoke@users.noreply.github.com> Date: Fri, 18 Jun 2021 16:30:49 -0700 Subject: [PATCH 92/93] Make AWSCore.Editor tests windows only (#1410) --- Gems/AWSCore/Code/CMakeLists.txt | 1 + .../AWSCoreEditorSystemComponentTest.cpp | 0 .../awscore_editor_tests_linux_files.cmake | 13 +++++++++++ .../Mac/awscore_editor_tests_mac_files.cmake | 13 +++++++++++ .../awscore_editor_tests_windows_files.cmake | 22 +++++++++++++++++++ .../Code/awscore_editor_tests_files.cmake | 9 -------- .../build/Platform/Linux/build_config.json | 4 ++-- 7 files changed, 51 insertions(+), 11 deletions(-) rename Gems/AWSCore/Code/Tests/{ => Editor}/AWSCoreEditorSystemComponentTest.cpp (100%) create mode 100644 Gems/AWSCore/Code/Tests/Editor/Platform/Linux/awscore_editor_tests_linux_files.cmake create mode 100644 Gems/AWSCore/Code/Tests/Editor/Platform/Mac/awscore_editor_tests_mac_files.cmake create mode 100644 Gems/AWSCore/Code/Tests/Editor/Platform/Windows/awscore_editor_tests_windows_files.cmake 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/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json index 903ac52568..9baa4d6702 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": { From ada63089b5d5f00f8ccbec22e34c4a1a2b5b2d5f Mon Sep 17 00:00:00 2001 From: Doug McDiarmid Date: Sat, 19 Jun 2021 01:30:36 -0700 Subject: [PATCH 93/93] Changed FullScreenTrianglePass::FrameBegin to use FramePrepareParams viewport and scissor states if they are set. Changed ReflectionScreenSpaceBlurChildPass to set the viewport and scissor states. --- .../ReflectionScreenSpaceBlurChildPass.cpp | 3 +++ .../RPI.Public/Pass/FullscreenTrianglePass.cpp | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) 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/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/FullscreenTrianglePass.cpp index aee4fc4f48..67a6fcaa5b 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); }