我正在编写一个物理引擎,并且很难找到一种设计数据存储的好方法。
我想要的功能:
- 有一个代表 PhysicsBody 的类
- 有一个代表碰撞体积的类(比如说一个盒子)
- 每个物理体可以附加一个以上的碰撞体积
- 可能有没有碰撞体积的物理体
- 可选:没有物理实体的 CollisionVolume。(想想触发量)
现在我基本上有两个循环。一种更新模拟中的物理体。它更新它们的位置/速度/旋转。第二个循环对所有碰撞体积执行碰撞检测。它只是一个嵌套的 for 循环,用于检查每对碰撞体积之间的碰撞。(我知道它可以做得更好,但这是一个单独的话题)
我知道理想的方法是将对象存储在连续的数组中。
std::vector<PhysicsBody> m_bodies;
std::vector<CollisionVolume> m_colliders;
我发现这种方法的问题:
- 很难维护 PhysicsBody -> CollisionVolume 关系。例如,如果我想从我的向量中删除一个 CollisionVolume,我会将它与最后一个交换并弹回。数据被移动,如果我在 PhysicsBody 中存储了 CollisionVolume 的索引,它就不再有效。
- 每当我销毁一个 PhysicsBody 时,析构函数都会检查是否有任何碰撞体积附在它上面,并适当地将其从物理系统中删除。问题是向量会制作内部副本并销毁它们,当这种情况发生时,它会通过删除不应该删除的碰撞体积来造成严重破坏。
- CollisionVolume 实际上是一个基类(不一定是),其他类从它派生出来,比如盒子/球体等等。我可能不使用继承并提出其他一些复杂的设计,但这是需要牢记的。
我努力寻找解决方法,但最终改为存储指针:
std::vector<PhysicsBody*> m_bodies;
std::vector<CollisionVolume*> m_colliders;
我想出的最小化缓存未命中的最佳解决方案是重载 new/delete 并将这些对象存储在内存池中,仅用于物理系统。
还有其他更好的解决方案吗?显然,性能是关键。