• 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();
    }
  • 相关阅读:
    突然想写一篇有关欧拉函数的博客
    洛谷P1199 三国游戏——题解
    洛谷P1310 表达式的值——题解
    洛谷P1309 瑞士轮——题解
    洛谷P1077 摆花——题解
    size_t是什么?
    c++ bitset——一个有趣的类型
    有关文件操作的总结
    一本通&&洛谷 ——靶型数独——题解
    一本通【例题4】Addition Chains——题解
  • 原文地址:https://www.cnblogs.com/k5bg/p/11497182.html
Copyright © 2020-2023  润新知