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.1
f);
// 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.