#50 

19-06-2015 13:18:20

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

D'accord, merci pour les détails smile.  Donc si j'appui sur deux boutons simultanément, l'animation la plus forte prend le dessus, et si je relâche un seul bouton l'animation restante étant active mais précédemment pas en lecture va prendre le relais. OK , je n'ai pas ce résultat pour le moment, je vais essayer de regarder du côté de la priorité car elle a l'air sans effet, pour le moment, quand je fais le test, rien ne m’empêche de lancer une animation de priorité 2 quand je joue une animation de priorité 10 hmm .

Dernière modification par jonath313 (19-06-2015 13:30:53)

Hors ligne


#51 

19-06-2015 13:49:13

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

ah ... ben alors la je sais pas ^^
poste ton code, que je regarde de plus pret

fait des "printf" un peut partout pour savoir ce qu'il si passe si tu n'est pas à laise avec un debugeur
si ça viens des prioritées, affiches la valeurs de la prioriter de "current" dans "active" au debut et a la fin

Hors ligne


#52 

19-06-2015 21:39:57

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Bon je me suis arraché pas mal de cheveux pour trouver un cas que je ne traite pas pour le moment. Déjà il y a quelque chose de sûr, avant de dire que le priorité est inéfficace, il faudrait qu'elle soit rafraichie au bon moment... Pour une foi que je suis sûr de quelque chose smile

Je t'explique :
Pour le moment, quand j'appui sur un bouton de la manette je bind une animation, elle se joue, pas de soucis.
J'appui sur un autre bouton , une autre animation se joue, tout va bien, c'est ce qu'on veut.

J'ai visualisé la valeur de la priorité au moment du bind() et au moment du unbind() et voici ce qu'il se passe :
Quand j'appui sur le bouton("marcher" -> priorité = 10) au moment de l'appui je bind() donc je vois s'afficher 10, tout va bien.
Je laisse appuyé le bouton marcher et maintenant j'appui sur sauter (priorité = 2) et là l'animation sauter se lance alors que marcher est active (on voit sur la console 2 qui s'affiche pour la priorité). Déjà là j'ai vue qu' il y a quelque chose qui ne va pas et c'est logique en même temps car dans le code si j'active une animation, j'écrase la priorité sans vérifier avant si elle est supérieure.

Après, je pense que la priorité devrait aussi être rafraîchi au moment du unbind() car ensuite j'ai relâché le bouton sauter en gardant toujours marcher appuyer et là j'ai vue sur la console "2" -> qui correspond à la priorité de sauter (normal vue que je rafraîchi la priorité que quand j'active et non quand je désactive).

Bon, ce poste m'a permis de poser le problème et prendre du recul, je pense avoir déniché ce qui me convient pas.

Donc du coups, j'ai compris que quand on jouait les frames 0,0 dans unbind(), on forçait le node sur cette animation.

Après niveau code j'ai pas changé grand chose, j'essai d'utiliser GenericState, plutôt que de créer une nouvelle classe IdleState.
Dans ma classe application je test les événements comme ceci:

Code c++ :


           if(event.JoystickEvent.Joystick == 0){   /*Si c'est la manette du player 1 ...*/
               //!--- Position du personnage:
               player1.SetPlayerState(event.JoystickEvent.Axis[1] <  -5000,     //! STICK GCHE => AVANCER
                                      event.JoystickEvent.Axis[1] >  5000,      //! STICK GCHE => RECULER
                                      event.JoystickEvent.IsButtonPressed(0));  //! BOUTON A => SAUTER
...
}


Dans ma classe player je fais :

Code c++ :


void CPlayer::LoadPersoPhysics(video::IVideoDriver* driver,scene::ISceneManager* smgr,btDiscreteDynamicsWorld *mWorld, btAxisSweep3 *sweep,int ID){
//Load du mesh ...
...
animati = new AnimationManager(NePlayer);
animati->activate(EAS_IDLE, true /*& 0b000001*/);
}

void CPlayer::SetPlayerState(bool Forward, bool Backward,bool Jump){
            if(Forward == true) goForward = true;
            else goForward = false;

            if(Backward == true) goBackward = true;
            else goBackward = false;

            if(Jump == true) goJump = true;
            else goJump = false;
}

void CPlayer::UpdatePlayerAnimation(){
        animati->activate(EAS_RUNNING, goForward);
        animati->activate(EAS_SWIMING,goJump);
}

    void CPlayer::UpdatePlayer(ICameraSceneNode *camera,
                               scene::ISceneManager* smgr,
                               irrklang::ISoundEngine* SoundEngine,
                               f32 TimeElap,
                               btVector3 Position,
                               btVector3 Rotation,
                               int hitState,
                               bool EnnemiIsAttackin)
{
            /*Update des Animations du personnage*/
            UpdatePlayerAnimation();

            /*Update de la position Rotation du personnage*/
            UpdatePersoDeplacement(camera,smgr,TimeElap);

            /*Update de la position Rotation de la camera personnage*/
            UpdateCameraMovement(camera,smgr,TimeElap);

            /*Update par rapport au vehicule*/
            ///UpdatePlayerInVehicule(Position,Rotation);

            /*Update si le player est touché par l'ennemi*/
            ///UpdateTestIFPlayerTouched(hitState, EnnemiIsAttackin);

            /*Update des sons du player*/
            ///UpdatePlayerSound(SoundEngine);
    }



Voila c'est pas glorieux mais je fais comme je peux smile

Hors ligne


#53 

19-06-2015 22:37:37

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

Déjà là j'ai vue qu' il y a quelque chose qui ne va pas et c'est logique en même temps car dans le code si j'active une animation, j'écrase la priorité sans vérifier avant si elle est supérieure.


le fait qu'une animation de prioriter inférieur a une animation courante ce bind est un soucis, par contre non je ne suis pas d'accord sur la fin de ta phrase smile
alors je ne sais pas, c'est un peut chiant ce terme "active" que j'utilise, ça fous le bordel dans les explications ^^"
mais a priorie, si j'ai comprit, tu pensse qu'une seul annimation peut être active ? ça dépend du sens, si tu parle de "activated" ou "binded"
une seul animation peut être "binded", mais plusieurs peuvent être "activated"

Après, je pense que la priorité devrait aussi être rafraîchi au moment du unbind() car ensuite j'ai relâché le bouton sauter en gardant toujours marcher appuyer et là j'ai vue sur la console "2" -> qui correspond à la priorité de sauter (normal vue que je rafraîchi la priorité que quand j'active et non quand je désactive).


tu la dit toi même quand tu relache le boutton sauter, un évènement ce produit donc peut importe comment tu apelle "activate" par je ne sais quelle bricolage (smile) l'animation est de tout façon rafraichie, sinon tu n'aurais pas "2" dans la console
je suppose que ce "2" est un printf dans unbind ? et ce qui suit c'est un bind qui n'a pas lieux, ce qu'il faut résoudre

Donc du coups, j'ai compris que quand on jouait les frames 0,0 dans unbind(), on forçait le node sur cette animation.


ouaip, mais de tout façon c'est écraser par l'animation suivante

Après niveau code j'ai pas changé grand chose, j'essai d'utiliser GenericState, plutôt que de créer une nouvelle classe IdleState.


niquel

je ne suis pas d'accord sur le rafraichissement de l'animation, mais ça ne devraient pas faire buguer le comportement
utilise tu std::sort ? le cas echéant tu peut ne plus avoir de correspondance avec ton enum

je regarderais ça demain matin,
je suis claquer (peut-être passer a coté d'un truc)

je vais peut-être reprendre un sample d'irrlicht pour coder ça du coup tu me met le doute a force 'O.o

Hors ligne


#54 

19-06-2015 22:50:26

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ha oui j'ai oublier de préciser que j'ai réussi à maintenir une correspondance entre les enum et ce que je voulais activer en faisant :

Code c++ :


       anim.push_back(new GenericState(NPlayer,1,200,295,true)); // idle ?
       std::sort(anim.begin(), anim.end());

        anim.push_back(new GenericState(NPlayer,10,0,80,true)); // running ?
        std::sort(anim.begin(), anim.end());

       anim.push_back(new GenericState(NPlayer,2,80,160,true)); // swimming ?
        std::sort(anim.begin(), anim.end());



Peut être que mon bricolage influe sur le fonctionnement aussi smile

Ps: pour te répondre, pour l'affichage j'ai fais :

  cout<<Apriority<<endl; dans bind() et unbind().

Ok pas de soucis repose toi bien, on se tient au courant demain alors smile .

Hors ligne


#55 

20-06-2015 10:19:41

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

std::sort c'est pour ranger t'est animation par prioriter
ce que tu fait, c'est égales a ça

Code c++ :


       anim.push_back(new GenericState(NPlayer,1,200,295,true)); // idle ?
        anim.push_back(new GenericState(NPlayer,10,0,80,true)); // running ?
       anim.push_back(new GenericState(NPlayer,2,80,160,true)); // swimming ?
        std::sort(anim.begin(), anim.end());


ranger 3 fois avec des éléments en plus, reviens a ranger une seul fois a la fin
qui est égale a ça

Code c++ :


       anim.push_back(new GenericState(NPlayer,1,200,295,true)); // idle ?
       anim.push_back(new GenericState(NPlayer,2,80,160,true)); // swimming ?
        anim.push_back(new GenericState(NPlayer,10,0,80,true)); // running ?



Code c++ :

#include <irrlicht.h>
#include <iostream>
#include <vector>

using namespace irr;

enum ANIMATION_STATE
{
     EAS_IDLE,
     EAS_RUNNING,
     EAS_JUMPING,
     EAS_ATTACKING,
     EAS_COUNT
};

class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual int priority() = 0;

        virtual bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }

        bool activated;
        bool binded;
};

class GenericState : public AnimationBinder
{
    public:
        GenericState(scene::IAnimatedMeshSceneNode* NePlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop)
        {
            binded = false;
            activated = false;
            NodePlayer = NePlayer;
            Apriority = AnimPriority;
            start = FrameStart;
            end = FrameEnd;
            loop = Frameloop;
        }

        virtual void bind()
        {
           std::cout << "bind::" << priority() << std::endl;
           binded = true;
           NodePlayer->setAnimationSpeed(10);
           NodePlayer->setLoopMode(loop);
           NodePlayer->setFrameLoop(start,end);
        }

        virtual void unbind()
        {
           binded = false;
           std::cout << "unbind::" << priority() << std::endl;
        }

        virtual int priority()
        {
            return Apriority;
        }

        scene::IAnimatedMeshSceneNode* NodePlayer;
        int Apriority;
        int start;
        int end;
        bool loop;
};

class AnimationManager
{
    public:
        AnimationManager(scene::IAnimatedMeshSceneNode* NePlayer)
        {
            binded = 0;
            anim.push_back(new GenericState(NePlayer,0,206,250,true)); // idle
            anim.push_back(new GenericState(NePlayer,1,  0, 13,true)); // running
            anim.push_back(new GenericState(NePlayer,3, 94,102,true)); // jumping
            anim.push_back(new GenericState(NePlayer,5, 32, 44,true)); // attacking
            activate(EAS_IDLE, true);
        }
        void activate(int animNumber, bool value)
        {
            AnimationBinder *current = anim[animNumber];
            current->activated = value;

            // idle at default
            current = anim[0];

            for(int i = 0; i<anim.size(); ++i)
                if(current < anim[i] && anim[i]->activated)
                    current = anim[i];

            if(!current->binded && current != binded)
            {
                if(binded)
                    binded->unbind();
                current->bind();
                binded = current;
            }
        }
    private:
        std::vector<AnimationBinder*> anim;
        AnimationBinder *binded;
};

class MyEventReceiver : public IEventReceiver
{
    public:
        MyEventReceiver(scene::IAnimatedMeshSceneNode* NePlayer)
        {
            anim = new AnimationManager(NePlayer);
        }
        virtual bool OnEvent(const SEvent& event)
        {
            if(event.EventType == irr::EET_KEY_INPUT_EVENT )
            {
                if(event.KeyInput.Key == irr::KEY_SPACE)
                    anim->activate(EAS_JUMPING, event.KeyInput.PressedDown);
                if(event.KeyInput.Key == irr::KEY_KEY_Z)
                    anim->activate(EAS_RUNNING, event.KeyInput.PressedDown);
                if(event.KeyInput.Key == irr::KEY_RETURN)
                    anim->activate(EAS_ATTACKING, event.KeyInput.PressedDown);
            }
            return false;
        }
    private:
        AnimationManager *anim;
};

int main()
{

    IrrlichtDevice* device = createDevice(irr::video::EDT_OPENGL,
        core::dimension2d<u32>(640, 480), 16, false, false, false);

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

    scene::IAnimatedMeshSceneNode* anms =
    smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/ninja.b3d"));

    anms->setMaterialFlag(video::EMF_LIGHTING, false);

    anms->setScale(core::vector3df(2.f,2.f,2.f));
    anms->setRotation(core::vector3df(0,-90,0));

    smgr->addCameraSceneNodeFPS();
    device->getCursorControl()->setVisible(false);

    MyEventReceiver receiver(anms);
    device->setEventReceiver(&receiver);

    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(255,113,113,133));
        smgr->drawAll();
        driver->endScene();
    }

    device->drop();
    return 0;
}

Hors ligne


#56 

20-06-2015 21:57:16

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ok merci Magun, j'ai compris pourquoi j'ai autant pinaillé et tu vas me dire si c'est normal...

En fait quand je compile ton programme et que je l'éxecute à partir de l'éditeur IDE codeblocks, sans rien modifier, le personnage joue les bind une fois toutes les "environ" 10 exécutions. En gros je compile 10 fois de suite pour que les événement clavier fonctionnent. De plus, je me suis rendu compte que çà marchait mieux mais pas encore parfaitement :

Le personnage marche puis j'interromp par un saut ok et après, attacking n'interrompait pas running, j'ai fais oulaaa là c'est pas normal, si tu ma posté le code c'est que çà marche et dans le code tout est bon. Je me suis dis, je vais essayer un truc, et si j’exécutais le .exe pour voir ,... et là ...

Tout fonctionne, ... en gros j'ai pas le même résultat entre une exécution par l'IDE et lancer moi-même le .exe . Tu pense que mon IDE est boiteux ? car là sérieux je trouve çà hyper bizard quand même, si çà se trouve la commande compil and run déconne ou un truc du genre.

En tout cas merci, je viens de m'apercevoir que tout ne venait pas de moi !

smile J'attends ton explication pro

Dernière modification par jonath313 (20-06-2015 22:14:42)

Hors ligne


#57 

21-06-2015 00:20:52

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

est tu sur que l'exe généré est bien celui que tu lance (entre ide/exploreur) ?
a tu plusieurs targets ? (debug/release/...)
unix, windows ?

j'ai souvenir d'avoir eu un problème similaire, je ne sais plus vraiment ce que j'avais fait
commence par supprimer tout les fichier généré par codeblocks *.o, *.depend, .fuse_hidden*, gmon.out, .obj/
fichier temporaire %TEMP% ou /tmp/*
un "rebuild all"

c'est un sujet sur le quelle on ne trouve pas beaucoup d'info

Hors ligne


#58 

21-06-2015 23:55:45

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ok, bon visiblement çà vient de mon antivirus, j'ai pris une mauvais habitude. Quand je compile and run l'antivirus fait un scan et j'ai tendance à désactiver l'antivirus à ce moment là. Je ne sais pas ce qu'il se produit si l'antivirus ne peut pas finir de scanner l'application. Enfin bref c'est la seule explication que j'ai car je fais souvent cette manipulation et ce coups ci tout avait planté. Mais c'est quand même bizard que le rebuild all soit sans effet, du-coups j'ai recréé un projet et là plus de problème avec l'ide. Merci pour l'info, je penserai à supprimer les fichiers généré par codeblocks maintenant.

En tout cas je tiens à te remercier car tu m'as vraiment aidé à résoudre ce sujet et tu y a consacré pas mal de temps, c'est vraiment sympas smile.

Maintenant je m’amuse à recréer ce code, en utilisant des classes, j'ai moins d'appréhension à les utiliser. Même si je suis encore loin de maîtriser, je vais m’entraîner pour que ce soit plus instinctif.


Encore merci wink

Hors ligne


#59 

22-06-2015 18:56:22

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 910
Corrections: 2
Site web

antivirus, ça existe encore ? big_smile

j'ai effectivement passer beaucoup de temps !
mais je reste dispo au besoin wink

amuse toi bien tongue

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
883 membres
1429 sujets
11121 messages
Dernier membre inscrit: Saidov17
68 invités en ligne
Aucun membre connecté
RSS Feed