对于我正在建造的物理引擎,我需要在前一帧快速确定两个刚体是否接触。我希望它尽可能快,所以也许你们可以提供一些想法?
这是我到目前为止所得到的。 (而且它工作正常,但整件事让我想知道如何改进它。)
// I thought using a struct would be a good idea with only two values?
struct Contact
{
public readonly PhyRigidBody Body1;
public readonly PhyRigidBody Body2;
public Contact(PhyRigidBody body1, PhyRigidBody body2)
{
Body1 = body1;
Body2 = body2;
}
}
class ContactComparer : IEqualityComparer<Contact>
{
public bool Equals(Contact x, Contact y)
{
// It just have to be the two same bodies, nevermind the order.
return (x.Body1 == y.Body1 && x.Body2 == y.Body2) || (x.Body1 == y.Body2 && x.Body2 == y.Body1);
}
public int GetHashCode(Contact obj)
{
// There has got to be a better way than this?
return RuntimeHelpers.GetHashCode(obj.Body1) + RuntimeHelpers.GetHashCode(obj.Body2);
}
}
// Hold all contacts in one big HashSet.
private HashSet<Contact> _contactGraph = new HashSet<Contact>(new ContactComparer());
// To query for contacts I do this
Contact contactKey = new Contact(body1, body2);
bool prevFrameContact = _contactGraph.Remove(contactKey);
// ... and then I re-insert it later, if there is still contact.
答案 0 :(得分:1)
您可以改为使用Dictionary<PhyRigidBody, HashSet<PhyRigidBody>>
将给定的身体映射到与其接触的一组其他身体(这意味着您将每个“联系人”保持两次,因为每个身体都包含在联系人中另一个)。这样就可以完全避免使用Contact
结构,以及有点可疑的Equals
方法。我不确定这是一个改进,但值得考虑。
答案 1 :(得分:0)
我对此感到困惑:
// It just have to be the two same bodies, nevermind the order.
return (x.Body1 == y.Body1 && x.Body2 == y.Body2) || (x.Body1 == y.Body2 && x.Body2 == y.Body1);
但总的来说,我不明白这一点。有多少尸体?身体是否移动,以便他们的接触经常变化?你能把它们放到空间网格中吗?您多久需要知道一下接触是什么?
如果不了解更多关于这个问题的话,很难说很多,虽然我的直觉是让所有的哈希码和数据结构都花费你很多时间。