在OpenSceneGraph开发中,为了方便会经常使用到一些不是三角形片的数据,比如四边形等数据。例如画一个管子用四边形带比用三角形片好计算得多。比如现在我们要画一个由两个平面组成的面,我可以这样做:

    osg::Geode* geode=new osg::Geode;
    osg::Geometry* polyGeom = new osg::Geometry;
    osg::Vec3 myCoords[]=
    {
        osg::Vec3(0,1,0),
        osg::Vec3(0,0,0),
        osg::Vec3(1,1,0),
        osg::Vec3(1,0,0),
        osg::Vec3(2,1,0),
        osg::Vec3(2,0,0)
    };

int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
    osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
    polyGeom->setVertexArray(vertices);
    polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,numCoords));
    geode->addDrawable(polyGeom);

这样就用6个点,用OpenGL提供的QUAD_STRIP方式画出了两个平面。
但是如果要把这个平面用于碰撞检测等技术,那么就需要把这六个点所表示的四边形带转换成三角形片才行。这些三角形定点如下:
0 1 0
0 0 0
1 1 0

0 0 0
1 0 0
1 1 0

1 1 0
1 0 0
2 1 0

1 0 0
2 0 0
2 1 0
可以看出两个平面由4个三角形组成,而且都是逆时针排列(朝向一致)。
以前我自己做过转换,但是感觉很麻烦。OpenSceneGraph的Example osggeometry中提供了一个printTriangles函数,它可以打印出一个drawable所有的三角形片,不管最初的数据结构如何:

struct NormalPrint
{
    void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool) const 
    {
        osg::Vec3 normal = (v2-v1)^(v3-v2);
        normal.normalize();
        std::cout << "\t("<<v1<<") ("<<v2<<") ("<<v3<<") "<<") normal ("<<normal<<")"<<std::endl;
    }
};

// decompose Drawable primtives into triangles, print out these triangles and computed normals.
void printTriangles(const std::string& name, osg::Drawable& drawable)
{
    std::cout<<name<<std::endl;
    
    osg::TriangleFunctor<NormalPrint> tf;
    drawable.accept(tf);
 
    std::cout<<std::endl;
}

核心的思想就是利用osg::TriangleFunctor这个模版。这个模版会让你重载()运算符,然后让Drawable去visit它。在这个过程中,所有原始的数据(不管是三角形片的,还是四边形的)都转换成了三角形片数据。
那么如何把三角形数据导出哪?只需要修改一下借助这个思路,将NormalPrint修改成我们需要的就对了。

struct GetVertex
{
    void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool) const 
    {
        vertexList->push_back(v1);
        vertexList->push_back(v2);
        vertexList->push_back(v3);
    }

osg::Vec3Array* vertexList;
    
};

void getTriangles(osg::Drawable& drawable)
{
    osg::TriangleFunctor<GetVertex> tf;
    tf.vertexList=new osg::Vec3Array;

drawable.accept(tf);

for(osg::Vec3Array::iterator itr=tf.vertexList->begin();
        itr!=tf.vertexList->end();
        itr++)
    {
        osg::Vec3 vertex=*itr;
        std::cout<<vertex<<std::endl;
    }

std::cout<<std::endl;
}

以下是完整的示例文件:

//  PrimitiveSet.cpp : 定义控制台应用程序的入口点。
//

#include  " stdafx.h "
#include  < iostream >

struct GetVertex
{
    void operator() (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool) const 
    {
        vertexList->push_back(v1);
        vertexList->push_back(v2);
        vertexList->push_back(v3);
    }

osg::Vec3Array* vertexList;
    
};

void getTriangles(osg::Drawable& drawable)
{
    osg::TriangleFunctor<GetVertex> tf;
    tf.vertexList=new osg::Vec3Array;

drawable.accept(tf);

for(osg::Vec3Array::iterator itr=tf.vertexList->begin();
        itr!=tf.vertexList->end();
        itr++)
    {
        osg::Vec3 vertex=*itr;
        std::cout<<vertex<<std::endl;
    }

std::cout<<std::endl;
}

osg::Node* createGeode()
{
    osg::Geode* geode=new osg::Geode;
    osg::Geometry* polyGeom = new osg::Geometry;
    osg::Vec3 myCoords[]=
    {
        osg::Vec3(0,1,0),
        osg::Vec3(0,0,0),
        osg::Vec3(1,1,0),
        osg::Vec3(1,0,0),
        osg::Vec3(2,1,0),
        osg::Vec3(2,0,0)
    };

int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
    osg::Vec3Array* vertices = new osg::Vec3Array(numCoords,myCoords);
    polyGeom->setVertexArray(vertices);
    polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,numCoords));
    geode->addDrawable(polyGeom);
    getTriangles(*polyGeom);
    return geode;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //Set up viewer
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::GraphicsContext::Traits> traits=new osg::GraphicsContext::Traits;
    traits->x=200;
    traits->y=200;
    traits->width=800;
    traits->height=600;
    traits->windowDecoration=true;
    traits->doubleBuffer=true;
    traits->sharedContext=0;
    
    osg::ref_ptr<osg::GraphicsContext> gc=osg::GraphicsContext::createGraphicsContext(traits.get());
    osg::ref_ptr<osg::Camera> camera=new osg::Camera;
    //osg::Camera camera=new osg::Camera;
    camera->setGraphicsContext(gc.get());
    camera->setViewport(new osg::Viewport(0,0,traits->width,traits->height));
    camera->setDrawBuffer(GL_BACK);
    camera->setReadBuffer(GL_BACK);
    osgGA::TrackballManipulator* tm=new osgGA::TrackballManipulator;
    
    viewer.setCameraManipulator(tm);
    
    viewer.addSlave(camera.get());

//Set up root node
    osg::ref_ptr<osg::Group> root=new osg::Group;

root->addChild(createGeode());

//Start show!
    viewer.setSceneData(root.get());
    viewer.realize();

while(!viewer.done())
    {
        viewer.frame();
    }
}

OpenSceneGraph 笔记–如何导出三角形数据相关推荐

  1. OpenSceneGraph 笔记--如何导出三角形数据

    在OpenSceneGraph开发中,为了方便会经常使用到一些不是三角形片的数据,比如四边形等数据.例如画一个管子用四边形带比用三角形片好计算得多.比如现在我们要画一个由两个平面组成的面,我可以这样做 ...

  2. oracle 11g dul,学习笔记:Oracle dul数据挖掘 导出Oracle11G数据文件坏块中表中

    试验模拟导出Oracle 11G数据库中数据文件坏块中表中的数据 以前一直以为dul对应的版本只能恢复最高的数据库版本一致,今天测试发现dul 10可以恢复11g最新版的数据库. 模拟环境SQL> ...

  3. 数据导不进oracle数据库,学习笔记:Oracle逻辑导出/导入 数据逻辑导出时跳过指定表不进行导出...

    天萃荷净 Oracle数据库逻辑exp导出时,跳过指定某些表,对其表中数据不进行导出 有一个需求,某个用户有很多张表,但是只能使用exp导出,而且想跳过其中某几张表,其他对象包括依赖关系都需要.针对这 ...

  4. Neo4J入门笔记[2]---导出数据为CSV

    在上一节<Neo4J入门笔记[1]-安装以及Cypher基本语法> 笔者主要分享了Neo4J的安装已经常用的命令.这个章节笔者分享从Neo4j里面导出数据到CSV.一个简单的方法,就是调用 ...

  5. php mysql生成excel文件,PHP导出MySQL数据到Excel文件简单示例

    这篇文章主要为大家详细介绍了PHP导出MySQL数据到Excel文件简单示例,具有一定的参考价值,可以用来参考一下. 对phpPHP导出MySQL数据到Excel文件简单示例感兴趣的小伙伴,下面一起跟 ...

  6. mysql dump hbase_导出mysqldump数据

    mysql备份,备份数据,数据库,表结构 mysql  mysqldump 这里我的数据库先叫做xmen; 备份数据库 代码如下: #mysqldump 数据库名 >数据库备份名 #mysqld ...

  7. R学习笔记(4): 使用外部数据

    来源于:R学习笔记(4): 使用外部数据 博客:心内求法 鉴于内存的非持久性和容量限制,一个有效的数据处理工具必须能够使用外部数据:能够从外部获取大量的数据,也能够将处理结果保存.R中提供了一系列的函 ...

  8. oracle11g 使用数据泵导出导入数据

    oracle11g 使用数据泵导出导入数据 终于搞定了 快写个笔记 记录下. 删除用户的时候提示已经登录了不能删除,这个需要把登录的session结束掉. select username,sid,se ...

  9. Polyworks脚本开发学习笔记(十九)-将数据对象与参考对象对齐的方法

    Polyworks脚本开发学习笔记(十九)-将数据对象与参考对象对齐的方法 把开发手册理了一遍,发现还有几个点没有记录下来,其中一个就是使用点对的粗对齐和使用参考目标的精确对齐.为了把这个学习笔记凑够 ...

最新文章

  1. xpath解析库的语法及使用
  2. java防止表单重复提交
  3. 前端学习(1154):常量const02
  4. 信息学奥赛一本通 1911:【00NOIP普及组】税收与补贴问题 | 洛谷 P1023 [NOIP2000 普及组] 税收与补贴问题
  5. C#LeetCode刷题之#172-阶乘后的零(Factorial Trailing Zeroes)
  6. 使用Pycharm开发WordCount程序
  7. ZooKeeper学习第四期---构建ZooKeeper应用
  8. day1 java的规范以及变量与数据类型
  9. oracle 查出所有空表,Oracle查看某个用户上的所有空表
  10. 【工业串口和网络软件通讯平台(SuperIO)教程】二.架构和组成部分
  11. 简历、PPT以及各尺寸学术会议海报模板(附PPT制作图片、视频、音频等素材及常用网址)
  12. Oracle数据库SQL优化详解
  13. 14-STM32F1 iic 24c02
  14. usb转rs485测试软件,usb转rs485
  15. 从物理到软件工程,中山大学转专业2017纪实
  16. 学海无涯——人工智能应用实例之写作软件的基本概念
  17. Google SketchUp Cookbook: (Chapter 1) Making Multiple Copies
  18. 2018-2-13-win10-uwp-切换主题
  19. Windows 10用户档案无法加载的解决方法
  20. UML设计——网上信用卡管理系统分析与设计(新手)

热门文章

  1. gateway路由网关,zuul的替代品
  2. (JAVA)获取对象
  3. 【C语言进阶深度学习记录】十一 C语言中enum,sizeof,typedef分析
  4. 【常见笔试面试算法题12续集二】动态规划算法案例2矩阵最小路径和练习题
  5. 冒泡排序 和 归并排序
  6. iOS录音后播放声音变小的解决方法
  7. Node.js server使用
  8. baidu patchrom项目开发详细教程(Being updated)
  9. 马云卸任CEO演讲全文:明天起生活将是我的工作
  10. IBM收购Rational一年总结