1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
14#ifndef OSGUTIL_Tessellator
15#define OSGUTIL_Tessellator
17#include <osg/Geometry>
19#include <osgUtil/Export>
26 /* Win32 calling conventions. (or a least that's what the GLUT example tess.c uses.)*/
32/** Originally a simple class for tessellating a single polygon boundary.
33 * Using old style glu tessellation functions for portability.
34 * Upgraded Jan 2004 to use the modern glu tessellation functions.*/
36class OSGUTIL_EXPORT Tessellator : public osg::Referenced
43 /** The winding rule, see red book ch 11. */
45 TESS_WINDING_ODD = GLU_TESS_WINDING_ODD,
46 TESS_WINDING_NONZERO = GLU_TESS_WINDING_NONZERO,
47 TESS_WINDING_POSITIVE = GLU_TESS_WINDING_POSITIVE,
48 TESS_WINDING_NEGATIVE = GLU_TESS_WINDING_NEGATIVE,
49 TESS_WINDING_ABS_GEQ_TWO = GLU_TESS_WINDING_ABS_GEQ_TWO
52 /** we interpret all contours in the geometry as a single set to be tessellated or
53 * each separate drawable's contours needs to be tessellated. */
54 enum TessellationType {
55 TESS_TYPE_GEOMETRY, // tessellate everything in the geometry object
56 TESS_TYPE_DRAWABLE, // tessellate each polygon, triangles & quads drawables in geometry separately
57 TESS_TYPE_POLYGONS // tessellate ONLY polygon drawables in geometry separately
60 /** Set and get tessellation request boundary only on/off */
61 void setBoundaryOnly (const bool tt) { _boundaryOnly=tt;}
62 inline bool getBoundaryOnly ( ) { return _boundaryOnly;}
64 /** Set and get tessellation windong rule */
65 void setWindingType (const WindingType wt) { _wtype=wt;}
66 inline WindingType getWindingType ( ) { return _wtype;}
68 /** Set and get tessellation type */
69 void setTessellationType (const TessellationType tt) { _ttype=tt;}
70 inline TessellationType getTessellationType ( ) { return _ttype;}
72 /** Change the contours lists of the geometry into tessellated primitives (the
73 * list of primitives in the original geometry is stored in the Tessellator for
75 * The name remains retessellatePolygons although it now handles trifans, strips, quads etc.
76 * as well as Polygons so as to not break old codes relying on this function name. */
77 void retessellatePolygons(osg::Geometry &cxgeom);
79 /** Define the normal to the tessellated polygon - this provides a hint how to
80 * tessellate the contours; see gluTessNormal in red book or man pages.
81 * GWM July 2005. Can improve teselation
82 * "For example, if you know that all polygons lie in the x-y plane,
83 * call gluTessNormal(tess, 0.0, 0.0, 1.0) before rendering any polygons."
85 void setTessellationNormal(const osg::Vec3 norm) { tessNormal=norm;}
87 osg::Geometry::PrimitiveSetList getContours() { return _Contours;}
89 struct Prim : public osg::Referenced
91 Prim(GLenum mode):_mode(mode) {}
93 typedef std::vector<osg::Vec3*> VecList;
99 virtual void beginTessellation();
103 /** Add a vertex to the current contour, see gluTessVertex for details.
104 * Note the vertex pointer is returned at the end of tessellation and
105 * must not be left dangling or be overwritten until all results are
108 void addVertex(osg::Vec3* vertex);
112 void endTessellation();
114 typedef std::vector< osg::ref_ptr<Prim> > PrimList;
116 PrimList& getPrimList() { return _primList; }
122 /** remove unused parts of the array, eg for when retessellating
123 * tessellation can introduce extra vertices for concave or crossing boundaries,
124 * these will leak memory if not removed when retessellating. */
125 void reduceArray(osg::Array * cold, const unsigned int nnu);
127 void collectTessellation(osg::Geometry &cxgeom, unsigned int originalIndex);
129 typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
130 void addContour(GLenum mode, unsigned int first, unsigned int last, osg::Vec3Array* vertices);
131 void addContour(osg::PrimitiveSet* primitive, osg::Vec3Array* vertices);
132 void handleNewVertices(osg::Geometry& geom,VertexPtrToIndexMap &vertexPtrToIndexMap);
134 void begin(GLenum mode);
135 void vertex(osg::Vec3* vertex);
136 void combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4]);
138 void error(GLenum errorCode);
141 static void CALLBACK beginCallback(GLenum which, void* userData);
142 static void CALLBACK vertexCallback(GLvoid *data, void* userData);
143 static void CALLBACK combineCallback(GLdouble coords[3], void* vertex_data[4],
144 GLfloat weight[4], void** outData,
146 static void CALLBACK endCallback(void* userData);
147 static void CALLBACK errorCallback(GLenum errorCode, void* userData);
170 NewVertex(const NewVertex& nv):
181 NewVertex(osg::Vec3* vx,
182 float f1,osg::Vec3* v1,
183 float f2,osg::Vec3* v2,
184 float f3,osg::Vec3* v3,
185 float f4,osg::Vec3* v4):
196 osg::Vec3 *_vpos; // added gwm Jan 2004 the vertex coords s.t. NewVertex can be used in a std::vector
212 //change NewVertexList from std::map<osg::Vec3*,NewVertex> NewVertexList;
213 // because this has undefined order of insertion for new vertices.
214 // which occasionally corrupted the texture mapping.
215 typedef std::vector<NewVertex> NewVertexList;
216 typedef std::vector<Vec3d*> Vec3dList;
218 osg::GLUtesselator* _tobj;
221 Vec3dList _coordData;
222 NewVertexList _newVertexList;
225 /** winding rule, which parts will become solid */
228 /** tessellation rule, which parts will become solid */
229 TessellationType _ttype;
231 bool _boundaryOnly; // see gluTessProperty - if true: make the boundary edges only.
233 /** number of vertices that are part of the 'original' set of contours */
234 unsigned int _numberVerts;
236 /** List of primitives that define the contours */
237 osg::Geometry::PrimitiveSetList _Contours;
239 /** count number of primitives in a geometry to get right no. of norms/colurs etc for per_primitive attributes. */
242 /** the gluTessNormal for tessellation hint */
243 osg::Vec3 tessNormal;
245 /** count of number of extra primitives added */
246 unsigned int _extraPrimitives;