Esempio n. 1
0
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::File& nif)
{
    mShape = new Resource::BulletShape;

    mCompoundShape.reset();
    mStaticMesh.reset();
    mAvoidStaticMesh.reset();

    if (nif.numRoots() < 1)
    {
        warn("Found no root nodes in NIF.");
        return mShape;
    }

    Nif::Record *r = nif.getRoot(0);
    assert(r != nullptr);

    Nif::Node *node = dynamic_cast<Nif::Node*>(r);
    if (node == nullptr)
    {
        warn("First root in file was not a node, but a " +
             r->recName + ". Skipping file.");
        return mShape;
    }

    if (findBoundingBox(node))
    {
        std::unique_ptr<btCompoundShape> compound (new btCompoundShape);

        std::unique_ptr<btBoxShape> boxShape(new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents)));
        btTransform transform = btTransform::getIdentity();
        transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate));
        compound->addChildShape(transform, boxShape.get());
        boxShape.release();

        mShape->mCollisionShape = compound.release();
        return mShape;
    }
    else
    {
        bool autogenerated = hasAutoGeneratedCollision(node);

        // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
        // assume all nodes in the file will be animated
        const auto filename = nif.getFilename();
        const bool isAnimated = pathFileNameStartsWithX(filename);

        handleNode(filename, node, 0, autogenerated, isAnimated, autogenerated);

        if (mCompoundShape)
        {
            if (mStaticMesh)
            {
                btTransform trans;
                trans.setIdentity();
                std::unique_ptr<btCollisionShape> child(new Resource::TriangleMeshShape(mStaticMesh.get(), true));
                mCompoundShape->addChildShape(trans, child.get());
                child.release();
                mStaticMesh.release();
            }
            mShape->mCollisionShape = mCompoundShape.release();
        }
        else if (mStaticMesh)
        {
            mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh.get(), true);
            mStaticMesh.release();
        }

        if (mAvoidStaticMesh)
        {
            mShape->mAvoidCollisionShape = new Resource::TriangleMeshShape(mAvoidStaticMesh.get(), false);
            mAvoidStaticMesh.release();
        }

        return mShape;
    }
}
osg::ref_ptr<Resource::BulletShape> BulletNifLoader::load(const Nif::NIFFilePtr& nif)
{
    mShape = new Resource::BulletShape;

    mCompoundShape = NULL;
    mStaticMesh = NULL;

    if (nif->numRoots() < 1)
    {
        warn("Found no root nodes in NIF.");
        return mShape;
    }

    Nif::Record *r = nif->getRoot(0);
    assert(r != NULL);

    Nif::Node *node = dynamic_cast<Nif::Node*>(r);
    if (node == NULL)
    {
        warn("First root in file was not a node, but a " +
             r->recName + ". Skipping file.");
        return mShape;
    }

    if (findBoundingBox(node))
    {
        std::unique_ptr<btCompoundShape> compound (new btCompoundShape);

        btBoxShape* boxShape = new btBoxShape(getbtVector(mShape->mCollisionBoxHalfExtents));
        btTransform transform = btTransform::getIdentity();
        transform.setOrigin(getbtVector(mShape->mCollisionBoxTranslate));
        compound->addChildShape(transform, boxShape);

        mShape->mCollisionShape = compound.release();
        return mShape;
    }
    else
    {
        bool autogenerated = hasAutoGeneratedCollision(node);
        bool isAnimated = false;

        // files with the name convention xmodel.nif usually have keyframes stored in a separate file xmodel.kf (see Animation::addAnimSource).
        // assume all nodes in the file will be animated
        std::string filename = nif->getFilename();
        size_t slashpos = filename.find_last_of("/\\");
        if (slashpos == std::string::npos)
            slashpos = 0;
        if (slashpos+1 < filename.size() && (filename[slashpos+1] == 'x' || filename[slashpos+1] == 'X'))
        {
            isAnimated = true;
        }

        handleNode(node, 0, autogenerated, isAnimated, autogenerated);

        if (mCompoundShape)
        {
            mShape->mCollisionShape = mCompoundShape;
            if (mStaticMesh)
            {
                btTransform trans;
                trans.setIdentity();
                mCompoundShape->addChildShape(trans, new Resource::TriangleMeshShape(mStaticMesh,true));
            }
        }
        else if (mStaticMesh)
            mShape->mCollisionShape = new Resource::TriangleMeshShape(mStaticMesh,true);

        return mShape;
    }
}