联系图

时间:2009-06-12 18:27:10

标签: c# optimization

对于我正在建造的物理引擎,我需要在前一帧快速确定两个刚体是否接触。我希望它尽可能快,所以也许你们可以提供一些想法?

这是我到目前为止所得到的。 (而且它工作正常,但整件事让我想知道如何改进它。)

    // 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.

2 个答案:

答案 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);

但总的来说,我不明白这一点。有多少尸体?身体是否移动,以便他们的接触经常变化?你能把它们放到空间网格中吗?您多久需要知道一下接触是什么?

如果不了解更多关于这个问题的话,很难说很多,虽然我的直觉是让所有的哈希码和数据结构都花​​费你很多时间。