static void convertToBullet(void) { cleanupBullet(); m_config = new btDefaultCollisionConfiguration(); btHashedOverlappingPairCache* pairCache = new btHashedOverlappingPairCache(); //m_broadphase = new btDbvtBroadphase(); btLowLevelData* lowLevelData = new btLowLevelData; lowLevelData->m_maxContacts = NUM_CONTACTS;//8024; lowLevelData->m_contactIdPool = (int*) btAlignedAlloc(sizeof(int)*lowLevelData->m_maxContacts ,16); lowLevelData->m_contacts = (PfxContactManifold*) btAlignedAlloc(sizeof(PfxContactManifold)*lowLevelData->m_maxContacts,16); lowLevelData->m_maxPairs = lowLevelData->m_maxContacts;//?? lowLevelData->m_pairsBuff[0] = (PfxBroadphasePair*) btAlignedAlloc(sizeof(PfxBroadphasePair)*lowLevelData->m_maxPairs,16); lowLevelData->m_pairsBuff[1] = (PfxBroadphasePair*) btAlignedAlloc(sizeof(PfxBroadphasePair)*lowLevelData->m_maxPairs,16); #define USE_LL_BP #ifdef USE_LL_BP btLowLevelBroadphase* llbp = new btLowLevelBroadphase(lowLevelData,pairCache); m_broadphase = llbp; #else //USE_LL_BP m_broadphase = new btDbvtBroadphase(); #endif //USE_LL_BP //m_dispatcher = new btCollisionDispatcher(m_config); m_dispatcher = new btLowLevelCollisionDispatcher(lowLevelData,m_config,NUM_CONTACTS); //#ifdef USE_PARALLEL_SOLVER // m_solver = new btSequentialImpulseConstraintSolver(); //#else //sThreadSupport = createSolverThreadSupport(4); //m_solver = new btLowLevelConstraintSolver(sThreadSupport); m_solver = new btLowLevelConstraintSolver2(lowLevelData); //#endif //USE_PARALLEL_SOLVER //m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_config); m_dynamicsWorld = new btBulletPhysicsEffectsWorld(lowLevelData, m_dispatcher,llbp,m_solver,m_config,0); PEDebugDrawer* drawer = new PEDebugDrawer(); drawer->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawAabb); m_dynamicsWorld->setDebugDrawer(drawer); m_dynamicsWorld ->getSolverInfo().m_splitImpulse = true; for(int i=0;i<physics_get_num_rigidbodies();i++) { btRigidBody* body = 0; btAlignedObjectArray<btCollisionShape*> shapes; btAlignedObjectArray<btTransform> childTtransforms; PfxRigidState &state = states[i];//physics_get_state(i); state.setUserData(0); const PfxCollidable &coll = physics_get_collidable(i); 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; btTransform childTransform; childTransform.setIdentity(); childTransform.setOrigin(getBtVector3(offsetT.getTranslation())); PfxQuat quat(offsetT.getUpper3x3()); childTransform.setBasis(btMatrix3x3(getBtQuat(quat))); childTtransforms.push_back(childTransform); switch(shape.getType()) { case kPfxShapeSphere: { btSphereShape* sphere = new btSphereShape(shape.getSphere().m_radius); shapes.push_back(sphere); //render_sphere( worldT, Vectormath::Aos::Vector3(1,1,1),Vectormath::floatInVec(shape.getSphere().m_radius)); } break; case kPfxShapeBox: { btBoxShape* box = new btBoxShape(getBtVector3(shape.getBox().m_half)); shapes.push_back(box); } //render_box( worldT, Vectormath::Aos::Vector3(1,1,1), shape.getBox().m_half); break; case kPfxShapeCapsule: shapes.push_back(new btCapsuleShapeX(shape.getCapsule().m_radius,2.f*shape.getCapsule().m_halfLen)); //render_capsule( worldT, Vectormath::Aos::Vector3(1,1,1), Vectormath::floatInVec(shape.getCapsule().m_radius), Vectormath::floatInVec(shape.getCapsule().m_halfLen)); break; case kPfxShapeCylinder: shapes.push_back(new btCylinderShapeX(btVector3(shape.getCylinder().m_halfLen,shape.getCylinder().m_radius,shape.getCylinder().m_radius))); //render_cylinder( worldT, Vectormath::Aos::Vector3(1,1,1), Vectormath::floatInVec(shape.getCylinder().m_radius),Vectormath::floatInVec(shape.getCylinder().m_halfLen)); break; case kPfxShapeConvexMesh: { const PfxConvexMesh* convex = shape.getConvexMesh(); const btScalar* vertices = (const btScalar*)&convex->m_verts[0]; btConvexHullShape* convexHull = new btConvexHullShape(vertices,convex->m_numVerts, sizeof(PfxVector3)); shapes.push_back(convexHull); } break; case kPfxShapeLargeTriMesh: { const PfxLargeTriMesh* mesh = shape.getLargeTriMesh(); btTriangleIndexVertexArray* meshInterface = new btTriangleIndexVertexArray(); int i; for (i= 0; i < mesh->m_numIslands;i++) { PfxTriMesh* island = &mesh->m_islands[i]; //mesh->m_islands //mesh->m_numIslands btIndexedMesh indexedMesh; indexedMesh.m_indexType = PHY_UCHAR; indexedMesh.m_numTriangles = island->m_numFacets; indexedMesh.m_triangleIndexBase = &island->m_facets[0].m_vertIds[0]; indexedMesh.m_triangleIndexStride = sizeof(PfxFacet); indexedMesh.m_vertexBase = (const unsigned char*) &island->m_verts[0]; indexedMesh.m_numVertices = island->m_numVerts;//unused indexedMesh.m_vertexStride = sizeof(PfxVector3); meshInterface->addIndexedMesh(indexedMesh,PHY_UCHAR); } btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface,true); shapes.push_back(trimesh); } break; default: { printf("unknown\n"); } break; } } if(shapes.size()>0) { printf("shapes!\n"); btCollisionShape* colShape = 0; if (shapes.size()==1 && childTtransforms[0].getOrigin().fuzzyZero()) //todo: also check orientation { colShape = shapes[0]; } else { btCompoundShape* compound = new btCompoundShape(); for (int i=0;i<shapes.size();i++) { compound->addChildShape(childTtransforms[i],shapes[i]); } colShape = compound; } btTransform worldTransform; worldTransform.setIdentity(); worldTransform.setOrigin(getBtVector3(rbT.getTranslation())); PfxQuat quat(rbT.getUpper3x3()); worldTransform.setBasis(btMatrix3x3(getBtQuat(quat))); btScalar mass = physics_get_body(i).getMass(); btRigidBody* body = addRigidBody(colShape,mass,worldTransform); void* ptr = (void*)&state; body->setUserPointer(ptr); state.setUserData(body); } } //very basic joint conversion (only limits of PFX_JOINT_SWINGTWIST joint) for (int i=0;i<numJoints;i++) { PfxJoint& joint = joints[i]; switch (joint.m_type) { case kPfxJointSwingtwist: { //btConeTwistConstraint* coneTwist = new btConeTwistConstraint(rbA,rbB,frameA,frameB); bool referenceA = true; btRigidBody* bodyA = (btRigidBody*)states[joint.m_rigidBodyIdA].getUserData(); btRigidBody* bodyB = (btRigidBody*)states[joint.m_rigidBodyIdB].getUserData(); if (bodyA&&bodyB) { btTransform frameA,frameB; frameA.setIdentity(); frameB.setIdentity(); frameA.setOrigin(getBtVector3(joint.m_anchorA)); frameB.setOrigin(getBtVector3(joint.m_anchorB)); bool referenceA = false; btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*bodyA,*bodyB,frameA,frameB,referenceA); for (int i=0;i<joint.m_numConstraints;i++) { switch (joint.m_constraints[i].m_lock) { case SCE_PFX_JOINT_LOCK_FIX: { dof6->setLimit(i,0,0); break; } case SCE_PFX_JOINT_LOCK_FREE: { dof6->setLimit(i,1,0); break; } case SCE_PFX_JOINT_LOCK_LIMIT: { //deal with the case where angular limits of Y-axis are free and/or beyond -PI/2 and PI/2 if ((i==4) && ((joint.m_constraints[i].m_movableLowerLimit<-SIMD_PI/2)||(joint.m_constraints[i].m_movableUpperLimit>SIMD_PI/2))) { printf("error with joint limits, forcing DOF to fixed\n"); dof6->setLimit(i,0,0); } else { dof6->setLimit(i,joint.m_constraints[i].m_movableLowerLimit,joint.m_constraints[i].m_movableUpperLimit); } break; } default: { printf("unknown joint lock state\n"); } } } m_dynamicsWorld->addConstraint(dof6,true); } else { printf("error: missing bodies during joint conversion\n"); } break; }; case kPfxJointBall: case kPfxJointHinge: case kPfxJointSlider: case kPfxJointFix: case kPfxJointUniversal: case kPfxJointAnimation: default: { printf("unknown joint\n"); } } } //create a large enough buffer. There is no method to pre-calculate the buffer size yet. int maxSerializeBufferSize = 1024*1024*5; btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); m_dynamicsWorld->serialize(serializer); FILE* file = fopen("testFile.bullet","wb"); fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); fclose(file); }
void graphics_from_physics(GLInstancingRenderer& renderer, bool syncTransformsOnly) { int cubeShapeIndex = -1; int strideInBytes = sizeof(float)*9; if (!syncTransformsOnly) { int numVertices = sizeof(cube_vertices)/strideInBytes; int numIndices = sizeof(cube_indices)/sizeof(int); cubeShapeIndex = renderer.registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices); } int curGraphicsIndex=0; for(int i=0;i<physics_get_num_rigidbodies();i++) { const PfxRigidState &state = physics_get_state(i); const PfxCollidable &coll = physics_get_collidable(i); const PfxRigidBody& body = physics_get_body(i); float color[4]={0,0,0,1}; if (body.getMass()==0.f) { color[0]=1.f; } else { color[1]=1.f; } 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; PfxQuat ornWorld( worldT.getUpper3x3()); switch(shape.getType()) { case kPfxShapeSphere: printf("render sphere\n"); /*render_sphere( worldT, PfxVector3(1,1,1), PfxFloatInVec(shape.getSphere().m_radius)); */ break; case kPfxShapeBox: { // printf("render box\n"); float cubeScaling[4] = {shape.getBox().m_half.getX(),shape.getBox().m_half.getY(),shape.getBox().m_half.getZ(),1}; float rotOrn[4] = {ornWorld.getX(),ornWorld.getY(),ornWorld.getZ(),ornWorld.getW()}; float position[4]={worldT.getTranslation().getX(),worldT.getTranslation().getY(),worldT.getTranslation().getZ(),0}; if (!syncTransformsOnly) { renderer.registerGraphicsInstance(cubeShapeIndex,position,rotOrn,color,cubeScaling); } else { renderer.writeSingleInstanceTransformToCPU(position,rotOrn,curGraphicsIndex); } curGraphicsIndex++; /* render_box( worldT, PfxVector3(1,1,1), shape.getBox().m_half); */ break; } case kPfxShapeCapsule: printf("render_capsule\n"); /*render_capsule( worldT, PfxVector3(1,1,1), PfxFloatInVec(shape.getCapsule().m_radius), PfxFloatInVec(shape.getCapsule().m_halfLen)); */ break; case kPfxShapeCylinder: printf("render_cylinder\n"); /* render_cylinder( worldT, PfxVector3(1,1,1), PfxFloatInVec(shape.getCylinder().m_radius), PfxFloatInVec(shape.getCylinder().m_halfLen)); */ break; case kPfxShapeConvexMesh: printf("render_mesh\n"); /* render_mesh( worldT, PfxVector3(1,1,1), convexMeshId); */ break; case kPfxShapeLargeTriMesh: printf("render_mesh\n"); /* render_mesh( worldT, PfxVector3(1,1,1), landscapeMeshId); */ break; default: break; } } } }
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(PfxUInt32 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)); const float w = 0.05f; render_debug_line(pA+PfxVector3(-w,0.0f,0.0f),pA+PfxVector3(w,0.0f,0.0f),PfxVector3(0,0,1)); render_debug_line(pA+PfxVector3(0.0f,-w,0.0f),pA+PfxVector3(0.0f,w,0.0f),PfxVector3(0,0,1)); render_debug_line(pA+PfxVector3(0.0f,0.0f,-w),pA+PfxVector3(0.0f,0.0f,w),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 for(int i=0;i<physics_get_num_rays();i++) { const PfxRayInput& rayInput = physics_get_rayinput(i); const PfxRayOutput& rayOutput = physics_get_rayoutput(i); if(rayOutput.m_contactFlag) { render_debug_line( rayInput.m_startPosition, rayOutput.m_contactPoint, PfxVector3(1.0f,0.0f,1.0f)); render_debug_line( rayOutput.m_contactPoint, rayOutput.m_contactPoint+rayOutput.m_contactNormal, PfxVector3(1.0f,0.0f,1.0f)); } else { render_debug_line(rayInput.m_startPosition, rayInput.m_startPosition+rayInput.m_direction, PfxVector3(0.5f,0.0f,0.5f)); } } extern bool doAreaRaycast; extern PfxVector3 areaCenter; extern PfxVector3 areaExtent; if(doAreaRaycast) { render_debug_box(areaCenter,areaExtent,PfxVector3(0,0,1)); } render_debug_end(); render_end(); }
void render(void) { render_begin(); for(int i=0;i<physics_get_num_rigidbodies();i++) { const PfxRigidState &state = physics_get_state(i); const PfxCollidable &coll = physics_get_collidable(i); 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, PfxVector3(1,1,1), PfxFloatInVec(shape.getSphere().m_radius)); break; case kPfxShapeBox: render_box( worldT, PfxVector3(1,1,1), shape.getBox().m_half); break; case kPfxShapeCapsule: render_capsule( worldT, PfxVector3(1,1,1), PfxFloatInVec(shape.getCapsule().m_radius), PfxFloatInVec(shape.getCapsule().m_halfLen)); break; case kPfxShapeCylinder: render_cylinder( worldT, PfxVector3(1,1,1), PfxFloatInVec(shape.getCylinder().m_radius), PfxFloatInVec(shape.getCylinder().m_halfLen)); break; case kPfxShapeConvexMesh: render_mesh( worldT, PfxVector3(1,1,1), convexMeshId); break; case kPfxShapeLargeTriMesh: render_mesh( worldT, PfxVector3(1,1,1), landscapeMeshId); break; default: break; } } } render_end(); }