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();
}

 

转载于:https://www.cnblogs.com/k5bg/p/11497182.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值