Пример #1
0
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);
				}
			}
		}
	}
}
Пример #2
0
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();
}
Пример #3
0
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();
}
Пример #4
0
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();

}
Пример #5
0
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();
}
Пример #6
0
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);
	}


}
Пример #7
0
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();
}
Пример #8
0
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);
		}
Пример #9
0
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);
		}
	}
}
Пример #10
0
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();
}
Пример #11
0
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]);
	
}
Пример #12
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);

}
Пример #14
0
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);
	}
}
Пример #15
0
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();
}
Пример #16
0
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
}
Пример #17
0
// ---------------------------------------------------------
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;
}
Пример #18
0
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)
}
Пример #19
0
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();

}
Пример #20
0
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-----
}
Пример #21
0
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);
}
Пример #22
0
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);
}
Пример #23
0
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);
			}
		}
	}

}
Пример #24
0
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();
}
Пример #25
0
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);
        }
    }
}
Пример #26
0
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();

}
Пример #27
0
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);
	
		}

	}
}
Пример #28
0
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();
}
Пример #29
0
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);
			}
		}
	}
}