void elfRecalcJoint(elfJoint* joint) { elfVec3f pos1; elfVec3f pos2; elfVec4f qua1; elfVec4f qua2; elfVec4f aqua1; elfVec4f aqua2; elfVec3f worldCoordPivot1; elfVec3f localCoordPivot2; elfVec3f localAxis1; elfVec3f localAxis2; float matrix1[16]; float matrix2[16]; float matrix3[16]; pos1 = elfGetActorPosition(joint->actor1); pos2 = elfGetActorPosition(joint->actor2); qua1 = elfGetActorOrientation(joint->actor1); qua2 = elfGetActorOrientation(joint->actor2); worldCoordPivot1.x = joint->pivot[0]; worldCoordPivot1.y = joint->pivot[1]; worldCoordPivot1.z = joint->pivot[2]; worldCoordPivot1 = elfAddVec3fVec3f(elfMulQuaVec3f(qua1, worldCoordPivot1), pos1); localCoordPivot2 = elfMulQuaVec3f(elfGetQuaInverted(qua2), elfSubVec3fVec3f(worldCoordPivot1, pos2)); btVector3 pivotInA(joint->pivot[0], joint->pivot[1], joint->pivot[2]); btVector3 pivotInB(localCoordPivot2.x, localCoordPivot2.y, localCoordPivot2.z); aqua1 = elfCreateQuaFromEuler(joint->axis[0], joint->axis[1], joint->axis[2]); localAxis1 = elfMulQuaVec3f(aqua1, elfCreateVec3f(0.0f, 0.0f, 1.0f)); aqua2 = elfMulQuaQua(aqua1, elfMulQuaQua(qua1, elfGetQuaInverted(qua2))); localAxis2 = elfMulQuaVec3f(aqua2, elfCreateVec3f(0.0f, 0.0f, 1.0f)); btVector3 axisInA(localAxis1.x, localAxis1.y, localAxis1.z); btVector3 axisInB(localAxis2.x, localAxis2.y, localAxis2.z); if(joint->jointType == ELF_HINGE) { joint->constraint = new btHingeConstraint(*joint->actor1->object->body,* joint->actor2->object->body, pivotInA, pivotInB, axisInA, axisInB); joint->actor1->scene->world->world->addConstraint(joint->constraint); } else if(joint->jointType == ELF_BALL) { joint->constraint = new btPoint2PointConstraint(*joint->actor1->object->body,* joint->actor2->object->body, pivotInA, pivotInB); joint->actor1->scene->world->world->addConstraint(joint->constraint); } else if(joint->jointType == ELF_CONE_TWIST) { gfxMatrix4SetIdentity(matrix1); matrix1[12] = joint->pivot[0]; matrix1[13] = joint->pivot[1]; matrix1[14] = joint->pivot[2]; gfxQuaToMatrix4(&aqua1.x, matrix2); gfxMulMatrix4Matrix4(matrix1, matrix2, matrix3); btTransform frameInA; frameInA.setFromOpenGLMatrix(matrix3); gfxMatrix4SetIdentity(matrix1); matrix1[12] = localCoordPivot2.x; matrix1[13] = localCoordPivot2.y; matrix1[14] = localCoordPivot2.z; gfxQuaToMatrix4(&aqua2.x, matrix2); gfxMulMatrix4Matrix4(matrix1, matrix2, matrix3); btTransform frameInB; frameInB.setFromOpenGLMatrix(matrix3); joint->constraint = new btConeTwistConstraint(*joint->actor1->object->body, *joint->actor2->object->body, frameInA, frameInB); joint->actor1->scene->world->world->addConstraint(joint->constraint); } }
void BasicDemo::initPhysics(){ //printing debug_print_ = false; //set up world broadphase_ = new btDbvtBroadphase(); collisionConfiguration_ = new btDefaultCollisionConfiguration(); dispatcher_ = new btCollisionDispatcher(collisionConfiguration_); solver_ = new btSequentialImpulseConstraintSolver; dynamicsWorld_ = new btDiscreteDynamicsWorld(dispatcher_,broadphase_,solver_,collisionConfiguration_); //set gravity. y is apparently up. dynamicsWorld_->setGravity(btVector3(0,-10,0)); //--------------OBJECT CREATION SECTION-----------------// //make the ground plane groundCollisionShape_ = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); //collisionShapes_.push_back(groundCollisionShape_); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0.0f,-55.0f,0.0f)); btScalar groundMass(0.0); //create the ground plane rigid body groundRigidBody_ = createRigidBody(groundCollisionShape_,groundMass,groundTransform); //add it to the dynamics world dynamicsWorld_->addRigidBody(groundRigidBody_); //Calculate the required origins based on startPose_ given by the runSimulation function btVector3 bravoOrigin = startPose_; btVector3 tangoOrigin = startPose_; //tangoOrigin.setX(tangoOrigin.getX()+1.5); //make bravo rigid body (the sliding box) const btVector3 bravoBoxHalfExtents( 1.0f, 1.0f, 1.0f ); bravoCollisionShape_ = new btBoxShape(bravoBoxHalfExtents); //collisionShapes_.push_back(bravoCollisionShape_); btTransform bravoTransform; bravoTransform.setIdentity(); //bravoTransform.setOrigin(btVector3(0.0f,1.0f,0.0f)); bravoTransform.setOrigin(bravoOrigin); btScalar bravoMass = 1.0f; //create the bravo rigid body bravoRigidBody_ = createRigidBody(bravoCollisionShape_,bravoMass,bravoTransform); //add it to the dynamics world dynamicsWorld_->addRigidBody(bravoRigidBody_); //make tango rigid body (the robots manipulator) const btVector3 tangoBoxHalfExtents( 0.1f, 0.5f, 0.1f ); tangoCollisionShape_ = new btBoxShape(tangoBoxHalfExtents); //collisionShapes_.push_back(tangoCollisionShape_); btTransform tangoTransform; tangoTransform.setIdentity(); //tangoTransform.setOrigin(btVector3(1.5f,1.0f,0.0f)); tangoTransform.setOrigin(tangoOrigin); btScalar tangoMass = 0.1f; //create the tango rigid body tangoRigidBody_ = createRigidBody(tangoCollisionShape_,tangoMass,tangoTransform); //add it to the dynamics world dynamicsWorld_->addRigidBody(tangoRigidBody_); //--------------END OBJECT CREATION SECTION-----------------// //--------------CONSTRAINT CREATION SECTION-----------------// // create a constraint //const btVector3 pivotInA( 1.5f, 0.0f, 0.0f ); const btVector3 pivotInA( 0.0f, 0.0f, 0.0f ); const btVector3 pivotInB( 0.0f, 0.0f, 0.0f ); btVector3 axisInA( 0.0f, 1.0f, 0.0f ); btVector3 axisInB( 0.0f, 1.0f, 0.0f ); bool useReferenceFrameA = false; hingeConstraint_ = new btHingeConstraint(*bravoRigidBody_,*tangoRigidBody_,pivotInA,pivotInB,axisInA,axisInB,useReferenceFrameA); // set joint feedback hingeConstraint_->setJointFeedback(&jfRobot_); // add constraint to the world const bool isDisableCollisionsBetweenLinkedBodies = true; //this used to be false dynamicsWorld_->addConstraint(hingeConstraint_, isDisableCollisionsBetweenLinkedBodies); //--------------END CONSTRAINT CREATION SECTION-----------------// //--------------INITIALIZE REMAINING PARAMETERS SECTION-----------------// //set controller values pGains_.setValue(5.0f,50.0f,5.0f); dGains_.setValue(2.0f,2.0f,2.0f); //initialize tangoRigidBody_->getMotionState()->getWorldTransform(tangoBodyTrans_); currentPose_ = tangoBodyTrans_.getOrigin(); desiredPose_ = currentPose_; bravoRigidBody_->forceActivationState(4); count_ = 0; //--------------END INITIALIZE REMAINING PARAMETERS SECTION-----------------// }
int main(int argc,char** argv) { int i; for (i=0;i<numObjects;i++) { if (i>0) { shapePtr[i] = prebuildShapePtr[1]; shapeIndex[i] = 1;//sphere } else { shapeIndex[i] = 0; shapePtr[i] = prebuildShapePtr[0]; } } ConvexDecomposition::WavefrontObj wo; char* filename = "file.obj"; tcount = wo.loadObj(filename); class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface { public: MyConvexDecomposition (FILE* outputFile) :mBaseCount(0), mHullCount(0), mOutputFile(outputFile) { } virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result) { TriangleMesh* trimesh = new TriangleMesh(); SimdVector3 localScaling(6.f,6.f,6.f); //export data to .obj printf("ConvexResult\n"); if (mOutputFile) { fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount ); fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount); fprintf(mOutputFile,"o Object%i\r\n",mBaseCount); for (unsigned int i=0; i<result.mHullVcount; i++) { const float *p = &result.mHullVertices[i*3]; fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] ); } //calc centroid, to shift vertices around center of mass centroids[numObjects] = SimdVector3(0,0,0); if ( 1 ) { const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullTcount; i++) { unsigned int index0 = *src++; unsigned int index1 = *src++; unsigned int index2 = *src++; SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]); SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]); SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; centroids[numObjects] += vertex0; centroids[numObjects]+= vertex1; centroids[numObjects]+= vertex2; } } centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3); if ( 1 ) { const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullTcount; i++) { unsigned int index0 = *src++; unsigned int index1 = *src++; unsigned int index2 = *src++; SimdVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]); SimdVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]); SimdVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; vertex0 -= centroids[numObjects]; vertex1 -= centroids[numObjects]; vertex2 -= centroids[numObjects]; trimesh->AddTriangle(vertex0,vertex1,vertex2); index0+=mBaseCount; index1+=mBaseCount; index2+=mBaseCount; fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 ); } } shapeIndex[numObjects] = numObjects; shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh); mBaseCount+=result.mHullVcount; // advance the 'base index' counter. } } int mBaseCount; int mHullCount; FILE* mOutputFile; }; if (tcount) { numObjects = 1; //always have the ground object first TriangleMesh* trimesh = new TriangleMesh(); SimdVector3 localScaling(6.f,6.f,6.f); for (int i=0;i<wo.mTriCount;i++) { int index0 = wo.mIndices[i*3]; int index1 = wo.mIndices[i*3+1]; int index2 = wo.mIndices[i*3+2]; SimdVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]); SimdVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]); SimdVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; trimesh->AddTriangle(vertex0,vertex1,vertex2); } shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh); } if (tcount) { char outputFileName[512]; strcpy(outputFileName,filename); char *dot = strstr(outputFileName,"."); if ( dot ) *dot = 0; strcat(outputFileName,"_convex.obj"); FILE* outputFile = fopen(outputFileName,"wb"); unsigned int depth = 7; float cpercent = 5; float ppercent = 15; unsigned int maxv = 16; float skinWidth = 0.01; printf("WavefrontObj num triangles read %i",tcount); ConvexDecomposition::DecompDesc desc; desc.mVcount = wo.mVertexCount; desc.mVertices = wo.mVertices; desc.mTcount = wo.mTriCount; desc.mIndices = (unsigned int *)wo.mIndices; desc.mDepth = depth; desc.mCpercent = cpercent; desc.mPpercent = ppercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; MyConvexDecomposition convexDecomposition(outputFile); desc.mCallback = &convexDecomposition; //convexDecomposition.performConvexDecomposition(desc); ConvexBuilder cb(desc.mCallback); int ret = cb.process(desc); if (outputFile) fclose(outputFile); } CollisionDispatcher* dispatcher = new CollisionDispatcher(); SimdVector3 worldAabbMin(-10000,-10000,-10000); SimdVector3 worldAabbMax(10000,10000,10000); OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); //OverlappingPairCache* broadphase = new SimpleBroadphase(); physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); physicsEnvironmentPtr->setDeactivationTime(2.f); physicsEnvironmentPtr->setGravity(0,-10,0); PHY_ShapeProps shapeProps; shapeProps.m_do_anisotropic = false; shapeProps.m_do_fh = false; shapeProps.m_do_rot_fh = false; shapeProps.m_friction_scaling[0] = 1.; shapeProps.m_friction_scaling[1] = 1.; shapeProps.m_friction_scaling[2] = 1.; shapeProps.m_inertia = 1.f; shapeProps.m_lin_drag = 0.2f; shapeProps.m_ang_drag = 0.1f; shapeProps.m_mass = 10.0f; PHY_MaterialProps materialProps; materialProps.m_friction = 10.5f; materialProps.m_restitution = 0.0f; CcdConstructionInfo ccdObjectCi; ccdObjectCi.m_friction = 0.5f; ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; SimdTransform tr; tr.setIdentity(); for (i=0;i<numObjects;i++) { shapeProps.m_shape = shapePtr[shapeIndex[i]]; shapeProps.m_shape->SetMargin(0.05f); bool isDyna = i>0; //if (i==1) // isDyna=false; if (0)//i==1) { SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); } if (i>0) { switch (i) { case 1: { ms[i].setWorldPosition(0,10,0); //for testing, rotate the ground cube so the stack has to recover a bit break; } case 2: { ms[i].setWorldPosition(0,8,2); break; } default: ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0); } float quatIma0,quatIma1,quatIma2,quatReal; SimdQuaternion quat; SimdVector3 axis(0,0,1); SimdScalar angle=0.5f; quat.setRotation(axis,angle); ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]); } else { ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0); } ccdObjectCi.m_MotionState = &ms[i]; ccdObjectCi.m_gravity = SimdVector3(0,0,0); ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); if (!isDyna) { shapeProps.m_mass = 0.f; ccdObjectCi.m_mass = shapeProps.m_mass; ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; } else { shapeProps.m_mass = 1.f; ccdObjectCi.m_mass = shapeProps.m_mass; ccdObjectCi.m_collisionFlags = 0; } SimdVector3 localInertia; if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) { //take inertia from first shape shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia); } else { shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); } ccdObjectCi.m_localInertiaTensor = localInertia; ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; physObjects[i]= new CcdPhysicsController( ccdObjectCi); // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS; //Experimental: better estimation of CCD Time of Impact: //physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS; physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); if (i==1) { //physObjects[i]->SetAngularVelocity(0,0,-2,true); } physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); } //create a constraint if (createConstraint) { //physObjects[i]->SetAngularVelocity(0,0,-2,true); int constraintId; float pivotX=CUBE_HALF_EXTENTS, pivotY=-CUBE_HALF_EXTENTS, pivotZ=CUBE_HALF_EXTENTS; float axisX=1,axisY=0,axisZ=0; HingeConstraint* hinge = 0; SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); SimdVector3 axisInA(0,1,0); SimdVector3 axisInB(0,-1,0); RigidBody* rb0 = physObjects[1]->GetRigidBody(); RigidBody* rb1 = physObjects[2]->GetRigidBody(); hinge = new HingeConstraint( *rb0, *rb1,pivotInA,pivotInB,axisInA,axisInB); physicsEnvironmentPtr->m_constraints.push_back(hinge); hinge->SetUserConstraintId(100); hinge->SetUserConstraintType(PHY_LINEHINGE_CONSTRAINT); } clientResetScene(); setCameraDistance(26.f); return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/"); }
void TestHingeTorque::initPhysics() { int upAxis = 1; m_guiHelper->setUpAxis(upAxis); createEmptyDynamicsWorld(); m_dynamicsWorld->getSolverInfo().m_splitImpulse = false; m_dynamicsWorld->setGravity(btVector3(0,0,-10)); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); int mode = btIDebugDraw::DBG_DrawWireframe +btIDebugDraw::DBG_DrawConstraints +btIDebugDraw::DBG_DrawConstraintLimits; m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode); { // create a door using hinge constraint attached to the world int numLinks = 2; bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals bool canSleep = false; bool selfCollide = false; btVector3 linkHalfExtents(0.05, 0.37, 0.1); btVector3 baseHalfExtents(0.05, 0.37, 0.1); btBoxShape* baseBox = new btBoxShape(baseHalfExtents); btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); btTransform baseWorldTrans; baseWorldTrans.setIdentity(); baseWorldTrans.setOrigin(basePosition); //mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm //init the base btVector3 baseInertiaDiag(0.f, 0.f, 0.f); float baseMass = 0.f; float linkMass = 1.f; btRigidBody* base = createRigidBody(baseMass,baseWorldTrans,baseBox); m_dynamicsWorld->removeRigidBody(base); base->setDamping(0,0); m_dynamicsWorld->addRigidBody(base,collisionFilterGroup,collisionFilterMask); btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents); btSphereShape* linkSphere = new btSphereShape(radius); btRigidBody* prevBody = base; for (int i=0;i<numLinks;i++) { btTransform linkTrans; linkTrans = baseWorldTrans; linkTrans.setOrigin(basePosition-btVector3(0,linkHalfExtents[1]*2.f*(i+1),0)); btCollisionShape* colOb = 0; if (i==0) { colOb = linkBox1; } else { colOb = linkSphere; } btRigidBody* linkBody = createRigidBody(linkMass,linkTrans,colOb); m_dynamicsWorld->removeRigidBody(linkBody); m_dynamicsWorld->addRigidBody(linkBody,collisionFilterGroup,collisionFilterMask); linkBody->setDamping(0,0); btTypedConstraint* con = 0; if (i==0) { //create a hinge constraint btVector3 pivotInA(0,-linkHalfExtents[1],0); btVector3 pivotInB(0,linkHalfExtents[1],0); btVector3 axisInA(1,0,0); btVector3 axisInB(1,0,0); bool useReferenceA = true; btHingeConstraint* hinge = new btHingeConstraint(*prevBody,*linkBody, pivotInA,pivotInB, axisInA,axisInB,useReferenceA); con = hinge; } else { btTransform pivotInA(btQuaternion::getIdentity(),btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset btTransform pivotInB(btQuaternion::getIdentity(),btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset btGeneric6DofSpring2Constraint* fixed = new btGeneric6DofSpring2Constraint(*prevBody, *linkBody, pivotInA,pivotInB); fixed->setLinearLowerLimit(btVector3(0,0,0)); fixed->setLinearUpperLimit(btVector3(0,0,0)); fixed->setAngularLowerLimit(btVector3(0,0,0)); fixed->setAngularUpperLimit(btVector3(0,0,0)); con = fixed; } btAssert(con); if (con) { btJointFeedback* fb = new btJointFeedback(); m_jointFeedback.push_back(fb); con->setJointFeedback(fb); m_dynamicsWorld->addConstraint(con,true); } prevBody = linkBody; } } if (1) { btVector3 groundHalfExtents(1,1,0.2); groundHalfExtents[upAxis]=1.f; btBoxShape* box = new btBoxShape(groundHalfExtents); box->initializePolyhedralFeatures(); btTransform start; start.setIdentity(); btVector3 groundOrigin(-0.4f, 3.f, 0.f); btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); btQuaternion groundOrn(btVector3(0,1,0),0.25*SIMD_PI); groundOrigin[upAxis] -=.5; groundOrigin[2]-=0.6; start.setOrigin(groundOrigin); // start.setRotation(groundOrn); btRigidBody* body = createRigidBody(0,start,box); body->setFriction(0); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); }