From 6eddf39effc6c6160bfe9f90bb7154aa4a2fcb7f Mon Sep 17 00:00:00 2001 From: jonbeer Date: Mon, 3 May 2021 15:27:26 -0700 Subject: [PATCH 01/24] Adding additional PhysX tests for work with Prefabs --- .../Physics/ShapeConfiguration.cpp | 18 +++ Gems/PhysX/Code/CMakeLists.txt | 1 + .../Code/Tests/PhysXColliderPrefabTests.cpp | 126 ++++++++++++++++++ Gems/PhysX/Code/physx_tests_files.cmake | 1 + 4 files changed, 146 insertions(+) create mode 100644 Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp index f01e42a443..617fd026b6 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp @@ -32,6 +32,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Radius", &SphereShapeConfiguration::m_radius) @@ -60,6 +63,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Configuration", &BoxShapeConfiguration::m_dimensions) @@ -88,6 +94,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Height", &CapsuleShapeConfiguration::m_height) @@ -137,6 +146,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("PhysicsAsset", &PhysicsAssetShapeConfiguration::m_asset) @@ -169,6 +181,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Scale", &NativeShapeConfiguration::m_nativeShapeScale) @@ -192,6 +207,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("CookedData", &CookedMeshShapeConfiguration::m_cookedData) diff --git a/Gems/PhysX/Code/CMakeLists.txt b/Gems/PhysX/Code/CMakeLists.txt index ac5fd902c2..65fafcf88b 100644 --- a/Gems/PhysX/Code/CMakeLists.txt +++ b/Gems/PhysX/Code/CMakeLists.txt @@ -45,6 +45,7 @@ ly_add_target( ${physx_dependency} AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework Legacy::CryCommon Gem::LmbrCentral ) diff --git a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp new file mode 100644 index 0000000000..d489ac2990 --- /dev/null +++ b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp @@ -0,0 +1,126 @@ +/* +* 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +namespace PhysX +{ + class PhysXColliderPrefabTest + : public ::testing::Test + { + protected: + void SetUp() override + { + + } + + void TearDown() override + { + + } + + + }; + + TEST_F(PhysXColliderPrefabTest, JsonStoreAndLoadPhysicsObjectsWithPrefabTest) + { + AzToolsFramework::Prefab::PrefabDom prefabDom; + + //material selection + Physics::MaterialSelection materialSelection; + AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), materialSelection); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Material Selection", prefabDom); + + Physics::MaterialSelection newSelection; + AZ::JsonSerialization::Load(newSelection, prefabDom); + + EXPECT_EQ(materialSelection.GetMaterialId(), newSelection.GetMaterialId()); + + //collider configuration + Physics::ColliderConfiguration colliderConfig; + AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfig); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); + + Physics::ColliderConfiguration newConfig; + AZ::JsonSerialization::Load(newConfig, prefabDom); + + EXPECT_EQ(colliderConfig.m_collisionLayer, newConfig.m_collisionLayer); + + //shared pointer - collider configuration - defaults only + auto colliderConfigPtr = AZStd::make_shared(); + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfigPtr); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); + + colliderConfigPtr = nullptr; + AZ::JsonSerialization::Load(colliderConfigPtr, prefabDom); + + EXPECT_NE(nullptr, colliderConfigPtr); + + //shared pointer - collider configuration - non default + auto updatedColliderConfigPtr = AZStd::make_shared(); + updatedColliderConfigPtr->m_isTrigger = true; + AZ::JsonSerializationResult::ResultCode result2 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedColliderConfigPtr); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); + + updatedColliderConfigPtr = nullptr; + AZ::JsonSerialization::Load(updatedColliderConfigPtr, prefabDom); + + EXPECT_NE(nullptr, updatedColliderConfigPtr); + + //shared pointer - shape configuration - defaults only + auto shapeConfigPtr = AZStd::make_shared(); + AZ::JsonSerializationResult::ResultCode result3 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeConfigPtr); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Shape Configuration", prefabDom); + + shapeConfigPtr = nullptr; + AZ::JsonSerialization::Load(shapeConfigPtr, prefabDom); + + EXPECT_NE(nullptr, shapeConfigPtr); + + //shared pointer - shape configuration - non default + auto updatedShapeConfigPtr = AZStd::make_shared(); + updatedShapeConfigPtr->m_radius = 2.0f; + AZ::JsonSerializationResult::ResultCode result4 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedShapeConfigPtr); + + AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Shape Configuration", prefabDom); + + updatedShapeConfigPtr = nullptr; + AZ::JsonSerialization::Load(updatedShapeConfigPtr, prefabDom); + + EXPECT_NE(nullptr, updatedColliderConfigPtr); + } +} diff --git a/Gems/PhysX/Code/physx_tests_files.cmake b/Gems/PhysX/Code/physx_tests_files.cmake index 406aed64a7..182ff6a625 100644 --- a/Gems/PhysX/Code/physx_tests_files.cmake +++ b/Gems/PhysX/Code/physx_tests_files.cmake @@ -25,6 +25,7 @@ set(FILES Tests/PhysXForceRegionTest.cpp Tests/PhysXMaterialLibraryTest.cpp Tests/PhysXCollisionFilteringTest.cpp + Tests/PhysXColliderPrefabTests.cpp Tests/PhysXJointsTest.cpp Tests/PhysXSceneTests.cpp Tests/PhysXSceneQueryTests.cpp From 3b8264016ab5ef9a88256d49f47fbc447012b831 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Tue, 4 May 2021 15:06:34 -0700 Subject: [PATCH 02/24] Updating testing --- .../Code/Tests/PhysXColliderPrefabTests.cpp | 157 ++++++++++++------ 1 file changed, 110 insertions(+), 47 deletions(-) diff --git a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp index d489ac2990..f6a913b61d 100644 --- a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp @@ -13,12 +13,12 @@ #include #include + #include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -26,101 +26,164 @@ #include #include #include -#include -#include -#include -#include namespace PhysX { - class PhysXColliderPrefabTest + class PhysXColliderPrefabTests : public ::testing::Test { protected: - void SetUp() override - { - - } - - void TearDown() override - { - - } - - }; - TEST_F(PhysXColliderPrefabTest, JsonStoreAndLoadPhysicsObjectsWithPrefabTest) + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_ValuesNotNull) { + //create a prefab for storing data AzToolsFramework::Prefab::PrefabDom prefabDom; //material selection Physics::MaterialSelection materialSelection; - AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), materialSelection); + AZ::JsonSerializationResult::ResultCode result + = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), materialSelection); - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Material Selection", prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); Physics::MaterialSelection newSelection; - AZ::JsonSerialization::Load(newSelection, prefabDom); + result = AZ::JsonSerialization::Load(newSelection, prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_EQ(materialSelection.GetMaterialId(), newSelection.GetMaterialId()); //collider configuration Physics::ColliderConfiguration colliderConfig; - AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfig); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfig); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); Physics::ColliderConfiguration newConfig; - AZ::JsonSerialization::Load(newConfig, prefabDom); + result = AZ::JsonSerialization::Load(newConfig, prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_EQ(colliderConfig.m_collisionLayer, newConfig.m_collisionLayer); + } + + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_PointersNotNull) + { + //create a prefab for storing data + AzToolsFramework::Prefab::PrefabDom prefabDom; //shared pointer - collider configuration - defaults only auto colliderConfigPtr = AZStd::make_shared(); AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfigPtr); - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); colliderConfigPtr = nullptr; - AZ::JsonSerialization::Load(colliderConfigPtr, prefabDom); + result = AZ::JsonSerialization::Load(colliderConfigPtr, prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_NE(nullptr, colliderConfigPtr); + //shared pointer - shape configuration - defaults only + auto shapeConfigPtr = AZStd::make_shared(); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeConfigPtr); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + + shapeConfigPtr = nullptr; + result = AZ::JsonSerialization::Load(shapeConfigPtr, prefabDom); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + EXPECT_NE(nullptr, shapeConfigPtr); + + + } + + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_NonDefaultPhysicsTypes_PointersNotNull) + { + //create a prefab for storing data + AzToolsFramework::Prefab::PrefabDom prefabDom; + //shared pointer - collider configuration - non default auto updatedColliderConfigPtr = AZStd::make_shared(); updatedColliderConfigPtr->m_isTrigger = true; - AZ::JsonSerializationResult::ResultCode result2 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedColliderConfigPtr); + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedColliderConfigPtr); - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Collider Configuration", prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); updatedColliderConfigPtr = nullptr; - AZ::JsonSerialization::Load(updatedColliderConfigPtr, prefabDom); + result = AZ::JsonSerialization::Load(updatedColliderConfigPtr, prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_NE(nullptr, updatedColliderConfigPtr); - //shared pointer - shape configuration - defaults only - auto shapeConfigPtr = AZStd::make_shared(); - AZ::JsonSerializationResult::ResultCode result3 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeConfigPtr); - - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Shape Configuration", prefabDom); - - shapeConfigPtr = nullptr; - AZ::JsonSerialization::Load(shapeConfigPtr, prefabDom); - - EXPECT_NE(nullptr, shapeConfigPtr); - //shared pointer - shape configuration - non default auto updatedShapeConfigPtr = AZStd::make_shared(); updatedShapeConfigPtr->m_radius = 2.0f; - AZ::JsonSerializationResult::ResultCode result4 = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedShapeConfigPtr); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedShapeConfigPtr); - AzToolsFramework::Prefab::PrefabDomUtils::PrintPrefabDomValue("Shape Configuration", prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); updatedShapeConfigPtr = nullptr; - AZ::JsonSerialization::Load(updatedShapeConfigPtr, prefabDom); + result = AZ::JsonSerialization::Load(updatedShapeConfigPtr, prefabDom); + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_NE(nullptr, updatedColliderConfigPtr); } + + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsColliderComponents_PointersNotNull) + { + //create a prefab for storing data + AzToolsFramework::Prefab::PrefabDom prefabDom; + + //shared pointer - box collider - defaults only + auto boxColliderPtr = AZStd::make_shared(); + AZ::JsonSerializationResult::ResultCode result + = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), boxColliderPtr); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + + boxColliderPtr = nullptr; + result = AZ::JsonSerialization::Load(boxColliderPtr, prefabDom); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + EXPECT_NE(nullptr, boxColliderPtr); + + //shared pointer - sphere collider - defaults only + auto sphereColliderPtr = AZStd::make_shared(); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), sphereColliderPtr); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + + sphereColliderPtr = nullptr; + result = AZ::JsonSerialization::Load(sphereColliderPtr, prefabDom); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + EXPECT_NE(nullptr, sphereColliderPtr); + + //shared pointer - capsule collider - defaults only + auto capsuleColliderPtr = AZStd::make_shared(); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), capsuleColliderPtr); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + + capsuleColliderPtr = nullptr; + result = AZ::JsonSerialization::Load(capsuleColliderPtr, prefabDom); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + EXPECT_NE(nullptr, capsuleColliderPtr); + + //shared pointer - shape collider - defaults only + auto shapeColliderPtr = AZStd::make_shared(); + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeColliderPtr); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + + shapeColliderPtr = nullptr; + result = AZ::JsonSerialization::Load(shapeColliderPtr, prefabDom); + + EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); + EXPECT_NE(nullptr, shapeColliderPtr); + } } From 36e3c80df435b89c14124844741cf947ac7fa3de Mon Sep 17 00:00:00 2001 From: jonbeer Date: Tue, 4 May 2021 15:41:23 -0700 Subject: [PATCH 03/24] Fixing spacing --- Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp index f6a913b61d..4287ce17db 100644 --- a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp @@ -96,8 +96,6 @@ namespace PhysX EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); EXPECT_NE(nullptr, shapeConfigPtr); - - } TEST_F(PhysXColliderPrefabTests, StoreAndLoad_NonDefaultPhysicsTypes_PointersNotNull) From 5e6d058a43434b938c067adbd94b7b643a91c9d3 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Tue, 4 May 2021 18:23:02 -0700 Subject: [PATCH 04/24] Removing default case to fix crash and updating tests --- .../Serialization/Json/JsonDeserializer.cpp | 4 +- .../Code/Tests/PhysXColliderPrefabTests.cpp | 44 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 8d0da9e54a..9e0ab80dd1 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -33,10 +33,10 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } - if (IsExplicitDefault(value)) + /*if (IsExplicitDefault(value)) { return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); - } + }*/ BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) diff --git a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp index 4287ce17db..5748fca931 100644 --- a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp @@ -36,7 +36,7 @@ namespace PhysX protected: }; - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_ValuesNotNull) + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_ValuesEqual) { //create a prefab for storing data AzToolsFramework::Prefab::PrefabDom prefabDom; @@ -130,58 +130,58 @@ namespace PhysX EXPECT_NE(nullptr, updatedColliderConfigPtr); } - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsColliderComponents_PointersNotNull) + TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsColliderComponents_ValuesEqual) { //create a prefab for storing data AzToolsFramework::Prefab::PrefabDom prefabDom; //shared pointer - box collider - defaults only - auto boxColliderPtr = AZStd::make_shared(); + BoxColliderComponent boxColliderComponent; AZ::JsonSerializationResult::ResultCode result - = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), boxColliderPtr); + = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), boxColliderComponent); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - boxColliderPtr = nullptr; - result = AZ::JsonSerialization::Load(boxColliderPtr, prefabDom); + BoxColliderComponent newBoxColliderComponent; + result = AZ::JsonSerialization::Load(newBoxColliderComponent, prefabDom); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, boxColliderPtr); + EXPECT_EQ(newBoxColliderComponent.GetCollisionLayerName(), boxColliderComponent.GetCollisionLayerName()); //shared pointer - sphere collider - defaults only - auto sphereColliderPtr = AZStd::make_shared(); - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), sphereColliderPtr); + SphereColliderComponent sphereColliderComponent; + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), sphereColliderComponent); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - sphereColliderPtr = nullptr; - result = AZ::JsonSerialization::Load(sphereColliderPtr, prefabDom); + SphereColliderComponent newSphereColliderComponent; + result = AZ::JsonSerialization::Load(newSphereColliderComponent, prefabDom); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, sphereColliderPtr); + EXPECT_EQ(newSphereColliderComponent.GetCollisionLayerName(), sphereColliderComponent.GetCollisionLayerName()); //shared pointer - capsule collider - defaults only - auto capsuleColliderPtr = AZStd::make_shared(); - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), capsuleColliderPtr); + CapsuleColliderComponent capsuleColliderComponent; + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), capsuleColliderComponent); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - capsuleColliderPtr = nullptr; - result = AZ::JsonSerialization::Load(capsuleColliderPtr, prefabDom); + CapsuleColliderComponent newCapsuleColliderComponent; + result = AZ::JsonSerialization::Load(newCapsuleColliderComponent, prefabDom); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, capsuleColliderPtr); + EXPECT_EQ(newCapsuleColliderComponent.GetCollisionLayerName(), capsuleColliderComponent.GetCollisionLayerName()); //shared pointer - shape collider - defaults only - auto shapeColliderPtr = AZStd::make_shared(); - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeColliderPtr); + ShapeColliderComponent shapeColliderComponent; + result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeColliderComponent); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - shapeColliderPtr = nullptr; - result = AZ::JsonSerialization::Load(shapeColliderPtr, prefabDom); + ShapeColliderComponent newShapeColliderComponent; + result = AZ::JsonSerialization::Load(newShapeColliderComponent, prefabDom); EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, shapeColliderPtr); + EXPECT_EQ(newShapeColliderComponent.GetCollisionLayerName(), shapeColliderComponent.GetCollisionLayerName()); } } From 7963924b6ac528e710565356862c41efa53566e4 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Tue, 4 May 2021 18:27:09 -0700 Subject: [PATCH 05/24] Removing extra commented code --- .../AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 9e0ab80dd1..88d698b352 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -33,11 +33,6 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } - /*if (IsExplicitDefault(value)) - { - return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); - }*/ - BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { From 790e41f675e9a2d4ec28c6560493e7dc699d65a1 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 May 2021 14:21:53 -0700 Subject: [PATCH 06/24] Reverted previous fix. --- .../AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 88d698b352..8d0da9e54a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -33,6 +33,11 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } + if (IsExplicitDefault(value)) + { + return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); + } + BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { From 6ad135f35c2ea50dc86a3905aac23fc743a04903 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 May 2021 16:41:54 -0700 Subject: [PATCH 07/24] Fix for smart pointers being loaded through the main load point with a default JSON object. --- .../Serialization/Json/BaseJsonSerializer.cpp | 5 ++++ .../Serialization/Json/BaseJsonSerializer.h | 12 ++++++++- .../Serialization/Json/JsonDeserializer.cpp | 26 +++++++++++++------ .../Json/SmartPointerSerializer.cpp | 5 ++++ .../Json/SmartPointerSerializer.h | 2 ++ 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 6c67fd284a..822fc12097 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -208,6 +208,11 @@ namespace AZ // BaseJsonSerializer // + BaseJsonSerializer::OperationFlags BaseJsonSerializer::GetOperationsFlags() const + { + return OperationFlags::None; + } + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading(void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, Flags flags) { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index f6ced44583..6664b16487 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -163,11 +163,17 @@ namespace AZ enum Flags { - None = 0, //! No extra flags. + 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. }; + 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. + }; + virtual ~BaseJsonSerializer() = default; //! Transforms the data from the rapidjson Value to outputValue, if the conversion is possible and supported. @@ -180,6 +186,9 @@ namespace AZ virtual JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) = 0; + //! Returns the operation flags which tells the Json Serialization how this custom json serializer can be used. + virtual OperationFlags GetOperationsFlags() const; + protected: //! Continues loading of a (sub)value. Use this function to load member variables for instance. This is more optimal than //! directly calling the json serialization. @@ -239,5 +248,6 @@ namespace AZ }; AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::Flags) + AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::OperationFlags) } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 8d0da9e54a..b194a48f6e 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -33,17 +33,17 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } - if (IsExplicitDefault(value)) - { - return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); - } - BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { - return serializer->Load(object, typeId, value, context); + bool isExplicitDefault = IsExplicitDefault(value); + bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == + BaseJsonSerializer::OperationFlags::ManualDefault; + return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) + ? serializer->Load(object, typeId, value, context) + : context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); } - + const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId); if (!classData) { @@ -56,9 +56,19 @@ namespace AZ serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()); if (serializer) { - return serializer->Load(object, typeId, value, context); + bool isExplicitDefault = IsExplicitDefault(value); + bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == + BaseJsonSerializer::OperationFlags::ManualDefault; + return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) + ? serializer->Load(object, typeId, value, context) + : context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); } } + + if (IsExplicitDefault(value)) + { + return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); + } if (classData->m_azRtti && (classData->m_azRtti->GetTypeTraits() & AZ::TypeTraits::is_enum) == AZ::TypeTraits::is_enum) { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp index 9e707f8644..2bd66e9a2a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp @@ -159,4 +159,9 @@ namespace AZ return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "Successfully processed smart pointer." : "A problem occurred while processing a smart pointer."); } + + BaseJsonSerializer::OperationFlags JsonSmartPointerSerializer::GetOperationsFlags() const + { + return OperationFlags::ManualDefault; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h index 8c550cb824..9a0cf61be9 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h @@ -28,5 +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; }; } // namespace AZ From ec52e514762814ebfaa6431ae04c2682abcb5d15 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 May 2021 17:22:57 -0700 Subject: [PATCH 08/24] Additional unit tests for the Json Serialization to make sure custom json serializer work if they're the first used through the higher Load/Store calls. --- .../AzCore/Tests/AssetJsonSerializerTests.cpp | 5 + .../Json/JsonSerializerConformityTests.h | 118 ++++++++++++++++-- .../Json/SmartPointerSerializerTests.cpp | 21 +++- 3 files changed, 131 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index a494207850..e44f77b119 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -104,6 +104,11 @@ namespace JsonSerializationTests AZ::AllocatorInstance::Destroy(); } + void Reflect(AZStd::unique_ptr& context) override + { + context->RegisterGenericType(); + } + AZStd::shared_ptr CreateSerializer() override { return AZStd::make_shared(); diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index 4f0825ff1b..fc2c2dede8 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -90,9 +90,14 @@ namespace JsonSerializationTests virtual ~JsonSerializerConformityTestDescriptor() = default; virtual AZStd::shared_ptr CreateSerializer() = 0; - + //! Create an instance of the target type with all values set to default. virtual AZStd::shared_ptr CreateDefaultInstance() = 0; + //! Create an instance of the target type that constructed with default constructor. + //! This will be the same instance that Json Serialization creates for dynamic types. Typically it's the same + //! as from CreateDefaultInstance(), except of types, such as pointers, that need to do minimal (de)serialization + //! to initialize an object. + virtual AZStd::shared_ptr CreateDefaultConstructedInstance() { return CreateDefaultInstance(); } //! Create an instance of the target type with some values set and some kept on defaults. //! If the target type doesn't support partial specialization this can be ignored and //! tests for partial support will be skipped. @@ -316,10 +321,10 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); - ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*original), + ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); if (this->m_features.m_mandatoryFields.empty()) @@ -339,6 +344,42 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.SupportsJsonType(rapidjson::kObjectType)) + { + this->m_jsonDocument->Parse("{}"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); + auto original = this->m_description.CreateDefaultInstance(); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load( + instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings); + + if (this->m_features.m_mandatoryFields.empty()) + { + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + } + else + { + EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); + bool validProcessing = + result.GetProcessing() == Processing::Altered || + result.GetProcessing() == Processing::PartialAlter; + EXPECT_TRUE(validProcessing); + } + EXPECT_TRUE(this->m_description.AreEqual(*original, *instance)); + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults) { using namespace AZ::JsonSerializationResult; @@ -349,7 +390,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); this->m_deserializationSettings->m_clearContainers = false; @@ -384,7 +425,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); this->m_deserializationSettings->m_clearContainers = true; @@ -488,7 +529,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreateFullySetInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), @@ -499,6 +540,28 @@ namespace JsonSerializationTests EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare)); } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance) + { + using namespace AZ::JsonSerializationResult; + + AZStd::string_view json = this->m_description.GetJsonFor_Load_DeserializeFullySetInstance(); + 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(); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings); + + 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_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported) { using namespace AZ::JsonSerializationResult; @@ -518,7 +581,7 @@ namespace JsonSerializationTests ASSERT_NE(this->m_jsonDocument->MemberEnd(), memberToErase); this->m_jsonDocument->RemoveMember(memberToErase); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); @@ -546,7 +609,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreatePartialDefaultInstance(); ASSERT_NE(nullptr, compare); @@ -567,7 +630,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); AZ::ScopedContextReporter reporter(*this->m_jsonDeserializationContext, [](AZStd::string_view message, ResultCode result, AZStd::string_view path) -> ResultCode @@ -604,7 +667,7 @@ namespace JsonSerializationTests } auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreateFullySetInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), @@ -635,7 +698,7 @@ namespace JsonSerializationTests } auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); @@ -693,6 +756,36 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned) + { + using namespace AZ::JsonSerializationResult; + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateDefaultInstance(); + rapidjson::Value convertedValue = this->CreateExplicitDefault(); + + AZ::JsonSerializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Store( + convertedValue, this->m_jsonDocument->GetAllocator(), instance.get(), instance.get(), azrtti_typeid(*instance), settings); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + if (convertedValue.IsObject() && !this->m_features.m_mandatoryFields.empty()) + { + ASSERT_EQ(convertedValue.MemberCount(), this->m_features.m_mandatoryFields.size()); + for (const AZStd::string& mandatoryField : this->m_features.m_mandatoryFields) + { + EXPECT_NE(convertedValue.MemberEnd(), convertedValue.FindMember(mandatoryField.c_str())); + } + } + else + { + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + this->Expect_ExplicitDefault(convertedValue); + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeWithDefaultsKept_FullyWrittenJson) { using namespace AZ::JsonSerializationResult; @@ -937,11 +1030,13 @@ namespace JsonSerializationTests Load_DeserializeUnreflectedType_ReturnsUnsupported, Load_DeserializeEmptyObject_SucceedsAndObjectMatchesDefaults, + Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearEnabled_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearedTarget_SucceedsAndObjectMatchesDefaults, Load_InterruptClearingTarget_ContainerIsNotCleared, Load_DeserializeFullySetInstance_SucceedsAndObjectMatchesFullySetInstance, + Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance, Load_DeserializePartialInstance_SucceedsAndObjectMatchesParialInstance, Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported, Load_InsertAdditionalData_SucceedsAndObjectMatchesFullySetInstance, @@ -950,6 +1045,7 @@ namespace JsonSerializationTests Store_SerializeUnreflectedType_ReturnsUnsupported, Store_SerializeDefaultInstance_EmptyJsonReturned, + Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned, Store_SerializeWithDefaultsKept_FullyWrittenJson, Store_SerializeFullySetInstance_StoredSuccessfullyAndJsonMatches, Store_SerializeWithoutDefault_StoredSuccessfullyAndJsonMatches, diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp index 2fc131aae2..75391d81d4 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp @@ -32,6 +32,11 @@ namespace JsonSerializationTests return AZStd::make_shared(); } + AZStd::shared_ptr CreateDefaultConstructedInstance() override + { + return AZStd::make_shared(); + } + void Reflect(AZStd::unique_ptr& context) override { context->RegisterGenericType(); @@ -228,13 +233,19 @@ namespace JsonSerializationTests public: using SmartPointer = typename SmartPointerSimpleDerivedClassTestDescription::SmartPointer; - AZStd::shared_ptr CreateDefaultInstance() override + // This test is specific for derived classes being used as a default value. + AZStd::shared_ptr CreateDefaultConstructedInstance() override { auto result = AZStd::make_shared(); *result = SmartPointer(aznew SimpleInheritence()); return result; } + AZStd::shared_ptr CreateDefaultInstance() override + { + return CreateDefaultConstructedInstance(); + } + AZStd::string_view GetJsonForPartialDefaultInstance() override { return R"( @@ -386,13 +397,19 @@ namespace JsonSerializationTests public: using SmartPointer = typename SmartPointerComplexDerivedClassTestDescription::SmartPointer; - AZStd::shared_ptr CreateDefaultInstance() override + // This test is specific for derived classes being used as a default value. + AZStd::shared_ptr CreateDefaultConstructedInstance() override { auto result = AZStd::make_shared(); *result = SmartPointer(aznew MultipleInheritence()); return result; } + AZStd::shared_ptr CreateDefaultInstance() override + { + return CreateDefaultConstructedInstance(); + } + AZStd::string_view GetJsonForPartialDefaultInstance() override { return R"( From 4661da23bb6a17aad4e47c59cc3e2bbd5d1d5516 Mon Sep 17 00:00:00 2001 From: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Date: Wed, 5 May 2021 17:51:22 -0700 Subject: [PATCH 09/24] Cleaned up the flags in the BaseJsonSerializer.h --- .../Serialization/Json/ArraySerializer.cpp | 8 ++-- .../Serialization/Json/BaseJsonSerializer.cpp | 28 ++++++------ .../Serialization/Json/BaseJsonSerializer.h | 24 ++++++----- .../Json/BasicContainerSerializer.cpp | 12 +++--- .../Serialization/Json/MapSerializer.cpp | 8 ++-- .../Json/SmartPointerSerializer.cpp | 7 +-- .../Serialization/Json/TupleSerializer.cpp | 10 +++-- .../Json/BaseJsonSerializerTests.cpp | 43 +++++++++++-------- 8 files changed, 79 insertions(+), 61 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp index 13a25e5aa6..d5a1730364 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp @@ -74,7 +74,7 @@ namespace AZ "Unable to retrieve the correct container information for AZStd::array instance."); } - Flags flags = Flags::None; + ContinuationFlags flags = ContinuationFlags::None; Uuid elementTypeId = Uuid::CreateNull(); auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement) { @@ -82,7 +82,7 @@ namespace AZ elementTypeId = genericClassElement->m_typeId; if (genericClassElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - flags = Flags::ResolvePointer; + flags = ContinuationFlags::ResolvePointer; } return false; }; @@ -161,7 +161,7 @@ namespace AZ "Not enough entries in JSON array to load an AZStd::array from."); } - Flags flags = Flags::None; + ContinuationFlags flags = ContinuationFlags::None; Uuid elementTypeId = Uuid::CreateNull(); auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement) { @@ -169,7 +169,7 @@ namespace AZ elementTypeId = genericClassElement->m_typeId; if (genericClassElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - flags = Flags::ResolvePointer; + flags = ContinuationFlags::ResolvePointer; } return false; }; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 822fc12097..9a426a1e59 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -213,22 +213,23 @@ namespace AZ return OperationFlags::None; } - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context, Flags flags) + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading( + void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags) { - return flags & Flags::ResolvePointer ? - JsonDeserializer::LoadToPointer(object, typeId, value, context) : - JsonDeserializer::Load(object, typeId, value, context); + return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer + ? JsonDeserializer::LoadToPointer(object, typeId, value, context) + : JsonDeserializer::Load(object, typeId, value, context); } - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring(rapidjson::Value& output, const void* object, - const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, Flags flags) + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring( + rapidjson::Value& output, const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, + ContinuationFlags flags) { using namespace JsonSerializationResult; - if (flags & Flags::ReplaceDefault && !context.ShouldKeepDefaults()) + if ((flags & ContinuationFlags::ReplaceDefault) == ContinuationFlags::ReplaceDefault && !context.ShouldKeepDefaults()) { - if (flags & Flags::ResolvePointer) + if ((flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer) { return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, context); } @@ -253,7 +254,7 @@ namespace AZ } } - return flags & Flags::ResolvePointer ? + return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer ? JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, context) : JsonSerializer::Store(output, object, defaultObject, typeId, context); } @@ -270,8 +271,9 @@ namespace AZ return JsonSerializer::StoreTypeName(output, typeId, context); } - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoadingFromJsonObjectField(void* object, const Uuid& typeId, const rapidjson::Value& value, - rapidjson::Value::StringRefType memberName, JsonDeserializerContext& context, Flags flags) + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoadingFromJsonObjectField( + void* object, const Uuid& typeId, const rapidjson::Value& value, rapidjson::Value::StringRefType memberName, + JsonDeserializerContext& context, ContinuationFlags flags) { using namespace JsonSerializationResult; @@ -296,7 +298,7 @@ namespace AZ JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoringToJsonObjectField(rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context, Flags flags) + const Uuid& typeId, JsonSerializerContext& context, ContinuationFlags flags) { using namespace JsonSerializationResult; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index 6664b16487..06c5eda6de 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -161,7 +161,7 @@ namespace AZ public: AZ_RTTI(BaseJsonSerializer, "{7291FFDC-D339-40B5-BB26-EA067A327B21}"); - enum Flags + 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. @@ -196,8 +196,9 @@ namespace AZ //! @param typeId Type id of the object passed in. //! @param value The value in the JSON document where the deserializer will start reading data from. //! @param context The context used during deserialization. Use the value passed in from Load. - JsonSerializationResult::ResultCode ContinueLoading(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueLoading( + void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, + ContinuationFlags flags = ContinuationFlags::None); //! Continues storing of a (sub)value. Use this function to store member variables for instance. This is more optimal than //! directly calling the json serialization. @@ -209,8 +210,9 @@ namespace AZ //! the settings. //! @param typeId The type id of the object and default object. //! @param context The context used during serialization. Use the value passed in from Store. - JsonSerializationResult::ResultCode ContinueStoring(rapidjson::Value& output, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueStoring( + rapidjson::Value& output, const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, + ContinuationFlags flags = ContinuationFlags::None); //! Retrieves the type id from a json object or json string. //! @param typeId The retrieved type id. @@ -231,12 +233,14 @@ namespace AZ const Uuid& typeId, JsonSerializerContext& context); //! Helper function similar to ContinueLoading, but loads the data as a member of 'value' rather than 'value' itself, if it exists. - JsonSerializationResult::ResultCode ContinueLoadingFromJsonObjectField(void* object, const Uuid& typeId, const rapidjson::Value& value, - rapidjson::Value::StringRefType memberName, JsonDeserializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueLoadingFromJsonObjectField( + void* object, const Uuid& typeId, const rapidjson::Value& value, rapidjson::Value::StringRefType memberName, + JsonDeserializerContext& context, ContinuationFlags flags = ContinuationFlags::None); //! Helper function similar to ContinueStoring, but stores the data as a member of 'output' rather than overwriting 'output'. - JsonSerializationResult::ResultCode ContinueStoringToJsonObjectField(rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, - const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueStoringToJsonObjectField( + rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, const void* object, const void* defaultObject, + const Uuid& typeId, JsonSerializerContext& context, ContinuationFlags flags = ContinuationFlags::None); //! Checks if a value is an explicit default. This useful for containers where not storing anything as a default would mean //! a slot wouldn't be used so something has to be added to represent the fully default target. @@ -247,7 +251,7 @@ namespace AZ rapidjson::Value GetExplicitDefault(); }; - AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::Flags) + AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::ContinuationFlags) AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::OperationFlags) } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index c15cb9ef54..400a3b7949 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -75,9 +75,10 @@ namespace AZ auto elementCallback = [this, &array, &retVal, &index, &context] (void* elementPtr, const Uuid& elementId, const SerializeContext::ClassData*, const SerializeContext::ClassElement* classElement) { - Flags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; - flags |= Flags::ReplaceDefault; + ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; + flags |= ContinuationFlags::ReplaceDefault; ScopedContextPath subPath(context, index); index++; @@ -161,8 +162,9 @@ namespace AZ container->EnumTypes(typeEnumCallback); AZ_Assert(classElement, "No class element found for the type in the basic container."); - Flags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; const size_t capacity = container->IsFixedCapacity() ? container->Capacity(outputValue) : std::numeric_limits::max(); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp index fa244d3dae..437a648e1e 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp @@ -215,10 +215,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."); - Flags keyLoadFlags = Flags::None; + ContinuationFlags keyLoadFlags = ContinuationFlags::None; if (keyElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - keyLoadFlags = Flags::ResolvePointer; + keyLoadFlags = ContinuationFlags::ResolvePointer; *reinterpret_cast(keyAddress) = nullptr; } JSR::ResultCode keyResult = ContinueLoading(keyAddress, keyElement->m_typeId, key, context, keyLoadFlags); @@ -231,10 +231,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."); - Flags valueLoadFlags = Flags::None; + ContinuationFlags valueLoadFlags = ContinuationFlags::None; if (valueElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - valueLoadFlags = Flags::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/SmartPointerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp index 2bd66e9a2a..0ab32ac08d 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp @@ -82,7 +82,7 @@ namespace AZ { // If the target type is the same as the type already stored in the smart pointer than no new // instance is created and the existing instance will be updated with the data in the json document. - result = ContinueLoading(instance, elementClassId, inputValue, context, Flags::ResolvePointer); + result = ContinueLoading(instance, elementClassId, inputValue, context, ContinuationFlags::ResolvePointer); return false; } } @@ -93,7 +93,7 @@ namespace AZ // the wrong address. In these cases explicitly reset the smart pointer. This will erase the existing // data but that's fine as it's not being used. void* element = nullptr; - result = ContinueLoading(&element, elementClassId, inputValue, context, Flags::ResolvePointer); + result = ContinueLoading(&element, elementClassId, inputValue, context, ContinuationFlags::ResolvePointer); if (result.GetProcessing() != JSR::Processing::Halted && result.GetProcessing() != JSR::Processing::Altered) { void* elementPtr = container->ReserveElement(instance, nullptr); @@ -155,7 +155,8 @@ namespace AZ container->EnumElements(const_cast(defaultValue), defaultInputCallback); } - JSR::ResultCode result = ContinueStoring(outputValue, inputValue, defaultValue, inputPtrType, context, Flags::ResolvePointer); + JSR::ResultCode result = + ContinueStoring(outputValue, inputValue, defaultValue, inputPtrType, context, ContinuationFlags::ResolvePointer); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "Successfully processed smart pointer." : "A problem occurred while processing a smart pointer."); } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp index 9ea22592bc..5b43cec817 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp @@ -99,8 +99,9 @@ namespace AZ ScopedContextPath subPath(context, i); - Flags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; JSR::ResultCode result = ContinueStoring(elementValues[i], elementAddress, defaultElementAddress, classElements[i]->m_typeId, context, flags); @@ -179,8 +180,9 @@ namespace AZ void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i); AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i); - Flags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; while (arrayIndex < inputValue.Size()) { diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp index 08de21b54f..47e05997fc 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp @@ -119,7 +119,8 @@ namespace JsonSerializationTests int value = 0; int* ptrValue = &value; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -134,7 +135,8 @@ namespace JsonSerializationTests json.Set(42); int* ptrValue = nullptr; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -150,7 +152,8 @@ namespace JsonSerializationTests rapidjson::Value json(rapidjson::kObjectType); int* ptrValue = nullptr; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -165,7 +168,8 @@ namespace JsonSerializationTests rapidjson::Value json(rapidjson::kNullType); int* ptrValue = reinterpret_cast(azmalloc(sizeof(int), alignof(int), AZ::SystemAllocator)); - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_EQ(nullptr, ptrValue); @@ -194,8 +198,8 @@ namespace JsonSerializationTests int value = 42; int* ptrValue = &value; - ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -210,8 +214,9 @@ namespace JsonSerializationTests int value2 = 42; int* defaultPtrValue = &value2; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("{}"); @@ -224,7 +229,7 @@ namespace JsonSerializationTests int* ptrValue = nullptr; ResultCode result = ContinueStoring( - *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -238,8 +243,9 @@ namespace JsonSerializationTests int value2 = 42; int* defaultPtrValue = &value2; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -252,8 +258,9 @@ namespace JsonSerializationTests int* ptrValue = nullptr; int* defaultPtrValue = nullptr; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -265,8 +272,8 @@ namespace JsonSerializationTests int value = 42; - ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ReplaceDefault); + ResultCode result = ContinueStoring( + *m_jsonDocument, &value, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -280,7 +287,7 @@ namespace JsonSerializationTests int* ptrValue = &value; ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ResolvePointer | Flags::ReplaceDefault); + ContinuationFlags::ResolvePointer | ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -293,8 +300,8 @@ namespace JsonSerializationTests int value = 42; AZ::Uuid unknownType("{09AE3CEC-EBFC-41EC-A7F6-949721521716}"); - ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext, - Flags::ReplaceDefault); + ResultCode result = + ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Halted, result.GetProcessing()); } From 52d2998a06cf5230ab05a2493631de95123996b5 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Thu, 6 May 2021 08:14:41 -0700 Subject: [PATCH 10/24] Removing physics test and aztoolsframework dependency --- Gems/PhysX/Code/CMakeLists.txt | 1 - .../Code/Tests/PhysXColliderPrefabTests.cpp | 187 ------------------ Gems/PhysX/Code/physx_tests_files.cmake | 1 - 3 files changed, 189 deletions(-) delete mode 100644 Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp diff --git a/Gems/PhysX/Code/CMakeLists.txt b/Gems/PhysX/Code/CMakeLists.txt index c6122744eb..ec98b0970f 100644 --- a/Gems/PhysX/Code/CMakeLists.txt +++ b/Gems/PhysX/Code/CMakeLists.txt @@ -45,7 +45,6 @@ ly_add_target( ${physx_dependency} AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework Legacy::CryCommon Gem::LmbrCentral ) diff --git a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp b/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp deleted file mode 100644 index 5748fca931..0000000000 --- a/Gems/PhysX/Code/Tests/PhysXColliderPrefabTests.cpp +++ /dev/null @@ -1,187 +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 -#include - -#include -#include - -#include -#include -#include - - -namespace PhysX -{ - class PhysXColliderPrefabTests - : public ::testing::Test - { - protected: - }; - - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_ValuesEqual) - { - //create a prefab for storing data - AzToolsFramework::Prefab::PrefabDom prefabDom; - - //material selection - Physics::MaterialSelection materialSelection; - AZ::JsonSerializationResult::ResultCode result - = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), materialSelection); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - Physics::MaterialSelection newSelection; - result = AZ::JsonSerialization::Load(newSelection, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(materialSelection.GetMaterialId(), newSelection.GetMaterialId()); - - //collider configuration - Physics::ColliderConfiguration colliderConfig; - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfig); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - - Physics::ColliderConfiguration newConfig; - result = AZ::JsonSerialization::Load(newConfig, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(colliderConfig.m_collisionLayer, newConfig.m_collisionLayer); - } - - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsTypes_PointersNotNull) - { - //create a prefab for storing data - AzToolsFramework::Prefab::PrefabDom prefabDom; - - //shared pointer - collider configuration - defaults only - auto colliderConfigPtr = AZStd::make_shared(); - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), colliderConfigPtr); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - colliderConfigPtr = nullptr; - result = AZ::JsonSerialization::Load(colliderConfigPtr, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, colliderConfigPtr); - - //shared pointer - shape configuration - defaults only - auto shapeConfigPtr = AZStd::make_shared(); - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeConfigPtr); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - shapeConfigPtr = nullptr; - result = AZ::JsonSerialization::Load(shapeConfigPtr, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, shapeConfigPtr); - } - - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_NonDefaultPhysicsTypes_PointersNotNull) - { - //create a prefab for storing data - AzToolsFramework::Prefab::PrefabDom prefabDom; - - //shared pointer - collider configuration - non default - auto updatedColliderConfigPtr = AZStd::make_shared(); - updatedColliderConfigPtr->m_isTrigger = true; - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedColliderConfigPtr); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - updatedColliderConfigPtr = nullptr; - result = AZ::JsonSerialization::Load(updatedColliderConfigPtr, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, updatedColliderConfigPtr); - - //shared pointer - shape configuration - non default - auto updatedShapeConfigPtr = AZStd::make_shared(); - updatedShapeConfigPtr->m_radius = 2.0f; - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), updatedShapeConfigPtr); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - updatedShapeConfigPtr = nullptr; - result = AZ::JsonSerialization::Load(updatedShapeConfigPtr, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_NE(nullptr, updatedColliderConfigPtr); - } - - TEST_F(PhysXColliderPrefabTests, StoreAndLoad_DefaultPhysicsColliderComponents_ValuesEqual) - { - //create a prefab for storing data - AzToolsFramework::Prefab::PrefabDom prefabDom; - - //shared pointer - box collider - defaults only - BoxColliderComponent boxColliderComponent; - AZ::JsonSerializationResult::ResultCode result - = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), boxColliderComponent); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - BoxColliderComponent newBoxColliderComponent; - result = AZ::JsonSerialization::Load(newBoxColliderComponent, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(newBoxColliderComponent.GetCollisionLayerName(), boxColliderComponent.GetCollisionLayerName()); - - //shared pointer - sphere collider - defaults only - SphereColliderComponent sphereColliderComponent; - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), sphereColliderComponent); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - SphereColliderComponent newSphereColliderComponent; - result = AZ::JsonSerialization::Load(newSphereColliderComponent, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(newSphereColliderComponent.GetCollisionLayerName(), sphereColliderComponent.GetCollisionLayerName()); - - //shared pointer - capsule collider - defaults only - CapsuleColliderComponent capsuleColliderComponent; - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), capsuleColliderComponent); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - CapsuleColliderComponent newCapsuleColliderComponent; - result = AZ::JsonSerialization::Load(newCapsuleColliderComponent, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(newCapsuleColliderComponent.GetCollisionLayerName(), capsuleColliderComponent.GetCollisionLayerName()); - - //shared pointer - shape collider - defaults only - ShapeColliderComponent shapeColliderComponent; - result = AZ::JsonSerialization::Store(prefabDom, prefabDom.GetAllocator(), shapeColliderComponent); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - - ShapeColliderComponent newShapeColliderComponent; - result = AZ::JsonSerialization::Load(newShapeColliderComponent, prefabDom); - - EXPECT_EQ(AZ::JsonSerializationResult::Processing::Completed, result.GetProcessing()); - EXPECT_EQ(newShapeColliderComponent.GetCollisionLayerName(), shapeColliderComponent.GetCollisionLayerName()); - } -} diff --git a/Gems/PhysX/Code/physx_tests_files.cmake b/Gems/PhysX/Code/physx_tests_files.cmake index 182ff6a625..406aed64a7 100644 --- a/Gems/PhysX/Code/physx_tests_files.cmake +++ b/Gems/PhysX/Code/physx_tests_files.cmake @@ -25,7 +25,6 @@ set(FILES Tests/PhysXForceRegionTest.cpp Tests/PhysXMaterialLibraryTest.cpp Tests/PhysXCollisionFilteringTest.cpp - Tests/PhysXColliderPrefabTests.cpp Tests/PhysXJointsTest.cpp Tests/PhysXSceneTests.cpp Tests/PhysXSceneQueryTests.cpp From dfd0cbb0fdc27ebd1e23f5dd2390c1589caf6bca Mon Sep 17 00:00:00 2001 From: mnaumov Date: Thu, 6 May 2021 13:10:55 -0700 Subject: [PATCH 11/24] Material Editor camera controller zoom respects viewport boundary --- .../Viewport/ViewportMessages.h | 2 ++ .../Viewport/RenderViewportWidget.h | 1 + .../Source/Viewport/RenderViewportWidget.cpp | 5 +++++ .../MaterialEditorViewportInputController.cpp | 17 +++++++++++++++-- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index a9949d382e..07f0964fc7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -246,6 +246,8 @@ namespace AzToolsFramework /// from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse /// position delta. virtual AZStd::optional PreviousViewportCursorScreenPosition() = 0; + /// Is mouse over viewport. + virtual bool IsMouseOver() const = 0; protected: ~ViewportMouseCursorRequests() = default; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index 5dbbf04f1b..cde3dacbc4 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -103,6 +103,7 @@ namespace AtomToolsFramework void EndCursorCapture() override; AzFramework::ScreenPoint ViewportCursorScreenPosition() override; AZStd::optional PreviousViewportCursorScreenPosition() override; + bool IsMouseOver() const override; // AzFramework::WindowRequestBus::Handler ... void SetWindowTitle(const AZStd::string& title) override; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 483b4bc55b..19da0c2b91 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -472,6 +472,11 @@ namespace AtomToolsFramework : AZStd::optional{}; } + bool RenderViewportWidget::IsMouseOver() const + { + return m_mouseOver; + } + void RenderViewportWidget::BeginCursorCapture() { if (m_capturingCursor) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp index 83ec5a41c5..36e4b76cec 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -136,6 +138,11 @@ namespace MaterialEditor const InputChannel::State state = event.m_inputChannel.GetState(); const KeyMask keysOld = m_keys; + bool mouseOver = false; + AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::EventResult( + mouseOver, GetViewportId(), + &AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Events::IsMouseOver); + if (!m_behavior) { EvaluateControlBehavior(); @@ -178,7 +185,10 @@ namespace MaterialEditor } else if (inputChannelId == InputDeviceMouse::Movement::Z) { - m_behavior->MoveZ(event.m_inputChannel.GetValue()); + if (mouseOver) + { + m_behavior->MoveZ(event.m_inputChannel.GetValue()); + } } break; case InputChannel::State::Ended: @@ -222,7 +232,10 @@ namespace MaterialEditor } else if (inputChannelId == InputDeviceMouse::Movement::Z) { - m_behavior->MoveZ(event.m_inputChannel.GetValue()); + if (mouseOver) + { + m_behavior->MoveZ(event.m_inputChannel.GetValue()); + } } break; } From 3751493862a64206b2e6c158879cfcdfc2ec7020 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Thu, 6 May 2021 14:44:19 -0700 Subject: [PATCH 12/24] Fixing ATOM RPI issue with new serialization changes --- .../RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h | 2 ++ .../Material/MaterialFunctorSourceDataSerializer.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h index 59f129b52a..05367d2df1 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h @@ -33,6 +33,8 @@ namespace AZ JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; + + BaseJsonSerializer::OperationFlags GetOperationsFlags() const override; }; } // namespace RPI diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp index a31d97c913..7ac8240faa 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp @@ -127,5 +127,10 @@ namespace AZ return context.Report(result, "Successfully processed MaterialFunctorSourceData."); } + + BaseJsonSerializer::OperationFlags JsonMaterialFunctorSourceDataSerializer::GetOperationsFlags() const + { + return OperationFlags::ManualDefault; + } } // namespace RPI } // namespace AZ From bf38935e85e2ca2a63f44c431aa59117235a1e4e Mon Sep 17 00:00:00 2001 From: jonbeer Date: Thu, 6 May 2021 14:49:44 -0700 Subject: [PATCH 13/24] Updating conformity tests --- .../Json/JsonSerializerConformityTests.h | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index fc2c2dede8..c0f470378c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -1017,6 +1017,20 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared) + { + if (this->m_features.SupportsJsonType(rapidjson::kObjectType)) + { + if (!this->m_features.m_mandatoryFields.empty()) + { + auto serializer = this->m_description.CreateSerializer(); + bool manuallyHandlesDefaults = (serializer->GetOperationsFlags() & AZ::BaseJsonSerializer::OperationFlags::ManualDefault) == + AZ::BaseJsonSerializer::OperationFlags::ManualDefault; + EXPECT_TRUE(manuallyHandlesDefaults); + } + } + } + REGISTER_TYPED_TEST_CASE_P(JsonSerializerConformityTests, Registration_SerializerIsRegisteredWithContext_SerializerFound, @@ -1027,7 +1041,7 @@ namespace JsonSerializationTests Load_InvalidTypeOfArrayType_ReturnsUnsupported, Load_InvalidTypeOfStringType_ReturnsUnsupported, Load_InvalidTypeOfNumberType_ReturnsUnsupported, - + Load_DeserializeUnreflectedType_ReturnsUnsupported, Load_DeserializeEmptyObject_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults, @@ -1053,10 +1067,12 @@ namespace JsonSerializationTests Store_SerializePartialInstance_StoredSuccessfullyAndJsonMatches, Store_SerializeEmptyArray_StoredSuccessfullyAndJsonMatches, Store_HaltedThroughCallback_StoreFailsAndHaltReported, - + StoreLoad_RoundTripWithPartialDefault_IdenticalInstances, StoreLoad_RoundTripWithFullSet_IdenticalInstances, - StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances); + StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances, + + GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared); } // namespace JsonSerializationTests namespace AZ From 550d935b82cfe561287f8afbebf5ad4326fe2289 Mon Sep 17 00:00:00 2001 From: mnaumov Date: Thu, 6 May 2021 15:48:39 -0700 Subject: [PATCH 14/24] Better AP error message when missing image present --- .../Code/Source/Processing/ImageConvert.cpp | 4 +++- Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageConvert.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageConvert.cpp index f63ae4ca77..7b6ec518bc 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageConvert.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Processing/ImageConvert.cpp @@ -851,7 +851,9 @@ namespace ImageProcessingAtom if (preset == nullptr) { - AZ_Assert(false, "preset should always exist"); + AZStd::string uuidStr; + textureSettings.m_preset.ToString(uuidStr); + AZ_Assert(false, "%s cannot find image preset with ID %s.", imageFilePath.c_str(), uuidStr.c_str()); return nullptr; } diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp index aec56af8d8..b5fc329a03 100644 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp +++ b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp @@ -739,7 +739,9 @@ namespace ImageProcessing if (preset == nullptr) { - AZ_Assert(false, "preset should always exist"); + AZStd::string uuidStr; + textureSettings.m_preset.ToString(uuidStr); + AZ_Assert(false, "%s cannot find image preset with ID %s.", imageFilePath.c_str(), uuidStr.c_str()); return nullptr; } From 62a84459ee33f9396aa31e596ec0cf1bfe7d22ff Mon Sep 17 00:00:00 2001 From: daimini Date: Thu, 6 May 2021 14:21:43 -0700 Subject: [PATCH 15/24] Fix to begin/end pair that was missed when porting a change from Prefab Outliner to Slice Outliner. --- .../UI/Outliner/OutlinerListModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp index 49d56f67df..ac9b92adce 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerListModel.cpp @@ -1481,7 +1481,7 @@ void OutlinerListModel::OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, (void)childId; AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - endRemoveRows(); + endResetModel(); //must refresh partial lock/visibility of parents m_isFilterDirty = true; From 8947abcbb78a468f392b6e84048faab7fb323070 Mon Sep 17 00:00:00 2001 From: jonbeer Date: Thu, 6 May 2021 16:35:01 -0700 Subject: [PATCH 16/24] PR fixes and recommendations --- .../Serialization/Json/JsonDeserializer.cpp | 27 ++++++++++--------- .../Serialization/Json/JsonDeserializer.h | 8 ++++++ .../MaterialFunctorSourceDataSerializer.h | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index b194a48f6e..93d12acba3 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -22,6 +22,19 @@ namespace AZ { + JsonSerializationResult::ResultCode JsonDeserializer::DeserializerDefaultCheck(BaseJsonSerializer* serializer, void* object, + const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context) + { + using namespace AZ::JsonSerializationResult; + + bool isExplicitDefault = IsExplicitDefault(value); + bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == + BaseJsonSerializer::OperationFlags::ManualDefault; + return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) + ? 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) { @@ -36,12 +49,7 @@ namespace AZ BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { - bool isExplicitDefault = IsExplicitDefault(value); - bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == - BaseJsonSerializer::OperationFlags::ManualDefault; - return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) - ? serializer->Load(object, typeId, value, context) - : context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); + return DeserializerDefaultCheck(serializer, object, typeId, value, context); } const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId); @@ -56,12 +64,7 @@ namespace AZ serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()); if (serializer) { - bool isExplicitDefault = IsExplicitDefault(value); - bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == - BaseJsonSerializer::OperationFlags::ManualDefault; - return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) - ? serializer->Load(object, typeId, value, context) - : context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); + return DeserializerDefaultCheck(serializer, object, typeId, value, context); } } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h index 89e527b9ae..5954082ee0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h @@ -113,5 +113,13 @@ namespace AZ //! Checks if a value is an explicit default. This means the value is an object with no members. static bool IsExplicitDefault(const rapidjson::Value& value); + + private: + static JsonSerializationResult::ResultCode DeserializerDefaultCheck( + BaseJsonSerializer* serializer, + void* object, + const Uuid& typeId, + const rapidjson::Value& value, + JsonDeserializerContext& context); }; } // namespace AZ diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h index 05367d2df1..a10e773891 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.h @@ -33,7 +33,7 @@ namespace AZ JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) override; - + private: BaseJsonSerializer::OperationFlags GetOperationsFlags() const override; }; From 4cf9af6c063ed141470fd3f8e03ea1a395139b35 Mon Sep 17 00:00:00 2001 From: dmcdiar Date: Thu, 6 May 2021 19:47:35 -0700 Subject: [PATCH 17/24] Released probe handle when deactivating the controller --- .../ReflectionProbe/ReflectionProbeComponentController.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp index 59d1f7afa7..772a995584 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/ReflectionProbe/ReflectionProbeComponentController.cpp @@ -164,6 +164,7 @@ namespace AZ if (m_featureProcessor) { m_featureProcessor->RemoveProbe(m_handle); + m_handle = nullptr; } LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect(); From 15787293bf7b8f671b890a64c1c5e4305ac621fc Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Wed, 5 May 2021 19:01:14 +0100 Subject: [PATCH 18/24] fixing physics pytests that fail --- .../physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py | 2 +- .../physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py | 2 +- AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py b/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py index e415687001..bc7b1b5e00 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py @@ -98,5 +98,5 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report + from editor_python_test_tools.utils import Report Report.start_test(C14861501_PhysXCollider_RenderMeshAutoAssigned) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py index d65e9050bd..57cdc8f9c5 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py @@ -114,5 +114,5 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report + from editor_python_test_tools.utils import Report Report.start_test(C4044695_PhysXCollider_AddMultipleSurfaceFbx) diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py index 3bbfe64e38..2b82c3e596 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py @@ -429,6 +429,8 @@ class TestAutomation(TestAutomationBase): from . import C4976236_AddPhysxColliderComponent as test_module self._run_test(request, workspace, editor, test_module) + @pytest.mark.xfail( + reason="This will fail due to this issue ATOM-15487.") def test_C14861502_PhysXCollider_AssetAutoAssigned(self, request, workspace, editor, launcher_platform): from . import C14861502_PhysXCollider_AssetAutoAssigned as test_module self._run_test(request, workspace, editor, test_module) From 5e65c5c71071f283f92e65d98a8a67d080c84ec8 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 7 May 2021 12:05:33 +0200 Subject: [PATCH 19/24] [LYN-2515] Project Manager Gem List Base (#603) * [LYN-2515] Project Manager Gem List Base * Added gem model based on a standard item model * Added list view using the gem model * Added item delegate for a gem according to the UX design * Removed th gem catalog ui file and replaced it with code * Moved the gem catalog files into a sub folder --- .../ProjectManager/Source/GemCatalog.cpp | 47 ---- .../Tools/ProjectManager/Source/GemCatalog.ui | 231 ------------------ .../Source/GemCatalog/GemCatalog.cpp | 103 ++++++++ .../Source/{ => GemCatalog}/GemCatalog.h | 17 +- .../Source/GemCatalog/GemItemDelegate.cpp | 135 ++++++++++ .../Source/GemCatalog/GemItemDelegate.h | 62 +++++ .../Source/GemCatalog/GemListView.cpp | 34 +++ .../Source/GemCatalog/GemListView.h | 31 +++ .../Source/GemCatalog/GemModel.cpp | 72 ++++++ .../Source/GemCatalog/GemModel.h | 53 ++++ .../ProjectManager/Source/ScreenFactory.cpp | 2 +- .../ProjectManager/Source/ScreenWidget.h | 2 +- .../project_manager_files.cmake | 11 +- 13 files changed, 505 insertions(+), 295 deletions(-) delete mode 100644 Code/Tools/ProjectManager/Source/GemCatalog.cpp delete mode 100644 Code/Tools/ProjectManager/Source/GemCatalog.ui create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp rename Code/Tools/ProjectManager/Source/{ => GemCatalog}/GemCatalog.h (83%) create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp create mode 100644 Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h diff --git a/Code/Tools/ProjectManager/Source/GemCatalog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog.cpp deleted file mode 100644 index 9d89740816..0000000000 --- a/Code/Tools/ProjectManager/Source/GemCatalog.cpp +++ /dev/null @@ -1,47 +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 - -namespace O3DE::ProjectManager -{ - GemCatalog::GemCatalog(ProjectManagerWindow* window) - : ScreenWidget(window) - , m_ui(new Ui::GemCatalogClass()) - { - m_ui->setupUi(this); - - ConnectSlotsAndSignals(); - } - - GemCatalog::~GemCatalog() - { - } - - void GemCatalog::ConnectSlotsAndSignals() - { - QObject::connect(m_ui->backButton, &QPushButton::pressed, this, &GemCatalog::HandleBackButton); - QObject::connect(m_ui->confirmButton, &QPushButton::pressed, this, &GemCatalog::HandleConfirmButton); - } - - void GemCatalog::HandleBackButton() - { - m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::NewProjectSettings); - } - void GemCatalog::HandleConfirmButton() - { - m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::ProjectsHome); - } - -} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog.ui b/Code/Tools/ProjectManager/Source/GemCatalog.ui deleted file mode 100644 index acc2ea80a1..0000000000 --- a/Code/Tools/ProjectManager/Source/GemCatalog.ui +++ /dev/null @@ -1,231 +0,0 @@ - - - GemCatalogClass - - - - 0 - 0 - 806 - 566 - - - - Form - - - - - - - - Gem Catalog - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Cart - - - - - - - Hamburger Menu - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - TextLabel - - - - - - - RadioButton - - - - - - - RadioButton - - - - - - - RadioButton - - - - - - - Qt::Horizontal - - - - - - - TextLabel - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - CheckBox - - - - - - - - - - 0 - 0 - - - - - - - - - - TextLabel - - - - - - - - 0 - 0 - - - - - Atom - - - - - Audio - - - - - Camera - - - - - PhysX - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Back - - - - - - - Create Project - - - - - - - - - - diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp new file mode 100644 index 0000000000..6ceb443df8 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.cpp @@ -0,0 +1,103 @@ +/* + * 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 O3DE::ProjectManager +{ + GemCatalog::GemCatalog(ProjectManagerWindow* window) + : ScreenWidget(window) + { + ConnectSlotsAndSignals(); + + m_gemModel = new GemModel(this); + + QVBoxLayout* vLayout = new QVBoxLayout(); + setLayout(vLayout); + + QHBoxLayout* hLayout = new QHBoxLayout(); + vLayout->addLayout(hLayout); + + QWidget* filterPlaceholderWidget = new QWidget(); + filterPlaceholderWidget->setFixedWidth(250); + hLayout->addWidget(filterPlaceholderWidget); + + m_gemListView = new GemListView(m_gemModel, this); + hLayout->addWidget(m_gemListView); + + QWidget* inspectorPlaceholderWidget = new QWidget(); + inspectorPlaceholderWidget->setFixedWidth(250); + hLayout->addWidget(inspectorPlaceholderWidget); + + // Temporary back and next buttons until they are centralized and shared. + QDialogButtonBox* backNextButtons = new QDialogButtonBox(); + vLayout->addWidget(backNextButtons); + + QPushButton* tempBackButton = backNextButtons->addButton("Back", QDialogButtonBox::RejectRole); + QPushButton* tempNextButton = backNextButtons->addButton("Next", QDialogButtonBox::AcceptRole); + connect(tempBackButton, &QPushButton::pressed, this, &GemCatalog::HandleBackButton); + connect(tempNextButton, &QPushButton::pressed, this, &GemCatalog::HandleConfirmButton); + + // Start: Temporary gem test data + { + m_gemModel->AddGem(GemInfo("EMotion FX", + "O3DE Foundation", + "EMFX is a real-time character animation system. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + (GemInfo::Android | GemInfo::iOS | GemInfo::Windows | GemInfo::Linux), + true)); + + m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Atom", + "O3DE Foundation", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + GemInfo::Android | GemInfo::Windows | GemInfo::Linux, + true)); + + m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("PhysX", + "O3DE Foundation", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + GemInfo::Android | GemInfo::Linux, + false)); + + m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Certificate Manager", + "O3DE Foundation", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + GemInfo::Windows, + false)); + + m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Cloud Gem Framework", + "O3DE Foundation", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + GemInfo::iOS | GemInfo::Linux, + false)); + + m_gemModel->AddGem(O3DE::ProjectManager::GemInfo("Achievements", + "O3DE Foundation", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + GemInfo::Android | GemInfo::Windows | GemInfo::Linux, + false)); + } + // End: Temporary gem test data + } + + void GemCatalog::HandleBackButton() + { + m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::NewProjectSettings); + } + void GemCatalog::HandleConfirmButton() + { + m_projectManagerWindow->ChangeToScreen(ProjectManagerScreen::ProjectsHome); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.h similarity index 83% rename from Code/Tools/ProjectManager/Source/GemCatalog.h rename to Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.h index e45d865e58..489752bbe7 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalog.h @@ -13,32 +13,25 @@ #if !defined(Q_MOC_RUN) #include +#include +#include #endif -namespace Ui -{ - class GemCatalogClass; -} - namespace O3DE::ProjectManager { class GemCatalog : public ScreenWidget { - public: explicit GemCatalog(ProjectManagerWindow* window); - ~GemCatalog(); - - protected: - void ConnectSlotsAndSignals() override; + ~GemCatalog() = default; protected slots: void HandleBackButton(); void HandleConfirmButton(); private: - QScopedPointer m_ui; + GemListView* m_gemListView = nullptr; + GemModel* m_gemModel = nullptr; }; - } // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp new file mode 100644 index 0000000000..22e77ed40e --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.cpp @@ -0,0 +1,135 @@ +/* +* 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 "GemItemDelegate.h" +#include "GemModel.h" +#include +#include +#include + +namespace O3DE::ProjectManager +{ + GemItemDelegate::GemItemDelegate(GemModel* gemModel, QObject* parent) + : QStyledItemDelegate(parent) + , m_gemModel(gemModel) + { + } + + void GemItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const + { + if (!modelIndex.isValid()) + { + return; + } + + QStyleOptionViewItem options(option); + initStyleOption(&options, modelIndex); + + painter->setRenderHint(QPainter::Antialiasing); + + QRect fullRect, itemRect, contentRect; + CalcRects(options, modelIndex, fullRect, itemRect, contentRect); + + QFont standardFont(options.font); + standardFont.setPixelSize(s_fontSize); + + painter->save(); + painter->setClipping(true); + painter->setClipRect(fullRect); + painter->setFont(options.font); + + // Draw background + painter->fillRect(fullRect, m_backgroundColor); + + // Draw item background + const QColor itemBackgroundColor = options.state & QStyle::State_MouseOver ? m_itemBackgroundColor.lighter(120) : m_itemBackgroundColor; + painter->fillRect(itemRect, itemBackgroundColor); + + // Draw border + if (options.state & QStyle::State_Selected) + { + painter->save(); + QPen borderPen(m_borderColor); + borderPen.setWidth(s_borderWidth); + painter->setPen(borderPen); + painter->drawRect(itemRect); + painter->restore(); + } + + // Gem name + const QString gemName = m_gemModel->GetName(modelIndex); + QFont gemNameFont(options.font); + gemNameFont.setPixelSize(s_gemNameFontSize); + gemNameFont.setBold(true); + QRect gemNameRect = GetTextRect(gemNameFont, gemName, s_gemNameFontSize); + gemNameRect.moveTo(contentRect.left(), contentRect.top()); + + painter->setFont(gemNameFont); + painter->setPen(m_textColor); + painter->drawText(gemNameRect, Qt::TextSingleLine, gemName); + + // Gem creator + const QString gemCreator = m_gemModel->GetCreator(modelIndex); + QRect gemCreatorRect = GetTextRect(standardFont, gemCreator, s_fontSize); + gemCreatorRect.moveTo(contentRect.left(), contentRect.top() + gemNameRect.height()); + + painter->setFont(standardFont); + painter->setPen(m_linkColor); + painter->drawText(gemCreatorRect, Qt::TextSingleLine, gemCreator); + + // Gem summary + const QSize summarySize = QSize(contentRect.width() - s_summaryStartX - s_itemMargins.right() * 4, contentRect.height()); + const QRect summaryRect = QRect(/*topLeft=*/QPoint(contentRect.left() + s_summaryStartX, contentRect.top()), summarySize); + + painter->setFont(standardFont); + painter->setPen(m_textColor); + + const QString summary = m_gemModel->GetSummary(modelIndex); + painter->drawText(summaryRect, Qt::AlignLeft | Qt::TextWordWrap, summary); + + painter->restore(); + } + + QSize GemItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const + { + QStyleOptionViewItem options(option); + initStyleOption(&options, modelIndex); + + int marginsHorizontal = s_itemMargins.left() + s_itemMargins.right() + s_contentMargins.left() + s_contentMargins.right(); + return QSize(marginsHorizontal + s_summaryStartX, s_height); + } + + bool GemItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) + { + if (!modelIndex.isValid()) + { + return false; + } + + return QStyledItemDelegate::editorEvent(event, model, option, modelIndex); + } + + void GemItemDelegate::CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const + { + const bool isFirst = modelIndex.row() == 0; + + outFullRect = QRect(option.rect); + outItemRect = QRect(outFullRect.adjusted(s_itemMargins.left(), isFirst ? s_itemMargins.top() * 2 : s_itemMargins.top(), -s_itemMargins.right(), -s_itemMargins.bottom())); + outContentRect = QRect(outItemRect.adjusted(s_contentMargins.left(), s_contentMargins.top(), -s_contentMargins.right(), -s_contentMargins.bottom())); + } + + QRect GemItemDelegate::GetTextRect(QFont& font, const QString& text, qreal fontSize) const + { + font.setPixelSize(fontSize); + return QFontMetrics(font).boundingRect(text); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h new file mode 100644 index 0000000000..3528d07d78 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemItemDelegate.h @@ -0,0 +1,62 @@ +/* +* 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 + +#if !defined(Q_MOC_RUN) +#include +#include "GemInfo.h" +#include "GemModel.h" +#endif + +QT_FORWARD_DECLARE_CLASS(QEvent) + +namespace O3DE::ProjectManager +{ + class GemItemDelegate + : public QStyledItemDelegate + { + Q_OBJECT // AUTOMOC + + public: + explicit GemItemDelegate(GemModel* gemModel, QObject* parent = nullptr); + ~GemItemDelegate() = default; + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const override; + bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& modelIndex) override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& modelIndex) const override; + + private: + void CalcRects(const QStyleOptionViewItem& option, const QModelIndex& modelIndex, QRect& outFullRect, QRect& outItemRect, QRect& outContentRect) const; + QRect GetTextRect(QFont& font, const QString& text, qreal fontSize) const; + + GemModel* m_gemModel = nullptr; + + // Colors + const QColor m_textColor = QColor("#FFFFFF"); + const QColor m_linkColor = QColor("#94D2FF"); + const QColor m_backgroundColor = QColor("#333333"); // Outside of the actual gem item + const QColor m_itemBackgroundColor = QColor("#404040"); // Background color of the gem item + const QColor m_borderColor = QColor("#1E70EB"); + + // Item + inline constexpr static int s_height = 140; // Gem item total height + inline constexpr static qreal s_gemNameFontSize = 16.0; + inline constexpr static qreal s_fontSize = 15.0; + inline constexpr static int s_summaryStartX = 200; + + // Margin and borders + inline constexpr static QMargins s_itemMargins = QMargins(/*left=*/20, /*top=*/10, /*right=*/20, /*bottom=*/10); // Item border distances + inline constexpr static QMargins s_contentMargins = QMargins(/*left=*/15, /*top=*/12, /*right=*/12, /*bottom=*/12); // Distances of the elements within an item to the item borders + inline constexpr static int s_borderWidth = 4; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp new file mode 100644 index 0000000000..ad75272c8f --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.cpp @@ -0,0 +1,34 @@ +/* +* 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 "GemListView.h" +#include "GemItemDelegate.h" +#include +#include +#include + +namespace O3DE::ProjectManager +{ + GemListView::GemListView(GemModel* model, QWidget *parent) : + QListView(parent) + { + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + QPalette palette; + palette.setColor(QPalette::Window, QColor("#333333")); + setPalette(palette); + + setModel(model); + setSelectionModel(model->GetSelectionModel()); + setItemDelegate(new GemItemDelegate(model, this)); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h new file mode 100644 index 0000000000..79e16bd211 --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemListView.h @@ -0,0 +1,31 @@ +/* +* 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 + +#if !defined(Q_MOC_RUN) +#include "GemInfo.h" +#include "GemModel.h" +#include +#endif + +namespace O3DE::ProjectManager +{ + class GemListView + : public QListView + { + Q_OBJECT // AUTOMOC + public: + explicit GemListView(GemModel* model, QWidget *parent = nullptr); + ~GemListView() = default; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp new file mode 100644 index 0000000000..89e629cf5f --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.cpp @@ -0,0 +1,72 @@ +/* +* 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 "GemModel.h" + +namespace O3DE::ProjectManager +{ + GemModel::GemModel(QObject* parent) + : QStandardItemModel(parent) + { + m_selectionModel = new QItemSelectionModel(this, parent); + } + + QItemSelectionModel* GemModel::GetSelectionModel() const + { + return m_selectionModel; + } + + void GemModel::AddGem(const GemInfo& gemInfo) + { + QStandardItem* item = new QStandardItem(); + + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + + item->setData(gemInfo.m_name, RoleName); + item->setData(gemInfo.m_creator, RoleCreator); + item->setData(static_cast(gemInfo.m_platforms), RolePlatforms); + item->setData(gemInfo.m_summary, RoleSummary); + item->setData(gemInfo.m_isAdded, RoleIsAdded); + + appendRow(item); + } + + void GemModel::Clear() + { + clear(); + } + + QString GemModel::GetName(const QModelIndex& modelIndex) const + { + return modelIndex.data(RoleName).toString(); + } + + QString GemModel::GetCreator(const QModelIndex& modelIndex) const + { + return modelIndex.data(RoleCreator).toString(); + } + + int GemModel::GetPlatforms(const QModelIndex& modelIndex) const + { + return static_cast(modelIndex.data(RolePlatforms).toInt()); + } + + QString GemModel::GetSummary(const QModelIndex& modelIndex) const + { + return modelIndex.data(RoleSummary).toString(); + } + + bool GemModel::IsAdded(const QModelIndex& modelIndex) const + { + return modelIndex.data(RoleIsAdded).toBool(); + } +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h new file mode 100644 index 0000000000..33ae02dc8a --- /dev/null +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemModel.h @@ -0,0 +1,53 @@ +/* +* 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 + +#if !defined(Q_MOC_RUN) +#include "GemInfo.h" +#include +#include +#endif + +namespace O3DE::ProjectManager +{ + class GemModel + : public QStandardItemModel + { + Q_OBJECT // AUTOMOC + + public: + explicit GemModel(QObject* parent = nullptr); + QItemSelectionModel* GetSelectionModel() const; + + void AddGem(const GemInfo& gemInfo); + void Clear(); + + QString GetName(const QModelIndex& modelIndex) const; + QString GetCreator(const QModelIndex& modelIndex) const; + int GetPlatforms(const QModelIndex& modelIndex) const; + QString GetSummary(const QModelIndex& modelIndex) const; + bool IsAdded(const QModelIndex& modelIndex) const; + + private: + enum UserRole + { + RoleName = Qt::UserRole, + RoleCreator, + RolePlatforms, + RoleSummary, + RoleIsAdded + }; + + QItemSelectionModel* m_selectionModel = nullptr; + }; +} // namespace O3DE::ProjectManager diff --git a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp index b07816e69e..9250b71ccd 100644 --- a/Code/Tools/ProjectManager/Source/ScreenFactory.cpp +++ b/Code/Tools/ProjectManager/Source/ScreenFactory.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/Code/Tools/ProjectManager/Source/ScreenWidget.h b/Code/Tools/ProjectManager/Source/ScreenWidget.h index b4c4fd190c..ddf4add65b 100644 --- a/Code/Tools/ProjectManager/Source/ScreenWidget.h +++ b/Code/Tools/ProjectManager/Source/ScreenWidget.h @@ -30,7 +30,7 @@ namespace O3DE::ProjectManager } protected: - virtual void ConnectSlotsAndSignals() = 0; + virtual void ConnectSlotsAndSignals() {} ProjectManagerWindow* m_projectManagerWindow; }; diff --git a/Code/Tools/ProjectManager/project_manager_files.cmake b/Code/Tools/ProjectManager/project_manager_files.cmake index a97ff692b7..b206cf1456 100644 --- a/Code/Tools/ProjectManager/project_manager_files.cmake +++ b/Code/Tools/ProjectManager/project_manager_files.cmake @@ -25,9 +25,6 @@ set(FILES Source/NewProjectSettings.h Source/NewProjectSettings.cpp Source/NewProjectSettings.ui - Source/GemCatalog.h - Source/GemCatalog.cpp - Source/GemCatalog.ui Source/ProjectsHome.h Source/ProjectsHome.cpp Source/ProjectsHome.ui @@ -37,6 +34,14 @@ set(FILES Source/EngineSettings.h Source/EngineSettings.cpp Source/EngineSettings.ui + Source/GemCatalog/GemCatalog.h + Source/GemCatalog/GemCatalog.cpp Source/GemCatalog/GemInfo.h Source/GemCatalog/GemInfo.cpp + Source/GemCatalog/GemItemDelegate.h + Source/GemCatalog/GemItemDelegate.cpp + Source/GemCatalog/GemListView.h + Source/GemCatalog/GemListView.cpp + Source/GemCatalog/GemModel.h + Source/GemCatalog/GemModel.cpp ) From 0c7be7ceff0117275774433172252b8148d38776 Mon Sep 17 00:00:00 2001 From: Aaron Ruiz Mora Date: Fri, 7 May 2021 11:31:34 +0100 Subject: [PATCH 20/24] Reenable NvCloth atom automated tests in AutomatedTesting project - Added NvCloth gem to AutomatedTesting project. - Fixed cloth test levels using atom components. - Updated and enabled cloth tests. They are marked as xfail for now until they properly work with atom null renderer. - Fixed crash when runnnig editor with null renderer on a level with Actor component. - Improved chicken asset and slice used in NvCloth gem. --- .../Gem/Code/runtime_dependencies.cmake | 1 + .../Gem/Code/tool_dependencies.cmake | 1 + .../Gem/PythonTests/CMakeLists.txt | 29 ++-- ...977329_NvCloth_AddClothSimulationToMesh.py | 7 +- ...77330_NvCloth_AddClothSimulationToActor.py | 7 +- .../PythonTests/NvCloth/TestSuite_Active.py | 3 +- ...977329_NvCloth_AddClothSimulationToMesh.ly | 4 +- .../filelist.xml | 2 +- .../level.pak | 4 +- ...77330_NvCloth_AddClothSimulationToActor.ly | 4 +- .../filelist.xml | 2 +- .../level.pak | 4 +- .../EMotionFXAtom/Code/Source/ActorAsset.cpp | 12 +- .../cloth/Chicken/Actor/chicken.fbx.assetinfo | 71 ++-------- .../Assets/slices/Cloth/Chicken_Actor.slice | 129 +++++++++--------- 15 files changed, 124 insertions(+), 156 deletions(-) diff --git a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake index c8e66740e4..62a6ed7f8c 100644 --- a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake @@ -53,5 +53,6 @@ set(GEM_DEPENDENCIES Gem::ImguiAtom Gem::Atom_AtomBridge Gem::AtomFont + Gem::NvCloth Gem::Blast ) diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake index 8c5da63f42..a6bbeee350 100644 --- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/tool_dependencies.cmake @@ -68,5 +68,6 @@ set(GEM_DEPENDENCIES Gem::ImguiAtom Gem::AtomFont Gem::AtomToolsFramework.Editor + Gem::NvCloth.Editor Gem::Blast.Editor ) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 31afab87ed..3124f1048a 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -107,20 +107,21 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) endif() ## NvCloth ## -# [TODO LYN-1928] Enable when AutomatedTesting runs with Atom -#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) -# ly_add_pytest( -# NAME AutomatedTesting::NvClothTests -# TEST_SUITE main -# TEST_SERIAL -# PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py -# TIMEOUT 1500 -# RUNTIME_DEPENDENCIES -# Legacy::Editor -# AZ::AssetProcessor -# AutomatedTesting.Assets -# ) -#endif() +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::NvClothTests_Main + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + NvCloth + ) +endif() ## Editor Python Bindings ## if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py index 2677ba5605..625c9772bd 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py @@ -20,7 +20,7 @@ class Tests: exit_game_mode = ("Exited game mode", "Failed to exit game mode") # fmt: on -def run(): +def C18977329_NvCloth_AddClothSimulationToMesh(): """ Summary: Load level with Entity having Mesh and Cloth components already setup. Verify that editor remains stable in Game mode. @@ -89,4 +89,7 @@ def run(): helper.close_editor() if __name__ == "__main__": - run() + import ImportPathHelper as imports + imports.init() + from editor_python_test_tools.utils import Report + Report.start_test(C18977329_NvCloth_AddClothSimulationToMesh) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py index 2d4fa4e325..9b3135cd2b 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py @@ -20,7 +20,7 @@ class Tests: exit_game_mode = ("Exited game mode", "Failed to exit game mode") # fmt: on -def run(): +def C18977330_NvCloth_AddClothSimulationToActor(): """ Summary: Load level with Entity having Actor and Cloth components already setup. Verify that editor remains stable in Game mode. @@ -89,4 +89,7 @@ def run(): helper.close_editor() if __name__ == "__main__": - run() + import ImportPathHelper as imports + imports.init() + from editor_python_test_tools.utils import Report + Report.start_test(C18977330_NvCloth_AddClothSimulationToActor) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py index 162c54afc8..86bfc48636 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py @@ -21,14 +21,15 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesti from base import TestAutomationBase -@pytest.mark.SUITE_main @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 17fee158d8..1afbf787db 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:a2a3360287a4711882c4254d64ca2ba70cd743012a7d38ca29aa2a57f151efaa -size 6661 +oid sha256:e15d484113e8151072b410924747a8ad304f6f12457fad577308c0491693ab34 +size 5472 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml index 6c8b361e57..9775a35c53 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 e80d5ca1d9..08a775b6c8 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:cd8105f020151e65093988dfb09ab42ff8d33ef5b97c61fbe0011384870aadf8 -size 39238 +oid sha256:64de37c805b0be77cdb7a85b5406af58b7f845e7d97fec1721ac5d789bb641db +size 38856 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 031989ee11..385027c479 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:f53fb5e096ff562e9f0f12856ce387891596776d086f49c7ed3a59dcd0a0c11a -size 6535 +oid sha256:7b595323d4d51211463dea0338abb6ce2a4a0a8d41efb12ac3c9dccd1f972171 +size 5504 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml index 290a28f223..7ccc1d51eb 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 fb91adeba5..12ce03fa87 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:87fbd9fda267daa505f11276b64f47c26115bee9e6d14f2a6f5a1cf1e1234218 -size 39179 +oid sha256:617c455668fc41cb7fd69de690e4aa3c80f2cb36deaa371902b79de18fcd1cb2 +size 39233 diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp index 8452a6c690..3594802dab 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/ActorAsset.cpp @@ -486,10 +486,14 @@ namespace AZ AZ_Assert(jointIndicesBufferAsset->GetBufferDescriptor().m_byteCount == remappedJointIndexBufferSizeInBytes, "Joint indices data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex); AZ_Assert(skinWeightsBufferAsset->GetBufferDescriptor().m_byteCount == remappedSkinWeightsBufferSizeInBytes, "Skin weights data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex); - Data::Instance jointIndicesBuffer = RPI::Buffer::FindOrCreate(jointIndicesBufferAsset); - jointIndicesBuffer->UpdateData(blendIndexBufferData.data(), remappedJointIndexBufferSizeInBytes); - Data::Instance skinWeightsBuffer = RPI::Buffer::FindOrCreate(skinWeightsBufferAsset); - skinWeightsBuffer->UpdateData(blendWeightBufferData.data(), remappedSkinWeightsBufferSizeInBytes); + if (Data::Instance jointIndicesBuffer = RPI::Buffer::FindOrCreate(jointIndicesBufferAsset)) + { + jointIndicesBuffer->UpdateData(blendIndexBufferData.data(), remappedJointIndexBufferSizeInBytes); + } + if (Data::Instance skinWeightsBuffer = RPI::Buffer::FindOrCreate(skinWeightsBufferAsset)) + { + skinWeightsBuffer->UpdateData(blendWeightBufferData.data(), remappedSkinWeightsBufferSizeInBytes); + } } // Create read-only input assembly buffers that are not modified during skinning and shared across all instances diff --git a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken.fbx.assetinfo b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken.fbx.assetinfo index 0036fa39f9..37480c52c1 100644 --- a/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken.fbx.assetinfo +++ b/Gems/NvCloth/Assets/Objects/cloth/Chicken/Actor/chicken.fbx.assetinfo @@ -23,42 +23,15 @@ { "Visible": true, "Position": [ - -0.08505599945783615, - 0.0, - 0.009370899759232998 - ], - "Rotation": [ - 0.7071437239646912, - 0.0, - 0.0, - 0.708984375 - ], - "propertyVisibilityFlags": 248 - }, - { - "$type": "CapsuleShapeConfiguration", - "Height": 0.191273495554924, - "Radius": 0.05063670128583908 - } - ] - ] - }, - { - "name": "def_c_neck_joint", - "shapes": [ - [ - { - "Visible": true, - "Position": [ - 0.08189810067415238, - -2.4586914726398847e-9, - -0.4713243842124939 + -0.03709467500448227, + -3.725290298461914e-9, + 0.013427333906292916 ], "propertyVisibilityFlags": 248 }, { "$type": "SphereShapeConfiguration", - "Radius": 0.2406993955373764 + "Radius": 0.12945009768009187 } ] ] @@ -70,42 +43,22 @@ { "Visible": true, "Position": [ - -2.0000000233721949e-7, - 0.012646200135350228, - -0.24104370176792146 - ], - "propertyVisibilityFlags": 248 - }, - { - "$type": "SphereShapeConfiguration", - "Radius": 0.24875959753990174 - } - ] - ] - }, - { - "name": "def_c_feather2_joint", - "shapes": [ - [ - { - "Visible": true, - "Position": [ - 0.06151500344276428, - 0.1300000101327896, - 7.729977369308472e-8 + 0.0, + 0.09497000277042389, + -0.19093050062656403 ], "Rotation": [ 0.0, - 0.7071062922477722, - 0.0, - 0.7071072459220886 + 0.662880003452301, + 0.7487256526947022, + 0.0 ], "propertyVisibilityFlags": 248 }, { "$type": "CapsuleShapeConfiguration", - "Height": 0.5730299949645996, - "Radius": 0.06151498109102249 + "Height": 0.8597599267959595, + "Radius": 0.27968019247055056 } ] ] diff --git a/Gems/NvCloth/Assets/slices/Cloth/Chicken_Actor.slice b/Gems/NvCloth/Assets/slices/Cloth/Chicken_Actor.slice index 6f64caf5f2..e7de286c1b 100644 --- a/Gems/NvCloth/Assets/slices/Cloth/Chicken_Actor.slice +++ b/Gems/NvCloth/Assets/slices/Cloth/Chicken_Actor.slice @@ -154,7 +154,7 @@ - + @@ -184,15 +184,15 @@ - + - + - + @@ -265,66 +265,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -511,6 +452,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cb44a7ebb2deed1e7d2b804290a02c6daab826f2 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Fri, 7 May 2021 14:10:28 +0100 Subject: [PATCH 21/24] first pass at moving physx debug from gEnv->pRenderer to DebugDisplayRequestBus (#600) --- .../Code/Source/SystemComponent.cpp | 112 ++++++++++-------- Gems/PhysXDebug/Code/Source/SystemComponent.h | 38 +++--- 2 files changed, 84 insertions(+), 66 deletions(-) diff --git a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp index 77b0959008..08bf71753d 100644 --- a/Gems/PhysXDebug/Code/Source/SystemComponent.cpp +++ b/Gems/PhysXDebug/Code/Source/SystemComponent.cpp @@ -39,14 +39,9 @@ namespace PhysXDebug { const float SystemComponent::m_maxCullingBoxSize = 150.0f; - - const ColorB CreateColorFromU32(AZ::u32 color) + namespace Internal { - const AZ::u8 a = static_cast((color & 0xFF000000) >> 24); - const AZ::u8 b = static_cast((color & 0x00FF0000) >> 16); - const AZ::u8 g = static_cast((color & 0x0000FF00) >> 8); - const AZ::u8 r = static_cast(color & 0x000000FF); - return ColorB(r, g, b, a); + const AZ::Crc32 VewportId = 0; // was AzFramework::g_defaultSceneEntityDebugDisplayId but it didn't render to the viewport. } bool UseEditorPhysicsScene() @@ -338,18 +333,18 @@ namespace PhysXDebug } } - void SystemComponent::BuildColorPickingMenuItem(const AZStd::string& label, ColorB& color) + void SystemComponent::BuildColorPickingMenuItem(const AZStd::string& label, AZ::Color& color) { - float col[3] = {color.r / 255.0f, color.g / 255.0f, color.b / 255.0f}; + float col[3] = {color.GetR(), color.GetG(), color.GetB()}; if (ImGui::ColorEdit3(label.c_str(), col, ImGuiColorEditFlags_NoAlpha)) { - const float r = AZ::GetClamp(col[0] * 255.0f, 0.0f, 255.0f); - const float g = AZ::GetClamp(col[1] * 255.0f, 0.0f, 255.0f); - const float b = AZ::GetClamp(col[2] * 255.0f, 0.0f, 255.0f); + const float r = AZ::GetClamp(col[0], 0.0f, 1.0f); + const float g = AZ::GetClamp(col[1], 0.0f, 1.0f); + const float b = AZ::GetClamp(col[2], 0.0f, 1.0f); - color.r = static_cast(r); - color.g = static_cast(g); - color.b = static_cast(b); + color.SetR(r); + color.SetG(g); + color.SetB(b); } } #endif // IMGUI_ENABLED @@ -511,16 +506,34 @@ namespace PhysXDebug void SystemComponent::RenderBuffers() { - if (gEnv && gEnv->pRenderer && !m_linePoints.empty()) + if (!m_linePoints.empty() || !m_trianglePoints.empty()) { - AZ_Assert(m_linePoints.size() == m_lineColors.size(), "Lines: Expected an equal number of points to colors."); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawLines(m_linePoints.begin(), m_linePoints.size(), m_lineColors.begin(), 1.0f); - } - - if (gEnv && gEnv->pRenderer && !m_trianglePoints.empty()) - { - AZ_Assert(m_trianglePoints.size() == m_triangleColors.size(), "Triangles: Expected an equal number of points to colors."); - gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangles(m_trianglePoints.begin(), m_trianglePoints.size(), m_triangleColors.begin()); + AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus; + AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, Internal::VewportId); + AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus."); + AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus); + if (debugDisplay) + { + if (!m_linePoints.empty()) + { + AZ_Assert(m_linePoints.size() == m_lineColors.size(), "Lines: Expected an equal number of points to colors."); + const size_t minLen = AZ::GetMin(m_linePoints.size(), m_lineColors.size()); + for (size_t i = 0; i < minLen; i += 2) + { + debugDisplay->DrawLine(m_linePoints[i], m_linePoints[i + 1], m_lineColors[i].GetAsVector4(), m_lineColors[i + 1].GetAsVector4()); + } + } + if (!m_trianglePoints.empty()) + { + AZ_Assert(m_trianglePoints.size() == m_triangleColors.size(), "Triangles: Expected an equal number of points to colors."); + const size_t minLen = AZ::GetMin(m_trianglePoints.size(), m_triangleColors.size()); + for (size_t i = 0; i < minLen; i += 3) + { + debugDisplay->SetColor(m_triangleColors[i]); + debugDisplay->DrawTri(m_trianglePoints[i], m_trianglePoints[i + 1], m_trianglePoints[i + 2]); + } + } + } } } @@ -677,8 +690,8 @@ namespace PhysXDebug if (!cameraTranslation.IsClose(AZ::Vector3::CreateZero())) { - physx::PxVec3 min = PxMathConvert(cameraTranslation - AZ::Vector3(m_culling.m_boxSize)); - physx::PxVec3 max = PxMathConvert(cameraTranslation + AZ::Vector3(m_culling.m_boxSize)); + const physx::PxVec3 min = PxMathConvert(cameraTranslation - AZ::Vector3(m_culling.m_boxSize)); + const physx::PxVec3 max = PxMathConvert(cameraTranslation + AZ::Vector3(m_culling.m_boxSize)); m_cullingBox = physx::PxBounds3(min, max); if (m_culling.m_boxWireframe) @@ -813,8 +826,8 @@ namespace PhysXDebug for (size_t lineIndex = 0; lineIndex < jointLineBufferSize / 2; lineIndex++) { - m_linePoints.emplace_back(AZVec3ToLYVec3(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex]))); - m_linePoints.emplace_back(AZVec3ToLYVec3(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex + 1]))); + m_linePoints.emplace_back(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex])); + m_linePoints.emplace_back(jointWorldTransform.TransformPoint(m_jointLineBuffer[2 * lineIndex + 1])); m_lineColors.emplace_back(m_colorMappings.m_green); m_lineColors.emplace_back(m_colorMappings.m_green); } @@ -829,16 +842,21 @@ namespace PhysXDebug { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics); - if (gEnv && gEnv->pRenderer && m_settings.m_visualizationEnabled && m_culling.m_boxWireframe) + if (m_settings.m_visualizationEnabled && m_culling.m_boxWireframe) { - ColorB wireframeColor = MapOriginalPhysXColorToUserDefinedValues(1); - AABB lyAABB(AZAabbToLyAABB(cullingBoxAabb)); - - gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(lyAABB, false, wireframeColor, EBoundingBoxDrawStyle::eBBD_Extremes_Color_Encoded); + AzFramework::DebugDisplayRequestBus::BusPtr debugDisplayBus; + AzFramework::DebugDisplayRequestBus::Bind(debugDisplayBus, Internal::VewportId); + AZ_Assert(debugDisplayBus, "Invalid DebugDisplayRequestBus."); + if (AzFramework::DebugDisplayRequests* debugDisplay = AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus)) + { + const AZ::Color wireframeColor = MapOriginalPhysXColorToUserDefinedValues(1); + debugDisplay->SetColor(wireframeColor.GetAsVector4()); + debugDisplay->DrawWireBox(cullingBoxAabb.GetMin(), cullingBoxAabb.GetMax()); + } } } - ColorB SystemComponent::MapOriginalPhysXColorToUserDefinedValues(const physx::PxU32& originalColor) + AZ::Color SystemComponent::MapOriginalPhysXColorToUserDefinedValues(const physx::PxU32& originalColor) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics); @@ -877,18 +895,18 @@ namespace PhysXDebug void SystemComponent::InitPhysXColorMappings() { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Physics); - m_colorMappings.m_defaultColor = CreateColorFromU32(physx::PxDebugColor::eARGB_GREEN); - m_colorMappings.m_black = CreateColorFromU32(physx::PxDebugColor::eARGB_BLACK); - m_colorMappings.m_red = CreateColorFromU32(physx::PxDebugColor::eARGB_RED); - m_colorMappings.m_green = CreateColorFromU32(physx::PxDebugColor::eARGB_GREEN); - m_colorMappings.m_blue = CreateColorFromU32(physx::PxDebugColor::eARGB_BLUE); - m_colorMappings.m_yellow = CreateColorFromU32(physx::PxDebugColor::eARGB_YELLOW); - m_colorMappings.m_magenta = CreateColorFromU32(physx::PxDebugColor::eARGB_MAGENTA); - m_colorMappings.m_cyan = CreateColorFromU32(physx::PxDebugColor::eARGB_CYAN); - m_colorMappings.m_white = CreateColorFromU32(physx::PxDebugColor::eARGB_WHITE); - m_colorMappings.m_grey = CreateColorFromU32(physx::PxDebugColor::eARGB_GREY); - m_colorMappings.m_darkRed = CreateColorFromU32(physx::PxDebugColor::eARGB_DARKRED); - m_colorMappings.m_darkGreen = CreateColorFromU32(physx::PxDebugColor::eARGB_DARKGREEN); - m_colorMappings.m_darkBlue = CreateColorFromU32(physx::PxDebugColor::eARGB_DARKBLUE); + m_colorMappings.m_defaultColor.FromU32(physx::PxDebugColor::eARGB_GREEN); + m_colorMappings.m_black.FromU32(physx::PxDebugColor::eARGB_BLACK); + m_colorMappings.m_red.FromU32(physx::PxDebugColor::eARGB_RED); + m_colorMappings.m_green.FromU32(physx::PxDebugColor::eARGB_GREEN); + m_colorMappings.m_blue.FromU32(physx::PxDebugColor::eARGB_BLUE); + m_colorMappings.m_yellow.FromU32(physx::PxDebugColor::eARGB_YELLOW); + m_colorMappings.m_magenta.FromU32(physx::PxDebugColor::eARGB_MAGENTA); + m_colorMappings.m_cyan.FromU32(physx::PxDebugColor::eARGB_CYAN); + m_colorMappings.m_white.FromU32(physx::PxDebugColor::eARGB_WHITE); + m_colorMappings.m_grey.FromU32(physx::PxDebugColor::eARGB_GREY); + m_colorMappings.m_darkRed.FromU32(physx::PxDebugColor::eARGB_DARKRED); + m_colorMappings.m_darkGreen.FromU32(physx::PxDebugColor::eARGB_DARKGREEN); + m_colorMappings.m_darkBlue.FromU32(physx::PxDebugColor::eARGB_DARKBLUE); } } diff --git a/Gems/PhysXDebug/Code/Source/SystemComponent.h b/Gems/PhysXDebug/Code/Source/SystemComponent.h index 66f546c661..631354c034 100644 --- a/Gems/PhysXDebug/Code/Source/SystemComponent.h +++ b/Gems/PhysXDebug/Code/Source/SystemComponent.h @@ -87,19 +87,19 @@ namespace PhysXDebug { AZ_RTTI(ColorMappings, "{021E40A6-568E-430A-9332-EF180DACD3C0}"); // user defined colors for physx debug primitives - ColorB m_defaultColor; - ColorB m_black; - ColorB m_red; - ColorB m_green; - ColorB m_blue; - ColorB m_yellow; - ColorB m_magenta; - ColorB m_cyan; - ColorB m_white; - ColorB m_grey; - ColorB m_darkRed; - ColorB m_darkGreen; - ColorB m_darkBlue; + AZ::Color m_defaultColor; + AZ::Color m_black; + AZ::Color m_red; + AZ::Color m_green; + AZ::Color m_blue; + AZ::Color m_yellow; + AZ::Color m_magenta; + AZ::Color m_cyan; + AZ::Color m_white; + AZ::Color m_grey; + AZ::Color m_darkRed; + AZ::Color m_darkGreen; + AZ::Color m_darkBlue; }; class SystemComponent @@ -156,7 +156,7 @@ namespace PhysXDebug /// Convert from PhysX Visualization debug colors to user defined colors. /// @param originalColor a color from the PhysX debug visualization data. /// @return a user specified color mapping (defaulting to the original PhysX color). - ColorB MapOriginalPhysXColorToUserDefinedValues(const physx::PxU32& originalColor); + AZ::Color MapOriginalPhysXColorToUserDefinedValues(const physx::PxU32& originalColor); /// Initialise the PhysX debug draw colors based on defaults. void InitPhysXColorMappings(); @@ -194,7 +194,7 @@ namespace PhysXDebug #ifdef IMGUI_ENABLED /// Build a specific color picker menu option. - void BuildColorPickingMenuItem(const AZStd::string& label, ColorB& color); + void BuildColorPickingMenuItem(const AZStd::string& label, AZ::Color& color); #endif // IMGUI_ENABLED physx::PxScene* GetCurrentPxScene(); @@ -209,10 +209,10 @@ namespace PhysXDebug bool m_editorPhysicsSceneDirty = true; static const float m_maxCullingBoxSize; - AZStd::vector m_linePoints; - AZStd::vector m_lineColors; - AZStd::vector m_trianglePoints; - AZStd::vector m_triangleColors; + AZStd::vector m_linePoints; + AZStd::vector m_lineColors; + AZStd::vector m_trianglePoints; + AZStd::vector m_triangleColors; // joint limit buffers AZStd::vector m_jointVertexBuffer; From cb4e394784fafa1a965535d06b1d92504fd9a456 Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Fri, 7 May 2021 14:12:07 +0100 Subject: [PATCH 22/24] Remove physics world body notification bus (#576) --- .../SimulatedBodyComponentBus.h} | 41 ++++++------------- .../AzFramework/AzFramework/Physics/Utils.cpp | 18 ++++---- .../AzFramework/azframework_files.cmake | 14 +++---- Gems/Blast/Code/Include/Blast/BlastActor.h | 4 +- .../Code/Source/Actor/BlastActorImpl.cpp | 16 ++++---- Gems/Blast/Code/Source/Actor/BlastActorImpl.h | 5 +-- Gems/Blast/Code/Source/Actor/ShapesProvider.h | 1 - .../Components/BlastFamilyComponent.cpp | 4 +- .../Code/Source/Family/ActorRenderManager.cpp | 2 +- .../Blast/Code/Source/Family/ActorTracker.cpp | 4 +- .../Code/Source/Family/BlastFamilyImpl.cpp | 4 +- .../Code/Source/Family/DamageManager.cpp | 2 +- Gems/Blast/Code/Tests/Mocks/BlastMocks.h | 4 +- Gems/PhysX/Code/Include/PhysX/UserDataTypes.h | 2 +- .../Code/Include/PhysX/UserDataTypes.inl | 4 +- .../PhysX/Code/Source/BaseColliderComponent.h | 5 +-- .../Source/Common/PhysXSceneQueryHelpers.cpp | 4 +- .../Code/Source/EditorColliderComponent.cpp | 11 +++-- .../Code/Source/EditorColliderComponent.h | 9 ++-- .../Code/Source/EditorRigidBodyComponent.cpp | 11 +++-- .../Code/Source/EditorRigidBodyComponent.h | 9 ++-- .../Source/EditorShapeColliderComponent.cpp | 13 +++--- .../Source/EditorShapeColliderComponent.h | 9 ++-- .../CharacterControllerComponent.cpp | 17 +++++--- .../Components/CharacterControllerComponent.h | 9 ++-- .../Components/CharacterGameplayComponent.cpp | 3 +- .../Components/RagdollComponent.cpp | 14 +++++-- .../Components/RagdollComponent.h | 9 ++-- Gems/PhysX/Code/Source/RigidBodyComponent.cpp | 13 +++--- Gems/PhysX/Code/Source/RigidBodyComponent.h | 9 ++-- .../PhysXSceneSimulationEventCallback.cpp | 8 ++-- .../Code/Source/StaticRigidBodyComponent.cpp | 23 ++++------- .../Code/Source/StaticRigidBodyComponent.h | 12 +++--- .../Code/Tests/CharacterControllerTests.cpp | 10 ++--- .../PhysX/Code/Tests/ColliderScalingTests.cpp | 6 +-- Gems/PhysX/Code/Tests/EditorTestUtilities.cpp | 2 +- .../Code/Tests/PhysXComponentBusTests.cpp | 24 +++++------ Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 8 ++-- Gems/PhysX/Code/Tests/RagdollTests.cpp | 2 +- .../Tests/ShapeColliderComponentTests.cpp | 12 +++--- Gems/PhysX/Code/physx_files.cmake | 1 - .../SurfaceDataColliderComponent.cpp | 6 +-- .../SurfaceDataColliderComponentTest.cpp | 11 ++--- 43 files changed, 203 insertions(+), 192 deletions(-) rename Code/Framework/AzFramework/AzFramework/Physics/{WorldBodyBus.h => Components/SimulatedBodyComponentBus.h} (54%) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h b/Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h similarity index 54% rename from Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h rename to Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h index 943e03d0f3..ac6d44af8b 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h @@ -19,44 +19,29 @@ namespace AzPhysics { - struct SimulatedBody; -} - -namespace Physics -{ - //! Requests for generic physical world bodies - class WorldBodyRequests + //! Requests for physics simulated body components. + class SimulatedBodyComponentRequests : public AZ::ComponentBus { public: using MutexType = AZStd::recursive_mutex; - //! Enable physics for this body + //! Enable physics for this body. virtual void EnablePhysics() = 0; - //! Disable physics for this body + //! Disable physics for this body. virtual void DisablePhysics() = 0; - //! Retrieve whether physics is enabled for this body + //! Retrieve whether physics is enabled for this body. virtual bool IsPhysicsEnabled() const = 0; - //! Retrieves the AABB(aligned-axis bounding box) for this body + //! Retrieves the AABB(aligned-axis bounding box) for this body. virtual AZ::Aabb GetAabb() const = 0; - //! Retrieves current WorldBody* for this body. Note: Do not hold a reference to AzPhysics::SimulatedBody* as could be deleted - virtual AzPhysics::SimulatedBody* GetWorldBody() = 0; - - //! Perform a single-object raycast against this body + //! Get the Simulated Body Handle for this body. + virtual AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const = 0; + //! Retrieves current WorldBody* for this body. + //! @note Do not hold a reference to AzPhysics::SimulatedBody* as it could be deleted or moved. + virtual AzPhysics::SimulatedBody* GetSimulatedBody() = 0; + //! Perform a single-object raycast against this body. virtual AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) = 0; }; - using WorldBodyRequestBus = AZ::EBus; - - //! Notifications for generic physical world bodies - class WorldBodyNotifications - : public AZ::ComponentBus - { - public: - //! Notification for physics enabled - virtual void OnPhysicsEnabled() = 0; - //! Notification for physics disabled - virtual void OnPhysicsDisabled() = 0; - }; - using WorldBodyNotificationBus = AZ::EBus; + using SimulatedBodyComponentRequestsBus = AZ::EBus; } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp index ae8f4308df..b5f113582b 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,19 +39,19 @@ namespace Physics { namespace ReflectionUtils { - void ReflectWorldBodyBus(AZ::ReflectContext* context) + void ReflectSimulatedBodyComponentRequestsBus(AZ::ReflectContext* context) { if (auto* behaviorContext = azrtti_cast(context)) { - behaviorContext->EBus("WorldBodyRequestBus") + behaviorContext->EBus("SimulatedBodyComponentRequestBus") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Module, "physics") ->Attribute(AZ::Script::Attributes::Category, "PhysX") - ->Event("EnablePhysics", &WorldBodyRequests::EnablePhysics) - ->Event("DisablePhysics", &WorldBodyRequests::DisablePhysics) - ->Event("IsPhysicsEnabled", &WorldBodyRequests::IsPhysicsEnabled) - ->Event("GetAabb", &WorldBodyRequests::GetAabb) - ->Event("RayCast", &WorldBodyRequests::RayCast) + ->Event("EnablePhysics", &AzPhysics::SimulatedBodyComponentRequests::EnablePhysics) + ->Event("DisablePhysics", &AzPhysics::SimulatedBodyComponentRequests::DisablePhysics) + ->Event("IsPhysicsEnabled", &AzPhysics::SimulatedBodyComponentRequests::IsPhysicsEnabled) + ->Event("GetAabb", &AzPhysics::SimulatedBodyComponentRequests::GetAabb) + ->Event("RayCast", &AzPhysics::SimulatedBodyComponentRequests::RayCast) ; } } @@ -131,7 +131,7 @@ namespace Physics AnimationConfiguration::Reflect(context); CharacterConfiguration::Reflect(context); AzPhysics::SimulatedBody::Reflect(context); - ReflectWorldBodyBus(context); + ReflectSimulatedBodyComponentRequestsBus(context); CollisionFilteringRequests::Reflect(context); AzPhysics::SceneQuery::ReflectSceneQueryObjects(context); ReflectWindBus(context); diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index 88f68d8bab..1b1cd49aa7 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -213,6 +213,12 @@ set(FILES StreamingInstall/StreamingInstall.cpp StreamingInstall/StreamingInstallRequests.h StreamingInstall/StreamingInstallNotifications.h + Physics/Collision/CollisionEvents.h + Physics/Collision/CollisionEvents.cpp + Physics/Collision/CollisionLayers.h + Physics/Collision/CollisionLayers.cpp + Physics/Collision/CollisionGroups.h + Physics/Collision/CollisionGroups.cpp Physics/Common/PhysicsSceneQueries.h Physics/Common/PhysicsSceneQueries.cpp Physics/Common/PhysicsEvents.h @@ -223,12 +229,7 @@ set(FILES Physics/Common/PhysicsSimulatedBodyEvents.h Physics/Common/PhysicsSimulatedBodyEvents.cpp Physics/Common/PhysicsTypes.h - Physics/Collision/CollisionEvents.h - Physics/Collision/CollisionEvents.cpp - Physics/Collision/CollisionLayers.h - Physics/Collision/CollisionLayers.cpp - Physics/Collision/CollisionGroups.h - Physics/Collision/CollisionGroups.cpp + Physics/Components/SimulatedBodyComponentBus.h Physics/Configuration/CollisionConfiguration.h Physics/Configuration/CollisionConfiguration.cpp Physics/Configuration/RigidBodyConfiguration.h @@ -265,7 +266,6 @@ set(FILES Physics/ShapeConfiguration.h Physics/ShapeConfiguration.cpp Physics/SystemBus.h - Physics/WorldBodyBus.h Physics/ColliderComponentBus.h Physics/RagdollPhysicsBus.h Physics/CharacterPhysicsDataBus.h diff --git a/Gems/Blast/Code/Include/Blast/BlastActor.h b/Gems/Blast/Code/Include/Blast/BlastActor.h index 4fb88b77ec..1c79eaef24 100644 --- a/Gems/Blast/Code/Include/Blast/BlastActor.h +++ b/Gems/Blast/Code/Include/Blast/BlastActor.h @@ -51,8 +51,8 @@ namespace Blast virtual AZ::Transform GetTransform() const = 0; virtual const BlastFamily& GetFamily() const = 0; virtual Nv::Blast::TkActor& GetTkActor() const = 0; - virtual AzPhysics::SimulatedBody* GetWorldBody() = 0; - virtual const AzPhysics::SimulatedBody* GetWorldBody() const = 0; + virtual AzPhysics::SimulatedBody* GetSimulatedBody() = 0; + virtual const AzPhysics::SimulatedBody* GetSimulatedBody() const = 0; virtual const AZ::Entity* GetEntity() const = 0; virtual const AZStd::vector& GetChunkIndices() const = 0; virtual bool IsStatic() const = 0; diff --git a/Gems/Blast/Code/Source/Actor/BlastActorImpl.cpp b/Gems/Blast/Code/Source/Actor/BlastActorImpl.cpp index c7c1c5a12e..1f05793b4b 100644 --- a/Gems/Blast/Code/Source/Actor/BlastActorImpl.cpp +++ b/Gems/Blast/Code/Source/Actor/BlastActorImpl.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -164,7 +164,7 @@ namespace Blast AZ::Transform BlastActorImpl::GetTransform() const { - return GetWorldBody()->GetTransform(); + return GetSimulatedBody()->GetTransform(); } const BlastFamily& BlastActorImpl::GetFamily() const @@ -177,19 +177,19 @@ namespace Blast return m_tkActor; } - AzPhysics::SimulatedBody* BlastActorImpl::GetWorldBody() + AzPhysics::SimulatedBody* BlastActorImpl::GetSimulatedBody() { AzPhysics::SimulatedBody* worldBody = nullptr; - Physics::WorldBodyRequestBus::EventResult( - worldBody, m_entity->GetId(), &Physics::WorldBodyRequests::GetWorldBody); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult( + worldBody, m_entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody); return worldBody; } - const AzPhysics::SimulatedBody* BlastActorImpl::GetWorldBody() const + const AzPhysics::SimulatedBody* BlastActorImpl::GetSimulatedBody() const { AzPhysics::SimulatedBody* worldBody = nullptr; - Physics::WorldBodyRequestBus::EventResult( - worldBody, m_entity->GetId(), &Physics::WorldBodyRequests::GetWorldBody); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult( + worldBody, m_entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody); return worldBody; } diff --git a/Gems/Blast/Code/Source/Actor/BlastActorImpl.h b/Gems/Blast/Code/Source/Actor/BlastActorImpl.h index 3b9b77652a..3b686b3641 100644 --- a/Gems/Blast/Code/Source/Actor/BlastActorImpl.h +++ b/Gems/Blast/Code/Source/Actor/BlastActorImpl.h @@ -12,7 +12,6 @@ #pragma once #include -#include #include #include #include @@ -45,8 +44,8 @@ namespace Blast const AZStd::vector& GetChunkIndices() const override; bool IsStatic() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; - const AzPhysics::SimulatedBody* GetWorldBody() const override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + const AzPhysics::SimulatedBody* GetSimulatedBody() const override; protected: //! We want to be able to override this function for testing purposes, because diff --git a/Gems/Blast/Code/Source/Actor/ShapesProvider.h b/Gems/Blast/Code/Source/Actor/ShapesProvider.h index 00a385a790..4e737be080 100644 --- a/Gems/Blast/Code/Source/Actor/ShapesProvider.h +++ b/Gems/Blast/Code/Source/Actor/ShapesProvider.h @@ -11,7 +11,6 @@ */ #pragma once -#include #include #include diff --git a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp index 90bcb633bc..841163d2ab 100644 --- a/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp +++ b/Gems/Blast/Code/Source/Components/BlastFamilyComponent.cpp @@ -467,7 +467,7 @@ namespace Blast } // transform all added lines from local to global - const AZ::Transform& localToGlobal = blastActor->GetWorldBody()->GetTransform(); + const AZ::Transform& localToGlobal = blastActor->GetSimulatedBody()->GetTransform(); for (uint32_t i = lineStartIndex; i < debugRenderBuffer.m_lines.size(); i++) { DebugLine& line = debugRenderBuffer.m_lines[i]; @@ -485,7 +485,7 @@ namespace Blast { for (auto actor : m_family->GetActorTracker().GetActors()) { - auto worldBody = actor->GetWorldBody(); + auto worldBody = actor->GetSimulatedBody(); if (actor->IsStatic()) { AZ::Vector3 gravity = AzPhysics::DefaultGravity; diff --git a/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp b/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp index 74bba48d3c..3695a9f07e 100644 --- a/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp +++ b/Gems/Blast/Code/Source/Family/ActorRenderManager.cpp @@ -74,7 +74,7 @@ namespace Blast { if (m_chunkActors[chunkId]) { - m_meshFeatureProcessor->SetTransform(m_chunkMeshHandles[chunkId], m_chunkActors[chunkId]->GetWorldBody()->GetTransform(), m_scale); + m_meshFeatureProcessor->SetTransform(m_chunkMeshHandles[chunkId], m_chunkActors[chunkId]->GetSimulatedBody()->GetTransform(), m_scale); } } } diff --git a/Gems/Blast/Code/Source/Family/ActorTracker.cpp b/Gems/Blast/Code/Source/Family/ActorTracker.cpp index 5ceae87cd6..abcbdf5da3 100644 --- a/Gems/Blast/Code/Source/Family/ActorTracker.cpp +++ b/Gems/Blast/Code/Source/Family/ActorTracker.cpp @@ -22,12 +22,12 @@ namespace Blast { m_actors.emplace(actor); m_entityIdToActor.emplace(actor->GetEntity()->GetId(), actor); - m_bodyToActor.emplace(actor->GetWorldBody(), actor); + m_bodyToActor.emplace(actor->GetSimulatedBody(), actor); } void ActorTracker::RemoveActor(BlastActor* actor) { - m_bodyToActor.erase(actor->GetWorldBody()); + m_bodyToActor.erase(actor->GetSimulatedBody()); m_entityIdToActor.erase(actor->GetEntity()->GetId()); m_actors.erase(actor); } diff --git a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp index 2b3f2fcc82..d276486548 100644 --- a/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp +++ b/Gems/Blast/Code/Source/Family/BlastFamilyImpl.cpp @@ -179,7 +179,7 @@ namespace Blast { return; } - parentBody = parentActor->GetWorldBody(); + parentBody = parentActor->GetSimulatedBody(); const bool parentStatic = parentActor->IsStatic(); @@ -493,7 +493,7 @@ namespace Blast } // transform all added lines from local to global - AZ::Transform localToGlobal = blastActor->GetWorldBody()->GetTransform(); + AZ::Transform localToGlobal = blastActor->GetSimulatedBody()->GetTransform(); for (uint32_t i = lineStartIndex; i < debugRenderBuffer.m_lines.size(); i++) { DebugLine& line = debugRenderBuffer.m_lines[i]; diff --git a/Gems/Blast/Code/Source/Family/DamageManager.cpp b/Gems/Blast/Code/Source/Family/DamageManager.cpp index 1f275b99a6..f20d46cea3 100644 --- a/Gems/Blast/Code/Source/Family/DamageManager.cpp +++ b/Gems/Blast/Code/Source/Family/DamageManager.cpp @@ -124,7 +124,7 @@ namespace Blast AZ::Vector3 DamageManager::TransformToLocal(BlastActor& actor, const AZ::Vector3& globalPosition) { - const AZ::Transform hitToActorTransform(actor.GetWorldBody()->GetTransform().GetInverse()); + const AZ::Transform hitToActorTransform(actor.GetSimulatedBody()->GetTransform().GetInverse()); const AZ::Vector3 hitPos = hitToActorTransform.TransformPoint(globalPosition); return hitPos; } diff --git a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h index 95a16c311f..a1e57a6917 100644 --- a/Gems/Blast/Code/Tests/Mocks/BlastMocks.h +++ b/Gems/Blast/Code/Tests/Mocks/BlastMocks.h @@ -284,12 +284,12 @@ namespace Blast return m_transform; } - AzPhysics::SimulatedBody* GetWorldBody() override + AzPhysics::SimulatedBody* GetSimulatedBody() override { return m_worldBody.get(); } - const AzPhysics::SimulatedBody* GetWorldBody() const override + const AzPhysics::SimulatedBody* GetSimulatedBody() const override { return m_worldBody.get(); } diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h index 606bdea10c..8b6b5fa0d4 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h @@ -88,7 +88,7 @@ namespace PhysX Physics::RagdollNode* GetRagdollNode() const; void SetRagdollNode(Physics::RagdollNode* ragdollNode); - AzPhysics::SimulatedBody* GetWorldBody() const; + AzPhysics::SimulatedBody* GetSimulatedBody() const; private: diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl index a24fdb27b2..d6897f9484 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl @@ -77,7 +77,7 @@ namespace PhysX inline AzPhysics::SimulatedBodyHandle ActorData::GetBodyHandle() const { - AzPhysics::SimulatedBody* body = GetWorldBody(); + AzPhysics::SimulatedBody* body = GetSimulatedBody(); if (body) { return body->m_bodyHandle; @@ -125,7 +125,7 @@ namespace PhysX m_payload.m_ragdollNode = ragdollNode; } - inline AzPhysics::SimulatedBody* ActorData::GetWorldBody() const + inline AzPhysics::SimulatedBody* ActorData::GetSimulatedBody() const { if (m_payload.m_rigidBody) { diff --git a/Gems/PhysX/Code/Source/BaseColliderComponent.h b/Gems/PhysX/Code/Source/BaseColliderComponent.h index cf4f43fb03..b23e6f1f09 100644 --- a/Gems/PhysX/Code/Source/BaseColliderComponent.h +++ b/Gems/PhysX/Code/Source/BaseColliderComponent.h @@ -100,10 +100,9 @@ namespace PhysX required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); } - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + static void GetIncompatibleServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - // Not compatible with cry engine colliders - incompatible.push_back(AZ_CRC("ColliderService", 0x902d4e93)); + } // AZ::Component diff --git a/Gems/PhysX/Code/Source/Common/PhysXSceneQueryHelpers.cpp b/Gems/PhysX/Code/Source/Common/PhysXSceneQueryHelpers.cpp index 9903a311af..4b0a8f7329 100644 --- a/Gems/PhysX/Code/Source/Common/PhysXSceneQueryHelpers.cpp +++ b/Gems/PhysX/Code/Source/Common/PhysXSceneQueryHelpers.cpp @@ -258,9 +258,9 @@ namespace PhysX { ActorData* userData = Utils::GetUserData(actor); Physics::Shape* shape = Utils::GetUserData(pxShape); - if (userData != nullptr && userData->GetWorldBody()) + if (userData != nullptr && userData->GetSimulatedBody()) { - return GetPxHitType(m_filterCallback(userData->GetWorldBody(), shape)); + return GetPxHitType(m_filterCallback(userData->GetSimulatedBody(), shape)); } } return m_hitType; diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index 2dc8fc97ec..2785ab19e1 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -387,7 +387,7 @@ namespace PhysX void EditorColliderComponent::Deactivate() { - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); m_colliderDebugDraw.Disconnect(); AZ::Data::AssetBus::MultiHandler::BusDisconnect(); m_nonUniformScaleChangedHandler.Disconnect(); @@ -642,7 +642,7 @@ namespace PhysX m_colliderDebugDraw.ClearCachedGeometry(); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } AZ::Data::Asset EditorColliderComponent::GetMeshAsset() const @@ -1072,7 +1072,7 @@ namespace PhysX return AZ::Aabb::CreateNull(); } - AzPhysics::SimulatedBody* EditorColliderComponent::GetWorldBody() + AzPhysics::SimulatedBody* EditorColliderComponent::GetSimulatedBody() { if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) { @@ -1084,6 +1084,11 @@ namespace PhysX return nullptr; } + AzPhysics::SimulatedBodyHandle EditorColliderComponent::GetSimulatedBodyHandle() const + { + return m_editorBodyHandle; + } + AzPhysics::SceneQueryHit EditorColliderComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_sceneInterface && m_editorBodyHandle != AzPhysics::InvalidSimulatedBodyHandle) diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.h b/Gems/PhysX/Code/Source/EditorColliderComponent.h index e78be1b959..1f9c00d4f5 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -105,7 +105,7 @@ namespace PhysX , private PhysX::ColliderShapeRequestBus::Handler , private AZ::Render::MeshComponentNotificationBus::Handler , private PhysX::EditorColliderComponentRequestBus::Handler - , private Physics::WorldBodyRequestBus::Handler + , private AzPhysics::SimulatedBodyComponentRequestsBus::Handler { public: AZ_RTTI(EditorColliderComponent, "{FD429282-A075-4966-857F-D0BBF186CFE6}", AzToolsFramework::Components::EditorComponentBase); @@ -205,12 +205,13 @@ namespace PhysX AZ::u32 OnConfigurationChanged(); void UpdateShapeConfigurationScale(); - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; // Mesh collider diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index fb663dd9a4..b6517b0499 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -265,14 +265,14 @@ namespace PhysX } CreateEditorWorldRigidBody(); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } void EditorRigidBodyComponent::Deactivate() { m_debugDisplayDataChangeHandler.Disconnect(); - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); m_nonUniformScaleChangedHandler.Disconnect(); m_sceneStartSimHandler.Disconnect(); Physics::ColliderComponentEventBus::Handler::BusDisconnect(); @@ -461,11 +461,16 @@ namespace PhysX return AZ::Aabb::CreateNull(); } - AzPhysics::SimulatedBody* EditorRigidBodyComponent::GetWorldBody() + AzPhysics::SimulatedBody* EditorRigidBodyComponent::GetSimulatedBody() { return m_editorBody; } + AzPhysics::SimulatedBodyHandle EditorRigidBodyComponent::GetSimulatedBodyHandle() const + { + return m_rigidBodyHandle; + } + AzPhysics::SceneQueryHit EditorRigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_editorBody) diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h index 2d42812292..b2b199e6be 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include @@ -49,7 +49,7 @@ namespace PhysX , protected AzFramework::EntityDebugDisplayEventBus::Handler , private AZ::TransformNotificationBus::Handler , private Physics::ColliderComponentEventBus::Handler - , private Physics::WorldBodyRequestBus::Handler + , private AzPhysics::SimulatedBodyComponentRequestsBus::Handler { public: AZ_EDITOR_COMPONENT(EditorRigidBodyComponent, "{F2478E6B-001A-4006-9D7E-DCB5A6B041DD}", AzToolsFramework::Components::EditorComponentBase); @@ -107,12 +107,13 @@ namespace PhysX // Physics::ColliderComponentEventBus void OnColliderChanged() override; - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; void CreateEditorWorldRigidBody(); diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp index aa1c945fa3..0a8bca33ea 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.cpp @@ -120,8 +120,6 @@ namespace PhysX void EditorShapeColliderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - // Not compatible with Legacy Cry Physics services - incompatible.push_back(AZ_CRC("ColliderService", 0x902d4e93)); incompatible.push_back(AZ_CRC("LegacyCryPhysicsService", 0xbb370351)); incompatible.push_back(AZ_CRC("PhysXShapeColliderService", 0x98a7e779)); } @@ -273,7 +271,7 @@ namespace PhysX m_editorBody = azdynamic_cast(m_sceneInterface->GetSimulatedBodyFromHandle(m_editorSceneHandle, m_editorBodyHandle)); } - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } AZ::u32 EditorShapeColliderComponent::OnConfigurationChanged() @@ -663,7 +661,7 @@ namespace PhysX void EditorShapeColliderComponent::Deactivate() { - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); m_colliderDebugDraw.Disconnect(); m_nonUniformScaleChangedHandler.Disconnect(); @@ -761,11 +759,16 @@ namespace PhysX return AZ::Aabb::CreateNull(); } - AzPhysics::SimulatedBody* EditorShapeColliderComponent::GetWorldBody() + AzPhysics::SimulatedBody* EditorShapeColliderComponent::GetSimulatedBody() { return m_editorBody; } + AzPhysics::SimulatedBodyHandle EditorShapeColliderComponent::GetSimulatedBodyHandle() const + { + return m_editorBodyHandle; + } + AzPhysics::SceneQueryHit EditorShapeColliderComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_editorBody) diff --git a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h index bbb14fe6a4..bcf5ac4eba 100644 --- a/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorShapeColliderComponent.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -68,7 +68,7 @@ namespace PhysX , protected DebugDraw::DisplayCallback , protected LmbrCentral::ShapeComponentNotificationsBus::Handler , private PhysX::ColliderShapeRequestBus::Handler - , protected Physics::WorldBodyRequestBus::Handler + , protected AzPhysics::SimulatedBodyComponentRequestsBus::Handler { public: AZ_EDITOR_COMPONENT(EditorShapeColliderComponent, "{2389DDC7-871B-42C6-9C95-2A679DDA0158}", @@ -120,12 +120,13 @@ namespace PhysX // handling for non-uniform scale void OnNonUniformScaleChanged(const AZ::Vector3& scale); - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; // LmbrCentral::ShapeComponentNotificationBus diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp index ca02554036..473e9534cb 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.cpp @@ -87,7 +87,7 @@ namespace PhysX AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId()); Physics::CharacterRequestBus::Handler::BusConnect(GetEntityId()); Physics::CollisionFilteringRequestBus::Handler::BusConnect(GetEntityId()); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } void CharacterControllerComponent::Deactivate() @@ -95,7 +95,7 @@ namespace PhysX DestroyController(); Physics::CollisionFilteringRequestBus::Handler::BusDisconnect(); - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::Handler::BusDisconnect(); Physics::CharacterRequestBus::Handler::BusDisconnect(); } @@ -215,11 +215,20 @@ namespace PhysX return AZ::Aabb::CreateNull(); } - AzPhysics::SimulatedBody* CharacterControllerComponent::GetWorldBody() + AzPhysics::SimulatedBody* CharacterControllerComponent::GetSimulatedBody() { return GetCharacter(); } + AzPhysics::SimulatedBodyHandle CharacterControllerComponent::GetSimulatedBodyHandle() const + { + if (m_controller) + { + return m_controller->m_bodyHandle; + } + return AzPhysics::InvalidSimulatedBodyHandle; + } + AzPhysics::SceneQueryHit CharacterControllerComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_controller) @@ -456,7 +465,5 @@ namespace PhysX m_preSimulateHandler.Disconnect(); CharacterControllerRequestBus::Handler::BusDisconnect(); - - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsDisabled); } } // namespace PhysX diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h index ca956b1757..31f5051ac4 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterControllerComponent.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,7 +35,7 @@ namespace PhysX class CharacterControllerComponent : public AZ::Component , public Physics::CharacterRequestBus::Handler - , public Physics::WorldBodyRequestBus::Handler + , public AzPhysics::SimulatedBodyComponentRequestsBus::Handler , public AZ::TransformNotificationBus::Handler , public CharacterControllerRequestBus::Handler , public Physics::CollisionFilteringRequestBus::Handler @@ -99,12 +99,13 @@ namespace PhysX bool IsPresent() const override { return IsPhysicsEnabled(); } Physics::Character* GetCharacter() override; - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; // CharacterControllerRequestBus diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp index e0c3ba40ba..70373f8db2 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/CharacterGameplayComponent.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -158,7 +157,7 @@ namespace PhysX void CharacterGameplayComponent::Activate() { AzPhysics::SimulatedBody* worldBody = nullptr; - Physics::WorldBodyRequestBus::EventResult(worldBody, GetEntityId(), &Physics::WorldBodyRequests::GetWorldBody); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(worldBody, GetEntityId(), &AzPhysics::SimulatedBodyComponentRequests::GetSimulatedBody); if (worldBody) { if (auto* sceneInterface = AZ::Interface::Get()) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp index 85060445fc..4c58187fb8 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.cpp @@ -257,11 +257,20 @@ namespace PhysX return AZ::Aabb::CreateNull(); } - AzPhysics::SimulatedBody* RagdollComponent::GetWorldBody() + AzPhysics::SimulatedBody* RagdollComponent::GetSimulatedBody() { return GetRagdoll(); } + AzPhysics::SimulatedBodyHandle RagdollComponent::GetSimulatedBodyHandle() const + { + if (m_ragdoll) + { + return m_ragdoll->m_bodyHandle; + } + return AzPhysics::InvalidSimulatedBodyHandle; + } + AzPhysics::SceneQueryHit RagdollComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_ragdoll) @@ -357,7 +366,7 @@ namespace PhysX } AzFramework::RagdollPhysicsRequestBus::Handler::BusConnect(GetEntityId()); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); AzFramework::RagdollPhysicsNotificationBus::Event(GetEntityId(), &AzFramework::RagdollPhysicsNotifications::OnRagdollActivated); @@ -367,7 +376,6 @@ namespace PhysX { if (m_ragdoll) { - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); AzFramework::RagdollPhysicsRequestBus::Handler::BusDisconnect(); AzFramework::RagdollPhysicsNotificationBus::Event(GetEntityId(), &AzFramework::RagdollPhysicsNotifications::OnRagdollDeactivated); diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h index 1b616dda79..e7397af877 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/Components/RagdollComponent.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace AzPhysics { @@ -28,7 +28,7 @@ namespace PhysX class RagdollComponent : public AZ::Component , public AzFramework::RagdollPhysicsRequestBus::Handler - , public Physics::WorldBodyRequestBus::Handler + , public AzPhysics::SimulatedBodyComponentRequestsBus::Handler , public AzFramework::CharacterPhysicsDataNotificationBus::Handler { public: @@ -81,12 +81,13 @@ namespace PhysX void SetNodeState(size_t nodeIndex, const Physics::RagdollNodeState& nodeState) override; Physics::RagdollNode* GetNode(size_t nodeIndex) const override; - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; // CharacterPhysicsDataNotificationBus diff --git a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp index 8984343fe5..cf2e306cc7 100644 --- a/Gems/PhysX/Code/Source/RigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/RigidBodyComponent.cpp @@ -189,7 +189,7 @@ namespace PhysX } Physics::RigidBodyRequestBus::Handler::BusDisconnect(); - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::MultiHandler::BusDisconnect(); m_sceneFinishSimHandler.Disconnect(); AZ::TickBus::Handler::BusDisconnect(); @@ -309,7 +309,7 @@ namespace PhysX AZ::TickBus::Handler::BusConnect(); AZ::TransformNotificationBus::MultiHandler::BusConnect(GetEntityId()); Physics::RigidBodyRequestBus::Handler::BusConnect(GetEntityId()); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } void RigidBodyComponent::EnablePhysics() @@ -341,7 +341,6 @@ namespace PhysX m_initialScale = transform.ExtractScale(); Physics::RigidBodyNotificationBus::Event(GetEntityId(), &Physics::RigidBodyNotificationBus::Events::OnPhysicsEnabled); - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsEnabled); } void RigidBodyComponent::DisablePhysics() @@ -352,7 +351,6 @@ namespace PhysX } Physics::RigidBodyNotificationBus::Event(GetEntityId(), &Physics::RigidBodyNotificationBus::Events::OnPhysicsDisabled); - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsDisabled); } bool RigidBodyComponent::IsPhysicsEnabled() const @@ -526,11 +524,16 @@ namespace PhysX return m_rigidBody; } - AzPhysics::SimulatedBody* RigidBodyComponent::GetWorldBody() + AzPhysics::SimulatedBody* RigidBodyComponent::GetSimulatedBody() { return m_rigidBody; } + AzPhysics::SimulatedBodyHandle RigidBodyComponent::GetSimulatedBodyHandle() const + { + return m_rigidBodyHandle; + } + AzPhysics::SceneQueryHit RigidBodyComponent::RayCast(const AzPhysics::RayCastRequest& request) { if (m_rigidBody) diff --git a/Gems/PhysX/Code/Source/RigidBodyComponent.h b/Gems/PhysX/Code/Source/RigidBodyComponent.h index c46e136669..12c4d3f5ff 100644 --- a/Gems/PhysX/Code/Source/RigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/RigidBodyComponent.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,7 +35,7 @@ namespace PhysX class RigidBodyComponent : public AZ::Component , public Physics::RigidBodyRequestBus::Handler - , public Physics::WorldBodyRequestBus::Handler + , public AzPhysics::SimulatedBodyComponentRequestsBus::Handler , public AZ::TickBus::Handler , public AzFramework::SliceGameEntityOwnershipServiceNotificationBus::Handler , protected AZ::TransformNotificationBus::MultiHandler @@ -120,8 +120,9 @@ namespace PhysX void SetSleepThreshold(float threshold) override; AzPhysics::RigidBody* GetRigidBody() override; - // WorldBodyRequestBus - AzPhysics::SimulatedBody* GetWorldBody() override; + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; // SliceGameEntityOwnershipServiceNotificationBus void OnSliceInstantiated(const AZ::Data::AssetId&, const AZ::SliceComponent::SliceInstanceAddress&, diff --git a/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationEventCallback.cpp b/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationEventCallback.cpp index fbe7b36a03..c19e047062 100644 --- a/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationEventCallback.cpp +++ b/Gems/PhysX/Code/Source/Scene/PhysXSceneSimulationEventCallback.cpp @@ -83,8 +83,8 @@ namespace PhysX continue; } - AzPhysics::SimulatedBody* body1 = actorData1->GetWorldBody(); - AzPhysics::SimulatedBody* body2 = actorData2->GetWorldBody(); + AzPhysics::SimulatedBody* body1 = actorData1->GetSimulatedBody(); + AzPhysics::SimulatedBody* body2 = actorData2->GetSimulatedBody(); if (!body1 || !body2) { @@ -161,7 +161,7 @@ namespace PhysX } ActorData* triggerBodyActorData = Utils::GetUserData(triggerPair.triggerActor); - AzPhysics::SimulatedBody* triggerBody = triggerBodyActorData->GetWorldBody(); + AzPhysics::SimulatedBody* triggerBody = triggerBodyActorData->GetSimulatedBody(); if (!triggerBody) { AZ_Error("PhysX", false, "onTrigger:: trigger body was invalid"); @@ -174,7 +174,7 @@ namespace PhysX } ActorData* otherActorData = Utils::GetUserData(triggerPair.otherActor); - AzPhysics::SimulatedBody* otherBody = otherActorData->GetWorldBody(); + AzPhysics::SimulatedBody* otherBody = otherActorData->GetSimulatedBody(); if (!otherBody) { AZ_Error("PhysX", false, "onTrigger:: otherBody was invalid"); diff --git a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp index 9387884999..79e5ea8204 100644 --- a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.cpp @@ -62,8 +62,6 @@ namespace PhysX void StaticRigidBodyComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - // Not compatible with cry engine colliders - incompatible.push_back(AZ_CRC("ColliderService", 0x902d4e93)); // There can be only one StaticRigidBodyComponent per entity incompatible.push_back(AZ_CRC("PhysXStaticRigidBodyService", 0xaae8973b)); // Cannot have both StaticRigidBodyComponent and RigidBodyComponent @@ -75,11 +73,6 @@ namespace PhysX dependent.push_back(AZ_CRC("PhysXColliderService", 0x4ff43f7c)); } - PhysX::StaticRigidBody* StaticRigidBodyComponent::GetStaticRigidBody() - { - return m_staticRigidBody; - } - void StaticRigidBodyComponent::InitStaticRigidBody() { AZ::Transform transform = AZ::Transform::CreateIdentity(); @@ -117,8 +110,7 @@ namespace PhysX InitStaticRigidBody(); - Physics::WorldBodyRequestBus::Handler::BusConnect(GetEntityId()); - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsEnabled); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(GetEntityId()); } void StaticRigidBodyComponent::Deactivate() @@ -130,7 +122,7 @@ namespace PhysX m_staticRigidBody = nullptr; } - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::Handler::BusDisconnect(); } @@ -149,8 +141,6 @@ namespace PhysX { sceneInterface->EnableSimulationOfBody(m_attachedSceneHandle, m_staticRigidBodyHandle); } - - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsEnabled); } void StaticRigidBodyComponent::DisablePhysics() @@ -159,8 +149,6 @@ namespace PhysX { sceneInterface->DisableSimulationOfBody(m_attachedSceneHandle, m_staticRigidBodyHandle); } - - Physics::WorldBodyNotificationBus::Event(GetEntityId(), &Physics::WorldBodyNotifications::OnPhysicsDisabled); } bool StaticRigidBodyComponent::IsPhysicsEnabled() const @@ -173,7 +161,12 @@ namespace PhysX return m_staticRigidBody->GetAabb(); } - AzPhysics::SimulatedBody* StaticRigidBodyComponent::GetWorldBody() + AzPhysics::SimulatedBodyHandle StaticRigidBodyComponent::GetSimulatedBodyHandle() const + { + return m_staticRigidBodyHandle; + } + + AzPhysics::SimulatedBody* StaticRigidBodyComponent::GetSimulatedBody() { return m_staticRigidBody; } diff --git a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h index f846329ca0..660521ab7a 100644 --- a/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h +++ b/Gems/PhysX/Code/Source/StaticRigidBodyComponent.h @@ -13,7 +13,7 @@ #include #include -#include +#include #include namespace AzPhysics @@ -27,7 +27,7 @@ namespace PhysX class StaticRigidBodyComponent final : public AZ::Component - , public Physics::WorldBodyRequestBus::Handler + , public AzPhysics::SimulatedBodyComponentRequestsBus::Handler , private AZ::TransformNotificationBus::Handler { public: @@ -44,14 +44,14 @@ namespace PhysX static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - PhysX::StaticRigidBody* GetStaticRigidBody(); - - // WorldBodyRequestBus + // AzPhysics::SimulatedBodyComponentRequestsBus::Handler overrides ... void EnablePhysics() override; void DisablePhysics() override; bool IsPhysicsEnabled() const override; AZ::Aabb GetAabb() const override; - AzPhysics::SimulatedBody* GetWorldBody() override; + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override; + AzPhysics::SimulatedBody* GetSimulatedBody() override; + AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) override; private: diff --git a/Gems/PhysX/Code/Tests/CharacterControllerTests.cpp b/Gems/PhysX/Code/Tests/CharacterControllerTests.cpp index 218571c01c..4e111787e6 100644 --- a/Gems/PhysX/Code/Tests/CharacterControllerTests.cpp +++ b/Gems/PhysX/Code/Tests/CharacterControllerTests.cpp @@ -460,14 +460,14 @@ namespace PhysX characterEntity->Activate(); bool physicsEnabled = false; - Physics::WorldBodyRequestBus::EventResult(physicsEnabled, characterEntity->GetId(), - &Physics::WorldBodyRequestBus::Events::IsPhysicsEnabled); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(physicsEnabled, characterEntity->GetId(), + &AzPhysics::SimulatedBodyComponentRequestsBus::Events::IsPhysicsEnabled); EXPECT_TRUE(physicsEnabled); // when physics is disabled - Physics::WorldBodyRequestBus::Event(characterEntity->GetId(), &Physics::WorldBodyRequestBus::Events::DisablePhysics); - Physics::WorldBodyRequestBus::EventResult(physicsEnabled, characterEntity->GetId(), - &Physics::WorldBodyRequestBus::Events::IsPhysicsEnabled); + AzPhysics::SimulatedBodyComponentRequestsBus::Event(characterEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequestsBus::Events::DisablePhysics); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(physicsEnabled, characterEntity->GetId(), + &AzPhysics::SimulatedBodyComponentRequestsBus::Events::IsPhysicsEnabled); EXPECT_FALSE(physicsEnabled); // expect no error occurs when sending common events diff --git a/Gems/PhysX/Code/Tests/ColliderScalingTests.cpp b/Gems/PhysX/Code/Tests/ColliderScalingTests.cpp index 51a11c7605..ae65fcfc23 100644 --- a/Gems/PhysX/Code/Tests/ColliderScalingTests.cpp +++ b/Gems/PhysX/Code/Tests/ColliderScalingTests.cpp @@ -77,7 +77,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const AZ::Aabb aabb = staticBody->GetAabb(); EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(5.6045f, 4.9960f, 11.7074f), 1e-3f)); @@ -153,7 +153,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const AZ::Aabb aabb = staticBody->GetAabb(); @@ -231,7 +231,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const AZ::Aabb aabb = staticBody->GetAabb(); diff --git a/Gems/PhysX/Code/Tests/EditorTestUtilities.cpp b/Gems/PhysX/Code/Tests/EditorTestUtilities.cpp index 94d86e27c7..043bd60acd 100644 --- a/Gems/PhysX/Code/Tests/EditorTestUtilities.cpp +++ b/Gems/PhysX/Code/Tests/EditorTestUtilities.cpp @@ -121,7 +121,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const auto* pxRigidStatic = static_cast(staticBody->GetNativePointer()); PHYSX_SCENE_READ_LOCK(pxRigidStatic->getScene()); diff --git a/Gems/PhysX/Code/Tests/PhysXComponentBusTests.cpp b/Gems/PhysX/Code/Tests/PhysXComponentBusTests.cpp index 0422746f80..d9d6d47b94 100644 --- a/Gems/PhysX/Code/Tests/PhysXComponentBusTests.cpp +++ b/Gems/PhysX/Code/Tests/PhysXComponentBusTests.cpp @@ -613,17 +613,17 @@ namespace PhysX // Create 3 colliders, one of each type and check that the AABB of their body is the expected EntityPtr box = TestUtils::CreateBoxEntity(m_testSceneHandle, AZ::Vector3(0, 0, 0), AZ::Vector3(32, 32, 32)); AZ::Aabb boxAABB; - Physics::WorldBodyRequestBus::EventResult(boxAABB, box->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(boxAABB, box->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(boxAABB.GetMin().IsClose(AZ::Vector3(-16, -16, -16)) && boxAABB.GetMax().IsClose(AZ::Vector3(16, 16, 16))); EntityPtr sphere = TestUtils::CreateSphereEntity(m_testSceneHandle, AZ::Vector3(-100, 0, 0), 16); AZ::Aabb sphereAABB; - Physics::WorldBodyRequestBus::EventResult(sphereAABB, sphere->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(sphereAABB, sphere->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(sphereAABB.GetMin().IsClose(AZ::Vector3(-16 -100, -16, -16)) && sphereAABB.GetMax().IsClose(AZ::Vector3(16 -100, 16, 16))); EntityPtr capsule = TestUtils::CreateCapsuleEntity(m_testSceneHandle, AZ::Vector3(100, 0, 0), 128, 16); AZ::Aabb capsuleAABB; - Physics::WorldBodyRequestBus::EventResult(capsuleAABB, capsule->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(capsuleAABB, capsule->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(capsuleAABB.GetMin().IsClose(AZ::Vector3(-16 +100, -16, -64)) && capsuleAABB.GetMax().IsClose(AZ::Vector3(16 +100, 16, 64))); } @@ -632,17 +632,17 @@ namespace PhysX // Create 3 colliders, one of each type and check that the AABB of their body is the expected EntityPtr box = TestUtils::CreateStaticBoxEntity(m_testSceneHandle, AZ::Vector3(0, 0, 0), AZ::Vector3(32, 32, 32)); AZ::Aabb boxAABB; - Physics::WorldBodyRequestBus::EventResult(boxAABB, box->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(boxAABB, box->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(boxAABB.GetMin().IsClose(AZ::Vector3(-16, -16, -16)) && boxAABB.GetMax().IsClose(AZ::Vector3(16, 16, 16))); EntityPtr sphere = TestUtils::CreateStaticSphereEntity(m_testSceneHandle, AZ::Vector3(-100, 0, 0), 16); AZ::Aabb sphereAABB; - Physics::WorldBodyRequestBus::EventResult(sphereAABB, sphere->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(sphereAABB, sphere->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(sphereAABB.GetMin().IsClose(AZ::Vector3(-16 -100, -16, -16)) && sphereAABB.GetMax().IsClose(AZ::Vector3(16 -100, 16, 16))); EntityPtr capsule = TestUtils::CreateStaticCapsuleEntity(m_testSceneHandle, AZ::Vector3(100, 0, 0), 128, 16); AZ::Aabb capsuleAABB; - Physics::WorldBodyRequestBus::EventResult(capsuleAABB, capsule->GetId(), &Physics::WorldBodyRequests::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(capsuleAABB, capsule->GetId(), &AzPhysics::SimulatedBodyComponentRequests::GetAabb); EXPECT_TRUE(capsuleAABB.GetMin().IsClose(AZ::Vector3(-16 +100, -16, -64)) && capsuleAABB.GetMax().IsClose(AZ::Vector3(16 +100, 16, 64))); } @@ -662,19 +662,19 @@ namespace PhysX request.m_direction = AZ::Vector3(0, 0, -1); request.m_distance = 200.f; - Physics::WorldBodyRequestBus::Event(entity->GetId(), &Physics::WorldBodyRequests::DisablePhysics); + AzPhysics::SimulatedBodyComponentRequestsBus::Event(entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::DisablePhysics); bool enabled = true; - Physics::WorldBodyRequestBus::EventResult(enabled, entity->GetId(), &Physics::WorldBodyRequests::IsPhysicsEnabled); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(enabled, entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::IsPhysicsEnabled); EXPECT_FALSE(enabled); AzPhysics::SceneQueryHits result = sceneInterface->QueryScene(sceneHandle, &request); EXPECT_FALSE(result); - Physics::WorldBodyRequestBus::Event(entity->GetId(), &Physics::WorldBodyRequests::EnablePhysics); + AzPhysics::SimulatedBodyComponentRequestsBus::Event(entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::EnablePhysics); enabled = false; - Physics::WorldBodyRequestBus::EventResult(enabled, entity->GetId(), &Physics::WorldBodyRequests::IsPhysicsEnabled); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(enabled, entity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::IsPhysicsEnabled); EXPECT_TRUE(enabled); result = sceneInterface->QueryScene(sceneHandle, &request); @@ -718,7 +718,7 @@ namespace PhysX request.m_distance = 200.0f; AzPhysics::SceneQueryHit hit; - Physics::WorldBodyRequestBus::EventResult(hit, staticBoxEntity->GetId(), &Physics::WorldBodyRequests::RayCast, request); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(hit, staticBoxEntity->GetId(), &AzPhysics::SimulatedBodyComponentRequests::RayCast, request); EXPECT_TRUE(hit); @@ -922,7 +922,7 @@ namespace PhysX static const RayCastFunc WorldBodyRaycastEBusCall = []([[maybe_unused]] AZ::EntityId entityId, [[maybe_unused]] const AzPhysics::RayCastRequest& request) { AzPhysics::SceneQueryHit ret; - Physics::WorldBodyRequestBus::EventResult(ret, entityId, &Physics::WorldBodyRequests::RayCast, request); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(ret, entityId, &AzPhysics::SimulatedBodyComponentRequests::RayCast, request); return ret; }; diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index e6b777f8c0..8e4da0fe4b 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -312,7 +312,7 @@ namespace PhysX { // set up a trigger box auto triggerBox = TestUtils::CreateTriggerAtPosition(AZ::Vector3(0.0f, 0.0f, 12.0f)); - auto triggerBody = triggerBox->FindComponent()->GetStaticRigidBody(); + auto* triggerBody = azdynamic_cast(triggerBox->FindComponent()->GetSimulatedBody()); auto triggerShape = triggerBody->GetShape(0); TestTriggerAreaNotificationListener testTriggerAreaNotificationListener(triggerBox->GetId()); @@ -445,7 +445,7 @@ namespace PhysX auto obj02 = TestUtils::AddStaticUnitTestObject(m_testSceneHandle, AZ::Vector3(0.0f, 0.0f, 0.0f), "TestBox01"); auto body01 = obj01->FindComponent()->GetRigidBody(); - auto body02 = obj02->FindComponent()->GetStaticRigidBody(); + auto* body02 = azdynamic_cast(obj02->FindComponent()->GetSimulatedBody()); auto shape01 = body01->GetShape(0).get(); auto shape02 = body02->GetShape(0).get(); @@ -588,7 +588,7 @@ namespace PhysX { // set up a trigger box auto triggerBox = TestUtils::CreateTriggerAtPosition(AZ::Vector3(0.0f, 0.0f, 0.0f)); - auto triggerBody = triggerBox->FindComponent()->GetStaticRigidBody(); + auto* triggerBody = azdynamic_cast(triggerBox->FindComponent()->GetSimulatedBody()); // Create a test box above the trigger so when it falls down it'd enter and leave the trigger box auto testBox = TestUtils::AddUnitTestObject(m_testSceneHandle, AZ::Vector3(0.0f, 0.0f, 1.5f), "TestBox"); @@ -628,7 +628,7 @@ namespace PhysX { // Set up a static non trigger box auto staticBox = TestUtils::AddStaticUnitTestObject(m_testSceneHandle, AZ::Vector3(0.0f, 0.0f, 0.0f)); - auto staticBody = staticBox->FindComponent()->GetStaticRigidBody(); + auto* staticBody = azdynamic_cast(staticBox->FindComponent()->GetSimulatedBody()); // Create a test trigger box above the static box so when it falls down it'd enter and leave the trigger box auto dynamicTrigger = TestUtils::CreateDynamicTriggerAtPosition(AZ::Vector3(0.0f, 0.0f, 5.0f)); diff --git a/Gems/PhysX/Code/Tests/RagdollTests.cpp b/Gems/PhysX/Code/Tests/RagdollTests.cpp index ec803c1707..477e754d74 100644 --- a/Gems/PhysX/Code/Tests/RagdollTests.cpp +++ b/Gems/PhysX/Code/Tests/RagdollTests.cpp @@ -37,7 +37,7 @@ namespace PhysX - + )DELIMITER"; diff --git a/Gems/PhysX/Code/Tests/ShapeColliderComponentTests.cpp b/Gems/PhysX/Code/Tests/ShapeColliderComponentTests.cpp index 422385a777..b00e226078 100644 --- a/Gems/PhysX/Code/Tests/ShapeColliderComponentTests.cpp +++ b/Gems/PhysX/Code/Tests/ShapeColliderComponentTests.cpp @@ -138,7 +138,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const auto* pxRigidStatic = static_cast(staticBody->GetNativePointer()); PHYSX_SCENE_READ_LOCK(pxRigidStatic->getScene()); @@ -196,7 +196,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const auto* pxRigidStatic = static_cast(staticBody->GetNativePointer()); PHYSX_SCENE_READ_LOCK(pxRigidStatic->getScene()); @@ -247,7 +247,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); // the vertices of the input polygon prism ranged from (0, 0) to (3, 3) and the height was set to 2 // the bounding box of the static rigid body should reflect those values combined with the scale values above @@ -291,7 +291,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const auto* pxRigidStatic = static_cast(staticBody->GetNativePointer()); PHYSX_SCENE_READ_LOCK(pxRigidStatic->getScene()); @@ -363,7 +363,7 @@ namespace PhysXEditorTests EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); // since there was no editor rigid body component, the runtime entity should have a static rigid body - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); const auto* pxRigidStatic = static_cast(staticBody->GetNativePointer()); PHYSX_SCENE_READ_LOCK(pxRigidStatic->getScene()); @@ -442,7 +442,7 @@ namespace PhysXEditorTests // make a game entity and check its bounding box is consistent with the changed transform EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get()); - const auto* staticBody = gameEntity->FindComponent()->GetStaticRigidBody(); + const auto* staticBody = azdynamic_cast(gameEntity->FindComponent()->GetSimulatedBody()); AZ::Aabb aabb = staticBody->GetAabb(); EXPECT_TRUE(aabb.GetMax().IsClose(translation + 0.5f * scale * boxDimensions)); EXPECT_TRUE(aabb.GetMin().IsClose(translation - 0.5f * scale * boxDimensions)); diff --git a/Gems/PhysX/Code/physx_files.cmake b/Gems/PhysX/Code/physx_files.cmake index ed2d59b8aa..6350c06e0d 100644 --- a/Gems/PhysX/Code/physx_files.cmake +++ b/Gems/PhysX/Code/physx_files.cmake @@ -102,7 +102,6 @@ set(FILES Source/PhysXCharacters/Components/CharacterGameplayComponent.h Source/PhysXCharacters/Components/RagdollComponent.cpp Source/PhysXCharacters/Components/RagdollComponent.h - Include/PhysX/Debug/PhysXDebugConfiguration.h Include/PhysX/Debug/PhysXDebugInterface.h Include/PhysX/Configuration/PhysXConfiguration.h diff --git a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp index 45f1970ac2..f994283fbf 100644 --- a/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp +++ b/Gems/SurfaceData/Code/Source/Components/SurfaceDataColliderComponent.cpp @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include @@ -221,7 +221,7 @@ namespace SurfaceData } AzPhysics::SceneQueryHit result; - Physics::WorldBodyRequestBus::EventResult(result, GetEntityId(), &Physics::WorldBodyRequestBus::Events::RayCast, request); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(result, GetEntityId(), &AzPhysics::SimulatedBodyComponentRequestsBus::Events::RayCast, request); if (result) { @@ -319,7 +319,7 @@ namespace SurfaceData colliderValidBeforeUpdate = m_colliderBounds.IsValid(); m_colliderBounds = AZ::Aabb::CreateNull(); - Physics::WorldBodyRequestBus::EventResult(m_colliderBounds, GetEntityId(), &Physics::WorldBodyRequestBus::Events::GetAabb); + AzPhysics::SimulatedBodyComponentRequestsBus::EventResult(m_colliderBounds, GetEntityId(), &AzPhysics::SimulatedBodyComponentRequestsBus::Events::GetAabb); colliderValidAfterUpdate = m_colliderBounds.IsValid(); } diff --git a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp index 2d232854f3..db3bb1881d 100644 --- a/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp +++ b/Gems/SurfaceData/Code/Tests/SurfaceDataColliderComponentTest.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include namespace UnitTest { @@ -45,12 +45,12 @@ namespace UnitTest }; class MockPhysicsWorldBusProvider - : public Physics::WorldBodyRequestBus::Handler + : public AzPhysics::SimulatedBodyComponentRequestsBus::Handler { public: MockPhysicsWorldBusProvider(const AZ::EntityId& id, AZ::Vector3 inPosition, bool setHitResult, const SurfaceData::SurfacePoint& hitResult) { - Physics::WorldBodyRequestBus::Handler::BusConnect(id); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusConnect(id); // Whether or not the test should return a successful hit, we still want to create a valid // AABB so that the SurfaceData component registers itself as a provider. @@ -73,14 +73,15 @@ namespace UnitTest virtual ~MockPhysicsWorldBusProvider() { - Physics::WorldBodyRequestBus::Handler::BusDisconnect(); + AzPhysics::SimulatedBodyComponentRequestsBus::Handler::BusDisconnect(); } // Minimal mocks needed to mock out this ebus void EnablePhysics() override {} void DisablePhysics() override {} bool IsPhysicsEnabled() const override { return true; } - AzPhysics::SimulatedBody* GetWorldBody() override { return nullptr; } + AzPhysics::SimulatedBody* GetSimulatedBody() override { return nullptr; } + AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const override { return AzPhysics::InvalidSimulatedBodyHandle; } // Functional mocks to mock out the data needed by the component AZ::Aabb GetAabb() const override { return m_aabb; } From 347073cbcdc83221a5aa7efad95d553efc7894d0 Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Fri, 7 May 2021 09:31:48 -0500 Subject: [PATCH 23/24] {LYN-2257} Helios - Add Matrix math type for JSON Serialization system (#561) * {LYN-2257} Helios - Add Matrix math type to the JSON Serialization system * Helios/Systems - Add Matrix math type to the JSON Serialization system * supports both YPR+scale+translation and array of values * supports Matrix3x3, Matrix3x4, Matrix4x4 Jira: https://jira.agscollab.com/browse/LYN-2257 Tests: Added Serialization/Json/MathMatrixSerializerTests.cpp * clang compile fixes * removed typename * fixing both tests and some default conformity impls * stablized the comformity test values; rotations drift too much --- .../AzCore/Math/MathMatrixSerializer.cpp | 485 +++++++++++++++ .../AzCore/AzCore/Math/MathMatrixSerializer.h | 54 ++ .../AzCore/AzCore/Math/MathReflection.cpp | 4 + .../AzCore/AzCore/azcore_files.cmake | 2 + .../Json/MathMatrixSerializerTests.cpp | 562 ++++++++++++++++++ .../AzCore/Tests/azcoretests_files.cmake | 1 + 6 files changed, 1108 insertions(+) create mode 100644 Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp create mode 100644 Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h create mode 100644 Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp new file mode 100644 index 0000000000..0b7e3300cf --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp @@ -0,0 +1,485 @@ +/* +* 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 +#include +#include +#include +#include + +namespace AZ::JsonMathMatrixSerializerInternal +{ + template + JsonSerializationResult::Result LoadArray(MatrixType& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + constexpr size_t ElementCount = RowCount * ColumnCount; + static_assert(ElementCount == 9 || ElementCount == 12 || ElementCount == 16, + "MathMatrixSerializer only support Matrix3x3, Matrix3x4 and Matrix4x4."); + + rapidjson::SizeType arraySize = inputValue.Size(); + if (arraySize < ElementCount) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, + "Not enough numbers in JSON array to load math matrix from."); + } + + AZ::BaseJsonSerializer* floatSerializer = context.GetRegistrationContext()->GetSerializerForType(azrtti_typeid()); + if (!floatSerializer) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Failed to find the JSON float serializer."); + } + + constexpr const char* names[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; + float values[ElementCount]; + for (int i = 0; i < ElementCount; ++i) + { + ScopedContextPath subPath(context, names[i]); + JSR::Result intermediate = floatSerializer->Load(values + i, azrtti_typeid(), inputValue[i], context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + } + + size_t valueIndex = 0; + for (size_t r = 0; r < RowCount; ++r) + { + for (size_t c = 0; c < ColumnCount; ++c) + { + output.SetElement(aznumeric_caster(r), aznumeric_caster(c), values[valueIndex++]); + } + } + + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read math matrix."); + } + + JsonSerializationResult::Result LoadFloatFromObject( + float& output, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context, + const char* name, + const char* altName) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + AZ::BaseJsonSerializer* floatSerializer = context.GetRegistrationContext()->GetSerializerForType(azrtti_typeid()); + if (!floatSerializer) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Failed to find the json float serializer."); + } + + const char* nameUsed = name; + JSR::ResultCode result(JSR::Tasks::ReadField); + auto iterator = inputValue.FindMember(rapidjson::StringRef(name)); + if (iterator == inputValue.MemberEnd()) + { + nameUsed = altName; + iterator = inputValue.FindMember(rapidjson::StringRef(altName)); + if (iterator == inputValue.MemberEnd()) + { + // field not found so leave default value + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed)); + nameUsed = nullptr; + } + } + + if (nameUsed) + { + ScopedContextPath subPath(context, nameUsed); + JSR::Result intermediate = floatSerializer->Load(&output, azrtti_typeid(), iterator->value, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + else + { + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } + } + + return context.Report(result, "Successfully read float."); + } + + JsonSerializationResult::Result LoadVector3FromObject( + Vector3& output, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context, + AZStd::fixed_vector names) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + constexpr size_t ElementCount = 3; // Vector3 + + JSR::ResultCode result(JSR::Tasks::ReadField); + float values[ElementCount]; + for (int i = 0; i < ElementCount; ++i) + { + values[i] = output.GetElement(i); + auto name = names[i * 2]; + auto altName = names[(i * 2) + 1]; + + JSR::Result intermediate = LoadFloatFromObject(values[i], inputValue, context, name.data(), altName.data()); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + else + { + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } + } + + for (int i = 0; i < ElementCount; ++i) + { + output.SetElement(i, values[i]); + } + + return context.Report(result, "Successfully read math matrix."); + } + + JsonSerializationResult::Result LoadQuaternionAndScale( + AZ::Quaternion& quaternion, + float& scale, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + JSR::ResultCode result(JSR::Tasks::ReadField); + scale = 1.0f; + JSR::Result intermediateScale = LoadFloatFromObject(scale, inputValue, context, "scale", "Scale"); + if (intermediateScale.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateScale; + } + result.Combine(intermediateScale); + + if (AZ::IsClose(scale, 0.0f)) + { + result.Combine({ JSR::Tasks::ReadField, JSR::Outcomes::Unsupported }); + return context.Report(result, "Scale can not be zero."); + } + + AZ::Vector3 degreesRollPitchYaw = AZ::Vector3::CreateZero(); + JSR::Result intermediateDegrees = LoadVector3FromObject(degreesRollPitchYaw, inputValue, context, { "roll", "Roll", "pitch", "Pitch", "yaw", "Yaw" }); + if (intermediateDegrees.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateDegrees; + } + result.Combine(intermediateDegrees); + + // the quaternion should be equivalent to a series of rotations in the order z, then y, then x + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(degreesRollPitchYaw); + quaternion = AZ::Quaternion::CreateRotationX(eulerRadians.GetX()) * + AZ::Quaternion::CreateRotationY(eulerRadians.GetY()) * + AZ::Quaternion::CreateRotationZ(eulerRadians.GetZ()); + + return context.Report(result, "Successfully read math yaw, pitch, roll, and scale."); + } + + template + JsonSerializationResult::Result LoadObject(MatrixType& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + output = MatrixType::CreateIdentity(); + + JSR::ResultCode result(JSR::Tasks::ReadField); + float scale; + AZ::Quaternion rotation; + + JSR::Result intermediate = LoadQuaternionAndScale(rotation, scale, inputValue, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + result.Combine(intermediate); + + AZ::Vector3 translation = AZ::Vector3::CreateZero(); + JSR::Result intermediateTranslation = LoadVector3FromObject(translation, inputValue, context, { "x", "X", "y", "Y", "z", "Z" }); + if (intermediateTranslation.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateTranslation; + } + result.Combine(intermediateTranslation); + + // composed a matrix by rotation, then scale, then translation + auto matrix = MatrixType::CreateFromQuaternion(rotation); + matrix.MultiplyByScale(Vector3{ scale }); + matrix.SetTranslation(translation); + + if (matrix == MatrixType::CreateIdentity()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Using identity matrix for empty object."); + } + + output = matrix; + return context.Report(result, "Successfully read math matrix."); + } + + template<> + JsonSerializationResult::Result LoadObject(Matrix3x3& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + output = Matrix3x3::CreateIdentity(); + + JSR::ResultCode result(JSR::Tasks::ReadField); + float scale; + AZ::Quaternion rotation; + + JSR::Result intermediate = LoadQuaternionAndScale(rotation, scale, inputValue, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + result.Combine(intermediate); + + // composed a matrix by rotation then scale + auto matrix = Matrix3x3::CreateFromQuaternion(rotation); + matrix.MultiplyByScale(Vector3{ scale }); + + if (matrix == Matrix3x3::CreateIdentity()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Using identity matrix for empty object."); + } + + output = matrix; + return context.Report(result, "Successfully read math matrix."); + } + + template + JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + constexpr size_t ElementCount = RowCount * ColumnCount; + static_assert(ElementCount == 9 || ElementCount == 12 || ElementCount == 16, + "MathMatrixSerializer only support Matrix3x3, Matrix3x4 and Matrix4x4."); + + AZ_Assert(azrtti_typeid() == outputValueTypeId, + "Unable to deserialize Matrix%zux%zu to json because the provided type is %s", + RowCount, ColumnCount, outputValueTypeId.ToString().c_str()); + AZ_UNUSED(outputValueTypeId); + + MatrixType* matrix = reinterpret_cast(outputValue); + AZ_Assert(matrix, "Output value for JsonMatrix%zux%zuSerializer can't be null.", RowCount, ColumnCount); + + switch (inputValue.GetType()) + { + case rapidjson::kArrayType: + return LoadArray(*matrix, inputValue, context); + case rapidjson::kObjectType: + return LoadObject(*matrix, inputValue, context); + + 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 matrix can only be read from arrays or objects."); + + default: + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, + "Unknown json type encountered in math matrix."); + } + } + + template + AZ::Quaternion CreateQuaternion(const MatrixType& matrix); + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x3& matrix) + { + return Quaternion::CreateFromMatrix3x3(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x4& matrix) + { + return Quaternion::CreateFromMatrix3x4(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix4x4& matrix) + { + return Quaternion::CreateFromMatrix4x4(matrix); + } + + template + JsonSerializationResult::Result StoreRotationAndScale(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, + const Uuid& valueTypeId, JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + AZ_UNUSED(valueTypeId); + + const MatrixType* matrix = reinterpret_cast(inputValue); + AZ_Assert(matrix, "Input value for JsonMatrixSerializer can't be null."); + const MatrixType* defaultMatrix = reinterpret_cast(defaultValue); + + if (!context.ShouldKeepDefaults() && defaultMatrix && *matrix == *defaultMatrix) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default math Matrix used."); + } + + MatrixType matrixToExport = *matrix; + AZ::Vector3 scale = matrixToExport.ExtractScale(); + + AZ::Quaternion rotation = CreateQuaternion(matrixToExport); + auto degrees = rotation.GetEulerDegrees(); + outputValue.AddMember(rapidjson::StringRef("roll"), degrees.GetX(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("pitch"), degrees.GetY(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("yaw"), degrees.GetZ(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("scale"), scale.GetX(), context.GetJsonAllocator()); + + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Math Matrix successfully stored."); + } + + template + JsonSerializationResult::Result StoreTranslation(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + AZ_UNUSED(valueTypeId); + + const MatrixType* matrix = reinterpret_cast(inputValue); + AZ_Assert(matrix, "Input value for JsonMatrixSerializer can't be null."); + const MatrixType* defaultMatrix = reinterpret_cast(defaultValue); + + if (!context.ShouldKeepDefaults() && defaultMatrix && *matrix == *defaultMatrix) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default math Matrix used."); + } + + auto translation = matrix->GetTranslation(); + outputValue.AddMember(rapidjson::StringRef("x"), translation.GetX(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("y"), translation.GetY(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("z"), translation.GetZ(), context.GetJsonAllocator()); + + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Math Matrix successfully stored."); + } +} + +namespace AZ +{ + // Matrix3x3 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x3Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix3x3Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix3x3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + return JsonMathMatrixSerializerInternal::StoreRotationAndScale( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + } + + + // Matrix3x4 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x4Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix3x4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix3x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + result.GetResultCode().Combine(resultTranslation); + return result; + } + + // Matrix4x4 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix4x4Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix4x4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix4x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( + 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 new file mode 100644 index 0000000000..81c9635a79 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h @@ -0,0 +1,54 @@ +/* +* 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 AZ +{ + class JsonMatrix3x3Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", 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; + }; + + class JsonMatrix3x4Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", 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; + }; + + class JsonMatrix4x4Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", 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; + }; +} diff --git a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp index e918f8fdb3..3c683f1988 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -366,6 +367,9 @@ namespace AZ { context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 5357ed66a6..dc0fb13f00 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -290,6 +290,8 @@ set(FILES Math/MathScriptHelpers.h Math/MathUtils.cpp Math/MathUtils.h + Math/MathMatrixSerializer.h + Math/MathMatrixSerializer.cpp Math/MathVectorSerializer.h Math/MathVectorSerializer.cpp Math/Matrix3x3.cpp diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp new file mode 100644 index 0000000000..b9d1edab76 --- /dev/null +++ b/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp @@ -0,0 +1,562 @@ +/* +* 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 +#include +#include +#include +#include +#include + +namespace JsonSerializationTests +{ + namespace DataHelper + { + // Build Matrix + + template + MatrixType BuildMatrixRotationWithSale(const AZ::Vector3& angles, float scale) + { + // start a matrix with angle degrees + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(angles); + const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX()); + const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY()); + const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ()); + auto matrix = rotX * rotY * rotZ; + + // apply a scale + matrix.MultiplyByScale(AZ::Vector3{ scale }); + return matrix; + } + + template + MatrixType BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3& translation) + { + auto matrix = BuildMatrixRotationWithSale(angles, scale); + matrix.SetTranslation(translation); + return matrix; + } + + template <> + AZ::Matrix3x3 BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3&) + { + return BuildMatrixRotationWithSale(angles, scale); + } + + // Arbitrary Matrix + + template + MatrixType CreateArbitraryMatrixRotationAndSale(AZ::SimpleLcgRandom& random) + { + // start a matrix with arbitrary degrees + float roll = random.GetRandomFloat() * 360.0f; + float pitch = random.GetRandomFloat() * 360.0f; + float yaw = random.GetRandomFloat() * 360.0f; + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(AZ::Vector3{ roll, pitch, yaw }); + const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX()); + const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY()); + const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ()); + auto matrix = rotX * rotY * rotZ; + + // apply a scale + matrix.MultiplyByScale(AZ::Vector3{ random.GetRandomFloat() }); + return matrix; + } + + template + void AssignArbitrarySetTranslation(MatrixType& matrix, AZ::SimpleLcgRandom& random) + { + float x = random.GetRandomFloat() * 10000.0f; + float y = random.GetRandomFloat() * 10000.0f; + float z = random.GetRandomFloat() * 10000.0f; + matrix.SetTranslation(AZ::Vector3{ x, y, z }); + } + + template + MatrixType CreateArbitraryMatrix(size_t seed); + + template <> + AZ::Matrix3x3 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + return CreateArbitraryMatrixRotationAndSale(random); + } + + template <> + AZ::Matrix3x4 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + auto matrix = CreateArbitraryMatrixRotationAndSale(random); + AssignArbitrarySetTranslation(matrix, random); + return matrix; + } + + template <> + AZ::Matrix4x4 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + auto matrix = CreateArbitraryMatrixRotationAndSale(random); + AssignArbitrarySetTranslation(matrix, random); + return matrix; + } + + // CreateQuaternion + + template + AZ::Quaternion CreateQuaternion(const MatrixType& matrix); + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x3& matrix) + { + return AZ::Quaternion::CreateFromMatrix3x3(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x4& matrix) + { + return AZ::Quaternion::CreateFromMatrix3x4(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix4x4& matrix) + { + return AZ::Quaternion::CreateFromMatrix4x4(matrix); + } + + template + void AddRotation(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator) + { + AZ::Quaternion rotation = CreateQuaternion(matrix); + const auto degrees = rotation.GetEulerDegrees(); + value.AddMember("yaw", degrees.GetX(), allocator); + value.AddMember("pitch", degrees.GetY(), allocator); + value.AddMember("roll", degrees.GetZ(), allocator); + } + + void AddScale(rapidjson::Value& value, float scale, rapidjson::Document::AllocatorType& allocator) + { + value.AddMember("scale", scale, allocator); + } + + void AddTranslation(rapidjson::Value& value, const AZ::Vector3& translation, rapidjson::Document::AllocatorType& allocator) + { + value.AddMember("x", translation.GetX(), allocator); + value.AddMember("y", translation.GetY(), allocator); + value.AddMember("z", translation.GetZ(), allocator); + } + + template + void AddData(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator); + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix3x3& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddRotation(value, matrix, allocator); + } + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix3x4& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddTranslation(value, matrix.GetTranslation(), allocator); + AddRotation(value, matrix, allocator); + } + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix4x4& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddTranslation(value, matrix.GetTranslation(), allocator); + AddRotation(value, matrix, allocator); + } + }; + + template + class MathMatrixSerializerTestDescription : + public JsonSerializerConformityTestDescriptor + { + public: + AZStd::shared_ptr CreateSerializer() override + { + return AZStd::make_shared(); + } + + AZStd::shared_ptr CreateDefaultInstance() override + { + return AZStd::make_shared(MatrixType::CreateIdentity()); + } + + AZStd::shared_ptr CreateFullySetInstance() override + { + auto angles = AZ::Vector3 { 0.0f, 0.0f, 0.0f }; + auto scale = 10.0f; + auto translation = AZ::Vector3{ 10.0f, 20.0f, 30.0f }; + auto matrix = DataHelper::BuildMatrix(angles, scale, translation); + return AZStd::make_shared(matrix); + } + + AZStd::string_view GetJsonForFullySetInstance() override + { + if constexpr (RowCount * ColumnCount == 9) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0}"; + } + else if constexpr (RowCount * ColumnCount == 12) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}"; + } + else if constexpr (RowCount * ColumnCount == 16) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}"; + } + else + { + static_assert((RowCount >= 3 && RowCount <= 4) && (ColumnCount >= 3 && ColumnCount <= 4), + "Only matrix 3x3, 3x4 or 4x4 are supported by this test."); + } + return "{}"; + } + + void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override + { + features.EnableJsonType(rapidjson::kArrayType); + features.EnableJsonType(rapidjson::kObjectType); + features.m_fixedSizeArray = true; + features.m_supportsPartialInitialization = false; + features.m_supportsInjection = false; + } + + bool AreEqual(const MatrixType& lhs, const MatrixType& rhs) override + { + for (int r = 0; r < RowCount; ++r) + { + for (int c = 0; c < ColumnCount; ++c) + { + if (!AZ::IsClose(lhs.GetElement(r, c), rhs.GetElement(r, c), AZ::Constants::Tolerance)) + { + return false; + } + } + } + return true; + } + }; + + using MathMatrixSerializerConformityTestTypes = ::testing::Types< + MathMatrixSerializerTestDescription, + MathMatrixSerializerTestDescription, + MathMatrixSerializerTestDescription + >; + INSTANTIATE_TYPED_TEST_CASE_P(JsonMathMatrixSerializer, JsonSerializerConformityTests, MathMatrixSerializerConformityTestTypes); + + template + class JsonMathMatrixSerializerTests + : public BaseJsonSerializerFixture + { + public: + using Descriptor = T; + + void SetUp() override + { + BaseJsonSerializerFixture::SetUp(); + m_serializer = AZStd::make_unique(); + } + + void TearDown() override + { + m_serializer.reset(); + BaseJsonSerializerFixture::TearDown(); + } + + protected: + AZStd::unique_ptr m_serializer; + }; + + struct Matrix3x3Descriptor + { + using MatrixType = AZ::Matrix3x3; + using Serializer = AZ::JsonMatrix3x3Serializer; + constexpr static size_t RowCount = 3; + constexpr static size_t ColumnCount = 3; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = false; + }; + + struct Matrix3x4Descriptor + { + using MatrixType = AZ::Matrix3x4; + using Serializer = AZ::JsonMatrix3x4Serializer; + constexpr static size_t RowCount = 3; + constexpr static size_t ColumnCount = 4; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = true; + }; + + struct Matrix4x4Descriptor + { + using MatrixType = AZ::Matrix4x4; + using Serializer = AZ::JsonMatrix4x4Serializer; + constexpr static size_t RowCount = 4; + constexpr static size_t ColumnCount = 4; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = true; + }; + + using JsonMathMatrixSerializerTypes = ::testing::Types < + Matrix3x3Descriptor, Matrix3x4Descriptor, Matrix4x4Descriptor>; + TYPED_TEST_CASE(JsonMathMatrixSerializerTests, JsonMathMatrixSerializerTypes); + + // Load array tests + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_Array_ReturnsConvertAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount; ++i) + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::Success, result.GetOutcome()); + + for (int r = 0; r < JsonMathMatrixSerializerTests::Descriptor::RowCount; ++r) + { + for (int c = 0; c < JsonMathMatrixSerializerTests::Descriptor::ColumnCount; ++c) + { + auto testValue = static_cast((r * JsonMathMatrixSerializerTests::Descriptor::ColumnCount) + c + 1); + EXPECT_FLOAT_EQ(testValue, output.GetElement(r, c)); + } + } + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidEntries_ReturnsUnsupportedAndLeavesMatrixUntouched) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount; ++i) + { + if (i == 1) + { + arrayValue.PushBack(rapidjson::StringRef("Invalid"), this->m_jsonDocument->GetAllocator()); + } + else + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + } + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); + + for (int r = 0; r < JsonMathMatrixSerializerTests::Descriptor::RowCount; ++r) + { + for (int c = 0; c < JsonMathMatrixSerializerTests::Descriptor::ColumnCount; ++c) + { + EXPECT_FLOAT_EQ(0.0f, output.GetElement(r, c)); + } + } + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_FloatSerializerMissingForArray_ReturnsCatastrophic) + { + using namespace AZ::JsonSerializationResult; + + this->m_jsonRegistrationContext->EnableRemoveReflection(); + this->m_jsonRegistrationContext->template Serializer()->template HandlesType(); + this->m_jsonRegistrationContext->DisableRemoveReflection(); + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount + 1; ++i) + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + + typename JsonMathMatrixSerializerTests::Descriptor::MatrixType output; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + EXPECT_EQ(Outcomes::Catastrophic, result.GetOutcome()); + + this->m_jsonRegistrationContext->template Serializer()->template HandlesType(); + } + + // Load object tests + TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectLowerCase_ReturnsSuccessAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator()); + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectWithExtraFields_ReturnsPartialConvertAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddScale(objectValue, input.RetrieveScale().GetX(), this->m_jsonDocument->GetAllocator()); + DataHelper::AddRotation(objectValue, input, this->m_jsonDocument->GetAllocator()); + objectValue.AddMember(rapidjson::StringRef("extra"), "no value", this->m_jsonDocument->GetAllocator()); + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, SaveLoad_Identity_LoadsDefaultMatrixWithIdentity) + { + using namespace AZ::JsonSerializationResult; + + auto defaultValue = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &defaultValue, + &defaultValue, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonSerializationContext); + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + objectInput.Accept(writer); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + EXPECT_TRUE(defaultValue == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Zero_SavesAndLoadsIdentityMatrix) + { + using namespace AZ::JsonSerializationResult; + + auto defaultValue = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &input, + &defaultValue, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonSerializationContext); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome()); + EXPECT_TRUE(defaultValue == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidFields_ReturnsUnsupportedAndLeavesMatrixUntouched) + { + using namespace AZ::JsonSerializationResult; + using Descriptor = typename JsonMathMatrixSerializerTests::Descriptor; + + const auto defaultValue = Descriptor::MatrixType::CreateIdentity(); + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator()); + objectValue["yaw"] = "Invalid"; + + auto output = Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Arbitrary_SavesAndLoadsArbitraryMatrix) + { + using namespace AZ::JsonSerializationResult; + using Descriptor = typename JsonMathMatrixSerializerTests::Descriptor; + + auto defaultValue = Descriptor::MatrixType::CreateIdentity(); + size_t elementCount = Descriptor::RowCount * Descriptor::ColumnCount; + auto input = DataHelper::CreateArbitraryMatrix(elementCount); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &input, + &defaultValue, + azrtti_typeid(), + *this->m_jsonSerializationContext); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + + for (int r = 0; r < Descriptor::RowCount; ++r) + { + for (int c = 0; c < Descriptor::ColumnCount; ++c) + { + EXPECT_NEAR(input.GetElement(r, c), output.GetElement(r, c), AZ::Constants::Tolerance); + } + } + } + +} // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 2129761bfe..f90717d003 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -111,6 +111,7 @@ set(FILES Serialization/Json/JsonSerializerMock.h Serialization/Json/MapSerializerTests.cpp Serialization/Json/MathVectorSerializerTests.cpp + Serialization/Json/MathMatrixSerializerTests.cpp Serialization/Json/SmartPointerSerializerTests.cpp Serialization/Json/StringSerializerTests.cpp Serialization/Json/TestCases.h From 2633efbd132e8ac58f6bda8cb93238341faf27ef Mon Sep 17 00:00:00 2001 From: Steve Pham <82231385+spham-amzn@users.noreply.github.com> Date: Fri, 7 May 2021 07:34:35 -0700 Subject: [PATCH 24/24] Moving SystemUtilsApple.mm and SystemUtilsApple.h from CrySystem to AzFramework to fix linker error when building iOS non-monolithically (#631) --- Code/CryEngine/CryCommon/WinBase.cpp | 2 +- Code/CryEngine/CrySystem/Log.cpp | 2 +- .../CryEngine/CrySystem/MobileDetectSpec_Ios.cpp | 2 +- .../Platform/Mac/platform_mac_files.cmake | 5 ----- .../Platform/iOS/platform_ios_files.cmake | 2 -- Code/CryEngine/CrySystem/SystemWin32.cpp | 2 +- .../CrySystem/crysystem_mac_files.cmake | 4 ---- .../Apple/AzFramework/Utils}/SystemUtilsApple.h | 0 .../Apple/AzFramework/Utils}/SystemUtilsApple.mm | 0 .../Mac/AzFramework/Utils/SystemUtilsApple.h | 16 ++++++++++++++++ .../Platform/Mac/platform_mac_files.cmake | 2 ++ .../iOS/AzFramework/Utils/SystemUtilsApple.h | 15 +++++++++++++++ .../Platform/iOS/platform_ios_files.cmake | 2 ++ .../Platform/iOS/O3DEApplicationDelegate_iOS.mm | 2 +- 14 files changed, 40 insertions(+), 16 deletions(-) rename Code/{CryEngine/CrySystem => Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils}/SystemUtilsApple.h (100%) rename Code/{CryEngine/CrySystem => Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils}/SystemUtilsApple.mm (100%) create mode 100644 Code/Framework/AzFramework/Platform/Mac/AzFramework/Utils/SystemUtilsApple.h create mode 100644 Code/Framework/AzFramework/Platform/iOS/AzFramework/Utils/SystemUtilsApple.h diff --git a/Code/CryEngine/CryCommon/WinBase.cpp b/Code/CryEngine/CryCommon/WinBase.cpp index d48a3327a7..e6ea1cd4a8 100644 --- a/Code/CryEngine/CryCommon/WinBase.cpp +++ b/Code/CryEngine/CryCommon/WinBase.cpp @@ -77,7 +77,7 @@ unsigned int g_EnableMultipleAssert = 0;//set to something else than 0 if to ena #endif #if defined(APPLE) - #include "../CrySystem/SystemUtilsApple.h" + #include #endif #include "StringUtils.h" diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index cdf145e4be..62cf29fef9 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -51,7 +51,7 @@ #define LOG_BACKUP_PATH "@log@/LogBackups" #if defined(IOS) -#include "SystemUtilsApple.h" +#include #endif ////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp index 1f3275f1c6..dc0a28490d 100644 --- a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp +++ b/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp @@ -15,7 +15,7 @@ #include #include "MobileDetectSpec.h" -#include "SystemUtilsApple.h" +#include namespace MobileSysInspect { diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake index 9c26988e94..4d5680a30d 100644 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake +++ b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake @@ -8,8 +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. # - -set(FILES - ../../SystemUtilsApple.h - ../../SystemUtilsApple.mm -) diff --git a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake index a5d743e6d7..bbe61fb488 100644 --- a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake +++ b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake @@ -13,8 +13,6 @@ set(FILES ../../MobileDetectSpec_Ios.cpp ../../MobileDetectSpec.cpp ../../MobileDetectSpec.h - ../../SystemUtilsApple.h - ../../SystemUtilsApple.mm ) diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index ce352966ac..b47519eb03 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -66,7 +66,7 @@ __pragma(comment(lib, "Winmm.lib")) #endif #if defined(APPLE) -#include "SystemUtilsApple.h" +#include #endif diff --git a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake b/Code/CryEngine/CrySystem/crysystem_mac_files.cmake index 7e539e6825..f5b9ea77a2 100644 --- a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_mac_files.cmake @@ -9,7 +9,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -set(FILES - SystemUtilsApple.h - SystemUtilsApple.mm -) diff --git a/Code/CryEngine/CrySystem/SystemUtilsApple.h b/Code/Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils/SystemUtilsApple.h similarity index 100% rename from Code/CryEngine/CrySystem/SystemUtilsApple.h rename to Code/Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils/SystemUtilsApple.h diff --git a/Code/CryEngine/CrySystem/SystemUtilsApple.mm b/Code/Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils/SystemUtilsApple.mm similarity index 100% rename from Code/CryEngine/CrySystem/SystemUtilsApple.mm rename to Code/Framework/AzFramework/Platform/Common/Apple/AzFramework/Utils/SystemUtilsApple.mm diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Utils/SystemUtilsApple.h b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Utils/SystemUtilsApple.h new file mode 100644 index 0000000000..33a89bd146 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Utils/SystemUtilsApple.h @@ -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. +* +*/ +// Original file Copyright Crytek GMBH or its affiliates, used under license. + +#pragma once + +#include "../../../Common/Apple/AzFramework/Utils/SystemUtilsApple.h" diff --git a/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake index 9f4a09418f..b69278665a 100644 --- a/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake +++ b/Code/Framework/AzFramework/Platform/Mac/platform_mac_files.cmake @@ -36,4 +36,6 @@ set(FILES ../Common/Unimplemented/AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Unimplemented.cpp AzFramework/Archive/ArchiveVars_Platform.h AzFramework/Archive/ArchiveVars_Mac.h + ../Common/Apple/AzFramework/Utils/SystemUtilsApple.h + ../Common/Apple/AzFramework/Utils/SystemUtilsApple.mm ) diff --git a/Code/Framework/AzFramework/Platform/iOS/AzFramework/Utils/SystemUtilsApple.h b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Utils/SystemUtilsApple.h new file mode 100644 index 0000000000..5ac96c8523 --- /dev/null +++ b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Utils/SystemUtilsApple.h @@ -0,0 +1,15 @@ +/* +* 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 "../../../Common/Apple/AzFramework/Utils/SystemUtilsApple.h" diff --git a/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake b/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake index c3e5e7b7c1..f1bf958067 100644 --- a/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake +++ b/Code/Framework/AzFramework/Platform/iOS/platform_ios_files.cmake @@ -36,5 +36,7 @@ set(FILES AzFramework/Process/ProcessCommon.h AzFramework/Process/ProcessWatcher_iOS.cpp AzFramework/Process/ProcessCommunicator_iOS.cpp + ../Common/Apple/AzFramework/Utils/SystemUtilsApple.h + ../Common/Apple/AzFramework/Utils/SystemUtilsApple.mm ) diff --git a/Code/LauncherUnified/Platform/iOS/O3DEApplicationDelegate_iOS.mm b/Code/LauncherUnified/Platform/iOS/O3DEApplicationDelegate_iOS.mm index ca7ab2def0..d78a83607b 100644 --- a/Code/LauncherUnified/Platform/iOS/O3DEApplicationDelegate_iOS.mm +++ b/Code/LauncherUnified/Platform/iOS/O3DEApplicationDelegate_iOS.mm @@ -19,7 +19,7 @@ #include // for AZ_MAX_PATH_LEN -#include +#include #import