IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Théorie des collisions : Formes 3D simples

Passons maintenant à la 3D !
Vous allez voir dans ce chapitre que la collision des formes 3D simples ressemble étrangement à leur équivalent en 2D.

Commentez Donner une note à l´article (5)

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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 :

kitxmlcodelatexdvpd = sqrt((x-C.x)^2 + (y-C.y)^2 + (z-C.z)^2)finkitxmlcodelatexdvp

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

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Licence Creative Commons
Le contenu de cet article est rédigé par Fvirtman et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.