demo_cyl.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*************************************************************************
  2. * *
  3. * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
  4. * All rights reserved. Email: [email protected] Web: www.q12.org *
  5. * *
  6. * This library is free software; you can redistribute it and/or *
  7. * modify it under the terms of EITHER: *
  8. * (1) The GNU Lesser General Public License as published by the Free *
  9. * Software Foundation; either version 2.1 of the License, or (at *
  10. * your option) any later version. The text of the GNU Lesser *
  11. * General Public License is included with this library in the *
  12. * file LICENSE.TXT. *
  13. * (2) The BSD-style license that is included with this library in *
  14. * the file LICENSE-BSD.TXT. *
  15. * *
  16. * This library is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
  19. * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
  20. * *
  21. *************************************************************************/
  22. // Test for non-capped cylinder, by Bram Stolk
  23. #include <ode/odeconfig.h>
  24. #include <assert.h>
  25. #ifdef HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #include <ode/ode.h>
  29. #include <drawstuff/drawstuff.h>
  30. #include "texturepath.h"
  31. #include "world_geom3.h" // this is our world mesh
  32. #ifdef _MSC_VER
  33. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  34. #endif
  35. #define BOX
  36. #define CYL
  37. // some constants
  38. #define RADIUS 0.22 // wheel radius
  39. #define WMASS 0.2 // wheel mass
  40. #define WHEELW 0.2 // wheel width
  41. #define BOXSZ 0.4 // box size
  42. //#define CYL_GEOM_OFFSET // rotate cylinder using geom offset
  43. // dynamics and collision objects (chassis, 3 wheels, environment)
  44. static dWorldID world;
  45. static dSpaceID space;
  46. #ifdef BOX
  47. static dBodyID boxbody;
  48. static dGeomID boxgeom;
  49. #endif
  50. #ifdef CYL
  51. static dBodyID cylbody;
  52. static dGeomID cylgeom;
  53. #endif
  54. static dJointGroupID contactgroup;
  55. static dGeomID world_mesh;
  56. // this is called by dSpaceCollide when two objects in space are
  57. // potentially colliding.
  58. static void nearCallback (void *data, dGeomID o1, dGeomID o2)
  59. {
  60. assert(o1);
  61. assert(o2);
  62. if (dGeomIsSpace(o1) || dGeomIsSpace(o2))
  63. {
  64. fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2);
  65. // colliding a space with something
  66. dSpaceCollide2(o1,o2,data,&nearCallback);
  67. // Note we do not want to test intersections within a space,
  68. // only between spaces.
  69. return;
  70. }
  71. // fprintf(stderr,"testing geoms %p %p\n", o1, o2);
  72. const int N = 32;
  73. dContact contact[N];
  74. int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact));
  75. if (n > 0)
  76. {
  77. for (int i=0; i<n; i++)
  78. {
  79. contact[i].surface.slip1 = 0.7;
  80. contact[i].surface.slip2 = 0.7;
  81. contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2;
  82. contact[i].surface.mu = 50.0; // was: dInfinity
  83. contact[i].surface.soft_erp = 0.96;
  84. contact[i].surface.soft_cfm = 0.04;
  85. dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
  86. dJointAttach (c,
  87. dGeomGetBody(contact[i].geom.g1),
  88. dGeomGetBody(contact[i].geom.g2));
  89. }
  90. }
  91. }
  92. // start simulation - set viewpoint
  93. static void start()
  94. {
  95. dAllocateODEDataForThread(dAllocateMaskAll);
  96. static float xyz[3] = {-8,-9,3};
  97. static float hpr[3] = {45.0000f,-27.5000f,0.0000f};
  98. dsSetViewpoint (xyz,hpr);
  99. }
  100. static void reset_state(void)
  101. {
  102. float sx=-4, sy=-4, sz=2;
  103. dQuaternion q;
  104. dQFromAxisAndAngle (q,1,0,0,M_PI*0.5);
  105. #ifdef BOX
  106. dBodySetPosition (boxbody, sx, sy+1, sz);
  107. dBodySetLinearVel (boxbody, 0,0,0);
  108. dBodySetAngularVel (boxbody, 0,0,0);
  109. dBodySetQuaternion (boxbody, q);
  110. #endif
  111. #ifdef CYL
  112. dBodySetPosition (cylbody, sx, sy, sz);
  113. dBodySetLinearVel (cylbody, 0,0,0);
  114. dBodySetAngularVel (cylbody, 0,0,0);
  115. dBodySetQuaternion (cylbody, q);
  116. #endif
  117. }
  118. // called when a key pressed
  119. static void command (int cmd)
  120. {
  121. switch (cmd)
  122. {
  123. case ' ':
  124. reset_state();
  125. break;
  126. }
  127. }
  128. // simulation loop
  129. static void simLoop (int pause)
  130. {
  131. double simstep = 0.005; // 5ms simulation steps
  132. double dt = dsElapsedTime();
  133. int nrofsteps = (int) ceilf(dt/simstep);
  134. for (int i=0; i<nrofsteps && !pause; i++)
  135. {
  136. dSpaceCollide (space,0,&nearCallback);
  137. dWorldQuickStep (world, simstep);
  138. dJointGroupEmpty (contactgroup);
  139. }
  140. dsSetColor (1,1,1);
  141. #ifdef BOX
  142. const dReal *BPos = dBodyGetPosition(boxbody);
  143. const dReal *BRot = dBodyGetRotation(boxbody);
  144. float bpos[3] = {BPos[0], BPos[1], BPos[2]};
  145. float brot[12] = { BRot[0], BRot[1], BRot[2], BRot[3], BRot[4], BRot[5], BRot[6], BRot[7], BRot[8], BRot[9], BRot[10], BRot[11] };
  146. float sides[3] = {BOXSZ, BOXSZ, BOXSZ};
  147. dsDrawBox
  148. (
  149. bpos,
  150. brot,
  151. sides
  152. ); // single precision
  153. #endif
  154. #ifdef CYL
  155. const dReal *CPos = dGeomGetPosition(cylgeom);
  156. const dReal *CRot = dGeomGetRotation(cylgeom);
  157. float cpos[3] = {CPos[0], CPos[1], CPos[2]};
  158. float crot[12] = { CRot[0], CRot[1], CRot[2], CRot[3], CRot[4], CRot[5], CRot[6], CRot[7], CRot[8], CRot[9], CRot[10], CRot[11] };
  159. dsDrawCylinder
  160. (
  161. // dBodyGetPosition(cylbody),
  162. // dBodyGetRotation(cylbody),
  163. cpos,
  164. crot,
  165. WHEELW,
  166. RADIUS
  167. ); // single precision
  168. #endif
  169. // draw world trimesh
  170. dsSetColor(0.7,0.7,0.4);
  171. dsSetTexture (DS_NONE);
  172. const dReal* Pos = dGeomGetPosition(world_mesh);
  173. float pos[3] = { Pos[0], Pos[1], Pos[2] };
  174. const dReal* Rot = dGeomGetRotation(world_mesh);
  175. float rot[12] = { Rot[0], Rot[1], Rot[2], Rot[3], Rot[4], Rot[5], Rot[6], Rot[7], Rot[8], Rot[9], Rot[10], Rot[11] };
  176. int numi = sizeof(world_indices) / sizeof(dTriIndex);
  177. for (int i=0; i<numi/3; i++)
  178. {
  179. int i0 = world_indices[i*3+0];
  180. int i1 = world_indices[i*3+1];
  181. int i2 = world_indices[i*3+2];
  182. float *v0 = world_vertices+i0*3;
  183. float *v1 = world_vertices+i1*3;
  184. float *v2 = world_vertices+i2*3;
  185. dsDrawTriangle(pos, rot, v0,v1,v2, true); // single precision draw
  186. }
  187. }
  188. int main (int argc, char **argv)
  189. {
  190. dMass m;
  191. dMatrix3 R;
  192. // setup pointers to drawstuff callback functions
  193. dsFunctions fn;
  194. fn.version = DS_VERSION;
  195. fn.start = &start;
  196. fn.step = &simLoop;
  197. fn.command = &command;
  198. fn.stop = 0;
  199. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  200. // create world
  201. dInitODE2(0);
  202. world = dWorldCreate();
  203. space = dHashSpaceCreate (0);
  204. contactgroup = dJointGroupCreate (0);
  205. dWorldSetGravity (world,0,0,-9.8);
  206. dWorldSetQuickStepNumIterations (world, 12);
  207. // Create a static world using a triangle mesh that we can collide with.
  208. int numv = sizeof(world_vertices)/(3*sizeof(float));
  209. int numi = sizeof(world_indices)/ sizeof(dTriIndex);
  210. printf("numv=%d, numi=%d\n", numv, numi);
  211. dTriMeshDataID Data = dGeomTriMeshDataCreate();
  212. dGeomTriMeshDataBuildSingle
  213. (
  214. Data,
  215. world_vertices,
  216. 3 * sizeof(float),
  217. numv,
  218. world_indices,
  219. numi,
  220. 3 * sizeof(dTriIndex)
  221. );
  222. world_mesh = dCreateTriMesh(space, Data, 0, 0, 0);
  223. dGeomSetPosition(world_mesh, 0, 0, 0.5);
  224. dRFromAxisAndAngle (R, 0,1,0, 0.0);
  225. dGeomSetRotation (world_mesh, R);
  226. #ifdef BOX
  227. boxbody = dBodyCreate (world);
  228. dMassSetBox (&m,1, BOXSZ, BOXSZ, BOXSZ);
  229. dMassAdjust (&m, 1);
  230. dBodySetMass (boxbody,&m);
  231. boxgeom = dCreateBox (0, BOXSZ, BOXSZ, BOXSZ);
  232. dGeomSetBody (boxgeom,boxbody);
  233. dSpaceAdd (space, boxgeom);
  234. #endif
  235. #ifdef CYL
  236. cylbody = dBodyCreate (world);
  237. dMassSetSphere (&m,1,RADIUS);
  238. dMassAdjust (&m,WMASS);
  239. dBodySetMass (cylbody,&m);
  240. cylgeom = dCreateCylinder(0, RADIUS, WHEELW);
  241. dGeomSetBody (cylgeom,cylbody);
  242. #if defined(CYL_GEOM_OFFSET)
  243. dMatrix3 mat;
  244. dRFromAxisAndAngle(mat,1.0f,0.0f,0.0f,M_PI/2.0);
  245. dGeomSetOffsetRotation(cylgeom,mat);
  246. #endif
  247. dSpaceAdd (space, cylgeom);
  248. #endif
  249. reset_state();
  250. // run simulation
  251. dsSimulationLoop (argc,argv,352,288,&fn);
  252. dJointGroupEmpty (contactgroup);
  253. dJointGroupDestroy (contactgroup);
  254. // First destroy geoms, then space, then the world.
  255. #ifdef CYL
  256. dGeomDestroy (cylgeom);
  257. #endif
  258. #ifdef BOX
  259. dGeomDestroy (boxgeom);
  260. #endif
  261. dGeomDestroy (world_mesh);
  262. dSpaceDestroy (space);
  263. dWorldDestroy (world);
  264. dCloseODE();
  265. return 0;
  266. (void)world_normals; // get rid of compiler warnings
  267. }