在使用OSG开发中,需要将OSG对应的三维模型转换为自己的模型,为了方便少出错,三角面是一个不错的选择(对于之支持三角面绘制的这点显得更重要),研究了下OSG,发现osg::TriangleFunctor这个模板可以实现我们想要的功能,用户使用的时候首先要重载operator()方法,然后调用geometry->accept()实现对其拆分。具体实现如下:
1.重载operator()方法
struct MyVecter
{
void operator() (const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3, bool) const
{
arrList->push_back(v1);
arrList->push_back(v2);
arrList->push_back(v3);
}
osg::Vec3Array* arrList;
};
2.转换为三角面
osg::TriangleFunctor<MyVecter> tf;
tf.arrList = new osg::Vec3Array;
geometry->accept(tf);
下面将给出一个简单的案例:构造一个四边面,然后转换为三角面
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Vec3>
#include <osg/TriangleFunctor>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <iostream>
#include <vector>
using namespace std;
struct MyVecter
{
void operator() (const osg::Vec3& v1, const osg::Vec3& v2, const osg::Vec3& v3, bool) const
{
arrList->push_back(v1);
arrList->push_back(v2);
arrList->push_back(v3);
}
osg::Vec3Array* arrList;
};
void PrintTriangles(osg::TriangleFunctor<MyVecter> tf)
{
int nCont = tf.arrList->size();
vector<osg::Vec3f> arrVec = tf.arrList->asVector();
for (int i = 0; i < nCont; i++)
{
osg::Vec3f v = arrVec[i];
cout << "X:" << v[0] <<" Y:" << v[1] << " Z:" << v[2] << endl;
}
}
osg::ref_ptr<osg::Node> createScene()
{
osg::ref_ptr<osg::Geometry> polyGeom = new osg::Geometry;
osg::Vec3 myCoords[] =
{
osg::Vec3(0.0247182, 0.0f, -0.156548),
osg::Vec3(0.0247182, 0.0f, -0.00823939),
osg::Vec3(-0.160668, 0.0f, -0.0453167),
osg::Vec3(-0.222464, 0.0f, -0.13183),
osg::Vec3(0.238942, 0.0f, -0.251302),
osg::Vec3(0.333696, 0.0f, 0.0329576),
osg::Vec3(0.164788, 0.0f, -0.0453167),
osg::Vec3(0.13595, 0.0f, -0.255421)
};
int numCoords = sizeof(myCoords)/sizeof(osg::Vec3);
osg::Vec3Array* vertices = new osg::Vec3Array(numCoords, myCoords);
polyGeom->setVertexArray(vertices);
osg::ref_ptr<osg::Vec4Array> shared_colors = new osg::Vec4Array;
shared_colors->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
polyGeom->setColorArray(shared_colors.get(), osg::Array::BIND_OVERALL);
osg::ref_ptr<osg::Vec3Array> shared_normals = new osg::Vec3Array;
shared_normals->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
polyGeom->setNormalArray(shared_normals.get(), osg::Array::BIND_OVERALL);
polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, numCoords));
osg::TriangleFunctor<MyVecter> tf;
tf.arrList = new osg::Vec3Array;
polyGeom->accept(tf);
PrintTriangles(tf);
//向geode类添加几何体
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(polyGeom);
return geode;
}
int main()
{
osg::Group* root = new osg::Group;
root->addChild( createScene() );
osgViewer::Viewer viewer;
viewer.setSceneData( root );
return viewer.run();
}
注意:本案例只是将四边面转换为三角面打印出来,并没有设置到geometry中去。