demo_plane2d.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Test my Plane2D constraint.
  2. // Uses ode-0.35 collision API.
  3. # include <stdio.h>
  4. # include <stdlib.h>
  5. # include <math.h>
  6. # include <ode/ode.h>
  7. # include <drawstuff/drawstuff.h>
  8. #include "texturepath.h"
  9. # define drand48() ((double) (((double) rand()) / ((double) RAND_MAX)))
  10. # define N_BODIES 40
  11. # define STAGE_SIZE 8.0 // in m
  12. # define TIME_STEP 0.01
  13. # define K_SPRING 10.0
  14. # define K_DAMP 10.0
  15. //using namespace ode;
  16. static dWorld dyn_world;
  17. static dBody dyn_bodies[N_BODIES];
  18. static dReal bodies_sides[N_BODIES][3];
  19. static dSpaceID coll_space_id;
  20. static dJointID plane2d_joint_ids[N_BODIES];
  21. static dJointGroup
  22. coll_contacts;
  23. static void cb_start ()
  24. /*************************/
  25. {
  26. dAllocateODEDataForThread(dAllocateMaskAll);
  27. static float xyz[3] = { 0.5f*STAGE_SIZE, 0.5f*STAGE_SIZE, 0.65f*STAGE_SIZE};
  28. static float hpr[3] = { 90.0f, -90.0f, 0 };
  29. dsSetViewpoint (xyz, hpr);
  30. }
  31. static void cb_near_collision (void *data, dGeomID o1, dGeomID o2)
  32. /********************************************************************/
  33. {
  34. dBodyID b1 = dGeomGetBody (o1);
  35. dBodyID b2 = dGeomGetBody (o2);
  36. dContact contact;
  37. // exit without doing anything if the two bodies are static
  38. if (b1 == 0 && b2 == 0)
  39. return;
  40. // exit without doing anything if the two bodies are connected by a joint
  41. if (b1 && b2 && dAreConnected (b1, b2))
  42. {
  43. /* MTRAP; */
  44. return;
  45. }
  46. contact.surface.mode = 0;
  47. contact.surface.mu = 0; // frictionless
  48. if (dCollide (o1, o2, 1, &contact.geom, sizeof (dContactGeom)))
  49. {
  50. dJointID c = dJointCreateContact (dyn_world.id(),
  51. coll_contacts.id (), &contact);
  52. dJointAttach (c, b1, b2);
  53. }
  54. }
  55. static void track_to_pos (dBody &body, dJointID joint_id,
  56. dReal target_x, dReal target_y)
  57. /************************************************************************/
  58. {
  59. dReal curr_x = body.getPosition()[0];
  60. dReal curr_y = body.getPosition()[1];
  61. dJointSetPlane2DXParam (joint_id, dParamVel, 1 * (target_x - curr_x));
  62. dJointSetPlane2DYParam (joint_id, dParamVel, 1 * (target_y - curr_y));
  63. }
  64. static void cb_sim_step (int pause)
  65. /*************************************/
  66. {
  67. if (! pause)
  68. {
  69. static dReal angle = 0;
  70. angle += REAL( 0.01 );
  71. track_to_pos (dyn_bodies[0], plane2d_joint_ids[0],
  72. dReal( STAGE_SIZE/2 + STAGE_SIZE/2.0 * cos (angle) ),
  73. dReal( STAGE_SIZE/2 + STAGE_SIZE/2.0 * sin (angle) ));
  74. /* double f0 = 0.001; */
  75. /* for (int b = 0; b < N_BODIES; b ++) */
  76. /* { */
  77. /* double p = 1 + b / (double) N_BODIES; */
  78. /* double q = 2 - b / (double) N_BODIES; */
  79. /* dyn_bodies[b].addForce (f0 * cos (p*angle), f0 * sin (q*angle), 0); */
  80. /* } */
  81. /* dyn_bodies[0].addTorque (0, 0, 0.1); */
  82. const int n = 10;
  83. for (int i = 0; i < n; i ++)
  84. {
  85. dSpaceCollide (coll_space_id, 0, &cb_near_collision);
  86. dyn_world.step (dReal(TIME_STEP/n));
  87. coll_contacts.empty ();
  88. }
  89. }
  90. # if 1 /* [ */
  91. {
  92. // @@@ hack Plane2D constraint error reduction here:
  93. for (int b = 0; b < N_BODIES; b ++)
  94. {
  95. const dReal *rot = dBodyGetAngularVel (dyn_bodies[b].id());
  96. const dReal *quat_ptr;
  97. dReal quat[4],
  98. quat_len;
  99. quat_ptr = dBodyGetQuaternion (dyn_bodies[b].id());
  100. quat[0] = quat_ptr[0];
  101. quat[1] = 0;
  102. quat[2] = 0;
  103. quat[3] = quat_ptr[3];
  104. quat_len = sqrt (quat[0] * quat[0] + quat[3] * quat[3]);
  105. quat[0] /= quat_len;
  106. quat[3] /= quat_len;
  107. dBodySetQuaternion (dyn_bodies[b].id(), quat);
  108. dBodySetAngularVel (dyn_bodies[b].id(), 0, 0, rot[2]);
  109. }
  110. }
  111. # endif /* ] */
  112. # if 0 /* [ */
  113. {
  114. // @@@ friction
  115. for (int b = 0; b < N_BODIES; b ++)
  116. {
  117. const dReal *vel = dBodyGetLinearVel (dyn_bodies[b].id()),
  118. *rot = dBodyGetAngularVel (dyn_bodies[b].id());
  119. dReal s = 1.00;
  120. dReal t = 0.99;
  121. dBodySetLinearVel (dyn_bodies[b].id(), s*vel[0],s*vel[1],s*vel[2]);
  122. dBodySetAngularVel (dyn_bodies[b].id(),t*rot[0],t*rot[1],t*rot[2]);
  123. }
  124. }
  125. # endif /* ] */
  126. {
  127. // ode drawstuff
  128. dsSetTexture (DS_WOOD);
  129. for (int b = 0; b < N_BODIES; b ++)
  130. {
  131. if (b == 0)
  132. dsSetColor (1.0, 0.5, 1.0);
  133. else
  134. dsSetColor (0, 0.5, 1.0);
  135. #ifdef dDOUBLE
  136. dsDrawBoxD (dyn_bodies[b].getPosition(), dyn_bodies[b].getRotation(), bodies_sides[b]);
  137. #else
  138. dsDrawBox (dyn_bodies[b].getPosition(), dyn_bodies[b].getRotation(), bodies_sides[b]);
  139. #endif
  140. }
  141. }
  142. }
  143. extern int main
  144. /******************/
  145. (
  146. int argc,
  147. char **argv
  148. )
  149. {
  150. int b;
  151. dsFunctions drawstuff_functions;
  152. dInitODE2(0);
  153. // dynamic world
  154. dReal cf_mixing;// = 1 / TIME_STEP * K_SPRING + K_DAMP;
  155. dReal err_reduct;// = TIME_STEP * K_SPRING * cf_mixing;
  156. err_reduct = REAL( 0.5 );
  157. cf_mixing = REAL( 0.001 );
  158. dWorldSetERP (dyn_world.id (), err_reduct);
  159. dWorldSetCFM (dyn_world.id (), cf_mixing);
  160. dyn_world.setGravity (0, 0.0, -1.0);
  161. coll_space_id = dSimpleSpaceCreate (0);
  162. // dynamic bodies
  163. for (b = 0; b < N_BODIES; b ++)
  164. {
  165. int l = (int) (1 + sqrt ((double) N_BODIES));
  166. dReal x = dReal( (0.5 + (b / l)) / l * STAGE_SIZE );
  167. dReal y = dReal( (0.5 + (b % l)) / l * STAGE_SIZE );
  168. dReal z = REAL( 1.0 ) + REAL( 0.1 ) * (dReal)drand48();
  169. bodies_sides[b][0] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) );
  170. bodies_sides[b][1] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) );
  171. bodies_sides[b][2] = z;
  172. dyn_bodies[b].create (dyn_world);
  173. dyn_bodies[b].setPosition (x, y, z/2);
  174. dyn_bodies[b].setData ((void*) (size_t)b);
  175. dBodySetLinearVel (dyn_bodies[b].id (),
  176. dReal( 3 * (drand48 () - 0.5) ),
  177. dReal( 3 * (drand48 () - 0.5) ), 0);
  178. dMass m;
  179. m.setBox (1, bodies_sides[b][0],bodies_sides[b][1],bodies_sides[b][2]);
  180. m.adjust (REAL(0.1) * bodies_sides[b][0] * bodies_sides[b][1]);
  181. dyn_bodies[b].setMass (&m);
  182. plane2d_joint_ids[b] = dJointCreatePlane2D (dyn_world.id (), 0);
  183. dJointAttach (plane2d_joint_ids[b], dyn_bodies[b].id (), 0);
  184. }
  185. dJointSetPlane2DXParam (plane2d_joint_ids[0], dParamFMax, 10);
  186. dJointSetPlane2DYParam (plane2d_joint_ids[0], dParamFMax, 10);
  187. // collision geoms and joints
  188. dCreatePlane (coll_space_id, 1, 0, 0, 0);
  189. dCreatePlane (coll_space_id, -1, 0, 0, -STAGE_SIZE);
  190. dCreatePlane (coll_space_id, 0, 1, 0, 0);
  191. dCreatePlane (coll_space_id, 0, -1, 0, -STAGE_SIZE);
  192. for (b = 0; b < N_BODIES; b ++)
  193. {
  194. dGeomID coll_box_id;
  195. coll_box_id = dCreateBox (coll_space_id,
  196. bodies_sides[b][0], bodies_sides[b][1], bodies_sides[b][2]);
  197. dGeomSetBody (coll_box_id, dyn_bodies[b].id ());
  198. }
  199. coll_contacts.create ();
  200. {
  201. // simulation loop (by drawstuff lib)
  202. drawstuff_functions.version = DS_VERSION;
  203. drawstuff_functions.start = &cb_start;
  204. drawstuff_functions.step = &cb_sim_step;
  205. drawstuff_functions.command = 0;
  206. drawstuff_functions.stop = 0;
  207. drawstuff_functions.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  208. dsSimulationLoop (argc, argv, 352,288,&drawstuff_functions);
  209. }
  210. dCloseODE();
  211. return 0;
  212. }