ODFAEG et les collisions

ODFAEG possède deux méthodes pour gérer les collisions, une moins précise et une plus précise.
La moins précise consiste à faire en sorte qu'on ne puisse pas passer sur une case particulière.


  World::getGridCellAt(math::Vec3f (0, 0, 0)))->setPassable(false);
  

On ne pourra donc pas passer sur la case qui se trouve en (0, 0, 0).
La méthode plus précise consiste à associé à chaque entité, une hiérarchie de volume englobant.
ODFAEG gère 5 types de volumes englobant, tout ces types héritent de la classe odfaeg::physic::BoundingVolume!
Voici les différents types de volumes englobants :
odfaeg::physic::BoundingBox : une boîte alignée avec les axes, le constructeur prend en paramètre la position en x, en y et en
z de la boîte ainsi que la taille (largeur, hauteur et profondeur) de la boîte.
odfaeg::physic::BoundingSpehre : une sphère, le constructeur de cette classe prend en pramètre la position du centre de la sphère,
ainsi que son rayon.
odfaeg::physic::BoundingEllipsoid : une éllipsoïde, le constructeur prend en paramètre le centre et les 3 rayons de l'éllipsoïde.
odfaeg::physic::OrientedBoundingBox : une boîte orientée, le constructeur prend en paramètre les coins de la boîtes.
(4 coins pour la 2D, 8 pour la 3D)
odfaeg::physic::BoundingPolygon : un polygône quelconque, le constructeur de cette classe prend 3 points en paramètres,
ainsi que un bool qui doit valoir true si le polygône est en 2D.
Voici comment associer un volume englobant à une entité :


  odfaeg::physic::BoundingVolume* volume = new odfaeg::physic::BoundingBox (0, 0, 0, 100, 100, 100);
  entity->setCollisionVolume(volume);
  
Tout comme les entités, les volumes de collisions peuvent posséder des volumes de collisions enfants, afin de faire des tests plus précis.

ODFAEG et les particules.

Le système de particule de odfaeg est fort similaire à celui de la librairie thor, c'est à dire qu'il faut d'abord créer un émitter, qui va émettre un certains nombre de particules par seconde :

  emitter.setEmissionRate(30);
    emitter.setParticleLifetime(Distributions::uniform(sf::seconds(5), sf::seconds(7)));
    emitter.setParticlePosition(Distributions::rect(Vec3f(50, 90, 0), Vec3f(25, 5, 0)));   // Emit particles in given circle
    emitter.setParticleVelocity(Distributions::deflect(Vec3f(0, -10, 0),  0)); // Emit towards direction with deviation of 15°
    emitter.setParticleRotation(Distributions::uniform(0.f, 0.f));
    emitter.setParticleTextureIndex(Distributions::uniformui(0, 9));
    emitter.setParticleScale(Distributions::rect(Vec3f(2.1f, 2.1f, 1.f), Vec3f(2.f, 2.f, 1.f)));
  

setEmmissionRate est le nombre de particules émises par seconde, ici, on emet 30 particules par secondes.
setParticlePosition est le rectangle dans lequel vont apparaître les particules, ici se sera dans le rectangle
de centre 50, 90, 0 et de taille 25, 5, 0.
setParticleLifetime est la durée de vie des particules, ici elle varie entre 5 et 7 secondes.
setParticleVelocity est la force des particules, ici elle est de 0, -10, 0 ça veut dire que les particules vont
monter vers le haut!
setPatricleRotation est la rotation des particules, ici la rotation des particules est nulle, donc, elle ne varie pas.
setParticuleTextureIndex sont les index des différentes textures utilisée pour dessiner les particules, ici il y en a 9.
J'utilise ici donc 10 textures pour dessiner les particules, qui seront choisie aléatoirement.
setParticleScale : modifie l'échelle des particules, ici l'échelle varie entre 2.1, 2.1, 1 et 2, 2, 1.
Ensuite il faut ajouter l'émetteur à un objet de type particule système :


  ps.addEmitter(refEmitter(emitter));
  

Vous pouvez ensuite dessiner les particules, comme ceci :


  void MyAppli::onDisplay(RenderWindow* window) {
    window->draw(ps);
  }
  

Par défaut les particules se dessinnent sur le sol (sur le plan x, y), ça ne pose pas de problème en vue 2D mais cela
pose problème en vue 3D.
Heureusement, ODFAEG possède une classe pour orienter les particules face à la caméra, cette classe se nomme
odfaeg::physic::billboard.


  billboard = new BillBoard(view, ps);
  billboard->setView(view);
  billboard->setCenter(Vec3f(0, 0, z+20));
  

Comme pour la fenêtre de rendu et les composants de rendu, il faut mettre à jour la vue pour le billboardà chaque fois
qu'on la modifie, setCenter met à jour le centre du billboard.
Lors du rendu, il faut appeler la méthode draw sur le billboard et non sur le système de particule :


  void MyAppli::onDisplay(RenderWindow* window) {
    window->draw(*billboard);
  }
  

Tout comme le système de particule de thor, on peut également ajouter des affecteurs.