[216] | 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 | #include <ode/ode.h> |
---|
| 24 | #include <drawstuff/drawstuff.h> |
---|
| 25 | |
---|
| 26 | #ifdef _MSC_VER |
---|
| 27 | #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints |
---|
| 28 | #endif |
---|
| 29 | |
---|
| 30 | // select correct drawing functions |
---|
| 31 | #ifdef dDOUBLE |
---|
| 32 | #define dsDrawBox dsDrawBoxD |
---|
| 33 | #endif |
---|
| 34 | |
---|
| 35 | |
---|
| 36 | // some constants |
---|
| 37 | #define SIDE (0.5f) // side length of a box |
---|
| 38 | #define MASS (1.0) // mass of a box |
---|
| 39 | |
---|
| 40 | |
---|
| 41 | // dynamics and collision objects |
---|
| 42 | static dWorldID world; |
---|
| 43 | static dBodyID body[2]; |
---|
| 44 | static dJointID slider; |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | // state set by keyboard commands |
---|
| 48 | static int occasional_error = 0; |
---|
| 49 | |
---|
| 50 | |
---|
| 51 | // start simulation - set viewpoint |
---|
| 52 | |
---|
| 53 | static void start() |
---|
| 54 | { |
---|
| 55 | static float xyz[3] = {1.0382f,-1.0811f,1.4700f}; |
---|
| 56 | static float hpr[3] = {135.0000f,-19.5000f,0.0000f}; |
---|
| 57 | dsSetViewpoint (xyz,hpr); |
---|
| 58 | printf ("Press 'e' to start/stop occasional error.\n"); |
---|
| 59 | } |
---|
| 60 | |
---|
| 61 | |
---|
| 62 | // called when a key pressed |
---|
| 63 | |
---|
| 64 | static void command (int cmd) |
---|
| 65 | { |
---|
| 66 | if (cmd == 'e' || cmd == 'E') { |
---|
| 67 | occasional_error ^= 1; |
---|
| 68 | } |
---|
| 69 | } |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | // simulation loop |
---|
| 73 | |
---|
| 74 | static void simLoop (int pause) |
---|
| 75 | { |
---|
| 76 | const dReal kd = -0.3; // angular damping constant |
---|
| 77 | const dReal ks = 0.5; // spring constant |
---|
| 78 | if (!pause) { |
---|
| 79 | // add an oscillating torque to body 0, and also damp its rotational motion |
---|
| 80 | static dReal a=0; |
---|
| 81 | const dReal *w = dBodyGetAngularVel (body[0]); |
---|
| 82 | dBodyAddTorque (body[0],kd*w[0],kd*w[1]+0.1*cos(a),kd*w[2]+0.1*sin(a)); |
---|
| 83 | a += 0.01; |
---|
| 84 | |
---|
| 85 | // add a spring force to keep the bodies together, otherwise they will |
---|
| 86 | // fly apart along the slider axis. |
---|
| 87 | const dReal *p1 = dBodyGetPosition (body[0]); |
---|
| 88 | const dReal *p2 = dBodyGetPosition (body[1]); |
---|
| 89 | dBodyAddForce (body[0],ks*(p2[0]-p1[0]),ks*(p2[1]-p1[1]), |
---|
| 90 | ks*(p2[2]-p1[2])); |
---|
| 91 | dBodyAddForce (body[1],ks*(p1[0]-p2[0]),ks*(p1[1]-p2[1]), |
---|
| 92 | ks*(p1[2]-p2[2])); |
---|
| 93 | |
---|
| 94 | // occasionally re-orient one of the bodies to create a deliberate error. |
---|
| 95 | if (occasional_error) { |
---|
| 96 | static int count = 0; |
---|
| 97 | if ((count % 20)==0) { |
---|
| 98 | // randomly adjust orientation of body[0] |
---|
| 99 | const dReal *R1; |
---|
| 100 | dMatrix3 R2,R3; |
---|
| 101 | R1 = dBodyGetRotation (body[0]); |
---|
| 102 | dRFromAxisAndAngle (R2,dRandReal()-0.5,dRandReal()-0.5, |
---|
| 103 | dRandReal()-0.5,dRandReal()-0.5); |
---|
| 104 | dMultiply0 (R3,R1,R2,3,3,3); |
---|
| 105 | dBodySetRotation (body[0],R3); |
---|
| 106 | |
---|
| 107 | // randomly adjust position of body[0] |
---|
| 108 | const dReal *pos = dBodyGetPosition (body[0]); |
---|
| 109 | dBodySetPosition (body[0], |
---|
| 110 | pos[0]+0.2*(dRandReal()-0.5), |
---|
| 111 | pos[1]+0.2*(dRandReal()-0.5), |
---|
| 112 | pos[2]+0.2*(dRandReal()-0.5)); |
---|
| 113 | } |
---|
| 114 | count++; |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | dWorldStep (world,0.05); |
---|
| 118 | } |
---|
| 119 | |
---|
| 120 | dReal sides1[3] = {SIDE,SIDE,SIDE}; |
---|
| 121 | dReal sides2[3] = {SIDE*0.8f,SIDE*0.8f,SIDE*2.0f}; |
---|
| 122 | dsSetTexture (DS_WOOD); |
---|
| 123 | dsSetColor (1,1,0); |
---|
| 124 | dsDrawBox (dBodyGetPosition(body[0]),dBodyGetRotation(body[0]),sides1); |
---|
| 125 | dsSetColor (0,1,1); |
---|
| 126 | dsDrawBox (dBodyGetPosition(body[1]),dBodyGetRotation(body[1]),sides2); |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | |
---|
| 130 | int main (int argc, char **argv) |
---|
| 131 | { |
---|
| 132 | // setup pointers to drawstuff callback functions |
---|
| 133 | dsFunctions fn; |
---|
| 134 | fn.version = DS_VERSION; |
---|
| 135 | fn.start = &start; |
---|
| 136 | fn.step = &simLoop; |
---|
| 137 | fn.command = &command; |
---|
| 138 | fn.stop = 0; |
---|
| 139 | fn.path_to_textures = "../../drawstuff/textures"; |
---|
| 140 | if(argc==2) |
---|
| 141 | { |
---|
| 142 | fn.path_to_textures = argv[1]; |
---|
| 143 | } |
---|
| 144 | |
---|
| 145 | // create world |
---|
| 146 | dInitODE(); |
---|
| 147 | world = dWorldCreate(); |
---|
| 148 | dMass m; |
---|
| 149 | dMassSetBox (&m,1,SIDE,SIDE,SIDE); |
---|
| 150 | dMassAdjust (&m,MASS); |
---|
| 151 | |
---|
| 152 | body[0] = dBodyCreate (world); |
---|
| 153 | dBodySetMass (body[0],&m); |
---|
| 154 | dBodySetPosition (body[0],0,0,1); |
---|
| 155 | body[1] = dBodyCreate (world); |
---|
| 156 | dBodySetMass (body[1],&m); |
---|
| 157 | dQuaternion q; |
---|
| 158 | dQFromAxisAndAngle (q,-1,1,0,0.25*M_PI); |
---|
| 159 | dBodySetPosition (body[1],0.2,0.2,1.2); |
---|
| 160 | dBodySetQuaternion (body[1],q); |
---|
| 161 | |
---|
| 162 | slider = dJointCreateSlider (world,0); |
---|
| 163 | dJointAttach (slider,body[0],body[1]); |
---|
| 164 | dJointSetSliderAxis (slider,1,1,1); |
---|
| 165 | |
---|
| 166 | // run simulation |
---|
| 167 | dsSimulationLoop (argc,argv,352,288,&fn); |
---|
| 168 | |
---|
| 169 | dWorldDestroy (world); |
---|
| 170 | dCloseODE(); |
---|
| 171 | return 0; |
---|
| 172 | } |
---|