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 |