physics: rigid body drive API (force/impulse/torque/velocity)

PhysicsWorld facade methods addressed by entity bits via body records:
AddForce/AddImpulse/AddTorque (dynamic bodies only, auto-wake), Set/
GetLinearVelocity/SetAngularVelocity (dynamic + kinematic). Inspector
RigidBody block gains impulse debug controls for manual response tests.
Transient by design — nothing serialized.
This commit is contained in:
2026-10-03 16:10:22 +08:00
parent fae6614e70
commit 6c81bfd70d
3 changed files with 82 additions and 0 deletions
+57
View File
@@ -578,6 +578,63 @@ namespace Engine {
return true;
}
// ---- 刚体驱动(游戏逻辑/编辑器调试;见头文件语义注释)----
const PhysicsWorld::BodyRecord *PhysicsWorld::FindRecord(const u32 entityBits) const {
const auto found = m_Bodies.find(entityBits);
return found != m_Bodies.end() ? &found->second : nullptr;
}
// 力/扭矩/冲量:仅动态体(Jolt 对静态/运动学体施加力无意义)
void PhysicsWorld::AddForce(const u32 entityBits, const glm::vec3 &force) {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type != static_cast<u8>(ECS::RigidBodyComponent::BodyType::Dynamic))
return;
m_System->GetBodyInterface().AddForce(
rec->id, JPH::Vec3(force.x, force.y, force.z));
}
void PhysicsWorld::AddImpulse(const u32 entityBits, const glm::vec3 &impulse) {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type != static_cast<u8>(ECS::RigidBodyComponent::BodyType::Dynamic))
return;
m_System->GetBodyInterface().AddImpulse(
rec->id, JPH::Vec3(impulse.x, impulse.y, impulse.z));
}
void PhysicsWorld::AddTorque(const u32 entityBits, const glm::vec3 &torque) {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type != static_cast<u8>(ECS::RigidBodyComponent::BodyType::Dynamic))
return;
m_System->GetBodyInterface().AddTorque(
rec->id, JPH::Vec3(torque.x, torque.y, torque.z));
}
// 速度直写:动态+运动学体都有效(运动学体速度即其运动方式)
void PhysicsWorld::SetLinearVelocity(const u32 entityBits, const glm::vec3 &velocity) {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type == static_cast<u8>(ECS::RigidBodyComponent::BodyType::Static))
return;
m_System->GetBodyInterface().SetLinearVelocity(
rec->id, JPH::Vec3(velocity.x, velocity.y, velocity.z));
}
void PhysicsWorld::SetAngularVelocity(const u32 entityBits, const glm::vec3 &angularVelocity) {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type == static_cast<u8>(ECS::RigidBodyComponent::BodyType::Static))
return;
m_System->GetBodyInterface().SetAngularVelocity(
rec->id, JPH::Vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z));
}
glm::vec3 PhysicsWorld::GetLinearVelocity(const u32 entityBits) const {
const auto *rec = FindRecord(entityBits);
if (!rec || rec->type == static_cast<u8>(ECS::RigidBodyComponent::BodyType::Static))
return {0.0f, 0.0f, 0.0f};
const JPH::Vec3 v = m_System->GetBodyInterface().GetLinearVelocity(rec->id);
return {v.GetX(), v.GetY(), v.GetZ()};
}
// ---- 写回:动态体姿态 → Transform(标脏,帧循环统一 Compose)----
void PhysicsWorld::Writeback() const {