| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <gtest/gtest.h>
- #include <QPushButton>
- #include <QAction>
- #include <QtTest>
- #include <Tests/UI/UIFixture.h>
- #include <Tests/UI/MenuUIFixture.h>
- #include <Tests/UI/ModalPopupHandler.h>
- #include <EMotionFX/CommandSystem/Source/CommandManager.h>
- #include <EMotionFX/Source/Actor.h>
- #include <Editor/ColliderContainerWidget.h>
- #include <EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
- #include <EMotionStudio/EMStudioSDK/Source/PluginManager.h>
- #include <Editor/Plugins/SimulatedObject/SimulatedObjectWidget.h>
- #include <Editor/Plugins/ColliderWidgets/SimulatedObjectColliderWidget.h>
- #include <Editor/InputDialogValidatable.h>
- #include <Editor/Plugins/SkeletonOutliner/SkeletonOutlinerPlugin.h>
- #include <Tests/TestAssetCode/SimpleActors.h>
- #include <Tests/TestAssetCode/ActorFactory.h>
- #include <Tests/TestAssetCode/TestActorAssets.h>
- #include <Tests/PhysicsSetupUtils.h>
- #include <Tests/UI/SkeletonOutlinerTestFixture.h>
- #include <Editor/ReselectingTreeView.h>
- #include <AzQtComponents/Components/Widgets/CardHeader.h>
- namespace EMotionFX
- {
- class CanAddSimulatedObjectFixture
- : public SkeletonOutlinerTestFixture
- {
- public:
- void TearDown() override
- {
- QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- m_actorAsset.Reset();
- UIFixture::TearDown();
- }
- void RecursiveGetAllChildren(QTreeView* treeView, const QModelIndex& index, QModelIndexList& outIndicies)
- {
- outIndicies.push_back(index);
- for (int i = 0; i < treeView->model()->rowCount(index); ++i)
- {
- RecursiveGetAllChildren(treeView, treeView->model()->index(i, 0, index), outIndicies);
- }
- }
- void CreateSimulateObject(const char* objectName)
- {
- // Select the newly created actor
- {
- AZStd::string result;
- EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand("Select -actorID 0", result)) << result.c_str();
- }
- // Change the Editor mode to Simulated Objects
- EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects");
- // Find the Simulated Object Manager and its button
- m_simulatedObjectWidget = EMStudio::GetPluginManager()->FindActivePlugin<EMotionFX::SimulatedObjectWidget>();
- ASSERT_TRUE(m_simulatedObjectWidget) << "Simulated Object plugin not found!";
- QPushButton* addSimulatedObjectButton = m_simulatedObjectWidget->GetDockWidget()->findChild<QPushButton*>("addSimulatedObjectButton");
- // Send the left button click directly to the button
- QTest::mouseClick(addSimulatedObjectButton, Qt::LeftButton);
- // In the Input Dialog set the name of the object and close the dialog
- EMStudio::InputDialogValidatable* inputDialog = qobject_cast<EMStudio::InputDialogValidatable*>(FindTopLevelWidget("EMFX.SimulatedObjectActionManager.SimulatedObjectDialog"));
- ASSERT_NE(inputDialog, nullptr) << "Cannot find input dialog.";
- inputDialog->SetText(objectName);
- inputDialog->accept();
- // There is one and only one simulated objects
- ASSERT_EQ(m_actorAsset->GetActor()->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 1);
- // Check it has the correct name
- EXPECT_STREQ(m_actorAsset->GetActor()->GetSimulatedObjectSetup()->GetSimulatedObject(0)->GetName().c_str(), objectName);
- }
- void AddCapsuleColliderToJointIndex(int index)
- {
- m_skeletonTreeView->selectionModel()->clearSelection();
- // Find the indexed joint in the TreeView and select it
- SelectIndexes(m_indexList, m_skeletonTreeView, index, index);
- // Open the Right Click Context Menu
- const QRect rect = m_skeletonTreeView->visualRect(m_indexList[index-1]);
- EXPECT_TRUE(rect.isValid());
- BringUpContextMenu(m_skeletonTreeView, rect);
- QMenu* contextMenu = m_skeletonOutliner->GetDockWidget()->findChild<QMenu*>("contextMenu");
- // Trace down the sub Menus to Add Collider and select it
- QAction* simulatedObjectColliderAction = GetNamedAction(m_skeletonOutliner->GetDockWidget(), "Add collider");
- ASSERT_TRUE(simulatedObjectColliderAction);
- QMenu* simulatedObjectColliderMenu = simulatedObjectColliderAction->menu();
- const QList<QAction*> addSelectedColliderMenuActions = simulatedObjectColliderMenu->actions();
- auto addCapsuleColliderAction = AZStd::find_if(addSelectedColliderMenuActions.begin(), addSelectedColliderMenuActions.end(), [](const QAction* action) {
- return action->text() == "Capsule";
- });
- ASSERT_NE(addCapsuleColliderAction, addSelectedColliderMenuActions.end());
- size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(
- m_actorAsset->GetActor(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- (*addCapsuleColliderAction)->trigger();
- // Delete the context menu, otherwise there it will still be around during this frame as the Qt event loop has not been run.
- delete contextMenu;
- const size_t numCapsuleCollidersAfterAdd = PhysicsSetupUtils::CountColliders(
- m_actorAsset->GetActor(), PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- ASSERT_EQ(numCapsuleCollidersAfterAdd, numCapsuleColliders + 1);
- m_skeletonTreeView->selectionModel()->clearSelection();
- }
- protected:
- AZ::Data::Asset<Integration::ActorAsset> m_actorAsset;
- EMotionFX::SimulatedObjectWidget* m_simulatedObjectWidget = nullptr;
- EMotionFX::SkeletonOutlinerPlugin* m_skeletonOutliner = nullptr;
- ReselectingTreeView* m_skeletonTreeView = nullptr;
- const QAbstractItemModel* m_skeletonModel;
- QModelIndexList m_indexList;
- };
- TEST_F(CanAddSimulatedObjectFixture, CanAddSimulatedObject)
- {
- RecordProperty("test_case_id", "C13048820");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 1, "CanAddSimulatedObjectActor");
- CreateSimulateObject("New simulated object");
- }
- TEST_F(UIFixture, CanAddSimulatedObjectWithJoints)
- {
- RecordProperty("test_case_id", "C13048818");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- AZ::Data::Asset<Integration::ActorAsset> actorAsset =
- TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 2, "CanAddSimulatedObjectWithJointsActor");
- Actor* actor = actorAsset->GetActor();
- ActorInstance* actorInstance = ActorInstance::Create(actor);
- EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects");
- {
- AZStd::string result;
- EXPECT_TRUE(CommandSystem::GetCommandManager()->ExecuteCommand(AZStd::string{"Select -actorInstanceID "} + AZStd::to_string(actorInstance->GetID()), result)) << result.c_str();
- }
- auto simulatedObjectWidget = static_cast<EMotionFX::SimulatedObjectWidget*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SimulatedObjectWidget::CLASS_ID));
- ASSERT_TRUE(simulatedObjectWidget) << "Simulated Object plugin not found!";
- auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- const QAbstractItemModel* model = treeView->model();
- const QModelIndex rootJointIndex = model->index(0, 0, model->index(0, 0));
- ASSERT_TRUE(rootJointIndex.isValid()) << "Unable to find a model index for the root joint of the actor";
- treeView->selectionModel()->select(rootJointIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- treeView->scrollTo(rootJointIndex);
- BringUpContextMenu(treeView, treeView->visualRect(rootJointIndex));
- QMenu* contextMenu = skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
- EXPECT_TRUE(contextMenu);
- QAction* addSelectedJointAction;
- EXPECT_TRUE(UIFixture::GetActionFromContextMenu(addSelectedJointAction, contextMenu, "Add to simulated object"));
- QMenu* addSelectedJointMenu = addSelectedJointAction->menu();
- EXPECT_TRUE(addSelectedJointMenu);
- QAction* newSimulatedObjectAction;
- EXPECT_TRUE(UIFixture::GetActionFromContextMenu(newSimulatedObjectAction, addSelectedJointMenu, "New simulated object..."));
- // Handle the add children dialog box.
- ModalPopupHandler messageBoxPopupHandler;
- messageBoxPopupHandler.WaitForPopupPressDialogButton<QMessageBox*>(QDialogButtonBox::No);
- newSimulatedObjectAction->trigger();
- EMStudio::InputDialogValidatable* inputDialog = qobject_cast<EMStudio::InputDialogValidatable*>(FindTopLevelWidget("EMFX.SimulatedObjectActionManager.SimulatedObjectDialog"));
- ASSERT_NE(inputDialog, nullptr) << "Cannot find input dialog.";
- inputDialog->SetText("New simulated object");
- inputDialog->accept();
- ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 1);
- const auto simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(0);
- EXPECT_STREQ(simulatedObject->GetName().c_str(), "New simulated object");
- EXPECT_EQ(simulatedObject->GetNumSimulatedRootJoints(), 1);
- EXPECT_EQ(simulatedObject->GetNumSimulatedJoints(), 1);
- EXPECT_STREQ(actor->GetSkeleton()->GetNode(simulatedObject->GetSimulatedJoint(0)->GetSkeletonJointIndex())->GetName(), "rootJoint");
- EXPECT_STREQ(actor->GetSkeleton()->GetNode(simulatedObject->GetSimulatedRootJoint(0)->GetSkeletonJointIndex())->GetName(), "rootJoint");
- QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- actorInstance->Destroy();
- }
- TEST_F(CanAddSimulatedObjectFixture, CanAddSimulatedObjectWithJointsAndName)
- {
- RecordProperty("test_case_id", "C13048820a");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 5, "CanAddSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- CreateSimulateObject("sim1");
- // Get the Skeleton Outliner and find the model relating to its treeview
- auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- const QAbstractItemModel* model = treeView->model();
- // Find the 3rd joint in the TreeView and select it
- const QModelIndex jointIndex = model->index(0, 3, model->index(0, 0));
- ASSERT_TRUE(jointIndex.isValid()) << "Unable to find a model index for the root joint of the actor";
- treeView->selectionModel()->select(jointIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- treeView->scrollTo(jointIndex);
- // Open the Right Click Context Menu
- const QRect rect = treeView->visualRect(jointIndex);
- EXPECT_TRUE(rect.isValid());
- BringUpContextMenu(treeView, rect);
- // Trace down the sub Menus to <New simulated object> and select it
- QMenu* contextMenu = skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
- EXPECT_TRUE(contextMenu);
- QAction* simulatedObjectAction;
- EXPECT_TRUE(UIFixture::GetActionFromContextMenu(simulatedObjectAction, contextMenu, "Add to simulated object"));
- QMenu* simulatedObjectMenu = simulatedObjectAction->menu();
- EXPECT_TRUE(simulatedObjectMenu);
- QAction* newSimulatedObjectAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(newSimulatedObjectAction, simulatedObjectMenu, "New simulated object..."));
- // Handle the add children dialog box.
- ModalPopupHandler messageBoxPopupHandler;
- messageBoxPopupHandler.WaitForPopupPressDialogButton<QMessageBox*>(QDialogButtonBox::No);
- newSimulatedObjectAction->trigger();
- // Set the name in the Dialog Box and test it.
- EMStudio::InputDialogValidatable* inputDialog = qobject_cast<EMStudio::InputDialogValidatable*>(FindTopLevelWidget("EMFX.SimulatedObjectActionManager.SimulatedObjectDialog"));
- ASSERT_NE(inputDialog, nullptr) << "Cannot find input dialog.";
- inputDialog->SetText("sim2");
- inputDialog->accept();
- ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 2);
- const auto simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(1);
- EXPECT_STREQ(simulatedObject->GetName().c_str(), "sim2");
- }
- TEST_F(CanAddSimulatedObjectFixture, CanAddColliderToSimulatedObject)
- {
- RecordProperty("test_case_id", "C13048816");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 5, "CanAddSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- CreateSimulateObject("sim1");
- // Get the Skeleton Outliner and find the model relating to its treeview
- auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- const QAbstractItemModel* model = treeView->model();
- // Find the 3rd joint in the TreeView and select it
- const QModelIndex jointIndex = model->index(0, 3, model->index(0, 0));
- ASSERT_TRUE(jointIndex.isValid()) << "Unable to find a model index for the root joint of the actor";
- treeView->selectionModel()->select(jointIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- treeView->scrollTo(jointIndex);
- // Open the Right Click Context Menu
- const QRect rect = treeView->visualRect(jointIndex);
- EXPECT_TRUE(rect.isValid());
- BringUpContextMenu(treeView, rect);
- // Trace down the sub Menus to Add Collider and select it
- QMenu* contextMenu = skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
- EXPECT_TRUE(contextMenu);
- QAction* addSelectedAddColliderAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addSelectedAddColliderAction, contextMenu, "Add collider"));
- QMenu* addSelectedColliderMenu = addSelectedAddColliderAction->menu();
- QAction* addCapsuleColliderAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addCapsuleColliderAction, addSelectedColliderMenu, "Capsule"));
- size_t numCapsuleColliders = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- EXPECT_EQ(numCapsuleColliders, 0);
- addCapsuleColliderAction->trigger();
- // Check that a collider has been added.
- size_t numCollidersAfterAddCapsule = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- ASSERT_EQ(numCollidersAfterAddCapsule, numCapsuleColliders + 1) << "Capsule collider not added.";
- QAction* addSphereColliderAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addSphereColliderAction, addSelectedColliderMenu, "Sphere"));
- const size_t numSphereColliders = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere);
- EXPECT_EQ(numSphereColliders, 0);
- addSphereColliderAction->trigger();
- // Check that a second collider has been added.
- const size_t numCollidersAfterAddSphere = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere);
- ASSERT_EQ(numCollidersAfterAddSphere, numSphereColliders + 1) << "Sphere collider not added.";
- }
- TEST_F(CanAddSimulatedObjectFixture, CanRemoveSimulatedObject)
- {
- RecordProperty("test_case_id", "C13048821");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 1, "CanRemoveSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- CreateSimulateObject("TestObject1");
- // Get the Simulated Object and find the model relating to its treeview
- EMotionFX::SimulatedObjectWidget* simulatedObjectWidget = static_cast<EMotionFX::SimulatedObjectWidget*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SimulatedObjectWidget::CLASS_ID));
- ASSERT_TRUE(simulatedObjectWidget);
- QTreeView* treeView = simulatedObjectWidget->GetDockWidget()->findChild<QTreeView*>("EMFX.SimulatedObjectWidget.TreeView");
- ASSERT_TRUE(treeView);
- const SimulatedObjectModel* model = reinterpret_cast<SimulatedObjectModel*>(treeView->model());
- const QModelIndex index = model->index(0, 0);
- treeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- treeView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
- treeView->scrollTo(index);
- BringUpContextMenu(treeView, treeView->visualRect(index));
- QMenu* contextMenu = simulatedObjectWidget->GetDockWidget()->findChild<QMenu*>("EMFX.SimulatedObjectWidget.ContextMenu");
- EXPECT_TRUE(contextMenu);
- QAction* removeObjectAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(removeObjectAction, contextMenu, "Remove object"));
- removeObjectAction->trigger();
- ASSERT_EQ(actor->GetSimulatedObjectSetup()->GetNumSimulatedObjects(), 0);
- }
- TEST_F(CanAddSimulatedObjectFixture, CanAddColliderToSimulatedObjectFromInspector)
- {
- RecordProperty("test_case_id", "C20385259");
-
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 5, "CanAddSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- CreateSimulateObject("sim1");
- // Get the Skeleton Outliner and find the model relating to its treeview
- auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- ASSERT_TRUE(skeletonOutliner);
- QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- ASSERT_TRUE(treeView);
- const QAbstractItemModel* model = treeView->model();
- QModelIndexList indexList;
- RecursiveGetAllChildren(treeView, model->index(0, 0, model->index(0, 0)), indexList);
- SelectIndexes(indexList, treeView, 3, 3);
- QDockWidget* simulatedObjectWidget = EMStudio::GetPluginManager()->FindActivePlugin<SimulatedObjectWidget>()->GetDockWidget();
- ASSERT_TRUE(simulatedObjectWidget);
- QPushButton* addColliderButton =
- simulatedObjectWidget->findChild<QPushButton*>("EMFX.SimulatedObjectColliderWidget.AddColliderButton");
- ASSERT_TRUE(addColliderButton);
- // Send the left button click directly to the button
- QTest::mouseClick(addColliderButton, Qt::LeftButton);
- const size_t numCapsuleColliders =
- PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- EXPECT_EQ(numCapsuleColliders, 0);
- const size_t numSphereColliders =
- PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere);
- EXPECT_EQ(numSphereColliders, 0);
- QMenu* contextMenu = addColliderButton->findChild<QMenu*>("EMFX.AddColliderButton.ContextMenu");
- EXPECT_TRUE(contextMenu);
- QAction* addCapsuleAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addCapsuleAction, contextMenu, "Add capsule"));
- addCapsuleAction->trigger();
- const size_t numCollidersAfterAddCapsule =
- PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Capsule);
- ASSERT_EQ(numCollidersAfterAddCapsule, numCapsuleColliders + 1) << "Capsule collider not added.";
- QAction* addSphereAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(addSphereAction, contextMenu, "Add sphere"));
- addSphereAction->trigger();
- const size_t numCollidersAfterAddSphere =
- PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider, false, Physics::ShapeType::Sphere);
- ASSERT_EQ(numCollidersAfterAddSphere, numSphereColliders + 1) << "Sphere collider not added.";
- }
- TEST_F(CanAddSimulatedObjectFixture, CanAddMultipleJointsToSimulatedObject)
- {
- RecordProperty("test_case_id", "C13048818");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 7, "CanAddSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- CreateSimulateObject("ANY");
- // Get the Skeleton Outliner and find the model relating to its treeview
- auto skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- ASSERT_TRUE(skeletonOutliner) << "Can't find SkeletonOutlinerPlugin";
- QTreeView* treeView = skeletonOutliner->GetDockWidget()->findChild<QTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- ASSERT_TRUE(treeView) << "Skeleton Treeview not found";
- const QAbstractItemModel* model = treeView->model();
- QModelIndexList indexList;
- RecursiveGetAllChildren(treeView, model->index(0, 0, model->index(0, 0)), indexList);
- SelectIndexes(indexList, treeView, 3, 5);
- // Open the Right Click Context Menu
- const QRect rect = treeView->visualRect(indexList[4]);
- EXPECT_TRUE(rect.isValid());
- BringUpContextMenu(treeView, rect);
- // Trace down the sub Menus to <New simulated object> and select it
- QMenu* contextMenu = skeletonOutliner->GetDockWidget()->findChild<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
- EXPECT_TRUE(contextMenu) << "Context Menu not found";
- QAction* simulatedObjectAction;
- EXPECT_TRUE(UIFixture::GetActionFromContextMenu(simulatedObjectAction, contextMenu, "Add to simulated object"));
- QMenu* simulatedObjectMenu = simulatedObjectAction->menu();
- EXPECT_TRUE(simulatedObjectMenu) << "Simulated Object Menu not found";
- QAction* newSimulatedObjectAction;
- ASSERT_TRUE(UIFixture::GetActionFromContextMenu(newSimulatedObjectAction, simulatedObjectMenu, "ANY")) << "Can't find named simulated object in menu";
- // Handle the add children dialog box.
- ModalPopupHandler messageBoxPopupHandler;
- messageBoxPopupHandler.WaitForPopupPressDialogButton<QMessageBox*>(QDialogButtonBox::No);
- newSimulatedObjectAction->trigger();
- const EMotionFX::SimulatedObject* simulatedObject = actor->GetSimulatedObjectSetup()->GetSimulatedObject(0);
- EXPECT_EQ(simulatedObject->GetNumSimulatedRootJoints(), 1);
- EXPECT_EQ(simulatedObject->GetNumSimulatedJoints(), 3);
- }
- TEST_F(CanAddSimulatedObjectFixture, CanRemoveColliderFromSimulatedObject)
- {
- RecordProperty("test_case_id", "C13048817");
- AZ::Data::AssetId actorAssetId("{5060227D-B6F4-422E-BF82-41AAC5F228A5}");
- m_actorAsset = TestActorAssets::CreateActorAssetAndRegister<SimpleJointChainActor>(actorAssetId, 5, "CanAddSimulatedObjectActor");
- Actor* actor = m_actorAsset->GetActor();
- EMStudio::GetMainWindow()->ApplicationModeChanged("SimulatedObjects");
- QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- CreateSimulateObject("sim1");
- m_skeletonOutliner = static_cast<EMotionFX::SkeletonOutlinerPlugin*>(EMStudio::GetPluginManager()->FindActivePlugin(EMotionFX::SkeletonOutlinerPlugin::CLASS_ID));
- m_skeletonTreeView = m_skeletonOutliner->GetDockWidget()->findChild<ReselectingTreeView*>("EMFX.SkeletonOutlinerPlugin.SkeletonOutlinerTreeView");
- m_skeletonModel = m_skeletonTreeView->model();
- m_indexList.clear();
- m_skeletonTreeView->RecursiveGetAllChildren(m_skeletonModel->index(0, 0, m_skeletonModel->index(0, 0)), m_indexList);
- // Add colliders to two joints.
- AddCapsuleColliderToJointIndex(3);
- AddCapsuleColliderToJointIndex(4);
- const size_t numCollidersAfterAdd = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider);
- EXPECT_EQ(numCollidersAfterAdd, 2);
- m_indexList.clear();
- m_skeletonTreeView->RecursiveGetAllChildren(m_skeletonModel->index(0, 0, m_skeletonModel->index(0, 0)), m_indexList);
- // Reselect joint 3 and pop up the context menu for it.
- m_skeletonTreeView->selectionModel()->clearSelection();
- SelectIndexes(m_indexList, m_skeletonTreeView, 3, 3);
- // Open the Right Click Context Menu
- const QRect rect = m_skeletonTreeView->visualRect(m_indexList[2]);
- EXPECT_TRUE(rect.isValid());
- BringUpContextMenu(m_skeletonTreeView, rect);
- const QList<QMenu*> contextMenus = m_skeletonOutliner->GetDockWidget()->findChildren<QMenu*>("EMFX.SkeletonOutlinerPlugin.ContextMenu");
- EXPECT_NE(contextMenus.size(), 0) << "Unable to find Skeketon Outliner context menu.";
- // There will be several existing menus, as the Qt event loop has not yet been run, so we need to find the latest and use that.
- QMenu* contextMenu = *(contextMenus.end() - 1);
- QAction* removeAction = contextMenu->findChild<QAction*>("EMFX.SimulatedObjectWidget.RemoveCollidersAction");
- ASSERT_TRUE(removeAction);
-
- removeAction->trigger();
- // Check that one of the colliders is now gone.
- const size_t numCollidersAfterFirstRemove = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider);
- ASSERT_EQ(numCollidersAfterFirstRemove, numCollidersAfterAdd - 1) << "RemoveCollider action in Simulated Object Inspector failed.";
- // Now do the same thing using the Simulated Object Inspector context menu.
- const SimulatedObjectColliderWidget* simulatedObjectColliderWidget = GetSimulatedObjectColliderWidget();
- ASSERT_TRUE(simulatedObjectColliderWidget) << "SimulatedObjectColliderWidget not found.";
- // Select the second collider that was made earlier.
- m_skeletonTreeView->selectionModel()->clearSelection();
- SelectIndexes(m_indexList, m_skeletonTreeView, 4, 4);
- const ColliderContainerWidget* colliderContainerWidget = simulatedObjectColliderWidget->findChild< ColliderContainerWidget*>();
- ASSERT_TRUE(colliderContainerWidget) << "ColliderContainerWidget not found.";
- // Get the collider widget card from the container.
- const ColliderWidget* colliderWidget = colliderContainerWidget->findChild<ColliderWidget*>();
- ASSERT_TRUE(colliderWidget) << "ColliderWidget not found.";
- const AzQtComponents::CardHeader* cardHeader = colliderWidget->findChild<AzQtComponents::CardHeader*>();
- ASSERT_TRUE(cardHeader) << "ColliderWidget CardHeader not found.";
- const QFrame* frame = cardHeader->findChild<QFrame*>("Background");
- ASSERT_TRUE(frame) << "ColliderWidget CardHeader Background Frame not found.";
- QPushButton* contextMenubutton = frame->findChild< QPushButton*>("ContextMenu");
- ASSERT_TRUE(contextMenubutton) << "ColliderWidget ContextMenu not found.";
- // Pop up the context menu.
- QTest::mouseClick(contextMenubutton, Qt::LeftButton);
- // Find the delete collider button and press it.
- const QMenu* collilderWidgetContextMenu = colliderWidget->findChild<QMenu*>("EMFX.ColliderContainerWidget.ContextMenu");
- QAction* delAction = collilderWidgetContextMenu->findChild<QAction*>("EMFX.ColliderContainerWidget.DeleteColliderAction");
- delAction->trigger();
- // Check that we have the number of colliders we started we expect.
- const size_t numCollidersAfterSecondRemove = PhysicsSetupUtils::CountColliders(actor, PhysicsSetup::SimulatedObjectCollider);
- ASSERT_EQ(numCollidersAfterSecondRemove, numCollidersAfterAdd - 2);
- }
- } // namespace EMotionFX
|