test(editor): verify physics play session runtime closure
This commit is contained in:
@@ -5,8 +5,12 @@
|
||||
#include "Core/PlaySessionController.h"
|
||||
#include "Commands/EntityCommands.h"
|
||||
|
||||
#include <XCEngine/Components/BoxColliderComponent.h>
|
||||
#include <XCEngine/Components/RigidbodyComponent.h>
|
||||
#include <XCEngine/Components/SphereColliderComponent.h>
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
#include <XCEngine/Input/InputManager.h>
|
||||
#include <XCEngine/Physics/PhysicsWorld.h>
|
||||
|
||||
namespace XCEngine::Editor {
|
||||
namespace {
|
||||
@@ -274,5 +278,68 @@ TEST_F(PlaySessionControllerTest, RuntimeSceneUndoRedoRebindsPlaySessionBeforeSt
|
||||
EXPECT_EQ(m_context.GetSceneManager().GetEntity(runtimeEntityId), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(PlaySessionControllerTest, PlayModeCreatesRuntimePhysicsWorldAndRestoresEditorSnapshotAfterSimulation) {
|
||||
if (!::XCEngine::Physics::PhysicsWorld::IsPhysXAvailable()) {
|
||||
GTEST_SKIP() << "PhysX is not available in this configuration.";
|
||||
}
|
||||
|
||||
auto* ground = m_context.GetSceneManager().CreateEntity("Ground");
|
||||
ASSERT_NE(ground, nullptr);
|
||||
ground->GetTransform()->SetLocalPosition(Math::Vector3(0.0f, -1.0f, 0.0f));
|
||||
auto* groundCollider = ground->AddComponent<::XCEngine::Components::BoxColliderComponent>();
|
||||
ASSERT_NE(groundCollider, nullptr);
|
||||
groundCollider->SetSize(Math::Vector3(10.0f, 1.0f, 10.0f));
|
||||
|
||||
auto* ball = m_context.GetSceneManager().CreateEntity("Ball");
|
||||
ASSERT_NE(ball, nullptr);
|
||||
const uint64_t ballId = ball->GetID();
|
||||
ball->GetTransform()->SetLocalPosition(Math::Vector3(0.0f, 5.0f, 0.0f));
|
||||
auto* rigidbody = ball->AddComponent<::XCEngine::Components::RigidbodyComponent>();
|
||||
ASSERT_NE(rigidbody, nullptr);
|
||||
rigidbody->SetUseGravity(true);
|
||||
rigidbody->SetLinearDamping(0.0f);
|
||||
rigidbody->SetAngularDamping(0.0f);
|
||||
auto* sphereCollider = ball->AddComponent<::XCEngine::Components::SphereColliderComponent>();
|
||||
ASSERT_NE(sphereCollider, nullptr);
|
||||
sphereCollider->SetRadius(0.5f);
|
||||
|
||||
const bool dirtyStateBeforePlay = m_context.GetSceneManager().IsSceneDirty();
|
||||
|
||||
ASSERT_TRUE(m_controller.StartPlay(m_context));
|
||||
ASSERT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Play);
|
||||
|
||||
::XCEngine::Physics::PhysicsWorld* physicsWorld = m_controller.GetRuntimePhysicsWorld();
|
||||
ASSERT_NE(physicsWorld, nullptr);
|
||||
EXPECT_TRUE(physicsWorld->IsInitialized());
|
||||
EXPECT_EQ(physicsWorld->GetTrackedRigidbodyCount(), 1u);
|
||||
EXPECT_EQ(physicsWorld->GetTrackedColliderCount(), 2u);
|
||||
|
||||
auto* runtimeBall = m_context.GetSceneManager().GetEntity(ballId);
|
||||
ASSERT_NE(runtimeBall, nullptr);
|
||||
const float initialRuntimeY = runtimeBall->GetTransform()->GetLocalPosition().y;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
m_controller.Update(m_context, 0.05f);
|
||||
}
|
||||
|
||||
runtimeBall = m_context.GetSceneManager().GetEntity(ballId);
|
||||
ASSERT_NE(runtimeBall, nullptr);
|
||||
const float simulatedRuntimeY = runtimeBall->GetTransform()->GetLocalPosition().y;
|
||||
EXPECT_LT(simulatedRuntimeY, initialRuntimeY);
|
||||
EXPECT_EQ(m_context.GetSceneManager().IsSceneDirty(), dirtyStateBeforePlay);
|
||||
|
||||
ASSERT_TRUE(m_controller.StopPlay(m_context));
|
||||
EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Edit);
|
||||
EXPECT_EQ(m_controller.GetRuntimePhysicsWorld(), nullptr);
|
||||
EXPECT_EQ(m_context.GetSceneManager().IsSceneDirty(), dirtyStateBeforePlay);
|
||||
|
||||
auto* restoredBall = m_context.GetSceneManager().GetEntity(ballId);
|
||||
ASSERT_NE(restoredBall, nullptr);
|
||||
const Math::Vector3 restoredPosition = restoredBall->GetTransform()->GetLocalPosition();
|
||||
EXPECT_NEAR(restoredPosition.x, 0.0f, 1e-4f);
|
||||
EXPECT_NEAR(restoredPosition.y, 5.0f, 1e-4f);
|
||||
EXPECT_NEAR(restoredPosition.z, 0.0f, 1e-4f);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace XCEngine::Editor
|
||||
|
||||
Reference in New Issue
Block a user