demo_rfriction.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. /*
  23. Angular friction demo:
  24. A bunch of ramps of different pitch.
  25. A bunch of spheres with rolling friction.
  26. */
  27. #include <ode/ode.h>
  28. #include <drawstuff/drawstuff.h>
  29. #include "texturepath.h"
  30. #ifdef _MSC_VER
  31. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  32. #endif
  33. // select correct drawing functions
  34. #ifdef dDOUBLE
  35. #define dsDrawBox dsDrawBoxD
  36. #define dsDrawSphere dsDrawSphereD
  37. #define dsDrawCylinder dsDrawCylinderD
  38. #define dsDrawCapsule dsDrawCapsuleD
  39. #endif
  40. // some constants
  41. #define GRAVITY 10 // the global gravity to use
  42. #define RAMP_COUNT 8
  43. static const dReal rampX = 6.0f;
  44. static const dReal rampY = 0.5f;
  45. static const dReal rampZ = 0.25f;
  46. static const dReal sphereRadius = 0.25f;
  47. static const dReal maxRamp = M_PI/4.0f; // Needs to be less than pi/2
  48. static const dReal rampInc = maxRamp/RAMP_COUNT;
  49. // dynamics and collision objects
  50. static dWorldID world = 0;
  51. static dSpaceID space = 0;
  52. static dJointGroupID contactgroup = 0;
  53. static dGeomID ground;
  54. static dReal mu = REAL(0.37); // the global mu to use
  55. static dReal rho = REAL(0.1); // the global rho to use
  56. static dReal omega = REAL(25.0);
  57. static dGeomID rampGeom[RAMP_COUNT];
  58. static dBodyID sphereBody[RAMP_COUNT];
  59. static dGeomID sphereGeom[RAMP_COUNT];
  60. // this is called by dSpaceCollide when two objects in space are
  61. // potentially colliding.
  62. static void nearCallback (void *data, dGeomID o1, dGeomID o2)
  63. {
  64. int i;
  65. dBodyID b1 = dGeomGetBody(o1);
  66. dBodyID b2 = dGeomGetBody(o2);
  67. if (b1==0 && b2==0) return;
  68. dContact contact[3];
  69. for (int ii=0; ii<3; ii++) {
  70. contact[ii].surface.mode = dContactApprox1 | dContactRolling;
  71. contact[ii].surface.mu = mu;
  72. contact[ii].surface.rho = rho;
  73. }
  74. if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) {
  75. for (i=0; i<numc; i++) {
  76. dJointID c = dJointCreateContact (world,contactgroup,contact+i);
  77. dJointAttach (c,b1,b2);
  78. }
  79. }
  80. }
  81. // start simulation - set viewpoint
  82. static void start()
  83. {
  84. dAllocateODEDataForThread(dAllocateMaskAll);
  85. static float xyz[3] = {0,-3.0f,3.0f};
  86. static float hpr[3] = {90.0000,-15.0000,0.0000};
  87. dsSetViewpoint (xyz,hpr);
  88. printf ("Press:\n"
  89. "\t'[' or ']' to change initial angular velocity\n"
  90. "\t'm' to increase sliding friction\n"
  91. "\t'n' to decrease sliding friction\n"
  92. "\t'j' to increase rolling friction\n"
  93. "\t'h' to decrease rolling friction\n"
  94. "\t'r' to reset simulation.\n");
  95. }
  96. /**
  97. Delete the bodies, etc.
  98. */
  99. static void clear()
  100. {
  101. if (contactgroup) dJointGroupDestroy (contactgroup);
  102. if (space) dSpaceDestroy (space);
  103. if (world) dWorldDestroy (world);
  104. }
  105. /**
  106. Cleanup if necessary and rebuild the
  107. world.
  108. */
  109. static void reset()
  110. {
  111. clear();
  112. // create world
  113. world = dWorldCreate();
  114. space = dHashSpaceCreate (0);
  115. contactgroup = dJointGroupCreate (0);
  116. dWorldSetGravity (world,0,0,-GRAVITY);
  117. ground = dCreatePlane (space,0,0,1,0);
  118. // Calculate mass for sphere a capsule with water density.
  119. dMass sphereMass;
  120. dMassSetSphere(&sphereMass,1000,sphereRadius);
  121. for (int ii=0;ii<RAMP_COUNT;++ii) {
  122. dQuaternion q;
  123. dReal angle = (ii+1)*rampInc;
  124. dReal cosA = dCos(angle);
  125. dReal sinA = dSin(angle);
  126. dReal rampW = rampX/cosA; // Box width that preserves ground distance
  127. dReal zPos = REAL(0.5)*(sinA*rampW-cosA*rampZ); // Position that makes end meet ground
  128. dReal yPos = ii*1.25*rampY;
  129. dReal xPos = 0;
  130. // Create the ramp
  131. rampGeom[ii] = dCreateBox(space,rampW,rampY,rampZ);
  132. dQFromAxisAndAngle(q,0,1,0,angle);
  133. dGeomSetQuaternion(rampGeom[ii],q);
  134. dGeomSetPosition(rampGeom[ii],xPos,yPos,zPos);
  135. // Create the spheres
  136. xPos = -REAL(0.5)*rampX + sphereRadius;
  137. zPos = sinA*rampW + sphereRadius;
  138. sphereBody[ii] = dBodyCreate(world);
  139. dBodySetMass(sphereBody[ii],&sphereMass);
  140. sphereGeom[ii] = dCreateSphere(space,sphereRadius);
  141. dGeomSetBody(sphereGeom[ii],sphereBody[ii]);
  142. dBodySetPosition(sphereBody[ii],xPos,yPos,zPos);
  143. dBodySetAngularVel(sphereBody[ii],0,omega,0);
  144. }
  145. }
  146. static void command (int cmd)
  147. {
  148. switch (cmd) {
  149. case 'h': case 'H':
  150. rho-=0.02;
  151. if (rho<0) rho=0;
  152. break;
  153. case 'j': case 'J':
  154. rho+=0.02;
  155. if (rho>1) rho=1;
  156. break;
  157. case 'n': case 'N':
  158. mu-=0.02;
  159. if (mu<0) mu=0;
  160. break;
  161. case 'm': case 'M':
  162. mu+=0.02;
  163. if (mu>1) mu=1;
  164. break;
  165. case 'r': case 'R':
  166. reset();
  167. break;
  168. case ']':
  169. omega+=1;
  170. break;
  171. case '[':
  172. omega-=1;
  173. break;
  174. }
  175. }
  176. // simulation loop
  177. static void simLoop (int pause)
  178. {
  179. if (!pause) {
  180. dSpaceCollide (space,0,&nearCallback);
  181. dWorldStep (world,0.017); // 60 fps
  182. // remove all contact joints
  183. dJointGroupEmpty (contactgroup);
  184. }
  185. // Render ramps and spheres
  186. dsSetTexture (DS_WOOD);
  187. for (int ii=0;ii<RAMP_COUNT;++ii) {
  188. dVector3 sides;
  189. dsSetColor (1,0.5,0);
  190. dGeomBoxGetLengths(rampGeom[ii],sides);
  191. dsDrawBox (dGeomGetPosition(rampGeom[ii]),dGeomGetRotation(rampGeom[ii]),sides);
  192. dsSetColor(0,0,1);
  193. dsDrawSphere (dGeomGetPosition(sphereGeom[ii]),dGeomGetRotation(sphereGeom[ii]), sphereRadius);
  194. }
  195. }
  196. int main (int argc, char **argv)
  197. {
  198. // setup pointers to drawstuff callback functions
  199. dsFunctions fn;
  200. fn.version = DS_VERSION;
  201. fn.start = &start;
  202. fn.step = &simLoop;
  203. fn.command = &command;
  204. fn.stop = 0;
  205. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  206. dInitODE2(0);
  207. reset();
  208. // run simulation
  209. dsSimulationLoop (argc,argv,352,288,&fn);
  210. clear();
  211. dCloseODE();
  212. return 0;
  213. }