Esempio n. 1
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();
}
Esempio n. 2
0
	DynamicsWorld::DynamicsWorld()
	{
		m_threadSupportSolver = 0;
		m_threadSupportCollision = 0;
		int maxNumOutstandingTasks = std::thread::hardware_concurrency();
		if (maxNumOutstandingTasks == 0)
			maxNumOutstandingTasks = 4;

		Debug::Log("Hardware Concurrency: " + std::to_string(std::thread::hardware_concurrency()));

		#ifdef SEQUENTIAL
		SequentialThreadSupport::SequentialThreadConstructionInfo colCI("collision", processCollisionTask, createCollisionLocalStoreMemory);
		m_threadSupportCollision = new SequentialThreadSupport(colCI);
		#else
		m_threadSupportCollision = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
			"collision",
			processCollisionTask,
			createCollisionLocalStoreMemory,
			maxNumOutstandingTasks));
		#endif

		///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. 
		btDefaultCollisionConstructionInfo cci;
		cci.m_defaultMaxPersistentManifoldPoolSize = 32768;
		collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(cci);


		///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
		//dispatcher = new btCollisionDispatcher(collisionConfiguration);
		dispatcher = new SpuGatheringCollisionDispatcher(m_threadSupportCollision, maxNumOutstandingTasks, collisionConfiguration);
		softBodyWorldInfo.m_dispatcher = dispatcher;

		///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. 
		overlappingPairCache = new btDbvtBroadphase(); 
		softBodyWorldInfo.m_broadphase = overlappingPairCache;
		
		///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) 
		//solver = new btSequentialImpulseConstraintSolver;
		#ifdef SEQUENTIAL
		solver = new btSequentialImpulseConstraintSolver();
		#else
		m_threadSupportSolver = createSolverThreadSupport(maxNumOutstandingTasks);
		solver = new btParallelConstraintSolver(m_threadSupportSolver);

		//this solver requires the contacts to be in a contiguous pool, so avoid dynamic allocation
		dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION);
		#endif

		dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); // , softBodySolver);

		dynamicsWorld->getSimulationIslandManager()->setSplitIslands(false);
		dynamicsWorld->getSolverInfo().m_numIterations = 4;
		dynamicsWorld->getSolverInfo().m_solverMode = SOLVER_SIMD + SOLVER_USE_WARMSTARTING;//+SOLVER_RANDMIZE_ORDER;

		dynamicsWorld->getDispatchInfo().m_enableSPU = true;

		dynamicsWorld->setGravity(btVector3(0,-9.8f,0));

		softBodyWorldInfo.m_gravity.setValue(0, -9.8f, 0);
		softBodyWorldInfo.m_sparsesdf.Initialize();
	}
void jmePhysicsSpace::createPhysicsSpace(jfloat minX, jfloat minY, jfloat minZ, jfloat maxX, jfloat maxY, jfloat maxZ, jint broadphaseId, jboolean threading) {
    // collision configuration contains default setup for memory, collision setup
    btDefaultCollisionConstructionInfo cci;
    //    if(threading){
    //        cci.m_defaultMaxPersistentManifoldPoolSize = 32768;
    //    }
    collisionConfiguration = new btDefaultCollisionConfiguration(cci);

    btVector3 min = btVector3(minX, minY, minZ);
    btVector3 max = btVector3(maxX, maxY, maxZ);

    // btBroadphaseInterface* broadphase;

    switch (broadphaseId) {
        case 0:
            broadphase = new btSimpleBroadphase();
            break;
        case 1:
            broadphase = new btAxisSweep3(min, max);
            break;
        case 2:
            //TODO: 32bit!
            broadphase = new btAxisSweep3(min, max);
            break;
        case 3:
            broadphase = new btDbvtBroadphase();
            break;
        case 4:
            //            broadphase = new btGpu3DGridBroadphase(
            //                    min, max,
            //                    20, 20, 20,
            //                    10000, 1000, 25);
            break;
    }

    // btCollisionDispatcher* dispatcher;
    // btConstraintSolver* solver;
    // use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
    if (threading) {
        btThreadSupportInterface* dispatchThreads = createDispatchThreadSupport(4);
        dispatcher = new SpuGatheringCollisionDispatcher(dispatchThreads, 4, collisionConfiguration);
        dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION);
    } else {
        dispatcher = new btCollisionDispatcher(collisionConfiguration);
    }

    // the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
    if (threading) {
        btThreadSupportInterface* solverThreads = createSolverThreadSupport(4);
        solver = new btParallelConstraintSolver(solverThreads);
    } else {
        solver = new btSequentialImpulseConstraintSolver;
    }

    //create dynamics world
    btDiscreteDynamicsWorld* world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
    dynamicsWorld = world;
    dynamicsWorld->setWorldUserInfo(this);

    //parallel solver requires the contacts to be in a contiguous pool, so avoid dynamic allocation
    if (threading) {
        world->getSimulationIslandManager()->setSplitIslands(false);
        world->getSolverInfo().m_numIterations = 4;
        world->getSolverInfo().m_solverMode = SOLVER_SIMD + SOLVER_USE_WARMSTARTING; //+SOLVER_RANDMIZE_ORDER;
        world->getDispatchInfo().m_enableSPU = true;
    }
    ghostPairCallback = new btGhostPairCallback();
    broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(ghostPairCallback);

    dynamicsWorld->setGravity(btVector3(0, -9.81f, 0));

    struct jmeFilterCallback : public btOverlapFilterCallback {
        // return true when pairs need collision

        virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy * proxy1) const {
//            bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
//            collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
            bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
            collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
            if (collides) {
                btCollisionObject* co0 = (btCollisionObject*)proxy0->m_clientObject;
                btCollisionObject* co1 = (btCollisionObject*)proxy1->m_clientObject;
                jmeUserPointer *up0 = (jmeUserPointer*)co0 -> getUserPointer(); 
                jmeUserPointer *up1 = (jmeUserPointer*)co1 -> getUserPointer(); 
                if (up0 != NULL && up1 != NULL) {
                    collides = (up0->group & up1->groups) != 0;
                    collides = collides && (up1->group & up0->groups);

                    //add some additional logic here that modified 'collides'
                    return collides;
                }
                return false;
            }
            return collides;
        }
    };
    dynamicsWorld->getPairCache()->setOverlapFilterCallback(new jmeFilterCallback());
    dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::preTickCallback, static_cast<void *> (this), true);
    dynamicsWorld->setInternalTickCallback(&jmePhysicsSpace::postTickCallback, static_cast<void *> (this));
    if (gContactProcessedCallback == NULL) {
        gContactProcessedCallback = &jmePhysicsSpace::contactProcessedCallback;
    }
}