Cylinder 之 osg:

圓柱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)));
可見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初始化時調用一次,是以并不适用。