예제 #1
0
// Constructor
_Collision::_Collision(const SpawnStruct &Object)
:	_Object(),
	TriangleIndexVertexArray(NULL),
	TriangleInfoMap(NULL),
	VertexList(NULL),
	FaceList(NULL) {
	
	gContactAddedCallback = CustomMaterialCallback;

	// Load collision mesh file
	_File MeshFile;
	if(MeshFile.OpenForRead(Object.Template->CollisionFile.c_str())) {

		// Read header
		int VertCount = MeshFile.ReadInt();
		int FaceCount = MeshFile.ReadInt();

		// Allocate memory for lists
		VertexList = new float[VertCount * 3];
		FaceList = new int[FaceCount * 3];

		// Read vertices
		int VertexIndex = 0;
		for(int i = 0; i < VertCount; i++) {
			VertexList[VertexIndex++] = MeshFile.ReadFloat();
			VertexList[VertexIndex++] = MeshFile.ReadFloat();
			VertexList[VertexIndex++] = -MeshFile.ReadFloat();
		}

		// Read faces
		int FaceIndex = 0;
		for(int i = 0; i < FaceCount; i++) {
			FaceList[FaceIndex+2] = MeshFile.ReadInt();
			FaceList[FaceIndex+1] = MeshFile.ReadInt();
			FaceList[FaceIndex+0] = MeshFile.ReadInt();
			FaceIndex += 3;
		}

		// Create triangle array
		TriangleIndexVertexArray = new btTriangleIndexVertexArray(FaceCount, FaceList, 3 * sizeof(int), VertCount * 3, VertexList, 3 * sizeof(float));

		// Create bvh shape
		btBvhTriangleMeshShape *Shape = new btBvhTriangleMeshShape(TriangleIndexVertexArray, true);
		TriangleInfoMap = new btTriangleInfoMap();
		btGenerateInternalEdgeInfo(Shape, TriangleInfoMap);

		// Create physics body
		CreateRigidBody(Object, Shape);
		SetProperties(Object);
		
		RigidBody->setCollisionFlags(RigidBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

		MeshFile.Close();
	}
}
예제 #2
0
btCollisionShape* Bullet::CreateBulletShape(const PINT_SHAPE_CREATE& desc)
{
	btCollisionShape* BulletShape = null;
	if(desc.mType==PINT_SHAPE_SPHERE)
	{
		const PINT_SPHERE_CREATE& SphereCreate = static_cast<const PINT_SPHERE_CREATE&>(desc);
		BulletShape = FindSphereShape(SphereCreate);
	}
	else if(desc.mType==PINT_SHAPE_BOX)
	{
		const PINT_BOX_CREATE& BoxCreate = static_cast<const PINT_BOX_CREATE&>(desc);
		BulletShape = FindBoxShape(BoxCreate);
	}
	else if(desc.mType==PINT_SHAPE_CAPSULE)
	{
		const PINT_CAPSULE_CREATE& CapsuleCreate = static_cast<const PINT_CAPSULE_CREATE&>(desc);
		BulletShape = FindCapsuleShape(CapsuleCreate);
	}
	else if(desc.mType==PINT_SHAPE_CONVEX)
	{
		const PINT_CONVEX_CREATE& ConvexCreate = static_cast<const PINT_CONVEX_CREATE&>(desc);
		BulletShape = FindConvexShape(ConvexCreate);
	}
	else if(desc.mType==PINT_SHAPE_MESH)
	{
		const PINT_MESH_CREATE& MeshCreate = static_cast<const PINT_MESH_CREATE&>(desc);

		// ### share meshes

		btTriangleIndexVertexArray* m_indexVertexArrays = new btTriangleIndexVertexArray(
			MeshCreate.mSurface.mNbFaces,
			(int*)MeshCreate.mSurface.mDFaces,
			3*sizeof(udword),
			MeshCreate.mSurface.mNbVerts,
			(float*)&MeshCreate.mSurface.mVerts->x,
			sizeof(Point));

		btBvhTriangleMeshShape* shape  = new btBvhTriangleMeshShape(m_indexVertexArrays, true, true);
		ASSERT(shape);

		btTriangleInfoMap* triangleInfoMap = null;
		if(gUseInternalEdgeUtility)
		{
			triangleInfoMap = new btTriangleInfoMap();
			btGenerateInternalEdgeInfo(shape, triangleInfoMap);
		}

		InternalMeshShape MeshData;
		MeshData.mShape				= shape;
		MeshData.mMeshData			= m_indexVertexArrays;
		MeshData.mTriangleInfoMap	= triangleInfoMap;
		mMeshShapes.push_back(MeshData);

		mCollisionShapes.push_back(shape);

		if(desc.mRenderer)
			shape->setUserPointer(desc.mRenderer);

		shape->setMargin(gCollisionMargin);

		BulletShape = shape;
	}

	else ASSERT(0);

	return BulletShape;
}
예제 #3
0
파일: tests.cpp 프로젝트: Meumeu/PMD
int main(int argc, char * argv[])
{
	btCollisionConfiguration * CollisionConfiguration = new btDefaultCollisionConfiguration();
	btCollisionDispatcher * Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
	btBroadphaseInterface * OverlappingPairCache = new btDbvtBroadphase();
	btConstraintSolver * Solver = new btSequentialImpulseConstraintSolver();

	btDynamicsWorld * World = new btDiscreteDynamicsWorld(Dispatcher, OverlappingPairCache, Solver, CollisionConfiguration);

	World->setGravity(btVector3(0, -20, 0));
	
	btTriangleMesh Trimesh;

	for(float x = 0; x < 100; x += 1)
	{
		for(float z = -3; z < 3; z += 1)
		{
			btVector3 v1(x+0, 0, z+0);
			btVector3 v2(x+0, 0, z+1);
			btVector3 v3(x+1, 0, z+0);
			btVector3 v4(x+1, 0, z+1);
			Trimesh.addTriangle(v1, v2, v3);
			Trimesh.addTriangle(v2, v3, v4);
		}
	}
	
	btBvhTriangleMeshShape TrimeshShape(&Trimesh, true);

	btRigidBody * body = new btRigidBody(0, new btDefaultMotionState, &TrimeshShape);
	World->addRigidBody(body);

	btTriangleInfoMap * triinfomap = new btTriangleInfoMap();
	btGenerateInternalEdgeInfo(&TrimeshShape, triinfomap);
	gContactAddedCallback = CustomMaterialCombinerCallback;
	body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK | btCollisionObject::CF_STATIC_OBJECT);

	btVector3 inertia;
	btBoxShape box(btVector3(0.3, 0.3, 0.3));
	box.calculateLocalInertia(10, inertia);

	btRigidBody * cube = new btRigidBody(10, new btDefaultMotionState(btTransform(btQuaternion::getIdentity(), btVector3(1, 0.3, 0))), &box, inertia);
	World->addRigidBody(cube);

	cube->setLinearVelocity(btVector3(15,0,0.1));
	//cube->setFriction(0);

	body->setContactProcessingThreshold(0);
	cube->setContactProcessingThreshold(0);

	std::fstream f("out.txt", std::fstream::out);

	const float dt = 1.0 / 60.0;
	for(float t = 0; t < 10; t += dt)
	{
		World->stepSimulation(1.0/60.0,1000,1.0/60.0);
		btVector3 pos = cube->getCenterOfMassPosition();
		
		f.width(12);
		f << std::left << t;
		f.width(12);
		f << pos.x();
		f.width(12);
		f << pos.y();
		f.width(12);
		f << pos.z();
		f << "\n";
	}

	return 0;
}
예제 #4
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

	
}
예제 #5
0
void CollisionMesh::loadImpl (void)
{
    APP_ASSERT(masterShape==NULL);

    Ogre::DataStreamPtr file;
    try {
        file = Ogre::ResourceGroupManager::getSingleton().openResource(name.substr(1), "GRIT");
    } catch (Ogre::Exception &e) {
        GRIT_EXCEPT(e.getDescription());
    }

    std::string ext = name.substr(name.length()-5);

    uint32_t fourcc = 0;
    for (int i=0 ; i<4 ; ++i) {
        unsigned char c;
        file->read(&c, 1);
        fourcc |= c << (i*8);
    }
    file->seek(0);

    std::string dir = grit_dirname(name);

    const btVector3 ZV(0,0,0);
    const btQuaternion ZQ(0,0,0,1);

    bool compute_inertia = false;
    bool is_static = false;

    if (fourcc==0x4c4f4342) { //BCOL

        Ogre::MemoryDataStreamPtr mem = 
            Ogre::MemoryDataStreamPtr(OGRE_NEW Ogre::MemoryDataStream(name,file));

        BColFile &bcol = *reinterpret_cast<BColFile*>(mem->getPtr());

        is_static = bcol.mass == 0.0f; // static

        masterShape = new btCompoundShape();

        BColMaterialMap mmap(dir,name);

        for (unsigned i=0 ; i<bcol.hullNum ; ++i) {
            BColHull &p = *bcol.hulls(i);
            btConvexHullShape *s2 = new btConvexHullShape();
            s2->setMargin(p.margin);
            for (unsigned j=0 ; j<p.vertNum ; ++j) {
                BColVert &v = *p.verts(j);
                s2->addPoint(btVector3(v.x, v.y, v.z));
            }
            masterShape->addChildShape(btTransform(ZQ,ZV), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }

        for (unsigned i=0 ; i<bcol.boxNum ; ++i) {
            BColBox &p = *bcol.boxes(i);
            btBoxShape *s2 = new btBoxShape(btVector3(p.dx/2,p.dy/2,p.dz/2));
            s2->setMargin(p.margin);
            masterShape->addChildShape(btTransform(btQuaternion(p.qx,p.qy,p.qz,p.qw),
                                                   btVector3(p.px,p.py,p.pz)), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }

        for (unsigned i=0 ; i<bcol.cylNum ; ++i) {
            BColCyl &p = *bcol.cyls(i);
            btCylinderShape *s2 = new btCylinderShapeZ(btVector3(p.dx/2,p.dy/2,p.dz/2));
            s2->setMargin(p.margin);
            masterShape->addChildShape(btTransform(btQuaternion(p.qx,p.qy,p.qz,p.qw),
                                                   btVector3(p.px,p.py,p.pz)), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }

        for (unsigned i=0 ; i<bcol.coneNum ; ++i) {
            BColCone &p = *bcol.cones(i);
            btConeShape *s2 = new btConeShapeZ(p.radius,p.height);
            s2->setMargin(p.margin);
            masterShape->addChildShape(btTransform(btQuaternion(p.qx,p.qy,p.qz,p.qw),
                                                   btVector3(p.px,p.py,p.pz)), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }

        for (unsigned i=0 ; i<bcol.planeNum ; ++i) {
            BColPlane &p = *bcol.planes(i);
            btStaticPlaneShape *s2 = new btStaticPlaneShape(btVector3(p.nx,p.ny,p.nz),p.d);
            masterShape->addChildShape(btTransform(ZQ,ZV), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }

        for (unsigned i=0 ; i<bcol.sphereNum ; ++i) {
            BColSphere &p = *bcol.spheres(i);
            btSphereShape *s2 = new btSphereShape(p.radius);
            masterShape->addChildShape(btTransform(ZQ, btVector3(p.px,p.py,p.pz)), s2);
            partMaterials.push_back(mmap(p.mat.name()));
        }


        if (bcol.triMeshFaceNum > 0) {

            bcolVerts.resize(bcol.triMeshVertNum);
            bcolFaces.resize(bcol.triMeshFaceNum);

            memcpy(&bcolVerts[0], bcol.triMeshVerts(0), bcol.triMeshVertNum * sizeof(BColVert));
            memcpy(&bcolFaces[0], bcol.triMeshFaces(0), bcol.triMeshFaceNum * sizeof(BColFace));

            faceMaterials.reserve(bcol.triMeshFaceNum);

            int counter = 0;
            float accum_area = 0;
            for (unsigned i=0 ; i<bcol.triMeshFaceNum ; ++i) {
                BColFace &face = *bcol.triMeshFaces(i);
                PhysicalMaterial *mat = mmap(face.mat.name());
                faceMaterials.push_back(mat);
                CollisionMesh::ProcObjFace po_face(to_v3(bcolVerts[face.v1]), 
                                                   to_v3(bcolVerts[face.v2]),
                                                   to_v3(bcolVerts[face.v3]));
                procObjFaceDB[mat->id].faces.push_back(po_face);
                float area = (po_face.AB.cross(po_face.AC)).length();
                APP_ASSERT(area>=0);
                procObjFaceDB[mat->id].areas.push_back(area);
                procObjFaceDB[mat->id].totalArea += area;
                if (++counter = 10) {
                    counter = 0;
                    accum_area = 0;
                    procObjFaceDB[mat->id].areas10.push_back(accum_area);
                }
                accum_area += area;
                    
            }

            btTriangleIndexVertexArray *v = new btTriangleIndexVertexArray(
                bcolFaces.size(), reinterpret_cast<int*>(&(bcolFaces[0].v1)), sizeof(BColFace),
                bcolVerts.size(), &(bcolVerts[0].x), sizeof(BColVert));


            if (is_static) {
                btBvhTriangleMeshShape *tm = new btBvhTriangleMeshShape(v,true,true);
                tm->setMargin(bcol.triMeshMargin);
                btTriangleInfoMap* tri_info_map = new btTriangleInfoMap();
                tri_info_map->m_edgeDistanceThreshold = bcol.triMeshEdgeDistanceThreshold;

                btGenerateInternalEdgeInfo(tm,tri_info_map);
                masterShape->addChildShape(btTransform::getIdentity(), tm);
            } else {
                // skip over dynamic trimesh
            }
        }

        setMass(bcol.mass);
        setLinearDamping(bcol.linearDamping);
        setAngularDamping(bcol.angularDamping);
        setLinearSleepThreshold(bcol.linearSleepThreshold);
        setAngularSleepThreshold(bcol.angularSleepThreshold);
        setCCDMotionThreshold(bcol.ccdMotionThreshold);
        setCCDSweptSphereRadius(bcol.ccdSweptSphereRadius);
        setInertia(Vector3(bcol.inertia[0],bcol.inertia[1],bcol.inertia[2]));

        compute_inertia = !bcol.inertiaProvided;

    } else if (fourcc==0x4c4f4354) { //TCOL

        ProxyStreamBuf proxy(file);

        std::istream stream(&proxy);
        quex::tcol_lexer qlex(&stream);
        TColFile tcol;
        parse_tcol_1_0(name,&qlex,tcol);

        is_static = tcol.mass == 0.0f; // static

        masterShape = new btCompoundShape();

        if (tcol.usingCompound) {

            TColCompound &c = tcol.compound;

            for (size_t i=0 ; i<c.hulls.size() ; ++i) {
                const TColHull &h = c.hulls[i];
                btConvexHullShape *s2 = new btConvexHullShape();
                s2->setMargin(h.margin);
                for (unsigned j=0 ; j<h.vertexes.size() ; ++j) {
                    const Vector3 &v = h.vertexes[j];
                    s2->addPoint(to_bullet(v));
                }
                masterShape->addChildShape(btTransform(ZQ,ZV), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,h.material));
            }

            for (size_t i=0 ; i<c.boxes.size() ; ++i) {
                const TColBox &b = c.boxes[i];
                /* implement with hulls
                btConvexHullShape *s2 = new btConvexHullShape();
                s2->addPoint(btVector3(-b.dx/2+b.margin, -b.dy/2+b.margin, -b.dz/2+b.margin));
                s2->addPoint(btVector3(-b.dx/2+b.margin, -b.dy/2+b.margin,  b.dz/2-b.margin));
                s2->addPoint(btVector3(-b.dx/2+b.margin,  b.dy/2-b.margin, -b.dz/2+b.margin));
                s2->addPoint(btVector3(-b.dx/2+b.margin,  b.dy/2-b.margin,  b.dz/2-b.margin));
                s2->addPoint(btVector3( b.dx/2-b.margin, -b.dy/2+b.margin, -b.dz/2+b.margin));
                s2->addPoint(btVector3( b.dx/2-b.margin, -b.dy/2+b.margin,  b.dz/2-b.margin));
                s2->addPoint(btVector3( b.dx/2-b.margin,  b.dy/2-b.margin, -b.dz/2+b.margin));
                s2->addPoint(btVector3( b.dx/2-b.margin,  b.dy/2-b.margin,  b.dz/2-b.margin));
                */
                btBoxShape *s2 =new btBoxShape(btVector3(b.dx/2,b.dy/2,b.dz/2));
                s2->setMargin(b.margin);
                masterShape->addChildShape(btTransform(btQuaternion(b.qx,b.qy,b.qz,b.qw),
                                 btVector3(b.px,b.py,b.pz)), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,b.material));
            }

            for (size_t i=0 ; i<c.cylinders.size() ; ++i) {
                const TColCylinder &cyl = c.cylinders[i];
                btCylinderShape *s2 =
                    new btCylinderShapeZ(btVector3(cyl.dx/2,cyl.dy/2,cyl.dz/2));
                s2->setMargin(cyl.margin);
                masterShape->addChildShape(
                    btTransform(btQuaternion(cyl.qx,cyl.qy,cyl.qz,cyl.qw),
                            btVector3(cyl.px,cyl.py,cyl.pz)), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,cyl.material));
            }

            for (size_t i=0 ; i<c.cones.size() ; ++i) {
                const TColCone &cone = c.cones[i];
                btConeShapeZ *s2 = new btConeShapeZ(cone.radius,cone.height);
                s2->setMargin(cone.margin);
                masterShape->addChildShape(
                      btTransform(btQuaternion(cone.qx,cone.qy,cone.qz,cone.qw),
                          btVector3(cone.px,cone.py,cone.pz)), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,cone.material));
            }

            for (size_t i=0 ; i<c.planes.size() ; ++i) {
                const TColPlane &p = c.planes[i];
                btStaticPlaneShape *s2 =
                    new btStaticPlaneShape(btVector3(p.nx,p.ny,p.nz),p.d);
                masterShape->addChildShape(btTransform(ZQ,ZV), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,p.material));
            }

            for (size_t i=0 ; i<c.spheres.size() ; ++i) {
                const TColSphere &sp = c.spheres[i];
                btSphereShape *s2 = new btSphereShape(sp.radius);
                masterShape->addChildShape(btTransform(ZQ,
                                 btVector3(sp.px,sp.py,sp.pz)), s2);
                partMaterials.push_back(phys_mats.getMaterial(dir,name,sp.material));
            }
        }

        if (tcol.usingTriMesh) {

            TColTriMesh &t = tcol.triMesh;

            std::swap(verts, t.vertexes);
            std::swap(faces, t.faces);


            faceMaterials.reserve(faces.size());
            int counter = 0;
            float accum_area = 0;
            for (TColFaces::const_iterator i=faces.begin(), i_=faces.end() ; i!=i_ ; ++i) {
                //optimisation possible here by changing the TCol struct to be more liek what
                //bullet wants, and then re-using memory
                PhysicalMaterial *mat = phys_mats.getMaterial(dir,name,i->material);
                faceMaterials.push_back(mat);
                CollisionMesh::ProcObjFace po_face(verts[i->v1], verts[i->v2], verts[i->v3]);
                procObjFaceDB[mat->id].faces.push_back(po_face);
                float area = (po_face.AB.cross(po_face.AC)).length();
                APP_ASSERT(area>=0);
                procObjFaceDB[mat->id].areas.push_back(area);
                procObjFaceDB[mat->id].totalArea += area;
                if (++counter = 10) {
                    counter = 0;
                    accum_area = 0;
                    procObjFaceDB[mat->id].areas10.push_back(accum_area);
                }
                accum_area += area;
                    
            }

            btTriangleIndexVertexArray *v = new btTriangleIndexVertexArray(
                faces.size(), &(faces[0].v1), sizeof(TColFace),
                verts.size(), &(verts[0].x), sizeof(Vector3));

            if (is_static) {
                btBvhTriangleMeshShape *tm = new btBvhTriangleMeshShape(v,true,true);
                tm->setMargin(t.margin);
                btTriangleInfoMap* tri_info_map = new btTriangleInfoMap();
                tri_info_map->m_edgeDistanceThreshold = t.edgeDistanceThreshold;

                btGenerateInternalEdgeInfo(tm,tri_info_map);
                masterShape->addChildShape(btTransform::getIdentity(), tm);
            } else {
                // Skip over dynamic trimesh
            }

        }

        setMass(tcol.mass);
        setInertia(Vector3(tcol.inertia_x,tcol.inertia_y,tcol.inertia_z));
        setLinearDamping(tcol.linearDamping);
        setAngularDamping(tcol.angularDamping);
        setLinearSleepThreshold(tcol.linearSleepThreshold);
        setAngularSleepThreshold(tcol.angularSleepThreshold);
        setCCDMotionThreshold(tcol.ccdMotionThreshold);
        setCCDSweptSphereRadius(tcol.ccdSweptSphereRadius);

        compute_inertia = !tcol.hasInertia;

    } else {
        GRIT_EXCEPT("Collision mesh \""+name+"\" seems to be corrupt.");
    }


    if (is_static) {
        setInertia(Vector3(0,0,0));
    } else {
        if (faceMaterials.size() > 0) {
            CERR << "While loading \"" + name + "\": Dynamic trimesh not supported." << std::endl;
        }
        if (compute_inertia) {
            btVector3 i;
            masterShape->calculateLocalInertia(mass,i);
            setInertia(from_bullet(i));
        }
    }
}
예제 #6
0
int main(int ArgumentCount, char **Arguments) {

	// Set up physics modules
	CollisionConfiguration = new btDefaultCollisionConfiguration();
	//BroadPhase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000));
	BroadPhase = new btDbvtBroadphase();
	Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
	Solver = new btSequentialImpulseConstraintSolver();
	World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration);
	World->setGravity(btVector3(0.0, -9.81, 0.0));
	btContactSolverInfo &SolverInfo = World->getSolverInfo();
	//SolverInfo.m_splitImpulseTurnErp = 0.0f;
	//SolverInfo.m_splitImpulse = 1;
	//SolverInfo.m_splitImpulsePenetrationThreshold = -0.02f;
	
	gContactAddedCallback = CustomMaterialCallback;
	
	{
		btScalar Mass = 1.0;
		btCollisionShape *Shape = new btSphereShape(0.5);
		btVector3 LocalInertia(0.0, 0.0, 0.0);
		Shape->calculateLocalInertia(Mass, LocalInertia);
		
		SphereBody = new btRigidBody(Mass, NULL, Shape, LocalInertia);
		SphereBody->setFriction(1.0);
		SphereBody->setDamping(0.1, 0.3);
		SphereBody->setActivationState(DISABLE_DEACTIVATION);
		SphereBody->translate(btVector3(0.71, 2.5, -0.8));
		
		World->addRigidBody(SphereBody);
	}
	
	// Set to 1 to test static box shape
	if(USE_STATIC_BOX) {
		
		btScalar Mass = 0.0;
		btCollisionShape *Shape = new btBoxShape(btVector3(1, 1, 1));
		btVector3 LocalInertia(0.0, 0.0, 0.0);
		Shape->calculateLocalInertia(Mass, LocalInertia);
		
		BoxBody = new btRigidBody(Mass, NULL, Shape, LocalInertia);
		BoxBody->setFriction(1.0);
		BoxBody->setDamping(0.1, 0.3);
		BoxBody->setActivationState(DISABLE_DEACTIVATION);
		BoxBody->translate(btVector3(0, -2, 0));
		
		World->addRigidBody(BoxBody);
	}
	else {
		btScalar Mass = 0.0;
		int VertexCount = sizeof(Vertices) / sizeof(btScalar);
		int FaceCount = sizeof(Indices) / sizeof(int) / 3;
		TriangleIndexVertexArray = new btTriangleIndexVertexArray(FaceCount, Indices, 3 * sizeof(int), VertexCount, Vertices, 3 * sizeof(btScalar));

		btBvhTriangleMeshShape *Shape = new btBvhTriangleMeshShape(TriangleIndexVertexArray, true);
		btTriangleInfoMap *TriangleInfoMap = new btTriangleInfoMap();
		btGenerateInternalEdgeInfo(Shape, TriangleInfoMap);
	
		MeshBody = new btRigidBody(Mass, NULL, Shape);
		MeshBody->setFriction(1.0);
		MeshBody->setDamping(0.1, 0.3);
		MeshBody->setCollisionFlags(MeshBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);

		// Add body
		World->addRigidBody(MeshBody);
	}
	
	for(int i = 0; i < 100; i++) {
		World->stepSimulation(TIMESTEP, 0, 0);
	
		const btTransform &Transform = SphereBody->getCenterOfMassTransform();
		const btVector3 &Position = Transform.getOrigin();
		printf("%f %f %f\n", Position.getX(), Position.getY(), Position.getZ());
	}
	
	World->removeRigidBody(SphereBody);
	if(MeshBody)
		World->removeRigidBody(MeshBody);
	if(BoxBody)
		World->removeRigidBody(BoxBody);
		
	delete SphereBody->getCollisionShape();	
	delete SphereBody;

	if(MeshBody) {
		delete ((btBvhTriangleMeshShape *)MeshBody->getCollisionShape())->getTriangleInfoMap();	
		delete ((btBvhTriangleMeshShape *)MeshBody->getCollisionShape())->getMeshInterface();	
		delete MeshBody->getCollisionShape();	
		delete MeshBody;
	}
	
	if(BoxBody) {
		delete BoxBody->getCollisionShape();	
		delete BoxBody;
	}
	
	delete World;
	delete Solver;
	delete Dispatcher;
	delete BroadPhase;
	delete CollisionConfiguration;

	return 0;
}