#0 

27-09-2010 18:24:32

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

Bonjour à tous,

Je voudrai déplacer mon node par rapport à la position du curseur, jusque là ça va, (surtout que je me suis un peu aidé d'un exemple) mais au niveau de la gestion des évènement de la souris je rame un peu (alors que pour les déplacement au clavier, pas de soucis hmm)

Je veux donc faire le truc classique : click droit maintenu + déplacement en X entraine le déplacement du node

J'ai donc essayé (entre autre!) de faire cela:

Code:

    
     if (event.EventType == EET_MOUSE_INPUT_EVENT)
        {
            if(event.MouseInput.Event== EMIE_RMOUSE_PRESSED_DOWN && event.MouseInput.X)
           { 
               poscur.X = event.MouseInput.X / sensibilite_souris;
            rotation = true;
            }
            

            else

                rotation = false;

            return true;

            
        }

ça ne fonctionne pas du tout comme je voudrai, en fait, lorsque je déplace ma souris en X+200 par exemple avec le bouton droit enfoncé, rien de se produit, c'est seulement lorsque je vais re-cliquer une fois que mon node va tourner d'un coup!
en gros: l'évènement de maintien du bouton droit n'a pas l'air d'être capté, j'ai du merdé dans le code ci dessus mais je ne vois pas où, surtout que j'ai testé beaucoup de possibilité (à l'aide de la doc pourtant...)

merci d'avance pour votre aide smile

Hors ligne


#1 

28-09-2010 02:45:15

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

Je pige pas tout mais ça doit être normal sinon tu ne serais pas ici. smile
Premièrement, le " && event.MouseInput.X" ne doit pas dons ton cas être considéré (casté) comme bool.
Je dirais même qu'il ne doit pas être utilisé pure car c'est la position X de la souris sur la fenêtre. cf:
http://irrlicht.sourceforge.net/docu/st … input.html
En fait tu devrais plus calculer le mouvement globale de la souris par frame, puis l'incrémenter à ta rotation actuelle.

Code c++ :


s32 LastPos; // globale de la position souris x frame précédente.

if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
    if(event.MouseInput.Event== EMIE_RMOUSE_PRESSED_DOWN)
    {
        if(rotation)
        {
            f32 Movement = (LastPos.X - event.MouseInput.X) / sensibilite;
            node->getRotation().X += Mouvement;
        }
        LastPos.X = event.MouseInput.X;
        rotation = true;
    }
    else
    rotation = false;
    return true;           
}

// y'a ptet des erreures ça fait un bye moi et irrlicht mais c'est le principe.

"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#2 

30-09-2010 17:04:10

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

merci pour ta réponse TUpac, j'ai compris ce que tu voulais faire

par contre ça ne marche pas vraiment, mais je me suis peut être planté quelque part, voici un bout de code:
(j'ai laissé le déplacement gauche au clavier pour exemple car ceci fonctionne très bien)

CEventReceiver.cpp

Code:

position2d<s32> cursor;

bool CEventReceiver::OnEvent(const irr::SEvent &event)
{
    

    ///////////////////// ROTATION JOUEUR ///////////////////

    
if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
    if(event.MouseInput.Event== EMIE_RMOUSE_PRESSED_DOWN)
    {

           cursor.X = event.MouseInput.X; 
        rotation = true;
    }
    else
    rotation = false;
    return true;           


//*******************GAUCHE (CLAVIER)**********************
    if(m_Nmodele != 0    
            
   && event.EventType == irr::EET_KEY_INPUT_EVENT

    && event.KeyInput.Key == irr::KEY_KEY_Q)    
    {
        
        if(event.KeyInput.PressedDown == true)
            gauche = true;


        else
            gauche = false;
      
        return true;
    }
}

.............................

void CEventReceiver::majPosMesh()// fonction de MAJ de la position du node
{

                f32 vitesse_deplacement = 1.f;
        f32 vitesse_rotation = 1.2f;


if(m_Nmodele != 0 && rotation == true)
    {
    
        position2d<f32> LastPos;
         

        irr::core::vector3df rotation = m_Nmodele->getRotation(); 

        f32 Movement = (LastPos.X - cursor.X) /sensibilite_souris;
        rotation.Y += Movement; 

         
            m_Nmodele->setRotation(rotation);
        
       LastPos.X = cursor.X;


if(m_Nmodele != 0 && gauche == true)
    {
       
        irr::core::vector3df r = m_Nmodele->getRotation();    
         r.Y -= vitesse_rotation;    
        m_Nmodele->setRotation(r);    

    }
.............................................
        
    
    }

et biensur j'ai mis dans ma boucle de rendu:

Code:

receiver.majPosMesh();

j'obtiens pas vraiment ce que je veux (mais y'a du mieux on va dire ^^)
en fait, plus de vais loin dans en X de mon curseur, plus mon node tourne vite
par exemple: si je me met mon curseur à 10 en X (quasiment tout à gauche de l'écran donc) et que je fait un clique droit, mon node va tourner lentement
ensuite si je déplace mon curseur à 20 en X, la rotation s'arrête mais si je re-clique, mon node va tourner de nouveau mais plus vite (et je ne vous raconte pas lorsque je met le curseur tout à droit de l'écran...c'est un coup à choper des convulsions :p)
le node ne tourne que dans un sens, mais ça c'est dû au fait que le X0 du curseur ne commence par au milieu de l'écran, il faudra que je créé un position2d<s32> avec le centre de l'écran comme référence (en faisant hauteur_écran / 2 et largeur_écran / 2 par exemple)

Dernière modification par magikus59 (30-09-2010 17:12:17)

Hors ligne


#3 

01-10-2010 20:30:15

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

Le problème est la:

Code c++ :


void CEventReceiver::majPosMesh()// fonction de MAJ de la position du node
{

                f32 vitesse_deplacement = 1.f; // la y'en a un autre
        f32 vitesse_rotation = 1.2f; // la aussi smile


if(m_Nmodele != 0 && rotation == true)
    {
   
        position2d<f32> LastPos; /* ICI */
         


Ton erreur c'est de créer tes variables dans la mise à jour. LastPos est ré-instanciée à chaque boucle avec la valeur 0. et " x - 0 = x " cqfd smile
Tu fais la même erreur (avec des conséquences différentes) sur vitesseDep et vitesseRot. Soit ils sont constants et c'est une perte de performances car tu crée & delete des variables. Le cas échéant tu devrais remplacer ces variables par des defines.
Si c'est amené à changer, c'est pareil que pour lastpos, il faut l'intégrer à la class ou ailleurs mais pas dans la fonction de mise à jour.

Code c++ :



#define vitesse_deplacement  1.f
#define vitesse_rotation  1.2f


position2d<s32> LastPos;
position2d<s32> cursor;

bool CEventReceiver::OnEvent(const irr::SEvent &event)
{
    ///////////////////// ROTATION JOUEUR ///////////////////

if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
    if(event.MouseInput.Event== EMIE_RMOUSE_PRESSED_DOWN)
    {

        cursor.X = event.MouseInput.X;
        rotation = true;
    }
    else
    rotation = false;
    return true;           

.............................

void CEventReceiver::majPosMesh()// fonction de MAJ de la position du node
{
    if(m_Nmodele != 0 && rotation == true)
    {
        irr::core::vector3df rotation = m_Nmodele->getRotation();
        f32 Movement = (LastPos.X - cursor.X) /sensibilite_souris;
        rotation.Y += Movement;
       m_Nmodele->setRotation(rotation);
       
       LastPos.X = cursor.X;


     if(m_Nmodele != 0 && gauche == true)
    {
       
        irr::core::vector3df r = m_Nmodele->getRotation();   
         r.Y -= vitesse_rotation;   
        m_Nmodele->setRotation(r);   

    }
.............................................
    }


Voilà ça devrait marcher mieu comme ça. wink


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#4 

02-10-2010 00:19:41

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

merci l'ami smile
une belle erreur de débutant (normal car comme tu as dû le remarquer, j'en suis un ^^) mais c'est en faisant ce genre de bêtise que l'on apprend, c'est cool

par contre, l'histoire du maintient du click + déplacement de la souris n'est pas résolu; maintenant, la rotation de mon node se met à jour uniquement lorsque je clique à nouveau sur le bouton droit (en gros, si je deplace mon curseur de gauche à droite et que je clique droit, mon node va faire une rotation en Y+, si je deplace mon curseur à doite......en Y-, ça ok, impec! le principe est là)
j'ai essayé différentes solutions pour palier à ce problème, comme un truc du genre:

Code:

 if (event.EventType == EET_MOUSE_INPUT_EVENT)
    {

    if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
    
    {
    if(event.MouseInput.Event== EMIE_RMOUSE_PRESSED_DOWN)
    {

        cursor.X = event.MouseInput.X;
        rotation = true;
    }
    else
    rotation = false;
    return true;           

}

}

mais c'est encore pire, je n'ai plus aucune rotation :p

peut être un piti problème dans le majPosMesh en fin de compte? je vais essayer de chercher encore ce week end

Hors ligne


#5 

02-10-2010 15:17:29

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

Y'a pas de soucis ça fait plaisir de transmettre son savoir car on l'a tous reçu de quelqu'un d'autre.
Je pense que tu saisis encore mal le concept d'event. Il serait judicieux de matter un ou deux tutos qui en parlent.
En fait à chaque boucle tu traite UN SEUL EVENT. Il s'appel "event" dans ton code et IL NE PEUT AVOIR DEUX VALEURS (EMIE_MOUSE_MOVED & EMIE_RMOUSE_PRESSED_DOWN).
Ton découpage est donc mauvais, il faut plus voir ça comme ça:

Code c++ :


bool OnEvent(SEvent &event)
{
    if(event.EventType == MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == MOUSE_MOVED)
        {
            if(rotation)
            {
                // Code de rotation
            }
            return true;
        }
        if(event.MouseInput.Event == MOUSE_PRESSED)
        {
            rotation = true;
            return true;
        }
        if(event.MouseInput.Event == MOUSE_RELEASED)
        {
            rotation = false;
            return true;
        }
    }
    return false;
}


Normalement on utilise des switch() mais des if c'est plus parlant. Donc a chaque OnEvent appelé par la souris, l'event sera soit moved soit pressed soit released. Mais pas deux à la fois. C'est ma faute j'aurais du le repérer en voyant ton code mais comme je l'ai dis, irrlicht n'est plus instinctif pour moi depuis trop longtemps wink


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#6 

02-10-2010 18:31:43

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

eh ben super, le déplacement souris + click fonctionne
tu as raison, je vais regarder des tutos sur les events

par contre j'ai un autre soucis que j'espère résoudre tout seul cette fois ci wink
si je déplace mon curseur de X200 à X400 par exemple, mon node va effectuer la rotation prévue, mais si je relâche le bouton et que je me déplace une nouvelle fois de X200 à X400 il va effectuer exactement la même plage de rotation (c'est pas évident à expliquer mais pour faire simple: imaginons que je met une sensibilité souris faible, je ne peux pas effectuer de rotation à 380°)
+ un problème quasiment lié à celui ci dessus, lorsque mon curseur est au bout de l'écran, plus de rotation (logique en fait), mais j'ai peut être une petite idée pour palier à ce problème, je testerai ça

du coup mon système de camera avance bien quand même, je filerai le code complet quand ce sera terminé bien entendu smile

Hors ligne


#7 

02-10-2010 19:47:24

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

En cas de clic tu doit mettre cursor.X = event.MouseInput.X; mais je pensais que c'était déjà le cas. Enfin je pense que tu as pigé tu trouvera vite en faisant des tests.


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#8 

03-10-2010 10:53:42

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

snif je pensai avoir tout compris mais ce n'est pas le cas apparement

Code:

bool OnEvent(SEvent &event)
{
    if(event.EventType == MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == MOUSE_MOVED)      // si il y a un mouvement de souris...
        {
            if(rotation)
            {
                // Code de rotation                    // -> ben normalement il ne se passe rien sans que je n'ai appuyé sur le bouton droit ^^
            }                                                  // j'avais donc mis cursor.X = event.MouseInput.X ici mais c'est peut être pour ça que mon node me fait toujours la même rotation
            return true;
        }
        if(event.MouseInput.Event == MOUSE_PRESSED)
        {
            rotation = true;
            return true;
        }
        if(event.MouseInput.Event == MOUSE_RELEASED)
        {
            rotation = false;
            return true;
        }
    }
    return false;
}

du coup je pensai qu'il fallait faire un truc du genre:

Code:

if(m_Nmodele != 0 && event.EventType == EET_MOUSE_INPUT_EVENT)
    {
       
    if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
        {
        
            if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
          {
            cursor.X = event.MouseInput.X;
            rotation = true;
            return true;
          }

        if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
          {
            rotation = false;
            return true;
          }
    }

}

mais ça ne marche pas non plus

j'ai regardé des tutos mais ça ne m'aide pas vraiment pour ce cas precis sad

Hors ligne


#9 

03-10-2010 12:23:46

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

bon finalement je vais y dir un mot ... hmm

il te fait utilise ton premiere code d'exemple, mais l'orsque tu clique il te faut récupéré la position initiale du curseur
et quand tu bouge une seconde position
l'orsque que vien le moment de passer la rotation au node il te faut rajouter la distance parcourue entre le point initial et le point final

il te faut donc faire quelque chose dans le genre:

Code c++ :


irr::core::line2df rotate;

bool OnEvent(SEvent &event)
{
    if(event.EventType == MOUSE_INPUT_EVENT)
    {
        if(event.MouseInput.Event == MOUSE_MOVED && rotation)
        {
            rotate.end = device->getCursorControl()->getPosition();
            float rotation = 0; // la tu récupère la rotation 'current'
               rotation += rotate.getLength();
            return true;
        }
        if(event.MouseInput.Event == MOUSE_PRESSED)
        {
            rotate.start = device->getCursorControl()->getPosition();
            rotation = true;
            return true;
        }
        if(event.MouseInput.Event == MOUSE_RELEASED)
        {
            rotation = false;
            return true;
        }
    }
    return false;
}



ps: pitié les variable pas en dehord du code ou d'une class, on perd l'utiliter de la poo !
ps2: il te faut aussi rajouter un petit algo pour que la rotation ne dépasse pas 360, sinon il pourrais y avoir un bug par raport a la valeur max du type de variable
quelque chose du genre: << rotation = rotate >= 360 ? rotate-(360*((int)(rotate/360))) : rotate; >>

Hors ligne


#10 

04-10-2010 00:34:55

magikus59
Membre
Date d'inscription: 23-08-2010
Messages: 31

un grand merci à vous 2 pour votre aide (et surtout pour votre patience ^^)

maintenant ça marche nickel

dans mon receiver

Code:

if(m_Nmodele != 0 && event.EventType == EET_MOUSE_INPUT_EVENT)
    {
       
        if(event.MouseInput.Event == EMIE_MOUSE_MOVED)  // en fait il ne fallait pas mettre && rotation sinon on a un gros bug lorsque l'on clique à nouveau (il prend une rotation bidon tant que l'on a pas bougé la souris)
        {
            
            cursor.X = event.MouseInput.X;
            
          
            return true;
        }
        if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
        {
            LastPos.X = event.MouseInput.X;
            rotation = true;
             device->getCursorControl ()-> setVisible (false); 
            return true;
        }
        
        if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
        {
            rotation = false;
             device->getCursorControl ()-> setVisible (true);
            return true;
        }
    
    return false;
}

et dans ma fonction de mise à jour:

Code:

    if(m_Nmodele != 0 && rotation == true)

    {
    
        irr::core::vector3df rotation = m_Nmodele->getRotation();
        Movement = (LastPos.X - cursor.X) /sensibilite_souris;
        rotation.Y -= Movement;
       m_Nmodele->setRotation(rotation);
     
     LastPos.X = cursor.X;
       
    }

lorsque j'aurai un peu + d'expérience je modifierai ce code pour dire que si on arrive en bout de course (bors de l'écran), on revient à 0, ça évitera d'être limité en rotation (mais là, je ne demande pas d'aide, je trouverai bien) pour le moment ça ira comme ça :p

en tout cas merci encore pour votre aide, avec tout ça je n'aurai pas trop de mal à faire bouger la camera en Y (c'est le même principe smile)

Hors ligne


#11 

04-10-2010 14:24:19

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

De rien content que ça avance et que tu file ton code pour les autres. Bonne continuation.


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

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