void GpuDemo1::setupScene(const ConstructionInfo& ci) { btCollisionShape* groundShape =0; // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); if (ci.m_useConcaveMesh) { btTriangleMesh* meshInterface = new btTriangleMesh(); btAlignedObjectArray<btVector3> concaveVertices; concaveVertices.push_back(btVector3(0,-20,0)); concaveVertices.push_back(btVector3(80,10,80)); concaveVertices.push_back(btVector3(80,10,-80)); concaveVertices.push_back(btVector3(-80,10,-80)); concaveVertices.push_back(btVector3(-80,10,80)); meshInterface->addTriangle(concaveVertices[0],concaveVertices[1],concaveVertices[2],true); meshInterface->addTriangle(concaveVertices[0],concaveVertices[2],concaveVertices[3],true); meshInterface->addTriangle(concaveVertices[0],concaveVertices[3],concaveVertices[4],true); meshInterface->addTriangle(concaveVertices[0],concaveVertices[4],concaveVertices[1],true); #if 0 groundShape = new btBvhTriangleMeshShape(meshInterface,true);//btStaticPlaneShape(btVector3(0,1,0),50); #else btBoxShape* shape =new btBoxShape(btVector3(btScalar(250.),btScalar(10.),btScalar(250.))); shape->initializePolyhedralFeatures(); groundShape = shape; #endif } else { groundShape = new btBoxShape(btVector3(btScalar(250.),btScalar(50.),btScalar(250.))); } m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,0,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: if (ci.m_useConcaveMesh) { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance //vertices.push_back(btVector3(0,1,0)); vertices.push_back(btVector3(1,1,1)); vertices.push_back(btVector3(1,1,-1)); vertices.push_back(btVector3(-1,1,-1)); vertices.push_back(btVector3(-1,1,1)); vertices.push_back(btVector3(1,-1,1)); vertices.push_back(btVector3(1,-1,-1)); vertices.push_back(btVector3(-1,-1,-1)); vertices.push_back(btVector3(-1,-1,1)); #if 0 btPolyhedralConvexShape* colShape = new btConvexHullShape(&vertices[0].getX(),vertices.size()); colShape->initializePolyhedralFeatures(); #else btCompoundShape* compoundShape = 0; { btPolyhedralConvexShape* colShape = new btConvexHullShape(&vertices[0].getX(),vertices.size()); colShape->initializePolyhedralFeatures(); compoundShape = new btCompoundShape(); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(0,-1,0)); compoundShape->addChildShape(tr,colShape); tr.setOrigin(btVector3(0,0,2)); compoundShape->addChildShape(tr,colShape); tr.setOrigin(btVector3(2,0,0)); compoundShape->addChildShape(tr,colShape); } btCollisionShape* colShape = compoundShape; #endif btPolyhedralConvexShape* boxShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); boxShape->initializePolyhedralFeatures(); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); m_collisionShapes.push_back(boxShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); float start_x = START_POS_X - ci.arraySizeX/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ci.arraySizeZ/2; for (int k=0;k<ci.arraySizeY;k++) { int sizeX = ci.arraySizeX; if (!ci.m_useConcaveMesh && k==0) sizeX = 50; int startX = !ci.m_useConcaveMesh&&k==0? -20 : 0; float gapX = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapX; for (int i=0;i<sizeX;i++) { int sizeZ = !ci.m_useConcaveMesh&&k==0? 50 : ci.arraySizeZ; int startZ = (!ci.m_useConcaveMesh)&&k==0? -20 : 0; float gapZ = !ci.m_useConcaveMesh&&k==0? 3.05 : ci.gapZ; for(int j = 0;j<sizeZ;j++) { //btCollisionShape* shape = k==0? boxShape : colShape; btCollisionShape* shape = colShape; btScalar mass = 1; if (!ci.m_useConcaveMesh && k==0) mass = k==0? 0.f : 1.f; //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) shape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(SCALING*btVector3( btScalar(startX+gapX*i + start_x), btScalar(20+ci.gapY*k + start_y), btScalar(startZ+gapZ*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } } }
int main() { int i, j; btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration); btBroadphaseInterface *overlappingPairCache = new btDbvtBroadphase(); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btDiscreteDynamicsWorld *dynamicsWorld = new btDiscreteDynamicsWorld( dispatcher, overlappingPairCache, solver, collisionConfiguration); dynamicsWorld->setGravity(btVector3(0, gravity, 0)); dynamicsWorld->setInternalTickCallback(myTickCallback); btAlignedObjectArray<btCollisionShape*> collisionShapes; // Ground. { btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, 0, 0)); btCollisionShape* groundShape; #if 1 // x / z plane at y = -1. groundShape = new btStaticPlaneShape(btVector3(groundXNormal, 1, 0), -1); #else // A cube of width 10 at y = -6. // Does not fall because we won't call: // colShape->calculateLocalInertia // TODO: remove this from this example into a collision shape example. groundTransform.setOrigin(btVector3(0, -6, 0)); groundShape = new btBoxShape( btVector3(btScalar(5.0), btScalar(5.0), btScalar(5.0))); #endif collisionShapes.push_back(groundShape); btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0, myMotionState, groundShape, btVector3(0, 0, 0)); btRigidBody* body = new btRigidBody(rbInfo); body->setRestitution(groundRestitution); dynamicsWorld->addRigidBody(body); } // Object. { btCollisionShape *colShape; #if 1 colShape = new btSphereShape(btScalar(1.0)); #else // Because of numerical instabilities, the cube spins all over, // moving on the x and y directions. colShape = new btBoxShape( btVector3(btScalar(1.0), btScalar(1.0), btScalar(1.0))); #endif collisionShapes.push_back(colShape); btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(0, initialY, 0)); btVector3 localInertia(0, 0, 0); btScalar mass(1.0f); colShape->calculateLocalInertia(mass, localInertia); btDefaultMotionState *myMotionState = new btDefaultMotionState(startTransform); btRigidBody *body = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo( mass, myMotionState, colShape, localInertia)); body->setRestitution(objectRestitution); dynamicsWorld->addRigidBody(body); } // Main loop. std::printf("step body x y z collision a b normal\n"); for (i = 0; i < maxNPoints; ++i) { dynamicsWorld->stepSimulation(timeStep); for (j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; --j) { btCollisionObject *obj = dynamicsWorld->getCollisionObjectArray()[j]; btRigidBody *body = btRigidBody::upcast(obj); btTransform trans; if (body && body->getMotionState()) { body->getMotionState()->getWorldTransform(trans); } else { trans = obj->getWorldTransform(); } btVector3 origin = trans.getOrigin(); std::printf("%d %d " PRINTF_FLOAT " " PRINTF_FLOAT " " PRINTF_FLOAT " ", i, j, origin.getX(), origin.getY(), origin.getZ()); auto& manifoldPoints = objectsCollisions[body]; if (manifoldPoints.empty()) { std::printf("0 "); } else { std::printf("1 "); for (auto& pt : manifoldPoints) { std::vector<btVector3> data; data.push_back(pt->getPositionWorldOnA()); data.push_back(pt->getPositionWorldOnB()); data.push_back(pt->m_normalWorldOnB); for (auto& v : data) { std::printf( PRINTF_FLOAT " " PRINTF_FLOAT " " PRINTF_FLOAT " ", v.getX(), v.getY(), v.getZ()); } } } puts(""); } } // Cleanup. for (i = dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) { btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { delete body->getMotionState(); } dynamicsWorld->removeCollisionObject(obj); delete obj; } for (i = 0; i < collisionShapes.size(); ++i) { delete collisionShapes[i]; } delete dynamicsWorld; delete solver; delete overlappingPairCache; delete dispatcher; delete collisionConfiguration; collisionShapes.clear(); }
HeightmapNode::HeightmapNode(EditorScene * _scene, Landscape *_land) : Entity() , position(0,0,0) , rotation(0) { SetName("HeightmapNode"); editorScene = _scene; SetVisible(false); land = _land; DVASSERT(land); //Get LandSize; Vector3 landSize; AABBox3 transformedBox; Matrix4 * worldTransformPtr = land->GetWorldTransformPtr(); land->GetBoundingBox().GetTransformedBox(*worldTransformPtr, transformedBox); landSize = transformedBox.max - transformedBox.min; heightmap = land->GetHeightmap(); sizeInMeters = landSize.x; areaScale = sizeInMeters / heightmap->Size(); maxHeight = landSize.z; heightScale = maxHeight / 65535.f; float32 minHeight = 0.0f; uint16 *dt = heightmap->Data(); size.x = (float32)heightmap->Size(); size.y = (float32)heightmap->Size(); hmap.resize(heightmap->Size() * heightmap->Size()); for (int32 y = 0; y < heightmap->Size(); ++y) { for (int32 x = 0; x < heightmap->Size(); ++x) { int32 index = x + (y) * heightmap->Size(); float32 mapValue = dt[index] * heightScale; SetValueToMap(x, y, mapValue, transformedBox); } } bool flipQuadEdges = true; colShape = new btHeightfieldTerrainShape(heightmap->Size(), heightmap->Size() , &hmap.front(), heightScale, minHeight, maxHeight , 2, PHY_FLOAT , flipQuadEdges); colShape->setLocalScaling(btVector3(areaScale, areaScale, 1.0f)); // Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(0.0f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3( btScalar(position.x), btScalar(position.y), btScalar(maxHeight/2.0f + position.z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects motionSate = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,motionSate,colShape,localInertia); rbInfo.m_friction = 0.9f; body = new btRigidBody(rbInfo); collisionObject = new btCollisionObject(); collisionObject->setWorldTransform(startTransform); collisionObject->setCollisionShape(colShape); editorScene->landCollisionWorld->addCollisionObject(collisionObject); editorScene->landCollisionWorld->updateAabbs(); }
void BasicGpuDemo::createObjects() { ///create a few basic rigid bodies btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(150.),btScalar(50.),btScalar(150.))); //groundShape->initializePolyhedralFeatures(); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); if (0) { btTransform tr; tr.setIdentity(); btVector3 faraway(-1e30,-1e30,-1e30); tr.setOrigin(faraway); btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(tr); btSphereShape* dummyShape = new btSphereShape(0.f); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,dummyShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setWorldTransform(groundTransform); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btBoxShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btSphereShape(btScalar(SCALING*1.f)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(SCALING*btVector3( btScalar(2.*i + start_x), btScalar(6+2.0*k + start_y), btScalar(2.*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setWorldTransform(startTransform); m_dynamicsWorld->addRigidBody(body); } } } } m_np->writeAllBodiesToGpu(); m_bp->writeAabbsToGpu(); m_rbp->writeAllInstancesToGpu(); }
void BasicDemo3D::initPhysics() { setTexturing(true); setShadows(false); // setCameraDistance(btScalar(SCALING*50.)); #if LARGE_DEMO setCameraDistance(btScalar(SCALING*50.)); #else setCameraDistance(btScalar(SCALING*20.)); #endif m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z); m_azi = btScalar(0.f); m_ele = btScalar(0.f); ///collision configuration contains default setup for memory, collision setup btDefaultCollisionConstructionInfo dci; dci.m_defaultMaxPersistentManifoldPoolSize=100000; dci.m_defaultMaxCollisionAlgorithmPoolSize=100000; dci.m_customCollisionAlgorithmMaxElementSize = sizeof(SpuContactManifoldCollisionAlgorithm); ///SpuContactManifoldCollisionAlgorithm is larger than any of the other collision algorithms //@@ dci.m_customMaxCollisionAlgorithmSize = sizeof(SpuContactManifoldCollisionAlgorithm); m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) //m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); #ifndef WIN32 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); #else unsigned int maxNumOutstandingTasks =4; //createCollisionLocalStoreMemory(); //processSolverTask Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("narrowphase_multi",processCollisionTask,createCollisionLocalStoreMemory,maxNumOutstandingTasks); class btThreadSupportInterface* threadInterface = new Win32ThreadSupport(threadConstructionInfo); m_dispatcher = new SpuGatheringCollisionDispatcher(threadInterface,maxNumOutstandingTasks,m_collisionConfiguration); #endif //SINGLE_THREADED_NARROWPHASE //## m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc); //## m_dispatcher->registerCollisionCreateFunc(CUSTOM_CONVEX_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc); // m_broadphase = new btDbvtBroadphase(); //## gPairCache = new (btAlignedAlloc(sizeof(btCudaDemoPairCache),16)) btCudaDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES); // gPairCache = NULL; gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); //m_broadphase = new btSimpleBroadphase(16384, gPairCache); /* btCudaBroadphase::btCudaBroadphase( btOverlappingPairCache* overlappingPairCache, const btVector3& worldAabbMin,const btVector3& worldAabbMax, int gridSizeX, int gridSizeY, int gridSizeZ, int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody, int maxBodiesPerCell, btScalar cellFactorAABB) */ btScalar maxDiam = 1.76f * 2.0f * SCALING; btVector3 cellSize(maxDiam, maxDiam, maxDiam); btVector3 numOfCells = (gWorldMax - gWorldMin) / cellSize; int numOfCellsX = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[0]); int numOfCellsY = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[1]); int numOfCellsZ = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[2]); m_broadphase = new bt3dGridBroadphaseOCL(gPairCache, cellSize,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,32,10.f, 32); // m_broadphase = new bt3dGridBroadphaseOCL(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,8,8,1./1.5); // m_broadphase = new btGpu3DGridBroadphaseOCL(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,8,8,1./1.5); // m_broadphase = new btGpu3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,8,8,1./1.5); //#define USE_CUDA_BROADPHASE 1 #ifdef USE_CUDA_BROADPHASE m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,20,18,8,1./1.5); #else #if DBVT btDbvtBroadphase* dbvt = new btDbvtBroadphase(gPairCache); m_broadphase = dbvt; dbvt->m_deferedcollide=false; dbvt->m_prediction = 0.f; #else // m_broadphase = new btAxisSweep3(gWorldMin,gWorldMax,32000,gPairCache,true);//(btDbvtBroadphase(gPairCache); #endif //DBVT #endif // create solvers for tests ///the default constraint solver sConstraintSolvers[0] = new btSequentialImpulseConstraintSolver(); /* sConstraintSolvers[1] = new btParallelBatchConstraintSolver(); sConstraintSolvers[2] = new btCudaConstraintSolver(); sConstraintSolvers[3] = new btParallelBatchConstraintSolver2(); sConstraintSolvers[4] = new btParallelBatchConstraintSolver3(); sConstraintSolvers[5] = new btCudaConstraintSolver3(); sConstraintSolvers[6] = new btParallelBatchConstraintSolver4(); sConstraintSolvers[7] = new btCudaConstraintSolver4(); sConstraintSolvers[8] = new btParallelBatchConstraintSolver5(); sConstraintSolvers[9] = new btParallelBatchConstraintSolver6(); sConstraintSolvers[10] = new btCudaConstraintSolver6(); */ sCurrSolverIndex = 0; m_solver = sConstraintSolvers[sCurrSolverIndex]; printf("\nUsing %s\n", sConstraintSolverNames[sCurrSolverIndex]); // sCudaMotionInterface = new btCudaMotionInterface(MAX_PROXIES); // m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, sCudaMotionInterface); // m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //## btCudaDemoDynamicsWorld* pDdw = new btCudaDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); btCudaDemoDynamicsWorld3D* pDdw = new btCudaDemoDynamicsWorld3D(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_pWorld = pDdw; m_dynamicsWorld = pDdw; pDdw->getDispatchInfo().m_enableSPU=true; pDdw->getSimulationIslandManager()->setSplitIslands(sCurrSolverIndex == 0); pDdw->setObjRad(SCALING); pDdw->setWorldMin(gWorldMin); pDdw->setWorldMax(gWorldMax); //#ifdef BT_USE_CUDA #if 1 gUseCPUSolver = false; #else gUseCPUSolver = true; #endif pDdw->setUseCPUSolver(gUseCPUSolver); // pDdw->setUseSolver2(gUseSolver2); // m_dynamicsWorld->setGravity(btVector3(0,0,0)); m_dynamicsWorld->setGravity(btVector3(0.f,-10.f,0.f)); m_dynamicsWorld->getSolverInfo().m_numIterations = 4; { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,0.1));//SCALING*1)); //## btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*.7,SCALING*.7,0.1));//SCALING*1)); btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*.7,SCALING*.7, SCALING*.7)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); #if (!SPEC_TEST) float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(SCALING*btVector3( 2.0*SCALING*i + start_x, 2.0*SCALING*k + start_y, 2.0*SCALING*j + start_z)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } #else // narrowphase test - 2 bodies at the same position float start_x = START_POS_X; float start_y = START_POS_Y; float start_z = START_POS_Z; // startTransform.setOrigin(SCALING*btVector3(start_x,start_y-14.f,start_z)); startTransform.setOrigin(SCALING*btVector3(start_x,start_y-11.f,start_z)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); // startTransform.setOrigin(SCALING*btVector3(start_x+1.2f,start_y+1.4f-14.f,start_z)); startTransform.setOrigin(SCALING*btVector3(start_x,start_y + 1.5f -11.f, start_z)); rbInfo.m_startWorldTransform=startTransform; body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); #endif } #if 0 ///create a few basic rigid bodies // btCollisionShape* groundShape = new btBox2dShape(btVector3(btScalar(50.),btScalar(1.),btScalar(50.))); // btCollisionShape* groundShape = new btBox2dShape(btVector3(btScalar(228.),btScalar(1.),btScalar(228.))); // btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(228.),btScalar(1.),btScalar(228.))); // btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); btCollisionShape* groundShape = new btBoxShape(btVector3(POS_OFFS_X, btScalar(1.), POS_OFFS_Z)); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, gWorldMin[1], 0)); // groundTransform.setOrigin(btVector3(0,-5,0)); // groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } #endif //clientResetScene(); }
void FeatherstoneMultiBodyDemo::initPhysics() { //m_idle=true; setTexturing(true); setShadows(true); setCameraDistance(btScalar(100.*scaling)); this->m_azi = 130; ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); //Use the btMultiBodyConstraintSolver for Featherstone btMultiBody support btMultiBodyConstraintSolver* sol = new btMultiBodyConstraintSolver; m_solver = sol; //use btMultiBodyDynamicsWorld for Featherstone btMultiBody support btMultiBodyDynamicsWorld* world = new btMultiBodyDynamicsWorld(m_dispatcher,m_broadphase,sol,m_collisionConfiguration); m_dynamicsWorld = world; m_dynamicsWorld->setDebugDrawer(&gDebugDraw); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); //groundShape->initializePolyhedralFeatures(); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,00)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: if (1) { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btBoxShape* colShape = new btBoxShape(btVector3(1,1,1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(btVector3( btScalar(3.0*i + start_x), btScalar(3.0*k + start_y), btScalar(3.0*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body);//,1,1+2); } } } } btMultiBodySettings settings; settings.m_numLinks = 2; settings.m_basePosition = btVector3 (60,29.5,-2)*scaling; settings.m_isFixedBase = false; settings.m_disableParentCollision = true;//the self-collision has conflicting/non-resolvable contact normals settings.m_usePrismatic = true; settings.m_canSleep = true; settings.m_createConstraints = true; //btMultiBody* createFeatherstoneMultiBody(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition,bool isFixedBase, bool usePrismatic, bool canSleep, bool createConstraints); btMultiBody* mbA = createFeatherstoneMultiBody(world, settings); settings.m_numLinks = 10; settings.m_basePosition = btVector3 (0,29.5,-settings.m_numLinks*4.f); settings.m_isFixedBase = true; settings.m_usePrismatic = false; btMultiBody* mbB = createFeatherstoneMultiBody(world, settings); settings.m_basePosition = btVector3 (-20*scaling,29.5*scaling,-settings.m_numLinks*4.f*scaling); settings.m_isFixedBase = false; btMultiBody* mbC = createFeatherstoneMultiBody(world, settings); settings.m_basePosition = btVector3 (-20,9.5,-settings.m_numLinks*4.f); settings.m_isFixedBase = true; settings.m_usePrismatic = true; settings.m_disableParentCollision = true; btMultiBody* mbPrim= createFeatherstoneMultiBody(world, settings); //btMultiBody* mbB = createFeatherstoneMultiBody(world, 15, btVector3 (0,29.5,-2), false,true,true); #if 0 if (0)//!useGroundShape && i==4) { //attach two multibody using a point2point constraint //btVector3 pivotInAworld(0,20,46); btVector3 pivotInAworld(-0.3,29,-3.5); int linkA = -1; int linkB = -1; btVector3 pivotInAlocal = mbA->worldPosToLocal(linkA, pivotInAworld); btVector3 pivotInBlocal = mbB->worldPosToLocal(linkB, pivotInAworld); btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(mbA,linkA,mbB,linkB,pivotInAlocal,pivotInBlocal); world->addMultiBodyConstraint(p2p); } #endif bool testRemoveLinks = false; if (testRemoveLinks) { while (mbA->getNumLinks()) { btCollisionObject* col = mbA->getLink(mbA->getNumLinks()-1).m_collider; m_dynamicsWorld->removeCollisionObject(col); delete col; mbA->setNumLinks(mbA->getNumLinks()-1); } } if (1)//useGroundShape { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body,1,1+2);//,1,1+2); } }
void Box2dDemo::initPhysics() { m_dialogDynamicsWorld = new GL_DialogDynamicsWorld(); //m_dialogDynamicsWorld->createDialog(100,110,200,50); //m_dialogDynamicsWorld->createDialog(100,00,100,100); //m_dialogDynamicsWorld->createDialog(0,0,100,100); GL_DialogWindow* settings = m_dialogDynamicsWorld->createDialog(50,0,200,120,"Settings"); GL_ToggleControl* toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 1"); toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 2"); toggle ->m_active = true; toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 3"); //GL_SliderControl* slider = m_dialogDynamicsWorld->createSlider(settings,"Slider"); GL_DialogWindow* dialog = m_dialogDynamicsWorld->createDialog(0,200,420,300,"Help"); GL_TextControl* txt = new GL_TextControl; dialog->addControl(txt); txt->m_textLines.push_back("Mouse to move"); txt->m_textLines.push_back("Test 2"); txt->m_textLines.push_back("mouse to interact"); txt->m_textLines.push_back("ALT + mouse to move camera"); txt->m_textLines.push_back("space to reset"); txt->m_textLines.push_back("cursor keys and z,x to navigate"); txt->m_textLines.push_back("i to toggle simulation, s single step"); txt->m_textLines.push_back("q to quit"); txt->m_textLines.push_back(". to shoot box"); txt->m_textLines.push_back("d to toggle deactivation"); txt->m_textLines.push_back("g to toggle mesh animation (ConcaveDemo)"); txt->m_textLines.push_back("h to toggle help text"); txt->m_textLines.push_back("o to toggle orthogonal/perspective view"); //txt->m_textLines.push_back("+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); setTexturing(true); setShadows(true); setCameraDistance(btScalar(SCALING*50.)); m_cameraTargetPosition.setValue(0,0,0);//0, ARRAY_SIZE_Y, 0); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVoronoiSimplexSolver* simplex = new btVoronoiSimplexSolver(); btMinkowskiPenetrationDepthSolver* pdSolver = new btMinkowskiPenetrationDepthSolver(); btConvex2dConvex2dAlgorithm::CreateFunc* convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(simplex,pdSolver); m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,convexAlgo2d); m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc()); m_broadphase = new btDbvtBroadphase(); //m_broadphase = new btSimpleBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); //m_dynamicsWorld->getSolverInfo().m_erp = 1.f; //m_dynamicsWorld->getSolverInfo().m_numIterations = 4; m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.),btScalar(50.),btScalar(150.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-43,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btScalar u= btScalar(1*SCALING-0.04); btVector3 points[3] = {btVector3(0,u,0),btVector3(-u,-u,0),btVector3(u,-u,0)}; btConvexShape* childShape0 = new btBoxShape(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); btConvexShape* colShape= new btConvex2dShape(childShape0); //btCollisionShape* colShape = new btBox2dShape(btVector3(SCALING*1,SCALING*1,0.04)); btConvexShape* childShape1 = new btConvexHullShape(&points[0].getX(),3); btConvexShape* colShape2= new btConvex2dShape(childShape1); btConvexShape* childShape2 = new btCylinderShapeZ(btVector3(btScalar(SCALING*1),btScalar(SCALING*1),btScalar(0.04))); btConvexShape* colShape3= new btConvex2dShape(childShape2); m_collisionShapes.push_back(colShape); m_collisionShapes.push_back(colShape2); m_collisionShapes.push_back(colShape3); m_collisionShapes.push_back(childShape0); m_collisionShapes.push_back(childShape1); m_collisionShapes.push_back(childShape2); //btUniformScalingShape* colShape = new btUniformScalingShape(convexColShape,1.f); colShape->setMargin(btScalar(0.03)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); // float start_x = START_POS_X - ARRAY_SIZE_X/2; // float start_y = START_POS_Y; // float start_z = START_POS_Z - ARRAY_SIZE_Z/2; btVector3 x(-ARRAY_SIZE_X, 8.0f,-20.f); btVector3 y; btVector3 deltaX(SCALING*1, SCALING*2,0.f); btVector3 deltaY(SCALING*2, 0.0f,0.f); for (int i = 0; i < ARRAY_SIZE_X; ++i) { y = x; for (int j = i; j < ARRAY_SIZE_Y; ++j) { startTransform.setOrigin(y-btVector3(-10,0,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0,0,0); switch (j%3) { #if 1 case 0: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape,localInertia); break; case 1: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape3,localInertia); break; #endif default: rbInfo = btRigidBody::btRigidBodyConstructionInfo(mass,myMotionState,colShape2,localInertia); } btRigidBody* body = new btRigidBody(rbInfo); //body->setContactProcessingThreshold(colShape->getContactBreakingThreshold()); body->setActivationState(ISLAND_SLEEPING); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); m_dynamicsWorld->addRigidBody(body); body->setActivationState(ISLAND_SLEEPING); // y += -0.8*deltaY; y += deltaY; } x += deltaX; } } clientResetScene(); }
int main(int argc, char** argv) { sf::RenderWindow* RenderWin = new sf::RenderWindow(sf::VideoMode(WIDTH, HEIGHT, 32), "lol test"); RenderWin->UseVerticalSync(true); // Collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. boost::shared_ptr<btDefaultCollisionConfiguration> collisionConfiguration(new btDefaultCollisionConfiguration()); // Use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded). boost::shared_ptr<btCollisionDispatcher> dispatcher(new btCollisionDispatcher(collisionConfiguration.get())); // btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. boost::shared_ptr<btBroadphaseInterface> broadphase(new btDbvtBroadphase()); // The default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded). boost::shared_ptr<btVoronoiSimplexSolver> simplex(new btVoronoiSimplexSolver()); boost::shared_ptr<btMinkowskiPenetrationDepthSolver> pd_solver(new btMinkowskiPenetrationDepthSolver()); boost::shared_ptr<btSequentialImpulseConstraintSolver> solver(new btSequentialImpulseConstraintSolver()); boost::shared_ptr<btDiscreteDynamicsWorld> dynamicsWorld(new btDiscreteDynamicsWorld(dispatcher.get(), broadphase.get(), solver.get(), collisionConfiguration.get())); boost::shared_ptr<btConvex2dConvex2dAlgorithm::CreateFunc> convex_algo_2d(new btConvex2dConvex2dAlgorithm::CreateFunc(simplex.get(),pd_solver.get())); dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE, convex_algo_2d.get()); dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE, new btBox2dBox2dCollisionAlgorithm::CreateFunc()); // Set gravity to 9.8m/s² along y-axis. dynamicsWorld->setGravity(btVector3(0, 1, 0)); // Get us some debug output. Without this, we'd see nothing at all. boost::shared_ptr<DebugDraw> debugDraw(new DebugDraw(RenderWin)); debugDraw->setDebugMode(btIDebugDraw::DBG_DrawWireframe); dynamicsWorld->setDebugDrawer(debugDraw.get()); // Keep track of the shapes, we release memory at exit. // Make sure to re-use collision shapes among rigid bodies whenever possible! btAlignedObjectArray<btCollisionShape*> collisionShapes; // Create a ground body. btScalar thickness(0.2); boost::shared_ptr<btCollisionShape> groundShape(new btBoxShape(btVector3(btScalar(WIDTH / 2 * METERS_PER_PIXEL), thickness, btScalar(10)))); collisionShapes.push_back(groundShape.get()); btTransform groundTransform(btQuaternion(0, 0, 0, 1), btVector3(WIDTH / 2 * METERS_PER_PIXEL, HEIGHT * METERS_PER_PIXEL, 0)); // Using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects. boost::shared_ptr<btDefaultMotionState> groundMotionState(new btDefaultMotionState(groundTransform)); btRigidBody::btRigidBodyConstructionInfo ground_rbInfo(0, groundMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> ground_body(new btRigidBody(ground_rbInfo)); ground_body->setLinearFactor(btVector3(1,1,0)); ground_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(ground_body.get()); // Create left wall. btTransform leftWallTransform(btQuaternion(0, 0, 1, 1), btVector3(0, HEIGHT / 2 * METERS_PER_PIXEL, 0)); boost::shared_ptr<btDefaultMotionState> leftWallMotionState(new btDefaultMotionState(leftWallTransform)); btRigidBody::btRigidBodyConstructionInfo leftWall_rbInfo(0, leftWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> leftwall_body(new btRigidBody(leftWall_rbInfo)); leftwall_body->setLinearFactor(btVector3(1,1,0)); leftwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(leftwall_body.get()); // Create right wall. btTransform rightWallTransform(btQuaternion(0, 0, 1, 1), btVector3(WIDTH * METERS_PER_PIXEL, HEIGHT / 2 * METERS_PER_PIXEL, 0)); boost::shared_ptr<btDefaultMotionState> rightWallMotionState(new btDefaultMotionState(rightWallTransform)); btRigidBody::btRigidBodyConstructionInfo rightWall_rbInfo(0, rightWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> rightwall_body(new btRigidBody(rightWall_rbInfo)); rightwall_body->setLinearFactor(btVector3(1,1,0)); rightwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(rightwall_body.get()); // Create ceiling btTransform topWallTransform(btQuaternion(0, 0, 0, 1), btVector3(WIDTH / 2 * METERS_PER_PIXEL, 0, 0)); boost::shared_ptr<btDefaultMotionState> topWallMotionState(new btDefaultMotionState(topWallTransform)); btRigidBody::btRigidBodyConstructionInfo topWall_rbInfo(0, topWallMotionState.get(), groundShape.get(), btVector3(0, 0, 0)); boost::shared_ptr<btRigidBody> topwall_body(new btRigidBody(topWall_rbInfo)); topwall_body->setLinearFactor(btVector3(1,1,0)); topwall_body->setAngularFactor(btVector3(0,0,1)); // Add the body to the dynamics world. dynamicsWorld->addRigidBody(topwall_body.get()); // Create dynamic rigid body. //btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); boost::shared_ptr<btCollisionShape> colShape(new btSphereShape(btScalar(0.6))); collisionShapes.push_back(colShape.get()); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0, 0, 0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3(2, 5, 0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects boost::shared_ptr<btDefaultMotionState> myMotionState(new btDefaultMotionState(startTransform)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState.get(),colShape.get(),localInertia); boost::shared_ptr<btRigidBody> body(new btRigidBody(rbInfo)); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); dynamicsWorld->addRigidBody(body.get()); // Create lulz boost::ptr_list<btRigidBody> body_list; boost::ptr_list<btDefaultMotionState> motionstate_list; boost::ptr_list<btCollisionShape> colshape_list; for (int i=0;i <= 10; ++i) { if (i < 5) colshape_list.push_back(new btSphereShape(btScalar(sf::Randomizer::Random(0.1f, 0.8f)))); else colshape_list.push_back(new btBoxShape(btVector3(sf::Randomizer::Random(0.1f,0.8f), sf::Randomizer::Random(0.1f,0.8f), 10))); if (isDynamic) colshape_list.back().calculateLocalInertia(mass,localInertia); collisionShapes.push_back(&(colshape_list.back())); startTransform.setIdentity(); startTransform.setOrigin(btVector3(i,i,0)); motionstate_list.push_back(new btDefaultMotionState(startTransform)); btRigidBody* lol = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo(mass,&(motionstate_list.back()),&(colshape_list.back()),localInertia)); lol->setLinearFactor(btVector3(1,1,0)); lol->setAngularFactor(btVector3(0,0,1)); body_list.push_back(lol); } BOOST_FOREACH (btRigidBody& body, body_list) { dynamicsWorld->addRigidBody(&body); }
void bulletPhysicsDemoCreate() { NiceColorPicker niceColorPicker; btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; world = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); world->setGravity(btVector3(0,-10,0)); { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); btScalar mass(0.); btVector3 localInertia(0,0,0); btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setUserPointer((void*)(++niceColorPicker).get().value); world->addRigidBody(body); body->setFriction(1); } for(int x=0; x<6; x++){ btCollisionShape* colShape = new btBoxShape(btVector3(2,1,3)); btTransform startTransform; startTransform.setIdentity(); btScalar mass(48.f); btVector3 localInertia(0,0,0); colShape->calculateLocalInertia(mass, localInertia); btQuaternion rot; rot.setEuler(10, 20, 30); startTransform.setRotation(rot); startTransform.setOrigin(btVector3(0, 10+x*10, (x-3) * 10)); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setUserPointer((void*)(++niceColorPicker).get().value); world->addRigidBody(body); Breakable* b = new Breakable(body); b->next = breakables; breakables = b; } for(int x=0; x<6; x++){ {//Destructible wall btCollisionShape* colShape = new btBoxShape(btVector3(2,1,3)); btTransform startTransform; startTransform.setIdentity(); btQuaternion rot; rot.setEuler(0, Pi/2, Pi/2); startTransform.setRotation(rot); btScalar mass(48.f); btVector3 localInertia(0,0,0); colShape->calculateLocalInertia(mass, localInertia); startTransform.setOrigin(btVector3(-30, 3, (x-3) * 10)); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setUserPointer((void*)(++niceColorPicker).get().value); world->addRigidBody(body); Breakable* b = new Breakable(body); b->next = breakables; breakables = b; } {//Cannon ball btCollisionShape* colShape = new btBoxShape(btVector3(.5f,.5f,.5f)); btTransform startTransform; startTransform.setIdentity(); btScalar mass(20.f); btVector3 localInertia(0,0,0); colShape->calculateLocalInertia(mass, localInertia); startTransform.setOrigin(btVector3(-40, 4, (x-3) * 10)); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setUserPointer((void*)(++niceColorPicker).get().value); body->setLinearVelocity(btVector3(20+x*20, 0, 0)); world->addRigidBody(body); } } }
void ChainDemo::initPhysics() { // Bullet2RigidBodyDemo::initPhysics(); m_config = new btDefaultCollisionConfiguration; m_dispatcher = new btCollisionDispatcher(m_config); m_bp = new btDbvtBroadphase(); //m_solver = new btNNCGConstraintSolver(); m_solver = new btSequentialImpulseConstraintSolver(); // btDantzigSolver* mlcp = new btDantzigSolver(); //btLemkeSolver* mlcp = new btLemkeSolver(); //m_solver = new btMLCPSolver(mlcp); // m_solver = new btSequentialImpulseConstraintSolver(); //btMultiBodyConstraintSolver* solver = new btMultiBodyConstraintSolver(); //m_solver = solver; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_bp,m_solver,m_config); m_dynamicsWorld->getSolverInfo().m_numIterations = 1000; m_dynamicsWorld->getSolverInfo().m_splitImpulse = false; int curColor=0; //create ground btScalar radius=scaling; int unitCubeShapeId = m_glApp->registerCubeShape(); float pos[]={0,0,0}; float orn[]={0,0,0,1}; //eateGround(unitCubeShapeId); int sphereShapeId = m_glApp->registerGraphicsSphereShape(radius,false); { float halfExtents[]={scaling,scaling,scaling,1}; btVector4 colors[4] = { btVector4(1,0,0,1), btVector4(0,1,0,1), btVector4(0,1,1,1), btVector4(1,1,0,1), }; btTransform startTransform; startTransform.setIdentity(); btCollisionShape* colShape = new btSphereShape(scaling); btScalar largeMass[]={1000,10,100,1000}; for (int i=0;i<1;i++) { btAlignedObjectArray<btRigidBody*> bodies; for (int k=0;k<NUM_SPHERES;k++) { btVector3 localInertia(0,0,0); btScalar mass = 0.f; curColor = 1; switch (k) { case 0: { mass = largeMass[i]; curColor = 0; break; } case NUM_SPHERES-1: { mass = 0.f; curColor = 2; break; } default: { curColor = 1; mass = 1.f; } }; if (mass) colShape ->calculateLocalInertia(mass,localInertia); btVector4 color = colors[curColor]; startTransform.setOrigin(btVector3( btScalar(7.5+-i*5), btScalar(6.*scaling+2.0*scaling*k), btScalar(0))); m_glApp->m_instancingRenderer->registerGraphicsInstance(sphereShapeId,startTransform.getOrigin(),startTransform.getRotation(),color,halfExtents); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); bodies.push_back(body); body->setActivationState(DISABLE_DEACTIVATION); m_dynamicsWorld->addRigidBody(body); } //add constraints btVector3 pivotInA(0,radius,0); btVector3 pivotInB(0,-radius,0); for (int k=0;k<NUM_SPHERES-1;k++) { btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*bodies[k],*bodies[k+1],pivotInA,pivotInB); m_dynamicsWorld->addConstraint(p2p,true); } } } m_glApp->m_instancingRenderer->writeTransforms(); }
void CLevel::Initialize(btDiscreteDynamicsWorld* pDynamicsWorld) { #if defined IW_DEBUG && (defined IW_BUILD_RESOURCES) if (IwGetResManager()->BuildResources()) return; // Register the model builder callbacks IwGetModelBuilder()->SetPostBuildFn(&BuildCollision); #endif CIwResGroup* pGroup = 0; m_iCurrentSegmentX = 0; m_iCurrentSegmentY = 0; m_pCurrentCollisionModel = NULL; m_pCurrentCollision = NULL; // allocating pointers m_apCollisionModel = new CIwModel*[NUM_SECTORS]; m_apCollision = new CCollision*[NUM_SECTORS]; m_apBodyGround = new btRigidBody*[NUM_SECTORS]; m_apGroundShape = new btBvhTriangleMeshShape*[NUM_SECTORS]; m_apMotionState = new btDefaultMotionState*[NUM_SECTORS]; m_apIndexVertexArrays = new btTriangleIndexVertexArray*[NUM_SECTORS]; m_apiColIndices = new int*[NUM_SECTORS]; m_apfColVertices = new float*[NUM_SECTORS]; m_pDynamicsWorld = pDynamicsWorld; btVector3 localInertia(0,0,0); pGroup = IwGetResManager()->LoadGroup("col3.group"); for (int i = 0; i < NUM_SECTORS; i++) { char strColFile[20]; sprintf(strColFile, "Box%d%d", i / 3, i % 3); m_apCollisionModel[i] = (CIwModel*)pGroup->GetResNamed(strColFile, IW_GRAPHICS_RESTYPE_MODEL); m_apCollision[i] = (CCollision*)pGroup->GetResNamed(strColFile, "CCollision"); // find some way to delete old unused trimeshes uint16 vertcount = m_apCollision[i]->GetVertCount(); m_apiColIndices[i] = (int*)malloc(vertcount * sizeof(int)); for (int j = 0; j < vertcount; j+=1) { m_apiColIndices[i][j] = j; //m_colIndices[i+1] = i+1; //m_colIndices[i+2] = i; } m_apfColVertices[i] = (btScalar*)malloc(vertcount*3 * sizeof(btScalar)); for (int j = 0; j<vertcount; j++) { m_apfColVertices[i][j*3] = m_apCollision[i]->GetVert(j).x; m_apfColVertices[i][j*3+1] = m_apCollision[i]->GetVert(j).y; m_apfColVertices[i][j*3+2] = m_apCollision[i]->GetVert(j).z; } // bullet m_apIndexVertexArrays[i] = new btTriangleIndexVertexArray(vertcount/3, m_apiColIndices[i], 3*sizeof(int), vertcount,(btScalar*) m_apfColVertices[i], 3*sizeof(btScalar)); m_apGroundShape[i] = new btBvhTriangleMeshShape(m_apIndexVertexArrays[i],true); m_pCollisionShapes.push_back(m_apGroundShape[i]); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,0,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects m_apMotionState[i] = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0.0f,m_apMotionState[i],m_apGroundShape[i],localInertia); m_apBodyGround[i] = new btRigidBody(rbInfo); //add the body to the dynamics world //body->setFriction(0.0f); m_apBodyGround[i]->setRestitution(0.9f); } m_pDynamicsWorld->addRigidBody(m_apBodyGround[0]); }
PintObjectHandle Bullet::CreateObject(const PINT_OBJECT_CREATE& desc) { udword NbShapes = desc.GetNbShapes(); if(!NbShapes) return null; ASSERT(mDynamicsWorld); const PINT_SHAPE_CREATE* CurrentShape = desc.mShapes; float FrictionCoeff = 0.5f; float RestitutionCoeff = 0.0f; btCollisionShape* colShape = null; if(NbShapes>1) { btCompoundShape* CompoundShape = new btCompoundShape(); colShape = CompoundShape; mCollisionShapes.push_back(colShape); while(CurrentShape) { if(CurrentShape->mMaterial) { FrictionCoeff = CurrentShape->mMaterial->mDynamicFriction; RestitutionCoeff = CurrentShape->mMaterial->mRestitution; } const btTransform LocalPose(ToBtQuaternion(CurrentShape->mLocalRot), ToBtVector3(CurrentShape->mLocalPos)); // ### TODO: where is this deleted? btCollisionShape* subShape = CreateBulletShape(*CurrentShape); if(subShape) { CompoundShape->addChildShape(LocalPose, subShape); } CurrentShape = CurrentShape->mNext; } } else { colShape = CreateBulletShape(*CurrentShape); if(CurrentShape->mMaterial) { FrictionCoeff = CurrentShape->mMaterial->mDynamicFriction; RestitutionCoeff = CurrentShape->mMaterial->mRestitution; } } const bool isDynamic = (desc.mMass != 0.0f); btVector3 localInertia(0,0,0); if(isDynamic) colShape->calculateLocalInertia(desc.mMass, localInertia); const btTransform startTransform(ToBtQuaternion(desc.mRotation), ToBtVector3(desc.mPosition)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(desc.mMass, myMotionState, colShape, localInertia); { rbInfo.m_friction = FrictionCoeff; rbInfo.m_restitution = RestitutionCoeff; // rbInfo.m_startWorldTransform; rbInfo.m_linearDamping = gLinearDamping; rbInfo.m_angularDamping = gAngularDamping; if(!gEnableSleeping) { // rbInfo.m_linearSleepingThreshold = 99999999.0f; // rbInfo.m_angularSleepingThreshold = 99999999.0f; // rbInfo.m_linearSleepingThreshold = 0.0f; // rbInfo.m_angularSleepingThreshold = 0.0f; } // rbInfo.m_additionalDamping; // rbInfo.m_additionalDampingFactor; // rbInfo.m_additionalLinearDampingThresholdSqr; // rbInfo.m_additionalAngularDampingThresholdSqr; // rbInfo.m_additionalAngularDampingFactor; } btRigidBody* body = new btRigidBody(rbInfo); ASSERT(body); if(!gEnableSleeping) body->setActivationState(DISABLE_DEACTIVATION); sword collisionFilterGroup, collisionFilterMask; if(isDynamic) { body->setLinearVelocity(ToBtVector3(desc.mLinearVelocity)); body->setAngularVelocity(ToBtVector3(desc.mAngularVelocity)); collisionFilterGroup = short(btBroadphaseProxy::DefaultFilter); collisionFilterMask = short(btBroadphaseProxy::AllFilter); if(desc.mCollisionGroup) { const udword btGroup = RemapCollisionGroup(desc.mCollisionGroup); ASSERT(btGroup<32); collisionFilterGroup = short(1<<btGroup); collisionFilterMask = short(mGroupMasks[btGroup]); } } else { // body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT); body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); collisionFilterGroup = short(btBroadphaseProxy::StaticFilter); collisionFilterMask = short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); } if(desc.mAddToWorld) // mDynamicsWorld->addRigidBody(body); mDynamicsWorld->addRigidBody(body, collisionFilterGroup, collisionFilterMask); if(gUseCCD) { // body->setCcdMotionThreshold(1e-7); // body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS); body->setCcdMotionThreshold(0.0001f); body->setCcdSweptSphereRadius(0.4f); } return body; }
Ragdoll::Ragdoll(btDiscreteDynamicsWorld * world, btScalar heightOffset) { this->world = world; btScalar bodyMass = (btScalar)70.0; // feet definition btScalar footLength = (btScalar)0.24, footHeight = (btScalar)0.08, footWidth = (btScalar)0.15; btScalar footTop = footHeight + heightOffset; btScalar footXOffset = (btScalar)0.04, footZOffset = (btScalar)0.167; btScalar footMass = bodyMass * (btScalar)1.38/100; // left foot btCollisionShape *bpShape = new btBoxShape(btVector3(footLength/2, footHeight/2, footWidth/2)); btQuaternion bpRotation(0, 0, 0, 1); btVector3 bpTranslation(footXOffset, footTop-footHeight/2, -footZOffset); btDefaultMotionState *bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); btVector3 bpInertia(0, 0, 0); btScalar bpMass = footMass; bpShape->calculateLocalInertia(bpMass, bpInertia); btRigidBody::btRigidBodyConstructionInfo rbInfo(bpMass, bpMotionState, bpShape, bpInertia); btRigidBody *body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_LEFT_FOOT] = new GrBulletObject(body); addBoxLinker(footLength / 2, footHeight / 2, footWidth / 2, bodyParts[BODYPART_LEFT_FOOT]); // right foot bpShape = new btBoxShape(btVector3(footLength / 2, footHeight / 2, footWidth / 2)); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(footXOffset, footTop - footHeight / 2, footZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = footMass; bpShape->calculateLocalInertia(bpMass, bpInertia); rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_RIGHT_FOOT] = new GrBulletObject(body); addBoxLinker(footLength / 2, footHeight / 2, footWidth / 2, bodyParts[BODYPART_RIGHT_FOOT]); // legs definition btScalar legRadius = (btScalar)0.055, legHeight = (btScalar) 0.34; btScalar legTop = footTop + legHeight; btScalar legMass = bodyMass * (btScalar)5.05/100; // left leg bpShape = new btCapsuleShape(legRadius, legHeight - 2 * legRadius); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, legTop - legHeight / 2, -footZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = legMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_LEFT_LEG] = new GrBulletObject(body); addCylinderLinker(legRadius, legHeight, bodyParts[BODYPART_LEFT_LEG]); // right leg bpShape = new btCapsuleShape(legRadius, legHeight - 2 * legRadius); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, legTop - legHeight / 2, footZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = legMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_RIGHT_LEG] = new GrBulletObject(body); addCylinderLinker(legRadius, legHeight, bodyParts[BODYPART_RIGHT_LEG]); // thighs definition btScalar thighRadius = (btScalar)0.07, thighHeight = (btScalar)0.32; btScalar thighAngle = (btScalar) (12 * M_PI / 180); btScalar thighAngledHeight = thighHeight * btCos(thighAngle); btScalar thighTop = legTop + thighAngledHeight; btScalar thighZOffset = (btScalar)0.1136; btScalar thighMass = bodyMass * (btScalar)11.125/100; // left thigh h=0.316 bpShape = new btCapsuleShape(thighRadius, thighHeight - 2 * thighRadius); bpRotation = btQuaternion(1 * btSin(thighAngle / 2), 0, 0, btCos(thighAngle / 2)); bpTranslation = btVector3(0, thighTop - thighAngledHeight/2, -thighZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = thighMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_LEFT_THIGH] = new GrBulletObject(body); addCylinderLinker(thighRadius, thighHeight, bodyParts[BODYPART_LEFT_THIGH]); // right thigh h=0.316 , ends at 0.706 bpShape = new btCapsuleShape(thighRadius, thighHeight - 2 * thighRadius); bpRotation = btQuaternion(-1 * btSin(thighAngle / 2), 0, 0, btCos(thighAngle / 2)); bpTranslation = btVector3(0, thighTop - thighAngledHeight / 2, thighZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = thighMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_RIGHT_THIGH] = new GrBulletObject(body); addCylinderLinker(thighRadius, thighHeight, bodyParts[BODYPART_RIGHT_THIGH]); // pelvis definition btScalar pelvisLength = (btScalar)0.19, pelvisHeight = (btScalar)0.15, pelvisWidth = (btScalar)0.35; btScalar pelvisTop = thighTop + pelvisHeight; btScalar pelvisMass = bodyMass * (btScalar)14.81/100; // pelvis bpShape = new btBoxShape(btVector3(pelvisLength/2, pelvisHeight/2, pelvisWidth/2)); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, pelvisTop - pelvisHeight/2, 0); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = pelvisMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_PELVIS] = new GrBulletObject(body); addBoxLinker(pelvisLength / 2, pelvisHeight / 2, pelvisWidth / 2, bodyParts[BODYPART_PELVIS]); // abdomen definition btScalar abdomenLength = (btScalar)0.13, abdomenHeight = (btScalar)0.113, abdomenWidth = (btScalar)0.268; btScalar abdomenTop = pelvisTop + abdomenHeight; btScalar abdomenMass = bodyMass * (btScalar)12.65 / 100; // abdomen bpShape = new btBoxShape(btVector3(abdomenLength/2, abdomenHeight/2, abdomenWidth/2)); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, abdomenTop - abdomenHeight/2, 0); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = abdomenMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_ABDOMEN] = new GrBulletObject(body); addBoxLinker(abdomenLength / 2, abdomenHeight / 2, abdomenWidth / 2, bodyParts[BODYPART_ABDOMEN]); // thorax definition btScalar thoraxLength = (btScalar)0.2, thoraxHeight = (btScalar)0.338, thoraxWidth = (btScalar)0.34; btScalar thoraxTop = abdomenTop + thoraxHeight; btScalar thoraxMass = bodyMass * (btScalar)18.56/100; // thorax bpShape = new btBoxShape(btVector3(thoraxLength/2, thoraxHeight/2, thoraxWidth/2)); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, thoraxTop-thoraxHeight/2, 0); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = thoraxMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_THORAX] = new GrBulletObject(body); addBoxLinker(thoraxLength / 2, thoraxHeight / 2, thoraxWidth / 2, bodyParts[BODYPART_THORAX]); // upper arms definition btScalar upperArmRadius = (btScalar)0.04, upperArmHeight = (btScalar)0.25; btScalar upperArmAngle = (btScalar)(25 * M_PI / 180); btScalar upperArmAngledHeight = upperArmHeight * btCos(upperArmAngle); btScalar upperArmBottom = thoraxTop - upperArmAngledHeight; btScalar upperArmZOffset = (btScalar)0.223; btScalar upperArmMass = bodyMass * (btScalar)3.075 / 100; // left upper arm bpShape = new btCapsuleShape(upperArmRadius, upperArmHeight - 2 * upperArmRadius); bpShape = new btBoxShape(btVector3(upperArmRadius, upperArmHeight/2, upperArmRadius)); bpRotation = btQuaternion(1 * btSin(upperArmAngle/2), 0, 0, btCos(upperArmAngle/2)); bpTranslation = btVector3(0, upperArmBottom + upperArmAngledHeight/2, -upperArmZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = upperArmMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_LEFT_UPPER_ARM] = new GrBulletObject(body); addCylinderLinker(upperArmRadius, upperArmHeight, bodyParts[BODYPART_LEFT_UPPER_ARM]); // right upper arm bpShape = new btCapsuleShape(upperArmRadius, upperArmHeight - 2 * upperArmRadius); bpRotation = btQuaternion(-1 * btSin(upperArmAngle / 2), 0, 0, btCos(upperArmAngle / 2)); bpTranslation = btVector3(0, upperArmBottom + upperArmAngledHeight / 2, upperArmZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = upperArmMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_RIGHT_UPPER_ARM] = new GrBulletObject(body); addCylinderLinker(upperArmRadius, upperArmHeight, bodyParts[BODYPART_RIGHT_UPPER_ARM]); // lower arms definition btScalar lowerArmRadius = (btScalar)0.035, lowerArmHeight = (btScalar)0.28; btScalar lowerArmTop = upperArmBottom; btScalar lowerArmZOffset = (btScalar)0.276; btScalar lowerArmMass = bodyMass * (btScalar)1.72 / 100; // left lower arm bpShape = new btCapsuleShape(lowerArmRadius, lowerArmHeight - 2 * lowerArmRadius); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, lowerArmTop - lowerArmHeight/2, -lowerArmZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = lowerArmMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_LEFT_LOWER_ARM] = new GrBulletObject(body); addCylinderLinker(lowerArmRadius, lowerArmHeight, bodyParts[BODYPART_LEFT_LOWER_ARM]); // right lower arm bpShape = new btCapsuleShape(lowerArmRadius, lowerArmHeight - 2 * lowerArmRadius); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, lowerArmTop - lowerArmHeight / 2, lowerArmZOffset); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = lowerArmMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_RIGHT_LOWER_ARM] = new GrBulletObject(body); addCylinderLinker(lowerArmRadius, lowerArmHeight, bodyParts[BODYPART_RIGHT_LOWER_ARM]); // neck definition btScalar neckRadius = (btScalar)0.05, neckHeight = (btScalar)0.04; btScalar neckTop = thoraxTop + neckHeight; btScalar neckMass = (btScalar)0.5; // neck bpShape = new btBoxShape(btVector3(neckRadius, neckHeight/2, neckRadius)); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, neckTop - neckHeight/2, 0); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = neckMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_NECK] = new GrBulletObject(body); addCylinderLinker(neckRadius, neckHeight, bodyParts[BODYPART_NECK]); // head definition btScalar headRadius = (btScalar)0.1, headHeight = (btScalar)0.283; btScalar headTop = neckTop + headHeight; btScalar headMass = (btScalar)5.0; // head bpShape = new btCapsuleShape(headRadius, headHeight-2*headRadius); bpRotation = btQuaternion(0, 0, 0, 1); bpTranslation = btVector3(0, headTop - headHeight/2, 0); bpMotionState = new btDefaultMotionState(btTransform(bpRotation, bpTranslation)); bpInertia = btVector3(0, 0, 0); bpMass = headMass; rbInfo = btRigidBody::btRigidBodyConstructionInfo(bpMass, bpMotionState, bpShape, bpInertia); body = new btRigidBody(rbInfo); world->addRigidBody(body); bodyParts[BODYPART_HEAD] = new GrBulletObject(body); addSphereLinker(headHeight/2, bodyParts[BODYPART_HEAD]); // create joints btConeTwistConstraint *coneConstraint; btHingeConstraint * hingeConstraint; // head-neck btTransform bodyA, bodyB; bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, 0, M_PI_2); bodyA.setOrigin(btVector3(0, -(headHeight/2 + 0.02), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, 0, M_PI_2); bodyB.setOrigin(btVector3(0, neckHeight/2 + 0.01, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_HEAD]->getRigidBody(), *bodyParts[BODYPART_NECK]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, M_PI_2); joints[JOINT_HEAD_NECK] = coneConstraint; world->addConstraint(joints[JOINT_HEAD_NECK], false); // neck-thorax bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, 0, M_PI_2); bodyA.setOrigin(btVector3(0, -neckHeight/2 - 0.02, 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, 0, M_PI_2); bodyB.setOrigin(btVector3(0, thoraxHeight / 2 + 0.02, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_NECK]->getRigidBody(), *bodyParts[BODYPART_THORAX]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_NECK_THORAX] = coneConstraint; world->addConstraint(joints[JOINT_NECK_THORAX], true); // thorax-leftupperarm bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, thoraxHeight / 2 - upperArmRadius, -(thoraxWidth / 2 + upperArmRadius))); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, upperArmHeight / 2 + upperArmRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_THORAX]->getRigidBody(), *bodyParts[BODYPART_LEFT_UPPER_ARM]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_2, M_PI_2, 0); joints[JOINT_THORAX_LEFT_UPPER_ARM] = coneConstraint; world->addConstraint(joints[JOINT_THORAX_LEFT_UPPER_ARM], true); // left upper-lower arm bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(upperArmHeight / 2 + upperArmRadius / 2), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, lowerArmHeight / 2 + lowerArmRadius / 2, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_LEFT_UPPER_ARM]->getRigidBody(), *bodyParts[BODYPART_LEFT_LOWER_ARM]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_2, M_PI_2, M_PI_4); joints[JOINT_LEFT_ARM_UPPER_LOWER] = coneConstraint; world->addConstraint(joints[JOINT_LEFT_ARM_UPPER_LOWER], true); // thorax-rightupperarm bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, -M_PI_2, 0); bodyA.setOrigin(btVector3(0, thoraxHeight / 2 - upperArmRadius, (thoraxWidth / 2 + upperArmRadius))); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, -M_PI_2, 0); bodyB.setOrigin(btVector3(0, upperArmHeight / 2 + upperArmRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_THORAX]->getRigidBody(), *bodyParts[BODYPART_RIGHT_UPPER_ARM]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_2, M_PI_2, 0); joints[JOINT_THORAX_RIGHT_UPPER_ARM] = coneConstraint; world->addConstraint(joints[JOINT_THORAX_RIGHT_UPPER_ARM], true); // right upper-lower arm bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(upperArmHeight / 2 + upperArmRadius / 2), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, lowerArmHeight / 2 + lowerArmRadius / 2, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_RIGHT_UPPER_ARM]->getRigidBody(), *bodyParts[BODYPART_RIGHT_LOWER_ARM]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_2, M_PI_2, M_PI_4); joints[JOINT_RIGHT_ARM_UPPER_LOWER] = coneConstraint; world->addConstraint(joints[JOINT_RIGHT_ARM_UPPER_LOWER], true); // thorax-abdomen bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(thoraxHeight/2 - 0.05), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, abdomenHeight/2 + 0.05, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_THORAX]->getRigidBody(), *bodyParts[BODYPART_ABDOMEN]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_THORAX_ADBOMEN] = coneConstraint; world->addConstraint(joints[JOINT_THORAX_ADBOMEN], true); // abdomen-pelvis bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(abdomenHeight/2 - 0.05), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, pelvisHeight/2 + 0.05, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_ABDOMEN]->getRigidBody(), *bodyParts[BODYPART_PELVIS]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_ABDOMEN_PELVIS] = coneConstraint; world->addConstraint(joints[JOINT_ABDOMEN_PELVIS], true); // pelvis-leftthigh bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(pelvisHeight / 2), -(pelvisWidth/2 - thighRadius))); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, thighHeight/2 + thighRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_PELVIS]->getRigidBody(), *bodyParts[BODYPART_LEFT_THIGH]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_PELVIS_LEFT_THIGH] = coneConstraint; world->addConstraint(joints[JOINT_PELVIS_LEFT_THIGH], true); // left thigh-leg bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(thighHeight / 2 + thighRadius), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, legHeight / 2 + legRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_LEFT_THIGH]->getRigidBody(), *bodyParts[BODYPART_LEFT_LEG]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_LEFT_THIGH_LEG] = coneConstraint; world->addConstraint(joints[JOINT_LEFT_THIGH_LEG], true); // left leg-foot bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(legHeight / 2 + legRadius), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(-footXOffset, footHeight + 0.03, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_LEFT_LEG]->getRigidBody(), *bodyParts[BODYPART_LEFT_FOOT]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_LEFT_LEG_FOOT] = coneConstraint; world->addConstraint(joints[JOINT_LEFT_LEG_FOOT], true); // pelvis-rightthigh bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(pelvisHeight / 2), (pelvisWidth / 2 - thighRadius))); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, thighHeight / 2 + thighRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_PELVIS]->getRigidBody(), *bodyParts[BODYPART_RIGHT_THIGH]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_PELVIS_RIGHT_THIGH] = coneConstraint; world->addConstraint(joints[JOINT_PELVIS_RIGHT_THIGH], true); // RIGHT thigh-leg bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(thighHeight / 2 + thighRadius), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(0, legHeight / 2 + legRadius, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_RIGHT_THIGH]->getRigidBody(), *bodyParts[BODYPART_RIGHT_LEG]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_RIGHT_THIGH_LEG] = coneConstraint; world->addConstraint(joints[JOINT_RIGHT_THIGH_LEG], true); // RIGHT leg-foot bodyA.setIdentity(); bodyA.getBasis().setEulerZYX(0, M_PI_2, 0); bodyA.setOrigin(btVector3(0, -(legHeight / 2 + legRadius), 0)); bodyB.setIdentity(); bodyB.getBasis().setEulerZYX(0, M_PI_2, 0); bodyB.setOrigin(btVector3(-footXOffset, footHeight + 0.03, 0)); coneConstraint = new btConeTwistConstraint(*bodyParts[BODYPART_RIGHT_LEG]->getRigidBody(), *bodyParts[BODYPART_RIGHT_FOOT]->getRigidBody(), bodyA, bodyB); coneConstraint->setLimit(M_PI_4, M_PI_4, 0); joints[JOINT_RIGHT_LEG_FOOT] = coneConstraint; world->addConstraint(joints[JOINT_RIGHT_LEG_FOOT], true); }
void SpheresDemo::setupScene(const ConstructionInfo& ci) { if (1) { btSphereShape* sphere = new btSphereShape(1); m_collisionShapes.push_back(sphere); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); float start_x = START_POS_X - ci.gapX*ci.arraySizeX/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ci.gapZ*ci.arraySizeZ/2; for (int k=0;k<ci.arraySizeY;k++) { int sizeX = ci.arraySizeX; int startX = -sizeX/2; float gapX = ci.gapX; for (int i=0;i<sizeX;i++) { int sizeZ = ci.arraySizeZ; int startZ = -sizeX/2; float gapZ =ci.gapZ; for(int j = 0;j<sizeZ;j++) { //btCollisionShape* shape = k==0? boxShape : colShape; btCollisionShape* shape = sphere; btScalar mass = 1; if (!ci.m_useConcaveMesh && k==0) mass = k==0? 0.f : 1.f; //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) shape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(SCALING*btVector3( btScalar(gapX*i + start_x), btScalar(ci.gapY*k + start_y), btScalar(gapZ*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } } { btVector3 planeNormal(0,1,0); btScalar planeConstant=0; //btCollisionShape* shape = new btStaticPlaneShape(planeNormal,planeConstant); //btBoxShape* plane = new btBoxShape(btVector3(100,1,100)); //plane->initializePolyhedralFeatures(); btSphereShape* shape = new btSphereShape(1000); btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setRotation(btQuaternion(btVector3(1,0,0),0.3)); groundTransform.setOrigin(btVector3(0,-1000,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } }
void BenchmarkDemo::initPhysics() { setCameraDistance(btScalar(100.)); ///collision configuration contains default setup for memory, collision setup btDefaultCollisionConstructionInfo cci; cci.m_defaultMaxPersistentManifoldPoolSize = 32768; m_collisionConfiguration = new btDefaultCollisionConfiguration(cci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); #if USE_PARALLEL_DISPATCHER_BENCHMARK int maxNumOutstandingTasks = 4; #ifdef _WIN32 Win32ThreadSupport* threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo( "collision",processCollisionTask, createCollisionLocalStoreMemory,maxNumOutstandingTasks)); #elif defined (USE_PTHREADS) PosixThreadSupport::ThreadConstructionInfo collisionConstructionInfo( "collision",processCollisionTask, createCollisionLocalStoreMemory,maxNumOutstandingTasks); PosixThreadSupport* threadSupportCollision = new PosixThreadSupport(collisionConstructionInfo); #endif //SequentialThreadSupport::SequentialThreadConstructionInfo sci("spuCD", processCollisionTask, createCollisionLocalStoreMemory); //SequentialThreadSupport* seq = new SequentialThreadSupport(sci); m_dispatcher = new SpuGatheringCollisionDispatcher(threadSupportCollision,1,m_collisionConfiguration); #endif ///the maximum size of the collision world. Make sure objects stay within these boundaries ///Don't make the world AABB size too large, it will harm simulation quality and performance btVector3 worldAabbMin(-1000,-1000,-1000); btVector3 worldAabbMax(1000,1000,1000); btHashedOverlappingPairCache* pairCache = new btHashedOverlappingPairCache(); m_overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,3500,pairCache); // m_overlappingPairCache = new btSimpleBroadphase(); // m_overlappingPairCache = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) #ifdef USE_PARALLEL_DISPATCHER_BENCHMARK btThreadSupportInterface* thread = createSolverThreadSupport(4); btConstraintSolver* sol = new btParallelConstraintSolver(thread); #else btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; #endif //USE_PARALLEL_DISPATCHER_BENCHMARK m_solver = sol; btDiscreteDynamicsWorld* dynamicsWorld; m_dynamicsWorld = dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_solver,m_collisionConfiguration); #ifdef USE_PARALLEL_DISPATCHER_BENCHMARK dynamicsWorld->getSimulationIslandManager()->setSplitIslands(false); #endif //USE_PARALLEL_DISPATCHER_BENCHMARK ///the following 3 lines increase the performance dramatically, with a little bit of loss of quality m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; //don't recalculate friction values each frame dynamicsWorld->getSolverInfo().m_numIterations = 5; //few solver iterations m_defaultContactProcessingThreshold = 0.f;//used when creating bodies: body->setContactProcessingThreshold(...); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); if (m_benchmark<5) { ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(250.),btScalar(50.),btScalar(250.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } } switch (m_benchmark) { case 1: { createTest1(); break; } case 2: { createTest2(); break; } case 3: { createTest3(); break; } case 4: { createTest4(); break; } case 5: { createTest5(); break; } case 6: { createTest6(); break; } case 7: { createTest7(); break; } default: { } } clientResetScene(); }
void BasicDemo::initPhysics() { setTexturing(false); setShadows(false); #if OECAKE_LOADER setCameraDistance(80.); m_cameraTargetPosition.setValue(50, 10, 0); #else #if LARGE_DEMO setCameraDistance(btScalar(SCALING*100.)); #else setCameraDistance(btScalar(SCALING*20.)); #endif m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z); #endif m_azi = btScalar(0.f); m_ele = btScalar(0.f); ///collision configuration contains default setup for memory, collision setup btDefaultCollisionConstructionInfo dci; dci.m_defaultMaxPersistentManifoldPoolSize=50000; dci.m_defaultMaxCollisionAlgorithmPoolSize=50000; m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc); m_dispatcher->setNearCallback(cudaDemoNearCallback); #if USE_CUDA_DEMO_PAIR_CASHE gPairCache = new (btAlignedAlloc(sizeof(btGpuDemoPairCache),16)) btGpuDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES); #else gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache(); #endif btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING); int numOfCellsX = (int)numOfCells[0]; int numOfCellsY = (int)numOfCells[1]; int numOfCellsZ = (int)numOfCells[2]; // m_broadphase = new btAxisSweep3(gWorldMin, gWorldMax, MAX_PROXIES,gPairCache); m_broadphase = new btDbvtBroadphase(gPairCache); // m_broadphase = new btGpu3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24); // m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24); ///the default constraint solver m_solver = new btSequentialImpulseConstraintSolver(); btGpuDemoDynamicsWorld* pDdw = new btGpuDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, MAX_PROXIES); m_dynamicsWorld = pDdw; pDdw->getSimulationIslandManager()->setSplitIslands(true); pDdw->setObjRad(SCALING); pDdw->setWorldMin(gWorldMin); pDdw->setWorldMax(gWorldMax); // gUseCPUSolver = true; pDdw->setUseCPUSolver(gUseCPUSolver); gUseBulletNarrowphase = false; pDdw->setUseBulletNarrowphase(gUseBulletNarrowphase); // m_dynamicsWorld->setGravity(btVector3(0,0,0)); m_dynamicsWorld->setGravity(btVector3(0,-10.,0)); m_dynamicsWorld->getSolverInfo().m_numIterations = 4; { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance #if 1 #define SPRADIUS btScalar(SCALING*0.1f) #define SPRPOS btScalar(SCALING*0.05f) static btVector3 sSphPos[8]; for (int k=0;k<8;k++) { sSphPos[k].setValue((k-4)*0.25*SCALING,0,0); } btVector3 inertiaHalfExtents(SPRADIUS, SPRADIUS, SPRADIUS); static btScalar sSphRad[8] = { // SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, 0.3 SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS }; // sSphPos[0].setX(sSphPos[0].getX()-0.15); #undef SPR btMultiSphereShape* colShape[2]; colShape[0] = new btMultiSphereShape( sSphPos, sSphRad, 8); colShape[1] = new btMultiSphereShape( sSphPos, sSphRad, 2); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape[0]); m_collisionShapes.push_back(colShape[1]); #endif /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(0.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); #if OECAKE_LOADER BasicDemoOecakeLoader loader(this); if (!loader.processFile("test1.oec")) { loader.processFile("../../test1.oec"); } #if 0 // perfomance test : work-in-progress { // add more object, but share their shapes int numNewObjects = 500; mass = 1.f; for(int n_obj = 0; n_obj < numNewObjects; n_obj++) { btDefaultMotionState* myMotionState= 0; btVector3 localInertia(0,0,0); btTransform worldTransform; worldTransform.setIdentity(); btScalar fx = fRandMinMax(-30., 30.); btScalar fy = fRandMinMax(5., 30.); worldTransform.setOrigin(btVector3(fx, fy, 0.f)); int sz = m_collisionShapes.size(); btMultiSphereShape* multiSphere = (btMultiSphereShape*)m_collisionShapes[1]; myMotionState = new btDefaultMotionState(worldTransform); multiSphere->calculateLocalInertia(mass, localInertia); btRigidBody* body = new btRigidBody(mass,myMotionState,multiSphere,localInertia); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); body->setWorldTransform(worldTransform); getDynamicsWorld()->addRigidBody(body); } } #endif #else #if (!SPEC_TEST) float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; int collisionShapeIndex = 0; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { float offs = (2. * (float)rand() / (float)RAND_MAX - 1.f) * 0.05f; startTransform.setOrigin(SCALING*btVector3( 2.0*SCALING*i + start_x + offs, 2.0*SCALING*k + start_y + offs, 2.0*SCALING*j + start_z)); if (isDynamic) colShape[collisionShapeIndex]->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[collisionShapeIndex],localInertia); collisionShapeIndex = 1 - collisionShapeIndex; rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } #else//SPEC_TEST // narrowphase test - 2 bodies at the same position float start_x = START_POS_X; // float start_y = START_POS_Y; float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f; float start_z = START_POS_Z; startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[0],localInertia); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); btPoint2PointConstraint * p2pConstr = new btPoint2PointConstraint(*body, btVector3(1., 0., 0.)); m_dynamicsWorld->addConstraint(p2pConstr); startTransform.setOrigin(SCALING*btVector3(start_x-2.f, start_y,start_z)); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body1 = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body1); p2pConstr = new btPoint2PointConstraint(*body, *body1, btVector3(-1., 0., 0.), btVector3(1., 0., 0.)); m_dynamicsWorld->addConstraint(p2pConstr); #endif//SPEC_TEST #endif //OE_CAKE_LOADER } // now set Ids used by collision detector and constraint solver int numObjects = m_dynamicsWorld->getNumCollisionObjects(); btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); for(int i = 0; i < numObjects; i++) { btCollisionObject* colObj = collisionObjects[i]; colObj->setCompanionId(i+1); // 0 reserved for the "world" object btCollisionShape* pShape = colObj->getCollisionShape(); int shapeType = pShape->getShapeType(); if(shapeType == MULTI_SPHERE_SHAPE_PROXYTYPE) { btMultiSphereShape* pMs = (btMultiSphereShape*)pShape; int numSpheres = pMs->getSphereCount(); pDdw->addMultiShereObject(numSpheres, i + 1); for(int j = 0; j < numSpheres; j++) { btVector3 sphPos = pMs->getSpherePosition(j); float sphRad = pMs->getSphereRadius(j); pDdw->addSphere(sphPos, sphRad); } } else { btAssert(0); } } #if OECAKE_LOADER clientResetScene(); #endif }
// --------------------------------------------------------- PhysBody3D* ModulePhysics3D::AddHeighField(const char* filename, int width, int length) { unsigned char* heightfieldData = new unsigned char[width*length]; { for(int i = 0; i<width*length; i++) heightfieldData[i] = 0; } FILE* heightfieldFile; fopen_s(&heightfieldFile, filename, "r"); if(heightfieldFile) { int numBytes = fread(heightfieldData, 1, width*length, heightfieldFile); //btAssert(numBytes); if(!numBytes) { printf("couldn't read heightfield at %s\n", filename); } fclose(heightfieldFile); } //btScalar maxHeight = 20000.f;//exposes a bug btScalar maxHeight = 100; bool useFloatDatam = false; bool flipQuadEdges = false; int upIndex = 1; btHeightfieldTerrainShape* heightFieldShape = new btHeightfieldTerrainShape(width, length, heightfieldData, maxHeight, upIndex, useFloatDatam, flipQuadEdges); btVector3 mmin, mmax; heightFieldShape->getAabb(btTransform::getIdentity(), mmin, mmax); btCollisionShape* groundShape = heightFieldShape; heightFieldShape->setUseDiamondSubdivision(true); btVector3 localScaling(10, 1, 10); localScaling[upIndex] = 1.f; groundShape->setLocalScaling(localScaling); shapes.add(groundShape); //create ground object btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(0, 49.4, 0)); btVector3 localInertia(0, 0, 0); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0.0f, myMotionState, groundShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); PhysBody3D* pbody = new PhysBody3D(body); body->setUserPointer(pbody); world->addRigidBody(body); bodies.add(pbody); return pbody; }
int mmdpiBullet::create_rigidbody( tagMMDPI_BULLET_TYPE rigidbody_type, btTransform *trans, float weight, int kinematic_flag, float width, float height, float depth, MMDPI_BULLET_RIGID_INFO_PTR rigid_info ) { btCollisionShape *pColShape; btScalar mass( weight ); // 質量0なら静的ボディ btTransform rigid_trans = *trans; //btDefaultMotionState* myMotionState = NULL; btMotionState *myMotionState = NULL; if( kinematic_flag && rigid_info->kinematic_mode ) myMotionState = new btKinematicMotionState( rigid_trans, rigid_info->offset, rigid_info->kinematicMatrix ); else myMotionState = new btDefaultMotionState( rigid_trans ); // シェープ作成 createShape( &pColShape, rigidbody_type, width, height, depth ); if( kinematic_flag ) mass = 0; bool isDynamic = ( mass != 0.0f ); btVector3 localInertia( 0, 0, 0 ); if( isDynamic ) pColShape->calculateLocalInertia( mass, localInertia ); btRigidBody::btRigidBodyConstructionInfo rbInfo( mass, myMotionState, pColShape, localInertia ); if( rigid_info ) { rbInfo.m_linearDamping = rigid_info->fLinearDamping; // 移動減 rbInfo.m_angularDamping = rigid_info->fAngularDamping; // 回転減 rbInfo.m_restitution = rigid_info->fRestitution; // 反発力 rbInfo.m_friction = rigid_info->fFriction; // 摩擦力 rbInfo.m_additionalDamping = true; } // 剛体生成 btRigidBody* body = new btRigidBody( rbInfo ); // キネマティクス剛体 if( kinematic_flag ) { body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT ); body->setActivationState( DISABLE_DEACTIVATION ) ; } body->setSleepingThresholds( 0.0f, 0.0f ); getCollisionArray()->push_back( pColShape ); // 衝突判定に追加 if( rigid_info ) // 拡張情報つき { ushort g_index = 0x0001 << rigid_info->rigidbody_group_index; ushort g_mask = rigid_info->rigidbody_group_mask; //if( g_mask == 0xffff ) // g_mask = 0; getDiscreteDynamicsWorld()->addRigidBody( body, g_index, g_mask ); // ワールドに追加 } else getDiscreteDynamicsWorld()->addRigidBody( body ); // ワールドに追加 return rigidbody_num ++; // 正常終了 (戻り値 => 剛体ID) }
void SerializeDemo::initPhysics() { setTexturing(true); setShadows(true); setCameraDistance(btScalar(SCALING*50.)); setupEmptyDynamicsWorld(); btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld); // fileLoader->setVerboseMode(true); if (!fileLoader->loadFile("testFile.bullet")) { ///create a few basic rigid bodies and save them to testFile.bullet btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); btCollisionObject* groundObject = 0; m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); groundObject = body; } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance int numSpheres = 2; btVector3 positions[2] = {btVector3(0.1f,0.2f,0.3f),btVector3(0.4f,0.5f,0.6f)}; btScalar radii[2] = {0.3f,0.4f}; btMultiSphereShape* colShape = new btMultiSphereShape(positions,radii,numSpheres); //btCollisionShape* colShape = new btCapsuleShapeZ(SCALING*1,SCALING*1); //btCollisionShape* colShape = new btCylinderShapeZ(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(SCALING*btVector3( btScalar(2.0*i + start_x), btScalar(20+2.0*k + start_y), btScalar(2.0*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setActivationState(ISLAND_SLEEPING); m_dynamicsWorld->addRigidBody(body); body->setActivationState(ISLAND_SLEEPING); } } } } int maxSerializeBufferSize = 1024*1024*5; btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); static char* groundName = "GroundName"; serializer->registerNameForPointer(groundObject, groundName); for (int i=0;i<m_collisionShapes.size();i++) { char* name = new char[20]; sprintf(name,"name%d",i); serializer->registerNameForPointer(m_collisionShapes[i],name); } btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*(btRigidBody*)getDynamicsWorld()->getCollisionObjectArray()[2],btVector3(0,1,0)); m_dynamicsWorld->addConstraint(p2p); const char* name = "constraintje"; serializer->registerNameForPointer(p2p,name); m_dynamicsWorld->serialize(serializer); FILE* f2 = fopen("testFile.bullet","wb"); fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); fclose(f2); } clientResetScene(); }
int main() #endif { ///-----includes_end----- int i; ///-----initialization_start----- ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration); dynamicsWorld->setGravity(btVector3(0,-10,0)); ///-----initialization_end----- ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); //keep track of the shapes, we release memory at exit. //make sure to re-use collision shapes among rigid bodies whenever possible! btAlignedObjectArray<btCollisionShape*> collisionShapes; collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-56,0)); { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world dynamicsWorld->addRigidBody(body); } { //create a dynamic rigidbody //btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); btCollisionShape* colShape = new btSphereShape(btScalar(1.)); collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3(2,10,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); dynamicsWorld->addRigidBody(body); } /// Do some simulation ///-----stepsimulation_start----- for (i=0;i<100;i++) { dynamicsWorld->stepSimulation(1.f/60.f,10); //print positions of all objects for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--) { btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { btTransform trans; body->getMotionState()->getWorldTransform(trans); printf("world pos = %f,%f,%f\n",float(trans.getOrigin().getX()),float(trans.getOrigin().getY()),float(trans.getOrigin().getZ())); } } } ///-----stepsimulation_end----- //cleanup in the reverse order of creation/initialization ///-----cleanup_start----- //remove the rigidbodies from the dynamics world and delete them for (i=dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) { btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { delete body->getMotionState(); } dynamicsWorld->removeCollisionObject( obj ); delete obj; } //delete collision shapes for (int j=0;j<collisionShapes.size();j++) { btCollisionShape* shape = collisionShapes[j]; collisionShapes[j] = 0; delete shape; } //delete dynamics world delete dynamicsWorld; //delete solver delete solver; //delete broadphase delete overlappingPairCache; //delete dispatcher delete dispatcher; delete collisionConfiguration; //next line is optional: it will be cleared by the destructor when the array goes out of scope collisionShapes.clear(); ///-----cleanup_end----- }
void FractureDemo::initPhysics() { m_guiHelper->setUpAxis(1); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; //m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); btFractureDynamicsWorld* fractureWorld = new btFractureDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_dynamicsWorld = fractureWorld; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //m_splitImpulse removes the penetration resolution from the applied impulse, otherwise objects might fracture due to deep penetrations. m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; { ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(50, 1, 50)); /// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, 0, 0)); createRigidBody(0.f, groundTransform, groundShape); } { ///create a few basic rigid bodies btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1)); m_collisionShapes.push_back(shape); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(5, 2, 0)); createRigidBody(0.f, tr, shape); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btCollisionShape* colShape = new btBoxShape(btVector3(SCALING * 1, SCALING * 1, SCALING * 1)); //btCollisionShape* colShape = new btCapsuleShape(SCALING*0.4,SCALING*1); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0, 0, 0); if (isDynamic) colShape->calculateLocalInertia(mass, localInertia); int gNumObjects = 10; for (int i = 0; i < gNumObjects; i++) { btTransform trans; trans.setIdentity(); btVector3 pos(i * 2 * CUBE_HALF_EXTENTS, 20, 0); trans.setOrigin(pos); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(trans); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia); btFractureBody* body = new btFractureBody(rbInfo, m_dynamicsWorld); body->setLinearVelocity(btVector3(0, -10, 0)); m_dynamicsWorld->addRigidBody(body); } } fractureWorld->stepSimulation(1. / 60., 0); fractureWorld->glueCallback(); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); }
void BulletPhysicsManager::addPhysicsObject(GameObject* gameObject) { BulletCollision* collisionComponent = dynamic_cast<BulletCollision*>(gameObject->getCollision()); if(collisionComponent != NULL) { btCollisionShape* shape = collisionComponent->shape; collisionComponent->dynamicsWorld = dynamicsWorld; BulletDynamics* rigidBodyComponent = dynamic_cast<BulletDynamics*>(gameObject->getDynamics()); // KinematicCharacterController* characterControllerComponent = gameObject->getKinematicCharacterController(); if(rigidBodyComponent != NULL) { // since the character controller is fully kinematic, doesn't make sense to have a rigidbody also // assert(characterControllerComponent == NULL); // localInertia defines how the object's mass is distributed btVector3 localInertia(0.0f, 0.0f, 0.0f); // TODO - should be calculating mass here, not just using density if (rigidBodyComponent->getDensity() > 0.0f) { shape->calculateLocalInertia(rigidBodyComponent->getDensity(), localInertia); } // set the initial position of the body from the actor Vector3* position = gameObject->getTransform()->getPosition(); Quaternion* orientation = gameObject->getTransform()->getOrientation(); ActorMotionState* const myMotionState = new ActorMotionState(*position, *orientation); btRigidBody::btRigidBodyConstructionInfo rbInfo(rigidBodyComponent->getDensity(), myMotionState, shape, localInertia); // set up the materal properties rbInfo.m_restitution = rigidBodyComponent->getRestitution(); rbInfo.m_friction = rigidBodyComponent->getFriction(); btRigidBody* body = new btRigidBody(rbInfo); if(rigidBodyComponent->isKinematic()) { // see Bullet manual section on "Kinematic Bodies" body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); body->setActivationState(DISABLE_DEACTIVATION); } if (collisionComponent->isTrigger()) { body->setCollisionFlags( body->getCollisionFlags() | btRigidBody::CF_NO_CONTACT_RESPONSE ); } if(rigidBodyComponent->isOverrideSleepingThresholds()) { body->setSleepingThresholds(0.0, 0.0); } // constrict motion to the X-Y plane for 2D games - http://code.google.com/p/bullet/issues/detail?id=208 body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); body->setUserPointer(gameObject); dynamicsWorld->addRigidBody(body, btBroadphaseProxy::DefaultFilter, btBroadphaseProxy::AllFilter); rigidBodyComponent->rigidBody = body; collisionComponent->collisionObject = body; // } else if (characterControllerComponent != NULL) { // // since the character controller is fully kinematic, doesn't make sense to have a rigidbody also // assert(rigidBodyComponent == NULL); // // btConvexShape* convexShape = dynamic_cast<btConvexShape*>(shape); // assert(convexShape != NULL); // // Vector3* position = gameObject->getTransform()->getPosition(); // Quaternion* orientation = gameObject->getTransform()->getOrientation(); // ActorMotionState myMotionState = ActorMotionState(*position, *orientation); // btTransform startTransform; // myMotionState.getWorldTransform(startTransform); // // btPairCachingGhostObject* m_ghostObject = new btPairCachingGhostObject(); // m_ghostObject->setWorldTransform(startTransform); // m_ghostObject->setCollisionShape (convexShape); // m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT); // // btKinematicCharacterController* m_character = new btKinematicCharacterController (m_ghostObject, convexShape, btScalar(0.0f)); // m_character->setGravity(0.0f); // m_ghostObject->setUserPointer(gameObject); // // dynamicsWorld->addCollisionObject(m_ghostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::AllFilter); // // if(!characterControllerComponent->isAllowPhysicsReaction()) { // // don't let the player push objects around in the world // m_ghostObject->setCollisionFlags( m_ghostObject->getCollisionFlags() | btRigidBody::CF_NO_CONTACT_RESPONSE ); // } // // collisionComponent->setCollisionObject(m_ghostObject); // characterControllerComponent->setCharacterController(m_character); } else { // never should have gotten here assert(false); } } physicsObjects.push_back(gameObject); }
void CcdPhysicsDemo::initPhysics() { setTexturing(true); setShadows(true); m_ShootBoxInitialSpeed = 4000.f; m_defaultContactProcessingThreshold = 0.f; ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); // m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); //m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_collisionConfiguration->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE)); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_RANDMIZE_ORDER; m_dynamicsWorld ->setDebugDrawer(&sDebugDrawer); //m_dynamicsWorld->getSolverInfo().m_splitImpulse=false; if (m_ccdMode==USE_CCD) { m_dynamicsWorld->getDispatchInfo().m_useContinuous=true; } else { m_dynamicsWorld->getDispatchInfo().m_useContinuous=false; } m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.))); // box->initializePolyhedralFeatures(); btCollisionShape* groundShape = box; // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); //m_collisionShapes.push_back(new btCylinderShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); m_collisionShapes.push_back(new btBoxShape (btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS))); btTransform groundTransform; groundTransform.setIdentity(); //groundTransform.setOrigin(btVector3(5,5,5)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(0.5); //body->setRollingFriction(0.3); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); int gNumObjects = 120;//120; int i; for (i=0;i<gNumObjects;i++) { btCollisionShape* shape = m_collisionShapes[1]; btTransform trans; trans.setIdentity(); //stack them int colsize = 10; int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); int row2 = row; int col = (i)%(colsize)-colsize/2; if (col>3) { col=11; row2 |=1; } btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); trans.setOrigin(pos); float mass = 1.f; btRigidBody* body = localCreateRigidBody(mass,trans,shape); body->setAnisotropicFriction(shape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); body->setFriction(0.5); //body->setRollingFriction(.3); ///when using m_ccdMode if (m_ccdMode==USE_CCD) { body->setCcdMotionThreshold(CUBE_HALF_EXTENTS); body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS); } } } }
int main() { btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration(); btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration); btBroadphaseInterface *overlappingPairCache = new btDbvtBroadphase(); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btDiscreteDynamicsWorld *dynamicsWorld = new btDiscreteDynamicsWorld( dispatcher, overlappingPairCache, solver, collisionConfiguration); dynamicsWorld->setGravity(btVector3(0, gravity, 0)); dynamicsWorld->setInternalTickCallback(myTickCallback); btAlignedObjectArray<btCollisionShape*> collisionShapes; // Ground. { btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0, 0, 0)); btCollisionShape* groundShape; groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), -1); collisionShapes.push_back(groundShape); btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(0, myMotionState, groundShape, btVector3(0, 0, 0)); btRigidBody* body = new btRigidBody(rbInfo); body->setRestitution(groundRestitution); dynamicsWorld->addRigidBody(body); } // Objects. std::vector<btRigidBody*> objects; for (size_t i = 0; i < nObjects; ++i) { btCollisionShape *colShape; colShape = new btSphereShape(btScalar(1.0)); collisionShapes.push_back(colShape); btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(initialXs[i], initialYs[i], 0)); btVector3 localInertia(0, 0, 0); btScalar mass(1.0f); colShape->calculateLocalInertia(mass, localInertia); btDefaultMotionState *myMotionState = new btDefaultMotionState(startTransform); btRigidBody *body = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo( mass, myMotionState, colShape, localInertia)); body->setRestitution(objectRestitution); dynamicsWorld->addRigidBody(body); objects.push_back(body); } // Main loop. std::printf(COMMON_PRINTF_HEADER " collision1 collision2\n"); for (std::remove_const<decltype(nSteps)>::type step = 0; step < nSteps; ++step) { dynamicsWorld->stepSimulation(timeStep); auto nCollisionObjects = dynamicsWorld->getNumCollisionObjects(); for (std::remove_const<decltype(nCollisionObjects)>::type objectIndex = 0; objectIndex < nCollisionObjects; ++objectIndex) { btRigidBody *body = btRigidBody::upcast(dynamicsWorld->getCollisionObjectArray()[objectIndex]); commonPrintBodyState(body, step, objectIndex); // We could use objects[i] here to check for one of the objects we've created. auto manifoldPoints = objectsCollisions[body]; if (manifoldPoints.empty()) { std::printf("0"); } else { std::printf("1"); } std::printf("\n"); } } // Cleanup. for (int i = dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) { btCollisionObject *obj = dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody *body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { delete body->getMotionState(); } dynamicsWorld->removeCollisionObject(obj); delete obj; } for (int i = 0; i < collisionShapes.size(); ++i) { delete collisionShapes[i]; } delete dynamicsWorld; delete solver; delete overlappingPairCache; delete dispatcher; delete collisionConfiguration; collisionShapes.clear(); }
void RollingFrictionDemo::initPhysics() { m_guiHelper->setUpAxis(2); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); // m_dynamicsWorld->getSolverInfo().m_singleAxisRollingFrictionThreshold = 0.f;//faster but lower quality m_dynamicsWorld->setGravity(btVector3(0,0,-10)); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); { ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(5.),btScalar(25.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,0,-28)); groundTransform.setRotation(btQuaternion(btVector3(0,1,0),SIMD_PI*0.03)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(1); body->setRollingFriction(1); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(100.),btScalar(100.),btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,0,-54)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(1); body->setRollingFriction(1); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance #define NUM_SHAPES 10 btCollisionShape* colShapes[NUM_SHAPES] = { new btSphereShape(btScalar(0.5)), new btCapsuleShape(0.25,0.5), new btCapsuleShapeX(0.25,0.5), new btCapsuleShapeZ(0.25,0.5), new btConeShape(0.25,0.5), new btConeShapeX(0.25,0.5), new btConeShapeZ(0.25,0.5), new btCylinderShape(btVector3(0.25,0.5,0.25)), new btCylinderShapeX(btVector3(0.5,0.25,0.25)), new btCylinderShapeZ(btVector3(0.25,0.25,0.5)), }; for (int i=0; i<NUM_SHAPES; i++) m_collisionShapes.push_back(colShapes[i]); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; { int shapeIndex = 0; for (int k=0; k<ARRAY_SIZE_Y; k++) { for (int i=0; i<ARRAY_SIZE_X; i++) { for(int j = 0; j<ARRAY_SIZE_Z; j++) { startTransform.setOrigin(SCALING*btVector3( btScalar(2.0*i + start_x), btScalar(2.0*j + start_z), btScalar(20+2.0*k + start_y))); shapeIndex++; btCollisionShape* colShape = colShapes[shapeIndex%NUM_SHAPES]; bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setFriction(1.f); body->setRollingFriction(.3); body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); m_dynamicsWorld->addRigidBody(body); } } } } } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); if (0) { btSerializer* s = new btDefaultSerializer; m_dynamicsWorld->serialize(s); b3ResourcePath p; char resourcePath[1024]; if (p.findResourcePath("slope.bullet",resourcePath,1024)) { FILE* f = fopen(resourcePath,"wb"); fwrite(s->getBufferPointer(),s->getCurrentBufferSize(),1,f); fclose(f); } } }
void VoronoiFractureDemo::initPhysics() { srand(13); useGenericConstraint = !useGenericConstraint; printf("useGenericConstraint = %d\n", useGenericConstraint); setTexturing(true); setShadows(true); setCameraDistance(btScalar(20.)); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); useMpr = 1 - useMpr; if (useMpr) { printf("using GJK+MPR convex-convex collision detection\n"); btConvexConvexMprAlgorithm::CreateFunc* cf = new btConvexConvexMprAlgorithm::CreateFunc; m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf); m_dispatcher->registerCollisionCreateFunc(CONVEX_HULL_SHAPE_PROXYTYPE, BOX_SHAPE_PROXYTYPE, cf); m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE, CONVEX_HULL_SHAPE_PROXYTYPE, cf); } else { printf("using default (GJK+EPA) convex-convex collision detection\n"); } m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; m_dynamicsWorld->setDebugDrawer(&sDebugDraw); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(8.),btScalar(1.))); btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); groundTransform.setOrigin(btVector3(0,0,0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } // ==> Voronoi Shatter Basic Demo: Random Cuboid // Random size cuboid (defined by bounding box max and min) btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 12. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5); btVector3 bbmin = -bbmax; // Place it 10 units above ground btVector3 bbt(0,15,0); // Use an arbitrary material density for shards (should be consitent/relative with/to rest of RBs in world) btScalar matDensity = 1; // Using random rotation btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.); bbq.normalize(); // Generate random points for voronoi cells btAlignedObjectArray<btVector3> points; btVector3 point; btVector3 diff = bbmax - bbmin; for (int i=0; i < VORONOIPOINTS; i++) { // Place points within box area (points are in world coordinates) point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() -diff.x()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() -diff.y()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() -diff.z()/2.)) + bbt; points.push_back(point); } m_perfmTimer.reset(); voronoiBBShatter(points, bbmin, bbmax, bbq, bbt, matDensity); printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds()/1000.); for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; obj->getCollisionShape()->setMargin(CONVEX_MARGIN+0.01); } m_dynamicsWorld->performDiscreteCollisionDetection(); for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; obj->getCollisionShape()->setMargin(CONVEX_MARGIN); } attachFixedConstraints(); }
void RaytestDemo::initPhysics() { m_ele = 10; m_azi = 75; setTexturing(true); setShadows(true); setCameraDistance(btScalar(20.)); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld ->setDebugDrawer(&sDebugDraw); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->setRollingFriction(1); body->setFriction(1); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { btVector3 convexPoints[]={ btVector3(-1,-1,-1),btVector3(-1,-1,1),btVector3(-1,1,1),btVector3(-1,1,-1), btVector3(2,0,0)}; btVector3 quad[] = { btVector3(0,1,-1), btVector3(0,1,1), btVector3(0,-1,1), btVector3(0,-1,-1)}; btTriangleMesh* mesh = new btTriangleMesh(); mesh->addTriangle(quad[0],quad[1],quad[2],true); mesh->addTriangle(quad[0],quad[2],quad[3],true); //btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(mesh,true,true); btGImpactMeshShape * trimesh = new btGImpactMeshShape(mesh); trimesh->updateBound(); #define NUM_SHAPES 6 btCollisionShape* colShapes[NUM_SHAPES] = { trimesh, new btConvexHullShape(&convexPoints[0].getX(),sizeof(convexPoints)/sizeof(btVector3),sizeof(btVector3)), new btSphereShape(1), new btCapsuleShape(0.2,1), new btCylinderShape(btVector3(0.2,1,0.2)), new btBoxShape(btVector3(1,1,1)) }; for (int i=0;i<NUM_SHAPES;i++) m_collisionShapes.push_back(colShapes[i]); for (int i=0;i<6;i++) { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3((i-3)*5,1,0)); btScalar mass(1.f); if (!i) mass=0.f; //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); btCollisionShape* colShape = colShapes[i%NUM_SHAPES]; if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); rbInfo.m_startWorldTransform = startTransform; btRigidBody* body = new btRigidBody(rbInfo); body->setRollingFriction(0.03); body->setFriction(1); body->setAnisotropicFriction(colShape->getAnisotropicRollingFrictionDirection(),btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); m_dynamicsWorld->addRigidBody(body); } } }
void SpheresGridDemo::initPhysics() { setTexturing(false); setShadows(false); setCameraDistance(80.); m_cameraTargetPosition.setValue(50, 10, 0); m_azi = btScalar(0.f); m_ele = btScalar(0.f); ///collision configuration contains default setup for memory, collision setup btDefaultCollisionConstructionInfo dci; dci.m_defaultMaxPersistentManifoldPoolSize=50000; dci.m_defaultMaxCollisionAlgorithmPoolSize=50000; m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_pairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache(); // m_broadphase = new btDbvtBroadphase(m_pairCache); m_broadphase = new btNullBroadphase(); ///the default constraint solver m_solver = new btSequentialImpulseConstraintSolver(); #ifdef INTEGRATION_DEMO m_pWorldI = new btIntegrationDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, 65536); #endif #ifdef SPHERES_DEMO m_pWorldS = new btSpheresGridDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, 65536); #endif #ifdef SPHERES_DEMO m_dialogDynamicsWorld = new GL_DialogDynamicsWorld(); GL_DialogWindow* settings = m_dialogDynamicsWorld->createDialog(50,0,280,280,"CPU fallback"); m_pWorldS->m_useCpuControls[0] = 0; GL_ToggleControl* ctrl = 0; m_pWorldS->m_useCpuControls[SIMSTAGE_APPLY_GRAVITY] = m_dialogDynamicsWorld->createToggle(settings,"Apply Gravity"); m_pWorldS->m_useCpuControls[SIMSTAGE_COMPUTE_CELL_ID] = m_dialogDynamicsWorld->createToggle(settings,"Compute Cell ID"); m_pWorldS->m_useCpuControls[SIMSTAGE_SORT_CELL_ID] = m_dialogDynamicsWorld->createToggle(settings,"Sort Cell ID"); m_pWorldS->m_useCpuControls[SIMSTAGE_FIND_CELL_START] = m_dialogDynamicsWorld->createToggle(settings,"Find Cell Start"); m_pWorldS->m_useCpuControls[SIMSTAGE_FIND_PAIRS] = m_dialogDynamicsWorld->createToggle(settings,"Find Pairs"); m_pWorldS->m_useCpuControls[SIMSTAGE_SCAN_PAIRS] = m_dialogDynamicsWorld->createToggle(settings,"Scan Pairs"); m_pWorldS->m_useCpuControls[SIMSTAGE_COMPACT_PAIRS] = m_dialogDynamicsWorld->createToggle(settings,"Compact Pairs"); m_pWorldS->m_useCpuControls[SIMSTAGE_COMPUTE_BATCHES] = m_dialogDynamicsWorld->createToggle(settings,"Compute Batches"); m_pWorldS->m_useCpuControls[SIMSTAGE_COMPUTE_CONTACTS] = m_dialogDynamicsWorld->createToggle(settings,"Compute Contacts"); m_pWorldS->m_useCpuControls[SIMSTAGE_SOLVE_CONSTRAINTS] = m_dialogDynamicsWorld->createToggle(settings,"Solve Constraints"); m_pWorldS->m_useCpuControls[SIMSTAGE_INTEGRATE_TRANSFORMS] = m_dialogDynamicsWorld->createToggle(settings,"Integrate Transforms"); m_pWorldS->m_useCpuControls[SIMSTAGE_KERNEL_COLLIDE_SPHERE_WALLS] = m_dialogDynamicsWorld->createToggle(settings,"Collide Sphere Walls"); for(int i = 1; i < SIMSTAGE_TOTAL; i++) { m_pWorldS->m_useCpuControls[i]->m_active = false; } #if defined(CL_PLATFORM_MINI_CL) m_pWorldS->m_useCpuControls[SIMSTAGE_SCAN_PAIRS]->m_active = true; m_pWorldS->m_useCpuControls[SIMSTAGE_SORT_CELL_ID]->m_active = true; m_pWorldS->m_useCpuControls[SIMSTAGE_COMPUTE_CONTACTS]->m_active = true; #endif #if defined(CL_PLATFORM_AMD) m_pWorldS->m_useCpuControls[SIMSTAGE_SORT_CELL_ID]->m_active = true; // sloooow, incorrect, crashes application m_pWorldS->m_useCpuControls[SIMSTAGE_FIND_CELL_START]->m_active = true; // run-time error "Unimplemented" m_pWorldS->m_useCpuControls[SIMSTAGE_SCAN_PAIRS]->m_active = true; // works, but very slow (up to 100 times) m_pWorldS->m_useCpuControls[SIMSTAGE_COMPUTE_BATCHES]->m_active = true; // run-time error "Unimplemented" #endif #endif //#ifdef SPHERES_DEMO if(m_demoType == DEMO_INTEGRATION) { #ifdef INTEGRATION_DEMO m_dynamicsWorld = m_pWorldI; #endif } else { #ifdef SPHERES_DEMO m_dynamicsWorld = m_pWorldS; #endif //#ifdef SPHERES_DEMO } #ifdef INTEGRATION_DEMO m_pWorldI->getSimulationIslandManager()->setSplitIslands(true); m_pWorldI->setGravity(btVector3(0,-10.,0)); m_pWorldI->getSolverInfo().m_numIterations = 4; #endif //INTEGRATION_DEMO #ifdef SPHERES_DEMO m_pWorldS->getSimulationIslandManager()->setSplitIslands(true); m_pWorldS->setGravity(btVector3(0,-10.,0)); m_pWorldS->getSolverInfo().m_numIterations = 4; #endif //#ifdef SPHERES_DEMO { btCollisionShape* colShape = new btSphereShape(btScalar(1.0f)); m_collisionShapes.push_back(colShape); btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); btVector3 localInertia(0,0,0); colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X * DIST * btScalar(0.5f); float start_y = START_POS_Y - ARRAY_SIZE_Y * DIST * btScalar(0.5f); float start_z = START_POS_Z - ARRAY_SIZE_Z * DIST * btScalar(0.5f); #if USE_BULLET_BODIES // may be very slow for > 10K bodies printf("\nGenerating bodies ...\n"); int total = ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z; int done = 0; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(btVector3( DIST*i + start_x, DIST*k + start_y, DIST*j + start_z)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); rbInfo.m_startWorldTransform = startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_pWorldI->addRigidBody(body); done++; } } printf("%6d of %6d\r", done, total); fflush(stdout); } printf("\n... Done!\n"); #else // add just one sphere #ifdef INTEGRATION_DEMO startTransform.setOrigin(btVector3(start_x, start_y, start_z)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape,localInertia); rbInfo.m_startWorldTransform = startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_pWorldI->addRigidBody(body); #endif // now fill m_hPos and m_hLinVel directly init_scene_directly(); #endif } btDynamicsWorld* tmpW = m_dynamicsWorld; #ifdef SPHERES_DEMO m_dynamicsWorld = m_pWorldS; SpheresGridDemoOecakeLoader loader(this); //loader.processFile("test1.oec"); #if 1 /// stress test btCompoundShape* compound = new btCompoundShape(); btSphereShape* sphere = new btSphereShape(1.f); btTransform localTrans; localTrans.setIdentity(); localTrans.setOrigin(btVector3(0,0,0)); compound->addChildShape(localTrans,sphere); //localTrans.setOrigin(btVector3(-1,0,0)); //compound->addChildShape(localTrans,sphere); btTransform trans; trans.setIdentity(); btVector3 offset(0.00001,0.00001,0.00001); for (int j=0;j<STRESS_X;j++) for (int i=0;i<STRESS_Y;i++) { trans.setOrigin(offset*i+btVector3(25+j*6,30+i*3,0.)); loader.createBodyForCompoundShape(compound,false,trans,1.); } #endif m_dynamicsWorld = tmpW; #else m_dynamicsWorld = m_pWorldI; #endif//#ifdef SPHERES_DEMO clientResetScene(); #ifdef INTEGRATION_DEMO m_pWorldI->initDeviceData(); #endif #ifdef SPHERES_DEMO m_pWorldS->initDeviceData(); #endif print_used_device(); }
void BasicDemo::initPhysics() { setTexturing(true); setShadows(true); setCameraDistance(btScalar(SCALING*50.)); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; //btParallelConstraintSolver* sol = new btParallelConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(SCALING*btVector3( btScalar(2.0*i + start_x), btScalar(20+2.0*k + start_y), btScalar(2.0*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } } }
void BasicDemo::initPhysics() { setTexturing(true); setShadows(true); setCameraDistance(btScalar(40)); ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); m_dynamicsWorld->setDebugDrawer(&gDebugDraw); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(500.),btScalar(50.),btScalar(500.))); //groundShape->initializePolyhedralFeatures(); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } /////////////////////////////////////////////////////////////////////////////////////////////// ///////////// Setting the sphere ////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// { btCollisionShape* sphereShape = new btSphereShape(4.5f); m_collisionShapes.push_back(sphereShape); btTransform startTransform; startTransform.setIdentity(); btScalar mass(500.0f); bool isDynamic = (mass != 0.0f); btVector3 localInertia(0,0,0); if (isDynamic) sphereShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3( btScalar(-1), btScalar(((btSphereShape*)sphereShape)->getRadius()), btScalar(-35) )); btDefaultMotionState* motionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState,sphereShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); body->applyCentralImpulse(btVector3(0,0,120000)); body->applyTorqueImpulse(btVector3(200,0,0)); m_dynamicsWorld->addRigidBody(body); m_sphere = body; } /////////////////////////////////////////////////////////////////////////////////////////////// /////////////// Setting the pins ////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btCollisionShape* shape = new btCylinderShape(btVector3(0.5f, 4, 1)); m_collisionShapes.push_back(shape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.5f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) shape->calculateLocalInertia(mass,localInertia); const btVector3 origin = btVector3(0,1,0); const float zdiff = 1.0f; const float xdiff = 1.0f; for (int rowNumber = 0; rowNumber < LENGTH_OF_CONE; rowNumber++) { for (int cylinderInRow = 0; cylinderInRow <= rowNumber; cylinderInRow++) { startTransform.setOrigin(btVector3( btScalar(origin.getX() + ((cylinderInRow * xdiff * 2) - (xdiff * (rowNumber)))), btScalar(4), btScalar(rowNumber*zdiff + origin.getZ()) )); spawnRagdoll(startTransform.getOrigin()); //btDefaultMotionState* motionState = new btDefaultMotionState(startTransform); //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState,shape,localInertia); //btRigidBody* body = new btRigidBody(rbInfo); //m_dynamicsWorld->addRigidBody(body); } } } }