예제 #1
0
const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) {
    btCollisionShape* shape = NULL;
    int type = info.getType();
    switch(type) {
        case SHAPE_TYPE_BOX: {
            shape = new btBoxShape(glmToBullet(info.getHalfExtents()));
        }
        break;
        case SHAPE_TYPE_SPHERE: {
            glm::vec3 halfExtents = info.getHalfExtents();
            float radius = glm::max(halfExtents.x, glm::max(halfExtents.y, halfExtents.z));
            shape = new btSphereShape(radius);
        }
        break;
        case SHAPE_TYPE_ELLIPSOID: {
            glm::vec3 halfExtents = info.getHalfExtents();
            float radius = halfExtents.x;
            const float MIN_RADIUS = 0.001f;
            const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f;
            if (radius > MIN_RADIUS
                    && fabsf(radius - halfExtents.y) / radius < MIN_RELATIVE_SPHERICAL_ERROR
                    && fabsf(radius - halfExtents.z) / radius < MIN_RELATIVE_SPHERICAL_ERROR) {
                // close enough to true sphere
                shape = new btSphereShape(radius);
            } else {
                ShapeInfo::PointList points;
                points.reserve(NUM_UNIT_SPHERE_DIRECTIONS);
                for (uint32_t i = 0; i < NUM_UNIT_SPHERE_DIRECTIONS; ++i) {
                    points.push_back(bulletToGLM(_unitSphereDirections[i]) * halfExtents);
                }
                shape = createConvexHull(points);
            }
        }
        break;
        case SHAPE_TYPE_CAPSULE_Y: {
            glm::vec3 halfExtents = info.getHalfExtents();
            float radius = halfExtents.x;
            float height = 2.0f * halfExtents.y;
            shape = new btCapsuleShape(radius, height);
        }
        break;
        case SHAPE_TYPE_COMPOUND:
        case SHAPE_TYPE_SIMPLE_HULL: {
            const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
            uint32_t numSubShapes = info.getNumSubShapes();
            if (numSubShapes == 1) {
                shape = createConvexHull(pointCollection[0]);
            } else {
                auto compound = new btCompoundShape();
                btTransform trans;
                trans.setIdentity();
                foreach (const ShapeInfo::PointList& hullPoints, pointCollection) {
                    btConvexHullShape* hull = createConvexHull(hullPoints);
                    compound->addChildShape(trans, hull);
                }
                shape = compound;
            }
        }
        break;
        case SHAPE_TYPE_SIMPLE_COMPOUND: {
            const ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
            const ShapeInfo::TriangleIndices& triangleIndices = info.getTriangleIndices();
            uint32_t numIndices = triangleIndices.size();
            uint32_t numMeshes = info.getNumSubShapes();
            const uint32_t MIN_NUM_SIMPLE_COMPOUND_INDICES = 2; // END_OF_MESH_PART + END_OF_MESH
            if (numMeshes > 0 && numIndices > MIN_NUM_SIMPLE_COMPOUND_INDICES) {
                uint32_t i = 0;
                std::vector<btConvexHullShape*> hulls;
                for (auto& points : pointCollection) {
                    // build a hull around each part
                    while (i < numIndices) {
                        ShapeInfo::PointList hullPoints;
                        hullPoints.reserve(points.size());
                        while (i < numIndices) {
                            int32_t j = triangleIndices[i];
                            ++i;
                            if (j == END_OF_MESH_PART) {
                                // end of part
                                break;
                            }
                            hullPoints.push_back(points[j]);
                        }
                        if (hullPoints.size() > 0) {
                            btConvexHullShape* hull = createConvexHull(hullPoints);
                            hulls.push_back(hull);
                        }

                        assert(i < numIndices);
                        if (triangleIndices[i] == END_OF_MESH) {
                            // end of mesh
                            ++i;
                            break;
                        }
                    }
                }
                uint32_t numHulls = (uint32_t)hulls.size();
                if (numHulls == 1) {
                    shape = hulls[0];
                } else {
                    auto compound = new btCompoundShape();
                    btTransform trans;
                    trans.setIdentity();
                    for (auto hull : hulls) {
                        compound->addChildShape(trans, hull);
                    }
                    shape = compound;
                }
            }
        }
        break;
        case SHAPE_TYPE_STATIC_MESH: {
            btTriangleIndexVertexArray* dataArray = createStaticMeshArray(info);
            if (dataArray) {
                shape = new StaticMeshShape(dataArray);
            }
        }
        break;
    }
예제 #2
0
파일: PhysicsMgr.cpp 프로젝트: RileyA/LD21
PhysicsObject* PhysicsMgr::createConvexHull(GfxObject* object,Ogre::Vector3 pos)
{
	return createConvexHull(object->getEntity()->getMesh()->getName(),pos);
}