demo_gyro2.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. // dynamics and collision objects
  41. static dWorldID world = 0;
  42. static const dReal dt = 1/REAL(60.0); // 60 fps
  43. // Water density if units are meters and kg
  44. static const dReal density = 1000;
  45. // A long skinny thing
  46. static dVector3 sides = {2,.5,.25};
  47. // Initial angular velocity
  48. static dVector3 omega = {5,1,2};
  49. static dVector3 torque = {0,10,0};
  50. static dBodyID noGyroBody;
  51. static dBodyID expGyroBody;
  52. static dBodyID impGyroBody;
  53. // start simulation - set viewpoint
  54. static void start()
  55. {
  56. dAllocateODEDataForThread(dAllocateMaskAll);
  57. static float xyz[3] = {0,-4.0f,3.0f};
  58. static float hpr[3] = {90.0000,-15.0000,0.0000};
  59. dsSetViewpoint (xyz,hpr);
  60. printf ("Press:\n"
  61. "\t'a' to apply a torque\n"
  62. "\t'r' to reset simulation.\n");
  63. }
  64. /**
  65. Delete the bodies, etc.
  66. */
  67. static void clear()
  68. {
  69. if (world) dWorldDestroy (world);
  70. world = 0;
  71. }
  72. /**
  73. Cleanup if necessary and rebuild the
  74. world.
  75. */
  76. static void reset()
  77. {
  78. clear();
  79. // create world
  80. world = dWorldCreate();
  81. // Calculate mass for a box;
  82. dMass boxMass;
  83. dMassSetBox(&boxMass,density,sides[0],sides[1],sides[2]);
  84. noGyroBody = dBodyCreate(world);// Conservation of ang-velocity
  85. expGyroBody = dBodyCreate(world);// Explicit conservation of ang-momentum
  86. impGyroBody = dBodyCreate(world);// Implicit conservation of ang-momentum
  87. dBodySetMass( noGyroBody , &boxMass );
  88. dBodySetMass( expGyroBody, &boxMass );
  89. dBodySetMass( impGyroBody, &boxMass );
  90. // Try to avoid collisions.
  91. dReal sep = dCalcVectorLength3(sides);
  92. dBodySetPosition( noGyroBody , -sep, 0, sep);
  93. dBodySetPosition( expGyroBody, 0, 0, sep);
  94. dBodySetPosition( impGyroBody, sep, 0, sep);
  95. // Set the initial angular velocity
  96. dBodySetAngularVel( noGyroBody , omega[0], omega[1], omega[2]);
  97. dBodySetAngularVel( expGyroBody, omega[0], omega[1], omega[2]);
  98. dBodySetAngularVel( impGyroBody, omega[0], omega[1], omega[2]);
  99. dBodySetGyroscopicMode( noGyroBody, 0);
  100. // We compute this ourselves using the math
  101. // that was in the old stepper.
  102. dBodySetGyroscopicMode(expGyroBody, 0);
  103. // Keep things from crashing by limiting
  104. // the angular speed of the explicit body.
  105. // Note that this isn't necessary for
  106. // the other two bodies.
  107. dBodySetMaxAngularSpeed( expGyroBody, 40 );
  108. }
  109. static void command (int cmd)
  110. {
  111. switch (cmd) {
  112. case 'a': case 'A':
  113. dBodyAddTorque( noGyroBody, torque[0], torque[1], torque[2]);
  114. dBodyAddTorque(expGyroBody, torque[0], torque[1], torque[2]);
  115. dBodyAddTorque(impGyroBody, torque[0], torque[1], torque[2]);
  116. break;
  117. case 'r': case 'R':
  118. reset();
  119. break;
  120. }
  121. }
  122. /**
  123. This is the explicit computation of
  124. gyroscopic forces.
  125. */
  126. static void expStep(dBodyID body)
  127. {
  128. // Explicit computation
  129. dMatrix3 I,tmp;
  130. dMass m;
  131. dBodyGetMass(body,&m);
  132. const dReal* R = dBodyGetRotation(body);
  133. // compute inertia tensor in global frame
  134. dMultiply2_333 (tmp,m.I,R);
  135. dMultiply0_333 (I,R,tmp);
  136. // compute explicit rotational force
  137. // we treat 'tmp'like a vector, but that's okay.
  138. const dReal* w = dBodyGetAngularVel(body);
  139. dMultiply0_331 (tmp,I,w);
  140. dVector3 tau;
  141. dCalcVectorCross3(tau,tmp,w);
  142. dBodyAddTorque(body,tau[0],tau[1],tau[2]);
  143. }
  144. // simulation loop
  145. static void simLoop (int pause)
  146. {
  147. if (!pause) {
  148. expStep(expGyroBody);
  149. dWorldStep (world,dt);
  150. }
  151. dsSetTexture (DS_WOOD);
  152. dsSetColor(1,0,0);
  153. dsDrawBox(dBodyGetPosition(noGyroBody ),dBodyGetRotation(noGyroBody ),sides);
  154. dsSetColor(1,1,0);
  155. dsDrawBox(dBodyGetPosition(expGyroBody),dBodyGetRotation(expGyroBody),sides);
  156. dsSetColor(0,1,0);
  157. dsDrawBox(dBodyGetPosition(impGyroBody),dBodyGetRotation(impGyroBody),sides);
  158. }
  159. int main (int argc, char **argv)
  160. {
  161. // setup pointers to drawstuff callback functions
  162. dsFunctions fn;
  163. fn.version = DS_VERSION;
  164. fn.start = &start;
  165. fn.step = &simLoop;
  166. fn.command = &command;
  167. fn.stop = 0;
  168. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  169. dInitODE2(0);
  170. reset();
  171. // run simulation
  172. dsSimulationLoop (argc,argv,352,288,&fn);
  173. clear();
  174. dCloseODE();
  175. return 0;
  176. }