std::vector<match_t> matchBodiesToRings(It begin, It end) { std::vector<match_t> batch; std::transform(begin, end, std::back_inserter(batch), [](b2Body* body) { auto f = body->GetFixtureList(); auto shape = static_cast<b2ChainShape*>(f->GetShape()); return std::make_pair(body, convertShape(body->GetWorldCenter(), shape)); }); return batch; }
void btBulletPhysicsEffectsWorld::createStateAndCollidable(btRigidBody* body) { int objectIndex = body->getBroadphaseProxy()->m_uniqueId; btAssert(objectIndex>=0); //btAssert(objectIndex<m_maxHandles); //initialize it sce::PhysicsEffects::PfxRigidBody* pfxbody = &m_lowLevelBodies[objectIndex]; sce::PhysicsEffects::PfxRigidState* pfxstate = &m_lowLevelStates[objectIndex]; sce::PhysicsEffects::PfxCollidable* pfxcollidable = &m_lowLevelCollidables[objectIndex]; ///convert/initialize body, shape, state and collidable pfxstate->reset(); pfxbody->reset(); pfxcollidable->reset(); pfxbody->setFriction(body->getFriction()); pfxbody->setRestitution(body->getRestitution()); if (body->getInvMass()) { btScalar mass = 1.f/body->getInvMass(); pfxbody->setMass(mass); Vectormath::Aos::Matrix3 inertiaInv = inertiaInv.identity(); inertiaInv.setElem(0,0,body->getInvInertiaDiagLocal().getX()); inertiaInv.setElem(1,1,body->getInvInertiaDiagLocal().getY()); inertiaInv.setElem(2,2,body->getInvInertiaDiagLocal().getZ()); pfxbody->setInertiaInv(inertiaInv); pfxstate->setMotionType(sce::PhysicsEffects::kPfxMotionTypeActive); } else { pfxstate->setMotionType(sce::PhysicsEffects::kPfxMotionTypeFixed); } btAlignedObjectArray<sce::PhysicsEffects::PfxShape> shapes; convertShape(body->getCollisionShape(), shapes); btAssert(shapes.size()>0); if (shapes.size()==1) { pfxcollidable->addShape(shapes[0]); pfxcollidable->finish(); } else { if (shapes.size()>1) { sce::PhysicsEffects::PfxUInt16* ints=new sce::PhysicsEffects::PfxUInt16[shapes.size()]; sce::PhysicsEffects::PfxShape* pfxshapes = new sce::PhysicsEffects::PfxShape[shapes.size()]; int p; for (p=0;p<shapes.size();p++) { ints[p]=p; pfxshapes[p] = shapes[p]; } pfxcollidable->reset(pfxshapes,ints,shapes.size()); for (p=0;p<shapes.size();p++) { pfxcollidable->addShape(pfxshapes[p]); } pfxcollidable->finish(); } } pfxstate->setRigidBodyId(objectIndex); syncRigidBodyState(body); }
static void convertShape(btCollisionShape* bulletShape, btAlignedObjectArray<sce::PhysicsEffects::PfxShape>& shapes) { switch (bulletShape->getShapeType()) { case BOX_SHAPE_PROXYTYPE: { btBoxShape* boxshape = (btBoxShape*)bulletShape; sce::PhysicsEffects::PfxBox box(boxshape->getHalfExtentsWithMargin().getX(),boxshape->getHalfExtentsWithMargin().getY(),boxshape->getHalfExtentsWithMargin().getZ()); sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setBox(box); break; } case TRIANGLE_MESH_SHAPE_PROXYTYPE: { btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) bulletShape; int numSubParts = trimesh->getMeshInterface()->getNumSubParts(); btAssert(numSubParts>0); for (int i=0;i<numSubParts;i++) { unsigned char* vertexBase=0; int numVerts = 0; PHY_ScalarType vertexType; int vertexStride=0; unsigned char* indexBase=0; int indexStride=0; int numFaces=0; PHY_ScalarType indexType; trimesh->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numVerts,vertexType,vertexStride,&indexBase,indexStride,numFaces,indexType,i); sce::PhysicsEffects::PfxCreateLargeTriMeshParam param; btAssert(param.flag&SCE_PFX_MESH_FLAG_16BIT_INDEX); unsigned short int* copyIndices = new unsigned short int[numFaces*3]; switch (indexType) { case PHY_UCHAR: { for (int p=0;p<numFaces;p++) { copyIndices[p*3]=indexBase[p*indexStride]; copyIndices[p*3+1]=indexBase[p*indexStride+1]; copyIndices[p*3+2]=indexBase[p*indexStride+2]; } break; } //PHY_INTEGER: //PHY_SHORT: default: { btAssert(0); } }; param.verts = (float*)vertexBase; param.numVerts = numVerts; param.vertexStrideBytes = vertexStride; param.triangles = copyIndices; param.numTriangles = numFaces; param.triangleStrideBytes = sizeof(unsigned short int)*3; sce::PhysicsEffects::PfxLargeTriMesh* largeMesh = new sce::PhysicsEffects::PfxLargeTriMesh(); sce::PhysicsEffects::PfxInt32 ret = pfxCreateLargeTriMesh(*largeMesh,param); if(ret != SCE_PFX_OK) { SCE_PFX_PRINTF("Can't create large mesh.\n"); } sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setLargeTriMesh(largeMesh); } break; } case SPHERE_SHAPE_PROXYTYPE: { btSphereShape* sphereshape = (btSphereShape*)bulletShape; sce::PhysicsEffects::PfxSphere sphere(sphereshape->getRadius()); sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setSphere(sphere); break; } case CAPSULE_SHAPE_PROXYTYPE: { btCapsuleShape* capsuleshape= (btCapsuleShape*)bulletShape;//assume btCapsuleShapeX for now sce::PhysicsEffects::PfxCapsule capsule(capsuleshape->getHalfHeight(),capsuleshape->getRadius()); sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setCapsule(capsule); break; } case CYLINDER_SHAPE_PROXYTYPE: { btCylinderShape* cylindershape= (btCylinderShape*)bulletShape;//assume btCylinderShapeX for now sce::PhysicsEffects::PfxCylinder cylinder(cylindershape->getHalfExtentsWithMargin()[0],cylindershape->getRadius()); sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setCylinder(cylinder); break; } case CONVEX_HULL_SHAPE_PROXYTYPE: { btConvexHullShape* convexHullShape = (btConvexHullShape*)bulletShape; sce::PhysicsEffects::PfxConvexMesh* convex = new sce::PhysicsEffects::PfxConvexMesh(); convex->m_numVerts = convexHullShape->getNumPoints(); convex->m_numIndices = 0;//todo for ray intersection test support for (int i=0;i<convex->m_numVerts;i++) { convex->m_verts[i].setX(convexHullShape->getPoints()[i].getX()); convex->m_verts[i].setY(convexHullShape->getPoints()[i].getY()); convex->m_verts[i].setZ(convexHullShape->getPoints()[i].getZ()); } convex->updateAABB(); sce::PhysicsEffects::PfxShape& shape = shapes.expand(); shape.reset(); shape.setConvexMesh(convex); break; } case COMPOUND_SHAPE_PROXYTYPE: { btCompoundShape* compound = (btCompoundShape*) bulletShape; for (int s=0;s<compound->getNumChildShapes();s++) { convertShape(compound->getChildShape(s),shapes); sce::PhysicsEffects::PfxMatrix3 rotMat = getVmMatrix3(compound->getChildTransform(s).getBasis()); sce::PhysicsEffects::PfxVector3 translate = getVmVector3(compound->getChildTransform(s).getOrigin()); sce::PhysicsEffects::PfxTransform3 childtransform(rotMat,translate); shapes[shapes.size()-1].setOffsetTransform(childtransform); } break; } default: { btAssert(0); } }; }