2009-06-12 7 views
1

Pour un moteur de physique que je construis, j'ai besoin de déterminer rapidement si deux corps rigides étaient en contact, au cadre précédent. Je veux que ce soit aussi rapide que possible, alors peut-être que vous pourriez nous donner quelques idées?Graphique de contact

C'est ce que j'ai jusqu'ici. (Et cela fonctionne bien, mais toute chose m'a demander comment je pourrais l'améliorer.)

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

Répondre

1

Vous pouvez utiliser à la place une Dictionary<PhyRigidBody, HashSet<PhyRigidBody>> qui associe un corps donné à un ensemble d'autres corps, il était en contact avec (Cela signifie que vous gardez chaque "contact" deux fois, car chaque corps est inclus dans l'ensemble de contact de l'autre). Cela éviterait complètement la structure Contact, ainsi que la méthode quelque peu louche Equals. Je ne suis pas sûr que ce soit une amélioration, mais cela vaut la peine d'être considéré.

+0

qu'en est-il de l'extraction d'une extension ou d'une méthode au niveau de la classe, "Contact" pour PhyRigidBody - c'est-à-dire bool contact = somePhyRigidBody.Contact (anotherObject). Mieux encore, si vous vouliez plus tard implémenter une physique non-rigide, vous devriez penser à faire partie de la méthode Contact() d'une interface, vous permettant d'étendre facilement votre bibliothèque. –

+0

Je pense que vous mélangez deux préoccupations différentes ici: comment déterminer le contact devrait en effet aller quelque part où il peut être remplacé (comme une interface, etc.). Mais le gars demande comment * stocker * les données de contact pour la trame précédente, soi-disant * après * le calcul. – Avish

+0

Merci pour les idées. Pensez que je vais ajouter un "HashSet contacts" à chaque PhyRigidBody. Encore besoin de garder les contacts deux fois, à moins que je vérifie simplement les deux corps lors de l'interrogation des contacts. – LaZe

0

Je suis confus par ceci:

// 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); 

mais obtenir dans l'ensemble je ne pas le point. Combien y a-t-il de corps? Est-ce que les corps bougent donc leur contact-ness change souvent? Pourriez-vous les déposer dans une grille spatiale? À quelle fréquence avez-vous besoin de savoir ce que sont les contac-tions? Sans trop en savoir plus sur le problème, il est difficile d'en dire beaucoup, même si mon intuition est que tout emballer dans les codes de hachage et la structure de données va vous coûter cher.

+0

À chaque image, je dois être en mesure de déterminer si deux corps se touchaient à l'image précédente. J'ai besoin de cette information pour de nombreuses paires de corps, à chaque image. Il y a peut-être beaucoup de corps dans la scène (des milliers), mais une grande partie d'entre eux est probablement statique ou en train de dormir. Je dois être en mesure de demander des contacts de pré-trame sur deux corps. – LaZe

+0

Fondamentalement, c'est une matrice booléenne clairsemée. Vous pourriez avoir un tableau 1-d indexé par body1, chaque élément contenant une liste de nombres body2. C'est essentiellement une configuration de hachage. D'un autre côté, si votre séquence de requêtes est hautement prévisible ou séquentielle, vous pourriez en profiter. –