ClothColliderTests.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 "Editor/ColliderHelpers.h"
  9. #include <gtest/gtest.h>
  10. #include <QtTest>
  11. #include <QTreeView>
  12. #include <Editor/Plugins/ColliderWidgets/ClothOutlinerNotificationHandler.h>
  13. #include <Editor/Plugins/SkeletonOutliner/SkeletonOutlinerPlugin.h>
  14. #include <Editor/ReselectingTreeView.h>
  15. #include <EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  16. #include <Tests/TestAssetCode/ActorFactory.h>
  17. #include <Tests/TestAssetCode/SimpleActors.h>
  18. #include <Tests/TestAssetCode/TestActorAssets.h>
  19. #include <Tests/UI/UIFixture.h>
  20. namespace EMotionFX
  21. {
  22. // Add so that ClothJointInspectorPlugin::IsNvClothGemAvailable() will return the correct value
  23. class SystemComponent
  24. : public AZ::Component
  25. // , public SystemRequestBus::Handler
  26. // , protected CrySystemEventBus::Handler
  27. {
  28. public:
  29. AZ_COMPONENT(SystemComponent, "{89DF5C48-64AC-4B8E-9E61-0D4C7A7B5491}");
  30. static void Reflect(AZ::ReflectContext* context)
  31. {
  32. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  33. {
  34. serializeContext->Class<SystemComponent, AZ::Component>()
  35. ->Version(0);
  36. }
  37. }
  38. protected:
  39. void Activate() override {}
  40. void Deactivate() override {}
  41. };
  42. class ClothColliderTestsFixture : public UIFixture
  43. {
  44. public:
  45. void TearDown() override
  46. {
  47. QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  48. UIFixture::TearDown();
  49. }
  50. void CreateSkeletonAndModelIndices()
  51. {
  52. // Select the newly created actor
  53. AZStd::string result;
  54. EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand("Select -actorID 0", result)) << result.c_str();
  55. // Change the Editor mode to Physics
  56. EMStudio::GetMainWindow()->ApplicationModeChanged("Physics");
  57. // Get the SkeletonOutlinerPlugin and find its treeview
  58. m_skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
  59. EXPECT_TRUE(m_skeletonOutliner);
  60. m_treeView = m_skeletonOutliner->GetDockWidget()->findChild<ReselectingTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
  61. m_indexList.clear();
  62. m_treeView->RecursiveGetAllChildren(m_treeView->model()->index(0, 0, m_treeView->model()->index(0, 0)), m_indexList);
  63. }
  64. protected:
  65. bool ShouldReflectPhysicSystem() override { return true; }
  66. void ReflectMockedSystems() override
  67. {
  68. UIFixture::ReflectMockedSystems();
  69. // Reflect the mocked version of the cloth system.
  70. AZ::SerializeContext* serializeContext = nullptr;
  71. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  72. SystemComponent::Reflect(serializeContext);
  73. }
  74. QModelIndexList m_indexList;
  75. ReselectingTreeView* m_treeView;
  76. EMotionFX::SkeletonOutlinerPlugin* m_skeletonOutliner;
  77. };
  78. TEST_F(ClothColliderTestsFixture, RemoveClothColliders)
  79. {
  80. const int numJoints = 8;
  81. const int firstIndex = 3;
  82. const int lastIndex = 6;
  83. RecordProperty("test_case_id", "C18970351");
  84. AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
  85. AZ::Data::Asset<Integration::ActorAsset> actorAsset =
  86. TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, numJoints, "RagdollEditTestsActor");
  87. CreateSkeletonAndModelIndices();
  88. EXPECT_EQ(m_indexList.size(), numJoints);
  89. // Select four Indexes
  90. SelectIndexes(m_indexList, m_treeView, firstIndex, lastIndex);
  91. // Bring up the contextMenu
  92. const QRect rect = m_treeView->visualRect(m_indexList[5]);
  93. EXPECT_TRUE(rect.isValid());
  94. BringUpContextMenu(m_treeView, rect);
  95. QMenu* contextMenu = m_skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
  96. ASSERT_TRUE(contextMenu);
  97. QAction* clothAction;
  98. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(clothAction, contextMenu, "Cloth"));
  99. QMenu* clothMenu = clothAction->menu();
  100. ASSERT_TRUE(clothMenu);
  101. QAction* colliderAction;
  102. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(colliderAction, clothMenu, "Add collider"));
  103. QMenu* colliderMenu = colliderAction->menu();
  104. ASSERT_TRUE(colliderMenu);
  105. QAction* addSphereAction;
  106. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(addSphereAction, colliderMenu, "Add sphere"));
  107. addSphereAction->trigger();
  108. // Check colliders are in model
  109. for (int i = firstIndex; i <= lastIndex; ++i)
  110. {
  111. EXPECT_TRUE(ColliderHelpers::NodeHasClothCollider(m_indexList[i]));
  112. }
  113. // Remove context menu as it is rebuild below
  114. delete contextMenu;
  115. const QRect rect2 = m_treeView->visualRect(m_indexList[4]);
  116. EXPECT_TRUE(rect2.isValid());
  117. BringUpContextMenu(m_treeView, rect2);
  118. // Find the "Remove colliders" entry and trigger it.
  119. contextMenu = m_skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
  120. ASSERT_TRUE(contextMenu);
  121. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(clothAction, contextMenu, "Cloth"));
  122. clothMenu = clothAction->menu();
  123. ASSERT_TRUE(clothMenu);
  124. QAction* removeClothAction;
  125. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(removeClothAction, clothMenu, "Remove colliders"));
  126. removeClothAction->trigger();
  127. // Check colliders have been removed
  128. for (int i = firstIndex; i <= lastIndex; ++i)
  129. {
  130. EXPECT_FALSE(ColliderHelpers::NodeHasClothCollider(m_indexList[i]));
  131. }
  132. }
  133. }