#0 

09-06-2015 23:18:16

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

Salut,

J'ai vu que irrlicht dispose d'un système d'animation pour contrôler des mesh 3d animés. Pour le moment j'anime en faisant des test if à rallonge, le problème c'est que plus je veux utiliser d'animations et plus les tests sont compliqués et rendent le code illisible.

Mon prôblème c'est que je voudrais utiliser plusieurs animations sur le même personnage, par exemple, marcher, tirer, sauter et que ces animations soient en quelque sorte managées. J'ai fais des recherches sur le net et j'ai testé plusieurs choses mais je n'arrive pas à aboutir à quelque chose de simple ni de vraiment fonctionnel.


Si quelqu'un à la solution... Au début je pensais faire des états en énumérant marcher, tirer, sauter mais le problême restait le même, pour distinguer marcher de tirer il fallait faire plusieurs tests dans un if.

Merci.

Hors ligne


#1 

10-06-2015 11:06:53

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

Salut !

j'ai déjà pas mal réfléchie a ce problème
dans ton cas je pensse que tu as plus de mal à harmonisé ton code et à le divisé
après évidemment ça dépends de t'est contraintes

si j'ai bien comprit tu anime chaque bonnes "manuelement" dans une grosse classe ?
pourquoi ne pas commencer par splitter ton code ?

Code c++ :


  class AnimationBinder
  {
        public:
            virtual void anim(ISkinnedMesh*) = 0;
  };
  class CustomManagerAnimation
  {
        public:
            CustomManagerAnimation()
            {
                upper.push_back(FollowCusorToHeadAnimation);
                middle.push_back(AttackAnimation);
                middle.push_back(UseObjectAnimation);
                lower.push_back(RunAnimation);
                lower.push_back(JumpAnimation);
                lower.push_back(CrouchAnimation);
                lower.push_back(IdleAnimation);
                ....
            }
            ...
            setLowerAnimation(int);
            ...
            void anim(ISkinnedMesh *a)
            {
                upper[upper_anim].anim(a);
                middle[middle_anim].anim(a);
                lowerlower[lower_anim].anim(a);
            }
        private:
            irr::core::array<AnimationBinder> upper;
            irr::core::array<AnimationBinder> middle;
            irr::core::array<AnimationBinder> lower;
            ...
  };



tu ne devraient avoir beusoin de ne distinguer que 3 animation simultanément je suppose
la tête qui tourne, une action, et le déplacement et aucun des trois ne devraient intéragir sur des bonnes d'une autres animations ?
au quelle cas tu devras peut-être faire un petit calcule ( vector3d<T>::getInterpolated )
ça te permetrais de réutiliser un peut mieux le code

du coup plus tard tu pourras remplacer tes "AnimationBinder" pour un chargement externe
binder de façon partiel une animation md2 par exemple

Hors ligne


#2 

10-06-2015 22:18:09

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

Ton code a l'air assez poussé. En fait j'utilise les animations par frame pour le moment, et effectivement quand mon personnage marche si je joue l'animation tirer, les jambes ne bougent plus car l'animation tirer bloc. Je ne sais pas si on parlait de la même chose. T'as solution me paraît tout de même complexe. Pour le moment je gére l'animation du personnage dans une classe player qui contient tout sur mon personnage (chargement du mesh, déplacement, animations,...).

Hors ligne


#3 

10-06-2015 23:01:05

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

mon code n'est pas spécialement complexe, juste quelques astuces, un peut de math, de la jugotte et un bon design smile
effectivement si tu utilise a l'heure actuelle, uniquement les animations md2 .... bref

dans ce cas peut-être qu'un exemple de t'a solution actuelle serait plus approprier ?
et expliquer un peut plus vers quoi tu veut tendre ?

wink

Hors ligne


#4 

10-06-2015 23:59:19

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

Je tiens à te remercier pour ton aide,

Actuellement mon code ressemble à çà :

Code c++ :

   
void CPlayer::SetPlayerAnimation(int NoAnim){
            switch(NoAnim){
                case 0:
                    AnimStand = true;
                    break;
                case 1:
                    AnimWalk = true;
                    break;
                case 2:
                    break;
                default:
                    AnimStand = false;
                    AnimWalk = false;
                    break;
            }
}

    void CPlayer::UpdatePlayerAnimation(){
   ///!--- Si le perso n'est pas dans un vehicule:
        if(IsInVehicule == false){
            if(AnimStand == false){
               //Pas traité
            }
            if(AnimWalk == false && goForward == true){
                ///NePlayer->setAnimationSpeed(10);
                NePlayer->setAnimationSpeed(50);
                NePlayer->setFrameLoop(0,80);
                AnimWalk = true;
                SfootStepActif = false;
            }
            if(AnimWalk ==true && goForward == false){
                NePlayer->setAnimationSpeed(0);
                NePlayer->setFrameLoop(0,0);
                AnimWalk = false;
               SfootStepActif = true;

            }
        }
        //!--- Sinon le perso est dans un vehicule:
        else{
            NePlayer->setAnimationSpeed(0);
            NePlayer->setFrameLoop(0,0);

        }
}


Seulement une seule animation peut être gérée correctement . Après si je veux faire une autre animation je dois faire des tests sur tous les cas et çà çà me plait pas.

J'ai essayé de converger vers quelque chose de plus structuré du genre :

Code c++ :

void CPlayer::setState(eAnimState newState)
{
   oldState = curState;
   curState = newState;
}
CPlayer::eAnimState CPlayer::getState()
{
   return curState;
}

void CPlayer::idle()
{
///NePlayer->animateJoints();
   setState(CPlayer::eAnimState::Idle);

   NePlayer->setAnimationSpeed(ANIMATION_SPEED);
   NePlayer->setLoopMode(true);
   NePlayer->setFrameLoop(90,113);
}

void CPlayer::walk()
{
   setState(CPlayer::eAnimState::Walk);

   NePlayer->setAnimationSpeed(ANIMATION_SPEED);
   NePlayer->setLoopMode(true);
   NePlayer->setFrameLoop(0,80);
}


Mais au final je me suis retrouvé avec le même problème -> complexité des tests if, j'ai seulement remplacé les booléens par des énumérations.

Je cherche à converger d'abord vers un moyen simple de jouer des animations les unes après les autres  (j'utilise une manette xbox360 pc):

Stick gauche haut -> animation en cours = Anim avancer
Si je tire -> le personnage s’arrête et joue l'animation tirer
Si je relâche le bouton du tire et si j'ai laissé le stick gauche bloqué vers le haut, l'animation marcher se joue.

Après, j'aimerai ajouter le contrôle des bones pour que quand je tire et que je vise le bras se déplace mais que çà joue l'animation tirer quand même.

Je sais pas si j'ai été assez clair car c'est pas évident à expliquer. En gros je voudrais réussir à manager pleins d'animations frame sans avoir à utiliser des milliers de booléens et de tests if à rallonge. Il faut aussi que ce soit à ma porté niveau codage.

Un exemple de ce que je recherche à faire :
https://www.youtube.com/watch?v=77wfrXvOkIQ

Puis par la suite, arriver à quelque chose de plus fluide tel que:
https://www.youtube.com/watch?v=0ea-CXxBEYg

Dernière modification par jonath313 (11-06-2015 00:05:26)

Hors ligne


#5 

11-06-2015 01:35:47

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

très bien, bon j'ai passer du temps a comprendre ou étais le soucis
si j'ai réellement compris d'ailleurs ... j'ai réadapté mon "esquisse" de départ

j'en suis donc arriver ici

Code c++ :


class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual void priority() = 0;
       
        bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }
       
        bool activated;
        bool binded;
};

class AnimationManager
{
    public:
        AnimationManager()
        {
            anim.push_back(new ...);
            ...
            anim.sort();
        }
        void activate(int animNumber, bool value)
        {
            auto current = anim[animNumber];
            current.activated = value;
           
            if(current.binded && !value)
                current.unbind();
           
            current = anim[0];
            for(auto it : anim)
                if(current < it && it.activated)
                    current = it;
           
            if(current.activated && !current.binded)
                current.bind();
        }
    private:
        irr::core::array<AnimationBinder*> anim;
};



pourquoi ne pas simplement utiliser un system de priorité ?
couplet avec deux états "actif" et "en utilisation" ?

seul l'animation aillent la plus forte priorité resteras active,
ce qui te permet d'activer/désactiver n'import qu'elle animation sans te soucier du reste
par exemple atacker auras probablement la plus grosse prioriter, suivras du saut, et de la marche
pour ce qui est du véhicule, je ne pensse pas que ça pose de soucis de la laisser a ça place
(ou au pire faire un "AnimationBinder" de prioriter maximal ?)

et donc il te suffi d'implementer "AnimationBinder"

Code c++ :


class RunningState : public AnimationBinder
{
    public:
        virtual void bind()
        {
           binded = true;
           NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(true);
           NePlayer->setFrameLoop(0,80);
        }
        virtual void unbind()
        {
           binded = false;
           NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(false);
           NePlayer->setFrameLoop(0,0);
        }
        virtual int priority()
        {
            return 0;
        }
};



dit moi ce que tu en pensse ? smile
ou si je suis à côté de la plaque ?

Hors ligne


#6 

11-06-2015 09:53:18

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

Et bien c'est exactement ce que je pensais mais j'avais du mal à détailler. En électronique c'est une interruption mais au final c'est le même raisonnement : système de priorité.

Merci pour l'idée çà me parait beaucoup plus pratique.

Je vais essayer de comprendre ton code. Pour le moment je n'ai jamais utilisé d'"operator" ni le mot clé "virtual" et "auto" ... je vais chercher sur le net ce qu'il en est et on en rediscute si tu es d'accord.

Merci smile

Hors ligne


#7 

11-06-2015 10:50:15

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

bien sur pas de soucis smile

Hors ligne


#8 

11-06-2015 20:26:35

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

Alors :

virtual : déclarer une fonction destinée à être redéfinie dans les classes qui héritent de la classe où elle a été déclarée.
auto : permet de laisser le compilateur choisir le type au moment de la compilation, ce type restera fixe.
operator : je ne vois pas comment expliquer cette ligne : bool operator < (AnimationBinder *other)

Peux tu m'expliquer comment tu ferais pour utiliser tes classes AnimationBinder, AnimationManager, RunningState .

Si je comprend bien:

AnimationBinder : permet de déclarer une animation.
AnimationManager : permet de "manager" toutes les animations bindés.
RunningState : Lier ou délier une animation.

Pour le moment j'ai une classe application qui fait tourner ma boucle de rendu, dans cette classe j'ai un capteur d'événnement qui test les évent manette. A l'initialisation je crée un objet player qui contient le chargement des mesh, la physique du perso et la gestion des animations.

Dernière modification par jonath313 (11-06-2015 20:26:57)

Hors ligne


#9 

12-06-2015 00:51:18

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

yep, dsl de ne pas avoir répondue plus tôt smile

virtual: waip
auto: oui
operator: c'est pour la surcharge des operateur arithmetique ici "<"
si AnimationBinder est comparer avec un autre AnimationBinder* via l'operateur "<" c'est la fonction en question qui seras appeller

petite info, le ":" dans le for n'est disponible que depuis c++11, "Range-based for loop"
en fonction du type du second parametre la boucle s'adapteras ...

<< for(auto i : data) >> est equivalent à << for(std::vector<int>::const_iterator it = data.begin(); it!=data.end(); ++it) { int element = *it; } >>
où << for(AnimationBinder *it = irr_array.pointor()[0] ; it != irr_array.pointor()[irr_array.size()]; ++it) >> c'est juste du code en confiture étallé smile

AnimationBinder: yep, je n'aime pas du tout le terme, mais en général ont le traduit par "patron"
RunningState: c'est une l'implementation d'une animation avec le "patron" en temps qu'exemple pour toi

justement smile
avec cette architecture et ta gestion des evenement tu n'a pas cas écrire quelque chose du genre

Code c++ :

animation.activate(EAB_RUNNING, (event. ... .ButtonStates & 0x00001) && event. ... .Axis[1]);
animation.activate(EAB_ATTACKING, event. ... .ButtonStates & 0x00010);

Hors ligne


#10 

12-06-2015 12:58:27

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

Ha ok, mais je dois tout de même faire un set-up pour définir les priorités ? Du style AnimationMarcher.priority(int priority);

Autre chose, j'ai plusieurs animations et tu as écris dans ton exemple:

Code c++ :

        virtual void bind()
        {
           binded = true;
           NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(true);
           NePlayer->setFrameLoop(0,80);
        }


L'animation à binder peut-elle être variable ?

Code c++ :

        virtual void bind()
        {
           binded = true;
           NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(true);

           switch(choix){
                case Marcher:
                 NePlayer->setFrameLoop(0,80);

               case Courrir:
                 NePlayer->setFrameLoop(80,120);

               case Sauter:
                 NePlayer->setFrameLoop(120,140);

               case ...:
                 NePlayer->setFrameLoop(...,....);
             }
           }
        }


Je sais pas si je dois faire çà comme çà.
Tu utilise aussi des cas énumérés EAB_RUNNING, EAB_ATTACKING, ... ? Ou je me trompe ?

Merci pour tes réponses.

Dernière modification par jonath313 (12-06-2015 13:30:02)

Hors ligne


#11 

12-06-2015 14:13:10

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

Ha ok, mais je dois tout de même faire un set-up pour définir les priorités ? Du style AnimationMarcher.priority(int priority);


???
juste definir dans ton implementation

Code c++ :

virtual int priority()
{
      return ta_prioriter; // 0, 1, 2, .... etc
}


après si tu veut des prioritées variable ça doit pouvoir ce faire facilement
d'ailleurs, elle devraient être constant cette fonction ^^"

Code c++ :

anim[x].setPriority(99);
activate(x, anim[x].activated);



oui ton animation peut être variable, mais tu devras te débrouiller pour rebinder l'animation si le choix change en cours d'utilisation
oui, c'est une enum, je trouve ça plus propre dans ce cas la qu'un entier

après si ton model d'animation reste standar tu peut passer par un template

ps: pas de soucis, c'est rare que le forum soit actif en ce moment donc, ça fait un peut de "vie" smile

Hors ligne


#12 

12-06-2015 20:37:03

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

Je commence à essayer de le coder comme tu m'as expliqué par contre j'ai des erreurs assez gênantes :

Code:

||=== Build: Debug in Jeu (compiler: GNU GCC Compiler) ===|

...\CPlayerAnimation.h                        ||In member function 'bool AnimationBinder::operator<(AnimationBinder*)':|
...\CPlayerAnimation.h                        |26|error: invalid operands of types 'void' and 'void' to binary 'operator<'|
...\CPlayerAnimation.h                        ||In constructor 'AnimationManager::AnimationManager()':|
...\CPlayerAnimation.h                        |38|error: expected type-specifier before '...' token|
...\CPlayerAnimation.h                        |38|error: expansion pattern '(int*)operator new(4u)' contains no argument packs|
...\CPlayerAnimation.h                        ||In member function 'void AnimationManager::activate(int, bool)':|
...\CPlayerAnimation.h                        |45|error: request for member 'activated' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h                        |47|error: request for member 'binded' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h                        |48|error: request for member 'unbind' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h                        |51|error: no matching function for call to 'begin(irr::core::array<AnimationBinder*>&)'|
...\CPlayerAnimation.h                        |51|note: candidates are:|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|89|note: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|89|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   'irr::core::array<AnimationBinder*>' is not derived from 'std::initializer_list<_Tp>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|87|note: template<class _Tp, unsigned int _Nm> _Tp* std::begin(_Tp (&)[_Nm])|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|87|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   mismatched types '_Tp [_Nm]' and 'irr::core::array<AnimationBinder*>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|note: template<class _Container> decltype (__cont.begin()) std::begin(const _Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|error: 'const class irr::core::array<AnimationBinder*>' has no member named 'begin'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|note: template<class _Container> decltype (__cont.begin()) std::begin(_Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|error: 'class irr::core::array<AnimationBinder*>' has no member named 'begin'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|error: no matching function for call to 'end(irr::core::array<AnimationBinder*>&)'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note: candidates are:|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|99|note: template<class _Tp> constexpr const _Tp* std::end(std::initializer_list<_Tp>)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|99|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   'irr::core::array<AnimationBinder*>' is not derived from 'std::initializer_list<_Tp>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|97|note: template<class _Tp, unsigned int _Nm> _Tp* std::end(_Tp (&)[_Nm])|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|97|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   mismatched types '_Tp [_Nm]' and 'irr::core::array<AnimationBinder*>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|note: template<class _Container> decltype (__cont.end()) std::end(const _Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|error: 'const class irr::core::array<AnimationBinder*>' has no member named 'end'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|note: template<class _Container> decltype (__cont.end()) std::end(_Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|note:   template argument deduction/substitution failed:|

...\CPlayerAnimation.h        |51|required from here|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|error: 'class irr::core::array<AnimationBinder*>' has no member named 'end'|

...\CPlayerAnimation.h        |51|error: unable to deduce 'auto' from '<expression error>'|
...\CPlayerAnimation.h        |55|error: request for member 'activated' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |55|error: request for member 'binded' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |56|error: request for member 'bind' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |80|error: conflicting return type specified for 'virtual int RunningState::priority()'|
...\CPlayerAnimation.h        |22|error:   overriding 'virtual void AnimationBinder::priority()'|
||=== Build failed: 18 error(s), 5 warning(s) (0 minute(s), 3 second(s)) ===|

Tu crois que je n'utilise pas le bon compilateur car il y a des erreurs que j'ai jamais vu ?! (la plupart)

Hors ligne


#13 

12-06-2015 22:48:51

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

je m'excuse je voulais poster avants de me coucher alors que je dormais sur mon clavier ^^"

...\CPlayerAnimation.h                        ||In member function 'bool AnimationBinder::operator<(AnimationBinder*)'neutral
...\CPlayerAnimation.h                        |26|error: invalid operands of types 'void' and 'void' to binary 'operator<'|
...\CPlayerAnimation.h        |80|error: conflicting return type specified for 'virtual int RunningState::priority()'|
...\CPlayerAnimation.h        |22|error:   overriding 'virtual void AnimationBinder::priority()'|


virtual int priority() = 0; et non virtual void priority() = 0;


...\CPlayerAnimation.h                        ||In constructor 'AnimationManager::AnimationManager()'neutral
...\CPlayerAnimation.h                        |38|error: expected type-specifier before '...' token|
...\CPlayerAnimation.h                        |38|error: expansion pattern '(int*)operator new(4u)' contains no argument packs|


les "..." de mon code sont la pour te dire de compléter smile

...\CPlayerAnimation.h                        ||In member function 'void AnimationManager::activate(int, bool)'neutral
...\CPlayerAnimation.h                        |45|error: request for member 'activated' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h                        |47|error: request for member 'binded' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h                        |48|error: request for member 'unbind' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |51|error: unable to deduce 'auto' from '<expression error>'|
...\CPlayerAnimation.h        |55|error: request for member 'activated' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |55|error: request for member 'binded' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|
...\CPlayerAnimation.h        |56|error: request for member 'bind' in 'current', which is of pointer type 'AnimationBinder*' (maybe you meant to use '->' ?)|


pareil à coter de la plaque remplace "." par "->"

...\CPlayerAnimation.h                        |51|error: no matching function for call to 'begin(irr::core::array<AnimationBinder*>&)'|
...\CPlayerAnimation.h                        |51|note: candidates are:|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|89|note: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|89|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   'irr::core::array<AnimationBinder*>' is not derived from 'std::initializer_list<_Tp>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|87|note: template<class _Tp, unsigned int _Nm> _Tp* std::begin(_Tp (&)[_Nm])|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|87|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   mismatched types '_Tp [_Nm]' and 'irr::core::array<AnimationBinder*>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|note: template<class _Container> decltype (__cont.begin()) std::begin(const _Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|58|error: 'const class irr::core::array<AnimationBinder*>' has no member named 'begin'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|note: template<class _Container> decltype (__cont.begin()) std::begin(_Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|48|error: 'class irr::core::array<AnimationBinder*>' has no member named 'begin'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|error: no matching function for call to 'end(irr::core::array<AnimationBinder*>&)'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note: candidates are:|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|99|note: template<class _Tp> constexpr const _Tp* std::end(std::initializer_list<_Tp>)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\initializer_list|99|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   'irr::core::array<AnimationBinder*>' is not derived from 'std::initializer_list<_Tp>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|97|note: template<class _Tp, unsigned int _Nm> _Tp* std::end(_Tp (&)[_Nm])|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|97|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|note:   mismatched types '_Tp [_Nm]' and 'irr::core::array<AnimationBinder*>'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|note: template<class _Container> decltype (__cont.end()) std::end(const _Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|note:   template argument deduction/substitution failed:|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|51|required from here|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|78|error: 'const class irr::core::array<AnimationBinder*>' has no member named 'end'|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|note: template<class _Container> decltype (__cont.end()) std::end(_Container&)|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|note:   template argument deduction/substitution failed:|

...\CPlayerAnimation.h        |51|required from here|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\range_access.h|68|error: 'class irr::core::array<AnimationBinder*>' has no member named 'end'|

...\CPlayerAnimation.h        |51|error: unable to deduce 'auto' from '<expression error>'|


irr::core::array ne doit visiblement pas marcher avec un "range-based for loop"
perso je passe par irr::core::list pas de soucis, ou sinon std::vector, std::array probablement plus adapter avec ce dernier
les fonctions irr::core::array::begin() et  irr::core::array::end() n'existe pas, ce qui explique l'erreur où peut-être bien que je les est définie en externe mais comme tu ne les as pas ...

Hors ligne


#14 

12-06-2015 23:16:47

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

J'ai fais des modifs :

Code c++ :


#ifndef CPLAYERANIMATION_H
#define CPLAYERANIMATION_H

#include <irr/irrlicht.h>

class AnimationBinder

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

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

        bool activated;
        bool binded;
};

class AnimationManager
{
    public:
        AnimationManager()
        {
            anim.push_back(new "?");
            ///...
            anim.sort();
        }
        void activate(int animNumber, bool value)
        {
            auto current = anim[animNumber];
            current->activated = value;

            if(current->binded && !value)
                current->unbind();

            current = anim[0];
            for(auto it : anim)
                if(current < it && it.activated)
                    current = it;

            if(current->activated && !current->binded)
                current->bind();
        }
    private:
        irr::core::array<AnimationBinder*> anim;
};


class RunningState : public AnimationBinder
{
    public:
        virtual void bind()
        {
           binded = true;
         /*  NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(true);
           NePlayer->setFrameLoop(0,80);*/

        }
        virtual void unbind()
        {
           binded = false;
          /* NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(false);
           NePlayer->setFrameLoop(0,0);*/

        }
        virtual int priority()
        {
            return 0;
        }
};

#endif // CPLAYERANIMATION_H



Après j'ai beau insister mais j'ai même pas d'idée pour completer le code... Alors trouver les réponses ne doit pas être de mon ressort au niveau programmation. J'ai l'impression que peut de personnes se sont lancer sur ce sujet, ce qui est sûr c'est que ce n'est pas simple.

Désolé de "traîner" la patte mais je fais ce que je peux, j'ai résolu pas mal de problêmes sur des sujets auxquels je t'ai sollicité mais plus j'avance et plus les interrogations deviennent complexes.

...Sinon j'ai eu une inspiration en regardant des videos ...
Vue que je dispose d'un piètre niveau d'inspiration à ce sujet, pourrait-on le faire comme ceci :

Code c++ :


CPlayer::CPlayer(ISceneManager *smgr){
     IAnimatedMesh* mesh = smgr->getMesh("?");
     playerNode = smgr->addAnimatedMeshSceneNode(mesh);
     currentAnimation = IDLE_ANIM_PLAYER;
}

void CPlayer::setAnimation(PlayerAnimation animation){
    if(currentAnimation  != animation){
       currentAnimation  = animation;

       switch(animation){
                 case IDLE_ANIM_PLAYER:
                           playerNode -> setFrameLoop(0,80);
                           playerNode -> setCurrentFrame(0);
                           break;
                 case RUN_ANIM_PLAYER:
                           playerNode -> setFrameLoop(80,120);
                           playerNode -> setCurrentFrame(80);
                           break;
                 case ATTACK_ANIM_PLAYER:
                           playerNode -> setFrameLoop(120,160);
                           playerNode -> setCurrentFrame(120);
                           break;
        };
     }
}

Dernière modification par jonath313 (12-06-2015 23:35:48)

Hors ligne


#15 

13-06-2015 11:30:29

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

new "?"


anim est un array constituer de quoi ?
et RuningState c'est quoi ?

Vue que je dispose d'un piètre niveau d'inspiration à ce sujet, pourrait-on le faire comme ceci :


tu retomber exactement sur ce que tu faisais au départ ? et puis tu ne peut pas géré les animations "précédentes"

je comprend pas bien où tu bute ... l'héritage ?

Hors ligne


#16 

13-06-2015 21:58:09

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

Oui je suis retombé sur la même chose, je m'en suis aperçut en le testant ... ducoups c'est pas une bonne solution.

Oui l'heritage me perturbe un peu.

anim est un array constitué des animations à déclencher, mais exactement te dire ce que c'est dans le code, je ne vois pas.

Pour moi quand tu écris :  anim.push_back(new "?");

Je me demande où "anim" a été déclarée.

Pour moi "RuningState " est une classe fille qui hérite de "AnimationBinder" . Si je crée un objet de type "RuningState ", celui-ci hériterage des attributs de la classe "AnimationBinder".

"RuningState " est un booléen ?

Dernière modification par jonath313 (13-06-2015 21:59:29)

Hors ligne


#17 

13-06-2015 22:44:47

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

OOOk smile
bon il va falloir éclaircir quelque point !

irr::core::array<AnimationBinder*> si tu veut c'est la même chose que AnimationBinder*[size]
mais du coup géré via une class pour les (re/des)allocations

Je me demande où "anim" a été déclarée.


si tu as déjà du mal avec le concepts de base des classes effectivement, l'héritage est peut être un peut prématuré
anim est déclarer dans AnimationManager, quand tu crée une instance de class une zone mémoire est réserver avec la taille de celle si,
ce qui inclue les objets qui y sont déclaré, ici "anim", pareil pour les fonctions, et l'héritage (vtable)
si tu maitrise le C je peut a la rigueur t'expliquer comment ont peut écrire une class et de l'héritage en C
si tout fois tu est à l'aise les pointeurs sur fonctions

Code c++ :


typedef struct AnimationManager
{
    irr::core::array<AnimationBinder*> anim;
};

void AnimationManagerActivate(AnimationManager *tmp, int animNumber, bool value)
{
    auto current = tmp->anim[animNumber];
    current->activated = value;

    if(current->binded && !value)
        current->unbind();

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

    if(current->activated && !current->binded)
        current->bind();
}

AnimationManager* ConstructAnimationManager()
{
    AnimationManager *tmp = malloc(sizeof(AnimationManager));
    tmp->anim.push_back(new "?");
    tmp->anim.sort();
    tmp->activate = &AnimationManagerActivate;
    return tmp;
}



et du coup pour l'héritage:

Code c++ :

typedef struct AnimationBinder
{
    void (*bind)(AnimationBinder*);
    void (*unbind)(AnimationBinder*);
    int  (*priority)(AnimationBinder*);
   
    bool activated;
    bool binded;
};

// operator '<'
void AnimationBinderCmp(AnimationManager *tmpA, AnimationManager *tmpB)
{
    return tmpA->priority() < tmpB->priority();
}

AnimationBinder* ConstructAnimationBinder()
{
    AnimationBinder *tmp = malloc(sizeof(AnimationBinder));
    tmp->bind = 0;
    tmp->unbind = 0;
    tmp->priority = 0;
    return tmp;
}

//======================================

typedef struct RuningState
{
    AnimationBinder base;
    irr::scene::IAnimatedMesh *NePlayer;
};

void RuningStateBind(AnimationBinder *tmp)
{
    RuningState *real = static_cast<RuningState*>(tmp);
    tmp->binded = true;
    real->NePlayer->setAnimationSpeed(ANIMATION_SPEED);
    real->NePlayer->setLoopMode(true);
    real->NePlayer->setFrameLoop(0,80);
}

void RuningStateUnBind(AnimationBinder *tmp)
{
    RuningState *real = static_cast<RuningState*>(tmp);
    tmp->binded = true;
    real->NePlayer->setAnimationSpeed(ANIMATION_SPEED);
    real->NePlayer->setLoopMode(false);
    real->NePlayer->setFrameLoop(0,0);
}

int RuningStatePriority(AnimationBinder *tmp)
{
    RuningState *real = static_cast<RuningState*>(tmp);
    return 0;
}

RuningState* ConstructRuningState()
{
    RuningState *tmp = malloc(sizeof(RuningState));
    AnimationBinder *base = static_cast<AnimationBinder*>(RuningState);
    tmp->bind = &RuningStateBind;
    tmp->unbind = &RuningStateUnBind;
    tmp->priority = &RuningStatePriority;
    return tmp;
}



Pour moi "RuningState " est une classe fille qui hérite de "AnimationBinder" . Si je crée un objet de type "RuningState ", celui-ci hériterage des attributs de la classe "AnimationBinder".

"RuningState " est un booléen ?


le début oui, mais que viens faire un booléen ici ?
tu la dit toi même ["RuningState " est une classe fille qui hérite de "AnimationBinder"] donc
"RuningState " c'est un "AnimationBinder" ...

pour rappelle tu peut écrire

Code c++ :

AnimationBinder *machin = new RuningState ();


même chose qui est utiliser pour la gui (IGUIElement et tout c'est dériver, comme les ISceneNode, IMesh, ... etc)
ces classes n'ont aucune consistance, ce sont comme ici des interfaces, ou "patron"
leurs implémentations sont dispos (cacher de l'utilisateur) sous le noms CGUIButton par exemple

je ne sais pas si ça te seras d'une grande aide, j'aurais essayer roll
après si tu veut que je t'explique plus simplement, ça doit pouvoir s'envisager ...

Hors ligne


#18 

13-06-2015 23:33:37

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

Ok je commence à y voir plus clair. Mais il y a quelque chose qui m'interroge ...
Imagine qu'il y a plusieurs animations, dans ce cas le code suivant doit être modifié ?

Code c++ :


void RuningStateBind(AnimationBinder *tmp)
{
    RuningState *real = static_cast<RuningState*>(tmp);
    tmp->binded = true;
    real->NePlayer->setAnimationSpeed(ANIMATION_SPEED);
    real->NePlayer->setLoopMode(true);

      //real->NePlayer->setFrameLoop(0,80);
      real->NePlayer->setFrameLoop(start,end); // ???
}



Après, tu as laissé :

Code c++ :


tmp->anim.push_back(new "?");



Est-ce volontaire ?

As tu déjà testé ce code ? Au niveau rendu çà donne coi exactement ?

Je me demande si le système de priorité ne va pas juste empêcher certaines actions de se produire ?

Hors ligne


#19 

13-06-2015 23:55:55

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

Imagine qu'il y a plusieurs animations


justement tu crée une nouvelle animation séparer avec ça propre implémentation de AnimationBinder
ou alors soit tu ne veut qu'une class et tu peut passer start et end en parametre de la class ou via un template
ou si tu veut quelque chose pour faire des enchainement spécifique passer pas IAnimationEndCallBack  (de mémoire)
genre "jump start", "jump fall", "jump land"

Est-ce volontaire ?
oui, d'un j'allais pas faire une class array en C
de deux faut que tu comprenne par toi même
sachant que je t'est donner la réponses dans le précédent poste, ainsi que m'ont premier wink

As tu déjà testé ce code ?
non pas pour les animations enfin au début j'avais quelque chose dans le style,
sur le forum je ne m'amuse pas a faire un projet a chaque fois pour tester ^.^
j'ai cependant suffisamment d'expérience, je pense pour te certifier de la méthode

Au niveau rendu çà donne coi exactement ?
les animations ce suive, si une n'est plus active, la précédente en terme de priorité et d'activite est lancer
si une d'une priorité supérieure est activer, elle remplace celle en cours, ce que tu veut faire

Je me demande si le système de priorité ne va pas juste empêcher certaines actions de se produire ?
tout dépend du nombre d'animation que tu doit géré il est vrais, mais tu n'est pas nom plus bloqué

rien ne t'empêche
- d’avoir des priorité dynamique
- d'avoir des priorité égales, donc tu peut imaginer un système pour les distinguées genre courir/marcher ???
- d'avoir un AnimationManager au seins d'un AnimationBinder genre le véhicule
- de pouvoir a terme converger vers des méthodes plus complexe (double animation courir + attaquer)
via ce type d'approche


t'as seul limite dans tout les cas, c'est ton imagination pour contourné les éventuelles problème
bonne soirée smile

Dernière modification par Magun (14-06-2015 00:31:10)

Hors ligne


#20 

14-06-2015 00:36:08

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

Je ne remet pas en question tes compétences smile

Alors, j'ai enfin une idée qui me vient , si j'écris :

Code c++ :


anim.push_back(new AnimationBinder);



C'est faux, je le sais mais ce que je dois faire c'est ajouter un élément dans ce que tu appel un array (tableau in french ). Si j'ai bien compris, le but est de déclarer des animations et de les "empiler" en mémoire, ces animations sont dans:

Code c++ :


irr::core::array<AnimationBinder*> anim;



Si j'ai encore dis une boulette je me reconverti en coupeur de citron ! smile

Hors ligne


#21 

14-06-2015 00:49:08

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

Je ne remet pas en question tes compétences ... loin de moi cette idée

c'est ça, effectivement tu ne peut pas allouer d'AnimationBinder, pour cause
les fonctions déclarer sont post-fixé de "=0" donc n'existe pas
elles permettes de déclaré dans la vtable les prototypes des fonctions usé dans les autres implémentations
comme j'ai fait

Code c++ :


    void (*bind)(AnimationBinder*);
    void (*unbind)(AnimationBinder*);
    int  (*priority)(AnimationBinder*);



par contre RuningState les implémentes, donc tu peut l'alloué, et il dérive de AnimationBinder ?
donc pourquoi n'a tu pas encore tester ? << anim.push_back(new RunningState); >>

et donc pour une autre animation bidon:

Code c++ :


class IdleState : public AnimationBinder
{
    public:
        IdleState() { activated = true; bind(); }
        virtual void bind()
        {
           binded = true;
           NePlayer->setLoopMode(true);
           NePlayer->setFrameLoop(0,80);
        }
        virtual void unbind()
        {
           binded = false;
        }
        virtual int priority()
        {
            return -1;
        }
};
anim.push_back(new IdleState);



ps: coupeur de citron ? je tombe sur un "ninja" en vidéo ... °-°
bon cette fois si je vais me coucher

Hors ligne


#22 

14-06-2015 01:12:44

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

J'ai essayé aussi et il me dit :

C:\Users\Jonathan\Jeu\CPlayerAnimation.h|39|error: expected type-specifier before 'RunningState'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|39|error: expected ')' before 'RunningState'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|39|error: no matching function for call to 'irr::core::array<AnimationBinder*>::push_back(int*)'|

C:\Users\Jonathan\Jeu\CPlayerAnimation.h|39|note: candidate is:|

c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\..\..\..\..\include\irr\irrArray.h|111|note: void irr::core::array<T, TAlloc>::push_back(const T&) [with T = AnimationBinder*; TAlloc = irr::core::irrAllocator<AnimationBinder*>]|
c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\..\..\..\..\include\irr\irrArray.h|111|note:   no known conversion for argument 1 from 'int*' to 'AnimationBinder* const&'|

ps0: Je suspecte le compilateur d'être en fait un conspirateur...
ps1: Coupeur de citron -> ninja -> ninja.b3d -> model 3d -> programmation -> utilisateur d'irrlicht (l'héritage j'ai pigé mais plus au niveau de la c*nnerie) smile
ps2: Bonne nuit ! Et merci pour ton aide !

Dernière modification par jonath313 (14-06-2015 01:31:23)

Hors ligne


#23 

14-06-2015 09:16:53

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

normalement il faut déclaré RunningState avant sont utilisation, donc avant AnimationManager ...
dsl je penssais que tu le vérrais, ou plutot que tu le scinderais dans un autre header

Hors ligne


#24 

14-06-2015 13:37:27

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

Ok oui effectivement je n'avais pas fais attention à l'ordre des classes, çà c'est le genre d'erreur que je pouvais corriger, ... désolé.

tu peut passer start et end en parametre de la class ou via un template


J'aimerais savoir comment on passe des paramètres à une classe (version propre) car moi pour le moment j'ai toujours déclaré une variable globale et j'utilisais des fonction set et get pour changer la valeur ou connaître son contenu.

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
70 invités en ligne
Aucun membre connecté
RSS Feed