修复physics物理数据计算不正确的问题,同时为物理添加map索引
This commit is contained in:
@@ -352,6 +352,7 @@ namespace Engine {
|
||||
!reg.all_of<ECS::RigidBodyComponent, ECS::TransformComponent>(e)) {
|
||||
bi.RemoveBody(it->second.id);
|
||||
bi.DestroyBody(it->second.id);
|
||||
m_BodyToEntity.erase(it->second.id.GetIndexAndSequenceNumber());
|
||||
invalidated.push_back(it->first);
|
||||
it = m_Bodies.erase(it);
|
||||
} else {
|
||||
@@ -370,6 +371,7 @@ namespace Engine {
|
||||
if (found != m_Bodies.end()) {
|
||||
bi.RemoveBody(found->second.id);
|
||||
bi.DestroyBody(found->second.id);
|
||||
m_BodyToEntity.erase(found->second.id.GetIndexAndSequenceNumber());
|
||||
m_Bodies.erase(found);
|
||||
invalidated.push_back(bits);
|
||||
}
|
||||
@@ -381,6 +383,7 @@ namespace Engine {
|
||||
if (found != m_Bodies.end()) {
|
||||
bi.RemoveBody(found->second.id);
|
||||
bi.DestroyBody(found->second.id);
|
||||
m_BodyToEntity.erase(found->second.id.GetIndexAndSequenceNumber());
|
||||
m_Bodies.erase(found);
|
||||
invalidated.push_back(bits);
|
||||
}
|
||||
@@ -402,6 +405,7 @@ namespace Engine {
|
||||
// 类型/碰撞体/质量变更 → 重建(简单正确,重置速度可接受)
|
||||
bi.RemoveBody(rec.id);
|
||||
bi.DestroyBody(rec.id);
|
||||
m_BodyToEntity.erase(found->second.id.GetIndexAndSequenceNumber());
|
||||
m_Bodies.erase(found);
|
||||
invalidated.push_back(bits);
|
||||
rb.bodyValid = false;
|
||||
@@ -891,6 +895,7 @@ namespace Engine {
|
||||
rec.lastPos = tr.GetWorldPosition();
|
||||
rec.lastRot = tr.GetWorldRotationQuat();
|
||||
m_Bodies[entityBits] = rec;
|
||||
m_BodyToEntity[id.GetIndexAndSequenceNumber()] = entityBits;
|
||||
|
||||
rb.bodyId = id.GetIndexAndSequenceNumber();
|
||||
rb.bodyValid = true;
|
||||
@@ -902,6 +907,7 @@ namespace Engine {
|
||||
auto &bi = m_System->GetBodyInterface();
|
||||
bi.RemoveBody(found->second.id);
|
||||
bi.DestroyBody(found->second.id);
|
||||
m_BodyToEntity.erase(found->second.id.GetIndexAndSequenceNumber());
|
||||
m_Bodies.erase(found);
|
||||
}
|
||||
|
||||
@@ -913,12 +919,9 @@ namespace Engine {
|
||||
}
|
||||
|
||||
bool PhysicsWorld::TryBitsByBodyId(const JPH::BodyID &id, u32 &outBits) const {
|
||||
for (const auto &[bits, rec]: m_Bodies) {
|
||||
if (rec.id == id) {
|
||||
outBits = bits;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const auto& found = m_BodyToEntity.find(id.GetIndexAndSequenceNumber());
|
||||
if (found == m_BodyToEntity.end()) return false;
|
||||
outBits = found->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1059,23 +1062,28 @@ namespace Engine {
|
||||
const JPH::BodyID id(rb.bodyId);
|
||||
const JPH::RVec3 pos = bi.GetPosition(id);
|
||||
const JPH::Quat rot = bi.GetRotation(id);
|
||||
const glm::vec3 worldPos(pos.GetX(), pos.GetY(), pos.GetZ());
|
||||
const glm::quat worldRot = ToGlm(rot);
|
||||
// body 姿态是世界系:写回经 world→local 换算(挂父层级实体
|
||||
// 不破坏相对位姿;根实体 = 直写)。标脏 → UpdateTransforms 重算
|
||||
m_Scene.SetWorldPose(
|
||||
e,
|
||||
glm::vec3(pos.GetX(), pos.GetY(), pos.GetZ()),
|
||||
ToGlm(rot),
|
||||
worldPos,
|
||||
worldRot,
|
||||
tr.GetWorldScale());
|
||||
|
||||
const JPH::Vec3 vel = bi.GetLinearVelocity(id);
|
||||
rb.velocity = glm::vec3(vel.GetX(), vel.GetY(), vel.GetZ());
|
||||
|
||||
// lastPos/lastRot 同步到 body 姿态:否则下帧 SyncScene 把物理
|
||||
// 位移误判为编辑器拖动 → teleport 回旧位置死循环
|
||||
// lastPos/lastRot 同步到 body 当前姿态:否则下帧 SyncScene 会把物理
|
||||
// 位移误判为编辑器拖动 → teleport + 清零速度死循环。
|
||||
// 注意:必须用 bi.GetPosition/GetRotation 的 fresh 值,不能读
|
||||
// tr.GetWorldPosition()——SetWorldPose 只改 local+标脏,world cache
|
||||
// 要等本帧末尾 Scene::UpdateTransforms 才重算,此刻仍是旧值。
|
||||
const u32 bits = static_cast<u32>(entt::to_integral(e));
|
||||
if (auto it = m_Bodies.find(bits); it != m_Bodies.end()) {
|
||||
it->second.lastPos = tr.GetWorldPosition();
|
||||
it->second.lastRot = tr.GetWorldRotationQuat();
|
||||
it->second.lastPos = worldPos;
|
||||
it->second.lastRot = worldRot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user