日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenSceneGraph 笔记–如何导出三角形数据 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在OpenSceneGraph開(kāi)發(fā)中,為了方便會(huì)經(jīng)常使用到一些不是三角形片的數(shù)據(jù),比如四邊形等數(shù)據(jù)。例如畫(huà)一個(gè)管子用四邊形帶比用三角形片好計(jì)算得多。比如現(xiàn)在我們要畫(huà)一個(gè)由兩個(gè)平面組成的面,我可以這樣做: ????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個(gè)點(diǎn),用OpenGL提供的QUAD_STRIP方式畫(huà)出了兩個(gè)平面。
但是如果要把這個(gè)平面用于碰撞檢測(cè)等技術(shù),那么就需要把這六個(gè)點(diǎn)所表示的四邊形帶轉(zhuǎn)換成三角形片才行。這些三角形定點(diǎn)如下:
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
可以看出兩個(gè)平面由4個(gè)三角形組成,而且都是逆時(shí)針排列(朝向一致)。
以前我自己做過(guò)轉(zhuǎn)換,但是感覺(jué)很麻煩。OpenSceneGraph的Example?osggeometry中提供了一個(gè)printTriangles函數(shù),它可以打印出一個(gè)drawable所有的三角形片,不管最初的數(shù)據(jù)結(jié)構(gòu)如何:

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這個(gè)模版。這個(gè)模版會(huì)讓你重載()運(yùn)算符,然后讓Drawable去visit它。在這個(gè)過(guò)程中,所有原始的數(shù)據(jù)(不管是三角形片的,還是四邊形的)都轉(zhuǎn)換成了三角形片數(shù)據(jù)。
那么如何把三角形數(shù)據(jù)導(dǎo)出哪?只需要修改一下借助這個(gè)思路,將NormalPrint修改成我們需要的就對(duì)了。

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?:?定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//

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

總結(jié)

以上是生活随笔為你收集整理的OpenSceneGraph 笔记–如何导出三角形数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。