OSG学习笔记-Group(2-3-1)-PositionAttitudeTransform/MatixTransform/AutoTransform

2.3 Group

​ osg::Group类是OSG的根节点,它允许用户程序为其添加任意数量的子节点,子节点也可以继续分发子节点。osg::Group作为一个基类,派生出了很多节点类,如osg::LOD、osg::Switch、osg::Transform、osg::PositionAttitudeTransform、osg::PagedLOD、osg::Impostor和osg::AutoTransform等。

​ osg::Group类是从osg::Referenced类派生出来的,在通常情况下,只有父节点引用这个Group对象,所以当释放场景图的根节点时,会引发连锁的内存释放动作,这样就不会产生内存的泄漏。

​ osg::Group类作为OSG的核心部分,可以使用户程序通过Group来有效地组织场景中的数据,osg::Group类的强大之处在于管理节点的接口,同时,osg::Group类还从osg::Node类继承了用于管理父节点的接口,OSG允许节点有多个父节点。

2.3.1 位置变换节点

​ 位置变换节点(osg::PositionAttitudeTransform)是一个位置变换节点,继承自osg::Transform,主要作用是提供模型的位置变换大小缩放原点位置的设置以及坐标系的变换
​ osg::PositionAttitudeTransform的常用成员函数

函数名称说明
void setPosition(const Vec3d& pos)设置位置
const Vec3d& getPosition()const获取位置
void setAttitude(const Quat& quat)设置姿态,参数为四元数
const Quat& getQuat() const获取姿态
void setScale(const Vec3d& scale)设置缩放
const Vec3d& getScale() const获取缩放系数
const setPivodPoint(const Vec3d&pivot)设置原点
const Vec3d& getPivodPoint()const获取原点

2.3.2 位置变换节点示例

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/PositionAttitudeTransform>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
int main()
{
    // 创建VIewer对象,场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group>root = new osg::Group();
    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    
    osg::ref_ptr<osg::PositionAttitudeTransform> pat1 = new osg::PositionAttitudeTransform();
    pat1->setPosition(osg::Vec3(-10.f,0.0f,0.0f));
    pat1->setScale(osg::Vec3(0.5f,0.5f,0.5f));
    pat1->addChild(node.get());
    
    osg::ref_ptr<osg::PositionAttitudeTransform> pat2 = new osg::PositionAttitudeTransform();
    pat2->setPosition(osg::Vec3(10.0f,0.0f,0.0f));
    pat2->addChild(node.get());
    
    root->addChild(pat1.get());
    root->addChild(pat2.get());
    
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;
}

2.3.3 矩阵变换节点

​ 矩阵变换节点(osg::MatixTransform)同样继承自osg::Transfom,其主要作用是负责场景中的矩阵变换、矩阵的原酸以及坐标系的变换
​ osg::MatrixTransform的常用成员函数如下表:

成员函数名称说明
void setMatrix(const Matrix&mat)设置矩阵
const Matrix& getMatrix()const获取矩阵
void preMult(const Matrix&mat)递乘,类似于++a
void postMult(const Matrix&mat)递乘,类似于a++
const Matrix&getInverseMatrix()const获取逆矩阵

2.3.4 矩阵变换节点示例

#include<osgViewer/Viewer>

#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/MatrixTransform>

#include<osgDB/ReadFile>
#include<osgDB/WriteFile>

#include<osgUtil/Optimizer>
int main()
{
    // 创建VIewer对象,场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group>root = new osg::Group();
    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    
    osg::ref_ptr<osg::MatrixTransform> mt1 = new osg::MatrixTransform();
    osg::Matrix m;
    m.makeTranslate(osg::Vec3(10.0f,0.0f,0.0f));// 平移
    m.makeRotate(45.0f,1.0f,0.0f,0.0f);// 绕X轴转45°
    mt1->setMatrix(m);
    mt1->addChild(node.get());
    
    osg::ref_ptr<osg::MatrixTransform> mt2 = new osg::MatrixTransform();
    osg::Matrix t;
    t.makeTranslate(osg::Vec3(-10.0f,0.0f,0.0f));// 平移
    mt2->setMatrix(t);
    mt2->addChild(node.get());
    
    root->addChild(mt1.get());
    root->addChild(mt2.get());
    
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;
}

2.3.5 自动对齐节点

​ 自动对齐节点(osg::AutoTransform)也继承自osg::Transform,它的主要作用是使节点自动对齐于摄像机或者屏幕。在实际应用中,通常可以用来显示一些不变化的文字或者其它的标识
​ osg::AutoTransform有如下3种对齐模式:

enum AutoRotateMode
{
    NO_ROTATION,     // 无旋转
    ROTATE_TO_SCREEN,// 自动朝向屏幕
    ROTATE_TO_CAMERA // 自动朝向相机
}

2.3.6 自动对齐节点示例

#include<osgViewer/Viewer>

#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/AutoTransform>

#include<osgDB/ReadFile>
#include<osgDB/WriteFile>

#include<osgText/Text>

#include<osgUtil/Optimizer>
// 创建自动变换节点
osg::ref_ptr<osg::Node> createAutoTransform(osg::Vec3&position,float size,std::string&label,osg::AutoTransform::AutoRotateMode autoMode,osgText::Text::AxisAlignment axisAlignment)
{
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    
    // 设置字体
    std::string font("fonts/cour.ttf");
    osg::ref_ptr<osgText::Text> text = new osgText::Text();
    geode->addDrawable(text.get());
    
    text->setFont(font);
    text->setFontResolution(128.0f,128.0f);// 设置字体的分辨力,默认为32*32
    text->setCharacterSize(size);// 设置字体大小
    text->setAlignment(osgText::Text::CENTER_CENTER);// 对齐
    text->setAxisAlignment(axisAlignment);// 设置方向
    text->setText(label);
    
    // 关闭光照
    geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
    
    // 创建自动变换节点
    osg::ref_ptr<osg::AutoTransform> at = new osg::AutoTransform();
    at->addChild(geode.get());
    at->setAutoRotateMode(autoMode);
    // 根据屏幕大小来缩放节点,默认为false,设置为true时,节点无法缩放
    at->setAutoScaleToScreen(false);
    // 设置缩放的最大和最小比例
    at->setMinimumScale(0.0f);
    at->setMaximumScale(5.0f);
    at->setPosition(position);
    
    return at.get();
}
//---------------------------------------------------------
int main()
{
    // 创建VIewer对象,场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group>root = new osg::Group();
    std::string text("Fly To Sky");
    
    // 添加ROTATE_TO_SCREEN模式变换节点
    root->addChild(createAutoTransform(osg::Vec3(0.0f,0.0f,0.0f),60.0f,text,osg::AutoTransform::ROTATE_TO_SCREEN,osgText::Text::XY_PLANE));
    
    // 添加NO_ROTATE模式变换节点
    root->addChild(createAutoTransform(osg::Vec3(0.0f,0.0f,0.0f),60.0f,text,osg::AutoTransform::NO_ROTATE,osgText::Text::YZ_PLANE));
    
    // 添加ROTATE_TO_CAMERA模式变换节点
    root->addChild(createAutoTransform(osg::Vec3(0.0f,0.0f,0.0f),60.0f,text,osg::AutoTransform::ROTATE_TO_CAMERA,osgText::Text::XY_PLANE));
    
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;
}
//---------------------------------------------------------
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风者868

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值