btCollisionShape * PhysicsObject::createCollisionShape(CollisionShape * input) { btCollisionShape * colShape = NULL; if (input->type == "box") colShape = new btBoxShape(stringToBTVector3(input->size)/2); else if (input->type == "sphere") colShape = new btSphereShape(stringToBTVector3(input->size).x()/2); else if (input->type == "capsule") colShape = new btCapsuleShape(stringToBTVector3(input->size).x()/2, stringToBTVector3(input->size).y()); else if (input->type == "cylinder") colShape = new btCylinderShape(stringToBTVector3(input->size)/2); else if (input->type == "cylinderX") colShape = new btCylinderShapeX(stringToBTVector3(input->size)/2); else if (input->type == "cylinderZ") colShape = new btCylinderShapeZ(stringToBTVector3(input->size)/2); else if (input->type == "hull") colShape = createConvexHullShape(&(input->vertices)); else colShape = new btBoxShape(btVector3(0.5f, 0.5f, 0.5f)); return colShape; }
btCollisionShape* btBulletWorldImporter::convertCollisionShape( btCollisionShapeData* shapeData ) { btCollisionShape* shape = 0; switch (shapeData->m_shapeType) { case STATIC_PLANE_PROXYTYPE: { btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; btVector3 planeNormal,localScaling; planeNormal.deSerializeFloat(planeData->m_planeNormal); localScaling.deSerializeFloat(planeData->m_localScaling); shape = createPlaneShape(planeNormal,planeData->m_planeConstant); shape->setLocalScaling(localScaling); break; } case GIMPACT_SHAPE_PROXYTYPE: { btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) { btTriangleIndexVertexArray* meshInterface = createMeshInterface(gimpactData->m_meshInterface); btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); btVector3 localScaling; localScaling.deSerializeFloat(gimpactData->m_localScaling); gimpactShape->setLocalScaling(localScaling); gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); gimpactShape->updateBound(); shape = gimpactShape; } else { printf("unsupported gimpact sub type\n"); } break; } case CYLINDER_SHAPE_PROXYTYPE: case CAPSULE_SHAPE_PROXYTYPE: case BOX_SHAPE_PROXYTYPE: case SPHERE_SHAPE_PROXYTYPE: case MULTI_SPHERE_SHAPE_PROXYTYPE: case CONVEX_HULL_SHAPE_PROXYTYPE: { btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; btVector3 implicitShapeDimensions; implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); btVector3 localScaling; localScaling.deSerializeFloat(bsd->m_localScaling); btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin); switch (shapeData->m_shapeType) { case BOX_SHAPE_PROXYTYPE: { shape = createBoxShape(implicitShapeDimensions/localScaling+margin); break; } case SPHERE_SHAPE_PROXYTYPE: { shape = createSphereShape(implicitShapeDimensions.getX()); break; } case CAPSULE_SHAPE_PROXYTYPE: { btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; switch (capData->m_upAxis) { case 0: { shape = createCapsuleShapeX(implicitShapeDimensions.getY(),2*implicitShapeDimensions.getX()); break; } case 1: { shape = createCapsuleShapeY(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getY()); break; } case 2: { shape = createCapsuleShapeZ(implicitShapeDimensions.getX(),2*implicitShapeDimensions.getZ()); break; } default: { printf("error: wrong up axis for btCapsuleShape\n"); } }; break; } case CYLINDER_SHAPE_PROXYTYPE: { btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; btVector3 halfExtents = implicitShapeDimensions+margin; switch (cylData->m_upAxis) { case 0: { shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); break; } case 1: { shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); break; } case 2: { shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); break; } default: { printf("unknown Cylinder up axis\n"); } }; break; } case MULTI_SPHERE_SHAPE_PROXYTYPE: { btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; int numSpheres = mss->m_localPositionArraySize; btAlignedObjectArray<btVector3> tmpPos; btAlignedObjectArray<btScalar> radii; radii.resize(numSpheres); tmpPos.resize(numSpheres); int i; for ( i=0;i<numSpheres;i++) { tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos); radii[i] = mss->m_localPositionArrayPtr[i].m_radius; } shape = new btMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); break; } case CONVEX_HULL_SHAPE_PROXYTYPE: { // int sz = sizeof(btConvexHullShapeData); // int sz2 = sizeof(btConvexInternalShapeData); // int sz3 = sizeof(btCollisionShapeData); btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; int numPoints = convexData->m_numUnscaledPoints; btAlignedObjectArray<btVector3> tmpPoints; tmpPoints.resize(numPoints); int i; for ( i=0;i<numPoints;i++) { #ifdef BT_USE_DOUBLE_PRECISION if (convexData->m_unscaledPointsDoublePtr) tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); if (convexData->m_unscaledPointsFloatPtr) tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); #else if (convexData->m_unscaledPointsFloatPtr) tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); if (convexData->m_unscaledPointsDoublePtr) tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); #endif //BT_USE_DOUBLE_PRECISION } btConvexHullShape* hullShape = createConvexHullShape(); for (i=0;i<numPoints;i++) { hullShape->addPoint(tmpPoints[i]); } shape = hullShape; break; } default: { printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); } } if (shape) { shape->setMargin(bsd->m_collisionMargin); btVector3 localScaling; localScaling.deSerializeFloat(bsd->m_localScaling); shape->setLocalScaling(localScaling); } break; } case TRIANGLE_MESH_SHAPE_PROXYTYPE: { btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; btTriangleIndexVertexArray* meshInterface = createMeshInterface(trimesh->m_meshInterface); if (!meshInterface->getNumSubParts()) { return 0; } btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); meshInterface->setScaling(scaling); btOptimizedBvh* bvh = 0; #if 0 if (trimesh->m_quantizedFloatBvh) { btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh); if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; } else { bvh = createOptimizedBvh(); bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); } } if (trimesh->m_quantizedDoubleBvh) { btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh); if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; } else { bvh = createOptimizedBvh(); bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); } } #endif btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); trimeshShape->setMargin(trimesh->m_collisionMargin); shape = trimeshShape; if (trimesh->m_triangleInfoMap) { btTriangleInfoMap* map = createTriangleInfoMap(); map->deSerialize(*trimesh->m_triangleInfoMap); trimeshShape->setTriangleInfoMap(map); #ifdef USE_INTERNAL_EDGE_UTILITY gContactAddedCallback = btAdjustInternalEdgeContactsCallback; #endif //USE_INTERNAL_EDGE_UTILITY } //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); break; } case COMPOUND_SHAPE_PROXYTYPE: { btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; btCompoundShape* compoundShape = createCompoundShape(); btAlignedObjectArray<btCollisionShape*> childShapes; for (int i=0;i<compoundData->m_numChildShapes;i++) { btCollisionShape* childShape = convertCollisionShape(compoundData->m_childShapePtr[i].m_childShape); if (childShape) { btTransform localTransform; localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); compoundShape->addChildShape(localTransform,childShape); } else { printf("error: couldn't create childShape for compoundShape\n"); } } shape = compoundShape; break; } default: { printf("unsupported shape type (%d)\n",shapeData->m_shapeType); } } return shape; }
void phyMgr::parseUserText(const wcs& node_name, const SPtr<z3D::SG::SNode>& node, const wcs& user_text) { Config* cfg = Config::fromWCS(user_text); if(cfg->exists(L"collision_shape")) { wcs shape_name = cfg->getWString(L"collision_shape"); REAL mass = cfg->getFloat(L"mass"); int32_t compound = cfg->getInt32(L"compound"); if(shape_name == L"box") { if(compound) { SPtr<phyShape> shape = createCompoundWrappedBoxShape(node->local_bound().extent(), node->local_bound().center()); SPtr<phyBody> body = createBody(node, shape, Mat4::identity, mass, false); addBody(body); node->setPhyBody(body); } else { SPtr<phyShape> shape = createBoxShape(node->local_bound().extent()); SPtr<phyBody> body = createBody(node, shape, Mat4::translation(Vec3(node->local_bound().center())), mass, false); addBody(body); node->setPhyBody(body); } } else if(shape_name == L"sphere") { Vec3 ext = node->local_bound().extent(); SPtr<phyShape> shape = createSphereShape((ext[0] + ext[1] + ext[2]) / 3); SPtr<phyBody> body = createBody(node, shape, Mat4::translation(Vec3(node->local_bound().center())), mass, false); addBody(body); node->setPhyBody(body); } else if(shape_name == L"mesh") { if(node->type_info()->kind_of(z3D::SG::SMeshNode::type_info_static())) { SPtr<phyShape> shape = createMeshShape(node.cast<z3D::SG::SMeshNode>()->mesh()); SPtr<phyBody> body = createBody(node, shape, Mat4::identity, mass, true); addBody(body); node->setPhyBody(body); } } else if(shape_name == L"convex_hull") { if(node->type_info()->kind_of(z3D::SG::SMeshNode::type_info_static())) { Vec3 offset; REAL computed_mass; Mat3 inertia_tensor; SPtr<phyShape> shape = createConvexHullShape(node.cast<z3D::SG::SMeshNode>()->mesh(), offset, computed_mass, inertia_tensor); SPtr<phyBody> body = createBody(node, shape, Mat4::translation(offset), mass, mass / computed_mass * Vec3(inertia_tensor[0][0], inertia_tensor[1][1], inertia_tensor[2][2])); addBody(body); node->setPhyBody(body); } } else if(shape_name == L"convex_decomp") { if(node->type_info()->kind_of(z3D::SG::SMeshNode::type_info_static())) { Vec3 offset; REAL computed_mass; Mat3 inertia_tensor; SPtr<phyShape> shape = createDecompConvexHullShape(node.cast<z3D::SG::SMeshNode>()->mesh(), offset, computed_mass, inertia_tensor); SPtr<phyBody> body = createBody(node, shape, Mat4::translation(offset), mass, mass / computed_mass * Vec3(inertia_tensor[0][0], inertia_tensor[1][1], inertia_tensor[2][2])); addBody(body); node->setPhyBody(body); } } } delete cfg; }