Пример #1
0
void	BasicDemo::initPhysics()
{

#ifdef FORCE_ZAXIS_UP
	m_cameraUp = btVector3(0,0,1);
	m_forwardAxis = 1;
#endif
	
	gContactAddedCallback = CustomMaterialCombinerCallback;

	setTexturing(true);
	setShadows(false);

	setCameraDistance(btScalar(SCALING*20.));
	this->m_azi = 90;

	///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);

#ifdef FORCE_ZAXIS_UP
	m_dynamicsWorld->setGravity(btVector3(0,0,-10));
#else
	m_dynamicsWorld->setGravity(btVector3(0,-10,0));
#endif
	m_dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION+SOLVER_USE_2_FRICTION_DIRECTIONS;
	m_dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;

#if 1
	m_blendReader = new BasicBlendReader(m_dynamicsWorld,this);


	//const char* fileName = "clubsilo_packed.blend";
	const char* fileName = "PhysicsAnimationBakingDemo.blend";
	
	char fullPath[512];
	
	if(!m_blendReader->openFile(fileName))
	{

		sprintf(fullPath,"../../%s",fileName);
		m_blendReader->openFile(fullPath);
		
	}

	if (m_blendReader)
	{
		m_blendReader->convertAllObjects();
	} else
	{
		printf("file not found\n");
	}
#endif

	///create a few basic rigid bodies
#if 0
	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,-60,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);

		//enable custom material callback
		body->setCollisionFlags(body->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

		//add the body to the dynamics world
		m_dynamicsWorld->addRigidBody(body);
	}
#endif

#if 0
	{
		//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 btBoxShape(btVector3(SCALING*.1,SCALING*.1,SCALING*.1));
		btCollisionShape* colShape = new btSphereShape(SCALING*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 = -ARRAY_SIZE_X;
		float start_y = -ARRAY_SIZE_Y;
		float start_z = - ARRAY_SIZE_Z;


		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(1.*SCALING*btVector3(
										2.0*i + start_x,
										2.0*k + start_y,
										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->setContactProcessingThreshold(colShape->getContactBreakingThreshold());
					body->setActivationState(ISLAND_SLEEPING);
					body->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);

				//	m_dynamicsWorld->addRigidBody(body);
					body->setActivationState(ISLAND_SLEEPING);
				}
			}
		}
	}

	btTriangleIndexVertexArray* meshInterface = new btTriangleIndexVertexArray();
	btIndexedMesh indexMesh;
	
	indexMesh.m_numTriangles = BUNNY_NUM_TRIANGLES ;
	indexMesh.m_numVertices = BUNNY_NUM_VERTICES;
	indexMesh.m_vertexBase = (const unsigned char*) &gVerticesBunny[0];
	indexMesh.m_vertexStride = 3*sizeof(REAL);
	indexMesh.m_triangleIndexBase = (const unsigned char*)&gIndicesBunny[0];
	indexMesh.m_triangleIndexStride = 3*sizeof(int);
	meshInterface->addIndexedMesh(indexMesh);
	btBvhTriangleMeshShape* bunny = new btBvhTriangleMeshShape(meshInterface,true);
	bunny->setLocalScaling(btVector3(2,2,2));
	btCollisionObject* obj = new btCollisionObject();
	btTransform tr;
	tr.setIdentity();
	tr.setOrigin(btVector3(0,2,-20));
	obj ->setWorldTransform(tr);
	obj->setCollisionShape(bunny);
	m_dynamicsWorld->addCollisionObject(obj);
#endif

#if 0
	btConvexTriangleMeshShape* convexBun = new btConvexTriangleMeshShape(meshInterface);
	obj = new btCollisionObject();
	tr.setOrigin(btVector3(0,2,-14));
	obj ->setWorldTransform(tr);
	obj->setCollisionShape(convexBun);
	m_dynamicsWorld->addCollisionObject(obj);
#endif

#if 0
	btConvexTriangleMeshShape* convexBun = new btConvexTriangleMeshShape(meshInterface);
	obj = new btCollisionObject();
	tr.setOrigin(btVector3(0,2,-14));
	obj ->setWorldTransform(tr);
	obj->setCollisionShape(convexBun);
	m_dynamicsWorld->addCollisionObject(obj);


	
	
	//btDiscreteCollisionDetectorInterface::ClosestPointInput input;
	//input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds
	//input.m_transformA = sphereObj->getWorldTransform();
	//input.m_transformB = triObj->getWorldTransform();
	//bool swapResults = m_swapped;
	//detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults);


	
	for (int v=1;v<10;v++)
	{

		float VOXEL_SIZE = VOXEL_SIZE_START * v;
		
		btVoxelizationCallback voxelizationCallback;

		btCompoundShape* compoundBunny = new btCompoundShape();
		voxelizationCallback.m_bunnyCompound = compoundBunny;
		voxelizationCallback.m_sphereChildShape = new btSphereShape(VOXEL_SIZE);

	#if 1
		float start_x = -ARRAY_SIZE_X;
			float start_y = -ARRAY_SIZE_Y;
			float start_z = - ARRAY_SIZE_Z;


		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++)
				{
					btVector3 pos =VOXEL_SIZE*SCALING*btVector3(
										2.0*i + start_x,
										2.0*k + start_y,
										2.0*j + start_z);
					btVector3 aabbMin(pos-btVector3(VOXEL_SIZE,VOXEL_SIZE,VOXEL_SIZE));
					btVector3 aabbMax(pos+btVector3(VOXEL_SIZE,VOXEL_SIZE,VOXEL_SIZE));
					voxelizationCallback.m_curSpherePos = pos;
					voxelizationCallback.m_oncePerSphere = false;

					bunny->processAllTriangles(&voxelizationCallback,aabbMin,aabbMax);
				}
			}
		}
		
		//btCollisionObject* obj2 = new btCollisionObject();
		//obj2->setCollisionShape(compoundBunny);
		//m_dynamicsWorld->addCollisionObject(obj2);

		btVector3 localInertia;
		compoundBunny->calculateLocalInertia(1,localInertia);
		btRigidBody* body = new btRigidBody(1,0,compoundBunny,localInertia);
		//m_dynamicsWorld->addRigidBody(body);
		btTransform start;
		start.setIdentity();
		start.setOrigin(btVector3(0,2,-12+6*v));
		localCreateRigidBody(1.,start,compoundBunny);
		printf("compoundBunny with %d spheres\n",compoundBunny->getNumChildShapes());

	#endif
}
#endif


	clientResetScene();
}
Пример #2
0
void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
{
	// Draw a small simplex at the center of the object
	getDebugDrawer()->drawTransform(worldTransform,1);

	if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
	{
		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
		for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
		{
			btTransform childTrans = compoundShape->getChildTransform(i);
			const btCollisionShape* colShape = compoundShape->getChildShape(i);
			debugDrawObject(worldTransform*childTrans,colShape,color);
		}

	} else
	{
		switch (shape->getShapeType())
		{

		case BOX_SHAPE_PROXYTYPE:
			{
				const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
				btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
				getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
				break;
			}

		case SPHERE_SHAPE_PROXYTYPE:
			{
				const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
				btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin

				getDebugDrawer()->drawSphere(radius, worldTransform, color);
				break;
			}
		case MULTI_SPHERE_SHAPE_PROXYTYPE:
			{
				const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);

				btTransform childTransform;
				childTransform.setIdentity();

				for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
				{
					childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
					getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
				}

				break;
			}
		case CAPSULE_SHAPE_PROXYTYPE:
			{
				const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);

				btScalar radius = capsuleShape->getRadius();
				btScalar halfHeight = capsuleShape->getHalfHeight();

				int upAxis = capsuleShape->getUpAxis();
				getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
				break;
			}
		case CONE_SHAPE_PROXYTYPE:
			{
				const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
				btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
				btScalar height = coneShape->getHeight();//+coneShape->getMargin();

				int upAxis= coneShape->getConeUpIndex();
				getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
				break;

			}
		case CYLINDER_SHAPE_PROXYTYPE:
			{
				const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
				int upAxis = cylinder->getUpAxis();
				btScalar radius = cylinder->getRadius();
				btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
				getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
				break;
			}

		case STATIC_PLANE_PROXYTYPE:
			{
				const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
				btScalar planeConst = staticPlaneShape->getPlaneConstant();
				const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
				getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
				break;

			}
		default:
			{

				if (shape->isConcave())
				{
					btConcaveShape* concaveMesh = (btConcaveShape*) shape;

					///@todo pass camera, for some culling? no -> we are not a graphics lib
					btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
					btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));

					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
					concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);

				}

				if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
				{
					btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
					//todo: pass camera for some culling			
					btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
					btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
					//DebugDrawcallback drawCallback;
					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
					convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
				}


				/// for polyhedral shapes
				if (shape->isPolyhedral())
				{
					btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;

					int i;
					for (i=0;i<polyshape->getNumEdges();i++)
					{
						btVector3 a,b;
						polyshape->getEdge(i,a,b);
						btVector3 wa = worldTransform * a;
						btVector3 wb = worldTransform * b;
						getDebugDrawer()->drawLine(wa,wb,color);

					}


				}
			}
		}
	}
}
Пример #3
0
int		CLPhysicsDemo::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userIndex)
{
	btVector3 aabbMin(0,0,0),aabbMax(0,0,0);
	if (collidableIndex>=0)
	{
		btAABBHost hostLocalAabbMin = m_data->m_localShapeAABBCPU->at(collidableIndex*2);
		btAABBHost hostLocalAabbMax = m_data->m_localShapeAABBCPU->at(collidableIndex*2+1);
		btVector3 localAabbMin(hostLocalAabbMin.fx,hostLocalAabbMin.fy,hostLocalAabbMin.fz);
		btVector3 localAabbMax(hostLocalAabbMax.fx,hostLocalAabbMax.fy,hostLocalAabbMax.fz);
		
		btScalar margin = 0.01f;
		btTransform t;
		t.setIdentity();
		t.setOrigin(btVector3(position[0],position[1],position[2]));
		t.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3]));
		
		btTransformAabb(localAabbMin,localAabbMax, margin,t,aabbMin,aabbMax);

		//(position[0],position[0],position[0]);

		
		//aabbMin -= btVector3(400.f,410.f,400.f);
		//aabbMax += btVector3(400.f,410.f,400.f);

	
		//btBroadphaseProxy* proxy = m_data->m_Broadphase->createProxy(aabbMin,aabbMax,collisionShapeIndex,userPointer,1,1,0,0);//m_dispatcher);
	
		if (useSapGpuBroadphase)
		{
			if (mass)
			{
				m_data->m_BroadphaseSap->createProxy(aabbMin,aabbMax,userIndex,1,1);//m_dispatcher);
			} else
			{
				m_data->m_BroadphaseSap->createLargeProxy(aabbMin,aabbMax,userIndex,1,1);//m_dispatcher);	
			}
		}
		else
		{
			void* userPtr = (void*)userIndex;
			m_data->m_BroadphaseGrid->createProxy(aabbMin,aabbMax,collidableIndex,userPtr ,1,1);//m_dispatcher);
		}
	}
			
	bool writeToGpu = false;
	int bodyIndex = -1;

	m_data->m_linVelHost.push_back(btVector3(0,0,0));
	m_data->m_angVelHost.push_back(btVector3(0,0,0));
	m_data->m_bodyTimesHost.push_back(0.f);
	
	

	if (m_narrowphaseAndSolver)
	{
		//bodyIndex = m_narrowphaseAndSolver->registerRigidBody(collisionShapeIndex,CollisionShape::SHAPE_CONVEX_HEIGHT_FIELD,mass,position,orientation,&aabbMin.getX(),&aabbMax.getX(),writeToGpu);
		bodyIndex = m_narrowphaseAndSolver->registerRigidBody(collidableIndex,mass,position,orientation,&aabbMin.getX(),&aabbMax.getX(),writeToGpu);
		

	}

	if (mass>0.f)
		m_numDynamicPhysicsInstances++;

	m_numPhysicsInstances++;
	return bodyIndex;
}
Пример #4
0
void	BtApplication::renderscene(int pass)
{
	btScalar	m[16];
	btMatrix3x3	rot;rot.setIdentity();
	const int	numObjects=m_dynamicsWorld->getNumCollisionObjects();
	btVector3 wireColor(1,0,0);
	for(int i=0;i<numObjects;i++)
	{
		btCollisionObject*	colObj=m_dynamicsWorld->getCollisionObjectArray()[i];
		btRigidBody*		body=btRigidBody::upcast(colObj);
		if(body&&body->getMotionState())
		{
			btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
			myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m);
			rot=myMotionState->m_graphicsWorldTrans.getBasis();
		}
		else
		{
			colObj->getWorldTransform().getOpenGLMatrix(m);
			rot=colObj->getWorldTransform().getBasis();
		}
		btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation
		if(i&1) wireColor=btVector3(0.f,0.0f,1.f);
		///color differently for active, sleeping, wantsdeactivation states
		if (colObj->getActivationState() == 1) //active
		{
			if (i & 1)
			{
				wireColor += btVector3 (1.f,0.f,0.f);
			}
			else
			{			
				wireColor += btVector3 (.5f,0.f,0.f);
			}
		}
		if(colObj->getActivationState()==2) //ISLAND_SLEEPING
		{
			if(i&1)
			{
				wireColor += btVector3 (0.f,1.f, 0.f);
			}
			else
			{
				wireColor += btVector3 (0.f,0.5f,0.f);
			}
		}

		btVector3 aabbMin(0,0,0),aabbMax(0,0,0);
		//m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax);
		
		aabbMin-=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
		aabbMax+=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
//		printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ());
//		printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ());
//		m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1));


		if (!(getDebugMode()& btIDebugDraw::DBG_DrawWireframe))
		{
			switch(pass)
			{
			case	0:	m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),aabbMin,aabbMax);break;
			case	1:	m_shapeDrawer->drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break;
			case	2:	m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor*btScalar(0.3),0,aabbMin,aabbMax);break;
			}
		}
	}
}
Пример #5
0
void render(void)
{
	render_begin();

	const PfxVector3 colorWhite(1.0f);
	const PfxVector3 colorGray(0.7f);

	for(int i=0;i<physics_get_num_rigidbodies();i++) {
		const PfxRigidState &state = physics_get_state(i);
		const PfxCollidable &coll = physics_get_collidable(i);

		PfxVector3 color = state.isAsleep()?colorGray:colorWhite;

		PfxTransform3 rbT(state.getOrientation(), state.getPosition());

		PfxShapeIterator itrShape(coll);
		for(int j=0;j<coll.getNumShapes();j++,++itrShape) {
			const PfxShape &shape = *itrShape;
			PfxTransform3 offsetT = shape.getOffsetTransform();
			PfxTransform3 worldT = rbT * offsetT;

			switch(shape.getType()) {
				case kPfxShapeSphere:
				render_sphere(
					worldT,
					color,
					PfxFloatInVec(shape.getSphere().m_radius));
				break;

				case kPfxShapeBox:
				render_box(
					worldT,
					color,
					shape.getBox().m_half);
				break;

				case kPfxShapeCapsule:
				render_capsule(
					worldT,
					color,
					PfxFloatInVec(shape.getCapsule().m_radius),
					PfxFloatInVec(shape.getCapsule().m_halfLen));
				break;

				case kPfxShapeCylinder:
				render_cylinder(
					worldT,
					color,
					PfxFloatInVec(shape.getCylinder().m_radius),
					PfxFloatInVec(shape.getCylinder().m_halfLen));
				break;

				case kPfxShapeConvexMesh:
				render_mesh(
					worldT,
					color,
					convexMeshId);
				break;

				case kPfxShapeLargeTriMesh:
				render_mesh(
					worldT,
					color,
					landscapeMeshId);
				break;

				default:
				break;
			}
		}
	}

	render_debug_begin();
	
	#ifdef ENABLE_DEBUG_DRAW_CONTACT
	for(int i=0;i<physics_get_num_contacts();i++) {
		const PfxContactManifold &contact = physics_get_contact(i);
		const PfxRigidState &stateA = physics_get_state(contact.getRigidBodyIdA());
		const PfxRigidState &stateB = physics_get_state(contact.getRigidBodyIdB());

		for(int j=0;j<contact.getNumContacts();j++) {
			const PfxContactPoint &cp = contact.getContactPoint(j);
			PfxVector3 pA = stateA.getPosition()+rotate(stateA.getOrientation(),pfxReadVector3(cp.m_localPointA));

			render_debug_point(pA,PfxVector3(0,0,1));
		}
	}
	#endif
	
	#ifdef ENABLE_DEBUG_DRAW_AABB
	for(int i=0;i<physics_get_num_rigidbodies();i++) {
		const PfxRigidState &state = physics_get_state(i);
		const PfxCollidable &coll = physics_get_collidable(i);

		PfxVector3 center = state.getPosition() + coll.getCenter();
		PfxVector3 half = absPerElem(PfxMatrix3(state.getOrientation())) * coll.getHalf();
		
		render_debug_box(center,half,PfxVector3(1,0,0));
	}
	#endif

	#ifdef ENABLE_DEBUG_DRAW_ISLAND
	const PfxIsland *island = physics_get_islands();
	if(island) {
		for(PfxUInt32 i=0;i<pfxGetNumIslands(island);i++) {
			PfxIslandUnit *islandUnit = pfxGetFirstUnitInIsland(island,i);
			PfxVector3 aabbMin(SCE_PFX_FLT_MAX);
			PfxVector3 aabbMax(-SCE_PFX_FLT_MAX);
			for(;islandUnit!=NULL;islandUnit=pfxGetNextUnitInIsland(islandUnit)) {
				const PfxRigidState &state = physics_get_state(pfxGetUnitId(islandUnit));
				const PfxCollidable &coll = physics_get_collidable(pfxGetUnitId(islandUnit));
				PfxVector3 center = state.getPosition() + coll.getCenter();
				PfxVector3 half = absPerElem(PfxMatrix3(state.getOrientation())) * coll.getHalf();
				aabbMin = minPerElem(aabbMin,center-half);
				aabbMax = maxPerElem(aabbMax,center+half);
			}
			render_debug_box((aabbMax+aabbMin)*0.5f,(aabbMax-aabbMin)*0.5f,PfxVector3(0,1,0));
		}
	}
	#endif

	render_debug_end();

	render_end();
}
Пример #6
0
void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax)
{
    m_useQuantization = useQuantizedAabbCompression;


    // NodeArray    triangleNodes;

    struct    NodeTriangleCallback : public btInternalTriangleIndexCallback
    {

        NodeArray&    m_triangleNodes;

        NodeTriangleCallback& operator=(NodeTriangleCallback& other)
        {
            m_triangleNodes = other.m_triangleNodes;
            return *this;
        }

        NodeTriangleCallback(NodeArray&    triangleNodes)
            :m_triangleNodes(triangleNodes)
        {
        }

        virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
        {
            btOptimizedBvhNode node;
            btVector3    aabbMin,aabbMax;
            aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
            aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
            aabbMin.setMin(triangle[0]);
            aabbMax.setMax(triangle[0]);
            aabbMin.setMin(triangle[1]);
            aabbMax.setMax(triangle[1]);
            aabbMin.setMin(triangle[2]);
            aabbMax.setMax(triangle[2]);

            //with quantization?
            node.m_aabbMinOrg = aabbMin;
            node.m_aabbMaxOrg = aabbMax;

            node.m_escapeIndex = -1;

            //for child nodes
            node.m_subPart = partId;
            node.m_triangleIndex = triangleIndex;
            m_triangleNodes.push_back(node);
        }
    };
    struct    QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback
    {
        QuantizedNodeArray&    m_triangleNodes;
        const btQuantizedBvh* m_optimizedTree; // for quantization

        QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other)
        {
            m_triangleNodes = other.m_triangleNodes;
            m_optimizedTree = other.m_optimizedTree;
            return *this;
        }

        QuantizedNodeTriangleCallback(QuantizedNodeArray&    triangleNodes,const btQuantizedBvh* tree)
            :m_triangleNodes(triangleNodes),m_optimizedTree(tree)
        {
        }

        virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
        {
            // The partId and triangle index must fit in the same (positive) integer
            btAssert(partId < (1<<MAX_NUM_PARTS_IN_BITS));
            btAssert(triangleIndex < (1<<(31-MAX_NUM_PARTS_IN_BITS)));
            //negative indices are reserved for escapeIndex
            btAssert(triangleIndex>=0);

            btQuantizedBvhNode node;
            btVector3    aabbMin,aabbMax;
            aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
            aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
            aabbMin.setMin(triangle[0]);
            aabbMax.setMax(triangle[0]);
            aabbMin.setMin(triangle[1]);
            aabbMax.setMax(triangle[1]);
            aabbMin.setMin(triangle[2]);
            aabbMax.setMax(triangle[2]);

            //PCK: add these checks for zero dimensions of aabb
            const btScalar MIN_AABB_DIMENSION = btScalar(0.002);
            const btScalar MIN_AABB_HALF_DIMENSION = btScalar(0.001);
            if (aabbMax.x() - aabbMin.x() < MIN_AABB_DIMENSION)
            {
                aabbMax.setX(aabbMax.x() + MIN_AABB_HALF_DIMENSION);
                aabbMin.setX(aabbMin.x() - MIN_AABB_HALF_DIMENSION);
            }
            if (aabbMax.y() - aabbMin.y() < MIN_AABB_DIMENSION)
            {
                aabbMax.setY(aabbMax.y() + MIN_AABB_HALF_DIMENSION);
                aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION);
            }
            if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION)
            {
                aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION);
                aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION);
            }

            m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0);
            m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1);

            node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;

            m_triangleNodes.push_back(node);
        }
    };



    int numLeafNodes = 0;


    if (m_useQuantization)
    {

        //initialize quantization values
        setQuantizationValues(bvhAabbMin,bvhAabbMax);

        QuantizedNodeTriangleCallback    callback(m_quantizedLeafNodes,this);


        triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax);

        //now we have an array of leafnodes in m_leafNodes
        numLeafNodes = m_quantizedLeafNodes.size();


        m_quantizedContiguousNodes.resize(2*numLeafNodes);


    } else
    {
        NodeTriangleCallback    callback(m_leafNodes);

        btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
        btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));

        triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);

        //now we have an array of leafnodes in m_leafNodes
        numLeafNodes = m_leafNodes.size();

        m_contiguousNodes.resize(2*numLeafNodes);
    }

    m_curNodeIndex = 0;

    buildTree(0,numLeafNodes);

    ///if the entire tree is small then subtree size, we need to create a header info for the tree
    if(m_useQuantization && !m_SubtreeHeaders.size())
    {
        btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
        subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
        subtree.m_rootNodeIndex = 0;
        subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
    }

    //PCK: update the copy of the size
    m_subtreeHeaderCount = m_SubtreeHeaders.size();

    //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
    m_quantizedLeafNodes.clear();
    m_leafNodes.clear();
}
//--------------------------------------------------------------
void ofxBulletTriMeshShape::create( btDiscreteDynamicsWorld* a_world, ofMesh& aMesh, btTransform &a_bt_tr, float a_mass, glm::vec3 aAAbbMin, glm::vec3 aAAbbMax ) {
    if( aMesh.getMode() != OF_PRIMITIVE_TRIANGLES ) {
        ofLogWarning() << " ofxBulletTriMeshShape :: create : mesh must be using triangles, not creating!!" << endl;
        return;
    }
    if( aMesh.getNumIndices() < 3 ) {
        ofLogWarning() << " ofxBulletTriMeshShape :: create : mesh must have indices, not creating!" << endl;
        return;
    }
    
    
    if( !_bInited || _shape == NULL ) {
        int vertStride  = sizeof(btVector3);
        int indexStride = 3*sizeof(int);
        
        totalVerts    = (int)aMesh.getNumVertices();
        totalIndices  = (int)aMesh.getNumIndices();
        
        const int totalTriangles = totalIndices / 3;
        
        if( bullet_indices != NULL ) {
            removeShape();
        }
        if( bullet_vertices != NULL ) {
            removeShape();
        }
        if( bullet_indexVertexArrays != NULL ) {
            removeShape();
        }
        if( _shape != NULL ) {
            removeShape();
        }
        
        bullet_vertices   = new btVector3[ totalVerts ];
        bullet_indices    = new int[ totalIndices ];
        
        auto& tverts = aMesh.getVertices();
        auto& tindices = aMesh.getIndices();
        
        for( int i = 0; i < totalVerts; i++ ) {
            bullet_vertices[i].setValue( tverts[i].x, tverts[i].y, tverts[i].z );
        }
        for( int i = 0; i < totalIndices; i++ ) {
            bullet_indices[i] = (int)tindices[i];
        }
        
        bullet_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, bullet_indices, indexStride,
                                                                  totalVerts, (btScalar*) &bullet_vertices[0].x(), vertStride);
        
        
//        if you are having trouble with objects falling through, try passing in smaller or larger aabbMin and aabbMax
//        to something closer to the size of your object //
//        btVector3 aabbMin(-10000,-10000,-10000),aabbMax(10000,10000,10000);
        if( aAAbbMin.length() > 0 && aAAbbMax.length() > 0 ) {
            btVector3 aabbMin( aAAbbMin.x, aAAbbMin.y, aAAbbMin.z );
            btVector3 aabbMax( aAAbbMax.x, aAAbbMax.y, aAAbbMax.z );
            _shape  = new btBvhTriangleMeshShape(bullet_indexVertexArrays, true, aabbMin, aabbMax );
        } else {
            _shape  = new btBvhTriangleMeshShape(bullet_indexVertexArrays, true, true );
        }
	}
    
    ofxBulletRigidBody::create( a_world, _shape, a_bt_tr, a_mass );
    
    
    createInternalUserData();
    updateMesh( a_world, aMesh );
}
Пример #8
0
void	InternalEdgeDemo::initPhysics()
{
	
	setTexturing(true);
	setShadows(false);//true);

	#define TRISIZE 10.f

     gContactAddedCallback = CustomMaterialCombinerCallback;

#define USE_TRIMESH_SHAPE 1
#ifdef USE_TRIMESH_SHAPE

	int vertStride = sizeof(btVector3);
	int indexStride = 3*sizeof(int);

	
	const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1);

	gVertices = new btVector3[totalVerts];
	gIndices = new int[totalTriangles*3];

	int i;


	setVertexPositions(waveheight,0.f);
	
	
	//gVertices[1].setY(21.1);
	//gVertices[1].setY(121.1);
	gVertices[1].setY(.1f);

#ifdef ROTATE_GROUND
	//gVertices[1].setY(-1.1);
#else
	//gVertices[1].setY(0.1);
	//gVertices[1].setY(-0.1);
	//gVertices[1].setY(-20.1);
	//gVertices[1].setY(-20);
#endif
	
	int index=0;
	for ( i=0;i<NUM_VERTS_X-1;i++)
	{
		for (int j=0;j<NUM_VERTS_Y-1;j++)
		{

#ifdef SWAP_WINDING
#ifdef SHIFT_INDICES
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = j*NUM_VERTS_X+i+1;
			
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			
#else
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = j*NUM_VERTS_X+i+1;
			gIndices[index++] = j*NUM_VERTS_X+i;

			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = j*NUM_VERTS_X+i;
#endif //SHIFT_INDICES
#else //SWAP_WINDING

#ifdef SHIFT_INDICES
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = j*NUM_VERTS_X+i+1;

#ifdef TEST_INCONSISTENT_WINDING
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;

#else //TEST_INCONSISTENT_WINDING
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
#endif //TEST_INCONSISTENT_WINDING
			
			
			
#else //SHIFT_INDICES
			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = j*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;

			gIndices[index++] = j*NUM_VERTS_X+i;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
			gIndices[index++] = (j+1)*NUM_VERTS_X+i;
#endif //SHIFT_INDICES

#endif //SWAP_WINDING

			
		}
	}

	m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles,
		gIndices,
		indexStride,
		totalVerts,(btScalar*) &gVertices[0].x(),vertStride);

	
	bool useQuantizedAabbCompression = true;

//comment out the next line to read the BVH from disk (first run the demo once to create the BVH)
#define SERIALIZE_TO_DISK 1
#ifdef SERIALIZE_TO_DISK
	btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
	
	trimeshShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax);
	m_collisionShapes.push_back(trimeshShape);
	
	
	///we can serialize the BVH data 
	void* buffer = 0;
	int numBytes = trimeshShape->getOptimizedBvh()->calculateSerializeBufferSize();
	buffer = btAlignedAlloc(numBytes,16);
	bool swapEndian = false;
	trimeshShape->getOptimizedBvh()->serialize(buffer,numBytes,swapEndian);
#ifdef __QNX__
	FILE* file = fopen("app/native/bvh.bin","wb");
#else
	FILE* file = fopen("bvh.bin","wb");
#endif
	fwrite(buffer,1,numBytes,file);
	fclose(file);
	btAlignedFree(buffer);
	


#else

	trimeshShape  = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false);

	char* fileName = "bvh.bin";

#ifdef __QNX__
	char* fileName = "app/native/bvh.bin";
#else
	char* fileName = "bvh.bin";
#endif
	int size=0;
	btOptimizedBvh* bvh = 0;

	if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) {        /* File operations denied? ok, just close and return failure */
		printf("Error: cannot get filesize from %s\n", fileName);
		exit(0);
	} else
	{

		fseek(file, 0, SEEK_SET);

		int buffersize = size+btOptimizedBvh::getAlignmentSerializationPadding();

		void* buffer = btAlignedAlloc(buffersize,16);
		int read = fread(buffer,1,size,file);
		fclose(file);
		bool swapEndian = false;
		bvh = btOptimizedBvh::deSerializeInPlace(buffer,buffersize,swapEndian);
	}

	trimeshShape->setOptimizedBvh(bvh);

#endif

	btCollisionShape* groundShape = trimeshShape;

	btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
	

	btGenerateInternalEdgeInfo(trimeshShape,triangleInfoMap);
	


#else
	btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50));

	m_collisionShapes.push_back(groundShape);

#endif //USE_TRIMESH_SHAPE

	m_collisionConfiguration = new btDefaultCollisionConfiguration();
	

	m_dispatcher = new	btCollisionDispatcher(m_collisionConfiguration);


	
	m_broadphase = new btDbvtBroadphase();
	m_solver = new btSequentialImpulseConstraintSolver();
	m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
/*
m_dynamicsWorld->getSolverInfo().m_splitImpulse = true;
	m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = 1e30f;
	m_dynamicsWorld->getSolverInfo().m_maxErrorReduction = 1e30f;
	m_dynamicsWorld->getSolverInfo().m_erp  =1.f;
	m_dynamicsWorld->getSolverInfo().m_erp2 = 1.f;
*/

	m_dynamicsWorld->setGravity(btVector3(0,-10,0));

	
	float mass = 0.f;
	btTransform	startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0,-2,0));


	btConvexHullShape* colShape = new btConvexHullShape();
	for (int i=0;i<TaruVtxCount;i++)
	{
		btVector3 vtx(TaruVtx[i*3],TaruVtx[i*3+1],TaruVtx[i*3+2]);
		colShape->addPoint(vtx);
	}
	//this will enable polyhedral contact clipping, better quality, slightly slower
	colShape->initializePolyhedralFeatures();

	//the polyhedral contact clipping can use either GJK or SAT test to find the separating axis
	m_dynamicsWorld->getDispatchInfo().m_enableSatConvex=false;

	m_collisionShapes.push_back(colShape);

	{
		for (int i=0;i<1;i++)
		{
			startTransform.setOrigin(btVector3(-10.f+i*3.f,2.2f+btScalar(i)*0.1f,-1.3f));
			btRigidBody* body = localCreateRigidBody(10, startTransform,colShape);
			body->setActivationState(DISABLE_DEACTIVATION);
			body->setLinearVelocity(btVector3(0,0,-1));
			//body->setContactProcessingThreshold(0.f);
		}
	}
	{
		btBoxShape* colShape = new btBoxShape(btVector3(1,1,1));
		colShape->initializePolyhedralFeatures();
		m_collisionShapes.push_back(colShape);
		startTransform.setOrigin(btVector3(-16.f+i*3.f,1.f+btScalar(i)*0.1f,-1.3f));
		btRigidBody* body = localCreateRigidBody(10, startTransform,colShape);
		body->setActivationState(DISABLE_DEACTIVATION);
		body->setLinearVelocity(btVector3(0,0,-1));
	}

	startTransform.setIdentity();
#ifdef ROTATE_GROUND
	btQuaternion orn(btVector3(0,0,1),SIMD_PI);
	startTransform.setOrigin(btVector3(-20,0,0));
	startTransform.setRotation(orn);
#endif //ROTATE_GROUND

	staticBody = localCreateRigidBody(mass, startTransform,groundShape);
	//staticBody->setContactProcessingThreshold(-0.031f);
	staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);//STATIC_OBJECT);

	//enable custom material callback
	staticBody->setCollisionFlags(staticBody->getCollisionFlags()  | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

	getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
	setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText+btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints);


#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
	btSetDebugDrawer(&gDebugDrawer);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW

	
}
Пример #9
0
void InternalEdgeDemo::clientMoveAndDisplay()
{
	 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

	float dt = getDeltaTimeMicroseconds() * 0.000001f;

	if (m_animatedMesh)
	{
		static float offset=0.f;
		offset+=0.01f;

	//	setVertexPositions(waveheight,offset);
#if 0 ///not currently supported, we need to update the btInternalTriangleInfoMap
		int i;
		int j;
		btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
		btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);

		for ( i=NUM_VERTS_X/2-3;i<NUM_VERTS_X/2+2;i++)
		{
			for (j=NUM_VERTS_X/2-3;j<NUM_VERTS_Y/2+2;j++)
			{
			
			aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]);
			aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]);
			
				gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
					0.f,
					//waveheight*sinf((float)i+offset)*cosf((float)j+offset),
					(j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
					
			aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]);
			aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]);

			}
		}
		trimeshShape->partialRefitTree(aabbMin,aabbMax);
#else
		btVector3 aabbMin,aabbMax;
		trimeshShape->getMeshInterface()->calculateAabbBruteForce(aabbMin,aabbMax);
		trimeshShape->refitTree(aabbMin,aabbMax);
	
#endif

		
		//for debugging: clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation.
		//m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
	}



	m_dynamicsWorld->stepSimulation(dt);
	///enable one of the following to debug (render debug lines each frame)
	//m_dynamicsWorld->stepSimulation(1./800.,0);
	//m_dynamicsWorld->stepSimulation(1./60.,100,1./800.);
	//m_dynamicsWorld->stepSimulation(1./60.,0);

	
	int lineWidth=450;
	int xStart = m_glutScreenWidth - lineWidth;
	int yStart = 20;

 #ifndef __QNX__
	if((getDebugMode() & btIDebugDraw::DBG_DrawText)!=0)
	{
		setOrthographicProjection();
		glDisable(GL_LIGHTING);
		glColor3f(0, 0, 0);
		char buf[124];
		
		glRasterPos3f(xStart, yStart, 0);
		if (enable)
		{
			sprintf(buf,"InternalEdgeUtility enabled");
		} else
		{
			sprintf(buf,"InternalEdgeUtility disabled");
		}
		GLDebugDrawString(xStart,20,buf);
		yStart+=20;
		glRasterPos3f(xStart, yStart, 0);
		sprintf(buf,"Press 'n' to toggle InternalEdgeUtility");
		yStart+=20;
		GLDebugDrawString(xStart,yStart,buf);
		glRasterPos3f(xStart, yStart, 0);
		
		resetPerspectiveProjection();
		glEnable(GL_LIGHTING);
	}
#endif
	
	renderme();

	//optional but useful: debug drawing
	m_dynamicsWorld->debugDrawWorld();


    glFlush();
    swapBuffers();

}
Пример #10
0
void InitShaders()
{
	
	btOverlappingPairCache* overlappingPairCache=0;
	int maxObjects = btMax(256,NUM_OBJECTS);
#ifdef	USE_NEW
	int maxPairsSmallProxy = 32;

	sBroadphase = new btGridBroadphaseCl(overlappingPairCache,btVector3(4.f, 4.f, 4.f), 128, 128, 128,maxObjects, maxObjects, maxPairsSmallProxy, 100.f, 128,
		g_cxMainContext ,g_device,g_cqCommandQue, g_deviceCL);
#else
	sBroadphase = new btGpu3DGridBroadphase(btVector3(2.f, 2.f, 2.f), 32, 32, 32,maxObjects, maxObjects, 64, 100.f, 64);
#endif



//	sBroadphase = new bt3dGridBroadphaseOCL(overlappingPairCache,btVector3(10.f, 10.f, 10.f), 32, 32, 32,NUM_OBJECTS, NUM_OBJECTS, 64, 100.f, 16,
//		g_cxMainContext ,g_device,g_cqCommandQue);



	bool loadFromFile = false;
	instancingShader = gltLoadShaderPair("instancing.vs","instancing.fs", loadFromFile);

	glLinkProgram(instancingShader);
	glUseProgram(instancingShader);
	angle_loc = glGetUniformLocation(instancingShader, "angle");
	ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");
	ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");
	uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");

	GLuint offset = 0;


	glGenBuffers(1, &cube_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);

	instance_positions_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_quaternion_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_colors_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_scale_ptr = (GLfloat*)new float[NUM_OBJECTS*3];

	

	int index=0;
	for (int i=0;i<NUM_OBJECTS_X;i++)
	{
		for (int j=0;j<NUM_OBJECTS_Y;j++)
		{
			for (int k=0;k<NUM_OBJECTS_Z;k++)
			{
				instance_positions_ptr[index*4]=(i*X_GAP-NUM_OBJECTS_X/2);
				instance_positions_ptr[index*4+1]=(j*Y_GAP-NUM_OBJECTS_Y/2);
				instance_positions_ptr[index*4+2]=(k*Z_GAP-NUM_OBJECTS_Z/2)+(j&1);
				
				instance_positions_ptr[index*4+3]=1;

				int shapeType =0;
				void* userPtr = 0;
				btVector3 aabbMin(
					instance_positions_ptr[index*4],
					instance_positions_ptr[index*4+1],
					instance_positions_ptr[index*4+2]);
				btVector3 aabbMax = aabbMin;
				aabbMin -= btVector3(1.f,1.f,1.f);
				aabbMax += btVector3(1.f,1.f,1.f);

				void* myptr = (void*)index;//0;//&mBoxes[i]
				btBroadphaseProxy* proxy = sBroadphase->createProxy(aabbMin,aabbMax,shapeType,myptr,1,1,0,0);//m_dispatcher);
				proxyArray.push_back(proxy);

				instance_quaternion_ptr[index*4]=0;
				instance_quaternion_ptr[index*4+1]=0;
				instance_quaternion_ptr[index*4+2]=0;
				instance_quaternion_ptr[index*4+3]=1;

				instance_colors_ptr[index*4]=j<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+1]=k<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+2]=i<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+3]=1.f;

				instance_scale_ptr[index*3] = 1;
				instance_scale_ptr[index*3+1] = 1;
				instance_scale_ptr[index*3+2] = 1;


				float mass = 1.f;//j? 1.f : 0.f;

				bool writeToGpu = false;
				if (narrowphaseAndSolver)
					narrowphaseAndSolver->registerRigidBody(gShapeIndex,mass,&instance_positions_ptr[index*4],&instance_quaternion_ptr[index*4],writeToGpu);

				index++;
			}
		}
	}

	float posZero[4] = {0,-NUM_OBJECTS_Y/2-1,0,0};
	float ornZero[4] = {0,0,0,1};

	//register a 'plane'
	if (narrowphaseAndSolver)
			narrowphaseAndSolver->registerRigidBody(-1, 0.f, posZero,ornZero,false);

	

	if (narrowphaseAndSolver)
		narrowphaseAndSolver->writeAllBodiesToGpu();


	int size = sizeof(cube_vertices)  + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE+SCALE_BUFFER_SIZE;
	VBOsize = size;

	char* bla = (char*)malloc(size);
	int szc = sizeof(cube_vertices);
	memcpy(bla,&cube_vertices[0],szc);
	memcpy(bla+sizeof(cube_vertices),instance_positions_ptr,POSITION_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE,instance_quaternion_ptr,ORIENTATION_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE,instance_colors_ptr, COLOR_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE,instance_scale_ptr, SCALE_BUFFER_SIZE);

	glBufferData(GL_ARRAY_BUFFER, size, bla, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);

	///initialize parts of the buffer
#ifdef _USE_SUB_DATA
	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube_vertices)+ 16384, bla);//cube_vertices);
#endif

	char* dest=  (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY
	memcpy(dest,cube_vertices,sizeof(cube_vertices));
	//memcpy(dest+sizeof(cube_vertices),instance_colors,sizeof(instance_colors));
	glUnmapBuffer( GL_ARRAY_BUFFER);



	writeTransforms();

	/*
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors), POSITION_BUFFER_SIZE, instance_positions_ptr);
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors)+POSITION_BUFFER_SIZE,ORIENTATION_BUFFER_SIZE , instance_quaternion_ptr);
	*/

	glGenVertexArrays(1, &cube_vao);
	glBindVertexArray(cube_vao);
	glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
	glBindVertexArray(0);

	glGenBuffers(1, &index_vbo);
	int indexBufferSize = sizeof(cube_indices);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSize,cube_indices);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ARRAY_BUFFER,0);
	glBindVertexArray(0);

}
Пример #11
0
int b3GpuNarrowPhase::registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation , const float* aabbMinPtr, const float* aabbMaxPtr,bool writeToGpu)
{
	b3Vector3 aabbMin(aabbMinPtr[0],aabbMinPtr[1],aabbMinPtr[2]);
	b3Vector3 aabbMax (aabbMaxPtr[0],aabbMaxPtr[1],aabbMaxPtr[2]);
	

	if (m_data->m_numAcceleratedRigidBodies >= (m_data->m_config.m_maxConvexBodies))
	{
		b3Error("registerRigidBody: exceeding the number of rigid bodies, %d > %d \n",m_data->m_numAcceleratedRigidBodies,m_data->m_config.m_maxConvexBodies);
		return -1;
	}
    
	m_data->m_bodyBufferGPU->resize(m_data->m_numAcceleratedRigidBodies+1);
    
	b3RigidBodyCL& body = m_data->m_bodyBufferCPU->at(m_data->m_numAcceleratedRigidBodies);
    
	float friction = 1.f;
	float restitution = 0.f;
    
	body.m_frictionCoeff = friction;
	body.m_restituitionCoeff = restitution;
	body.m_angVel.setZero();
	body.m_linVel.setValue(0,0,0);//.setZero();
	body.m_pos.setValue(position[0],position[1],position[2]);
	body.m_quat.setValue(orientation[0],orientation[1],orientation[2],orientation[3]);
	body.m_collidableIdx = collidableIndex;
	if (collidableIndex>=0)
	{
//		body.m_shapeType = m_data->m_collidablesCPU.at(collidableIndex).m_shapeType;
	} else
	{
	//	body.m_shapeType = CollisionShape::SHAPE_PLANE;
		m_planeBodyIndex = m_data->m_numAcceleratedRigidBodies;
	}
	//body.m_shapeType = shapeType;
	
	
	body.m_invMass = mass? 1.f/mass : 0.f;
    
	if (writeToGpu)
	{
		m_data->m_bodyBufferGPU->copyFromHostPointer(&body,1,m_data->m_numAcceleratedRigidBodies);
	}
    
	b3InertiaCL& shapeInfo = m_data->m_inertiaBufferCPU->at(m_data->m_numAcceleratedRigidBodies);
    
	if (mass==0.f)
	{
		if (m_data->m_numAcceleratedRigidBodies==0)
			m_static0Index = 0;
        
		shapeInfo.m_initInvInertia.setValue(0,0,0,0,0,0,0,0,0);
		shapeInfo.m_invInertiaWorld.setValue(0,0,0,0,0,0,0,0,0);
	} else
	{
        
		b3Assert(body.m_collidableIdx>=0);
        
		//approximate using the aabb of the shape
        
		//Aabb aabb = (*m_data->m_shapePointers)[shapeIndex]->m_aabb;
		b3Vector3 halfExtents = (aabbMax-aabbMin);//*0.5f;//fake larger inertia makes demos more stable ;-)
        
		b3Vector3 localInertia;
        
		float lx=2.f*halfExtents[0];
		float ly=2.f*halfExtents[1];
		float lz=2.f*halfExtents[2];
        
		localInertia.setValue( (mass/12.0f) * (ly*ly + lz*lz),
                                   (mass/12.0f) * (lx*lx + lz*lz),
                                   (mass/12.0f) * (lx*lx + ly*ly));
        
		b3Vector3 invLocalInertia;
		invLocalInertia[0] = 1.f/localInertia[0];
		invLocalInertia[1] = 1.f/localInertia[1];
		invLocalInertia[2] = 1.f/localInertia[2];
		invLocalInertia[3] = 0.f;
        
		shapeInfo.m_initInvInertia.setValue(
			invLocalInertia[0],		0,						0,
			0,						invLocalInertia[1],		0,
			0,						0,						invLocalInertia[2]);

		b3Matrix3x3 m (body.m_quat);

		shapeInfo.m_invInertiaWorld = m.scaled(invLocalInertia) * m.transpose();
        
	}
    
	if (writeToGpu)
		m_data->m_inertiaBufferGPU->copyFromHostPointer(&shapeInfo,1,m_data->m_numAcceleratedRigidBodies);
    
    
    
	return m_data->m_numAcceleratedRigidBodies++;
}
Пример #12
0
void InitShaders()
{
	
	btOverlappingPairCache* overlappingPairCache=0;
#ifdef	USE_NEW
	sBroadphase = new btGridBroadphaseCl(overlappingPairCache,btVector3(3.f, 3.f, 3.f), 32, 32, 32,NUM_OBJECTS, NUM_OBJECTS, 64, 100.f, 16,
		g_cxMainContext ,g_device,g_cqCommandQue);
#else
	sBroadphase = new btGpu3DGridBroadphase(btVector3(10.f, 10.f, 10.f), 32, 32, 32,NUM_OBJECTS, NUM_OBJECTS, 64, 100.f, 16);
#endif



//	sBroadphase = new bt3dGridBroadphaseOCL(overlappingPairCache,btVector3(10.f, 10.f, 10.f), 32, 32, 32,NUM_OBJECTS, NUM_OBJECTS, 64, 100.f, 16,
//		g_cxMainContext ,g_device,g_cqCommandQue);



	bool loadFromFile = false;
	instancingShader = gltLoadShaderPair("instancing.vs","instancing.fs", loadFromFile);

	glLinkProgram(instancingShader);
	glUseProgram(instancingShader);
	angle_loc = glGetUniformLocation(instancingShader, "angle");
	ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");
	ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");
	uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");

	GLuint offset = 0;


	glGenBuffers(1, &cube_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);

	instance_positions_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_quaternion_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_colors_ptr = (GLfloat*)new float[NUM_OBJECTS*4];
	instance_scale_ptr = (GLfloat*)new float[NUM_OBJECTS*3];

	int index=0;
	for (int i=0;i<NUM_OBJECTS_X;i++)
	{
		for (int j=0;j<NUM_OBJECTS_Y;j++)
		{
			for (int k=0;k<NUM_OBJECTS_Z;k++)
			{
				instance_positions_ptr[index*4]=-(i-NUM_OBJECTS_X/2)*10;
				instance_positions_ptr[index*4+1]=-(j-NUM_OBJECTS_Y/2)*10;
				instance_positions_ptr[index*4+2]=-(k-NUM_OBJECTS_Z/2)*10;
				instance_positions_ptr[index*4+3]=1;

				int shapeType =0;
				void* userPtr = 0;
				btVector3 aabbMin(
					instance_positions_ptr[index*4],
					instance_positions_ptr[index*4+1],
					instance_positions_ptr[index*4+2]);
				btVector3 aabbMax = aabbMin;
				aabbMin -= btVector3(1,1,1);
				aabbMax += btVector3(1,1,1);

				void* myptr = (void*)index;//0;//&mBoxes[i]
				btBroadphaseProxy* proxy = sBroadphase->createProxy(aabbMin,aabbMax,shapeType,myptr,1,1,0,0);//m_dispatcher);
				proxyArray.push_back(proxy);

				instance_quaternion_ptr[index*4]=0;
				instance_quaternion_ptr[index*4+1]=0;
				instance_quaternion_ptr[index*4+2]=0;
				instance_quaternion_ptr[index*4+3]=1;

				instance_colors_ptr[index*4]=j<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+1]=k<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+2]=i<NUM_OBJECTS_Y/2? 0.5f : 1.f;
				instance_colors_ptr[index*4+3]=1.f;

				instance_scale_ptr[index*3] = 1;
				instance_scale_ptr[index*3+1] = 1;
				instance_scale_ptr[index*3+2] = 1;
				

				index++;
			}
		}
	}

	int size = sizeof(cube_vertices)  + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE+SCALE_BUFFER_SIZE;

	char* bla = (char*)malloc(size);
	int szc = sizeof(cube_vertices);
	memcpy(bla,&cube_vertices[0],szc);
	memcpy(bla+sizeof(cube_vertices),instance_positions_ptr,POSITION_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE,instance_quaternion_ptr,ORIENTATION_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE,instance_colors_ptr, COLOR_BUFFER_SIZE);
	memcpy(bla+sizeof(cube_vertices)+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE,instance_scale_ptr, SCALE_BUFFER_SIZE);

	glBufferData(GL_ARRAY_BUFFER, size, bla, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);

	///initialize parts of the buffer
#ifdef _USE_SUB_DATA
	glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube_vertices)+ 16384, bla);//cube_vertices);
#endif

	char* dest=  (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY
	memcpy(dest,cube_vertices,sizeof(cube_vertices));
	//memcpy(dest+sizeof(cube_vertices),instance_colors,sizeof(instance_colors));
	glUnmapBuffer( GL_ARRAY_BUFFER);



	writeTransforms();

	/*
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors), POSITION_BUFFER_SIZE, instance_positions_ptr);
	glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices) + sizeof(instance_colors)+POSITION_BUFFER_SIZE,ORIENTATION_BUFFER_SIZE , instance_quaternion_ptr);
	*/

	glGenVertexArrays(1, &cube_vao);
	glBindVertexArray(cube_vao);
	glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
	glBindVertexArray(0);

	glGenBuffers(1, &index_vbo);
	int indexBufferSize = sizeof(cube_indices);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSize,cube_indices);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ARRAY_BUFFER,0);
	glBindVertexArray(0);

}
void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
{
	// Draw a small simplex at the center of the object
	{
		btVector3 start = worldTransform.getOrigin();
		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0));
		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0));
		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1));
	}

	if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
	{
		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
		for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
		{
			btTransform childTrans = compoundShape->getChildTransform(i);
			const btCollisionShape* colShape = compoundShape->getChildShape(i);
			debugDrawObject(worldTransform*childTrans,colShape,color);
		}

	} else
	{
		switch (shape->getShapeType())
		{

		case SPHERE_SHAPE_PROXYTYPE:
			{
				const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
				btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
				
				debugDrawSphere(radius, worldTransform, color);
				break;
			}
		case MULTI_SPHERE_SHAPE_PROXYTYPE:
			{
				const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);

				for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
				{
					btTransform childTransform = worldTransform;
					childTransform.getOrigin() += multiSphereShape->getSpherePosition(i);
					debugDrawSphere(multiSphereShape->getSphereRadius(i), childTransform, color);
				}

				break;
			}
		case CAPSULE_SHAPE_PROXYTYPE:
			{
				const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);

				btScalar radius = capsuleShape->getRadius();
				btScalar halfHeight = capsuleShape->getHalfHeight();

				// Draw the ends
				{
					btTransform childTransform = worldTransform;
					childTransform.getOrigin() = worldTransform * btVector3(0,halfHeight,0);
					debugDrawSphere(radius, childTransform, color);
				}

				{
					btTransform childTransform = worldTransform;
					childTransform.getOrigin() = worldTransform * btVector3(0,-halfHeight,0);
					debugDrawSphere(radius, childTransform, color);
				}

				// Draw some additional lines
				btVector3 start = worldTransform.getOrigin();
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(-radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(-radius,-halfHeight,0), color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(radius,halfHeight,0),start+worldTransform.getBasis() * btVector3(radius,-halfHeight,0), color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,-radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,-radius), color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * btVector3(0,halfHeight,radius),start+worldTransform.getBasis() * btVector3(0,-halfHeight,radius), color);

				break;
			}
		case CONE_SHAPE_PROXYTYPE:
			{
				const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
				btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
				btScalar height = coneShape->getHeight();//+coneShape->getMargin();
				btVector3 start = worldTransform.getOrigin();

				int upAxis= coneShape->getConeUpIndex();
				

				btVector3	offsetHeight(0,0,0);
				offsetHeight[upAxis] = height * btScalar(0.5);
				btVector3	offsetRadius(0,0,0);
				offsetRadius[(upAxis+1)%3] = radius;
				btVector3	offset2Radius(0,0,0);
				offset2Radius[(upAxis+2)%3] = radius;

				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color);



				break;

			}
		case CYLINDER_SHAPE_PROXYTYPE:
			{
				const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
				int upAxis = cylinder->getUpAxis();
				btScalar radius = cylinder->getRadius();
				btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
				btVector3 start = worldTransform.getOrigin();
				btVector3	offsetHeight(0,0,0);
				offsetHeight[upAxis] = halfHeight;
				btVector3	offsetRadius(0,0,0);
				offsetRadius[(upAxis+1)%3] = radius;
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
				break;
			}

			case STATIC_PLANE_PROXYTYPE:
				{
					const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
					btScalar planeConst = staticPlaneShape->getPlaneConstant();
					const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
					btVector3 planeOrigin = planeNormal * planeConst;
					btVector3 vec0,vec1;
					btPlaneSpace1(planeNormal,vec0,vec1);
					btScalar vecLen = 100.f;
					btVector3 pt0 = planeOrigin + vec0*vecLen;
					btVector3 pt1 = planeOrigin - vec0*vecLen;
					btVector3 pt2 = planeOrigin + vec1*vecLen;
					btVector3 pt3 = planeOrigin - vec1*vecLen;
					getDebugDrawer()->drawLine(worldTransform*pt0,worldTransform*pt1,color);
					getDebugDrawer()->drawLine(worldTransform*pt2,worldTransform*pt3,color);
					break;

				}
		default:
			{

				if (shape->isConcave())
				{
					btConcaveShape* concaveMesh = (btConcaveShape*) shape;
					
					//todo pass camera, for some culling
					btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
					btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));

					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
					concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);

				}

				if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
				{
					btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
					//todo: pass camera for some culling			
					btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
					btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
					//DebugDrawcallback drawCallback;
					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
					convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
				}


				/// for polyhedral shapes
				if (shape->isPolyhedral())
				{
					btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;

					int i;
					for (i=0;i<polyshape->getNumEdges();i++)
					{
						btPoint3 a,b;
						polyshape->getEdge(i,a,b);
						btVector3 wa = worldTransform * a;
						btVector3 wb = worldTransform * b;
						getDebugDrawer()->drawLine(wa,wb,color);

					}

					
				}
			}
		}
	}
}
Пример #14
0
/*! Initializes the physics for the Ramp
 *
 *  @param          pWorld          Pointer to physics world
 *  @returns        ICRESULT        Success/failure of physics initialization
**/
ICRESULT Ramp::InitPhysics(btDiscreteDynamicsWorld* pWorld)
{
    if (!pWorld) return IC_OK;;


    m_pworld = pWorld;

    if (m_verts)
        delete[] m_verts;

    if (m_ib) 
        delete[] m_ib;


    
    //m_pContent->Load("Resource/models/skeeball_collision.icm",&model);

    //// try to open the model file
    icFile file;
    if (ICEFAIL(file.Open("Resource/models/skeeball_collision.icm", ICFMREAD_EXISTING)))
    {
        icWarningf("Content loader could not open: %s", "Resource/models/skeeball_collision.icm");
        return IC_FAIL_GEN;
    }

    _ICE_MODEL model_header = {0};

    size_t sizeread = 0;

    // read the ice model header
    if (ICEFAIL(file.Read(&model_header, sizeof(_ICE_MODEL), &sizeread)))
    {
        icWarningf("Content loader could not read: %s", "Resource/models/skeeball_collision.icm");
        return IC_FAIL_GEN;
    }

    
    m_verts = NULL;

    int totalTriangles = model_header.numInd/3;

    int totalVerts = model_header.numVerts;

    m_verts = new icVector3[model_header.numVerts];

    m_ib = new int [model_header.numInd];

    m_vb = malloc(sizeof(ICVRTNRM_DIF)*model_header.numVerts);

    size_t read;
    // CREATE VERTEX BUFFER
    switch(model_header.modelVersion)
    {
    case ICE_MODEL_FORMAT:
        {
            switch (model_header.vertType)
            {
            case IC_VERT_DIF:
                {
                    ICVRT_DIF cur_vert;
                    for (int i=0; i<model_header.numVerts; ++i)
                    {
                        file.Read(&cur_vert,sizeof(ICVRT_DIF),&read);
                        m_verts[i] = cur_vert.pos;
                    }
                }break;
            case IC_VERT_NRM_DIF:
                {
                    ICVRTNRM_DIF cur_vert;
                    for (int i=0; i<model_header.numVerts; ++i)
                    {
                        file.Read(&cur_vert,sizeof(ICVRTNRM_DIF),&read);
                        m_verts[i] = cur_vert.pos;
                    }
                }break;
            default:
                ;
            }
        }break;
    case 101:
        {
            switch (model_header.vertType)
            {
            case 2:
                {
                    ICVRT_DIF cur_vert;
                    for (int i=0; i<model_header.numVerts; ++i)
                    {
                        file.Read(&cur_vert,sizeof(ICVRT_DIF),&read);
                        m_verts[i] = cur_vert.pos;
                    }
                }break;
            case 8:
                {
                    ICVRTNRM_DIF cur_vert;
                    for (int i=0; i<model_header.numVerts; ++i)
                    {
                        file.Read(&cur_vert,sizeof(ICVRT_DIF),&read);
                        m_verts[i] = cur_vert.pos;
                    }
                }break;
            default:
                {
                    ICVRTNRM_DIF cur_vert;
                    for (int i=0; i<model_header.numVerts; ++i)
                    {
                        file.Read(&cur_vert,sizeof(ICVRT_DIF),&read);
                        m_verts[i] = cur_vert.pos;
                    }
                }
            }
        }break;
    case 100:
        {
            file.SetPos(sizeof(_ICE_MODEL_100)); // rewind

            ICVRT_DIF cur_vert;
            for (int i=0; i<model_header.numVerts; ++i)
            {
                file.Read(&cur_vert,sizeof(ICVRT_DIF),&read);
                m_verts[i] = cur_vert.pos;
            }
        }break;
    default:
        icWarningf("Invalid model format: %s", "Resource/models/skeeball_collision.icm");
        return IC_FAIL_GEN;
    }

    file.Read(m_ib,model_header.numInd*sizeof(int),&read);

    m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles,
        m_ib,
        3*sizeof(int),
        model_header.numVerts,(btScalar*)m_verts,sizeof(icVector3));
    
    btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000);
    m_colShape = new btBvhTriangleMeshShape(m_indexVertexArrays,true,aabbMin,aabbMax);


    m_colObject = new btCollisionObject();
    m_colObject->setCollisionShape(m_colShape);

    m_colObject2 = new btCollisionObject();
    m_colObject2->setCollisionShape(m_colShape);

    m_colObject3 = new btCollisionObject();
    m_colObject3->setCollisionShape(m_colShape);

	btTransform transform;
    transform.setFromOpenGLMatrix((btScalar*)m_Trans);
    m_colObject->setWorldTransform(transform);

    transform.setOrigin(btVector3(-105.422f,0.0f,0.0f));
    m_colObject2->setWorldTransform(transform);

    transform.setOrigin(btVector3(105.422f,0.0f,0.0f));
    m_colObject3->setWorldTransform(transform);



    pWorld->addCollisionObject(m_colObject);//, 0x0001, 0x00FF);
    pWorld->addCollisionObject(m_colObject2);//, 0x0001, 0x00FF);
    pWorld->addCollisionObject(m_colObject3);//, 0x0001, 0x00FF);

    return IC_OK;
}// END FUNCTION InitPhysics(b2World* pWorld)