其实,无需关心osg矩阵是如何实现的.但是要记住的是osg中采用的左乘操作,我们平时里讨论的操作如旋转平移等。
OpenGL的: newpos = R* T * oldpos //先执行平移 后执行 旋转 (全局坐标系)
osg当中: newpos =oldpos * T *R //先执行平移 后执行旋转 (全局坐标系)
因为在osg当中矩阵执行的操作则是行矩阵操作.因此为了跟OpenGL的列矩阵做同步 而不在定义的时候就相当于做了一个转置操作.即
你只需牢记 在OSG当中变换的步骤则是左乘操作(全局坐标系)..即左边的是先执行变换的.
谈完如上的那些之后.我们现在来看MatrixTransform 和PositionAttitudeTransform.
参考坐标系有三种
RELATIVE_RF, //全局 相对 ()
ABSOLUTE_RF, //局部 绝对 ()
ABSOLUTE_RF_INHERIT_VIEWPOINT //基于视点一个局部坐标系.很少用到.
MatrixTransform 故名 矩阵变换节点.在位于它的节点之下的节点都将按照这它的矩阵变换来进行模型变换操作.因此 MatrixTransform的主要功能之一就是提供模型变换操作..你只要根据你所需要的设置其模型矩阵就行.
即执行 setMatrix() 因此.查看计算当前World矩阵的方法就可以很清晰的明白其最后结果就是:
如果是相对的.那么 先执行自身的变换,在执行父节点的变换操作.这类似OpenGL中后写的变换是先执行的一样(全局坐标系考虑)
否则是绝对的,那么当前矩阵就是自身矩阵
#include <osg/NodeCallback>
#include <osg/PositionAttitudeTransform>
#include <osgViewer/Viewer>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
//旋转控制
/*
int main()
{
//创建XYZ坐标节点
osg::Node* axesNode = NULL;
//根节点
osg::Group* root = new osg::Group();
osgViewer::Viewer viewer;
//读入axes.osg
axesNode = osgDB::readNodeFile("axes.osg");
//旋转度到弧度
float iRadians = osg::DegreesToRadians(-45.0);
//旋转弧度到度
float iDegress = osg::RadiansToDegrees(1.2);
//创建一个四元数来控制旋转弧度
osg::Quat quat(iRadians, osg::Vec3(1,0,0));
//创建位置变换节点
osg::MatrixTransform* axesXform;
axesXform = new osg::MatrixTransform();
//创建变换实例
osg::Matrixd mat;
//旋转45度
mat.makeRotate(quat);
axesXform->setMatrix(mat);
axesXform->addChild(axesNode);
root->addChild(axesXform);
viewer.setSceneData(root);
viewer.realize();
return viewer.run();
}
*/
osg::Group* createTrans()
{
osg::Group* root = new osg::Group;
//创建姿态节点
osg::PositionAttitudeTransform* posCow = new osg::PositionAttitudeTransform;
root->addChild(posCow);
//创建变换节点
osg::MatrixTransform* matrixCow = new osg::MatrixTransform;
root->addChild(matrixCow);
//牛
osg::Node* cow = osgDB::readNodeFile("cow.osg");
posCow->addChild(cow);
osg::Quat quat;
//旋转
quat.makeRotate(osg::PI_2,osg::Vec3(0.0,0.0,1.0));
posCow->setAttitude(quat);
//设置位置
posCow->setPosition(osg::Vec3(-10,0.0,0.0));
matrixCow->addChild(cow);
//旋转
quat.makeRotate(osg::DegreesToRadians(60.0),osg::Vec3(0.0,0.0,1.0));
//设置位置
matrixCow->setMatrix(osg::Matrixd::translate(osg::Vec3(10.0,0.0,0.0))*osg::Matrixd::rotate(quat));
return root;
}
int main()
{
//根节点
osg::Group* root = new osg::Group();
root = createTrans();
osgViewer::Viewer viewer;
//创建节点到场景中
viewer.setSceneData(root);
viewer.realize();
return viewer.run();
}