Tutoriel Irrlicht 15

Charger des scènes à partir de fichiers .irr

| Nikolaus Gebhart | Laurent Alexandre |

Traducteur

Neckara

Ce tutoriel est une traduction de l'anglais des tutoriels officiels d'Irrlicht.

Depuis la version 1.1, Irrlicht est capable de sauvegarder et de charger des scènes entières dans un fichier .irr, un format basé sur le XML. Il y a un éditeur disponible pour ces fichiers nommé irrEdit qui peut aussi être utilisé comme éditeur de monde et de particule. Ce tutoriel montre comment utiliser ces fichiers .irr.

Commentez

- Titre : Tutoriel Irrlicht 15

- Auteurs : Nikolaus Gebhart, Laurent Alexandre

- Traducteur : Neckara

- Parution : 4 juin 2013

- Mise à jour : 4 juin 2013

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Neckara. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Chargement du fichier

- II. Création du sélectionneur de triangles

- III. Animateur de réponses aux collisions

- IV. Conclusion

- V. Remerciements

I - Chargement du fichier

Commençons : créons le moteur Irrlicht et configurons la fenêtre.

#include <irrlicht.h>
#include "driverChoice.h"

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

int main(int argc, char** argv)
{
// Demande à l'utilisateur un pilote.
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;

// Crée le moteur et quitte si la création a échoué.

IrrlichtDevice* device =
createDevice(driverType, core::dimension2d<u32>(640, 480));

if (device == 0)
return 1; // Ne peut pas créer le pilote sélectionné.

device->setWindowCaption(L"Load .irr file example");

video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();

Maintenant, chargeons notre fichier .irr, les fichiers .irr peuvent stocker toute une scène en incluant les animateurs, les matériels et les systèmes de particules. Il est aussi possible de stocker arbitrairement des données utilisateur dans chaque nœud de scène dans ce fichier. Pour garder cet exemple simple, nous chargeons uniquement la scène. Regardez la documentation de ISceneManager::loadScene et de ISceneManager::saveScene pour plus d'informations. Pour charger et afficher une grande scène compliquée, nous avons juste besoin d'un seul appel à loadScene().

// Charge la scène.
if (argc>1)
smgr->loadScene(argv[1]);
else
smgr->loadScene("../../media/example.irr");

Maintenant, nous allons créer une caméra et lui donner un animateur pour détecter les collisions contre les nœuds des objets présents dans la scène que nous venons juste de charger.

scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0, 50.f, 0.1f);

// Crée le métasélectionneur de triangles pour contenir plusieurs sélectionneurs de triangles.
scene::IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector();

II - Création du sélectionneur de triangles

Ensuite nous allons trouver tous les nœuds dans la scène et créer un sélectionneur de triangles pour chaque nœud approprié. Typiquement, vous souhaitez prendre des décisions plus précises pour choisir les nœuds pour lesquels vérifier les collisions. Vous pouvez prendre cette information dans le nom du nœud ou son identifiant.

core::array<scene::ISceneNode *> nodes;
smgr->getSceneNodesFromType(scene::ESNT_ANY, nodes); // Trouver tous les nœuds.

for (u32 i=0; i < nodes.size(); ++i)
{
scene::ISceneNode * node = nodes[i];
scene::ITriangleSelector * selector = 0;

switch(node->getType())
{
case scene::ESNT_CUBE:
case scene::ESNT_ANIMATED_MESH:
// Parce que le sélectionneur ne s'anime pas avec l'objet
// et que c'est le seul utilisé pour la collision de caméra, nous n'utiliserons qu'une boîte englobante approximative à la place de
// ((scene::IAnimatedMeshSceneNode*)node)->getMesh(0).
selector = smgr->createTriangleSelectorFromBoundingBox(node);
break;

case scene::ESNT_MESH:
case scene::ESNT_SPHERE: // Hérite de IMeshSceneNode.
selector = smgr->createTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
break;

case scene::ESNT_TERRAIN:
selector = smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)node);
break;

case scene::ESNT_OCTREE:
selector = smgr->createOctreeTriangleSelector(((scene::IMeshSceneNode*)node)->getMesh(), node);
break;

default:
// Ne crée pas de sélectionneur pour ce type de nœud.
break;
}

if(selector)
{
// L'ajoute au métasélectionneur qui prendra sa référence.
meta->addTriangleSelector(selector);
// Et abandonne ma référence car le métasélectionneur en est propriétaire.
selector->drop();
}
}

III - Animateur de réponses aux collisions

Maintenant que les nœuds de scène de mesh ont un sélectionneur de triangles créé et ajouté au métasélectionneur, nous créons un animateur répondant aux collisions à partir de ce métasélectionneur.

scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator(
meta, camera, core::vector3df(5,5,5),
core::vector3df(0,0,0));
meta->drop(); // J'ai maintenant fini avec le métasélectionneur.

camera->addAnimator(anim);
anim->drop(); // J'ai maintenant fini avec l'animateur.

// Et défini la position de la caméra ainsi on ne commence pas collé à la géométrie.
camera->setPosition(core::vector3df(0.f, 20.f, 0.f));

// Dirige la caméra vers le nœud de cube en cherchant le premier nœud de type  ESNT_CUBE.
scene::ISceneNode * cube = smgr->getSceneNodeFromType(scene::ESNT_CUBE);
if(cube)
camera->setTarget(cube->getAbsolutePosition());

Voilà. Dessinons tout et finissons comme d'habitude.

int lastFPS = -1;

while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(0,200,200,200));
smgr->drawAll();
driver->endScene();

int fps = driver->getFPS();

if (lastFPS != fps)
{
core::stringw str = L"Load Irrlicht File example - Irrlicht Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;

device->setWindowCaption(str.c_str());
lastFPS = fps;
}

}

device->drop();

return 0;
}

IV - Conclusion

Désormais, vous pouvez charger une scène entière à partir d'un fichier .irr.

Dans le prochain tutoriel Support des cartes Quake 3 et de leurs effets, nous verrons comment charger une carte Quake 3 avec le moteur, créer un nœud de scène optimisé pour les rendus et créer une caméra contrôlée par l'utilisateur.

V - Remerciements

Merci à Nikolaus Gebhardt de nous permettre de traduire ce tutoriel.

Merci à LittleWhite pour sa relecture technique ainsi qu'à ClaudeLELOUP pour sa relecture orthographique.