In the development of openscenegraph, some data, such as quadrilateral, are often used for the convenience of some non-triangular slices. For example, drawing a pipe with four-sided bands is much better than using triangular slices. For example, now we are going to draw a plane consisting of two planes, which I can do: 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::D rawarrays (OSG::P rimitiveset::quad_strip,0,numcoords));
Geode->adddrawable (POLYGEOM);
With 6 dots, two planes were drawn with the Quad_strip method provided by OpenGL.
However, if you want to use this plane for collision detection techniques, then you need to convert the four-sided bands represented by these six points into triangular slices. These triangles are fixed as follows:
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
shows that two planes consist of 4 triangles and are all counterclockwise (toward the same direction).
I've done my own conversion before, but I feel a lot of trouble. OpenSceneGraph's Example osggeometry provides a printtriangles function that prints out a drawable of all triangular slices, regardless of the initial data structure: struct Normalprint
{
void operator () (const  OSG::VEC3 &  V1, const  OSG::VEC3 & v2, const  OSG::VEC3 & v3, bool) const  
  &NB sp; {
osg::Vec3 normal = (v2-v1) ^ (v3-v2 );
normal.normalize ();
std::cout << "\ t (" << v1 << ") &nbs P; ( "<< 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::D rawable& drawable)
{
std::cout<<name<<std::endl;
osg::trianglefunctor<normalprint> tf;
drawable.accept (TF);
std::cout<<std::endl;
}
The core idea is to use the Osg::trianglefunctor template. This template will let you reload the () operator and let Drawable go visit it. In this process, all the original data (whether triangular or quadrilateral) is converted into triangular slices of data.
So how to export the triangle data. Just need to change it. With this idea, it is right to change the normalprint to what we need. 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::D rawable& 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;
}
The following is a complete sample file://PrimitiveSet.cpp: Defines the entry point of the console application.
//
#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::D rawable& 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[]=
{
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;OSG::VEC3 (0,1,0),
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;OSG::VEC3 ( 0,0,0),
osg::vec3 (1,1,0),
&NBSP;&NBSP;&NBSP;OSG::VEC3 (1,0,0),
osg::vec3 (2,1,0),
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;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::D rawarrays (OSG::P rimitiveset::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-><