osg模型的移动,旋转和缩放

简述

    和其他三维引擎一样,模型的矩阵操作是比不可少的。 osg中有一个专门的类来处理。即osg::MatrixTransform类。同样osg::MatrixTransform这个类的祖宗类也是osg::Group, 继承类osg::Group所有的特性。所以它可以当一个子节点加入到根节点Root中。也可以当父亲节点添加很多子节点,这样当对它进行移动等矩阵变换时,它所有的子节点都会相应变换。

    这里还涉及到另外一个类osg::Matrixd,这个类是一个矩阵类,被当成参数传入osg::MatrixTransform,以实现模型的矩阵变换。

    其中osg::Matrixd实现了一些静态函数可以直接调用

    移动

    static Matrixd  translate (const Vec3f &dv)
staticMatrixd  translate (const Vec3d &dv)
staticMatrixd 
translate (value_type x, value_type y, value_type z)

    缩放

    static Matrixd  scale (const Vec3f &sv)
staticMatrixd  scale (const Vec3d &sv)
staticMatrixd 
scale (value_type sx, value_type sy, value_type sz)

    旋转

    static Matrixd  rotate (const Vec3f &from, const Vec3f &to)
staticMatrixd  rotate (const Vec3d &from, const Vec3d &to)
staticMatrixd  rotate (value_type angle, value_type x, value_type y, value_type z)
staticMatrixd  rotate (value_type angle, constVec3f &axis)
staticMatrixd 
rotate (value_type angle, const Vec3d &axis)

     矩阵操作的简单流程

    (1) 实例化一个MatrixTransform对象

    osg::ref_ptr mt = new osg::MatrixTransform;

    (2)添加一个子节点

     osg::ref_ptr cow= osgDB::readNodeFile("cow.osg");
     mt->addChild(cow);

    (3)设置矩阵,先向x轴移动30, 绕x轴旋转90度, 再缩放到原来的0.2倍

    mt->setMatrix(osg::Matrix::translate(osg::Vec3(30, 0, 0)) *

                           osg::Matrix::rotate(90, osg::Vec3d(1, 0, 0)) *            

                           osg::Matrix::scale(osg::Vec3(0.2, 0.2, 0.2)) );

    注:--如果 移动和缩放效果要累加,矩阵相乘即可。不能多次调用setMatrix函数,后面的会覆盖掉前面的

           下面的是错误做法,只会缩放到原来的0.2倍

           mt->setMatrix(osg::Matrix::translate(osg::Vec3(30, 0, 0)));

           mt->setMatrix(osg::Matrix::rotate(90, osg::Vec3d(1, 0, 0)));

           mt->setMatrix(osg::Matrix::scale(osg::Vec3(0.2, 0.2, 0.2)));

           --矩阵相乘一般不满足交换律,所有前后顺序不能任意变动,否则会出现不同的效果

           这样设置和上面的效果是不同的

           mt->setMatrix(osg::Matrix::scale(osg::Vec3(0.2, 0.2, 0.2)) *

                                 osg::Matrix::translate(osg::Vec3(30, 0, 0)) *

                                 osg::Matrix::rotate(90, osg::Vec3d(1, 0, 0)));


实现

   

int main()
{
	osg::ref_ptr viewer = new osgViewer::Viewer;
	osg::ref_ptr root = new osg::Group;
	osg::ref_ptr glider = osgDB::readNodeFile("glider.osg");

	osg::ref_ptr mt = new osg::MatrixTransform;
	osg::ref_ptr cow= osgDB::readNodeFile("cow.osg");
	mt->addChild(cow);
	mt->setMatrix( osg::Matrix::translate(osg::Vec3(30, 0, 0)) *  osg::Matrix::rotate(90, osg::Vec3d(1, 0, 0)) * osg::Matrix::scale(osg::Vec3(0.2, 0.2, 0.2)));

	root->addChild(glider);
	root->addChild(mt);

	viewer->setSceneData(root);
	viewer->addEventHandler(new osgViewer::WindowSizeHandler);
	return viewer->run();

	return 0;
}


你可能感兴趣的:(Osg)