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

转载:http://blog.csdn.net/pizi0475/article/details/5384389

在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();
    }
}

0
0

OpenSceneGraph 笔记--如何导出三角形数据的更多相关文章

  1. matlab学习笔记4--导入和导出Internet数据

    一起来学matlab-matlab学习笔记4 数据导入和导出_4 导入和导出Internet数据 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合 ...

  2. matlab学习笔记4--导入和导出电子数据表

    一起来学matlab-matlab学习笔记4 数据导入和导出_3 导入和导出电子数据表 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用> ...

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

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

  4. SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

  5. 【Telerik】<telerik:RadComboBox>导出列表数据

    近来在做项目,做到导出功能.使用<telerik:RadComboBox>的下拉框来实现导出部分或导出所有数据的功能.

  6. 使用BCP导出导入数据

    bcp 实用工具可以在 Microsoft SQL Server 实例和用户指定格式的数据文件间大容量复制数据. 使用 bcp 实用工具可以将大量新行导入 SQL Server 表,或将表数据导出到数 ...

  7. mysqldump导出部分数据的方法: 加入--where参数

    mysqldump导出部分数据的方法: 加入--where参数 mysqldump -u用户名 -p密码 数据库名 表名 --where="筛选条件" > 导出文件路径 my ...

  8. linux下导入、导出mysql数据库命令 下载文件到本地

    一.下载到本地 yum install lrzsz sz filename  下载 rz filename  上传   linux下导入.导出mysql数据库命令 一.导出数据库用mysqldump命 ...

  9. phpmyadmin导入导出大数据文件的办法

    在phpmyadmin的使用中,经常需要进行导入导出数据库的操作. 但是在导入导出大型数据库文件的时候经常会只是部分导出或者部分导入. 或者是导入导出不成功. 原因就是服务器和php.mysql限制了 ...

随机推荐

  1. MySQL 5.6 OOM 问题解决分享【转】

    本文来自:杨德华的原创分享 | MySQL 5.6 OOM 问题解决分享 延伸阅读:Linux的内存回收和交换 当遇到应用程序OOM的时候,大多数时候只能用头疼来形容,应用程序还可以通过引流来临时重启 ...

  2. html图标插件

    https://bitbucket.org/cleonello/jqplot/downloads/ 下载地址 http://www.cnblogs.com/yaozhenfa/p/jqplot-pie ...

  3. linux I/O复用

    转载自:哈维.dpkirin url:http://blog.csdn.NET/zhang_shuai_2011/article/details/7675797 http://blog.csdn.Ne ...

  4. StringBuffer与StringBuilder的简单理解

    联系:两者都适用于字符串的操作,都可以随便对字符串的内容进行变更操作,都继承至AbstractStringBuilder. 区别:StringBuffer是线程安全的,方法都加了synchronize ...

  5. SQL语法和运算符(一)

    一个数据库通常包含一个或多个表.每个表由一个名字标识,表包含带有数据的记录(行). 一些最重要的SQL命令(SQL对大小写不敏感): 一.SQL语法 select:从数据库中提取数据 update:更 ...

  6. iOS-上架APP之启动页设置(新手必看!)

    今天自己做的小作品准备提交,就差一个启动页,各种百度,各种搜,结果还好最后终于出来了,和大家分享一下,这个过程中遇到的各种小问题.(注XCode版本为7.2) 1.启动页一般都是图片,因为苹果有4,4 ...

  7. POJ 3009 Curling 2.0【带回溯DFS】

    POJ 3009 题意: 给出一个w*h的地图,其中0代表空地,1代表障碍物,2代表起点,3代表终点,每次行动可以走多个方格,每次只能向附近一格不是障碍物的方向行动,直到碰到障碍物才停下来,此时障碍物 ...

  8. java中的泛型的使用与理解

    什么是泛型? 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写 体验泛型代码时定义一些可变部份,那些部份在使用前必须作出指明.各种程序设计语言和其编译器.运行环境对泛型的支持均不一样 ...

  9. C/C++ 知识点1:内存对齐

    预备知识:基本类型占用字节 在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢? 32位操作系统: char : 1    int :4    short : 2    unsigned ...

  10. iOS设计模式

    一.代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现. 优势:解耦合 敏捷原则:开放-封闭原则 实例:tableview的 数据源delegate,通过和pro ...