Pages: 1
Bonjour à tous !
Je suis confronté à un problème que je pense assez basique mais boàn voilà, je comprends pas donc je m'en remet à vos petits (ou grands) cerveaux !
Voici un bout du code malicieux :
clicAnim = smgr->addAnimatedMeshSceneNode (smgr->getMesh("./media/ninja.b3d"),0 ,-1 , intersection, irr::core::vector3df(0, 0, 0), irr::core::vector3df(0.1f, 0.1f, 0.1f)); clicAnim->setMaterialFlag(irr::video::EMF_LIGHTING, false); clicAnim->setMaterialFlag(irr::video::EMF_NORMALIZE_NORMALS, false); //clicAnim->setAnimationSpeed(10); //clicAnim->setFrameLoop(0, 200); clicAnim->setLoopMode(false); //clicAnim->setFrameLoop(0, 200); //clicAnim->setCurrentFrame(1); //clicAnim->setAnimationEndCallback(anim_cb);
voilà, donc si je fais setLoopMode(false) l'animation ne démarre pas du tout, si je le passe à true elle se fait correctement.
Comme vous le voyez j'ai essayé pas de mal de bazard (en commentaire) mais rien n'y fait.
j'ai également essayé avec d'autres models et d'autres formats. RIEN
Ca doit être tout facile pour vous, j'en suis désolé mais si vous pouviez m'expliquer un peu ca serait super généreux de votre part.
P.S. : Le but final étant de gérer un évènement (la suppression du mesh) à la fin de l'aniomation avec le endcallback. donc si vous avez une meilleure façon de faire ça, je suis aussi preneur
Merci, ++
Hors ligne
Tiens voici un code qui marche (je l'ai testé), j'y ai mis quelques explications :
#include <irrlicht.h> //#include "pthread.h" using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; IAnimatedMeshSceneNode* ANode; class MyEventReceiver : public IEventReceiver { public : MyEventReceiver(IrrlichtDevice *device) : Device(device) {} IrrlichtDevice *Device; virtual bool OnEvent(const SEvent& event) { if (event.EventType == EET_MOUSE_INPUT_EVENT) { switch(event.MouseInput.Event) { case EMIE_LMOUSE_PRESSED_DOWN: { /// } break; case EMIE_RMOUSE_PRESSED_DOWN: { /// } break; default: break; } } if (event.EventType == EET_KEY_INPUT_EVENT) { if(event.KeyInput.PressedDown) { switch(event.KeyInput.Key) { case KEY_ESCAPE: Device->closeDevice(); // QUITTE L'APPLICATION break; case KEY_KEY_A: { ANode->setFrameLoop(0,13); // walk } break; case KEY_KEY_Z: { ANode->setFrameLoop(146,148); // backflip } break; case KEY_SPACE: { ANode->setFrameLoop(94,102); // jump } break; default: break; } } } return false; } }; int main(int argc, char** argv) { // fenetre IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2du(1280, 720), 32, false, false, false, 0); MyEventReceiver* receiver = new MyEventReceiver(device); device->setEventReceiver(receiver); device->setWindowCaption(L"Fenetre principale"); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); IGUIEnvironment* guienv = device->getGUIEnvironment(); // dessin à réalisé dans la fenetre ANode = smgr->addAnimatedMeshSceneNode(smgr->getMesh("./media/ninja.b3d")); ANode->setMaterialTexture(0, driver->getTexture("./media/nskinbl.jpg")); ANode->setMaterialFlag(EMF_LIGHTING, false); ANode->setMaterialFlag(EMF_NORMALIZE_NORMALS, false); ANode->setAnimationSpeed(10); ANode->setLoopMode(false); // il ne joue l'animation qu'une fois par appel ANode->setFrameLoop(0,0); // position de départ // caméras smgr->addCameraSceneNodeFPS(); // dessin fenetre while(device->run()) { // teste si l'animation est arrivée à sa fin if( ANode->getFrameNr() == ANode->getEndFrame() ) { // alors on remet le personnage à la frame 0 ANode->setFrameLoop(0,0); /** ATTENTION ANode->setCurrentFrame(0); remmetterait l'animation en route car irrlicht voit que la frame courante et différent de celle de fin **/ } // fenetre driver->beginScene(true, true, SColor(0,200,200,200)); smgr->drawAll(); guienv->drawAll(); driver->endScene(); } device->drop(); return 0; }
Il suffit de reculer un peu pour voir le personnage et appuies sur les A, Z ou ESPACE pour déclencher une animation.
S'il y a quelque chose que tu comprends pas, il n'y a qu'à demander.
Hors ligne
Merci pour ta réponse rapide,
Ton code m'a permis de comprendre une chose : avec un setLoopMode(false); l'animation ne se déclenche qu'après un smgr->drawAll(); ET un setFrameLoop() après le drawAll.
Bizarre comme comportement. Mais bon, ce côté là est réglé. Par contre, quelqu'un a-t-il un exemple de code qui supprime un node ? quand je veux le supprimer avec remove(); le prochain appel de smgr->drawAll() plante. Idem avec drop().
Merci de votre aide.
Hors ligne
Salut,
Si tu as un crash après suppression d'un node suite à un remove, c'est que tu dois avoir un pointer à se même node qui est appelé ailleurs dans ton code....
Post ton code ça nous aidera à y voir plus clair .
Hors ligne
Bonjour, j'ai réglé mon soucis en utilisant addToDeletionQueue à la place du remove, cela me parait plus logique en plus.
Désolé mais difficile de poster mon code, il est réparti sur plusieurs classes.
Donc pour ceux qui cherchent à faire comme moi :
class Anim_CB : public irr::scene::IAnimationEndCallBack { public: void OnAnimationEnd( irr::scene::IAnimatedMeshSceneNode *node); }; void Anim_CB:: OnAnimationEnd(irr::scene::IAnimatedMeshSceneNode *node){ std::cout << "Animation finie" << std::endl; IrrDriver::getInstance()->getSceneManager()->addToDeletionQueue(node); }
Cela fonctionne pour l'instant.
Merci pour votre aide.
P.S. : j'ouvre un autre sujet sur un autre soucis que j'ai
Hors ligne
Pages: 1