CanAddJointAndChildren.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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 <gtest/gtest.h>
  9. #include <QPushButton>
  10. #include <QAction>
  11. #include <QtTest>
  12. #include <Tests/UI/UIFixture.h>
  13. #include <Tests/UI/ModalPopupHandler.h>
  14. #include <EMotionFX/Source/Actor.h>
  15. #include <EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  16. #include <Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h>
  17. #include <Editor/Plugins/SkeletonOutliner/SkeletonOutlinerPlugin.h>
  18. #include <Tests/TestAssetCode/SimpleActors.h>
  19. #include <Tests/TestAssetCode/ActorFactory.h>
  20. #include <Tests/TestAssetCode/TestActorAssets.h>
  21. namespace EMotionFX
  22. {
  23. TEST_F(UIFixture, CanAddJointAndChildren)
  24. {
  25. /*
  26. Test Case: C13048819
  27. Can Add Joint And Children
  28. Creates an actor, navigates the context menu to invoke "Add Joint and Children", then validates that it functions correctly.
  29. */
  30. RecordProperty("test_case_id", "C13048819");
  31. // Create an actor
  32. AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
  33. AZ::Data::Asset<Integration::ActorAsset> actorAsset =
  34. TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 5, "SimpleActor");
  35. ActorInstance* actorInstance = ActorInstance::Create(actorAsset->GetActor());
  36. const Actor* actor = actorAsset->GetActor();
  37. // Open simulated objects layout
  38. EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects");
  39. // Execute command to select actor instance
  40. {
  41. AZStd::string result;
  42. EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand(AZStd::string{ "Select -actorInstanceID " } +AZStd::to_string(actorInstance->GetID()), result)) << result.c_str();
  43. }
  44. auto simulatedObjectWidget = static_cast<EMotionFX::SimulatedObjectWidget*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SimulatedObjectWidget::CLASS_ID));
  45. ASSERT_TRUE(simulatedObjectWidget) << "Simulated Object plugin not found!";
  46. auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
  47. QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
  48. const QAbstractItemModel* model = treeView->model();
  49. const QModelIndex rootJointIndex = model->index(0, 0, model->index(0, 0));
  50. ASSERT_TRUE(rootJointIndex.isValid()) << "Unable to find a model index for the root joint of the actor";
  51. treeView->selectionModel()->select(rootJointIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
  52. // Open context menu
  53. treeView->scrollTo(rootJointIndex);
  54. const QRect rect = treeView->visualRect(rootJointIndex);
  55. ASSERT_TRUE(rect.isValid());
  56. {
  57. QContextMenuEvent cme(QContextMenuEvent::Mouse, rect.center(), treeView->viewport()->mapTo(treeView->window(), rect.center()));
  58. QSpontaneKeyEvent::setSpontaneous(&cme);
  59. QApplication::instance()->notify(
  60. treeView->viewport(),
  61. &cme
  62. );
  63. }
  64. // "Simulated object" -> "Add joints and children" -> "<New simulated object>"
  65. QMenu* contextMenu = skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
  66. EXPECT_TRUE(contextMenu);
  67. QAction* simulatedObjectAction;
  68. EXPECT_TRUE(UIFixture::GetActionFromContextMenu(simulatedObjectAction, contextMenu, "Add to simulated object"));
  69. QMenu* simulatedObjectMenu = simulatedObjectAction->menu();
  70. EXPECT_TRUE(simulatedObjectMenu);
  71. QAction* newSimulatedObjectAction;
  72. ASSERT_TRUE(UIFixture::GetActionFromContextMenu(newSimulatedObjectAction, simulatedObjectMenu, "New simulated object..."));
  73. // Handle the add children dialog box.
  74. ModalPopupHandler messageBoxPopupHandler;
  75. messageBoxPopupHandler.WaitForPopupPressDialogButton<QMessageBox*>(QDialogButtonBox::Yes);
  76. newSimulatedObjectAction->trigger();
  77. EMStudio::InputDialogValidatable* inputDialog = qobject_cast<EMStudio::InputDialogValidatable*>(FindTopLevelWidget("EMFX.SimulatedObjectActionManager.SimulatedObjectDialog"));
  78. ASSERT_NE(inputDialog, nullptr) << "Cannot find input dialog.";
  79. inputDialog->SetText("Joint and Children Simulated Object");
  80. inputDialog->accept();
  81. ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 1);
  82. const auto simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(0);
  83. EXPECT_STREQ(simulatedObject->GetName().c_str(), "Joint and Children Simulated Object");
  84. EXPECT_EQ(simulatedObject->GetNumSimulatedRootJoints(), 1);
  85. EXPECT_EQ(simulatedObject->GetNumSimulatedJoints(), 5);
  86. EXPECT_STREQ(actor->GetSkeleton()->GetNode(simulatedObject->GetSimulatedJoint(0)->GetSkeletonJointIndex())->GetName(), "rootJoint");
  87. EXPECT_STREQ(actor->GetSkeleton()->GetNode(simulatedObject->GetSimulatedRootJoint(0)->GetSkeletonJointIndex())->GetName(), "rootJoint");
  88. QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
  89. actorInstance->Destroy();
  90. }
  91. } // namespace EMotionFX