/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of EITHER: * * (1) The GNU Lesser General Public License as published by the Free * * Software Foundation; either version 2.1 of the License, or (at * * your option) any later version. The text of the GNU Lesser * * General Public License is included with this library in the * * file LICENSE.TXT. * * (2) The BSD-style license that is included with this library in * * the file LICENSE-BSD.TXT. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * * LICENSE.TXT and LICENSE-BSD.TXT for more details. * * * *************************************************************************/ /* This file try to demonstrate how the PR joint is working. The axisP is draw in red and the axisR is in green */ #include #include #include #include #include "texturepath.h" #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif // select correct drawing functions #ifdef dDOUBLE #define dsDrawBox dsDrawBoxD #endif // physics parameters #define BOX1_LENGTH 2 // Size along the X axis #define BOX1_WIDTH 1 // Size along the Y axis #define BOX1_HEIGHT 0.4 // Size along the Z axis (up) since gravity is (0,0,-10) #define BOX2_LENGTH 0.2 #define BOX2_WIDTH 0.1 #define BOX2_HEIGHT 0.4 #define Mass1 10 #define Mass2 0.1 #define PRISMATIC_ONLY 1 #define ROTOIDE_ONLY 2 int flag = 0; //camera view static float xyz[3] = {2.0f,-3.5f,2.0000f}; static float hpr[3] = {90.000f,-25.5000f,0.0000f}; //world,space,body & geom static dWorldID world; static dSpaceID space; static dSpaceID box1_space; static dBodyID box1_body[1]; static dBodyID box2_body[1]; static dJointID joint[1]; static dJointGroupID contactgroup; static dGeomID ground; static dGeomID box1[1]; static dGeomID box2[1]; //collision detection static void nearCallback (void *, dGeomID o1, dGeomID o2) { int i,n; dBodyID b1 = dGeomGetBody(o1); dBodyID b2 = dGeomGetBody(o2); if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; const int N = 10; dContact contact[N]; n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact)); if (n > 0) { for (i=0; i= 2 ) { for (int i=1; i < argc; ++i) { if ( 0 == strcmp("-h", argv[i]) || 0 == strcmp("--help", argv[i]) ) Help(argv); if (!flag && (0 == strcmp("-p", argv[i]) ||0 == strcmp("--prismatic-only", argv[i])) ) flag = PRISMATIC_ONLY; if (!flag && (0 == strcmp("-r", argv[i]) || 0 == strcmp("--rotoide-only", argv[i])) ) flag = ROTOIDE_ONLY; if (0 == strcmp("-t", argv[i]) || 0 == strcmp("--texture-path", argv[i])) { int j = i+1; if ( j >= argc || // Check if we have enough arguments argv[j][0] == '\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 } } } dInitODE2(0); // create world world = dWorldCreate(); space = dHashSpaceCreate (0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-10); ground = dCreatePlane (space,0,0,1,0); //create two boxes dMass m; box1_body[0] = dBodyCreate (world); dMassSetBox (&m,1,BOX1_LENGTH,BOX1_WIDTH,BOX1_HEIGHT); dMassAdjust (&m,Mass1); dBodySetMass (box1_body[0],&m); box1[0] = dCreateBox (0,BOX1_LENGTH,BOX1_WIDTH,BOX1_HEIGHT); dGeomSetBody (box1[0],box1_body[0]); box2_body[0] = dBodyCreate (world); dMassSetBox (&m,10,BOX2_LENGTH,BOX2_WIDTH,BOX2_HEIGHT); dMassAdjust (&m,Mass2); dBodySetMass (box2_body[0],&m); box2[0] = dCreateBox (0,BOX2_LENGTH,BOX2_WIDTH,BOX2_HEIGHT); dGeomSetBody (box2[0],box2_body[0]); //set the initial positions of body1 and body2 dMatrix3 R; dRSetIdentity(R); dBodySetPosition (box1_body[0],0,0,BOX1_HEIGHT/2.0); dBodySetRotation (box1_body[0], R); dBodySetPosition (box2_body[0], 2.1, 0.0, BOX2_HEIGHT/2.0); dBodySetRotation (box2_body[0], R); //set PR joint joint[0] = dJointCreatePR(world,0); dJointAttach (joint[0],box1_body[0],box2_body[0]); switch (flag) { case PRISMATIC_ONLY: dJointSetPRAnchor (joint[0], 2.1, 0.0, BOX2_HEIGHT/2.0); dJointSetPRParam (joint[0],dParamLoStop, -0.5); dJointSetPRParam (joint[0],dParamHiStop, 1.5); break; case ROTOIDE_ONLY: dJointSetPRAnchor (joint[0], 0.0, 0.0, BOX2_HEIGHT/2.0); dJointSetPRParam (joint[0],dParamLoStop, 0.0); dJointSetPRParam (joint[0],dParamHiStop, 0.0); break; default: dJointSetPRAnchor (joint[0], 1.1, 0.0, BOX2_HEIGHT/2.0); dJointSetPRParam (joint[0],dParamLoStop, -0.5); dJointSetPRParam (joint[0],dParamHiStop, 1.5); break; } dJointSetPRAxis1(joint[0],1,0,0); dJointSetPRAxis2(joint[0],0,0,1); // We position the 2 body // The position of the rotoide joint is on the second body so it can rotate on itself // and move along the X axis. // With this anchor // - A force in X will move only the body 2 inside the low and hi limit // of the prismatic // - A force in Y will make the 2 bodies to rotate around on the plane box1_space = dSimpleSpaceCreate (space); dSpaceSetCleanup (box1_space,0); dSpaceAdd(box1_space,box1[0]); // run simulation dsSimulationLoop (argc,argv,400,300,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }