Navigation▲
| Tutoriel précédent : les collisions dans les jeux | Sommaire | Tutoriel suivant : gestion des collisions dans un monde 3D |
II. Introduction▲
Passons maintenant à la 3D !
Vous allez voir dans ce chapitre que la collision des formes 3D simples ressemble étrangement à leur équivalent en 2D.
III. Axis Aligned Bounding Box 3D▲
Voici maintenant quelques algorithmes de collision en 3D.
Pour commencer, voyons les collisions AABB mais en 3D.
III-A. Définition▲
Une boite englobante 3D, alignée sur les axes, est comme une boite englobante 2D vue au-dessus, mais avec une dimension supplémentaire.

Nous pourrons définir la structure suivante :
struct AABB3D
{
float x,y,z;
float w,h,d;
};Nous avons les coordonnées x,y,z du point le plus proche de l'origine du monde, et la largeur w (width), la hauteur h (height) et la profondeur d (depth).
En 3D, il est d'usage de travailler avec des coordonnées réelles, donc des nombres flottants. Nous travaillons donc dans l'espace réel R³.
III-B. Applications▲
Ce type de collision est très utilisé dans les jeux 3D. Ici dans Descent FreeSpace pour détecter les collisions entre vos tirs et les vaisseaux ennemis :
III-C. Calcul de collision▲
III-C-1. Point dans AABB3D▲
Le calcul est très similaire à celui du premier chapitre. Il suffit de vérifier si le point (de coordonnées x,y,z est entre six parois de la AABB 3D.
bool Collision(float x,float y,float z,AABB3D box)
{
if (x >= box.x
&& x < box.x + box.w
&& y >= box.y
&& y < box.y + box.h
&& z >= box.z
&& z < box.z + box.d)
return true;
else
return false;
}III-C-2. Collision de deux AABB3D▲
De même, le concept ici est vraiment très proche de celui de collision de deux AABB (2D). Il faudra vérifier, pour une box1, si la box2 n'est pas « trop à gauche », « trop à droite », « trop en haut » ou « trop en bas », comme pour les box 2D, mais également qu'elle ne soit pas non plus « trop devant » et « trop derrière ».
Il suffit d'enrichir le if de la fonction, et nous obtenons alors la fonction suivante :
bool Collision(AABB3D box1,AABB3D box2)
{
if((box2.x >= box1.x + box1.w) // trop à droite
|| (box2.x + box2.w <= box1.x) // trop à gauche
|| (box2.y >= box1.y + box1.h) // trop en bas
|| (box2.y + box2.h <= box1.y) // trop en haut
|| (box2.z >= box1.z + box1.d) // trop derrière
|| (box2.z + box2.d <= box1.z)) // trop devant
return false;
else
return true;
}IV. Sphères▲
Les sphères englobantes sont une application en 3D des algorithmes sur les cercles que nous avons vus plus haut.
IV-A. Définition▲
Une sphère est définie par son centre (x,y,z) et son rayon.

En C, on peut définir cette structure :
struct Sphere
{
float x,y,z;
float rayon;
};IV-B. Applications▲
Un jeu de billard en 3D peut utiliser ce type de collision. Également d'autres shoot'em up 3D (tel Descent FreeSpace vu ci-dessus) si on considère les vaisseaux inscrits dans des sphères au lieu de AABB3D, les 2 formes peuvent donner de bons résultats).

IV-C. Calcul de collision▲
Les calculs sont très similaires à ceux vus dans le chapitre sur les cercles en 2D.
Ils se basent sur le calcul de distance 3D. Ce calcul est une généralisation de Pythagore dans l'espace :
Avec la même astuce, considérant la distance au carré, nous arrivons aux deux fonctions suivantes :
IV-C-1. Point dans une sphère▲
Soit le point (x,y,z), nous souhaitons savoir s'il est dans la sphère :
bool Collision(float x,float y,float z,Sphere S)
{
int d2 = (x-S.x)*(x-S.x) + (y-S.y)*(y-S.y) + (z-S.z)*(z-S.z);
if (d2>S.rayon*S.rayon)
return false;
else
return true;
}IV-C-2. Collision de deux sphères▲
Voyons si la distance entre les deux centres est supérieure ou inférieure à la somme des rayons.
bool Collision(Sphere S1,Sphere S2)
{
int d2 = (S1.x-S2.x)*(S1.x-S2.x) + (S1.y-S2.y)*(S1.y-S2.y) + (S1.z-S2.z)*(S1.z-S2.z);
if (d2 > (S1.rayon + S2.rayon)*(S1.rayon + S2.rayon);
return false;
else
return true;
}De même qu'en 2D, ces collisions sont rapides et efficaces.
Navigation▲
| Tutoriel précédent : les collisions dans les jeux | Sommaire | Tutoriel suivant : gestion des collisions dans un monde 3D |




