快速学习OSG(4)——Group

        osg:Group类是OSG的组节点,它允许用户程序为其添加任意数量的子节点,子节点也可以继续发子节点。osg::Group 作为-一个基类,派生出了很多实用的节点类,如osg:LOD、 osg::Switch、osg::Transform、osg:PositionAttitudeTransform、 osg:PagedLOD、 osg::Impostor og::AutoTransform等,后面的几节会对它们逐一进行介绍。

       osg::Group类是从osg::Referenced 类派生出来的,在通常情况下,只有父节点引用了这个Grou对象,所以当释放场景图的根节点时,会引发连锁的内存释放动作,这样就不会产生内存的泄osg::Group类作为OSG的核心部分,可以使用户程序通过Group来有效地组织场景图中的数据。osg:Group类的强大之处在于管理子节点的接口,同时,osg:Group类还从osg::Node类继承了用于管理父节点的接口,OSG允许节点有多个父节点。

一、位置变化节点

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

       osg:PositionttiudeTransform继承关系图如图所示。

快速学习OSG(4)——Group_第1张图片

osg:PositionAttitudeTransform的常用主要成员函数如下:

void setPosition(const Vec3d &pos) //设置位置
const Vec3d & getPosition0 const //得到位置
void settitude(const Quat &quat) //设置要态,参数为四元数
const Quat & getAttitude0 const //得到姿态
void setScale(const Vec3d &scale)/设置縮放
const Vec3d & getScale0 const //得到缩放
void setPivotPoint(const Vec3d &pivot)/设置原点(自定义原点位置,一且设置以后,所有变换均基于该原点)
const Vec3d & getPivotPoint 0 const //得到原点

1.1案例

#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 
int main()
{
    //创建Viewer对象,场景浏览器
    osg::ref_ptr viewer = new osgViewer::Viewer();
    //创建场景组节点
    osg::ref_ptr root = new osg::Group();
    //创建一个节点,读取牛的模型
    osg::ref_ptr node = osgDB::readNodeFile("cow.osg");
    //创建位置变化节点pat1
    osg::ref_ptr pat1 = new osg::PositionAttitudeTransform();
    //设置位置为osg::Vec3(-10.0f,0.0f,0.0f);
    pat1->setPosition(osg::Vec3(-10.0f, 0.0f, 0.0f));
    //设置缩放,XYZ都缩小一半
    pat1->setScale(osg::Vec3(0.5f, 0.5f, 0.5f));
    //添加子节点
    pat1->addChild(node.get());
    //创建位置变化节点pat2
    osg::ref_ptr pat2 = new osg::PositionAttitudeTransform();
    //设置位置为osg::Vec3(10.0f,0.0f,0.0f)
    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->setUpViewInWindow(200, 200, 800, 800);
    viewer->run();
    return 0;
}

二、矩阵变化节点

  矩阵变换节点(osg::MatrixTansform) 同样继承自osg::Transform,其主要作用是负责场景中的矩阵变换、矩阵的运算及坐标系的变换。后面要讲的动画更新也是用MatrixTransform来设置移动和旋转。通过使用矩阵变换节点(osgMtrixTransform)可以对场景中的模型进行旋转、平移等操作。

      osg::MatrixTransform的继承关系图如图所示。

2.1 案例

#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 
int main()

{
    //创建Viewer对象,场景浏览器
    osg::ref_ptr viewer = new osgViewer::Viewer();
    //创建场景组节点
    osg::ref_ptr root = new osg::Group();
    //创建一个节点,读取牛的模型
    osg::ref_ptr node = osgDB::readNodeFile("cow.osg");
    //创建矩阵变化节点mt1
    osg::ref_ptr mt1 = new osg::MatrixTransform();
    //创建一个矩阵
    osg::Matrix m;
    //在X方向平移10个单位
    m.makeTranslate(osg::Vec3(10.0f, 0.0f, 0.0f));
    //绕X轴旋转90°
    m.makeRotate(90.0f, 1.0f, 0.0f, 0.0f);
    //设置矩阵
    mt1->setMatrix(m);
    //添加子节点
    mt1->addChild(node.get());
    //创建矩阵变化节点mt2
    osg::ref_ptr mt2 = new osg::MatrixTransform();
    //创建一个矩阵
    osg::Matrix t;
    //在X负方向平移10个单位
    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->setUpViewInWindow(200, 200, 800, 800);
    viewer->run();

    return 0;
}

三、自动对齐节点

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

       osg:AutoTransform有如下3种对齐模式:

enum
AutoRotateMode
NO ROTATION,/无旋转
ROTATE TO SCREEN/自动朝向屏幕
ROTATE TO CAMERA //自动朝向相机

3.1 案例

#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 

#include 

#include 

//创建自动变化的节点
osg::ref_ptr createAutoTransform(osg::Vec3& position, float size, std::string& label,
    osg::AutoTransform::AutoRotateMode autoMode, osgText::Text::AxisAlignment axisAlignment)
{
    osg::ref_ptr geode = new osg::Geode();
    //字体
    std::string font("font/cour.ttf");
    //创建text对象
    osg::ref_ptr text = new osgText::Text();
    //将text放入到geode
    geode->addChild(text.get());
    //设置字体
    text->setFont(font);
    //设置字体的分辨率,默认为32*32
    text->setFontResolution(1280.0f, 128.0f);
    //设置字体的大小
    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 at = new osg::AutoTransform();
    //添加子节点
    at->addChild(geode.get());
    //设置自动变化的方式
    at->setAutoRotateMode(autoMode);
    //根据屏幕的大小来缩放节点。默认为false,设置为true时,节点无法缩放
    at->setAutoScaleToScreen(false);
    //at->setAutoScaleToScreen(true);;
    //设置缩放的最大和最小比例
    at->setMinimumScale(0.0f);
    at->setMaximumScale(5.0F);
    //设置位置
    at->setPosition(position);
    return at.get();
}
int main()
{
    osg::ref_ptr viewer = new osgViewer::Viewer();
    osg::ref_ptr root = new osg::Group();
    std::string text("So I do");
    /*变化模式
     enum AutoRotateMode
        {
            NO_ROTATION,    无朝向
            ROTATE_TO_SCREEN,    自动朝向屏幕
            ROTATE_TO_CAMERA,    自动朝向相机
            ROTATE_TO_AXIS        自动朝向坐标轴
        };
    */
    //添加为朝向屏幕
    osg::Vec3 nor(0.0f, 0.0f, 0.0f);
    root->addChild(createAutoTransform(nor, 60.0f, text,
        osg::AutoTransform::ROTATE_TO_SCREEN,osgText::Text::XY_PLANE));
    //添加无朝向
    root->addChild(createAutoTransform(nor, 60.0f, text,
        osg::AutoTransform::NO_ROTATION, osgText::Text::XY_PLANE));
    //添加朝向相机
    /*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->setUpViewInWindow(200, 200, 800, 800);
    viewer->run();

    return 0;
}

    学习OSG本身是一件很有意思的事,希望读者可以敲一下代码,运行一下结果

    持续更新......

你可能感兴趣的:(OSG,学习)