aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/ode/demo/demo_crash.cpp
diff options
context:
space:
mode:
authordan miller2007-10-19 05:15:33 +0000
committerdan miller2007-10-19 05:15:33 +0000
commit79eca25c945a535a7a0325999034bae17da92412 (patch)
tree40ff433d94859d629aac933d5ec73b382f62ba1a /libraries/ode-0.9/ode/demo/demo_crash.cpp
parentadding ode source to /libraries (diff)
downloadopensim-SC-79eca25c945a535a7a0325999034bae17da92412.zip
opensim-SC-79eca25c945a535a7a0325999034bae17da92412.tar.gz
opensim-SC-79eca25c945a535a7a0325999034bae17da92412.tar.bz2
opensim-SC-79eca25c945a535a7a0325999034bae17da92412.tar.xz
resubmitting ode
Diffstat (limited to 'libraries/ode-0.9/ode/demo/demo_crash.cpp')
-rw-r--r--libraries/ode-0.9/ode/demo/demo_crash.cpp635
1 files changed, 635 insertions, 0 deletions
diff --git a/libraries/ode-0.9/ode/demo/demo_crash.cpp b/libraries/ode-0.9/ode/demo/demo_crash.cpp
new file mode 100644
index 0000000..29ec01f
--- /dev/null
+++ b/libraries/ode-0.9/ode/demo/demo_crash.cpp
@@ -0,0 +1,635 @@
1/*************************************************************************
2 * *
3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org 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// This is a demo of the QuickStep and StepFast methods,
24// originally by David Whittaker.
25
26#include <ode/ode.h>
27#include <drawstuff/drawstuff.h>
28
29#ifdef _MSC_VER
30#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints
31#endif
32
33// select correct drawing functions
34
35#ifdef dDOUBLE
36#define dsDrawBox dsDrawBoxD
37#define dsDrawSphere dsDrawSphereD
38#define dsDrawCylinder dsDrawCylinderD
39#define dsDrawCapsule dsDrawCapsuleD
40#endif
41
42
43// select the method you want to test here (only uncomment *one* line)
44#define QUICKSTEP 1
45//#define STEPFAST 1
46
47// some constants
48
49#define LENGTH 3.5 // chassis length
50#define WIDTH 2.5 // chassis width
51#define HEIGHT 1.0 // chassis height
52#define RADIUS 0.5 // wheel radius
53#define STARTZ 1.0 // starting height of chassis
54#define CMASS 1 // chassis mass
55#define WMASS 1 // wheel mass
56#define COMOFFSET -5 // center of mass offset
57#define WALLMASS 1 // wall box mass
58#define BALLMASS 1 // ball mass
59#define FMAX 25 // car engine fmax
60#define ROWS 1 // rows of cars
61#define COLS 1 // columns of cars
62#define ITERS 20 // number of iterations
63#define WBOXSIZE 1.0 // size of wall boxes
64#define WALLWIDTH 12 // width of wall
65#define WALLHEIGHT 10 // height of wall
66#define DISABLE_THRESHOLD 0.008 // maximum velocity (squared) a body can have and be disabled
67#define DISABLE_STEPS 10 // number of steps a box has to have been disable-able before it will be disabled
68#define CANNON_X -10 // x position of cannon
69#define CANNON_Y 5 // y position of cannon
70#define CANNON_BALL_MASS 10 // mass of the cannon ball
71#define CANNON_BALL_RADIUS 0.5
72
73//#define BOX
74#define CARS
75#define WALL
76//#define BALLS
77//#define BALLSTACK
78//#define ONEBALL
79//#define CENTIPEDE
80#define CANNON
81
82// dynamics and collision objects (chassis, 3 wheels, environment)
83
84static dWorldID world;
85static dSpaceID space;
86static dBodyID body[10000];
87static int bodies;
88static dJointID joint[100000];
89static int joints;
90static dJointGroupID contactgroup;
91static dGeomID ground;
92static dGeomID box[10000];
93static int boxes;
94static dGeomID sphere[10000];
95static int spheres;
96static dGeomID wall_boxes[10000];
97static dBodyID wall_bodies[10000];
98static dGeomID cannon_ball_geom;
99static dBodyID cannon_ball_body;
100static int wb_stepsdis[10000];
101static int wb;
102static bool doFast;
103static dBodyID b;
104static dMass m;
105
106
107// things that the user controls
108
109static dReal turn = 0, speed = 0; // user commands
110static dReal cannon_angle=0,cannon_elevation=-1.2;
111
112
113
114// this is called by dSpaceCollide when two objects in space are
115// potentially colliding.
116
117static void nearCallback (void *data, dGeomID o1, dGeomID o2)
118{
119 int i,n;
120
121 dBodyID b1 = dGeomGetBody(o1);
122 dBodyID b2 = dGeomGetBody(o2);
123 if (b1 && b2 && dAreConnected(b1, b2))
124 return;
125
126 const int N = 4;
127 dContact contact[N];
128 n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
129 if (n > 0) {
130 for (i=0; i<n; i++) {
131 contact[i].surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1;
132 if (dGeomGetClass(o1) == dSphereClass || dGeomGetClass(o2) == dSphereClass)
133 contact[i].surface.mu = 20;
134 else
135 contact[i].surface.mu = 0.5;
136 contact[i].surface.slip1 = 0.0;
137 contact[i].surface.slip2 = 0.0;
138 contact[i].surface.soft_erp = 0.8;
139 contact[i].surface.soft_cfm = 0.01;
140 dJointID c = dJointCreateContact (world,contactgroup,contact+i);
141 dJointAttach (c,dGeomGetBody(o1),dGeomGetBody(o2));
142 }
143 }
144}
145
146
147// start simulation - set viewpoint
148
149static void start()
150{
151 static float xyz[3] = {3.8548f,9.0843f,7.5900f};
152 static float hpr[3] = {-145.5f,-22.5f,0.25f};
153 dsSetViewpoint (xyz,hpr);
154 printf ("Press:\t'a' to increase speed.\n"
155 "\t'z' to decrease speed.\n"
156 "\t',' to steer left.\n"
157 "\t'.' to steer right.\n"
158 "\t' ' to reset speed and steering.\n"
159 "\t'[' to turn the cannon left.\n"
160 "\t']' to turn the cannon right.\n"
161 "\t'1' to raise the cannon.\n"
162 "\t'2' to lower the cannon.\n"
163 "\t'x' to shoot from the cannon.\n"
164 "\t'f' to toggle fast step mode.\n"
165 "\t'+' to increase AutoEnableDepth.\n"
166 "\t'-' to decrease AutoEnableDepth.\n"
167 "\t'r' to reset simulation.\n");
168}
169
170
171void makeCar(dReal x, dReal y, int &bodyI, int &jointI, int &boxI, int &sphereI)
172{
173 int i;
174 dMass m;
175
176 // chassis body
177 body[bodyI] = dBodyCreate (world);
178 dBodySetPosition (body[bodyI],x,y,STARTZ);
179 dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT);
180 dMassAdjust (&m,CMASS/2.0);
181 dBodySetMass (body[bodyI],&m);
182 box[boxI] = dCreateBox (space,LENGTH,WIDTH,HEIGHT);
183 dGeomSetBody (box[boxI],body[bodyI]);
184
185 // wheel bodies
186 for (i=1; i<=4; i++) {
187 body[bodyI+i] = dBodyCreate (world);
188 dQuaternion q;
189 dQFromAxisAndAngle (q,1,0,0,M_PI*0.5);
190 dBodySetQuaternion (body[bodyI+i],q);
191 dMassSetSphere (&m,1,RADIUS);
192 dMassAdjust (&m,WMASS);
193 dBodySetMass (body[bodyI+i],&m);
194 sphere[sphereI+i-1] = dCreateSphere (space,RADIUS);
195 dGeomSetBody (sphere[sphereI+i-1],body[bodyI+i]);
196 }
197 dBodySetPosition (body[bodyI+1],x+0.4*LENGTH-0.5*RADIUS,y+WIDTH*0.5,STARTZ-HEIGHT*0.5);
198 dBodySetPosition (body[bodyI+2],x+0.4*LENGTH-0.5*RADIUS,y-WIDTH*0.5,STARTZ-HEIGHT*0.5);
199 dBodySetPosition (body[bodyI+3],x-0.4*LENGTH+0.5*RADIUS,y+WIDTH*0.5,STARTZ-HEIGHT*0.5);
200 dBodySetPosition (body[bodyI+4],x-0.4*LENGTH+0.5*RADIUS,y-WIDTH*0.5,STARTZ-HEIGHT*0.5);
201
202 // front and back wheel hinges
203 for (i=0; i<4; i++) {
204 joint[jointI+i] = dJointCreateHinge2 (world,0);
205 dJointAttach (joint[jointI+i],body[bodyI],body[bodyI+i+1]);
206 const dReal *a = dBodyGetPosition (body[bodyI+i+1]);
207 dJointSetHinge2Anchor (joint[jointI+i],a[0],a[1],a[2]);
208 dJointSetHinge2Axis1 (joint[jointI+i],0,0,(i<2 ? 1 : -1));
209 dJointSetHinge2Axis2 (joint[jointI+i],0,1,0);
210 dJointSetHinge2Param (joint[jointI+i],dParamSuspensionERP,0.8);
211 dJointSetHinge2Param (joint[jointI+i],dParamSuspensionCFM,1e-5);
212 dJointSetHinge2Param (joint[jointI+i],dParamVel2,0);
213 dJointSetHinge2Param (joint[jointI+i],dParamFMax2,FMAX);
214 }
215
216 //center of mass offset body. (hang another copy of the body COMOFFSET units below it by a fixed joint)
217 dBodyID b = dBodyCreate (world);
218 dBodySetPosition (b,x,y,STARTZ+COMOFFSET);
219 dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT);
220 dMassAdjust (&m,CMASS/2.0);
221 dBodySetMass (b,&m);
222 dJointID j = dJointCreateFixed(world, 0);
223 dJointAttach(j, body[bodyI], b);
224 dJointSetFixed(j);
225 //box[boxI+1] = dCreateBox(space,LENGTH,WIDTH,HEIGHT);
226 //dGeomSetBody (box[boxI+1],b);
227
228 bodyI += 5;
229 jointI += 4;
230 boxI += 1;
231 sphereI += 4;
232}
233
234
235void resetSimulation()
236{
237 int i;
238 i = 0;
239 // destroy world if it exists
240 if (bodies)
241 {
242 dJointGroupDestroy (contactgroup);
243 dSpaceDestroy (space);
244 dWorldDestroy (world);
245 }
246
247 for (i = 0; i < 1000; i++)
248 wb_stepsdis[i] = 0;
249
250 // recreate world
251
252 world = dWorldCreate();
253 space = dHashSpaceCreate (0);
254 contactgroup = dJointGroupCreate (0);
255 dWorldSetGravity (world,0,0,-1.5);
256 dWorldSetCFM (world, 1e-5);
257 dWorldSetERP (world, 0.8);
258 dWorldSetQuickStepNumIterations (world,ITERS);
259 ground = dCreatePlane (space,0,0,1,0);
260
261 bodies = 0;
262 joints = 0;
263 boxes = 0;
264 spheres = 0;
265 wb = 0;
266
267#ifdef CARS
268 for (dReal x = 0.0; x < COLS*(LENGTH+RADIUS); x += LENGTH+RADIUS)
269 for (dReal y = -((ROWS-1)*(WIDTH/2+RADIUS)); y <= ((ROWS-1)*(WIDTH/2+RADIUS)); y += WIDTH+RADIUS*2)
270 makeCar(x, y, bodies, joints, boxes, spheres);
271#endif
272#ifdef WALL
273 bool offset = false;
274 for (dReal z = WBOXSIZE/2.0; z <= WALLHEIGHT; z+=WBOXSIZE)
275 {
276 offset = !offset;
277 for (dReal y = (-WALLWIDTH+z)/2; y <= (WALLWIDTH-z)/2; y+=WBOXSIZE)
278 {
279 wall_bodies[wb] = dBodyCreate (world);
280 dBodySetPosition (wall_bodies[wb],-20,y,z);
281 dMassSetBox (&m,1,WBOXSIZE,WBOXSIZE,WBOXSIZE);
282 dMassAdjust (&m, WALLMASS);
283 dBodySetMass (wall_bodies[wb],&m);
284 wall_boxes[wb] = dCreateBox (space,WBOXSIZE,WBOXSIZE,WBOXSIZE);
285 dGeomSetBody (wall_boxes[wb],wall_bodies[wb]);
286 //dBodyDisable(wall_bodies[wb++]);
287 wb++;
288 }
289 }
290 dMessage(0,"wall boxes: %i", wb);
291#endif
292#ifdef BALLS
293 for (dReal x = -7; x <= -4; x+=1)
294 for (dReal y = -1.5; y <= 1.5; y+=1)
295 for (dReal z = 1; z <= 4; z+=1)
296 {
297 b = dBodyCreate (world);
298 dBodySetPosition (b,x*RADIUS*2,y*RADIUS*2,z*RADIUS*2);
299 dMassSetSphere (&m,1,RADIUS);
300 dMassAdjust (&m, BALLMASS);
301 dBodySetMass (b,&m);
302 sphere[spheres] = dCreateSphere (space,RADIUS);
303 dGeomSetBody (sphere[spheres++],b);
304 }
305#endif
306#ifdef ONEBALL
307 b = dBodyCreate (world);
308 dBodySetPosition (b,0,0,2);
309 dMassSetSphere (&m,1,RADIUS);
310 dMassAdjust (&m, 1);
311 dBodySetMass (b,&m);
312 sphere[spheres] = dCreateSphere (space,RADIUS);
313 dGeomSetBody (sphere[spheres++],b);
314#endif
315#ifdef BALLSTACK
316 for (dReal z = 1; z <= 6; z+=1)
317 {
318 b = dBodyCreate (world);
319 dBodySetPosition (b,0,0,z*RADIUS*2);
320 dMassSetSphere (&m,1,RADIUS);
321 dMassAdjust (&m, 0.1);
322 dBodySetMass (b,&m);
323 sphere[spheres] = dCreateSphere (space,RADIUS);
324 dGeomSetBody (sphere[spheres++],b);
325 }
326#endif
327#ifdef CENTIPEDE
328 dBodyID lastb = 0;
329 for (dReal y = 0; y < 10*LENGTH; y+=LENGTH+0.1)
330 {
331 // chassis body
332
333 b = body[bodies] = dBodyCreate (world);
334 dBodySetPosition (body[bodies],-15,y,STARTZ);
335 dMassSetBox (&m,1,WIDTH,LENGTH,HEIGHT);
336 dMassAdjust (&m,CMASS);
337 dBodySetMass (body[bodies],&m);
338 box[boxes] = dCreateBox (space,WIDTH,LENGTH,HEIGHT);
339 dGeomSetBody (box[boxes++],body[bodies++]);
340
341 for (dReal x = -17; x > -20; x-=RADIUS*2)
342 {
343 body[bodies] = dBodyCreate (world);
344 dBodySetPosition(body[bodies], x, y, STARTZ);
345 dMassSetSphere(&m, 1, RADIUS);
346 dMassAdjust(&m, WMASS);
347 dBodySetMass(body[bodies], &m);
348 sphere[spheres] = dCreateSphere (space, RADIUS);
349 dGeomSetBody (sphere[spheres++], body[bodies]);
350
351 joint[joints] = dJointCreateHinge2 (world,0);
352 if (x == -17)
353 dJointAttach (joint[joints],b,body[bodies]);
354 else
355 dJointAttach (joint[joints],body[bodies-2],body[bodies]);
356 const dReal *a = dBodyGetPosition (body[bodies++]);
357 dJointSetHinge2Anchor (joint[joints],a[0],a[1],a[2]);
358 dJointSetHinge2Axis1 (joint[joints],0,0,1);
359 dJointSetHinge2Axis2 (joint[joints],1,0,0);
360 dJointSetHinge2Param (joint[joints],dParamSuspensionERP,1.0);
361 dJointSetHinge2Param (joint[joints],dParamSuspensionCFM,1e-5);
362 dJointSetHinge2Param (joint[joints],dParamLoStop,0);
363 dJointSetHinge2Param (joint[joints],dParamHiStop,0);
364 dJointSetHinge2Param (joint[joints],dParamVel2,-10.0);
365 dJointSetHinge2Param (joint[joints++],dParamFMax2,FMAX);
366
367 body[bodies] = dBodyCreate (world);
368 dBodySetPosition(body[bodies], -30 - x, y, STARTZ);
369 dMassSetSphere(&m, 1, RADIUS);
370 dMassAdjust(&m, WMASS);
371 dBodySetMass(body[bodies], &m);
372 sphere[spheres] = dCreateSphere (space, RADIUS);
373 dGeomSetBody (sphere[spheres++], body[bodies]);
374
375 joint[joints] = dJointCreateHinge2 (world,0);
376 if (x == -17)
377 dJointAttach (joint[joints],b,body[bodies]);
378 else
379 dJointAttach (joint[joints],body[bodies-2],body[bodies]);
380 const dReal *b = dBodyGetPosition (body[bodies++]);
381 dJointSetHinge2Anchor (joint[joints],b[0],b[1],b[2]);
382 dJointSetHinge2Axis1 (joint[joints],0,0,1);
383 dJointSetHinge2Axis2 (joint[joints],1,0,0);
384 dJointSetHinge2Param (joint[joints],dParamSuspensionERP,1.0);
385 dJointSetHinge2Param (joint[joints],dParamSuspensionCFM,1e-5);
386 dJointSetHinge2Param (joint[joints],dParamLoStop,0);
387 dJointSetHinge2Param (joint[joints],dParamHiStop,0);
388 dJointSetHinge2Param (joint[joints],dParamVel2,10.0);
389 dJointSetHinge2Param (joint[joints++],dParamFMax2,FMAX);
390 }
391 if (lastb)
392 {
393 dJointID j = dJointCreateFixed(world,0);
394 dJointAttach (j, b, lastb);
395 dJointSetFixed(j);
396 }
397 lastb = b;
398 }
399#endif
400#ifdef BOX
401 body[bodies] = dBodyCreate (world);
402 dBodySetPosition (body[bodies],0,0,HEIGHT/2);
403 dMassSetBox (&m,1,LENGTH,WIDTH,HEIGHT);
404 dMassAdjust (&m, 1);
405 dBodySetMass (body[bodies],&m);
406 box[boxes] = dCreateBox (space,LENGTH,WIDTH,HEIGHT);
407 dGeomSetBody (box[boxes++],body[bodies++]);
408#endif
409#ifdef CANNON
410 cannon_ball_body = dBodyCreate (world);
411 cannon_ball_geom = dCreateSphere (space,CANNON_BALL_RADIUS);
412 dMassSetSphereTotal (&m,CANNON_BALL_MASS,CANNON_BALL_RADIUS);
413 dBodySetMass (cannon_ball_body,&m);
414 dGeomSetBody (cannon_ball_geom,cannon_ball_body);
415 dBodySetPosition (cannon_ball_body,CANNON_X,CANNON_Y,CANNON_BALL_RADIUS);
416#endif
417}
418
419// called when a key pressed
420
421static void command (int cmd)
422{
423 switch (cmd) {
424 case 'a': case 'A':
425 speed += 0.3;
426 break;
427 case 'z': case 'Z':
428 speed -= 0.3;
429 break;
430 case ',':
431 turn += 0.1;
432 if (turn > 0.3)
433 turn = 0.3;
434 break;
435 case '.':
436 turn -= 0.1;
437 if (turn < -0.3)
438 turn = -0.3;
439 break;
440 case ' ':
441 speed = 0;
442 turn = 0;
443 break;
444 case 'f': case 'F':
445 doFast = !doFast;
446 break;
447 case '+':
448 dWorldSetAutoEnableDepthSF1 (world, dWorldGetAutoEnableDepthSF1 (world) + 1);
449 break;
450 case '-':
451 dWorldSetAutoEnableDepthSF1 (world, dWorldGetAutoEnableDepthSF1 (world) - 1);
452 break;
453 case 'r': case 'R':
454 resetSimulation();
455 break;
456 case '[':
457 cannon_angle += 0.1;
458 break;
459 case ']':
460 cannon_angle -= 0.1;
461 break;
462 case '1':
463 cannon_elevation += 0.1;
464 break;
465 case '2':
466 cannon_elevation -= 0.1;
467 break;
468 case 'x': case 'X': {
469 dMatrix3 R2,R3,R4;
470 dRFromAxisAndAngle (R2,0,0,1,cannon_angle);
471 dRFromAxisAndAngle (R3,0,1,0,cannon_elevation);
472 dMultiply0 (R4,R2,R3,3,3,3);
473 dReal cpos[3] = {CANNON_X,CANNON_Y,1};
474 for (int i=0; i<3; i++) cpos[i] += 3*R4[i*4+2];
475 dBodySetPosition (cannon_ball_body,cpos[0],cpos[1],cpos[2]);
476 dReal force = 10;
477 dBodySetLinearVel (cannon_ball_body,force*R4[2],force*R4[6],force*R4[10]);
478 dBodySetAngularVel (cannon_ball_body,0,0,0);
479 break;
480 }
481 }
482}
483
484
485// simulation loop
486
487static void simLoop (int pause)
488{
489 int i, j;
490
491 dsSetTexture (DS_WOOD);
492
493 if (!pause) {
494#ifdef BOX
495 dBodyAddForce(body[bodies-1],lspeed,0,0);
496#endif
497 for (j = 0; j < joints; j++)
498 {
499 dReal curturn = dJointGetHinge2Angle1 (joint[j]);
500 //dMessage (0,"curturn %e, turn %e, vel %e", curturn, turn, (turn-curturn)*1.0);
501 dJointSetHinge2Param(joint[j],dParamVel,(turn-curturn)*1.0);
502 dJointSetHinge2Param(joint[j],dParamFMax,dInfinity);
503 dJointSetHinge2Param(joint[j],dParamVel2,speed);
504 dJointSetHinge2Param(joint[j],dParamFMax2,FMAX);
505 dBodyEnable(dJointGetBody(joint[j],0));
506 dBodyEnable(dJointGetBody(joint[j],1));
507 }
508 if (doFast)
509 {
510 dSpaceCollide (space,0,&nearCallback);
511#if defined(QUICKSTEP)
512 dWorldQuickStep (world,0.05);
513#elif defined(STEPFAST)
514 dWorldStepFast1 (world,0.05,ITERS);
515#endif
516 dJointGroupEmpty (contactgroup);
517 }
518 else
519 {
520 dSpaceCollide (space,0,&nearCallback);
521 dWorldStep (world,0.05);
522 dJointGroupEmpty (contactgroup);
523 }
524
525 for (i = 0; i < wb; i++)
526 {
527 b = dGeomGetBody(wall_boxes[i]);
528 if (dBodyIsEnabled(b))
529 {
530 bool disable = true;
531 const dReal *lvel = dBodyGetLinearVel(b);
532 dReal lspeed = lvel[0]*lvel[0]+lvel[1]*lvel[1]+lvel[2]*lvel[2];
533 if (lspeed > DISABLE_THRESHOLD)
534 disable = false;
535 const dReal *avel = dBodyGetAngularVel(b);
536 dReal aspeed = avel[0]*avel[0]+avel[1]*avel[1]+avel[2]*avel[2];
537 if (aspeed > DISABLE_THRESHOLD)
538 disable = false;
539
540 if (disable)
541 wb_stepsdis[i]++;
542 else
543 wb_stepsdis[i] = 0;
544
545 if (wb_stepsdis[i] > DISABLE_STEPS)
546 {
547 dBodyDisable(b);
548 dsSetColor(0.5,0.5,1);
549 }
550 else
551 dsSetColor(1,1,1);
552
553 }
554 else
555 dsSetColor(0.4,0.4,0.4);
556 dVector3 ss;
557 dGeomBoxGetLengths (wall_boxes[i], ss);
558 dsDrawBox(dGeomGetPosition(wall_boxes[i]), dGeomGetRotation(wall_boxes[i]), ss);
559 }
560 }
561 else
562 {
563 for (i = 0; i < wb; i++)
564 {
565 b = dGeomGetBody(wall_boxes[i]);
566 if (dBodyIsEnabled(b))
567 dsSetColor(1,1,1);
568 else
569 dsSetColor(0.4,0.4,0.4);
570 dVector3 ss;
571 dGeomBoxGetLengths (wall_boxes[i], ss);
572 dsDrawBox(dGeomGetPosition(wall_boxes[i]), dGeomGetRotation(wall_boxes[i]), ss);
573 }
574 }
575
576 dsSetColor (0,1,1);
577 dReal sides[3] = {LENGTH,WIDTH,HEIGHT};
578 for (i = 0; i < boxes; i++)
579 dsDrawBox (dGeomGetPosition(box[i]),dGeomGetRotation(box[i]),sides);
580 dsSetColor (1,1,1);
581 for (i=0; i< spheres; i++) dsDrawSphere (dGeomGetPosition(sphere[i]),
582 dGeomGetRotation(sphere[i]),RADIUS);
583
584 // draw the cannon
585 dsSetColor (1,1,0);
586 dMatrix3 R2,R3,R4;
587 dRFromAxisAndAngle (R2,0,0,1,cannon_angle);
588 dRFromAxisAndAngle (R3,0,1,0,cannon_elevation);
589 dMultiply0 (R4,R2,R3,3,3,3);
590 dReal cpos[3] = {CANNON_X,CANNON_Y,1};
591 dReal csides[3] = {2,2,2};
592 dsDrawBox (cpos,R2,csides);
593 for (i=0; i<3; i++) cpos[i] += 1.5*R4[i*4+2];
594 dsDrawCylinder (cpos,R4,3,0.5);
595
596 // draw the cannon ball
597 dsDrawSphere (dBodyGetPosition(cannon_ball_body),dBodyGetRotation(cannon_ball_body),
598 CANNON_BALL_RADIUS);
599}
600
601int main (int argc, char **argv)
602{
603 doFast = true;
604
605 // setup pointers to drawstuff callback functions
606 dsFunctions fn;
607 fn.version = DS_VERSION;
608 fn.start = &start;
609 fn.step = &simLoop;
610 fn.command = &command;
611 fn.stop = 0;
612 fn.path_to_textures = "../../drawstuff/textures";
613 if(argc==2)
614 {
615 fn.path_to_textures = argv[1];
616 }
617
618 dInitODE();
619
620 bodies = 0;
621 joints = 0;
622 boxes = 0;
623 spheres = 0;
624
625 resetSimulation();
626
627 // run simulation
628 dsSimulationLoop (argc,argv,352,288,&fn);
629
630 dJointGroupDestroy (contactgroup);
631 dSpaceDestroy (space);
632 dWorldDestroy (world);
633 dCloseODE();
634 return 0;
635}