demo_boxstack.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  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. #include <ode/ode.h>
  23. #include <drawstuff/drawstuff.h>
  24. #include "texturepath.h"
  25. #ifdef _MSC_VER
  26. #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
  27. #endif
  28. //<---- Icosahedron ---->
  29. unsigned int Sphere_pointcount = 42;
  30. unsigned int Sphere_planecount = 80;
  31. dReal Sphere_points[126]={
  32. 0.000000,0.000000,-0.300000,
  33. 0.217080,-0.157716,-0.134164,
  34. -0.082915,-0.255192,-0.134164,
  35. -0.268327,0.000000,-0.134164,
  36. -0.082915,0.255192,-0.134164,
  37. 0.217080,0.157716,-0.134164,
  38. 0.082915,-0.255192,0.134164,
  39. -0.217080,-0.157716,0.134164,
  40. -0.217080,0.157716,0.134164,
  41. 0.082915,0.255192,0.134164,
  42. 0.268327,0.000000,0.134164,
  43. 0.000000,0.000000,0.300000,
  44. 0.127597,-0.092703,-0.255196,
  45. -0.048737,-0.149999,-0.255196,
  46. 0.078861,-0.242703,-0.157721,
  47. 0.127597,0.092703,-0.255196,
  48. 0.255194,0.000000,-0.157721,
  49. -0.157719,0.000000,-0.255195,
  50. -0.206457,-0.149999,-0.157721,
  51. -0.048737,0.149999,-0.255196,
  52. -0.206457,0.149999,-0.157721,
  53. 0.078861,0.242703,-0.157721,
  54. 0.285317,0.092704,0.000000,
  55. 0.285317,-0.092704,0.000000,
  56. 0.176336,-0.242705,0.000000,
  57. 0.000000,-0.300000,0.000000,
  58. -0.176336,-0.242705,0.000000,
  59. -0.285317,-0.092704,0.000000,
  60. -0.285317,0.092704,0.000000,
  61. -0.176336,0.242705,0.000000,
  62. 0.000000,0.300000,0.000000,
  63. 0.176336,0.242705,0.000000,
  64. 0.206457,-0.149999,0.157721,
  65. -0.078861,-0.242703,0.157721,
  66. -0.255194,0.000000,0.157721,
  67. -0.078861,0.242703,0.157721,
  68. 0.206457,0.149999,0.157721,
  69. 0.157719,0.000000,0.255195,
  70. 0.048737,-0.149999,0.255196,
  71. -0.127597,-0.092703,0.255196,
  72. -0.127597,0.092703,0.255196,
  73. 0.048737,0.149999,0.255196
  74. };
  75. unsigned int Sphere_polygons[]={
  76. 3,14,12,1,
  77. 3,12,14,13,
  78. 3,2,13,14,
  79. 3,13,0,12,
  80. 3,16,1,12,
  81. 3,12,15,16,
  82. 3,5,16,15,
  83. 3,12,0,15,
  84. 3,18,13,2,
  85. 3,13,18,17,
  86. 3,3,17,18,
  87. 3,17,0,13,
  88. 3,20,17,3,
  89. 3,17,20,19,
  90. 3,4,19,20,
  91. 3,19,0,17,
  92. 3,21,19,4,
  93. 3,19,21,15,
  94. 3,5,15,21,
  95. 3,15,0,19,
  96. 3,23,1,16,
  97. 3,16,22,23,
  98. 3,10,23,22,
  99. 3,22,16,5,
  100. 3,25,2,14,
  101. 3,14,24,25,
  102. 3,6,25,24,
  103. 3,24,14,1,
  104. 3,27,3,18,
  105. 3,18,26,27,
  106. 3,7,27,26,
  107. 3,26,18,2,
  108. 3,29,4,20,
  109. 3,20,28,29,
  110. 3,8,29,28,
  111. 3,28,20,3,
  112. 3,31,5,21,
  113. 3,21,30,31,
  114. 3,9,31,30,
  115. 3,30,21,4,
  116. 3,32,23,10,
  117. 3,23,32,24,
  118. 3,6,24,32,
  119. 3,24,1,23,
  120. 3,33,25,6,
  121. 3,25,33,26,
  122. 3,7,26,33,
  123. 3,26,2,25,
  124. 3,34,27,7,
  125. 3,27,34,28,
  126. 3,8,28,34,
  127. 3,28,3,27,
  128. 3,35,29,8,
  129. 3,29,35,30,
  130. 3,9,30,35,
  131. 3,30,4,29,
  132. 3,36,31,9,
  133. 3,31,36,22,
  134. 3,10,22,36,
  135. 3,22,5,31,
  136. 3,38,6,32,
  137. 3,32,37,38,
  138. 3,11,38,37,
  139. 3,37,32,10,
  140. 3,39,7,33,
  141. 3,33,38,39,
  142. 3,11,39,38,
  143. 3,38,33,6,
  144. 3,40,8,34,
  145. 3,34,39,40,
  146. 3,11,40,39,
  147. 3,39,34,7,
  148. 3,41,9,35,
  149. 3,35,40,41,
  150. 3,11,41,40,
  151. 3,40,35,8,
  152. 3,37,10,36,
  153. 3,36,41,37,
  154. 3,11,37,41,
  155. 3,41,36,9,
  156. };
  157. dReal Sphere_planes[]={
  158. 0.471317,-0.583121,-0.661687,0.283056,
  159. 0.187594,-0.577345,-0.794658,0.280252,
  160. -0.038547,-0.748789,-0.661687,0.283056,
  161. 0.102381,-0.315090,-0.943523,0.283057,
  162. 0.700228,-0.268049,-0.661688,0.283056,
  163. 0.607060,0.000000,-0.794656,0.280252,
  164. 0.700228,0.268049,-0.661688,0.283056,
  165. 0.331305,0.000000,-0.943524,0.283057,
  166. -0.408939,-0.628443,-0.661686,0.283056,
  167. -0.491119,-0.356821,-0.794657,0.280252,
  168. -0.724044,-0.194735,-0.661694,0.283057,
  169. -0.268034,-0.194737,-0.943523,0.283057,
  170. -0.724044,0.194735,-0.661694,0.283057,
  171. -0.491119,0.356821,-0.794657,0.280252,
  172. -0.408939,0.628443,-0.661686,0.283056,
  173. -0.268034,0.194737,-0.943523,0.283057,
  174. -0.038547,0.748789,-0.661687,0.283056,
  175. 0.187594,0.577345,-0.794658,0.280252,
  176. 0.471317,0.583121,-0.661687,0.283056,
  177. 0.102381,0.315090,-0.943523,0.283057,
  178. 0.904981,-0.268049,-0.330393,0.283056,
  179. 0.982246,0.000000,-0.187599,0.280252,
  180. 0.992077,0.000000,0.125631,0.283057,
  181. 0.904981,0.268049,-0.330393,0.283056,
  182. 0.024726,-0.943519,-0.330396,0.283056,
  183. 0.303531,-0.934171,-0.187598,0.280251,
  184. 0.306568,-0.943519,0.125651,0.283056,
  185. 0.534590,-0.777851,-0.330395,0.283056,
  186. -0.889698,-0.315092,-0.330386,0.283056,
  187. -0.794656,-0.577348,-0.187595,0.280251,
  188. -0.802607,-0.583125,0.125648,0.283055,
  189. -0.574584,-0.748793,-0.330397,0.283055,
  190. -0.574584,0.748793,-0.330397,0.283055,
  191. -0.794656,0.577348,-0.187595,0.280251,
  192. -0.802607,0.583125,0.125648,0.283055,
  193. -0.889698,0.315092,-0.330386,0.283056,
  194. 0.534590,0.777851,-0.330395,0.283056,
  195. 0.303531,0.934171,-0.187598,0.280251,
  196. 0.306568,0.943519,0.125651,0.283056,
  197. 0.024726,0.943519,-0.330396,0.283056,
  198. 0.889698,-0.315092,0.330386,0.283056,
  199. 0.794656,-0.577348,0.187595,0.280251,
  200. 0.574584,-0.748793,0.330397,0.283055,
  201. 0.802607,-0.583125,-0.125648,0.283055,
  202. -0.024726,-0.943519,0.330396,0.283055,
  203. -0.303531,-0.934171,0.187598,0.280251,
  204. -0.534590,-0.777851,0.330395,0.283056,
  205. -0.306568,-0.943519,-0.125651,0.283056,
  206. -0.904981,-0.268049,0.330393,0.283056,
  207. -0.982246,0.000000,0.187599,0.280252,
  208. -0.904981,0.268049,0.330393,0.283056,
  209. -0.992077,0.000000,-0.125631,0.283057,
  210. -0.534590,0.777851,0.330395,0.283056,
  211. -0.303531,0.934171,0.187598,0.280251,
  212. -0.024726,0.943519,0.330396,0.283055,
  213. -0.306568,0.943519,-0.125651,0.283056,
  214. 0.574584,0.748793,0.330397,0.283055,
  215. 0.794656,0.577348,0.187595,0.280251,
  216. 0.889698,0.315092,0.330386,0.283056,
  217. 0.802607,0.583125,-0.125648,0.283055,
  218. 0.408939,-0.628443,0.661686,0.283056,
  219. 0.491119,-0.356821,0.794657,0.280252,
  220. 0.268034,-0.194737,0.943523,0.283057,
  221. 0.724044,-0.194735,0.661694,0.283057,
  222. -0.471317,-0.583121,0.661687,0.283056,
  223. -0.187594,-0.577345,0.794658,0.280252,
  224. -0.102381,-0.315090,0.943523,0.283057,
  225. 0.038547,-0.748789,0.661687,0.283056,
  226. -0.700228,0.268049,0.661688,0.283056,
  227. -0.607060,0.000000,0.794656,0.280252,
  228. -0.331305,0.000000,0.943524,0.283057,
  229. -0.700228,-0.268049,0.661688,0.283056,
  230. 0.038547,0.748789,0.661687,0.283056,
  231. -0.187594,0.577345,0.794658,0.280252,
  232. -0.102381,0.315090,0.943523,0.283057,
  233. -0.471317,0.583121,0.661687,0.283056,
  234. 0.724044,0.194735,0.661694,0.283057,
  235. 0.491119,0.356821,0.794657,0.280252,
  236. 0.268034,0.194737,0.943523,0.283057,
  237. 0.408939,0.628443,0.661686,0.283056,
  238. };
  239. //<---- Convex Object
  240. dReal planes[]= // planes for a cube, these should coincide with the face array
  241. {
  242. 1.0f ,0.0f ,0.0f ,0.25f,
  243. 0.0f ,1.0f ,0.0f ,0.25f,
  244. 0.0f ,0.0f ,1.0f ,0.25f,
  245. -1.0f,0.0f ,0.0f ,0.25f,
  246. 0.0f ,-1.0f,0.0f ,0.25f,
  247. 0.0f ,0.0f ,-1.0f,0.25f
  248. /*
  249. 1.0f ,0.0f ,0.0f ,2.0f,
  250. 0.0f ,1.0f ,0.0f ,1.0f,
  251. 0.0f ,0.0f ,1.0f ,1.0f,
  252. 0.0f ,0.0f ,-1.0f,1.0f,
  253. 0.0f ,-1.0f,0.0f ,1.0f,
  254. -1.0f,0.0f ,0.0f ,0.0f
  255. */
  256. };
  257. const unsigned int planecount=6;
  258. dReal points[]= // points for a cube
  259. {
  260. 0.25f,0.25f,0.25f, // point 0
  261. -0.25f,0.25f,0.25f, // point 1
  262. 0.25f,-0.25f,0.25f, // point 2
  263. -0.25f,-0.25f,0.25f,// point 3
  264. 0.25f,0.25f,-0.25f, // point 4
  265. -0.25f,0.25f,-0.25f,// point 5
  266. 0.25f,-0.25f,-0.25f,// point 6
  267. -0.25f,-0.25f,-0.25f,// point 7
  268. };
  269. const unsigned int pointcount=8;
  270. unsigned int polygons[] = //Polygons for a cube (6 squares)
  271. {
  272. 4,0,2,6,4, // positive X
  273. 4,1,0,4,5, // positive Y
  274. 4,0,1,3,2, // positive Z
  275. 4,3,1,5,7, // negative X
  276. 4,2,3,7,6, // negative Y
  277. 4,5,4,6,7, // negative Z
  278. };
  279. //----> Convex Object
  280. // select correct drawing functions
  281. #ifdef dDOUBLE
  282. #define dsDrawBox dsDrawBoxD
  283. #define dsDrawSphere dsDrawSphereD
  284. #define dsDrawCylinder dsDrawCylinderD
  285. #define dsDrawCapsule dsDrawCapsuleD
  286. #define dsDrawConvex dsDrawConvexD
  287. #endif
  288. // some constants
  289. #define NUM 100 // max number of objects
  290. #define DENSITY (5.0) // density of all objects
  291. #define GPB 3 // maximum number of geometries per body
  292. #define MAX_CONTACTS 8 // maximum number of contact points per body
  293. #define MAX_FEEDBACKNUM 20
  294. #define GRAVITY REAL(0.5)
  295. #define USE_GEOM_OFFSET 1
  296. // dynamics and collision objects
  297. struct MyObject {
  298. dBodyID body; // the body
  299. dGeomID geom[GPB]; // geometries representing this body
  300. };
  301. static int num=0; // number of objects in simulation
  302. static int nextobj=0; // next object to recycle if num==NUM
  303. static dWorldID world;
  304. static dSpaceID space;
  305. static MyObject obj[NUM];
  306. static dJointGroupID contactgroup;
  307. static int selected = -1; // selected object
  308. static int show_aabb = 0; // show geom AABBs?
  309. static int show_contacts = 0; // show contact points?
  310. static int random_pos = 1; // drop objects from random position?
  311. static int write_world = 0;
  312. static int show_body = 0;
  313. struct MyFeedback {
  314. dJointFeedback fb;
  315. bool first;
  316. };
  317. static int doFeedback=0;
  318. static MyFeedback feedbacks[MAX_FEEDBACKNUM];
  319. static int fbnum=0;
  320. // this is called by dSpaceCollide when two objects in space are
  321. // potentially colliding.
  322. static void nearCallback (void *data, dGeomID o1, dGeomID o2)
  323. {
  324. int i;
  325. // if (o1->body && o2->body) return;
  326. // exit without doing anything if the two bodies are connected by a joint
  327. dBodyID b1 = dGeomGetBody(o1);
  328. dBodyID b2 = dGeomGetBody(o2);
  329. if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return;
  330. dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box
  331. for (i=0; i<MAX_CONTACTS; i++) {
  332. contact[i].surface.mode = dContactBounce | dContactSoftCFM;
  333. contact[i].surface.mu = dInfinity;
  334. contact[i].surface.mu2 = 0;
  335. contact[i].surface.bounce = 0.1;
  336. contact[i].surface.bounce_vel = 0.1;
  337. contact[i].surface.soft_cfm = 0.01;
  338. }
  339. if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
  340. sizeof(dContact))) {
  341. dMatrix3 RI;
  342. dRSetIdentity (RI);
  343. const dReal ss[3] = {0.02,0.02,0.02};
  344. for (i=0; i<numc; i++) {
  345. dJointID c = dJointCreateContact (world,contactgroup,contact+i);
  346. dJointAttach (c,b1,b2);
  347. if (show_contacts) dsDrawBox (contact[i].geom.pos,RI,ss);
  348. if (doFeedback && (b1==obj[selected].body || b2==obj[selected].body))
  349. {
  350. if (fbnum<MAX_FEEDBACKNUM)
  351. {
  352. feedbacks[fbnum].first = b1==obj[selected].body;
  353. dJointSetFeedback (c,&feedbacks[fbnum++].fb);
  354. }
  355. else fbnum++;
  356. }
  357. }
  358. }
  359. }
  360. // start simulation - set viewpoint
  361. static void start()
  362. {
  363. dAllocateODEDataForThread(dAllocateMaskAll);
  364. static float xyz[3] = {2.1640f,-1.3079f,1.7600f};
  365. static float hpr[3] = {125.5000f,-17.0000f,0.0000f};
  366. dsSetViewpoint (xyz,hpr);
  367. printf ("To drop another object, press:\n");
  368. printf (" b for box.\n");
  369. printf (" s for sphere.\n");
  370. printf (" c for capsule.\n");
  371. printf (" y for cylinder.\n");
  372. printf (" v for a convex object.\n");
  373. printf (" x for a composite object.\n");
  374. printf ("To select an object, press space.\n");
  375. printf ("To disable the selected object, press d.\n");
  376. printf ("To enable the selected object, press e.\n");
  377. printf ("To dump transformation data for the selected object, press p.\n");
  378. printf ("To toggle showing the geom AABBs, press a.\n");
  379. printf ("To toggle showing the contact points, press t.\n");
  380. printf ("To toggle dropping from random position/orientation, press r.\n");
  381. printf ("To save the current state to 'state.dif', press 1.\n");
  382. printf ("To show joint feedbacks of selected object, press f.\n");
  383. }
  384. char locase (char c)
  385. {
  386. if (c >= 'A' && c <= 'Z') return c - ('a'-'A');
  387. else return c;
  388. }
  389. // called when a key pressed
  390. static void command (int cmd)
  391. {
  392. size_t i;
  393. int j,k;
  394. dReal sides[3];
  395. dMass m;
  396. int setBody;
  397. cmd = locase (cmd);
  398. if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y' || cmd == 'v')
  399. {
  400. setBody = 0;
  401. if (num < NUM) {
  402. i = num;
  403. num++;
  404. }
  405. else {
  406. i = nextobj;
  407. nextobj++;
  408. if (nextobj >= num) nextobj = 0;
  409. // destroy the body and geoms for slot i
  410. dBodyDestroy (obj[i].body);
  411. for (k=0; k < GPB; k++) {
  412. if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]);
  413. }
  414. memset (&obj[i],0,sizeof(obj[i]));
  415. }
  416. obj[i].body = dBodyCreate (world);
  417. for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1;
  418. dMatrix3 R;
  419. if (random_pos)
  420. {
  421. dBodySetPosition (obj[i].body,
  422. dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2);
  423. dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
  424. dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
  425. }
  426. else
  427. {
  428. dReal maxheight = 0;
  429. for (k=0; k<num; k++)
  430. {
  431. const dReal *pos = dBodyGetPosition (obj[k].body);
  432. if (pos[2] > maxheight) maxheight = pos[2];
  433. }
  434. dBodySetPosition (obj[i].body, 0,0,maxheight+1);
  435. dRSetIdentity (R);
  436. //dRFromAxisAndAngle (R,0,0,1,/*dRandReal()*10.0-5.0*/0);
  437. }
  438. dBodySetRotation (obj[i].body,R);
  439. dBodySetData (obj[i].body,(void*) i);
  440. if (cmd == 'b') {
  441. dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
  442. obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]);
  443. }
  444. else if (cmd == 'c') {
  445. sides[0] *= 0.5;
  446. dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]);
  447. obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]);
  448. }
  449. //<---- Convex Object
  450. else if (cmd == 'v')
  451. {
  452. dMassSetBox (&m,DENSITY,0.25,0.25,0.25);
  453. #if 0
  454. obj[i].geom[0] = dCreateConvex (space,
  455. planes,
  456. planecount,
  457. points,
  458. pointcount,
  459. polygons);
  460. #else
  461. obj[i].geom[0] = dCreateConvex (space,
  462. Sphere_planes,
  463. Sphere_planecount,
  464. Sphere_points,
  465. Sphere_pointcount,
  466. Sphere_polygons);
  467. #endif
  468. }
  469. //----> Convex Object
  470. else if (cmd == 'y') {
  471. dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]);
  472. obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]);
  473. }
  474. else if (cmd == 's') {
  475. sides[0] *= 0.5;
  476. dMassSetSphere (&m,DENSITY,sides[0]);
  477. obj[i].geom[0] = dCreateSphere (space,sides[0]);
  478. }
  479. else if (cmd == 'x' && USE_GEOM_OFFSET) {
  480. setBody = 1;
  481. // start accumulating masses for the encapsulated geometries
  482. dMass m2;
  483. dMassSetZero (&m);
  484. dReal dpos[GPB][3]; // delta-positions for encapsulated geometries
  485. dMatrix3 drot[GPB];
  486. // set random delta positions
  487. for (j=0; j<GPB; j++) {
  488. for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15;
  489. }
  490. for (k=0; k<GPB; k++) {
  491. if (k==0) {
  492. dReal radius = dRandReal()*0.25+0.05;
  493. obj[i].geom[k] = dCreateSphere (space,radius);
  494. dMassSetSphere (&m2,DENSITY,radius);
  495. }
  496. else if (k==1) {
  497. obj[i].geom[k] = dCreateBox (space,sides[0],sides[1],sides[2]);
  498. dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]);
  499. }
  500. else {
  501. dReal radius = dRandReal()*0.1+0.05;
  502. dReal length = dRandReal()*1.0+0.1;
  503. obj[i].geom[k] = dCreateCapsule (space,radius,length);
  504. dMassSetCapsule (&m2,DENSITY,3,radius,length);
  505. }
  506. dRFromAxisAndAngle (drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
  507. dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
  508. dMassRotate (&m2,drot[k]);
  509. dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]);
  510. // add to the total mass
  511. dMassAdd (&m,&m2);
  512. }
  513. for (k=0; k<GPB; k++) {
  514. dGeomSetBody (obj[i].geom[k],obj[i].body);
  515. dGeomSetOffsetPosition (obj[i].geom[k],
  516. dpos[k][0]-m.c[0],
  517. dpos[k][1]-m.c[1],
  518. dpos[k][2]-m.c[2]);
  519. dGeomSetOffsetRotation(obj[i].geom[k], drot[k]);
  520. }
  521. dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]);
  522. dBodySetMass (obj[i].body,&m);
  523. }
  524. else if (cmd == 'x') {
  525. dGeomID g2[GPB]; // encapsulated geometries
  526. dReal dpos[GPB][3]; // delta-positions for encapsulated geometries
  527. // start accumulating masses for the encapsulated geometries
  528. dMass m2;
  529. dMassSetZero (&m);
  530. // set random delta positions
  531. for (j=0; j<GPB; j++) {
  532. for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15;
  533. }
  534. for (k=0; k<GPB; k++) {
  535. obj[i].geom[k] = dCreateGeomTransform (space);
  536. dGeomTransformSetCleanup (obj[i].geom[k],1);
  537. if (k==0) {
  538. dReal radius = dRandReal()*0.25+0.05;
  539. g2[k] = dCreateSphere (0,radius);
  540. dMassSetSphere (&m2,DENSITY,radius);
  541. }
  542. else if (k==1) {
  543. g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]);
  544. dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]);
  545. }
  546. else {
  547. dReal radius = dRandReal()*0.1+0.05;
  548. dReal length = dRandReal()*1.0+0.1;
  549. g2[k] = dCreateCapsule (0,radius,length);
  550. dMassSetCapsule (&m2,DENSITY,3,radius,length);
  551. }
  552. dGeomTransformSetGeom (obj[i].geom[k],g2[k]);
  553. // set the transformation (adjust the mass too)
  554. dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]);
  555. dMatrix3 Rtx;
  556. dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
  557. dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
  558. dGeomSetRotation (g2[k],Rtx);
  559. dMassRotate (&m2,Rtx);
  560. // Translation *after* rotation
  561. dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]);
  562. // add to the total mass
  563. dMassAdd (&m,&m2);
  564. }
  565. // move all encapsulated objects so that the center of mass is (0,0,0)
  566. for (k=0; k<GPB; k++) {
  567. dGeomSetPosition (g2[k],
  568. dpos[k][0]-m.c[0],
  569. dpos[k][1]-m.c[1],
  570. dpos[k][2]-m.c[2]);
  571. }
  572. dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]);
  573. }
  574. if (!setBody)
  575. for (k=0; k < GPB; k++) {
  576. if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body);
  577. }
  578. dBodySetMass (obj[i].body,&m);
  579. }
  580. if (cmd == ' ') {
  581. selected++;
  582. if (selected >= num) selected = 0;
  583. if (selected < 0) selected = 0;
  584. }
  585. else if (cmd == 'd' && selected >= 0 && selected < num) {
  586. dBodyDisable (obj[selected].body);
  587. }
  588. else if (cmd == 'e' && selected >= 0 && selected < num) {
  589. dBodyEnable (obj[selected].body);
  590. }
  591. else if (cmd == 'a') {
  592. show_aabb ^= 1;
  593. }
  594. else if (cmd == 't') {
  595. show_contacts ^= 1;
  596. }
  597. else if (cmd == 'r') {
  598. random_pos ^= 1;
  599. }
  600. else if (cmd == '1') {
  601. write_world = 1;
  602. }
  603. else if (cmd == 'p'&& selected >= 0)
  604. {
  605. const dReal* pos = dGeomGetPosition(obj[selected].geom[0]);
  606. const dReal* rot = dGeomGetRotation(obj[selected].geom[0]);
  607. printf("POSITION:\n\t[%f,%f,%f]\n\n",pos[0],pos[1],pos[2]);
  608. printf("ROTATION:\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\n",
  609. rot[0],rot[1],rot[2],rot[3],
  610. rot[4],rot[5],rot[6],rot[7],
  611. rot[8],rot[9],rot[10],rot[11]);
  612. }
  613. else if (cmd == 'f' && selected >= 0 && selected < num) {
  614. if (dBodyIsEnabled(obj[selected].body))
  615. doFeedback = 1;
  616. }
  617. }
  618. // draw a geom
  619. void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb)
  620. {
  621. int i;
  622. if (!g) return;
  623. if (!pos) pos = dGeomGetPosition (g);
  624. if (!R) R = dGeomGetRotation (g);
  625. int type = dGeomGetClass (g);
  626. if (type == dBoxClass) {
  627. dVector3 sides;
  628. dGeomBoxGetLengths (g,sides);
  629. dsDrawBox (pos,R,sides);
  630. }
  631. else if (type == dSphereClass) {
  632. dsDrawSphere (pos,R,dGeomSphereGetRadius (g));
  633. }
  634. else if (type == dCapsuleClass) {
  635. dReal radius,length;
  636. dGeomCapsuleGetParams (g,&radius,&length);
  637. dsDrawCapsule (pos,R,length,radius);
  638. }
  639. //<---- Convex Object
  640. else if (type == dConvexClass)
  641. {
  642. #if 0
  643. dsDrawConvex(pos,R,planes,
  644. planecount,
  645. points,
  646. pointcount,
  647. polygons);
  648. #else
  649. dsDrawConvex(pos,R,
  650. Sphere_planes,
  651. Sphere_planecount,
  652. Sphere_points,
  653. Sphere_pointcount,
  654. Sphere_polygons);
  655. #endif
  656. }
  657. //----> Convex Object
  658. else if (type == dCylinderClass) {
  659. dReal radius,length;
  660. dGeomCylinderGetParams (g,&radius,&length);
  661. dsDrawCylinder (pos,R,length,radius);
  662. }
  663. else if (type == dGeomTransformClass) {
  664. dGeomID g2 = dGeomTransformGetGeom (g);
  665. const dReal *pos2 = dGeomGetPosition (g2);
  666. const dReal *R2 = dGeomGetRotation (g2);
  667. dVector3 actual_pos;
  668. dMatrix3 actual_R;
  669. dMULTIPLY0_331 (actual_pos,R,pos2);
  670. actual_pos[0] += pos[0];
  671. actual_pos[1] += pos[1];
  672. actual_pos[2] += pos[2];
  673. dMULTIPLY0_333 (actual_R,R,R2);
  674. drawGeom (g2,actual_pos,actual_R,0);
  675. }
  676. if (show_body) {
  677. dBodyID body = dGeomGetBody(g);
  678. if (body) {
  679. const dReal *bodypos = dBodyGetPosition (body);
  680. const dReal *bodyr = dBodyGetRotation (body);
  681. dReal bodySides[3] = { 0.1, 0.1, 0.1 };
  682. dsSetColorAlpha(0,1,0,1);
  683. dsDrawBox(bodypos,bodyr,bodySides);
  684. }
  685. }
  686. if (show_aabb) {
  687. // draw the bounding box for this geom
  688. dReal aabb[6];
  689. dGeomGetAABB (g,aabb);
  690. dVector3 bbpos;
  691. for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]);
  692. dVector3 bbsides;
  693. for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2];
  694. dMatrix3 RI;
  695. dRSetIdentity (RI);
  696. dsSetColorAlpha (1,0,0,0.5);
  697. dsDrawBox (bbpos,RI,bbsides);
  698. }
  699. }
  700. // simulation loop
  701. static void simLoop (int pause)
  702. {
  703. dsSetColor (0,0,2);
  704. dSpaceCollide (space,0,&nearCallback);
  705. if (!pause) dWorldQuickStep (world,0.02);
  706. if (write_world) {
  707. FILE *f = fopen ("state.dif","wt");
  708. if (f) {
  709. dWorldExportDIF (world,f,"X");
  710. fclose (f);
  711. }
  712. write_world = 0;
  713. }
  714. if (doFeedback)
  715. {
  716. if (fbnum>MAX_FEEDBACKNUM)
  717. printf("joint feedback buffer overflow!\n");
  718. else
  719. {
  720. dVector3 sum = {0, 0, 0};
  721. printf("\n");
  722. for (int i=0; i<fbnum; i++) {
  723. dReal* f = feedbacks[i].first?feedbacks[i].fb.f1:feedbacks[i].fb.f2;
  724. printf("%f %f %f\n", f[0], f[1], f[2]);
  725. sum[0] += f[0];
  726. sum[1] += f[1];
  727. sum[2] += f[2];
  728. }
  729. printf("Sum: %f %f %f\n", sum[0], sum[1], sum[2]);
  730. dMass m;
  731. dBodyGetMass(obj[selected].body, &m);
  732. printf("Object G=%f\n", GRAVITY*m.mass);
  733. }
  734. doFeedback = 0;
  735. fbnum = 0;
  736. }
  737. // remove all contact joints
  738. dJointGroupEmpty (contactgroup);
  739. dsSetColor (1,1,0);
  740. dsSetTexture (DS_WOOD);
  741. for (int i=0; i<num; i++) {
  742. for (int j=0; j < GPB; j++) {
  743. if (i==selected) {
  744. dsSetColor (0,0.7,1);
  745. }
  746. else if (! dBodyIsEnabled (obj[i].body)) {
  747. dsSetColor (1,0.8,0);
  748. }
  749. else {
  750. dsSetColor (1,1,0);
  751. }
  752. drawGeom (obj[i].geom[j],0,0,show_aabb);
  753. }
  754. }
  755. }
  756. int main (int argc, char **argv)
  757. {
  758. // setup pointers to drawstuff callback functions
  759. dsFunctions fn;
  760. fn.version = DS_VERSION;
  761. fn.start = &start;
  762. fn.step = &simLoop;
  763. fn.command = &command;
  764. fn.stop = 0;
  765. fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
  766. if(argc==2)
  767. {
  768. fn.path_to_textures = argv[1];
  769. }
  770. // create world
  771. dInitODE2(0);
  772. world = dWorldCreate();
  773. space = dHashSpaceCreate (0);
  774. contactgroup = dJointGroupCreate (0);
  775. dWorldSetGravity (world,0,0,-GRAVITY);
  776. dWorldSetCFM (world,1e-5);
  777. dWorldSetAutoDisableFlag (world,1);
  778. #if 1
  779. dWorldSetAutoDisableAverageSamplesCount( world, 10 );
  780. #endif
  781. dWorldSetLinearDamping(world, 0.00001);
  782. dWorldSetAngularDamping(world, 0.005);
  783. dWorldSetMaxAngularSpeed(world, 200);
  784. dWorldSetContactMaxCorrectingVel (world,0.1);
  785. dWorldSetContactSurfaceLayer (world,0.001);
  786. dCreatePlane (space,0,0,1,0);
  787. memset (obj,0,sizeof(obj));
  788. // run simulation
  789. dsSimulationLoop (argc,argv,352,288,&fn);
  790. dJointGroupDestroy (contactgroup);
  791. dSpaceDestroy (space);
  792. dWorldDestroy (world);
  793. dCloseODE();
  794. return 0;
  795. }