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

来源:互联网 发布:怎么学好数据库 编辑:程序博客网 时间:2024/05/16 17:51

简述

    和其他三维引擎一样,模型的矩阵操作是比不可少的。 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<osg::MatrixTransform> mt = new osg::MatrixTransform;

    (2)添加一个子节点

     osg::ref_ptr<osg::Node> 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<osgViewer::Viewer> viewer = new osgViewer::Viewer;osg::ref_ptr<osg::Group> root = new osg::Group;osg::ref_ptr<osg::Node> glider = osgDB::readNodeFile("glider.osg");osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;osg::ref_ptr<osg::Node> 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;}