ODE仿真引擎使用(四)
简要介绍3D部分,例如Drawstuff库。ODE的demo程序中展示了很好看的外观,美丽的挂着云彩的天空和网格划分的地面。Drawstuff只是一个非常简单的3D绘图库,它并不适用于一些商用游戏,但对于你的工作的仿真器它足够了。Drawstuff可以用Ogre3D和Irrlicht替换。Drawstuff应用于OpenGL 3D绘图库,Drawstuff是一个非常简单的库,因此它是有用的对于学习OpenGL。Drawstuff的APIs的首字母缩写为“ds”。
Using Drawstuff
1、包含头文件以使用Drawstuff库。
#include <drawstuff/drawstuff.h>
2、设置
为了使用Drawstuff,dsFunctions的每一个成员都必须被设置。
// dsFunctions结构的定义 typedef struct dsFunctions { int version; /* set DS_VERSION */ void (*start)(); /* 在仿真前的start function */ void (*step) (int pause); /* step function */ void (*command) (int cmd); /* 接受键盘的命令command function */ void (*stop)(); /* 仿真结束后的stop function */ const char *path_to_textures;/* texture的路径 */ } dsFunctions;
1)Version: DS_VERSION must be assigned
··fn.version = DS_VERSION
2)Pre-processing functions: the simulation will be called before the start of the simulation loop. Here, the camera viewpoint and gaze direction are set.
··fn.start = &start;
3)Viewpoint of the camera, eyes
··dsSetViewpoint (point of view, the gaze direction);
4)Simulation Loop function: the simLoop function is called in each loop of the Simulation. The function do almost every thing in the simulation, such as compute dynamics, collision detection, and visualization.
··fn.step = &simLoop;
5)Key processing function: the command function is called when a key pressed. If you do not need this function. NULL (null pointer) or 0 (zero) must be assignment to it.
··fn.command = &command; // NULL or 0 (when you do not need)
6)Post-processing function: the function is called after the simulation loop. If you do not need it, set the NULL pointer.
··fn.stop = &stop; // NULL (when you do not need)
7)Texture path
··fn.path_to_textures = “path”;
3、仿真循环
The following API must be called only once in the main function.
dsSimulationLoop (argc, argv, witdh, height, & fn);
··argc, argv: main function arguments
··width: The width of the window
··height: The height of the window
··fn: dsFunctions is a structure for Drawstuff
1 /* 3D Graphics */ 2 #include "ode/ode.h" 3 #include "drawstuff/drawstuff.h" 4 #ifdef _MSC_VER 5 #pragma warning(disable:4244 4305) // Stop VC++ warnings 6 #endif 7 #ifdef dDOUBLE 8 #define dsDrawBox dsDrawBoxD 9 #define dsDrawSphere dsDrawSphereD 10 #define dsDrawCylinder dsDrawCylinderD 11 #define dsDrawCapsule dsDrawCapsuleD 12 #define dsDrawLine dsDrawLineD 13 #endif 14 15 #define DENSITY (5.0) 16 17 struct MyObject { 18 dBodyID body; // a rigid body 19 }; 20 21 dReal radius = 0.25; // radius 22 dReal length = 1.0; // length 23 dReal sides[3] = {0.5,0.5,1.0}; // length of edges 24 static dWorldID world; // a dynamic world 25 static MyObject sphere, box, capsule, cylinder; // objects 26 27 // start simulation 28 static void start() 29 { 30 static float xyz[3] = {5,3,0.5}; // view point [m] 31 static float hpr[3] = {-180, 0, 0}; // view direction[°] 32 dsSetViewpoint (xyz,hpr); // set a view point and direction 33 } 34 35 // Simulation loop 36 static void simLoop (int pause) 37 { 38 const dReal *pos1,*R1,*pos2,*R2,*pos3,*R3; // draw a sphere 39 dsSetColor(1,0,0); // set red color 40 dsSetSphereQuality(3); // set quality of spere. 3 is pretty good 41 pos1 = dBodyGetPosition(sphere.body); // get a position 42 R1 = dBodyGetRotation(sphere.body); // get an orientation 43 dsDrawSphere(pos1,R1,radius); // draw a sphere 44 45 // draw a cylinder 46 dsSetColorAlpha (0,1,0,1); 47 pos2 = dBodyGetPosition(cylinder.body); 48 R2 = dBodyGetRotation(cylinder.body); 49 dsDrawCylinder(pos2,R2,length,radius); 50 // draw an capsule dsSetColorAlpha (1,1,1,1); 51 pos2 = dBodyGetPosition(capsule.body); 52 R2 = dBodyGetRotation(capsule.body); 53 dsDrawCapsule(pos2,R2,length,radius); 54 55 // draw a box 56 dsSetColorAlpha (0,0,1,1); 57 pos3 = dBodyGetPosition(box.body); 58 R3 = dBodyGetRotation(box.body); 59 dsDrawBox(pos3,R3,sides); // draw a line 60 dReal posA[3] = {0, 5, 0}, posB[3]={0, 5, 1.9}; 61 dsDrawLine(posA,posB); 62 } 63 64 int main (int argc, char **argv) 65 { 66 // set drawstuff 67 dsFunctions fn; 68 fn.version = DS_VERSION; 69 fn.start = &start; 70 fn.step = &simLoop; 71 fn.command = NULL; 72 fn.stop = NULL; 73 fn.path_to_textures = "../../drawstuff/textures"; 74 75 dInitODE(); // Initialize ODE 76 world = dWorldCreate(); // Create a world 77 78 dMass m; // mass parameter 79 dMassSetZero (&m); //set mass parameter to zero 80 81 // sphere 82 sphere.body = dBodyCreate (world); // create a body 83 dReal radius = 0.5; // radius [m] 84 dMassSetSphere (&m,DENSITY,radius); // Calcurate mass parameter 85 dBodySetMass (sphere.body,&m); // Set mass parameter to the body 86 dBodySetPosition (sphere.body,0,1, 1); // Set a position 87 88 // Box 89 box.body = dBodyCreate (world); 90 dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); 91 dBodySetMass (box.body,&m); 92 dBodySetPosition (box.body,0,2,1); 93 94 // Capsule 95 capsule.body = dBodyCreate (world); 96 dMassSetCapsule(&m,DENSITY,3,radius,length); 97 dBodySetMass (capsule.body,&m); 98 dBodySetPosition (capsule.body,0,4,1); 99 100 // Cylinder 101 cylinder.body = dBodyCreate (world); 102 dMassSetCylinder(&m,DENSITY,3,radius,length); 103 dBodySetMass (cylinder.body,&m); 104 dBodySetPosition (cylinder.body,0,3,1); 105 106 // Simulation loop 107 dsSimulationLoop (argc,argv,960,480,&fn); 108 109 dWorldDestroy (world); // destroy the world 110 dCloseODE(); // close ODE 111 return 0; 112 }