对模型最常用的操作莫过于移动了,有很多人不知道如何操作来移动一个模型。现在我们要明确一个事例,也就是说OSG把加入的模型默认都放在中点了,这非常的不好受。其实有些时候并不建议在场景中移动模型,替代的是模型在未加入场景之前位置就是完好的。 移动/旋转/缩放其实都是对矩阵进行操作,在OSG当中,矩阵可以当作一个特殊的结点加入到root当中,而矩阵下也可以另入结点,而加入的结点就会被这个矩阵处理过,比如移动过/旋转过/缩放过。在OSG中控制矩阵的类可以为osg::MatrixTransform。下面看一个示例,示例对osgCool.osg进行了各种操作。程序结构如图1:
图1
程序实例:移动/旋转/缩放模型
功能:移动/旋转/缩放模型,这里加入了四个coolosg,一个是默认加入在最中间,一个向上移2单位,一个是向下移2单位且缩放0.5倍,另一个是向右4单位,缩放0.5且平躺45度。如图2所示。
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/MatrixTransform>
void main()
{
osgViewer::Viewer viewer;
osg::ref_ptr < osg::Group> oot = new osg::Group() ;
osg::ref_ptr < osg::Node> osgcool = osgDB::readNodeFile("osgcool.osg") ;
osg::ref_ptr < osg::MatrixTransform> trans = new osg::MatrixTransform ;
trans ->setMatrix(osg::Matrix::translate(0, 0, 2)) ;
trans ->addChild(osgcool.get()) ;
osg::ref_ptr < osg::MatrixTransform> scale = new osg::MatrixTransform ;
scale ->setMatrix(osg::Matrix::scale(0.5, 0.5, 0.5)*osg::Matrix::translate(0, 0, -2)) ;
scale ->addChild(osgcool.get()) ;
osg::ref_ptr < osg::MatrixTransform > rot = new osg::MatrixTransform ;
rot ->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), 1, 0, 0)*osg::Matrix::scale(0.5, 0.5, 0.5)*osg::Matrix::translate(4, 0, -2)) ;
rot ->addChild(osgcool.get()) ;
root ->addChild(osgcool.get()) ;
root ->addChild(trans.get()) ;
root ->addChild(scale.get()) ;
root ->addChild(rot.get()) ;
viewer.setSceneData(root.get());
viewer.realize();
viewer.run();
}
图2
代码解释:
第10行:读入一个osgcool.osg模型
第12~14行:申请一个矩阵使加入矩阵的东西沿Z轴平移2个单位,在OSG中坐标轴是可以设置的,默认X轴是X轴,向里的是Y轴,而向上是Z轴,这与传统的OPENGL坐标轴多有不同。
第16~18行:申请一个矩阵使加入该矩的模型向下移动两个单位,值得一提的是,移动和缩放以及旋转都是对矩阵进行操作,这些操作如果要叠加直接矩阵相乘就可以了,可以查阅一下矩阵的基本知识,最好看图形学的相关书籍中关于矩阵操作一节。 第20~22行:申请一个矩阵使加入该矩阵的模型向下移动两个单位,向右移动四个单位,且绕X轴转45度。这里的几个矩阵也是叠加的,函数DegreesToRadians可以把角度转为弧度。
第24~27行:把这些矩阵都加入到root当中。