Beispiel #1
0
void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform,
                                       bool isAnimated, bool avoid)
{
    assert(shape != nullptr);

    // If the object was marked "NCO" earlier, it shouldn't collide with
    // anything. So don't do anything.
    if ((flags & 0x800))
    {
        return;
    }

    if (!shape->skin.empty())
        isAnimated = false;

    if (shape->data.empty())
        return;
    if (shape->data->triangles.empty())
        return;

    if (isAnimated)
    {
        if (!mCompoundShape)
            mCompoundShape.reset(new btCompoundShape);

        std::unique_ptr<btTriangleMesh> childMesh(new btTriangleMesh);

        fillTriangleMesh(*childMesh, shape->data.get());

        std::unique_ptr<Resource::TriangleMeshShape> childShape(new Resource::TriangleMeshShape(childMesh.get(), true));
        childMesh.release();

        float scale = shape->trafo.scale;
        const Nif::Node* parent = shape;
        while (parent->parent)
        {
            parent = parent->parent;
            scale *= parent->trafo.scale;
        }
        osg::Quat q = transform.getRotate();
        osg::Vec3f v = transform.getTrans();
        childShape->setLocalScaling(btVector3(scale, scale, scale));

        btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z()));

        mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));

        mCompoundShape->addChildShape(trans, childShape.get());
        childShape.release();
    }
    else if (avoid)
    {
        if (!mAvoidStaticMesh)
            mAvoidStaticMesh.reset(new btTriangleMesh(false));

        fillTriangleMeshWithTransform(*mAvoidStaticMesh, shape->data.get(), transform);
    }
    else
    {
        if (!mStaticMesh)
            mStaticMesh.reset(new btTriangleMesh(false));

        // Static shape, just transform all vertices into position
        fillTriangleMeshWithTransform(*mStaticMesh, shape->data.get(), transform);
    }
}
void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const osg::Matrixf &transform, bool isAnimated)
{
    assert(shape != NULL);

    // If the object was marked "NCO" earlier, it shouldn't collide with
    // anything. So don't do anything.
    if ((flags & 0x800))
    {
        return;
    }

    if (!shape->skin.empty())
        isAnimated = false;

    if (shape->data.empty())
        return;
    if (shape->data->triangles.empty())
        return;

    if (isAnimated)
    {
        if (!mCompoundShape)
            mCompoundShape = new btCompoundShape();

        btTriangleMesh* childMesh = new btTriangleMesh();

        const Nif::NiTriShapeData *data = shape->data.getPtr();

        childMesh->preallocateVertices(data->vertices.size());
        childMesh->preallocateIndices(data->triangles.size());

        const std::vector<osg::Vec3f> &vertices = data->vertices;
        const std::vector<unsigned short> &triangles = data->triangles;

        for(size_t i = 0;i < data->triangles.size();i+=3)
        {
            osg::Vec3f b1 = vertices[triangles[i+0]];
            osg::Vec3f b2 = vertices[triangles[i+1]];
            osg::Vec3f b3 = vertices[triangles[i+2]];
            childMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
        }

        Resource::TriangleMeshShape* childShape = new Resource::TriangleMeshShape(childMesh,true);

        float scale = shape->trafo.scale;
        const Nif::Node* parent = shape;
        while (parent->parent)
        {
            parent = parent->parent;
            scale *= parent->trafo.scale;
        }
        osg::Quat q = transform.getRotate();
        osg::Vec3f v = transform.getTrans();
        childShape->setLocalScaling(btVector3(scale, scale, scale));

        btTransform trans(btQuaternion(q.x(), q.y(), q.z(), q.w()), btVector3(v.x(), v.y(), v.z()));

        mShape->mAnimatedShapes.insert(std::make_pair(shape->recIndex, mCompoundShape->getNumChildShapes()));

        mCompoundShape->addChildShape(trans, childShape);
    }
    else
    {
        if (!mStaticMesh)
            mStaticMesh = new btTriangleMesh(false);

        // Static shape, just transform all vertices into position
        const Nif::NiTriShapeData *data = shape->data.getPtr();
        const std::vector<osg::Vec3f> &vertices = data->vertices;
        const std::vector<unsigned short> &triangles = data->triangles;

        mStaticMesh->preallocateVertices(data->vertices.size());
        mStaticMesh->preallocateIndices(data->triangles.size());

        size_t numtris = data->triangles.size();
        for(size_t i = 0;i < numtris;i+=3)
        {
            osg::Vec3f b1 = vertices[triangles[i+0]]*transform;
            osg::Vec3f b2 = vertices[triangles[i+1]]*transform;
            osg::Vec3f b3 = vertices[triangles[i+2]]*transform;
            mStaticMesh->addTriangle(getbtVector(b1), getbtVector(b2), getbtVector(b3));
        }
    }
}