int main (int argc, char **argv) { static dMass m; dReal mass = 1.0; // set for drawing dsFunctions fn; fn.version = DS_VERSION; fn.start = &start; fn.step = &simLoop; fn.command = NULL; fn.stop = NULL; fn.path_to_textures = "../textures"; dInitODE(); // init ODE world = dWorldCreate(); // create a dynamic world space = dSimpleSpaceCreate (0); //@a box capsule = dBodyCreate (world); geom = dCreateCapsule (space,radius,length); //create geometry. dMassSetCapsule(&m,DENSITY,3,radius,length); dBodySetMass (capsule,&m); dGeomSetBody(geom,capsule); dBodySetPosition (capsule,0,4,1); //Gravedad y cosas de simulacion dWorldSetGravity(world,0,0,-9.81); dWorldSetCFM (world,1e-5); dCreatePlane (space,0,0,1,0); contactgroup = dJointGroupCreate (0); // the simulation dsSimulationLoop (argc,argv,960,480,&fn); //-- Destroy the world!!! dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
dGeomID set_phys_geom_type(dGeomID geom, dBodyID body, int i, int t, const float *v) { /* Destroy the old geom and its data. */ if (geom) { free(dGeomGetData(geom)); dGeomDestroy(geom); geom = 0; } /* Create a new geom of the required type. */ switch (t) { case dSphereClass: geom = dCreateSphere(space, v[0]); break; case dCapsuleClass: geom = dCreateCapsule(space, v[0], v[1]); break; case dBoxClass: geom = dCreateBox(space, v[0], v[1], v[2]); break; case dPlaneClass: geom = dCreatePlane(space, v[0], v[1], v[2], v[3]); break; case dRayClass: geom = dCreateRay(space, (dReal) sqrt(v[3] * v[3] + v[4] * v[4] + v[5] * v[5])); dGeomRaySet(geom, v[0], v[1], v[2], v[3], v[4], v[5]); break; } /* Assign geom data and attach it to the body. */ if (geom) { dGeomSetData(geom, create_data(i)); dGeomSetBody(geom, body); } return geom; }
/* ================================================================================= createUniversalLeg Use parameters to create leg body/geom and attach to body with universal joint **Warning** mass is not set ================================================================================= */ void createUniversalLeg(ODEObject &leg, ODEObject &bodyAttachedTo, dJointID& joint, dReal xPos, dReal yPos, dReal zPos, dReal xRot, dReal yRot, dReal zRot, dReal radius, dReal length, dReal maxAngle, dReal minAngle, dReal anchorXPos, dReal anchorYPos, dReal anchorZPos) { dMatrix3 legOrient; dRFromEulerAngles(legOrient, xRot, yRot, zRot); //position and orientation leg.Body = dBodyCreate(World); dBodySetPosition(leg.Body, xPos, yPos, zPos); dBodySetRotation(leg.Body, legOrient); dBodySetLinearVel(leg.Body, 0, 0, 0); dBodySetData(leg.Body, (void *)0); //mass dMass legMass; dMassSetCapsule(&legMass, 1, 3, radius, length); //dBodySetMass(leg.Body, &legMass); //geometry leg.Geom = dCreateCapsule(Space, radius, length); dGeomSetBody(leg.Geom, leg.Body); //universal joint joint = dJointCreateUniversal(World, jointgroup); //attach and anchor dJointAttach(joint, bodyAttachedTo.Body, leg.Body); dJointSetUniversalAnchor(joint, anchorXPos, anchorYPos, anchorZPos); //axes dJointSetUniversalAxis1(joint, 0, 0, 1); dJointSetUniversalAxis2(joint, 0, 1, 0); //Max and min angles dJointSetUniversalParam(joint, dParamHiStop, maxAngle); dJointSetUniversalParam(joint, dParamLoStop, minAngle); dJointSetUniversalParam(joint, dParamHiStop2, maxAngle); dJointSetUniversalParam(joint, dParamLoStop2, minAngle); }
/*** ロボットアームの生成 ***/ void makeArm() { dMass mass; // 質量パラメータ dReal x[NUM] = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}; // 重心 x dReal y[NUM] = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}; // 重心 y dReal z[NUM] = {0.05, 0.55, 1.55, 2.30, 2.80, 3.35, 3.85, 4.0}; // 重心 z dReal length[NUM-1] = {0.10, 1.00, 1.00, 0.50, 0.50, 0.50, 0.50}; // 長さ dReal weight[NUM] = {9.00, 2.00, 2.00, 1.00, 1.00, 0.50, 0.50, 0.50}; // 質量 dReal r[NUM-1] = {0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}; // 半径 dReal c_x[NUM] = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}; // 関節中心点 x dReal c_y[NUM] = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}; // 関節中心点 y dReal c_z[NUM] = {0.00, 0.10, 1.10, 2.10, 2.60, 3.10, 3.60, 3.9}; // 関節中心点 z dReal axis_x[NUM] = {0, 0, 0, 0, 0, 0, 0, 0}; // 関節回転軸 x dReal axis_y[NUM] = {0, 0, 1, 1, 0, 1, 0, 0}; // 関節回転軸 y dReal axis_z[NUM] = {1, 1, 0, 0, 1, 0, 1, 1}; // 関節回転軸 z // リンクの生成 for (int i = 0; i < NUM-1; i++) { rlink[i].body = dBodyCreate(world); dBodySetPosition(rlink[i].body, x[i], y[i], z[i]); dMassSetZero(&mass); dMassSetCapsuleTotal(&mass,weight[i],3,r[i],length[i]); dBodySetMass(rlink[i].body, &mass); rlink[i].geom = dCreateCapsule(space,r[i],length[i]); dGeomSetBody(rlink[i].geom,rlink[i].body); } rlink[NUM-1].body = dBodyCreate(world); dBodySetPosition(rlink[NUM-1].body, x[NUM-1], y[NUM-1], z[NUM-1]); dMassSetZero(&mass); dMassSetBoxTotal(&mass,weight[NUM-1],0.4,0.4,0.4); dBodySetMass(rlink[NUM-1].body, &mass); rlink[NUM-1].geom = dCreateBox(space,0.4,0.4,0.4); dGeomSetBody(rlink[NUM-1].geom,rlink[NUM-1].body); // ジョイントの生成とリンクへの取り付け joint[0] = dJointCreateFixed(world, 0); // 固定ジョイント dJointAttach(joint[0], rlink[0].body, 0); dJointSetFixed(joint[0]); for (int j = 1; j < NUM; j++) { joint[j] = dJointCreateHinge(world, 0); // ヒンジジョイント dJointAttach(joint[j], rlink[j].body, rlink[j-1].body); dJointSetHingeAnchor(joint[j], c_x[j], c_y[j], c_z[j]); dJointSetHingeAxis(joint[j], axis_x[j], axis_y[j],axis_z[j]); } }
AvatarGameObj::AvatarGameObj(const ORE1::ObjType& obj) : GameObj(obj, Sim::gen_sphere_body(80, 0.5)), // TODO Load mass information from the ORE mission description _xrot_delta(0.0), _zrot_delta(0.0), _ypos_delta(0.0), _ylvel_delta(0.0), _xavel_delta(0.0), _zavel_delta(0.0), _norm_coll_steptime(0), _run_coll_steptime(0), _mesh(MeshAnimation::load("mesh-LIBAvatar")), _attached(false), _attached_this_frame(false) { // TODO Load volume information from the ORE mission description _height = 2.25; _coll_rad = 0.25; // Set up a geom for detecting regular collisions get_entity().set_geom( "physical", dCreateCapsule(Sim::get_dyn_space(), _coll_rad, _height - 2*_coll_rad), std::auto_ptr<CollisionHandler>(new AvatarContactHandler(this)) ); // TODO Maybe some missions start off in upright mode? _uprightness = 0.0; // Set up a geom at our feet to detect when we can run on a surface get_entity().set_geom( "sticky_attach", dCreateRay(Sim::get_dyn_space(), RUNNING_MAX_DELTA_Y_POS*2), std::auto_ptr<CollisionHandler>(new StickyAttachmentContactHandler(this)) ); dQuaternion rdq; dQFromAxisAndAngle(rdq, 1, 0, 0, M_PI_2); dGeomSetOffsetQuaternion(get_entity().get_geom("sticky_attach"), rdq); dGeomDisable(get_entity().get_geom("sticky_attach")); update_geom_offsets(); }
void dmCreateCapsule(dmObject *obj, double p[3], double R[12], double m, double r, double l, double color[3]) { obj->body = dBodyCreate(world); obj->m = m; obj->r = r; obj->l = l; obj->R = R; obj->p = p; obj->color = color; dMass mass; // 構造体massの宣言 dMassSetZero(&mass); // 構造体massの初期化 dMassSetBoxTotal(&mass,obj->m, 3, obj->r, obj->l); // 構造体massに質量を設定 dBodySetMass(obj->body,&mass); // ボールにmassを設定 dBodySetPosition(obj->body, obj->p[0], obj->p[1], obj->p[2]); // ボールの位置(x,y,z)を設定 dBodySetRotation(obj->body, obj->R); obj->geom = dCreateCapsule(space,obj->r, obj->l); // 円柱ジオメトリの生成 dGeomSetBody(obj->geom, obj->body); // ボディとジオメトリの関連付け }
Else::AcrobotArticulatedBody ::AcrobotArticulatedBody( dWorldID argWorldID, dSpaceID argSpaceID, double argScale ) : ArticulatedBody( argWorldID, argSpaceID ), myRadius( 0.1 * argScale ), myLength( argScale ), myJointGroupID( 0 ) { // create body gmtl::Vec3d dims( 2*myRadius, 2*myRadius, 2*myRadius + myLength ); const double density = 1.0; const int zDirection = 3; const double extraSpace = 0.1*myLength; dMass mass; dBodyID body = dBodyCreate( myWorldID ); dBodySetData( body, this ); // create cylinder aligned to z-axis dGeomID geom = dCreateCapsule( mySpaceID, myRadius, myLength ); dGeomSetBody( geom, body ); dBodySetPosition( body, 0, 0, extraSpace + 0.5*myLength + myRadius ); dMassSetCappedCylinder( &mass, density, zDirection, myRadius, myLength ); dBodySetMass( body, &mass ); dJointID joint = dJointCreateHinge( myWorldID, myJointGroupID ); dJointAttach( joint, NULL, body ); dJointSetHingeAnchor( joint, 0, 0, extraSpace + myLength + myRadius ); dVector3 axis; axis[0] = 0; axis[1] = 1; axis[2] = 0; dJointSetHingeAxis( joint, axis[0], axis[1], axis[2] ); myBodies[0] = body; myJoints[0] = joint; myBodyDims[0] = dims; myGeoms.push_back( geom ); }
dGeomID PhysWorld::AddCapsule(dReal radius, dReal length) { return dCreateCapsule(mSpace, radius, length); }
static void command (int cmd) { int i,j,k; dReal sides[3]; dMass m; bool setBody = false; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'v' /* || cmd == 'l' */) { if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy (obj[i].body); for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*2-1,dRandReal()*2-1,dRandReal()+1); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dReal maxheight = 0; for (k=0; k<num; k++) { const dReal *pos = dBodyGetPosition (obj[k].body); if (pos[2] > maxheight) maxheight = pos[2]; } dBodySetPosition (obj[i].body, 0,0,maxheight+1); dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*)(size_t)i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } /* // cylinder option not yet implemented else if (cmd == 'l') { sides[1] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } */ else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } else if (cmd == 'x') { setBody = true; // start accumulating masses for the composite geometries dMass m2; dMassSetZero (&m); dReal dpos[GPB][3]; // delta-positions for composite geometries dMatrix3 drot[GPB]; // set random delta positions for (j=0; j<GPB; j++) for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; for (k=0; k<GPB; k++) { if (k==0) { dReal radius = dRandReal()*0.25+0.05; obj[i].geom[k] = dCreateSphere (space,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; obj[i].geom[k] = dCreateCapsule(space,radius,length); dMassSetCapsule(&m2,DENSITY,3,radius,length); } dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dMassRotate(&m2,drot[k]); dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); // add to the total mass dMassAdd(&m,&m2); } for (k=0; k<GPB; k++) { dGeomSetBody(obj[i].geom[k],obj[i].body); dGeomSetOffsetPosition(obj[i].geom[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); } dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); dBodySetMass(obj[i].body,&m); } else if (cmd == 'v') { dMassSetBox (&m,DENSITY,0.25,0.25,0.25); obj[i].geom[0] = dCreateConvex(space, planes, planecount, points, pointcount, polygons); } if (!setBody) { // avoid calling for composite geometries for (k=0; k < GPB; k++) if (obj[i].geom[k]) dGeomSetBody(obj[i].geom[k],obj[i].body); dBodySetMass(obj[i].body,&m); } } if (cmd == ' ') { selected++; if (selected >= num) selected = 0; if (selected < 0) selected = 0; } else if (cmd == 'd' && selected >= 0 && selected < num) { dBodyDisable (obj[selected].body); } else if (cmd == 'e' && selected >= 0 && selected < num) { dBodyEnable (obj[selected].body); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } }
void makeRobot_Nleg() { for(int segment = 0; segment < BODY_SEGMENTS; ++segment) { dReal segmentOffsetFromMiddle = segment - MIDDLE_BODY_SEGMENT; dReal torso_m = 50.0; // Mass of body // torso_m[segment] = 10.0; dReal l1m = 0.005,l2m = 0.5, l3m = 0.5; // Mass of leg segments //for four legs // dReal x[num_legs][num_links] = {{-cx1,-cx1,-cx1},// Position of each link (x coordinate) // {-cx1,-cx1,-cx1}}; dReal x[num_legs][num_links] = {{0,0,0},// Position of each link (x coordinate) {0,0,0}}; dReal y[num_legs][num_links] = {{ cy1, cy1, cy1},// Position of each link (y coordinate) {-cy1,-cy1,-cy1}}; dReal z[num_legs][num_links] = { // Position of each link (z coordinate) {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2}, {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2} }; dReal r[num_links] = { r1, r2, r3}; // radius of leg segment dReal length[num_links] = { l1, l2, l3}; // Length of leg segment dReal weight[num_links] = {l1m,l2m,l3m}; // Mass of leg segment // //for one leg // dReal axis_x[num_legs_pneat][num_links_pneat] = {{ 0,1, 0}}; // dReal axis_y[num_legs_pneat][num_links_pneat] = {{ 1,0, 1}}; // dReal axis_z[num_legs_pneat][num_links_pneat] = {{ 0,0, 0}}; //for four legs dReal axis_x[num_legs][num_links]; dReal axis_y[num_legs][num_links]; dReal axis_z[num_legs][num_links]; for(int i = 0; i < num_legs; ++i) { axis_x[i][0] = 0.0; axis_x[i][1] = 1.0; axis_x[i][2] = 0.0; axis_y[i][0] = 1.0; axis_y[i][1] = 0.0; axis_y[i][2] = 1.0; axis_z[i][0] = 0.0; axis_z[i][1] = 0.0; axis_z[i][2] = 0.0; } // For mation of the body dMass mass; torso[segment].body = dBodyCreate(world); dMassSetZero(&mass); dMassSetBoxTotal(&mass,torso_m, lx, ly, lz); dBodySetMass(torso[segment].body,&mass); torso[segment].geom = dCreateBox(space,lx, ly, lz); dGeomSetBody(torso[segment].geom, torso[segment].body); dBodySetPosition(torso[segment].body, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS), SY, SZ); // Formation of leg dMatrix3 R; // Revolution queue dRFromAxisAndAngle(R,1,0,0,M_PI/2); // 90 degrees to turn, parallel with the land for (int i = 0; i < num_legs; i++) { for (int j = 0; j < num_links; j++) { THETA[segment][i][j] = 0; leg[segment][i][j].body = dBodyCreate(world); if (j == 0) dBodySetRotation(leg[segment][i][j].body,R); dBodySetPosition(leg[segment][i][j].body, SX+x[i][j]+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS), SY+y[i][j], SZ+z[i][j]); dMassSetZero(&mass); dMassSetCapsuleTotal(&mass,weight[j],3,r[j],length[j]); dBodySetMass(leg[segment][i][j].body, &mass); //if(i==1 and j==2) //to set the length of one leg differently //leg[i][j].geom = dCreateCapsule(space_pneat,r[j],length[j]+.5); //set the length of the leg //else leg[segment][i][j].geom = dCreateCapsule(space,r[j],length[j]); //set the length of the leg dGeomSetBody(leg[segment][i][j].geom,leg[segment][i][j].body); } } // Formation of joints (and connecting them up) for (int i = 0; i < num_legs; i++) { for (int j = 0; j < num_links; j++) { leg[segment][i][j].joint = dJointCreateHinge(world, 0); if (j == 0){ dJointAttach(leg[segment][i][j].joint, torso[segment].body, leg[segment][i][j].body); //connects hip to the environment dJointSetHingeParam(leg[segment][i][j].joint, dParamLoStop, -.50*M_PI); //prevent the hip forward-back from going more than 90 degrees dJointSetHingeParam(leg[segment][i][j].joint, dParamHiStop, .50*M_PI); } else dJointAttach(leg[segment][i][j].joint, leg[segment][i][j-1].body, leg[segment][i][j].body); dJointSetHingeAnchor(leg[segment][i][j].joint, SX+x[i][j]+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS), SY+c_y[i][j],SZ+c_z[i][j]); dJointSetHingeAxis(leg[segment][i][j].joint, axis_x[i][j], axis_y[i][j],axis_z[i][j]); } } } #ifdef USE_NLEG_ROBOT // link torsos for(int segment = 0; segment < BODY_SEGMENTS-1; ++segment) { dReal segmentOffsetFromMiddle = segment - MIDDLE_BODY_SEGMENT; switch (hingeType) { case 1: //Hinge Joint, X axis (back-breaker) torso[segment].joint = dJointCreateHinge(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetHingeAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); dJointSetHingeAxis (torso[segment].joint, 1.0, 0.0, 0.0); break; case 2: //Hinge Joint, Y axis (???) torso[segment].joint = dJointCreateHinge(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetHingeAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); dJointSetHingeAxis (torso[segment].joint, 0.0, 1.0, 0.0); break; case 3: //Hinge Joint, Z axis (snake-like) torso[segment].joint = dJointCreateHinge(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetHingeAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); dJointSetHingeAxis (torso[segment].joint, 0.0, 0.0, 1.0); break; case 4: // Slider, Y axis (??) torso[segment].joint = dJointCreateSlider(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetSliderAxis (torso[segment].joint, 0.0, 1.0, 0.0); break; case 5: // Slider, X axis (extendo) torso[segment].joint = dJointCreateSlider(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetSliderAxis (torso[segment].joint, 1.0, 0.0, 0.0); break; case 6: //Universal Joint torso[segment].joint = dJointCreateUniversal(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetUniversalAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); dJointSetUniversalAxis1(torso[segment].joint, 0.0, 1.0, 0.0); dJointSetUniversalAxis2(torso[segment].joint, 0.0, 0.0, 1.0); break; case 7: //Ball Joint torso[segment].joint = dJointCreateBall(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetBallAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); break; case 8: // Fixed torso[segment].joint = dJointCreateHinge(world, 0); dJointAttach(torso[segment].joint, torso[segment].body, torso[segment+1].body); dJointSetHingeAnchor(torso[segment].joint, SX+segmentOffsetFromMiddle*(lx+DISTANCE_BETWEEN_SEGMENTS)+(lx+DISTANCE_BETWEEN_SEGMENTS)/2, SY,SZ); dJointSetHingeAxis (torso[segment].joint, 1.0, 0.0, 0.0); dJointSetHingeParam(torso[segment].joint, dParamLoStop, -0.00*M_PI); //prevent the hip forward-back from going more than 90 degrees dJointSetHingeParam(torso[segment].joint, dParamHiStop, 0.00*M_PI); break; default: assert(false); // not a valid hinge type break; } } #endif }
static void command (int cmd) { int i,j,k; dReal sides[3]; dMass m; bool setBody = false; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || cmd == 'y' || cmd == 'v') { if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy (obj[i].body); for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dReal maxheight = 0; for (k=0; k<num; k++) { const dReal *pos = dBodyGetPosition (obj[k].body); if (pos[2] > maxheight) maxheight = pos[2]; } dBodySetPosition (obj[i].body, 0,0,maxheight+1); dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*)(size_t)i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } else if (cmd == 'v') { dMassSetBox (&m,DENSITY,0.25,0.25,0.25); obj[i].geom[0] = dCreateConvex(space, planes, planecount, points, pointcount, polygons); } else if (cmd == 'y') { sides[1] *= 0.5; dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } else if (cmd == 'm') { dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); dGeomTriMeshDataPreprocess2(new_tmdata, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL); obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0); // remember the mesh's dTriMeshDataID on its userdata for convenience. dGeomSetData(obj[i].geom[0], new_tmdata); dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] ); printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]); dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]); dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]); } else if (cmd == 'x') { setBody = true; // start accumulating masses for the composite geometries dMass m2; dMassSetZero (&m); dReal dpos[GPB][3]; // delta-positions for composite geometries dMatrix3 drot[GPB]; // set random delta positions for (j=0; j<GPB; j++) for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; for (k=0; k<GPB; k++) { if (k==0) { dReal radius = dRandReal()*0.25+0.05; obj[i].geom[k] = dCreateSphere (space,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { obj[i].geom[k] = dCreateBox(space,sides[0],sides[1],sides[2]); dMassSetBox(&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; obj[i].geom[k] = dCreateCapsule(space,radius,length); dMassSetCapsule(&m2,DENSITY,3,radius,length); } dRFromAxisAndAngle(drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dMassRotate(&m2,drot[k]); dMassTranslate(&m2,dpos[k][0],dpos[k][1],dpos[k][2]); // add to the total mass dMassAdd(&m,&m2); } for (k=0; k<GPB; k++) { dGeomSetBody(obj[i].geom[k],obj[i].body); dGeomSetOffsetPosition(obj[i].geom[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); } dMassTranslate(&m,-m.c[0],-m.c[1],-m.c[2]); dBodySetMass(obj[i].body,&m); } if (!setBody) { // avoid calling for composite geometries for (k=0; k < GPB; k++) if (obj[i].geom[k]) dGeomSetBody(obj[i].geom[k],obj[i].body); dBodySetMass(obj[i].body,&m); } } if (cmd == ' ') { selected++; if (selected >= num) selected = 0; if (selected < 0) selected = 0; } else if (cmd == 'd' && selected >= 0 && selected < num) { dBodyDisable (obj[selected].body); } else if (cmd == 'e' && selected >= 0 && selected < num) { dBodyEnable (obj[selected].body); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } }
void PhysicsCapsuleGeom::onCreate(const PhysicsCapsuleGeom *) { _GeomID = dCreateCapsule(0, getRadius(), getLength()); setCategoryBits(dGeomGetCategoryBits(_GeomID)); setCollideBits(dGeomGetCollideBits(_GeomID)); }
/*** Formation of robot ***/ void makeRobot() { dReal torso_m = 10.0; // Mass of body dReal l1m = 0.005,l2m = 0.5, l3m = 0.5; // Mass of leg segments //for four legs dReal x[num_legs][num_links] = {{ cx1, cx1, cx1},{-cx1,-cx1,-cx1},// Position of each link (x coordinate) {-cx1,-cx1,-cx1},{ cx1, cx1, cx1}}; dReal y[num_legs][num_links] = {{ cy1, cy1, cy1},{ cy1, cy1, cy1},// Position of each link (y coordinate) {-cy1,-cy1,-cy1},{-cy1,-cy1,-cy1}}; dReal z[num_legs][num_links] = { // Position of each link (z coordinate) {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2}, {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2}, {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2}, {c_z[0][0],(c_z[0][0]+c_z[0][2])/2,c_z[0][2]-l3/2}}; dReal r[num_links] = { r1, r2, r3}; // radius of leg segment dReal length[num_links] = { l1, l2, l3}; // Length of leg segment dReal weight[num_links] = {l1m,l2m,l3m}; // Mass of leg segment // //for one leg // dReal axis_x[num_legs_pneat][num_links_pneat] = {{ 0,1, 0}}; // dReal axis_y[num_legs_pneat][num_links_pneat] = {{ 1,0, 1}}; // dReal axis_z[num_legs_pneat][num_links_pneat] = {{ 0,0, 0}}; //for four legs dReal axis_x[num_legs][num_links] = {{ 0,1, 0},{ 0,1,0},{ 0, 1, 0},{ 0, 1, 0}}; dReal axis_y[num_legs][num_links] = {{ 1,0, 1},{ 1,0,1},{ 1, 0, 1},{ 1, 0, 1}}; dReal axis_z[num_legs][num_links] = {{ 0,0, 0},{ 0,0,0},{ 0, 0, 0},{ 0, 0, 0}}; // For mation of the body dMass mass; torso[0].body = dBodyCreate(world); dMassSetZero(&mass); dMassSetBoxTotal(&mass,torso_m, lx, ly, lz); dBodySetMass(torso[0].body,&mass); torso[0].geom = dCreateBox(space, lx, ly, lz); dGeomSetBody(torso[0].geom, torso[0].body); dBodySetPosition(torso[0].body, SX, SY, SZ); // Formation of leg dMatrix3 R; // Revolution queue dRFromAxisAndAngle(R,1,0,0,M_PI/2); // 90 degrees to turn, parallel with the land for (int i = 0; i < num_legs; i++) { for (int j = 0; j < num_links; j++) { leg[0][i][j].body = dBodyCreate(world); if (j == 0) dBodySetRotation(leg[0][i][j].body,R); dBodySetPosition(leg[0][i][j].body, SX+x[i][j], SY+y[i][j], SZ+z[i][j]); dMassSetZero(&mass); dMassSetCapsuleTotal(&mass,weight[j],3,r[j],length[j]); dBodySetMass(leg[0][i][j].body, &mass); //if(i==1 and j==2) //to set the length of one leg differently //leg[i][j].geom = dCreateCapsule(space_pneat,r[j],length[j]+.5); //set the length of the leg //else leg[0][i][j].geom = dCreateCapsule(space,r[j],length[j]); //set the length of the leg dGeomSetBody(leg[0][i][j].geom,leg[0][i][j].body); } } // Formation of joints (and connecting them up) for (int i = 0; i < num_legs; i++) { for (int j = 0; j < num_links; j++) { leg[0][i][j].joint = dJointCreateHinge(world, 0); if (j == 0){ dJointAttach(leg[0][i][j].joint, torso[0].body, leg[0][i][j].body); //connects hip to the environment dJointSetHingeParam(leg[0][i][j].joint, dParamLoStop, -.5*M_PI); //prevent the hip forward-back from going more than 90 degrees dJointSetHingeParam(leg[0][i][j].joint, dParamHiStop, .5*M_PI); } else dJointAttach(leg[0][i][j].joint, leg[0][i][j-1].body, leg[0][i][j].body); dJointSetHingeAnchor(leg[0][i][j].joint, SX+c_x[i][j], SY+c_y[i][j],SZ+c_z[i][j]); dJointSetHingeAxis(leg[0][i][j].joint, axis_x[i][j], axis_y[i][j],axis_z[i][j]); } } }
// called when a key pressed static void command( int cmd ) { int i,k; dReal sides[3]; dMass m; cmd = locase( cmd ); if ( cmd == 'v' || cmd == 'b' || cmd == 'c' || cmd == 's' ) { if ( num < NUM ) { i = num; num++; } else { i = nextobj; nextobj++; if ( nextobj >= num ) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy( obj[i].body ); for ( k=0; k < GPB; k++ ) { if ( obj[i].geom[k] ) dGeomDestroy( obj[i].geom[k] ); } memset( &obj[i],0,sizeof( obj[i] ) ); } obj[i].body = dBodyCreate( world ); for ( k=0; k<3; k++ ) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if ( random_pos ) { dBodySetPosition( obj[i].body, dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3 ); dRFromAxisAndAngle( R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0 ); } else { dReal maxheight = 0; for ( k=0; k<num; k++ ) { const dReal *pos = dBodyGetPosition( obj[k].body ); if ( pos[2] > maxheight ) maxheight = pos[2]; } dBodySetPosition( obj[i].body, 0,0,maxheight+1 ); dRFromAxisAndAngle( R,0,0,1,dRandReal()*10.0-5.0 ); } dBodySetRotation( obj[i].body,R ); dBodySetData( obj[i].body,( void* )( size_t )i ); if ( cmd == 'b' ) { dMassSetBox( &m,DENSITY,sides[0],sides[1],sides[2] ); obj[i].geom[0] = dCreateBox( space,sides[0],sides[1],sides[2] ); } else if ( cmd == 'c' ) { sides[0] *= 0.5; dMassSetCapsule( &m,DENSITY,3,sides[0],sides[1] ); obj[i].geom[0] = dCreateCapsule( space,sides[0],sides[1] ); } else if ( cmd == 's' ) { sides[0] *= 0.5; dMassSetSphere( &m,DENSITY,sides[0] ); obj[i].geom[0] = dCreateSphere( space,sides[0] ); } else if ( cmd == 'v' ) { obj[i].geom[0] = dCreateConvex( space, convexBunnyPlanes, convexBunnyPlaneCount, convexBunnyPoints, convexBunnyPointCount, convexBunnyPolygons ); /// Use equivalent TriMesh to set mass dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle( new_tmdata, &Vertices[0], 3 * sizeof( float ), VertexCount, ( dTriIndex* )&Indices[0], IndexCount, 3 * sizeof( dTriIndex ) ); dGeomID triMesh = dCreateTriMesh( 0, new_tmdata, 0, 0, 0 ); dMassSetTrimesh( &m, DENSITY, triMesh ); dGeomDestroy( triMesh ); dGeomTriMeshDataDestroy( new_tmdata ); printf( "mass at %f %f %f\n", m.c[0], m.c[1], m.c[2] ); dGeomSetPosition( obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2] ); dMassTranslate( &m, -m.c[0], -m.c[1], -m.c[2] ); } for ( k=0; k < GPB; k++ ) { if ( obj[i].geom[k] ) dGeomSetBody( obj[i].geom[k],obj[i].body ); } dBodySetMass( obj[i].body,&m ); } if ( cmd == ' ' ) { selected++; if ( selected >= num ) selected = 0; if ( selected < 0 ) selected = 0; } else if ( cmd == 'd' && selected >= 0 && selected < num ) { dBodyDisable( obj[selected].body ); } else if ( cmd == 'e' && selected >= 0 && selected < num ) { dBodyEnable( obj[selected].body ); } else if ( cmd == 'a' ) { show_aabb ^= 1; } else if ( cmd == 't' ) { show_contacts ^= 1; } else if ( cmd == 'r' ) { random_pos ^= 1; } }
static void command (int cmd) { int i,j,k; dReal sides[3]; dMass m; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' /* || cmd == 'l' */) { if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy (obj[i].body); for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*WORLD_SIZE-(WORLD_SIZE/2),dRandReal()*WORLD_SIZE-(WORLD_SIZE/2),dRandReal()+1); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dReal maxheight = 0; for (k=0; k<num; k++) { const dReal *pos = dBodyGetPosition (obj[k].body); if (pos[2] > maxheight) maxheight = pos[2]; } dBodySetPosition (obj[i].body, 0,0,maxheight+1); dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*)(size_t)i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } /* // cylinder option not yet implemented else if (cmd == 'l') { sides[1] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } */ else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } else if (cmd == 'x') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j<GPB; j++) { for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; } for (k=0; k<GPB; k++) { obj[i].geom[k] = dCreateGeomTransform (space); dGeomTransformSetCleanup (obj[i].geom[k],1); if (k==0) { dReal radius = dRandReal()*0.25+0.05; g2[k] = dCreateSphere (0,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]); dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; g2[k] = dCreateCapsule (0,radius,length); dMassSetCapsule (&m2,DENSITY,3,radius,length); } dGeomTransformSetGeom (obj[i].geom[k],g2[k]); // set the transformation (adjust the mass too) dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]); dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]); dMatrix3 Rtx; dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dGeomSetRotation (g2[k],Rtx); dMassRotate (&m2,Rtx); // add to the total mass dMassAdd (&m,&m2); } // move all encapsulated objects so that the center of mass is (0,0,0) for (k=0; k<2; k++) { dGeomSetPosition (g2[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); } dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]); } for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body); } dBodySetMass (obj[i].body,&m); } if (cmd == ' ') { selected++; if (selected >= num) selected = 0; if (selected < 0) selected = 0; } else if (cmd == 'd' && selected >= 0 && selected < num) { dBodyDisable (obj[selected].body); } else if (cmd == 'e' && selected >= 0 && selected < num) { dBodyEnable (obj[selected].body); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } else if (cmd == 'o') { draw_geom ^= 1; } }
int test_ccylinder_point_depth() { int j; dVector3 p,a; dMatrix3 R; dReal r,l,beta,x,y,d; dSimpleSpace space(0); dGeomID ccyl = dCreateCapsule (0,1,1); dSpaceAdd (space,ccyl); // ********** make a random ccyl r = dRandReal()*0.5 + 0.01; l = dRandReal()*1 + 0.01; dGeomCapsuleSetParams (ccyl,r,l); dMakeRandomVector (p,3,1.0); dGeomSetPosition (ccyl,p[0],p[1],p[2]); dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, dRandReal()*2-1,dRandReal()*10-5); dGeomSetRotation (ccyl,R); // ********** test point on axis has depth of 'radius' beta = dRandReal()-0.5; for (j=0; j<3; j++) a[j] = p[j] + l*beta*R[j*4+2]; if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - r) >= tol) FAILED(); // ********** test point on surface (excluding caps) has depth 0 beta = dRandReal()*2*M_PI; x = r*sin(beta); y = r*cos(beta); beta = dRandReal()-0.5; for (j=0; j<3; j++) a[j] = p[j] + x*R[j*4+0] + y*R[j*4+1] + l*beta*R[j*4+2]; if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2])) >= tol) FAILED(); // ********** test point on surface of caps has depth 0 for (j=0; j<3; j++) a[j] = dRandReal()-0.5; dNormalize3 (a); if (dCalcVectorDot3_14(a,R+2) > 0) { for (j=0; j<3; j++) a[j] = p[j] + a[j]*r + l*0.5*R[j*4+2]; } else { for (j=0; j<3; j++) a[j] = p[j] + a[j]*r - l*0.5*R[j*4+2]; } if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2])) >= tol) FAILED(); // ********** test point inside ccyl has positive depth for (j=0; j<3; j++) a[j] = dRandReal()-0.5; dNormalize3 (a); beta = dRandReal()-0.5; for (j=0; j<3; j++) a[j] = p[j] + a[j]*r*0.99 + l*beta*R[j*4+2]; if (dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) < 0) FAILED(); // ********** test point depth (1) d = (dRandReal()*2-1) * r; beta = dRandReal()*2*M_PI; x = (r-d)*sin(beta); y = (r-d)*cos(beta); beta = dRandReal()-0.5; for (j=0; j<3; j++) a[j] = p[j] + x*R[j*4+0] + y*R[j*4+1] + l*beta*R[j*4+2]; if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - d) >= tol) FAILED(); // ********** test point depth (2) d = (dRandReal()*2-1) * r; for (j=0; j<3; j++) a[j] = dRandReal()-0.5; dNormalize3 (a); if (dCalcVectorDot3_14(a,R+2) > 0) { for (j=0; j<3; j++) a[j] = p[j] + a[j]*(r-d) + l*0.5*R[j*4+2]; } else { for (j=0; j<3; j++) a[j] = p[j] + a[j]*(r-d) - l*0.5*R[j*4+2]; } if (dFabs(dGeomCapsulePointDepth (ccyl,a[0],a[1],a[2]) - d) >= tol) FAILED(); PASSED(); }
int main (int argc, char **argv) { dInitODE2(0); bool fixed = true; // setup pointers to drawstuff callback functions dsFunctions fn; fn.version = DS_VERSION; fn.start = &start; fn.step = &simLoop; fn.command = &command; fn.stop = 0; fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; dVector3 offset; dSetZero (offset, 4); // Default test case if (argc >= 2 ) { for (int i=1; i < argc; ++i) { //static int tata = 0; if (1) { if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) Help (argv); if ( 0 == strcmp ("-s", argv[i]) || 0 == strcmp ("--slider", argv[i]) ) type = dJointTypeSlider; if ( 0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) { int j = i+1; if ( j+1 > argc || // Check if we have enough arguments argv[j] == '\0' || // We should have a path here argv[j][0] == '-' ) // We should have a path not a command line Help (argv); else fn.path_to_textures = argv[++i]; // Increase i since we use this argument } } if ( 0 == strcmp ("-1", argv[i]) || 0 == strcmp ("--offset1", argv[i]) ) tc = 1; if ( 0 == strcmp ("-2", argv[i]) || 0 == strcmp ("--offset2", argv[i]) ) tc = 2; if ( 0 == strcmp ("-3", argv[i]) || 0 == strcmp ("--offset3", argv[i]) ) tc = 3; if (0 == strcmp ("-n", argv[i]) || 0 == strcmp ("--notFixed", argv[i]) ) fixed = false; } } world = dWorldCreate(); dWorldSetERP (world, 0.8); space = dSimpleSpaceCreate (0); contactgroup = dJointGroupCreate (0); geom[GROUND] = dCreatePlane (space, 0,0,1,0); dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); dGeomSetCollideBits (geom[GROUND], catBits[ALL]); dMass m; dMatrix3 R; // Create the Obstacle geom[OBS] = dCreateBox (space, OBS_SIDES[0], OBS_SIDES[1], OBS_SIDES[2]); dGeomSetCategoryBits (geom[OBS], catBits[OBS]); dGeomSetCollideBits (geom[OBS], catBits[ALL]); //Rotation of 45deg around y dRFromAxisAndAngle (R, 1,1,0, -0.25*PI); dGeomSetRotation (geom[OBS], R); dGeomSetPosition (geom[OBS], 1.95, -0.2, 0.5); //Rotation of 90deg around y // Will orient the Z axis along X dRFromAxisAndAngle (R, 0,1,0, -0.5*PI); // Create Body2 (Wiil be attached to the world) body[BODY2] = dBodyCreate (world); // Main axis of cylinder is along X=1 dMassSetBox (&m, 1, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); dMassAdjust (&m, Mass1); geom[BODY2] = dCreateBox (space, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); dGeomSetBody (geom[BODY2], body[BODY2]); dGeomSetOffsetRotation (geom[BODY2], R); dGeomSetCategoryBits (geom[BODY2], catBits[BODY2]); dGeomSetCollideBits (geom[BODY2], catBits[ALL] & (~catBits[BODY1]) ); dBodySetMass (body[BODY2], &m); // Create Body 1 (Slider on the prismatic axis) body[BODY1] = dBodyCreate (world); // Main axis of capsule is along X=1 dMassSetCapsule (&m, 1, 1, RADIUS, BODY1_LENGTH); dMassAdjust (&m, Mass1); geom[BODY1] = dCreateCapsule (space, RADIUS, BODY1_LENGTH); dGeomSetBody (geom[BODY1], body[BODY1]); dGeomSetOffsetRotation (geom[BODY1], R); dGeomSetCategoryBits (geom[BODY1], catBits[BODY1]); dGeomSetCollideBits (geom[BODY1], catBits[ALL] & ~catBits[BODY2] & ~catBits[RECT]); dMass mRect; dMassSetBox (&mRect, 1, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); dMassAdd (&m, &mRect); // TODO: translate m? geom[RECT] = dCreateBox (space, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); dGeomSetBody (geom[RECT], body[BODY1]); dGeomSetOffsetPosition (geom[RECT], (BODY1_LENGTH-RECT_SIDES[0]) /2.0, 0.0, -RADIUS -RECT_SIDES[2]/2.0); dGeomSetCategoryBits (geom[RECT], catBits[RECT]); dGeomSetCollideBits (geom[RECT], catBits[ALL] & (~catBits[BODY1]) ); dBodySetMass (body[BODY1], &m); setPositionBodies (tc); if ( fixed ) { // Attache external cylinder to the world dJointID fixed = dJointCreateFixed (world,0); dJointAttach (fixed , NULL, body[BODY2]); dJointSetFixed (fixed ); dWorldSetGravity (world,0,0,-0.8); } else { dWorldSetGravity (world,0,0,0); } // The static is here only to help debugging switch (type) { case dJointTypeSlider : { dSliderJoint *sj = new dSliderJoint (world, 0); sj->attach (body[BODY1], body[BODY2]); sj->setAxis (1, 0, 0); joint = sj; } break; case dJointTypePiston : // fall through default default: { dPistonJoint *pj = new dPistonJoint (world, 0); pj->attach (body[BODY1], body[BODY2]); pj->setAxis (1, 0, 0); dJointSetPistonAnchor(pj->id(), anchor[X], anchor[Y], anchor[Z]); joint = pj; } break; }; // run simulation dsSimulationLoop (argc,argv,400,300,&fn); delete joint; dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
dGeomID ColCapsule::CreateGeom( dSpaceID spaceID ) { float scale = PhysicsServer::s_pInstance->GetWorldScale(); float height = m_Height - m_Radius*2.0f; return dCreateCapsule( spaceID, m_Radius*scale, height*scale ); } // ColCapsule::CreateGeom
/******************************************************************************* Function to initialize ODE. *******************************************************************************/ void initODE() { ///////////////// Initializing the ODE general features //////////////////// dInitODE(); //Initialize library. World = dWorldCreate(); //Crate a new dynamics, empty world. Space = dSimpleSpaceCreate(0); //Create a new space for collision (independent). ContactGroup = dJointGroupCreate(0); //Create a joints container, without specifying size. dWorldSetGravity( World, 0.0, -9.81, 0 ); //Add gravity to this World. //Define error conrrection constants. dWorldSetERP( World, 0.2 ); dWorldSetCFM( World, 1e-5 ); //Set the velocity that interpenetrating objects will separate at. dWorldSetContactMaxCorrectingVel( World, 0.9 ); //Set the safety area for contacts to be considered at rest. dWorldSetContactSurfaceLayer( World, 0.001 ); //Automatically disable objects that have come to a rest. dWorldSetAutoDisableFlag( World, false ); /////////////// Initializing the rigid bodies in the world ///////////////// //Create a collision plane and add it to space. The next parameters are the //literal components of ax + by + cz = d. dCreatePlane( Space, 0.0, 1.0, 0.0, 0.0 ); const dReal xPos = 0; const dReal yPos = 5; const dReal zPos = 0; const dReal xRot = 0; const dReal yRot = 0; const dReal zRot = 0; const dReal radius = .75; const dReal length = 4; const dReal sides[3] = { 2, 2, 2 }; //Create body body.Body = dBodyCreate(World); dBodySetPosition(body.Body, xPos, yPos, zPos); dMatrix3 Orient3; //dRFromAxisAndAngle(Orient3, 0, 0, 1, 3.14/4); dRFromEulerAngles(Orient3, xRot, yRot, zRot); //dRFromEulerAngles(Orient3, 0, 0, 0); dBodySetRotation(body.Body, Orient3); dBodySetLinearVel(body.Body, 0, 0, 0); dBodySetData(body.Body, (void *)0); dMass bodyMass; dMassSetCapsule(&bodyMass, 1.0, 3, radius, length); //dMassSetBox(&bodyMass, 10, sides[0], sides[1], sides[2]); dBodySetMass(body.Body, &bodyMass); body.Geom = dCreateCapsule(Space, radius, length); //body.Geom = dCreateBox(Space, sides[0], sides[1], sides[2]); dGeomSetBody(body.Geom, body.Body); float head_pos[ 3 ] = { 0.0f, 5.0f, -1.0f }; createInvisibleHead( head_pos ); createFrontLegs(); createMiddleLegs(); createBackLegs(); rng_engine.seed( std::chrono::duration_cast< std::chrono::microseconds >( std::chrono::system_clock::now().time_since_epoch() ).count() ); const int foodPrize = 10; dReal position[3] = { 10.0f, 0.0f, -20.0f }; addFoodParticle( position, foodPrize, &World, &Space ); }
int test_ray_and_ccylinder() { int j; dContactGeom contact; dVector3 p,a,b,n; dMatrix3 R; dReal r,l,k,x,y; dSimpleSpace space(0); dGeomID ray = dCreateRay (0,0); dGeomID ccyl = dCreateCapsule (0,1,1); dSpaceAdd (space,ray); dSpaceAdd (space,ccyl); // ********** make a random capped cylinder r = dRandReal()*0.5 + 0.01; l = dRandReal()*1 + 0.01; dGeomCapsuleSetParams (ccyl,r,l); dMakeRandomVector (p,3,1.0); dGeomSetPosition (ccyl,p[0],p[1],p[2]); dRFromAxisAndAngle (R,dRandReal()*2-1,dRandReal()*2-1, dRandReal()*2-1,dRandReal()*10-5); dGeomSetRotation (ccyl,R); // ********** test ray completely within ccyl for (j=0; j<3; j++) a[j] = dRandReal()-0.5; dNormalize3 (a); k = (dRandReal()-0.5)*l; for (j=0; j<3; j++) a[j] = p[j] + r*0.99*a[j] + k*0.99*R[j*4+2]; for (j=0; j<3; j++) b[j] = dRandReal()-0.5; dNormalize3 (b); k = (dRandReal()-0.5)*l; for (j=0; j<3; j++) b[j] = p[j] + r*0.99*b[j] + k*0.99*R[j*4+2]; dGeomRaySetLength (ray,dCalcPointsDistance3(a,b)); for (j=0; j<3; j++) b[j] -= a[j]; dNormalize3 (b); dGeomRaySet (ray,a[0],a[1],a[2],b[0],b[1],b[2]); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); // ********** test ray outside ccyl that just misses (between caps) k = dRandReal()*2*M_PI; x = sin(k); y = cos(k); for (j=0; j<3; j++) a[j] = x*R[j*4+0] + y*R[j*4+1]; k = (dRandReal()-0.5)*l; for (j=0; j<3; j++) b[j] = -a[j]*r*2 + k*R[j*4+2] + p[j]; dGeomRaySet (ray,b[0],b[1],b[2],a[0],a[1],a[2]); dGeomRaySetLength (ray,r*0.99); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); // ********** test ray outside ccyl that just hits (between caps) dGeomRaySetLength (ray,r*1.01); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); // check depth of contact point if (dFabs (dGeomCapsulePointDepth (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) FAILED(); // ********** test ray outside ccyl that just misses (caps) for (j=0; j<3; j++) a[j] = dRandReal()-0.5; dNormalize3 (a); if (dCalcVectorDot3_14(a,R+2) < 0) { for (j=0; j<3; j++) b[j] = p[j] - a[j]*2*r + l*0.5*R[j*4+2]; } else { for (j=0; j<3; j++) b[j] = p[j] - a[j]*2*r - l*0.5*R[j*4+2]; } dGeomRaySet (ray,b[0],b[1],b[2],a[0],a[1],a[2]); dGeomRaySetLength (ray,r*0.99); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 0) FAILED(); // ********** test ray outside ccyl that just hits (caps) dGeomRaySetLength (ray,r*1.01); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom)) != 1) FAILED(); // check depth of contact point if (dFabs (dGeomCapsulePointDepth (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) FAILED(); // ********** test random rays for (j=0; j<3; j++) a[j] = dRandReal()-0.5; for (j=0; j<3; j++) n[j] = dRandReal()-0.5; dNormalize3 (n); dGeomRaySet (ray,a[0],a[1],a[2],n[0],n[1],n[2]); dGeomRaySetLength (ray,10); if (dCollide (ray,ccyl,1,&contact,sizeof(dContactGeom))) { // check depth of contact point if (dFabs (dGeomCapsulePointDepth (ccyl,contact.pos[0],contact.pos[1],contact.pos[2])) > tol) FAILED(); // check normal signs if (dCalcVectorDot3 (n,contact.normal) > 0) FAILED(); draw_all_objects (space); } PASSED(); }
bool WorldManagerServer::loadMap(const Ogre::String& mapName) { WorldManager::loadMap(mapName); //cleanup for (std::vector<dGeomID>::iterator igeom = mStaticGeometries.begin(); igeom != mStaticGeometries.end(); igeom++) { dGeomDestroy(*igeom); } //creating new game and loading new map Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(mapName); MyGUI::xml::xmlDocument xml; if (!xml.open(stream)) return false; MyGUI::xml::xmlNodePtr root_node = xml.getRoot(); if (root_node->getName() != "map") return false; MyGUI::xml::xmlNodeIterator inode = root_node->getNodeIterator(); while (inode.nextNode()) { if (inode->getName() == "geom") { Ogre::String type = inode->findAttribute("type"); std::vector<Ogre::String> params = Ogre::StringUtil::split(inode->findAttribute("size"), " "); dGeomID geom; if (type == "box") { geom = dCreateBox(mStaticSpace, Ogre::StringConverter::parseReal(params[0]), Ogre::StringConverter::parseReal(params[1]), Ogre::StringConverter::parseReal(params[2]) ); } else if (type == "sphere") { geom = dCreateSphere(mStaticSpace, Ogre::StringConverter::parseReal(params[0]) ); } else if (type == "cylinder") { geom = dCreateCylinder(mStaticSpace, Ogre::StringConverter::parseReal(params[0]), Ogre::StringConverter::parseReal(params[1]) ); } else if (type == "capsule") { geom = dCreateCapsule(mStaticSpace, Ogre::StringConverter::parseReal(params[0]), Ogre::StringConverter::parseReal(params[1]) ); } else if (type == "plane") { geom = dCreatePlane(mStaticSpace, Ogre::StringConverter::parseReal(params[0]), Ogre::StringConverter::parseReal(params[1]), Ogre::StringConverter::parseReal(params[2]), Ogre::StringConverter::parseReal(params[3]) ); } else { return false; } mStaticGeometries.push_back(geom); } else { return false; } } return true; }
static void command (int cmd) { size_t i; int k; dReal sides[3]; dMass m; int setBody; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'y') { setBody = 0; if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i if (obj[i].body) { dBodyDestroy (obj[i].body); } for (k=0; k < GPB; k++) { if (obj[i].geom[k]) { dGeomDestroy (obj[i].geom[k]); } } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*2-1 + platpos[0], dRandReal()*2-1 + platpos[1], dRandReal()+2 + platpos[2]); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dBodySetPosition (obj[i].body, platpos[0], platpos[1], platpos[2]+2); dRSetIdentity (R); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*) i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } else if (cmd == 'y') { dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } if (!setBody) for (k=0; k < GPB; k++) { if (obj[i].geom[k]) { dGeomSetBody (obj[i].geom[k],obj[i].body); } } dBodySetMass (obj[i].body,&m); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } else if (cmd == '1') { write_world = 1; } else if (cmd == ' ') { mov_time = 0; } else if (cmd == 'm') { mov_type = mov_type==1 ? 2 : 1; mov_time = 0; } }
static void command (int cmd) { int i,j,k; dReal sides[3]; dMass m; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || cmd == 'y' ) { if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy (obj[i].body); for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*2-1,dRandReal()*2-1,dRandReal()+3); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dReal maxheight = 0; for (k=0; k<num; k++) { const dReal *pos = dBodyGetPosition (obj[k].body); if (pos[2] > maxheight) maxheight = pos[2]; } dBodySetPosition (obj[i].body, 0,0,maxheight+1); dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*)(size_t)i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } else if (cmd == 'y') { sides[1] *= 0.5; dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } else if (cmd == 'm') { dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); obj[i].geom[0] = dCreateTriMesh(space, new_tmdata, 0, 0, 0); // remember the mesh's dTriMeshDataID on its userdata for convenience. dGeomSetData(obj[i].geom[0], new_tmdata); dMassSetTrimesh( &m, DENSITY, obj[i].geom[0] ); printf("mass at %f %f %f\n", m.c[0], m.c[1], m.c[2]); dGeomSetPosition(obj[i].geom[0], -m.c[0], -m.c[1], -m.c[2]); dMassTranslate(&m, -m.c[0], -m.c[1], -m.c[2]); } else if (cmd == 'x') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j<GPB; j++) { for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; } for (k=0; k<GPB; k++) { obj[i].geom[k] = dCreateGeomTransform (space); dGeomTransformSetCleanup (obj[i].geom[k],1); if (k==0) { dReal radius = dRandReal()*0.25+0.05; g2[k] = dCreateSphere (0,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]); dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; g2[k] = dCreateCapsule (0,radius,length); dMassSetCapsule (&m2,DENSITY,3,radius,length); } dGeomTransformSetGeom (obj[i].geom[k],g2[k]); // set the transformation (adjust the mass too) dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]); dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]); dMatrix3 Rtx; dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dGeomSetRotation (g2[k],Rtx); dMassRotate (&m2,Rtx); // add to the total mass dMassAdd (&m,&m2); } // move all encapsulated objects so that the center of mass is (0,0,0) for (k=0; k<2; k++) { dGeomSetPosition (g2[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); } dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]); } for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body); } dBodySetMass (obj[i].body,&m); } if (cmd == ' ') { selected++; if (selected >= num) selected = 0; if (selected < 0) selected = 0; } else if (cmd == 'd' && selected >= 0 && selected < num) { dBodyDisable (obj[selected].body); } else if (cmd == 'e' && selected >= 0 && selected < num) { dBodyEnable (obj[selected].body); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } }
static void command (int cmd) { size_t i; int j,k; dReal sides[3]; dMass m; int setBody; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y' || cmd == 'v') { setBody = 0; if (num < NUM) { i = num; num++; } else { i = nextobj; nextobj++; if (nextobj >= num) nextobj = 0; // destroy the body and geoms for slot i dBodyDestroy (obj[i].body); for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); } memset (&obj[i],0,sizeof(obj[i])); } obj[i].body = dBodyCreate (world); for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; dMatrix3 R; if (random_pos) { dBodySetPosition (obj[i].body, dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2); dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); } else { dReal maxheight = 0; for (k=0; k<num; k++) { const dReal *pos = dBodyGetPosition (obj[k].body); if (pos[2] > maxheight) maxheight = pos[2]; } dBodySetPosition (obj[i].body, 0,0,maxheight+1); dRSetIdentity (R); //dRFromAxisAndAngle (R,0,0,1,/*dRandReal()*10.0-5.0*/0); } dBodySetRotation (obj[i].body,R); dBodySetData (obj[i].body,(void*) i); if (cmd == 'b') { dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); } else if (cmd == 'c') { sides[0] *= 0.5; dMassSetCapsule (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCapsule (space,sides[0],sides[1]); } //<---- Convex Object else if (cmd == 'v') { dMassSetBox (&m,DENSITY,0.25,0.25,0.25); #if 0 obj[i].geom[0] = dCreateConvex (space, planes, planecount, points, pointcount, polygons); #else obj[i].geom[0] = dCreateConvex (space, Sphere_planes, Sphere_planecount, Sphere_points, Sphere_pointcount, Sphere_polygons); #endif } //----> Convex Object else if (cmd == 'y') { dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); } else if (cmd == 's') { sides[0] *= 0.5; dMassSetSphere (&m,DENSITY,sides[0]); obj[i].geom[0] = dCreateSphere (space,sides[0]); } else if (cmd == 'x' && USE_GEOM_OFFSET) { setBody = 1; // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); dReal dpos[GPB][3]; // delta-positions for encapsulated geometries dMatrix3 drot[GPB]; // set random delta positions for (j=0; j<GPB; j++) { for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; } for (k=0; k<GPB; k++) { if (k==0) { dReal radius = dRandReal()*0.25+0.05; obj[i].geom[k] = dCreateSphere (space,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { obj[i].geom[k] = dCreateBox (space,sides[0],sides[1],sides[2]); dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; obj[i].geom[k] = dCreateCapsule (space,radius,length); dMassSetCapsule (&m2,DENSITY,3,radius,length); } dRFromAxisAndAngle (drot[k],dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dMassRotate (&m2,drot[k]); dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]); // add to the total mass dMassAdd (&m,&m2); } for (k=0; k<GPB; k++) { dGeomSetBody (obj[i].geom[k],obj[i].body); dGeomSetOffsetPosition (obj[i].geom[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); dGeomSetOffsetRotation(obj[i].geom[k], drot[k]); } dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]); dBodySetMass (obj[i].body,&m); } else if (cmd == 'x') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j<GPB; j++) { for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15; } for (k=0; k<GPB; k++) { obj[i].geom[k] = dCreateGeomTransform (space); dGeomTransformSetCleanup (obj[i].geom[k],1); if (k==0) { dReal radius = dRandReal()*0.25+0.05; g2[k] = dCreateSphere (0,radius); dMassSetSphere (&m2,DENSITY,radius); } else if (k==1) { g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]); dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]); } else { dReal radius = dRandReal()*0.1+0.05; dReal length = dRandReal()*1.0+0.1; g2[k] = dCreateCapsule (0,radius,length); dMassSetCapsule (&m2,DENSITY,3,radius,length); } dGeomTransformSetGeom (obj[i].geom[k],g2[k]); // set the transformation (adjust the mass too) dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]); dMatrix3 Rtx; dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); dGeomSetRotation (g2[k],Rtx); dMassRotate (&m2,Rtx); // Translation *after* rotation dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]); // add to the total mass dMassAdd (&m,&m2); } // move all encapsulated objects so that the center of mass is (0,0,0) for (k=0; k<GPB; k++) { dGeomSetPosition (g2[k], dpos[k][0]-m.c[0], dpos[k][1]-m.c[1], dpos[k][2]-m.c[2]); } dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]); } if (!setBody) for (k=0; k < GPB; k++) { if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body); } dBodySetMass (obj[i].body,&m); } if (cmd == ' ') { selected++; if (selected >= num) selected = 0; if (selected < 0) selected = 0; } else if (cmd == 'd' && selected >= 0 && selected < num) { dBodyDisable (obj[selected].body); } else if (cmd == 'e' && selected >= 0 && selected < num) { dBodyEnable (obj[selected].body); } else if (cmd == 'a') { show_aabb ^= 1; } else if (cmd == 't') { show_contacts ^= 1; } else if (cmd == 'r') { random_pos ^= 1; } else if (cmd == '1') { write_world = 1; } else if (cmd == 'p'&& selected >= 0) { const dReal* pos = dGeomGetPosition(obj[selected].geom[0]); const dReal* rot = dGeomGetRotation(obj[selected].geom[0]); printf("POSITION:\n\t[%f,%f,%f]\n\n",pos[0],pos[1],pos[2]); printf("ROTATION:\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\t[%f,%f,%f,%f]\n\n", rot[0],rot[1],rot[2],rot[3], rot[4],rot[5],rot[6],rot[7], rot[8],rot[9],rot[10],rot[11]); } else if (cmd == 'f' && selected >= 0 && selected < num) { if (dBodyIsEnabled(obj[selected].body)) doFeedback = 1; } }