Il y a quelques mises en garde à ma réponse, que je vais aborder en premier: elle ne concerne que les boîtes englobantes non tournantes. Il suppose que vous essayez de traiter les problèmes de tunneling , c'est-à-dire les problèmes causés par des objets se déplaçant à grande vitesse.
Une fois que vous avez identifié le MTV, vous connaissez le bord / la surface normale que vous devez tester. Vous connaissez également le vecteur de vitesse linéaire de l'objet interpénétré.
Une fois que vous avez établi qu'à un moment donné de l'image, une intersection s'est produite, vous pouvez ensuite effectuer des opérations binaires en demi-pas, en fonction des points de départ suivants: Identifiez le sommet qui a pénétré en premier pendant l'image:
vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
if (dot(vert, MTV) < mindot)
{
mindot = dot(vert, MTV);
vertex = vert;
}
}
Une fois le sommet identifié, le demi-pas binaire devient beaucoup moins cher:
//mindistance is the where the reference edge/plane intersects it's own normal.
//The max dot product of all vertices in B along the MTV will get you this value.
halfstep = 1.0f;
vec3 cp = vertex;
vec3 v = A.velocity*framedurationSeconds;
float errorThreshold = 0.01f; //choose meaningful value here
//alternatively, set the while condition to be while halfstep > some minimum value
while (abs(dot(cp,normal)) > errorThreshold)
{
halfstep*=0.5f;
if (dot(cp,normal) < mindistance) //cp is inside the object, move backward
{
cp += v*(-1*halfstep);
}
else if ( dot(cp,normal) > mindistance) //cp is outside, move it forward
{
cp += v*(halfstep);
}
}
return cp;
Ceci est raisonnablement précis, mais ne fournira qu'un seul point de collision, dans un seul cas.
Le fait est qu'il est généralement possible de dire à l'avance si un objet se déplacera assez rapidement par image pour pouvoir tunneler comme ça, donc le meilleur conseil est d'identifier les sommets principaux le long de la vitesse et de faire un test de rayon le long du vecteur de vitesse. Dans le cas d'objets en rotation, vous devrez effectuer une sorte de slerp binaire à demi-pas afin de déterminer le bon point de contact.
Dans la plupart des cas, cependant, on peut supposer en toute sécurité que la plupart des objets de votre scène ne se déplaceront pas assez rapidement pour pénétrer aussi loin dans une seule image, donc aucun demi-pas n'est nécessaire, et une détection de collision discrète suffira. Les objets à grande vitesse comme les balles, qui se déplacent trop vite pour être vus, peuvent être tracés par rayons pour les points de contact.
Fait intéressant, cette méthode à mi-étape peut également vous donner l'heure (presque) exacte à laquelle l'objet s'est produit pendant la trame:
float collisionTime = frametimeSeconds * halfstep;
Si vous effectuez une sorte de résolution de collision physique, vous pouvez alors corriger la position de A en:
v - (v*halfstep)
alors vous pouvez faire votre physique normalement à partir de là. L'inconvénient est que si l'objet se déplace assez rapidement, vous le verrez se téléporter le long de son vecteur de vitesse.