demo_basket.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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. // Basket ball demo.
  23. // Serves as a test for the sphere vs trimesh collider
  24. // By Bram Stolk.
  25. // Press the spacebar to reset the position of the ball.
  26. #include <assert.h>
  27. #ifdef HAVE_UNISTD_H
  28. #include <unistd.h>
  29. #endif
  30. #include <ode/ode.h>
  31. #include <drawstuff/drawstuff.h>
  32. #include "texturepath.h"
  33. #include "basket_geom.h" // this is our world mesh
  34. #ifdef _MSC_VER
  35. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  36. #endif
  37. // some constants
  38. #define RADIUS 0.14
  39. // dynamics and collision objects (chassis, 3 wheels, environment)
  40. static dWorldID world;
  41. static dSpaceID space;
  42. static dBodyID sphbody;
  43. static dGeomID sphgeom;
  44. static dJointGroupID contactgroup;
  45. static dGeomID world_mesh;
  46. // this is called by dSpaceCollide when two objects in space are
  47. // potentially colliding.
  48. static void nearCallback (void *data, dGeomID o1, dGeomID o2)
  49. {
  50. assert(o1);
  51. assert(o2);
  52. if (dGeomIsSpace(o1) || dGeomIsSpace(o2))
  53. {
  54. fprintf(stderr,"testing space %p %p\n", (void*)o1, (void*)o2);
  55. // colliding a space with something
  56. dSpaceCollide2(o1,o2,data,&nearCallback);
  57. // Note we do not want to test intersections within a space,
  58. // only between spaces.
  59. return;
  60. }
  61. // fprintf(stderr,"testing geoms %p %p\n", o1, o2);
  62. const int N = 32;
  63. dContact contact[N];
  64. int n = dCollide (o1,o2,N,&(contact[0].geom),sizeof(dContact));
  65. if (n > 0)
  66. {
  67. for (int i=0; i<n; i++)
  68. {
  69. // Paranoia <-- not working for some people, temporarily removed for 0.6
  70. //dIASSERT(dVALIDVEC3(contact[i].geom.pos));
  71. //dIASSERT(dVALIDVEC3(contact[i].geom.normal));
  72. //dIASSERT(!dIsNan(contact[i].geom.depth));
  73. contact[i].surface.slip1 = 0.7;
  74. contact[i].surface.slip2 = 0.7;
  75. contact[i].surface.mode = dContactSoftERP | dContactSoftCFM | dContactApprox1 | dContactSlip1 | dContactSlip2;
  76. contact[i].surface.mu = 50.0; // was: dInfinity
  77. contact[i].surface.soft_erp = 0.96;
  78. contact[i].surface.soft_cfm = 0.04;
  79. dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
  80. dJointAttach (c,
  81. dGeomGetBody(contact[i].geom.g1),
  82. dGeomGetBody(contact[i].geom.g2));
  83. }
  84. }
  85. }
  86. // start simulation - set viewpoint
  87. static void start()
  88. {
  89. dAllocateODEDataForThread(dAllocateMaskAll);
  90. float xyz[3] = {-8,0,5};
  91. float hpr[3] = {0.0f,-29.5000f,0.0000f};
  92. dsSetViewpoint (xyz,hpr);
  93. }
  94. static void reset_ball(void)
  95. {
  96. float sx=0.0f, sy=3.40f, sz=7.15;
  97. dQuaternion q;
  98. dQSetIdentity(q);
  99. dBodySetPosition (sphbody, sx, sy, sz);
  100. dBodySetQuaternion(sphbody, q);
  101. dBodySetLinearVel (sphbody, 0,0,0);
  102. dBodySetAngularVel (sphbody, 0,0,0);
  103. }
  104. // called when a key pressed
  105. static void command (int cmd)
  106. {
  107. switch (cmd)
  108. {
  109. case ' ':
  110. reset_ball();
  111. break;
  112. }
  113. }
  114. // simulation loop
  115. static void simLoop (int pause)
  116. {
  117. double simstep = 0.001; // 1ms simulation steps
  118. double dt = dsElapsedTime();
  119. int nrofsteps = (int) ceilf(dt/simstep);
  120. // fprintf(stderr, "dt=%f, nr of steps = %d\n", dt, nrofsteps);
  121. for (int i=0; i<nrofsteps && !pause; i++)
  122. {
  123. dSpaceCollide (space,0,&nearCallback);
  124. dWorldQuickStep (world, simstep);
  125. dJointGroupEmpty (contactgroup);
  126. }
  127. dsSetColor (1,1,1);
  128. const dReal *SPos = dBodyGetPosition(sphbody);
  129. const dReal *SRot = dBodyGetRotation(sphbody);
  130. float spos[3] = {SPos[0], SPos[1], SPos[2]};
  131. float srot[12] = { SRot[0], SRot[1], SRot[2], SRot[3], SRot[4], SRot[5], SRot[6], SRot[7], SRot[8], SRot[9], SRot[10], SRot[11] };
  132. dsDrawSphere
  133. (
  134. spos,
  135. srot,
  136. RADIUS
  137. );
  138. // draw world trimesh
  139. dsSetColor(0.4,0.7,0.9);
  140. dsSetTexture (DS_NONE);
  141. const dReal* Pos = dGeomGetPosition(world_mesh);
  142. //dIASSERT(dVALIDVEC3(Pos));
  143. float pos[3] = { Pos[0], Pos[1], Pos[2] };
  144. const dReal* Rot = dGeomGetRotation(world_mesh);
  145. //dIASSERT(dVALIDMAT3(Rot));
  146. 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] };
  147. int numi = sizeof(world_indices) / sizeof(dTriIndex);
  148. for (int i=0; i<numi/3; i++)
  149. {
  150. int i0 = world_indices[i*3+0];
  151. int i1 = world_indices[i*3+1];
  152. int i2 = world_indices[i*3+2];
  153. float *v0 = world_vertices+i0*3;
  154. float *v1 = world_vertices+i1*3;
  155. float *v2 = world_vertices+i2*3;
  156. dsDrawTriangle(pos, rot, v0,v1,v2, true); // single precision draw
  157. }
  158. }
  159. int main (int argc, char **argv)
  160. {
  161. dMass m;
  162. dMatrix3 R;
  163. // setup pointers to drawstuff callback functions
  164. dsFunctions fn;
  165. fn.version = DS_VERSION;
  166. fn.start = &start;
  167. fn.step = &simLoop;
  168. fn.command = &command;
  169. fn.stop = 0;
  170. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  171. // create world
  172. dInitODE2(0);
  173. world = dWorldCreate();
  174. space = dHashSpaceCreate (0);
  175. contactgroup = dJointGroupCreate (0);
  176. dWorldSetGravity (world,0,0,-9.8);
  177. dWorldSetQuickStepNumIterations (world, 64);
  178. // Create a static world using a triangle mesh that we can collide with.
  179. int numv = sizeof(world_vertices)/(3*sizeof(float));
  180. int numi = sizeof(world_indices)/ sizeof(dTriIndex);
  181. printf("numv=%d, numi=%d\n", numv, numi);
  182. dTriMeshDataID Data = dGeomTriMeshDataCreate();
  183. // fprintf(stderr,"Building Single Precision Mesh\n");
  184. dGeomTriMeshDataBuildSingle
  185. (
  186. Data,
  187. world_vertices,
  188. 3 * sizeof(float),
  189. numv,
  190. world_indices,
  191. numi,
  192. 3 * sizeof(dTriIndex)
  193. );
  194. world_mesh = dCreateTriMesh(space, Data, 0, 0, 0);
  195. dGeomTriMeshEnableTC(world_mesh, dSphereClass, false);
  196. dGeomTriMeshEnableTC(world_mesh, dBoxClass, false);
  197. dGeomSetPosition(world_mesh, 0, 0, 0.5);
  198. dRSetIdentity(R);
  199. //dIASSERT(dVALIDMAT3(R));
  200. dGeomSetRotation (world_mesh, R);
  201. //float sx=0.0, sy=3.40, sz=6.80;
  202. (void)world_normals; // get rid of compiler warning
  203. sphbody = dBodyCreate (world);
  204. dMassSetSphere (&m,1,RADIUS);
  205. dBodySetMass (sphbody,&m);
  206. sphgeom = dCreateSphere(0, RADIUS);
  207. dGeomSetBody (sphgeom,sphbody);
  208. reset_ball();
  209. dSpaceAdd (space, sphgeom);
  210. // run simulation
  211. dsSimulationLoop (argc, argv, DS_SIMULATION_DEFAULT_WIDTH, DS_SIMULATION_DEFAULT_HEIGHT, &fn);
  212. // Causes segm violation? Why?
  213. // (because dWorldDestroy() destroys body connected to geom; must call first!)
  214. dGeomDestroy(sphgeom);
  215. dGeomDestroy (world_mesh);
  216. dJointGroupEmpty (contactgroup);
  217. dJointGroupDestroy (contactgroup);
  218. dSpaceDestroy (space);
  219. dWorldDestroy (world);
  220. dCloseODE();
  221. return 0;
  222. }