3
0

ClothComponentTest.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzTest/AzTest.h>
  9. #include <AzCore/UnitTest/UnitTest.h>
  10. #include <AzCore/Component/Entity.h>
  11. #include <AzFramework/Components/TransformComponent.h>
  12. #include <Components/ClothComponent.h>
  13. #include <ActorHelper.h>
  14. #include <Integration/Components/ActorComponent.h>
  15. namespace UnitTest
  16. {
  17. class NvClothComponent
  18. : public ::testing::Test
  19. {
  20. protected:
  21. AZStd::unique_ptr<AZ::Entity> CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration);
  22. bool IsConnectedToMeshComponentNotificationBus(NvCloth::ClothComponent* clothComponent) const;
  23. };
  24. AZStd::unique_ptr<AZ::Entity> NvClothComponent::CreateClothActorEntity(const NvCloth::ClothConfiguration& clothConfiguration)
  25. {
  26. AZStd::unique_ptr<AZ::Entity> entity = AZStd::make_unique<AZ::Entity>();
  27. entity->CreateComponent<AzFramework::TransformComponent>();
  28. entity->CreateComponent<EMotionFX::Integration::ActorComponent>();
  29. entity->CreateComponent<NvCloth::ClothComponent>(clothConfiguration);
  30. entity->Init();
  31. return entity;
  32. }
  33. bool NvClothComponent::IsConnectedToMeshComponentNotificationBus(NvCloth::ClothComponent* clothComponent) const
  34. {
  35. return static_cast<AZ::Render::MeshComponentNotificationBus::Handler*>(clothComponent)->BusIsConnectedId(clothComponent->GetEntityId());
  36. }
  37. TEST_F(NvClothComponent, ClothComponent_WithoutDependencies_ReturnsMissingRequiredService)
  38. {
  39. AZStd::unique_ptr<AZ::Entity> entity = AZStd::make_unique<AZ::Entity>();
  40. entity->CreateComponent<NvCloth::ClothComponent>();
  41. entity->Init();
  42. AZ::Entity::DependencySortOutcome sortOutcome = entity->EvaluateDependenciesGetDetails();
  43. EXPECT_FALSE(sortOutcome.IsSuccess());
  44. EXPECT_TRUE(sortOutcome.GetError().m_code == AZ::Entity::DependencySortResult::MissingRequiredService);
  45. }
  46. TEST_F(NvClothComponent, ClothComponent_WithTransformAndActor_DependenciesAreMet)
  47. {
  48. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity({});
  49. AZ::Entity::DependencySortOutcome sortOutcome = entity->EvaluateDependenciesGetDetails();
  50. EXPECT_TRUE(sortOutcome.IsSuccess());
  51. }
  52. TEST_F(NvClothComponent, ClothComponent_WithoutMultiplayerGem_ConnectsToMeshComponentNotificationBusOnActivation)
  53. {
  54. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity({});
  55. entity->Activate();
  56. auto* clothComponent = entity->FindComponent<NvCloth::ClothComponent>();
  57. EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent));
  58. }
  59. TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Game_ConnectsToMeshComponentNotificationBusOnActivation)
  60. {
  61. // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR
  62. AZ::ConsoleDataWrapper<bool, ConsoleThreadSafety<bool>> sv_isDedicated(false,
  63. nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate);
  64. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity({});
  65. entity->Activate();
  66. auto* clothComponent = entity->FindComponent<NvCloth::ClothComponent>();
  67. EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent));
  68. }
  69. TEST_F(NvClothComponent, ClothComponent_WithMultiplayerGem_Server_DoesNotConnectToMeshComponentNotificationBusOnActivation)
  70. {
  71. // Fake that multiplayer gem is enabled by creating a local sv_isDedicated AZ_CVAR
  72. AZ::ConsoleDataWrapper<bool, ConsoleThreadSafety<bool>> sv_isDedicated(true,
  73. nullptr, "sv_isDedicated", "", AZ::ConsoleFunctorFlags::DontReplicate);
  74. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity({});
  75. entity->Activate();
  76. auto* clothComponent = entity->FindComponent<NvCloth::ClothComponent>();
  77. EXPECT_FALSE(IsConnectedToMeshComponentNotificationBus(clothComponent));
  78. }
  79. TEST_F(NvClothComponent, ClothComponent_OneEntityWithTwoClothComponents_BothConnectToMeshComponentNotificationBusOnActivation)
  80. {
  81. AZStd::unique_ptr<AZ::Entity> entity = AZStd::make_unique<AZ::Entity>();
  82. entity->CreateComponent<AzFramework::TransformComponent>();
  83. entity->CreateComponent<EMotionFX::Integration::ActorComponent>();
  84. auto* clothComponent1 = entity->CreateComponent<NvCloth::ClothComponent>();
  85. auto* clothComponent2 = entity->CreateComponent<NvCloth::ClothComponent>();
  86. entity->Init();
  87. entity->Activate();
  88. EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent1));
  89. EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent2));
  90. }
  91. TEST_F(NvClothComponent, ClothComponent_AfterDeactivation_IsNotConnectedToMeshComponentNotificationBus)
  92. {
  93. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity({});
  94. entity->Activate();
  95. auto* clothComponent = entity->FindComponent<NvCloth::ClothComponent>();
  96. EXPECT_TRUE(IsConnectedToMeshComponentNotificationBus(clothComponent));
  97. entity->Deactivate();
  98. EXPECT_FALSE(IsConnectedToMeshComponentNotificationBus(clothComponent));
  99. }
  100. // [TODO LYN-1891]
  101. // Revisit when Cloth Component Mesh works with Actors adapted to Atom models.
  102. // At the moment, CreateAssetFromActor fills only Actor to the ActorAsset, but not the RenderActor,
  103. // because of that the AtomModel is not created and OnModelReady is not called.
  104. TEST_F(NvClothComponent, DISABLED_ClothComponent_WithActorSetup_ReturnsValidClothComponentMesh)
  105. {
  106. const AZStd::string meshNodeName = "cloth_mesh_node";
  107. const AZStd::vector<AZ::Vector3> meshVertices = {{
  108. AZ::Vector3(1.0f, 0.0f, 0.0f),
  109. AZ::Vector3(-1.0f, 0.0f, 0.0f),
  110. AZ::Vector3(0.0f, 1.0f, 0.0f)
  111. }};
  112. const AZStd::vector<NvCloth::SimIndexType> meshIndices = {{
  113. 0, 1, 2
  114. }};
  115. const AZStd::vector<VertexSkinInfluences> meshSkinningInfo = {{
  116. VertexSkinInfluences{ SkinInfluence(0, 1.0f) },
  117. VertexSkinInfluences{ SkinInfluence(0, 1.0f) },
  118. VertexSkinInfluences{ SkinInfluence(0, 1.0f) }
  119. }};
  120. const AZStd::vector<AZ::Vector2> meshUVs = {{
  121. AZ::Vector2(1.0f, 1.0f),
  122. AZ::Vector2(0.0f, 1.0f),
  123. AZ::Vector2(0.5f, 0.0f)
  124. }};
  125. // [inverse mass, motion constrain radius, backstop offset, backstop radius]
  126. const AZStd::vector<AZ::Color> meshClothData = {{
  127. AZ::Color(0.75f, 0.6f, 0.5f, 0.1f),
  128. AZ::Color(1.0f, 0.16f, 0.1f, 1.0f),
  129. AZ::Color(0.25f, 1.0f, 0.9f, 0.5f)
  130. }};
  131. const AZ::u32 lodLevel = 0;
  132. NvCloth::ClothConfiguration clothConfiguration;
  133. clothConfiguration.m_meshNode = meshNodeName;
  134. AZStd::unique_ptr<AZ::Entity> entity = CreateClothActorEntity(clothConfiguration);
  135. entity->Activate();
  136. auto* actorComponent = entity->FindComponent<EMotionFX::Integration::ActorComponent>();
  137. auto* clothComponent = entity->FindComponent<NvCloth::ClothComponent>();
  138. {
  139. auto actor = AZStd::make_unique<ActorHelper>("actor_test");
  140. auto meshNodeIndex = actor->AddJoint(meshNodeName);
  141. actor->SetMesh(lodLevel, meshNodeIndex, CreateEMotionFXMesh(meshVertices, meshIndices, meshSkinningInfo, meshUVs/*, meshClothData*/));
  142. actor->FinishSetup();
  143. actorComponent->SetActorAsset(CreateAssetFromActor(AZStd::move(actor)));
  144. }
  145. EXPECT_TRUE(clothComponent->GetClothComponentMesh() != nullptr);
  146. }
  147. } // namespace UnitTest