Fiouf, j'ai enfin finis en ce qui concerne les volumes englobants, j'ai terminé par le plus simple : la sphère!
Franchement le code n'est pas compliqué, il faut utiliser le théorème de Pythagore. ^^
Code :
package wotck.editeur.gui;
import wotck.editeur.Vec3t;
import wotck.editeur.items.Item;
import wotck.editeur.selection.Ray;
public class BoundingSphere {
private float radius;
private Vec3t center;
private Vec3t intersection1, intersection2;
public BoundingSphere (Vec3t center, float radius) {
this.radius = radius;
this.center = center;
intersection1 = new Vec3t(0, 0, 0);
intersection2 = new Vec3t (0, 0, 0);
}
public BoundingSphere (Item item) {
if (item.getLargeur() > item.getHauteur() && item.getLargeur() > item.getLongueur())
radius = item.getLargeur() / 2;
else if (item.getHauteur() > item.getLargeur() && item.getHauteur() > item.getLongueur())
radius = item.getHauteur() / 2;
else
radius = item.getLongueur() / 2;
center = item.getCentre();
intersection1 = new Vec3t(0, 0, 0);
intersection2 = new Vec3t (0, 0, 0);
}
public boolean intersect (Ray rayon) {
//Direction du centre de la Sphere par rapport à l'origine du rayon.
Vec3t l = center.soustraire(rayon.getOrig());
//Direction du rayon.
Vec3t v = rayon.getDest().soustraire(rayon.getOrig());
//On fait une projection orhtogonale du centre de la Sphere sur v.
float d = v.normalize().produitScalaire(l.normalize()) * l.longueur();
//Longueur de l au carré.
float l2 = l.longueur() * l.longueur();
float tNear, tFar;
//Si la longueur de l au carré est supérieur au rayon au carré
//Et que la projection est négative, la sphere est derrière le rayon!
if (l2 > radius * radius && d < 0)
return false;
//Distance entre le rayon et le centre de la Sphere. (Théorême de Pythagore : a = sqrt(c² - b²)!)
float h2 = l2 - d * d;
//Si la distance entre le rayon et le centre de la sphere au carré est supérieur au rayon au carré.
//Alors le rayon ne coupe pas la Sphere!
if (h2 > radius * radius)
return false;
//On recherche ou à lieu l'intersection.
//Distance entre le rayon et le bord de la sphere.(Théorême de Pythagore : a = sqrt(c² - b²)!)
float dPrim = (float) Math.sqrt(radius * radius - h2);
//Intersections par rapport à la direction du rayon.
float t1 = d - dPrim;
float t2 = d + dPrim;
float tmp;
//On permutte si nécessaire.
if (t1 > t2) {
tmp = t1;
t1 = t2;
t2 = tmp;
} else
tmp = t1;
//Pour avoir l'intersecion par rapport au rayon, on divise par la lonueur du rayon.
tNear = t1 / v.longueur();
tFar = t2 / v.longueur();
//Ensuite on peut récupérer l'intersection réelle.
intersection1 = rayon.getOrig().additionner(v.scale(tNear, true, true, true));
intersection2 = rayon.getOrig().additionner(v.scale(tFar, true, true, true));
return true;
}
public boolean intersect (BoundingSphere bs) {
float d = center.calculerDistance(bs.center);
float rSum = radius + bs.radius;
if (d > rSum)
return false;
return true;
}
public static void main (String[] args) {
Ray rayon = new Ray (new Vec3t(0, 19, -10), new Vec3t (0, 19, 100));
BoundingSphere bs = new BoundingSphere (new Vec3t (0, 0, 50), 20);
if (bs.intersect(rayon))
System.out.println("Intersections : "+bs.intersection1 + " "+bs.intersection2);
}
}
Voilà niveau sélection et utilisation de volumes englobant je touche enfin le fond! Mais pour le moment je ne travaille que avec des plans pour tester, ça va ça avance, si je continue comme ça, dans quelques mois je pourrai déjà créer des environnement sympa pour mon futur jeux. x)
________ "Il n'y a qu'avec ce que je crée que je représente quelque chose dans la vie des autres.
Mes créations sont ma seule fierté."
|