OSG:幼儿园篇 第三章 节点坐标变换类
一.简介
osg::Transform 位置类继承于 osg::Group 组节点类
osg::PositionAttitudeTransform 位置变换类继承于 osg::Transform 位置类
osg::MatrixTransform 矩阵变换类继承于 osg::Transform 位置类
在OSG的坐标轴中,X轴永远向右边为正,Y轴向后边为正,Z轴向上为正
二.osg::PositionAttitudeTransform 位置变换类
1.类定义
class OSG_EXPORT PositionAttitudeTransform : public Transform { public:
//构造函数
PositionAttitudeTransform();
PositionAttitudeTransform(const PositionAttitudeTransform& pat, const CopyOp& copyop = CopyOp::SHALLOW_COPY):
Transform(pat, copyop), _position(pat._position), _attitude(pat.attitude), _scale(pat._scale), _pivotPoint(pat._pivotPoint){}
META_Node(osg, PositionAttitudeTransform);
virtual PositionAttitudeTransform* asPositionAttitudeTransform() {return this;}
virtual const PositionAttitudeTransform* asPositionAttitudeTransform() const {return this;}
//移动 inline void setPosition(const Vec3& pos) {_position = pos; dirtyBound();} inline const Vec3d& getPosition() const {return _position} //旋转 inline void setAttitude(const Quat& quat) {_attitude = quat; dirtyBound();} inline const Quat& getAttitude() const {return _attitude;} //缩放 inline void setScale(const Vec3d& scale) {_scale = scale; dirtyBound();} inline const Vec3d& getScale() const {return _scale;} inline void setPivotPoint(const Vec3d& pivot) {_pivotPoint = pivot; dirtyBound();} inline const Vec3d& getPivotPoint() const {return _pivotPoint;}
virtual bool computeLocalToWorldMatrix(Matrix& matrix, NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(Matrix& matrix, NodeVisitor* nv) const;
protected:
virtual ~PositionAttitudeTransform() {}
Vec3d _position;
Quat _attitude;
Vec3d _scale;
Vec3d _pivotPoint; };
2.使用步骤
#include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/Group> #include <osgFX/Scribe> #include <osgGA/GUIEventHandler> #include <osgUtil/LineSegmentIntersector> #include <osg/PositionAttitudeTransform> osg::ref_ptr<osg::Node> CreateNode() { osg::ref_ptr<osg::Group> _root = new osg::Group; //创建一个节点,读取牛的模型 osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg"); //创建位置变换节点pat1,缩放 osg::ref_ptr<osg::PositionAttitudeTransform> pat1 = new osg::PositionAttitudeTransform; //设置位置为-10 0 0 pat1->setPosition(osg::Vec3(0.0f, 0.0f, 0.0f)); //设置缩放在X Y Z 都缩放一倍 pat1->setScale(osg::Vec3(0.5f, 0.5f, 0.5f)); //把牛放到这个位置变化节点中去 pat1->addChild(node.get()); _root->addChild(pat1.get()); //创建位置变换节点pat2 平移位置 osg::ref_ptr<osg::PositionAttitudeTransform> pat2 = new osg::PositionAttitudeTransform; //设置位置10,0,0 pat2->setPivotPoint(osg::Vec3(0.0f, -100.0f, 0.0f)); pat2->setPosition(osg::Vec3(0.0f, -100.0f, 0.0f)); pat2->addChild(node.get()); _root->addChild(pat2.get()); //创建位置变换节点pat3,改变姿态 osg::ref_ptr<osg::PositionAttitudeTransform> pat3 = new osg::PositionAttitudeTransform; //设置位置10,0,0 pat3->setPosition(osg::Vec3(0.0f, 0.0f, 0.0f)); //姿态变换,绕着osg::Vec3(0.0f, 1.0f, 0.0)把物体旋转osg::PI个弧度 pat3->setAttitude(osg::Quat(osg::PI, osg::Vec3(0.0f, 1.0f, 0.0f))); pat3->addChild(node.get()); //_root->addChild(pat3.get()); return _root.get(); } int main(int, char**) { osgViewer::Viewer viewer; viewer.setSceneData(CreateNode()); //viewer.addEventHandler(new CPickHandler(&viewer)); viewer.realize(); viewer.run(); return 0; }
三.osg::MatrixTransform 矩阵变换节点
osg中正确的矩阵变换级联顺序应该是:缩放(scale) 旋转(rotate) 平移(translate),简称为SRT,顺序不同将导致结果不同
osg是行矩阵,进行左乘操作;
[1, 0, 0, 0]
[0, 1, 0, 0]
[0, 0, 1, 0]
[x, y, z, 1]
class OSG_EXPORT MatrixTransform : public Transform { public: MatrixTransform(); MatrixTransform(const MatrixTransform&, const CopyOp& copyop = CopyOp::SHALLOW_COPY); MatrixTransform(const Matrix& matrix); META_Node(osg, MatrixTransform); virtual MatrixTransform* asMatrixTrasnform() {return this;} virtual const MatrixTransform* asMatrixTransform() const {return this;} void setMatrix(const Matrix& mat) {_matrix = mat; _inverseDirty = true; dirtyBound();} inline const Matrix& getMatrix() const {return _matrix;} void preMult(const Matrix& mat) {_matrix.preMult(mat); _inverseDirty = true; dirtyBound();} void postMult(const Matrix& mat) {_matrix.postMult(mat); _inverseDirty = true; dirtyBound();} inline const Matrix& getInverseMatrix() const { if(_inverseDirty) { _inverse.invert(_matrix); _inverseDirty = false; } return _inverse; } virtual bool computeLocalToWorldMatrix(Matrix& matrix, NodeVisitor*) const; virtual bool computeWorldToLocalMatrix(Matrix& matrix, NodeVisitor*) const; protected: virtual ~MatrixTransform(); Matrix _matrix; mutable Matrix _inverse; mutable bool _inverseDirty; };
osg::ref_ptr<osg::Node> CreateNode1() { osg::ref_ptr<osg::Group> _root = new osg::Group; osg::ref_ptr<osg::Node> _node = osgDB::readNodeFile("cow.osg"); osg::ref_ptr<osg::MatrixTransform> _mt = new osg::MatrixTransform; osg::Matrix _m; _m.makeTranslate(osg::Vec3(10.0f, 0.0f, 0.0f)); //X方向平移10个单位 _m.makeRotate(45.0f, osg::Vec3(1.0f, 0.0f, 0.0f)); //绕着后面这个轴转45度 _mt->setMatrix(_m); _mt->addChild(_node.get()); //构造一个变换矩阵节点 osg::ref_ptr<osg::MatrixTransform> _mt1 = new osg::MatrixTransform; //创建一个矩阵对象 //要达到叠加效果,需要矩阵相乘,以下两种方式可以得到 //osg::Matrix _m1 = osg::Matrix::translate(osg::Vec3(-10.0f, 0.0f, 0.0f) * osg::Matrix::rotate(-45.0f, osg::Vec3(1.0f, 0.0f, 0.0f))); osg::Matrix _m1, _m2; _m1.makeTranslate(osg::Vec3(-10.0f, 0.0f, 0.0f)); //向X方向平移10个单位 _m2.makeRotate(-45.0f, osg::Vec3(1.0f, 0.0f, 0.0f)); //绕着后面这个轴转-45度 _m1 = _m1 * _m2; _mt1->setMatrix(_m1); _mt1->addChild(_node.get()); _root->addChild(_mt.get()); _root->addChild(_mt1.get()); _root->addChild(_node.get()); return _root.get(); }