demo_piston.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  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. * Created by: Remi Ricard *
  22. * ([email protected] or [email protected]) *
  23. * Creation date: 2007/05/04 *
  24. *************************************************************************/
  25. /*
  26. This program demonstrates how the Piston joint works.
  27. A Piston joint enables the sliding of a body with respect to another body
  28. and the 2 bodies are free to rotate about the sliding axis.
  29. - The yellow body is fixed to the world.
  30. - The yellow body and the blue body are attached by a Piston joint with
  31. the axis along the x direction.
  32. - The purple object is a geometry obstacle.
  33. - The red line is the representation of the prismatic axis
  34. - The orange line is the representation of the rotoide axis
  35. - The light blue ball is the anchor position
  36. N.B. Many command options are available type -h to print them.
  37. */
  38. #include <ode/ode.h>
  39. #include <drawstuff/drawstuff.h>
  40. #include <iostream>
  41. #include <math.h>
  42. #include "texturepath.h"
  43. #ifdef _MSC_VER
  44. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  45. #endif
  46. // select correct drawing functions
  47. #ifdef dDOUBLE
  48. #define dsDrawBox dsDrawBoxD
  49. #define dsDrawCylinder dsDrawCylinderD
  50. #define dsDrawCapsule dsDrawCapsuleD
  51. #define dsDrawSphere dsDrawSphereD
  52. #endif
  53. const dReal VEL_INC = 0.01; // Velocity increment
  54. // physics parameters
  55. const dReal PI = 3.14159265358979323846264338327950288419716939937510;
  56. const dReal BODY1_LENGTH = 1.5; // Size along the X axis
  57. const dReal RADIUS = 0.2;
  58. const dReal AXIS_RADIUS = 0.01;
  59. #define X 0
  60. #define Y 1
  61. #define Z 2
  62. enum INDEX
  63. {
  64. BODY1 = 0,
  65. BODY2,
  66. RECT,
  67. BOX,
  68. OBS,
  69. GROUND,
  70. NUM_PARTS,
  71. ALL = NUM_PARTS
  72. };
  73. const int catBits[NUM_PARTS+1] =
  74. {
  75. 0x0001, ///< Ext Cylinder category
  76. 0x0002, ///< Int Cylinder category
  77. 0x0004, ///< Int_Rect Cylinder category
  78. 0x0008, ///< Box category
  79. 0x0010, ///< Obstacle category
  80. 0x0020, ///< Ground category
  81. ~0L ///< All categories
  82. };
  83. #define Mass1 10
  84. #define Mass2 8
  85. //camera view
  86. static const float xyz[3] = {2.0f,-5.5f,2.0000f};
  87. static const float hpr[3] = {90.000f,-15.5000f,0.0000f};
  88. //world,space,body & geom
  89. static dWorldID world;
  90. static dSpaceID space;
  91. static dJointGroupID contactgroup;
  92. static dBodyID body[NUM_PARTS];
  93. static dGeomID geom[NUM_PARTS];
  94. // Default Positions and anchor of the 2 bodies
  95. dVector3 pos1;
  96. dVector3 pos2;
  97. dVector3 anchor;
  98. static dJoint *joint;
  99. const dReal BODY2_SIDES[3] = {0.4, 0.4, 0.4};
  100. const dReal OBS_SIDES[3] = {1,1,1};
  101. const dReal RECT_SIDES[3] = {0.3, 0.1, 0.2};
  102. int type = dJointTypePiston;
  103. //#pragma message("tc to be changed to 0")
  104. int tc = 0; // The test case choice;
  105. //collision detection
  106. static void nearCallback (void *, dGeomID o1, dGeomID o2)
  107. {
  108. int i,n;
  109. dBodyID b1 = dGeomGetBody (o1);
  110. dBodyID b2 = dGeomGetBody (o2);
  111. if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact) ) return;
  112. const int N = 10;
  113. dContact contact[N];
  114. n = dCollide (o1,o2,N,&contact[0].geom,sizeof (dContact) );
  115. if (n > 0)
  116. {
  117. for (i=0; i<n; i++)
  118. {
  119. contact[i].surface.mode = (dContactSlip1 | dContactSlip2 |
  120. dContactSoftERP | dContactSoftCFM |
  121. dContactApprox1);
  122. contact[i].surface.mu = 0.1;
  123. contact[i].surface.slip1 = 0.02;
  124. contact[i].surface.slip2 = 0.02;
  125. contact[i].surface.soft_erp = 0.1;
  126. contact[i].surface.soft_cfm = 0.0001;
  127. dJointID c = dJointCreateContact (world,contactgroup,&contact[i]);
  128. dJointAttach (c,dGeomGetBody (contact[i].geom.g1),dGeomGetBody (contact[i].geom.g2) );
  129. }
  130. }
  131. }
  132. static void printKeyBoardShortCut()
  133. {
  134. printf ("Press 'h' for this help.\n");
  135. printf ("Press 'q' to add force on BLUE body along positive x direction.\n");
  136. printf ("Press 'w' to add force on BLUE body along negative x direction.\n");
  137. printf ("Press 'a' to add force on BLUE body along positive y direction.\n");
  138. printf ("Press 's' to add force on BLUE body along negative y direction.\n");
  139. printf ("Press 'z' to add force on BLUE body along positive z direction.\n");
  140. printf ("Press 'x' to add force on BLUE body along negative z direction.\n");
  141. printf ("Press 'e' to add torque on BLUE body around positive x direction \n");
  142. printf ("Press 'r' to add torque on BLUE body around negative x direction \n");
  143. printf ("Press 'd' to add torque on BLUE body around positive y direction \n");
  144. printf ("Press 'f' to add torque on BLUE body around negative y direction \n");
  145. printf ("Press 'c' to add torque on BLUE body around positive z direction \n");
  146. printf ("Press 'v' to add torque on BLUE body around negative z direction \n");
  147. printf ("Press 't' to add force on prismatic joint in the positive axis direction\n");
  148. printf ("Press 'y' to add force on prismatic joint in the negative axis direction\n");
  149. printf ("Press 'i' to add limits on the prismatic joint (0 to 0) \n");
  150. printf ("Press 'o' to add limits on the rotoide joint (0 to 0)\n");
  151. printf ("Press 'k' to add limits on the rotoide joint (-45 to 45deg) \n");
  152. printf ("Press 'l' to remove limits on the rotoide joint \n");
  153. printf ("Press '.' to increase joint velocity along the prismatic direction.\n");
  154. printf ("Press ',' to decrease joint velocity along the prismatic direction.\n");
  155. printf ("Press 'p' to print the Position of the joint.\n");
  156. printf ("Press '+' Go to the next test case.\n");
  157. printf ("Press '-' Go to the previous test case.\n");
  158. printf ("Press '8' To remove one of the body. The blue body and the world will be\n");
  159. printf (" attached to the joint (blue body at position 1)\n");
  160. printf ("Press '9' To remove one of the body. The blue body and the world will be\n");
  161. printf (" attached to the joint (body body at position 2)\n");
  162. }
  163. // start simulation - set viewpoint
  164. static void start()
  165. {
  166. dAllocateODEDataForThread(dAllocateMaskAll);
  167. dsSetViewpoint (xyz,hpr);
  168. printf ("This program demonstrates how the Piston joint works.\n");
  169. printf ("A Piston joint enables the sliding of a body with respect to another body\n");
  170. printf ("and the 2 bodies are free to rotate about the sliding axis.\n\n");
  171. printf ("The yellow body is fixed to the world\n");
  172. printf ("The yellow body and the blue body are attached by a Piston joint with\n");
  173. printf ("the axis along the x direction.\n");
  174. printf ("The purple object is a geometry obstacle.\n");
  175. printKeyBoardShortCut();
  176. }
  177. void setPositionBodies (int val)
  178. {
  179. const dVector3 POS1 = {0,0,1.5,0};
  180. const dVector3 POS2 = {0,0,1.5,0};
  181. const dVector3 ANCHOR = {0,0,1.5,0};
  182. for (int i=0; i<3; ++i)
  183. {
  184. pos1[i] = POS1[i];
  185. pos2[i] = POS2[i];
  186. anchor[i] = ANCHOR[i];
  187. }
  188. if (body[BODY1])
  189. {
  190. dBodySetLinearVel (body[BODY1], 0,0,0);
  191. dBodySetAngularVel (body[BODY1], 0,0,0);
  192. }
  193. if (body[BODY2])
  194. {
  195. dBodySetLinearVel (body[BODY2], 0,0,0);
  196. dBodySetAngularVel (body[BODY2], 0,0,0);
  197. }
  198. switch (val)
  199. {
  200. case 3:
  201. pos1[Z] += -0.5;
  202. anchor[Z] -= 0.25;
  203. break;
  204. case 2:
  205. pos1[Z] -= 0.5;
  206. anchor[Z] -= 0.5;
  207. break;
  208. case 1:
  209. pos1[Z] += -0.5;
  210. break;
  211. default: // This is also case 0
  212. // Nothing to be done
  213. break;
  214. }
  215. const dMatrix3 R =
  216. {
  217. 1,0,0,0,
  218. 0,1,0,0,
  219. 0,0,1,0
  220. };
  221. if (body[BODY1])
  222. {
  223. dBodySetPosition (body[BODY1], pos1[X], pos1[Y], pos1[Z]);
  224. dBodySetRotation (body[BODY1], R);
  225. }
  226. if (body[BODY2])
  227. {
  228. dBodySetPosition (body[BODY2], pos2[X], pos2[Y], pos2[Z]);
  229. dBodySetRotation (body[BODY2], R);
  230. }
  231. if (joint)
  232. {
  233. joint->attach (body[BODY1], body[BODY2]);
  234. if (joint->getType() == dJointTypePiston)
  235. dJointSetPistonAnchor(joint->id(), anchor[X], anchor[Y], anchor[Z]);
  236. }
  237. }
  238. // function to update camera position at each step.
  239. void update()
  240. {
  241. // static FILE *file = fopen("x:/sim/src/libode/tstsrcSF/export.dat", "w");
  242. // static int cnt = 0;
  243. // char str[24];
  244. // sprintf(str, "%06d",cnt++);
  245. // dWorldExportDIF(world, file, str);
  246. }
  247. // called when a key pressed
  248. static void command (int cmd)
  249. {
  250. switch (cmd)
  251. {
  252. case 'h' :
  253. case 'H' :
  254. case '?' :
  255. printKeyBoardShortCut();
  256. break;
  257. // Force
  258. case 'q' :
  259. case 'Q' :
  260. dBodyAddForce (body[BODY1],4,0,0);
  261. break;
  262. case 'w' :
  263. case 'W' :
  264. dBodyAddForce (body[BODY1],-4,0,0);
  265. break;
  266. case 'a' :
  267. case 'A' :
  268. dBodyAddForce (body[BODY1],0,40,0);
  269. break;
  270. case 's' :
  271. case 'S' :
  272. dBodyAddForce (body[BODY1],0,-40,0);
  273. break;
  274. case 'z' :
  275. case 'Z' :
  276. dBodyAddForce (body[BODY1],0,0,4);
  277. break;
  278. case 'x' :
  279. case 'X' :
  280. dBodyAddForce (body[BODY1],0,0,-4);
  281. break;
  282. // Torque
  283. case 'e':
  284. case 'E':
  285. dBodyAddTorque (body[BODY1],0.1,0,0);
  286. break;
  287. case 'r':
  288. case 'R':
  289. dBodyAddTorque (body[BODY1],-0.1,0,0);
  290. break;
  291. case 'd':
  292. case 'D':
  293. dBodyAddTorque (body[BODY1],0, 0.1,0);
  294. break;
  295. case 'f':
  296. case 'F':
  297. dBodyAddTorque (body[BODY1],0,-0.1,0);
  298. break;
  299. case 'c':
  300. case 'C':
  301. dBodyAddTorque (body[BODY1],0.1,0,0);
  302. break;
  303. case 'v':
  304. case 'V':
  305. dBodyAddTorque (body[BODY1],-0.1,0,0);
  306. break;
  307. case 't':
  308. case 'T':
  309. if (joint->getType() == dJointTypePiston)
  310. dJointAddPistonForce (joint->id(),1);
  311. else
  312. dJointAddSliderForce (joint->id(),1);
  313. break;
  314. case 'y':
  315. case 'Y':
  316. if (joint->getType() == dJointTypePiston)
  317. dJointAddPistonForce (joint->id(),-1);
  318. else
  319. dJointAddSliderForce (joint->id(),-1);
  320. break;
  321. case '8' :
  322. dJointAttach(joint->id(), body[0], 0);
  323. break;
  324. case '9' :
  325. dJointAttach(joint->id(), 0, body[0]);
  326. break;
  327. case 'i':
  328. case 'I' :
  329. joint->setParam (dParamLoStop, 0);
  330. joint->setParam (dParamHiStop, 0);
  331. break;
  332. case 'o':
  333. case 'O' :
  334. joint->setParam (dParamLoStop2, 0);
  335. joint->setParam (dParamHiStop2, 0);
  336. break;
  337. case 'k':
  338. case 'K':
  339. joint->setParam (dParamLoStop2, -45.0*3.14159267/180.0);
  340. joint->setParam (dParamHiStop2, 45.0*3.14159267/180.0);
  341. break;
  342. case 'l':
  343. case 'L':
  344. joint->setParam (dParamLoStop2, -dInfinity);
  345. joint->setParam (dParamHiStop2, dInfinity);
  346. break;
  347. // Velocity of joint
  348. case ',':
  349. case '<' :
  350. {
  351. dReal vel = joint->getParam (dParamVel) - VEL_INC;
  352. joint->setParam (dParamVel, vel);
  353. std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n';
  354. }
  355. break;
  356. case '.':
  357. case '>' :
  358. {
  359. dReal vel = joint->getParam (dParamVel) + VEL_INC;
  360. joint->setParam (dParamVel, vel);
  361. std::cout<<"Velocity = "<<vel<<" FMax = 2"<<'\n';
  362. }
  363. break;
  364. case 'p' :
  365. case 'P' :
  366. {
  367. switch (joint->getType() )
  368. {
  369. case dJointTypeSlider :
  370. {
  371. dSliderJoint *sj = reinterpret_cast<dSliderJoint *> (joint);
  372. std::cout<<"Position ="<<sj->getPosition() <<"\n";
  373. }
  374. break;
  375. case dJointTypePiston :
  376. {
  377. dPistonJoint *rj = reinterpret_cast<dPistonJoint *> (joint);
  378. std::cout<<"Position ="<<rj->getPosition() <<"\n";
  379. }
  380. break;
  381. default:
  382. {} // keep the compiler happy
  383. }
  384. }
  385. break;
  386. case '+' :
  387. (++tc) %= 4;
  388. setPositionBodies (tc);
  389. break;
  390. case '-' :
  391. (--tc) %= 4;
  392. setPositionBodies (tc);
  393. break;
  394. }
  395. }
  396. static void drawBox (dGeomID id, int R, int G, int B)
  397. {
  398. if (!id)
  399. return;
  400. const dReal *pos = dGeomGetPosition (id);
  401. const dReal *rot = dGeomGetRotation (id);
  402. dsSetColor (R,G,B);
  403. dVector3 l;
  404. dGeomBoxGetLengths (id, l);
  405. dsDrawBox (pos, rot, l);
  406. }
  407. // simulation loop
  408. static void simLoop (int pause)
  409. {
  410. const dReal *rot;
  411. dVector3 ax;
  412. dReal l=0;
  413. switch (joint->getType() )
  414. {
  415. case dJointTypeSlider :
  416. ( (dSliderJoint *) joint)->getAxis (ax);
  417. l = ( (dSliderJoint *) joint)->getPosition();
  418. break;
  419. case dJointTypePiston :
  420. ( (dPistonJoint *) joint)->getAxis (ax);
  421. l = ( (dPistonJoint *) joint)->getPosition();
  422. break;
  423. default:
  424. {} // keep the compiler happy
  425. }
  426. if (!pause)
  427. {
  428. double simstep = 0.01; // 1ms simulation steps
  429. double dt = dsElapsedTime();
  430. int nrofsteps = (int) ceilf (dt/simstep);
  431. if (!nrofsteps)
  432. nrofsteps = 1;
  433. for (int i=0; i<nrofsteps && !pause; i++)
  434. {
  435. dSpaceCollide (space,0,&nearCallback);
  436. dWorldStep (world, simstep);
  437. dJointGroupEmpty (contactgroup);
  438. }
  439. update();
  440. dReal radius, length;
  441. dsSetTexture (DS_WOOD);
  442. drawBox (geom[BODY2], 1,1,0);
  443. drawBox (geom[RECT], 0,0,1);
  444. if ( geom[BODY1] )
  445. {
  446. const dReal *pos = dGeomGetPosition (geom[BODY1]);
  447. rot = dGeomGetRotation (geom[BODY1]);
  448. dsSetColor (0,0,1);
  449. dGeomCapsuleGetParams (geom[BODY1], &radius, &length);
  450. dsDrawCapsule (pos, rot, length, radius);
  451. }
  452. drawBox (geom[OBS], 1,0,1);
  453. // Draw the prismatic axis
  454. if ( geom[BODY1] )
  455. {
  456. const dReal *pos = dGeomGetPosition (geom[BODY1]);
  457. rot = dGeomGetRotation (geom[BODY2]);
  458. dVector3 p;
  459. p[X] = pos[X] - l*ax[X];
  460. p[Y] = pos[Y] - l*ax[Y];
  461. p[Z] = pos[Z] - l*ax[Z];
  462. dsSetColor (1,0,0);
  463. dsDrawCylinder (p, rot, 3.75, 1.05*AXIS_RADIUS);
  464. }
  465. if (joint->getType() == dJointTypePiston )
  466. {
  467. dVector3 anchor;
  468. dJointGetPistonAnchor(joint->id(), anchor);
  469. // Draw the rotoide axis
  470. rot = dGeomGetRotation (geom[BODY2]);
  471. dsSetColor (1,0.5,0);
  472. dsDrawCylinder (anchor, rot, 4, AXIS_RADIUS);
  473. dsSetColor (0,1,1);
  474. rot = dGeomGetRotation (geom[BODY1]);
  475. dsDrawSphere (anchor, rot, 1.5*RADIUS);
  476. }
  477. }
  478. }
  479. void Help (char **argv)
  480. {
  481. printf ("%s ", argv[0]);
  482. printf (" -h | --help : print this help\n");
  483. printf (" -s | --slider : Set the joint as a slider\n");
  484. printf (" -p | --piston : Set the joint as a Piston. (Default joint)\n");
  485. printf (" -1 | --offset1 : Create an offset between the 2 bodies\n");
  486. printf (" Offset one of the body by z=-0.5 and keep the anchor\n");
  487. printf (" point in the middle of the fixed body\n");
  488. printf (" -2 | --offset2 : Create an offset between the 2 bodies\n");
  489. printf (" Offset one of the body by z=-0.5 and set the anchor\n");
  490. printf (" point in the middle of the movable body\n");
  491. printf (" -3 | --offset3 : Create an offset between the 2 bodies\n");
  492. printf (" Offset one of the body by z=-0.5 and set the anchor\n");
  493. printf (" point in the middle of the 2 bodies\n");
  494. printf (" -t | --texture-path path : Path to the texture.\n");
  495. printf (" Default = %s\n", DRAWSTUFF_TEXTURE_PATH);
  496. printf (" -n | --notFixed : In free space with no gravity mode");
  497. printf ("-notex : Don't use texture\n");
  498. printf ("-noshadow : No shadow\n");
  499. printf ("-noshadows : No shadows\n");
  500. printf ("-pause : Initial pause\n");
  501. printf ("--------------------------------------------------\n");
  502. printf ("Hit any key to continue:");
  503. getchar();
  504. exit (0);
  505. }
  506. int main (int argc, char **argv)
  507. {
  508. dInitODE2(0);
  509. bool fixed = true;
  510. // setup pointers to drawstuff callback functions
  511. dsFunctions fn;
  512. fn.version = DS_VERSION;
  513. fn.start = &start;
  514. fn.step = &simLoop;
  515. fn.command = &command;
  516. fn.stop = 0;
  517. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  518. dVector3 offset;
  519. dSetZero (offset, 4);
  520. // Default test case
  521. if (argc >= 2 )
  522. {
  523. for (int i=1; i < argc; ++i)
  524. {
  525. //static int tata = 0;
  526. if (1)
  527. {
  528. if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) )
  529. Help (argv);
  530. if ( 0 == strcmp ("-s", argv[i]) || 0 == strcmp ("--slider", argv[i]) )
  531. type = dJointTypeSlider;
  532. if ( 0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) )
  533. {
  534. int j = i+1;
  535. if ( j >= argc || // Check if we have enough arguments
  536. argv[j][0] == '\0' || // We should have a path here
  537. argv[j][0] == '-' ) // We should have a path not a command line
  538. Help (argv);
  539. else
  540. fn.path_to_textures = argv[++i]; // Increase i since we use this argument
  541. }
  542. }
  543. if ( 0 == strcmp ("-1", argv[i]) || 0 == strcmp ("--offset1", argv[i]) )
  544. tc = 1;
  545. if ( 0 == strcmp ("-2", argv[i]) || 0 == strcmp ("--offset2", argv[i]) )
  546. tc = 2;
  547. if ( 0 == strcmp ("-3", argv[i]) || 0 == strcmp ("--offset3", argv[i]) )
  548. tc = 3;
  549. if (0 == strcmp ("-n", argv[i]) || 0 == strcmp ("--notFixed", argv[i]) )
  550. fixed = false;
  551. }
  552. }
  553. world = dWorldCreate();
  554. dWorldSetERP (world, 0.8);
  555. space = dSimpleSpaceCreate (0);
  556. contactgroup = dJointGroupCreate (0);
  557. geom[GROUND] = dCreatePlane (space, 0,0,1,0);
  558. dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]);
  559. dGeomSetCollideBits (geom[GROUND], catBits[ALL]);
  560. dMass m;
  561. dMatrix3 R;
  562. // Create the Obstacle
  563. geom[OBS] = dCreateBox (space, OBS_SIDES[0], OBS_SIDES[1], OBS_SIDES[2]);
  564. dGeomSetCategoryBits (geom[OBS], catBits[OBS]);
  565. dGeomSetCollideBits (geom[OBS], catBits[ALL]);
  566. //Rotation of 45deg around y
  567. dRFromAxisAndAngle (R, 1,1,0, -0.25*PI);
  568. dGeomSetRotation (geom[OBS], R);
  569. dGeomSetPosition (geom[OBS], 1.95, -0.2, 0.5);
  570. //Rotation of 90deg around y
  571. // Will orient the Z axis along X
  572. dRFromAxisAndAngle (R, 0,1,0, -0.5*PI);
  573. // Create Body2 (Wiil be attached to the world)
  574. body[BODY2] = dBodyCreate (world);
  575. // Main axis of cylinder is along X=1
  576. dMassSetBox (&m, 1, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]);
  577. dMassAdjust (&m, Mass1);
  578. geom[BODY2] = dCreateBox (space, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]);
  579. dGeomSetBody (geom[BODY2], body[BODY2]);
  580. dGeomSetOffsetRotation (geom[BODY2], R);
  581. dGeomSetCategoryBits (geom[BODY2], catBits[BODY2]);
  582. dGeomSetCollideBits (geom[BODY2], catBits[ALL] & (~catBits[BODY1]) );
  583. dBodySetMass (body[BODY2], &m);
  584. // Create Body 1 (Slider on the prismatic axis)
  585. body[BODY1] = dBodyCreate (world);
  586. // Main axis of capsule is along X=1
  587. dMassSetCapsule (&m, 1, 1, RADIUS, BODY1_LENGTH);
  588. dMassAdjust (&m, Mass1);
  589. geom[BODY1] = dCreateCapsule (space, RADIUS, BODY1_LENGTH);
  590. dGeomSetBody (geom[BODY1], body[BODY1]);
  591. dGeomSetOffsetRotation (geom[BODY1], R);
  592. dGeomSetCategoryBits (geom[BODY1], catBits[BODY1]);
  593. dGeomSetCollideBits (geom[BODY1], catBits[ALL] & ~catBits[BODY2] & ~catBits[RECT]);
  594. dMass mRect;
  595. dMassSetBox (&mRect, 1, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]);
  596. dMassAdd (&m, &mRect);
  597. // TODO: translate m?
  598. geom[RECT] = dCreateBox (space, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]);
  599. dGeomSetBody (geom[RECT], body[BODY1]);
  600. dGeomSetOffsetPosition (geom[RECT],
  601. (BODY1_LENGTH-RECT_SIDES[0]) /2.0,
  602. 0.0,
  603. -RADIUS -RECT_SIDES[2]/2.0);
  604. dGeomSetCategoryBits (geom[RECT], catBits[RECT]);
  605. dGeomSetCollideBits (geom[RECT], catBits[ALL] & (~catBits[BODY1]) );
  606. dBodySetMass (body[BODY1], &m);
  607. setPositionBodies (tc);
  608. if ( fixed )
  609. {
  610. // Attache external cylinder to the world
  611. dJointID fixed = dJointCreateFixed (world,0);
  612. dJointAttach (fixed , NULL, body[BODY2]);
  613. dJointSetFixed (fixed );
  614. dWorldSetGravity (world,0,0,-0.8);
  615. }
  616. else
  617. {
  618. dWorldSetGravity (world,0,0,0);
  619. }
  620. // The static is here only to help debugging
  621. switch (type)
  622. {
  623. case dJointTypeSlider :
  624. {
  625. dSliderJoint *sj = new dSliderJoint (world, 0);
  626. sj->attach (body[BODY1], body[BODY2]);
  627. sj->setAxis (1, 0, 0);
  628. joint = sj;
  629. }
  630. break;
  631. case dJointTypePiston : // fall through default
  632. default:
  633. {
  634. dPistonJoint *pj = new dPistonJoint (world, 0);
  635. pj->attach (body[BODY1], body[BODY2]);
  636. pj->setAxis (1, 0, 0);
  637. dJointSetPistonAnchor(pj->id(), anchor[X], anchor[Y], anchor[Z]);
  638. joint = pj;
  639. }
  640. break;
  641. };
  642. // run simulation
  643. dsSimulationLoop (argc, argv, DS_SIMULATION_DEFAULT_WIDTH, DS_SIMULATION_DEFAULT_HEIGHT, &fn);
  644. delete joint;
  645. dJointGroupDestroy (contactgroup);
  646. dSpaceDestroy (space);
  647. dWorldDestroy (world);
  648. dCloseODE();
  649. return 0;
  650. }