IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ODE Discussion :

Comprendre comment ca marche


Sujet :

ODE

  1. #1
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut Comprendre comment ca marche
    Salut

    Alors je me suis lancer dans ODE avec OpenGL (rien d'exceptionnel)
    Mais je truc j'ai lu la doc officielle (en anglais) le problème c'est que je comprend pas trop le système de collision.
    J'ai compris qui faut les deux monde l'un ou y'a les objet physique l'autre ou y'a les collisions.
    En suite je sais qu'il faut faire des joins lorsqu'on détecte une collision mais aprés ca ...
    J'ai regarde plein de code, mais jamais aucun que j'ai eu que j'ai essayer de modifier marcher convenablement.
    Je regarde une collision effectuer avec succes et aprés bien rien. Ou alors collision mais complètement irréel.
    Enfin voila quoi j'aurais besoin d'un vrai bon tutorial de base en francais si possible (parce que s'arracher les yeux avec l'anglais j'en ai mar :p ).

    merci d'avance
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  2. #2
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut
    Bon je commence a comprendre un peu plus comment on fait.
    Enfin surtout j'ai des chose un peu plus réaliste.

    Donc on dois crée un groupe de contacte jusqu'a présent je le fesais pas vraiement vu que sur ce forum on le fait jamais et puis dans le nearcallback il faut crée des contactes temporaires. avec les paramètres qu'on veut.
    Ensuite on lance la simulation et puis enfin on vide le groupes.
    Bon j'ai encore des problèmes de réalisme genre le cube qui saute d'un coup tout seul ....

    Ma fonction callback
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    void nearCallback (void *data, dGeomID o1, dGeomID o2)
    {
      const int N = 32;
      dContact contact[N];
      int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact));
      if (n > 0)
      {
        for (int i=0; i<n; i++)
        {
          contact[i].surface.mu = 5000; // was: dInfinity
          contact[i].surface.bounce = 0.02;
          dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
          dJointAttach (c,dGeomGetBody(contact[i].geom.g1),dGeomGetBody(contact[i].geom.g2));
        }
      }
    }
    le bou de code pour faire les simulations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      /// on fais les changements ODE
            dSpaceCollide(space,contactgroup,&nearCallback); // teste les collisions entre les objets
            dWorldQuickStep(world,0.01);       // a chaque frame, calcule la nouvelle position des objets
            dJointGroupEmpty (contactgroup);//on detruit les contacts temporaires
    et puis bien sur en globals il faut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static dJointGroupID contactgroup = dJointGroupCreate (0);
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  3. #3
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut Petit problème
    Alors j'ai réussi a faire marche tous correctement enfin presque.
    J'ai un petit problème c'est que l'application plante a un moment souvant le même mais je sais pas trop pourquoi.
    Je pense que c'est a cause du nombres de collisions.
    Donc est-ce que ce nombre et limité ? ou le nombre de liaisons est limité ?
    Je vous mets le code.

    Les variables globals :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    //Variable pour la fenêtre
    int L = 640;
    int H = 480;
    ///
     
     
    static dWorldID world; // notre monde
    static dSpaceID space; // l'espace
     
    //groupe de contact temporaire pour les collisions
    static dJointGroupID contactgroup = dJointGroupCreate (0);
    ///

    Le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
     
    int main (int argc,char *argv[])
    {
    	bool continuer = true;
    	SDL_Event evenement;//pour la gestion des evenements
     
    	//initialisation de ODE
    	world = dWorldCreate();
    	space = dHashSpaceCreate(0);
    	dWorldSetGravity (world,0,0,-9.81);
    	dWorldSetERP(world,(dReal)0.8);
    	dWorldSetCFM(world,(dReal)1E-5);
    	///
     
    	//initialisation des objets ODE
    	dBodyID bodyCube = dBodyCreate(world);//création de l'objet
    	dMass matricePoid;
    	dMassSetBoxTotal(&matricePoid, (dReal)10 , (dReal)2 ,(dReal)2,(dReal)2);//initialisation de la matrice
    	dBodySetMass(bodyCube ,&matricePoid);//application de la matrice poid
    	dBodySetPosition(bodyCube,5,2,3);
     
    	dGeomID geomCube = dCreateBox (space,(dReal)2,(dReal)2,(dReal)2);//création de l'objet pour les collisions
    	dGeomSetBody (geomCube,bodyCube);//liaison de l'objet physique et de collision
     
    	dCreatePlane ( space , 0 , 0 , 1 , 0);
    	dCreatePlane ( space , 1 , 0 , 1 , -50);
    	dCreatePlane ( space , -1 , 0 , 1 , -50);
    	dCreatePlane ( space , 0 , 1 , 1 , -50);
    	dCreatePlane ( space , 0 , -1 , 1 , -50);
     
    	std::vector<dBodyID> cubes;//Cube à dessiner
    	std::vector<dGeomID> cubesGeom;//Cube à dessiner
    	int nombre_de_cube = 0;
    	///
     
    	//initialisation de la SDL
    	SDL_Init(SDL_INIT_VIDEO);
    	SDL_WM_SetCaption("OpenGL with ODE",NULL);
        SDL_SetVideoMode(L, H, 32, SDL_OPENGL);
    	SDL_ShowCursor(0); // on cache le cursor
    	///
     
    	//inistialisation de OpenGL
    	glMatrixMode( GL_PROJECTION );
    	glLoadIdentity( );
    	gluPerspective(70,(double)L/H,1,1000);
    	glEnable(GL_DEPTH_TEST);
    	///
     
    	//Gestion du temps
    	Uint32 last_time = SDL_GetTicks();
        Uint32 current_time,ellapsed_time;
        Uint32 start_time;
    	///
     
    	while (continuer)
    	{
    		start_time = SDL_GetTicks();
     
    		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // mise a jour d'opengl
    		SDL_PollEvent(&evenement);
    		if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_F9)
    			continuer = false;
     
    		glMatrixMode( GL_MODELVIEW );
    		glLoadIdentity( );
     
        	if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_LEFT)
        		dBodyAddForce (bodyCube,0,10,0);
    		if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_UP)
        		dBodyAddForce (bodyCube,10,0,0);
    		if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_RIGHT)
        		dBodyAddForce (bodyCube,0,-10,0);
    		if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_DOWN)
        		dBodyAddForce (bodyCube,-10,0,0);
    		if(evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_SPACE)
        		dBodyAddForce (bodyCube,0,0,10);
    		if(nombre_de_cube < 500 && evenement.type == SDL_MOUSEBUTTONDOWN && evenement.button.button == SDL_BUTTON_LEFT)
    		{
    			//ajoute un cube
    			cubes.push_back( dBodyCreate(world));//création de l'objet
    			dBodySetMass(cubes[nombre_de_cube] ,&matricePoid);//application de la matrice poid
    			dBodySetPosition(cubes[nombre_de_cube],0,nombre_de_cube%6 * 2,((int)nombre_de_cube/6)*2);
    			cubesGeom.push_back(dCreateBox (space,(dReal)2,(dReal)2,(dReal)2));
    			dGeomSetBody (cubesGeom[nombre_de_cube],cubes[nombre_de_cube]);//liaison de l'objet physique et de collision
    			++nombre_de_cube;
    		}
        	if(nombre_de_cube > 0 && evenement.type == SDL_MOUSEBUTTONDOWN && evenement.button.button == SDL_BUTTON_RIGHT)
        	{
    			//suprime le dernier cube
    			--nombre_de_cube;
    			dGeomDestroy(cubesGeom[nombre_de_cube]);
    			dBodyDestroy(cubes[nombre_de_cube]);
     
    			cubesGeom.pop_back();
    			cubes.pop_back();
    		}
    		if( evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_F1)
    		{
    			//Explosion
    			int i = 0;
    			while ( i < nombre_de_cube)
    			{
    				dReal d = sqrt(dBodyGetPosition(cubes[i])[0] * dBodyGetPosition(cubes[i])[0] + dBodyGetPosition(cubes[i])[1] * dBodyGetPosition(cubes[i])[1] + dBodyGetPosition(cubes[i])[2] * dBodyGetPosition(cubes[i])[2]);
    				dReal a = 40000*(1.0-0.2*d*d);
    				if (a<0)
    					a=0;
    				dBodySetForce(cubes[i],	dBodyGetPosition(cubes[i])[0]*a ,dBodyGetPosition(cubes[i])[1]*a ,dBodyGetPosition(cubes[i])[2]*a);
    				++i;
    			}
    		}
    		if( evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_F2)
    		{
    			//implosion
    			int i = 0;
    			while ( i < nombre_de_cube)
    			{
    				dReal x,y,z;
    					x = dBodyGetPosition(cubes[i])[0]*-100;
    					y = dBodyGetPosition(cubes[i])[1]*-100;
    					z =dBodyGetPosition(cubes[i])[2]*-100;;
    				dBodySetForce(cubes[i],x,y,z );
    				++i;
    			}
    		}
     
        	//caméra
    		gluLookAt(	0,50,50,//possition
    					(float)dBodyGetPosition(bodyCube)[0],(float)dBodyGetPosition(bodyCube)[1],(float)dBodyGetPosition(bodyCube)[2],//cible
    					0,0,1);//vecteur vertical
     
    		dSpaceCollide(space,contactgroup,&nearCallback); // teste les collisions entre les objets
    		dWorldQuickStep(world, 0.1f);//lancement de la simulation
    		dJointGroupEmpty (contactgroup);	
     
    		dessinePlan();
    		dessineCube(bodyCube);
     
    		int i = 0;
    		while ( i < nombre_de_cube)
    			dessineCube(cubes[i++]);
     
     
    		glFlush();
    		SDL_GL_SwapBuffers();
    		ellapsed_time = SDL_GetTicks() - start_time;
            if (ellapsed_time < 10)
                SDL_Delay(10 - ellapsed_time);
     
    	}
     
    	//on détruit les éléments de ODE
    	dSpaceDestroy (space);
        dWorldDestroy (world);
        dCloseODE(); // on ferme ODE
        ///
     
    	return EXIT_SUCCESS;
    }
    La fonctions callback pour les collisions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
    void nearCallback (void *data, dGeomID o1, dGeomID o2)
    {
    	const int N = 32;
    	dContact contact[N];
    	dReal n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact));
    	if (n > 0)
    	{
    		for (int i=0; i<n; i++)
    		{
    			// CFM activé en soft (rendre la surface molle) et bounce activé (rendre la surface rebondissante)
    			contact[i].surface.mode = dContactBounce | dContactSoftCFM;
    			// Mettre le coefficient de friction à infinity ( 0 : surface sans friction, dInfinity : le maximum de friction ou 50)
    			contact[i].surface.mu = 20;
    			// Optionnel au cas où mu marche pas, s'applique sur la direction 2
    			contact[i].surface.mu2 = 0;
    			// Valeur de rebond (avec pour max = 1, min = 0)
    			contact[i].surface.bounce = 0.2;
    			// Vélocité minimal de l'objet entrant en contact pour qu'il y ai rebond
    			contact[i].surface.bounce_vel = 1;
    			// Douceur de la surface
    			contact[i].surface.soft_cfm = 0.01;
    			dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
    			dJointAttach (c,dGeomGetBody(contact[i].geom.g1),dGeomGetBody(contact[i].geom.g2));
    		}
    	}
    }
    Le changement de matrice pour dessiner de ODE a OpenGL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    void LDEsetM(const dReal *pos,const dReal *R)
    {
        float local_matrix[16];
        local_matrix[0]     =     R[0];
        local_matrix[1]     =     R[4];
        local_matrix[2]     =     R[8];
        local_matrix[3]     =     0;
        local_matrix[4]     =     R[1];
        local_matrix[5]     =     R[5];
        local_matrix[6]     =     R[9];
        local_matrix[7]     =     0;
        local_matrix[8]     =     R[2];
        local_matrix[9]     =     R[6];
        local_matrix[10]    =     R[10];
        local_matrix[11]    =     0;
        local_matrix[12]    =     pos[0];
        local_matrix[13]    =     pos[1];
        local_matrix[14]    =     pos[2];
        local_matrix[15]    =     1;
        glMultMatrixf(local_matrix);
    }
    Dessin du cube
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    void dessineCube(dBodyID cube)
    {
    	glPushMatrix();
    	LDEsetM(dBodyGetPosition(cube),dBodyGetRotation(cube));
    	glBegin(GL_QUADS);
    		glColor3ub(255,0,0); //face rouge
    		glVertex3d(1,1,1);
    	    glVertex3d(1,1,-1);
    	    glVertex3d(-1,1,-1);
    	    glVertex3d(-1,1,1);
     
       		glColor3ub(0,255,0); //face verte
    		glVertex3d(1,-1,1);
    		glVertex3d(1,-1,-1);
    		glVertex3d(1,1,-1);
    		glVertex3d(1,1,1);
     
    		glColor3ub(0,0,255); //face bleue
    		glVertex3d(-1,-1,1);
    		glVertex3d(-1,-1,-1);
    		glVertex3d(1,-1,-1);
    		glVertex3d(1,-1,1);
     
    		glColor3ub(255,255,0); //face jaune
    		glVertex3d(-1,1,1);
    		glVertex3d(-1,1,-1);
    		glVertex3d(-1,-1,-1);
    		glVertex3d(-1,-1,1);
     
    		glColor3ub(0,255,255); //face cyan
    		glVertex3d(1,1,-1);
    		glVertex3d(1,-1,-1);
    		glVertex3d(-1,-1,-1);
    		glVertex3d(-1,1,-1);
     
    		glColor3ub(255,0,255); //face magenta
    		glVertex3d(1,-1,1);
    		glVertex3d(1,1,1);
    		glVertex3d(-1,1,1);
    		glVertex3d(-1,-1,1);
    	glEnd();
    	glPopMatrix();
    }
    Dessin des plan
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    void dessinePlan()
    {
    	glBegin(GL_QUADS);
    	//sol
    		glColor3ub(255,255,255); //blanc
    		glVertex3d(50,50,0);
    	    glVertex3d(50,-50,0);
    	    glVertex3d(-50,-50,0);
    	    glVertex3d(-50,50,0);
    	//murs
    		glColor3ub(200,200,200); //gris
    		glVertex3d(-100,100,50);
    	    glVertex3d(0,0,-50);
    	    glVertex3d(0,0,-50);
    	    glVertex3d(-100,-100,50);
     
    		glColor3ub(200,200,200); //gris
    		glVertex3d(100,100,50);
    	    glVertex3d(0,100,-50);
    	    glVertex3d(0,-100,-50);
    	    glVertex3d(100,-100,50);
     
    		glColor3ub(100,100,100); //gris
    		glVertex3d(100,100,50);
    	    glVertex3d(50,50,0);
    	    glVertex3d(-50,50,0);
    	    glVertex3d(-100,100,50);
     
    		glColor3ub(100,100,100); //gris
    		glVertex3d(100,-100,50);
    	    glVertex3d(50,-50,0);
    	    glVertex3d(-50,-50,0);
    	    glVertex3d(-100,-100,50);
    	glEnd();
    }
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  4. #4
    Rédacteur
    Avatar de bafman
    Profil pro
    Développeur informatique
    Inscrit en
    novembre 2003
    Messages
    2 574
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : novembre 2003
    Messages : 2 574
    Points : 5 306
    Points
    5 306
    Par défaut
    effectivement, sous windows, si tu a un trop drang nombre de collision, tu peut avoir un stack overflow. dans la faq d'ODE, ils expliquent comment reduire le probleme.
    * Il est infiniment plus simple de faire rapidement un code qui marche que de faire un code rapide qui marche
    * pour faciliter les recherches, n'oubliez pas de voter pour les réponses pertinentes
    Mes articles

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [RegEx] Problème simple pour comprendre comment marche les regex
    Par Fabious dans le forum Langage
    Réponses: 3
    Dernier message: 11/05/2011, 14h39
  2. Comprendre comment marche 'conv2'
    Par hollowdeadoss dans le forum MATLAB
    Réponses: 1
    Dernier message: 06/05/2009, 17h55
  3. [SYNEDIT] -> Comment ça marche ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 20h11
  4. [TP][Turbo Vision] comment ça marche ??
    Par Costello dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 05/08/2003, 01h24
  5. [update][req. imbriquee] Comment ca marche ??
    Par terziann dans le forum Langage SQL
    Réponses: 3
    Dernier message: 11/07/2003, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo