Voila je vous présente un code d'essai des collisions.
fichier main.cpp
#include <irrlicht.h> #include "MyEventReceiver.h" using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; int main(int argc, char** argv) { IrrlichtDevice* device = createDevice( video::EDT_OPENGL, core::dimension2d<s32>(1000, 800),32, false, false, false); device->setWindowCaption(L"Collisions"); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); IGUIEnvironment* guienv = device->getGUIEnvironment(); IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2"); IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); if (node) { node->setMaterialFlag(EMF_LIGHTING, false); node->setFrameLoop(0, 0); node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") ); } scene::ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0); camera->setPosition(core::vector3df(0, 55, -30)); // ajout du terrain scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( "../../media/terrain-heightmap.bmp", 0, // parent node -1, // node id core::vector3df(-1000.f, -500.f, -1000.f), // position core::vector3df(0.f, 0.f, 0.f), // rotation core::vector3df(40.f, 4.4f, 40.f), // scale video::SColor ( 255, 255, 255, 255 ), // vertexColor, 5, // maxLOD scene::ETPS_17, // patchSize 4 // smoothFactor ); terrain->setMaterialFlag(video::EMF_LIGHTING, false); terrain->setMaterialTexture(0, driver->getTexture("../../media/terrain-texture.jpg")); terrain->setMaterialTexture(1, driver->getTexture("../../media/detailmap3.jpg")); terrain->setMaterialType(video::EMT_DETAIL_MAP); terrain->scaleTexture(1.0f, 20.0f); // création du selector du terrain scene::ITriangleSelector* selector = smgr->createTerrainTriangleSelector(terrain, 0); terrain->setTriangleSelector(selector); // create collision response animator and attach it to the camera scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( selector, camera, core::vector3df(60,50,60), core::vector3df(0,0,0), core::vector3df(0,50,0)); //création de l'animator et l'attache au mesh de sydney scene::ISceneNodeAnimator* anim2 = smgr->createCollisionResponseAnimator( selector, node, core::vector3df(30,50,30), core::vector3df(0,-100,0)); selector->drop(); camera->addAnimator(anim); node->addAnimator(anim2); anim->drop(); anim2->drop(); MyEventReceiver receiver(node); device->setEventReceiver(&receiver); bool bouje; bool boujeActif; while (device->run()) { driver->beginScene(true, true, SColor(0,200,200,200)); smgr->drawAll(); guienv->drawAll(); driver->endScene(); receiver.majPosMesh(); } device->drop(); return 0; }
fichier MyEventReceiver.h
#ifndef DEF_MYEVENTRECEIVER #define DEF_MYEVENTRECEIVER #include <irrlicht.h> class MyEventReceiver : public irr::IEventReceiver { public: MyEventReceiver(irr::scene::IAnimatedMeshSceneNode* ); virtual bool OnEvent(const irr::SEvent& ); //met à jour la position de l'objet void majPosMesh(); private : //Le modele qu'on va controler. irr::scene::IAnimatedMeshSceneNode* m_Nmodele; //va permettre de changer la position de l'objet par rapport à son axe irr::core::matrix4 Mat; //Indique si l'objet est en mouvement bool m_isMoving; //reçoit la valeur de la touche enfoncée char *myKeyPressed; }; #endif
fichier MyEventReceiver.cpp
#include <irrlicht.h> #include "MyEventReceiver.h" using namespace irr; MyEventReceiver::MyEventReceiver(scene::IAnimatedMeshSceneNode* Nmodele ) { //On pointe le mesh passe en parametre. m_Nmodele = Nmodele; //Par defaut on ne bouge pas m_isMoving = false; myKeyPressed = NULL; } bool MyEventReceiver::OnEvent(const SEvent& event) { //Si l'objet existe et qu'une touche est préssé if (m_Nmodele != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT && (event.KeyInput.Key == irr::KEY_KEY_Z ||event.KeyInput.Key == irr::KEY_KEY_S ||event.KeyInput.Key == irr::KEY_KEY_Q ||event.KeyInput.Key == irr::KEY_KEY_D)) { //gère les différent cas suivant la touche switch (event.KeyInput.Key) { case irr::KEY_KEY_Z: //On y ajoute la valeur de déplacement myKeyPressed="Z"; //On renvoie la nouvelle position break; case irr::KEY_KEY_S: myKeyPressed="S"; break; case irr::KEY_KEY_Q: myKeyPressed="Q"; break; case irr::KEY_KEY_D: myKeyPressed="D"; break; default : break; } m_isMoving = event.KeyInput.PressedDown; return true; } return false; } void MyEventReceiver::majPosMesh() { //faire tomber un mesh //sans cette ligne, le mesh ne tombe pas et donc ne suivra plus le terrain en descente //faite un test sans cette ligne vous comprendrez m_Nmodele->setPosition(m_Nmodele->getPosition() - core::vector3df(0.0, 0.05, 0.0)); //On vérifie que le pointeur vers le mesh est //ok et que la touche est enfoncée if (m_Nmodele != 0 && m_isMoving == true) { //On commence par récupérer la position actuelle core::vector3df v = m_Nmodele->getPosition(); //et sa rotation pour que l'objet bouge en se basant sur son axe core::vector3df r = m_Nmodele->getRotation(); if (myKeyPressed=="Z") { //On y ajoute la valeur de deplacement Mat.setRotationDegrees(m_Nmodele->getRotation()); core::vector3df Target(0.2,0,0); Mat.transformVect(Target); core::vector3df NewPos=m_Nmodele->getPosition(); NewPos += Target; m_Nmodele->setPosition(NewPos); } else if (myKeyPressed=="S") { Mat.setRotationDegrees(m_Nmodele->getRotation()); core::vector3df Target(-0.2,0,0); Mat.transformVect(Target); core::vector3df NewPos=m_Nmodele->getPosition(); NewPos += Target; m_Nmodele->setPosition(NewPos); } if (myKeyPressed=="Q") { r.Y-= 0.1; m_Nmodele->setRotation(r); } else if (myKeyPressed=="D") { r.Y+= 0.1; m_Nmodele->setRotation(r); } } }
C'est un code à améliorer mais au moins ca donne une base.
Je suis persuadé de la fonction smgr->createCollisionResponseAnimator(); n'est pas adapté à une sceneNode mais bon... j'ai pas trouvé mieux pour l'instant !
Si quelqu'un avait une idée...
Merci pour se petit tuto, tu ma bien aider...
Hors ligne
Pages: 1