Bonjour à tous,
Je vous propose avec retard, les étapes a suivre, pour réussir à utiliser
Open Dyanmics Engine, en C++, qui au début parait un peu dur pour certains.
Le site officiel est: http://www.ode.org/
Pour le télécharger directement:
http://prdownloads.sourceforge.net/o...6.zip?download
Compilateurs compatible: Tous C/C++. (moi j'utilise Code::Blocks)
Un petit screen:
Alors on commence par déclarer quelques trucs.
Puis on déclare 2 objets, un cube et une sphère, ou chaque objet a un body(corp) et un geom(géométrie?).
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 static dWorldID world; // notre monde static dSpaceID space; // l'espace static dGeomID sol; // pour créer un sol infini static dJointGroupID contactgroup; GLUquadricObj *sphere; // une sphère grâce a GLU int stop = 0, h = 640, l = 480, LDEmouse_x = 0, // la position X du cursor sur l'ecran en pixels LDEmouse_y = 0, // la position Y du cursor sur l'ecran en pixels LDEmouse_X = 0, // la force sur l'axe X du mouse LDEmouse_Y = 0; // la force sur l'axe Y du mouse SDL_Event evenement; float cam_rx = 0, cam_ry = 32;
Alors pour la fonction nearCallback, qui vas etre appelée par la fonction dSpaceCollide(), il suffit de prendre exemple sur les sources présentes
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 dBodyID body_cube, body_sphere; dGeomID geom_cube, geom_speher;
dans le dossier TEST de ODE, pour copier.
Une grille
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 static void nearCallback(void *data, dGeomID o1, dGeomID o2) { int i; // exit without doing anything if the two bodies are connected by a joint dBodyID b1 = dGeomGetBody(o1); dBodyID b2 = dGeomGetBody(o2); if (b1 && b2 && dAreConnected (b1,b2)) return; dContact contact[3]; // up to 3 contacts per box for (i=0; i<3; i++) { contact[i].surface.mode = dContactSoftCFM | dContactApprox1; contact[i].surface.mu = 30; contact[i].surface.soft_cfm = 0.2; } if ( !dGeomGetBody(o1) & !dGeomGetBody(o2)); else if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { for (i=0; i<numc; i++) { dJointID c = dJointCreateContact (world,contactgroup,contact+i); dJointAttach (c,b1,b2); } } }
On dessine notre 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 void grille(float g,float l,/*double *axes_color,double *grid_color*/) { glPushMatrix(); glScalef(l,l,l); // début du dessin de la grille glLineWidth(2); glBegin(GL_LINES); //glColor3dv(axes_color); glVertex3f(g,0,0); glVertex3f(-g,0,0); glVertex3f(0,0,g); glVertex3f(0,0,-g); glEnd(); glLineWidth(1); glBegin(GL_LINES); for (int i = 1; i <= g; ++i) { //glColor3dv(grid_color); //les lignes sur l'axe X glVertex3f(-g,0, i); glVertex3f( g,0, i); glVertex3f(-g,0,-i); glVertex3f( g,0,-i); //les lignes sur l'axe Z glVertex3f(-i,0, g); glVertex3f(-i,0,-g); glVertex3f( i,0, g); glVertex3f( i,0,-g); } glEnd(); glPopMatrix(); glColor3d(1,1,1); }
Puis on auras besoin d'une petite fonction pour transformer notre matrice d'ODE en Matrice OpenGL, pour pouvoir bouger les objets.
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 void glCube(float x,float y,float z) { glPushMatrix(); glScalef(x/2,y/2,z/2); glBegin (GL_QUADS); //face 1 glNormal3i(-1, 1,-1); glTexCoord2i(0,1); glVertex3i(-1, 1,-1); glNormal3i( 1, 1,-1); glTexCoord2i(1,1); glVertex3i( 1, 1,-1); glNormal3i( 1,-1,-1); glTexCoord2i(1,0); glVertex3i( 1,-1,-1); glNormal3i(-1,-1,-1); glTexCoord2i(0,0); glVertex3i(-1,-1,-1); //face 2 glNormal3i(-1,-1,-1); glTexCoord2i(0,1); glVertex3i(-1,-1,-1); glNormal3i( 1,-1,-1); glTexCoord2i(1,1); glVertex3i( 1,-1,-1); glNormal3i( 1,-1, 1); glTexCoord2i(1,0); glVertex3i( 1,-1, 1); glNormal3i(-1,-1, 1); glTexCoord2i(0,0); glVertex3i(-1,-1, 1); // face 3 glNormal3i( 1,-1, 1); glTexCoord2i(0,1); glVertex3i( 1,-1, 1); glNormal3i( 1,-1,-1); glTexCoord2i(1,1); glVertex3i( 1,-1,-1); glNormal3i( 1, 1,-1); glTexCoord2i(1,0); glVertex3i( 1, 1,-1); glNormal3i( 1, 1, 1); glTexCoord2i(0,0); glVertex3i( 1, 1, 1); //face 4 glNormal3i( 1, 1,-1); glTexCoord2i(0,1); glVertex3i( 1, 1,-1); glNormal3i(-1, 1,-1); glTexCoord2i(1,1); glVertex3i(-1, 1,-1); glNormal3i(-1, 1, 1); glTexCoord2i(1,0); glVertex3i(-1, 1, 1); glNormal3i( 1, 1, 1); glTexCoord2i(0,0); glVertex3i( 1, 1, 1); //face 5 glNormal3i(-1, 1, 1); glTexCoord2i(0,1); glVertex3i(-1, 1, 1); glNormal3i(-1, 1,-1); glTexCoord2i(1,1); glVertex3i(-1, 1,-1); glNormal3i(-1,-1,-1); glTexCoord2i(1,0); glVertex3i(-1,-1,-1); glNormal3i(-1,-1, 1); glTexCoord2i(0,0); glVertex3i(-1,-1, 1); //face 6 glNormal3i( 1,-1, 1); glTexCoord2i(0,1); glVertex3i( 1,-1, 1); glNormal3i( 1, 1, 1); glTexCoord2i(1,1); glVertex3i( 1, 1, 1); glNormal3i(-1, 1, 1); glTexCoord2i(1,0); glVertex3i(-1, 1, 1); glNormal3i(-1,-1, 1); glTexCoord2i(0,0); glVertex3i(-1,-1, 1); glEnd(); glPopMatrix(); }
Ici, on vas initialiser ODE, OpenGL et notre fenêtre grâce a SDL.
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) { LDEfloat 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); }
Ici on rentre dans la boucle de notre application.
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 int main(int argc,char *argv[]) { SDL_SetVideoMode(h,l,32,SDL_OPENGL |SDL_FULLSCREEN ); // on init SDL SDL_ShowCursor(0); // on cache le cursor sphere = gluNewQuadric(); // on initialise la sphere glu /// Some OpenGL settings GLfloat lumiere_couleur[] = {1,1,1,1}; // on indique la couleur glMaterialfv(GL_FRONT,GL_SHININESS,lumiere_couleur); // on set la couleur glEnable(GL_LIGHT0); // on active la lumiere 0 d'OpenGL glEnable(GL_LIGHTING); glClearColor(0.7,0.7,0.7,0); // la couleur du fond d'écran glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); /// /// on vas initialiser ODE world = dWorldCreate(); // on crée le monde space = dHashSpaceCreate(0); // et on crée l'espace dWorldSetGravity (world,0,-0.2,0); // on indique la gravité /// /// on vas créer nos onjets ODE (le cube ,la sphere) et le sol. sol = dCreatePlane (space,0,1,0,0); // on crée le sol dMass m; // le cube dMassSetBox (&m,1,1,1,1); dMassAdjust(&m,0.2); // on indique la ca masse body_cube = dBodyCreate(world); // on crée le cube dans notre monde dBodySetMass(body_cube,&m); // geom_cube = dCreateBox(space,1,1,1); // on crée la géométrie dGeomSetBody(geom_cube,body_cube); // on atache la geometrie au corp dGeomSetPosition(geom_cube,0,4,0); // on indique sa position // // la sphere dMassSetSphere(&m,1,1); dMassAdjust(&m,1); body_sphere = dBodyCreate(world); dBodySetMass(body_sphere,&m); geom_sphere = dCreateSphere(space,1); dGeomSetBody(geom_sphere,body_sphere); dBodySetPosition(body_sphere,4,5,0); // ///
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 /// boucle /// while(!stop) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // refresh opengl /// les controls SDL SDL_PollEvent(&evenement); SDL_GetMouseState(&LDEmouse_x,&LDEmouse_y); SDL_GetRelativeMouseState(&LDEmouse_X,&LDEmouse_Y); if ( evenement.type == SDL_KEYDOWN && evenement.key.keysym.sym == SDLK_F9 ) stop = 1; /// /// on arrange le contexte OpenGL glViewport(0,0,h,l); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,(float)h/(float)l,0.1,4000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /// /// on fais les changements ODE dSpaceCollide(space,0,&nearCallback); // teste les collisions entre les objets dWorldQuickStep(world,0.01); // a chaque frame, calcule la nouvelle position des objets /// /// camera glTranslatef(0,0,-5); glRotatef(cam_rx,1,0,0); glRotatef(cam_ry,0,1,0); glTranslatef(-dGeomGetPosition(geom_cube)[0], -dGeomGetPosition(geom_cube)[1], -dGeomGetPosition(geom_cube)[2]); // if ( evenement.type == SDL_MOUSEBUTTONDOWN && evenement.button.button == SDL_BUTTON_LEFT ) { cam_rx += (float)LDEmouse_Y/2; cam_ry += (float)LDEmouse_X/2; } /// glColor3d(1,0,0); glDisable(GL_LIGHTING); grille(20,2); // le sol glEnable(GL_LIGHTING); /// on affiche notre cube & sphere // le cube glPushMatrix(); glColor3d(1,0.5,5); LDEsetM(dBodyGetPosition(body_cube),dBodyGetRotation(body_cube)); glCube(1,1,1); glPopMatrix(); // //sphere glPushMatrix(); LDEsetM(dBodyGetPosition(body_sphere),dBodyGetRotation(body_sphere)); gluSphere(sphere,1,15,10); glPopMatrix(); /// SDL_GL_SwapBuffers(); // Swap Buffers }
Puis enfin après avoir sorti de la boucle ( avec la touche F9 ), on détruit le monde et l'espace ODE.
Voici le code compilé, et le source code c++ (EXE+DLLs+source_code):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); // on ferme ODE }
http://rapidshare.de/files/26204011/...dlls_.rar.html
Il faut toujours chercher dans la DOC si vous avez un problème:
http://www.ode.org/ode-latest-userguide.html
Maintenant que vous avez vu plus ou moins comment ODE fonctionne, il vous reste a vous rendre dans le dossier TEST d'ODE,
et regarder les exemples.
Je vais essayer d'ici quelques jours, mettre un exemple de voiture.
edit: Ca fait bien longtemps que je devrait mettre un example de voiture,
mais je suis passé le jour même a une autre lib physique, donc je n'ai pas pu.
Donc, voici un lien ou j'avait mis le code avant de créer ce poste, donc désolé si ca fait pub, il n'y a pas de commentaires sur le code, et c'est en anglais, pour ceux que ca interesse: lien
@+![]()
Partager