demo_plane2d.cpp 10 KB

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