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: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 //得到原点
#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的继承关系图如图所示。
#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 //自动朝向相机
#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本身是一件很有意思的事,希望读者可以敲一下代码,运行一下结果
持续更新......