OpenSceneGraph 笔记–如何导出三角形数据
????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所有的三角形片,不管最初的數據結構如何:
{
????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修改成我們需要的就對了。
{
????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 笔记–如何导出三角形数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 国庆小长假信用卡盗刷怎么理赔
- 下一篇: datetimepicker不可以选择当