OSG学习笔记-Shape(3-3)

3.3 使用OSG中预定义的几何体

在OSG中,为了简化场景的绘制,同时也为了方便开发者能够快速地构造一个场景,它本身预定义了一些常用的几何体。

3.3.1 osg::Shape类

osg::Shape类直接继承自osg::Object基类。osg::Shape类是各种内嵌几何体的基类,它不但可用于剔除和碰撞检测,还可用于生成预定义的几何体对象。

常用的内嵌几何体包括如下几种

osg::Box 正方形
osg::Capsule 太空舱
osg::Cone 椎体
osg::Cylinder 柱体
osg::HeightField 高度图
osg::InfinitePlane 无限平面
osg::Sphere 球体
osg::TriangleMesh 三角片

3.3.2 osg::ShapeDrawable类

osg::ShapeDrawable类派生自osg::Drawable类,在osg::ShapeDrawable类的构造函数中提供了关联osg::Shape的方法:

  • ShapeDrawable(Shape* shape,TessellationHints *hints = 0);// 第一个参数为shape,第二个参数默认下不细化

3.3.3 网格化类

网格化类(osg::TessellationHints)直接继承自osg::Object基类,osg::Tessellation类的主要作用是设置预定义几何体对象的精细程度、精细程度越高,表示其细分越详细,但对于不同的预定义几何体对象它的作用是不一样的。

  • Box(四棱柱):网格化类对于四棱柱没有意义
  • Capsule(太空舱):太空舱分3个部分,上下半球部分和圆柱侧面部分,默认圆柱侧面被细分
  • Cone(圆锥):直接细分
  • Cylinder(柱体):直接细分
  • Sphere(球):直接细分

目前,osg::TessellationHints类并不完整,部分类成员函数还没有实现,具体可以查看源码。在内嵌几何体对象中,默认的情况下,网格化类的精细度为0,表示预定义的几何体此时按照原顶点默认绘制,不做任何细化处理。

3.3.4 预定义几何体示例

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/ShapeDrawable>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
//------------------------------------------------------------------------------------
// 绘制多个预定义的几何体
osg::ref_ptr<osg::Geode> createShape()
{
    // 创建一个叶节点
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    
    // 设置半径和高度
    float radius = 0.8f;
    float height = 1.0f;
    
    // 创建精细度对象,精细度越高,细分就越多
    osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
    // 设置精细度为0.5f
    hints->setDetailRatio(0.5f);
    
    // 添加一个球体,第一个参数是预定义几何体对象,第二个是精细度,默认为0
    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius),hints));
    
    // 添加一个正方体
    geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2 * radius),hints));
    
    // 添加一个圆锥
    geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints));
    
    // 添加一个圆柱体
    geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height),hints));
    
    // 添加一个太空舱
    geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(8.0f,0.0f,0.0f),radius,height),hints));
    
    return geode.get();
}
//--------------------------------------------------------------------------------
int main()
{
    // 创建Viewer对象,场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group>root = new osg::Group();
    
    // 添加到场景
    root->addChild(createShape());
    
    // 优化场景数据
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liangfei868/article/details/123722844
3-3