#0 

11-06-2008 08:42:58

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

Bonjour, j'utilise la classe d'un membre de ce forum (je l'en remercie beaucoup) : Zangetsu qui permet à la caméra d'être positionnée tout le temps derrière le personnage.

J'ai crée une fonction qui permet de faire tourner/déplacer le personnage en fonction des touches tapées au clavier:

Code:

void CEventReceiver::majOfPos()
{
    if(Nmodele != 0 && isMoving == true)
    {
        irr::core::vector3df vector = Nmodele->getRotation();
        irr::core::vector3df v = Nmodele->getPosition();

        if(move == forward)
        {
            v.X += 1.0f;
        }
        else if(move == backward)
        {
            v.X -= 1.0f;
        }
        else if(move == left)
        {
            v.Z += 1.0f;
        }
        else if(move == right)
        {
            v.Z -= 1.0f;
        }
        else if(move == turnLeft)
        {
            vector.Y--;
        }
        else if(move == turnRight)
        {
            vector.Y++;
        }

        Nmodele->setRotation(irr::core::vector3df(vector.X, vector.Y, vector.Z));
        Nmodele->setPosition(v);
    }
}

Le personnage avance et tourne bien correctement (la caméra le suit parfaitement).
Où est le problème ? Il est étrange, quand je n'effectue pas de rotation, le personnage avance correctement (z pour devant, s pour derrière, q pour la gauche et d pour la droite). Dès que j'effectue une rotation, le déplacement est modifié (z provoque un déplacement différent de celui demandé, idem pour les 3 autres touches). Si je reviens "en position initiale" tout refonctionne.

Merci d'avance smile

PS: Pour les noms de fonctions, de classes... Si vous êtes perturbé c'est normal, le programme que je développe est une sorte de "prototype" juste pour voir de quoi est capable le moteur, du moins de quoi je suis capable de faire avec ce moteur donc sur le projet final les variables seront mieux nommées, les classes plus explicites...

Dernière modification par samsoft (11-06-2008 08:50:36)


Le savoir est un droit universel, libérez le code source !

Hors ligne


#1 

11-06-2008 09:51:52

dark calculator
Abonné
Date d'inscription: 25-02-2007
Messages: 153

Salut,
La réponse se trouve plus dans un cours de math qu'autre chose. En effet les vecteurs de positions et de rotation sont absolues. Donc quand tu augmente z augmente la profondeur de ton personnage par rapport à l'origine du repère, il ne tient pas conte de la rotation qui a été appliqué à ton model. C'est à dire que si tu tourne ton perso de 30° quand il va avancer se serat sur une droite qui fait 30° par rapport à l'axe des z et non sur l'axe des z.
C'est à dire qu'il te faut faire de la trigonométrie.
Tu dois faire quelque chose comme ca(a confirmer car je n'est jamais vraiment tester) :

Code:

        if(move == forward)
        {
            v.X += sin(vector.Y);
            v.Z += cos(vector.Y);
        }
        else if(move == backward)
        {
            v.X += sin(vector.Y + 180);
            v.Z += cos(vector.Y + 180);
        }
        else if(move == left)
        {
            v.X += sin(vector.Y + 90);
            v.Z += cos(vector.Y + 90);
        }
        else if(move == right)
        {
            v.X += sin(vector.Y - 90);
            v.Z += cos(vector.Y - 90);
        }
        else if(move == turnLeft)
        {
            vector.Y--;
        }
        else if(move == turnRight)
        {
            vector.Y++;
        }

J'ai supposé que les fonctions cos et sin marchait avec des deugré et que getrotation renvoyait aussi des deugrés si tel n'était pas le cas il faudrait modifier en conséquence les fonctions en remplacant 180 par pi et 90 par pi/2 et convertir les angles.

En espérant avoir aidé même si je suis pas sur de tout.

Dark calculator

Hors ligne


#2 

11-06-2008 10:34:34

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

N'ayant que 16 ans et programmant par passion, je ne pouvais pas prévoir (je n'y avais pas pensé) ce cas là.

Je vais voir cela, au pire je me fais une fonction qui transforme des radians (pourvu que ce ne soit pas des gradients) en degrés (j'ai programmé ca en basic sur ma calculette wink )

Merci, je test cela smile

EDIT: Ca ne fonctionne pas comme prévue, le résultat est le même qu'avec le code posté au premier message. Pour faire simple, j'ai supprimé left et right qui en réalité ne sont pas réalistes et gardé forward et backward:

Code:

        if(move == forward)
        {
            v.X += sin(vector.Y + 180);
            v.Z += cos(vector.Y + 180);
        }
        else if(move == backward)
        {
            v.X += sin(vector.Y - 180);
            v.Z += cos(vector.Y - 180);
        }
        else if(move == turnLeft)
        {
            vector.Y--;
        }
        else if(move == turnRight)
        {
            vector.Y++;
        }

PS:
Dans vector3d j'ai vu plusieurs fois degres.
J'ai testé avec 3.1415/2 aussi

Dernière modification par samsoft (11-06-2008 10:55:10)


Le savoir est un droit universel, libérez le code source !

Hors ligne


#3 

11-06-2008 11:47:37

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Il font quoi au lycée de nos jours ... big_smile
Si tu commences à toucher a la programmation orientée 3D il va obligatoirement te falloir les bases en mathematique de l'espace : vecteur et  trigonometrie et plus tard matrice.
Il y a 3 types de repere : le local , le global , et le repere parent , ce dernier tu peux l'oublier pour le moment.
Le global ne bouge pas , ne tourne pas ,il a toujour au centre du monde : (0,0,0) ( orientation non directe ).
Le Local tourne et bougge avec l'objet ( ici Nmodele ) il lui est accroché.
Donc quand tu tournes puis que tu avances  ( v.Z +=1.0f ) l'axe d'avancement est celui du repere global  alors qu'il faudrait que se soit celui du local afin de tenir compte de la rotation faite.
Le plus simple et si la node n'a qu'une seul rotation possible ,c'est d'utiliser la trigornometrie :

Code:

irr::core::vector3df rotation= Nmodele->getRotation();
irr::core::vector3df axe_z_local=irr::core::vector3df(ccos(rotation.Y),0,sin(rotation.Y));
axe_z_local.normalize();
 
if( move== forward ){
 Nmodele->setPosition(Nmodele->getPosition()+axe_z_local)

}

Dernière modification par firnafin (11-06-2008 12:02:38)

Hors ligne


#4 

11-06-2008 12:32:12

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

Je crois saisir votre concept de local, global. Mais même avec votre code, cela ne roule pas hmm

Code:

void CEventReceiver::majOfPos()
{
    if(Nmodele != 0 && isMoving == true)
    {
        irr::core::vector3df rot = Nmodele->getRotation();
        irr::core::vector3df axe_z_local = irr::core::vector3df(cos(rot.Y), 0, sin(rot.Y));
        axe_z_local.normalize();

        if(move == forward)
        {
            Nmodele->setPosition(Nmodele->getPosition()+axe_z_local);
        }
        else if(move == backward)
        {
            Nmodele->setPosition(Nmodele->getPosition()-axe_z_local);
        }
        else if(move == turnLeft)
        {
            rot.Y--;
        }
        else if(move == turnRight)
        {
            rot.Y++;
        }
        Nmodele->setRotation(irr::core::vector3df(rot.X, rot.Y, rot.Z));
    }
}

J'ai vérifie, c'est bien la variable Y qu'il faut modifier.

axe_z_local.normalize();


Veut il dire qu'on transforme les coordonnées en norme ?

Faut il uniquement utiliser le vecteur_z ?


PS: Au lycée ben moi j'ai vu vecteur... (2d et 3d pour coordonnées) là je suis en prem S mais pas de rotation (c'est en term) et puis l'arithémique/analyse (suite, fonction, proba) j'adore ca mais la géométrique (excepté l'analytique qui ressemble à la physique) j'aime pas smile

Dernière modification par samsoft (11-06-2008 12:33:29)


Le savoir est un droit universel, libérez le code source !

Hors ligne


#5 

11-06-2008 12:50:18

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Code:

axe_z_local=irr::core::vector3df( -sin(rot.Y),0,cos(rot.Y));

C'est un peu mieu , j'avais ecri le chagement pour l'axe X   hmm.
A part ca , ca devrait marcher.

Le

Code:

axe_z_local.normalize()

c'etait juste pour le normaliser mais c'est inutile , il est deja de norme 1.

samsoft :

Faut-il uniquement utiliser le vecteur_z ?


Bien si tu veux avancer seulement oui , si tu veux translater a droite ou a gauche il faut la meme chose avec le vecteur x .

Hors ligne


#6 

11-06-2008 12:58:21

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

C'est un peu mieu , j'avais ecri le chagement pour l'axe X   hmm.
A part ca , ca devrait marcher.


hmm Toujours pas :p

Code:

Bien si tu veux avancer seulement oui , si tu veux translater a droite ou a gauche il faut la meme chose avec le vecteur x .

C'est que je suis borné pour moi z est la profondeur, x en bas et y en haut mais en 3d tout change smile (tout tourne)
Ouai avancer et reculer, c'est uniquement ce dont j'ai besoin.

Voilà le code :

Code:

void CEventReceiver::majOfPos()
{
    if(Nmodele != 0 && isMoving == true)
    {
        irr::core::vector3df rot = Nmodele->getRotation();
        irr::core::vector3df axe_z_local = irr::core::vector3df(-sin(rot.Y), 0, cos(rot.Y));

        if(move == forward)
        {
            Nmodele->setPosition(Nmodele->getPosition()+axe_z_local);
        }
        else if(move == backward)
        {
            Nmodele->setPosition(Nmodele->getPosition()-axe_z_local);
        }
        else if(move == turnLeft)
        {
            rot.Y--;
        }
        else if(move == turnRight)
        {
            rot.Y++;
        }
        Nmodele->setRotation(irr::core::vector3df(rot.X, rot.Y, rot.Z));
    }
}

Si j'ai bien suivi, le problème se situe ici :

Code:

irr::core::vector3df axe_z_local = irr::core::vector3df(-sin(rot.Y), 0, cos(rot.Y));

Merci pour tout et d'avance,


Le savoir est un droit universel, libérez le code source !

Hors ligne


#7 

11-06-2008 18:22:07

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

i pi pi Hourra ! J'ai réussi grâce à vous (et à mon prof de proba) big_smile Alors comme je n'ai pas (encore) les connaissances pour parvenir de manière raisonnée à mon problème j'ai utilisé un arbre (c'est là que je dis thx à mon prof de maths) pour tester les différentes possibilités de :

Code:

irr::core::vector3df axe_z_local = irr::core::vector3df(cos(rot.Y*3.1415f/180.0f), 0, sin(rot.Y*3.1415f/180.0f));

J'ai dis que 1 = cos(rot.Y*3.1415f/180.0f) ; 2 = 0 et 3 = sin(rot.Y*3.1415f/180.0f);

A l'aide de mon arbre j'ai testé toutes les possibilités et j'ai trouvé que 3-2-1 était la plus probable.
Cependant, ça ne fonctionnait toujours pas alors je me suis souvenu du moins que vous aviez placé, j'ai pas compris (de manière mathématique) pourquoi mais de manière logique j'ai compris.
En effet, mon perso allez dans la diagonale "opposée" au déplacement voulu j'ai donc mis un moins à sin pour régler ce problème.

Résolu,

Encore merci smile

Code:

void CEventReceiver::majOfPos()
{
    if(Nmodele != 0 && isMoving == true)
    {
        irr::core::vector3df rot = Nmodele->getRotation();
        irr::core::vector3df axe_z_local = irr::core::vector3df(cos(rot.Y*3.1415f/180.0f), 0, -sin(rot.Y*3.1415f/180.0f));

        if(move == forward)
        {
            Nmodele->setPosition(Nmodele->getPosition()+axe_z_local);
        }
        else if(move == backward)
        {
            Nmodele->setPosition(Nmodele->getPosition()-axe_z_local);
        }
        else if(move == turnLeft)
        {
            rot.Y--;
        }
        else if(move == turnRight)
        {
            rot.Y++;
        }
        Nmodele->setRotation(irr::core::vector3df(rot.X, rot.Y, rot.Z));
    }
}

Dernière modification par samsoft (11-06-2008 18:23:54)


Le savoir est un droit universel, libérez le code source !

Hors ligne


#8 

11-06-2008 18:46:49

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

samsoft :

2 = 0


euh ... il  me semble que non ( je suis licencié de math pourtant  )  hmm

Hors ligne


#9 

11-06-2008 18:55:57

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

Ah non, je voulais dire:

Cas 1 = ...
Cas 2 = 0

lol big_smile


Le savoir est un droit universel, libérez le code source !

Hors ligne


#10 

12-06-2008 10:28:21

nikska
Membre
Lieu: Montpellier
Date d'inscription: 12-05-2008
Messages: 36

Pour ma part j'utilise cette methode :

Code:

irr::core::matrix4 Mat;

    if (m_Nmodele != 0 && m_isMoving == true)
    {
        //On commence par recuperer la position actuelle
        core::vector3df v = m_Nmodele->getPosition();
        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);


        }
    }

Hors ligne


#11 

12-06-2008 11:03:01

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

Ouai, j'ai entendu parler des matrices (comme méthode alternative), cependant, les matrices on les voit en premiere ES et moi je suis en S. De plus ma méthode est plus courte smile

Mais merci quand même, elle doit être meilleur wink


Le savoir est un droit universel, libérez le code source !

Hors ligne


#12 

12-06-2008 11:06:22

nikska
Membre
Lieu: Montpellier
Date d'inscription: 12-05-2008
Messages: 36

oui c'était surtout histoire de montrer une autre magnière de faire qui peut s'avérer très utile dans d'autre cas wink

Hors ligne


#13 

12-06-2008 13:14:33

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

les matrices on les voit en premier ES et moi je suis en S


Je ne sais pas d'ou tu sorts ca, les matrices sont abordées en bac +1 en général.De toute maniere si tu ne comptes pas apprendre par toi meme et attendre que "l'école" t'enseigne alors tu es mal barré.Les matrices c'est tres simple conceptuellement ,comprendre comment s'en servir aussi , la theorie est plus lourde mais en prog l'avantage c'est que la théorie on la met la ou je pense. Essaye de comprendre le code de nikska car la trigo c'est vraiment pour faire de la bidouille.

Hors ligne


#14 

12-06-2008 14:29:56

samsoft
Membre
Lieu: Moissy Cramayel (77550)
Date d'inscription: 10-06-2008
Messages: 14
Site web

Un ami en première ES m'a dit cela après moi je suis pas en première ES. En fait, après le bac français, je compte apprendre la 3D (matrices, vecteurs) du moins de manière simplifiée juste pour m'aider à régler les futurs problèmes éventuels.

tu es mal barré


Je fais cela par passion (sur mon temps libre), je compte devenir ingénieur informaticien ("catégorie": programmeur) donc en gros là je suis assez "en avance" après à "l'école" je vais tout réapprendre donc pas de soucis à ce niveau là smile

Je viens de trouver une "preuve" de l'apprentissage des matrices en ES :
http://yallouz.arie.free.fr/premiere_co … 6_2007.php
Après on parle peut  être pas de la même chose hmm

Dernière modification par samsoft (12-06-2008 14:30:42)


Le savoir est un droit universel, libérez le code source !

Hors ligne


#15 

12-06-2008 20:32:23

Aranoth
Abonné
Lieu: Toulouse
Date d'inscription: 25-09-2006
Messages: 242
Site web

Effectivement les "éco" voient les matrices en maths au lycée et pas les S
J'ai toujours trouvé ça stupide mais bon... avec les programmes de maths bien chargés qu'on avait au lycée, on va pas s'en plaindre.

Par contre je confirme aussi que tu es amené à revoir les matrices dans le supérieur wink

Hors ligne


#16 

12-06-2008 22:01:35

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

"A ouaih"  ... et en es en plus ..seulement depuis 2002 (j'ai raté ca , je suis trop vieux sad ) .Pas super pédagogique je trouve de voir les matrices ss parler d'espace vectoriel et tout le blabla de l'algebre linéaire ; on aura tout vu ... et dire que je vais devenir prof hmm

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
Analysé par
880 membres
1424 sujets
11113 messages
Dernier membre inscrit: mandrifidy
29 invités en ligne
Aucun membre connecté
RSS Feed