feat(physics): add rigidbody velocity control

This commit is contained in:
2026-04-15 12:53:36 +08:00
parent 8645334e38
commit 1d207cf251
6 changed files with 243 additions and 3 deletions

View File

@@ -398,4 +398,70 @@ TEST(PhysicsWorld_Test, RuntimeBodyTypeChangesRebuildActorAndEnableSimulation) {
EXPECT_LT(body->GetTransform()->GetPosition().y, initialY - 0.1f);
}
TEST(PhysicsWorld_Test, RuntimeLinearVelocityMovesDynamicBody) {
using namespace XCEngine::Components;
if (!XCEngine::Physics::PhysicsWorld::IsPhysXAvailable()) {
GTEST_SKIP() << "PhysX backend is not available in this build.";
}
Scene scene("PhysicsScene");
GameObject* body = scene.CreateGameObject("Body");
body->GetTransform()->SetPosition(XCEngine::Math::Vector3(0.0f, 1.0f, 0.0f));
RigidbodyComponent* rigidbody = body->AddComponent<RigidbodyComponent>();
rigidbody->SetBodyType(XCEngine::Physics::PhysicsBodyType::Dynamic);
rigidbody->SetUseGravity(false);
rigidbody->SetLinearVelocity(XCEngine::Math::Vector3(0.0f, 2.0f, 0.0f));
SphereColliderComponent* sphereCollider = body->AddComponent<SphereColliderComponent>();
sphereCollider->SetRadius(0.5f);
XCEngine::Physics::PhysicsWorld world;
XCEngine::Physics::PhysicsWorldCreateInfo createInfo = {};
createInfo.scene = &scene;
ASSERT_TRUE(world.Initialize(createInfo));
const float initialY = body->GetTransform()->GetPosition().y;
for (int index = 0; index < 30; ++index) {
world.Step(1.0f / 60.0f);
}
EXPECT_GT(body->GetTransform()->GetPosition().y, initialY + 0.9f);
EXPECT_NEAR(rigidbody->GetLinearVelocity().y, 2.0f, 0.02f);
}
TEST(PhysicsWorld_Test, AddForceImpulseMovesDynamicBody) {
using namespace XCEngine::Components;
if (!XCEngine::Physics::PhysicsWorld::IsPhysXAvailable()) {
GTEST_SKIP() << "PhysX backend is not available in this build.";
}
Scene scene("PhysicsScene");
GameObject* body = scene.CreateGameObject("Body");
body->GetTransform()->SetPosition(XCEngine::Math::Vector3(0.0f, 1.0f, 0.0f));
RigidbodyComponent* rigidbody = body->AddComponent<RigidbodyComponent>();
rigidbody->SetBodyType(XCEngine::Physics::PhysicsBodyType::Dynamic);
rigidbody->SetUseGravity(false);
rigidbody->SetMass(1.0f);
SphereColliderComponent* sphereCollider = body->AddComponent<SphereColliderComponent>();
sphereCollider->SetRadius(0.5f);
XCEngine::Physics::PhysicsWorld world;
XCEngine::Physics::PhysicsWorldCreateInfo createInfo = {};
createInfo.scene = &scene;
ASSERT_TRUE(world.Initialize(createInfo));
const float initialY = body->GetTransform()->GetPosition().y;
rigidbody->AddForce(
XCEngine::Math::Vector3(0.0f, 3.0f, 0.0f),
XCEngine::Physics::PhysicsForceMode::Impulse);
for (int index = 0; index < 10; ++index) {
world.Step(1.0f / 60.0f);
}
EXPECT_GT(body->GetTransform()->GetPosition().y, initialY + 0.35f);
EXPECT_NEAR(rigidbody->GetLinearVelocity().y, 3.0f, 0.02f);
}
} // namespace