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.

Image non disponible

Nous pourrons définir la structure suivante :

 
Sélectionnez
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 :

Image non disponible

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.

 
Sélectionnez
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 :

 
Sélectionnez
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.

Image non disponible

En C, on peut définir cette structure :

 
Sélectionnez
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).

Image non disponible

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 :

Image non disponible

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 :

 
Sélectionnez
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.

 
Sélectionnez
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