天天看點

osg、bullet之 Cylinder比較與比對

Cylinder 之 osg:

osg、bullet之 Cylinder比較與比對

圓柱Cylinder:質心(0.0, 0.0, 0.0),半徑和高1.0,圓柱的軸與z平行。

osg::Cylinder* cylinder = new osg::Cylinder(osg::Vec3(1.0f, 0.0f, 0.0f), radius * 0.5, height * 1.0);
cylinder->setRotation(osg::Quat(osg::PI_4, osg::Vec3(0.0, 1.0, 0.0)));
           
osg、bullet之 Cylinder比較與比對

可見cylinder可以通過矩陣變換接口對圓柱原始頂點做平移與旋轉操作,且順序為先旋轉後平移。

Cylinder 之 bullet

bullet中btCylinderShapeZ(btVector3(0.5, 0.5, 0.5))與osg::Cylinder()等價,差別在于bullet沒有提供初始矩陣去修改碰撞模型的原始頂點,為了達到這一效果我們可以繼承btMotionState類通過重寫矩陣接口,添加相應的初始矩陣

class KinematicMatrixTransform: public osg::MatrixTransform, public btMotionState
{
    typedef osg::MatrixTransform inherited;
    typedef btMotionState inheritedbt;
public:
    KinematicMatrixTransform(osg::Matrix start = osg::Matrix::identity(), osg::Matrix offset = osg::Matrix::identity())
        :mWorldTrans(tobtMatrix(start)), mOffsetTrans(tobtMatrix(offset)){}

    void setMatrix(const osg::Matrix& mat)
    {
        inherited::setMatrix(mat);
        setWorldTransform(tobtMatrix(mat));
    }

    virtual void getWorldTransform(btTransform & worldTrans) const
    {
        worldTrans = mWorldTrans * mOffsetTrans;
    }

    virtual void setWorldTransform(const btTransform& worldTrans)
    {
        mWorldTrans = worldTrans;
    }

private:
    osg::Matrix toMatrix(const btTransform& t)
    {
        btScalar ogl[16];
        t.getOpenGLMatrix(ogl);
        osg::Matrix m(ogl);
        return m;
    }

    btTransform tobtMatrix(osg::Matrix m)
    {
        const osg::Matrix::value_type* oPtr = m.ptr();
        btScalar bPtr[16];
        int idx;
        for (idx=0; idx<16; idx++)
            bPtr[idx] = oPtr[idx];
        btTransform t;
        t.setFromOpenGLMatrix(bPtr);
        return t;
    }

private:
    btTransform mWorldTrans;
    btTransform mOffsetTrans;
};
           

該類重點在于對btMotionState虛函數:getWorldTransform、setWorldTransform的實作;成員變量mOffsetTrans用于存儲osg::Cylinder的 rotate * translate矩陣。

-------------------------------------------------------注意事項!---------------------------------------------------------------

bullet中總共有三種剛體Static, Dynamic and Kinematic ,KinematicMatrixTransform主要用于解決Kinematic類型與osg可視化模型的比對,由于Dynamic和static類型的剛體getWorldTransform隻會在bullet初始化時調用一次,是以并不适用。