root/OpenSceneGraph/trunk/include/osgUtil/Tesselator @ 3326

Revision 3326, 7.9 kB (checked in by robert, 10 years ago)

Added handling of DrawArrayLengths? PrimitiveSet?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
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.
7 *
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.
12*/
13
14#ifndef OSGUTIL_Tesselator
15#define OSGUTIL_Tesselator
16
17#include <osg/Geometry>
18
19#include <osgUtil/Export>
20
21#include <osg/GLU>
22
23#include <vector>
24
25/* Win32 calling conventions. (or a least thats what the GLUT example tess.c uses.)*/
26#ifndef CALLBACK
27#define CALLBACK
28#endif
29
30
31namespace osgUtil {
32
33/** Originally a simple class for tessellating a single polygon boundary.
34  * Using old style glu tessellation functions for portability.
35  * Upgraded Jan 2004 to use the modern glu tessellation functions.*/
36
37class OSGUTIL_EXPORT Tesselator : public osg::Referenced
38{
39    public:
40   
41        Tesselator();
42        ~Tesselator();
43
44        /** The winding rule, see red book ch 11. */
45        enum WindingType{
46            TESS_WINDING_ODD          = GLU_TESS_WINDING_ODD,
47            TESS_WINDING_NONZERO      = GLU_TESS_WINDING_NONZERO     ,
48            TESS_WINDING_POSITIVE     = GLU_TESS_WINDING_POSITIVE    ,
49            TESS_WINDING_NEGATIVE     = GLU_TESS_WINDING_NEGATIVE    ,
50            TESS_WINDING_ABS_GEQ_TWO  =    GLU_TESS_WINDING_ABS_GEQ_TWO
51        } ;
52
53        /** we interpret all contours in the geometry as a single set to be tesselated or
54         * each separate drawable's contours needs to be tesselated. */
55        enum TesselationType {
56            TESS_TYPE_GEOMETRY, // tesselate everything in the geometry object
57            TESS_TYPE_DRAWABLE, // tesselate each polygon, triangles & quads drawables in geometry separately
58            TESS_TYPE_POLYGONS // tesselate ONLY polygon drawables in geometry separately
59        };
60
61        /** Set and get tesselation request boundary only on/off */
62        void setBoundaryOnly (const bool tt) { _boundaryOnly=tt;}
63        inline const bool getBoundaryOnly ( ) { return _boundaryOnly;}
64
65        /** Set and get tesselation windong rule */
66        void setWindingType (const WindingType wt) { _wtype=wt;}
67        inline const WindingType getWindingType ( ) { return _wtype;}
68
69        /** Set and get tesselation type */
70        void setTesselationType (const TesselationType tt) { _ttype=tt;}
71        inline const TesselationType getTesselationType ( ) { return _ttype;}
72
73        /** Change the contours lists of the geometry into tesselated primitives (the
74          * list of primitives in the original geometry is stored in the tesselator for
75          * possible re-use.
76          * The name remains retesselatePolygons although it now handles trifans, strips, quads etc.
77          * as well as Polygons so as to not break old codes relying on this function name. */
78        void retesselatePolygons(osg::Geometry &cxgeom);
79
80        osg::Geometry::PrimitiveSetList  getContours() { return _Contours;}
81
82        typedef std::vector<osg::Vec3*> VertexPointList;
83       
84        struct Prim : public osg::Referenced
85        {
86            Prim(GLenum mode):_mode(mode) {}
87       
88            typedef std::vector<osg::Vec3*> VecList;
89
90            GLenum  _mode;
91            VecList _vertices;
92        };
93       
94        void beginTesselation();
95       
96        void beginContour();
97        void addVertex(osg::Vec3* vertex);
98        void endContour();
99       
100        void endTesselation();
101
102        typedef std::vector< osg::ref_ptr<Prim> > PrimList;
103       
104        PrimList& getPrimList() { return _primList; }       
105       
106        void reset();
107       
108    protected:
109
110        /** remove unused parts of the array, eg for wehn retesselating
111         * tesselation can introduce extra vertices for concave or crossing boundaries,
112         * these will leak memory if not removed when retesselating. */
113        void reduceArray(osg::Array * cold, const unsigned int nnu);
114
115        void collectTesselation(osg::Geometry &cxgeom);
116       
117        typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
118        void addContour(GLenum  mode, unsigned int first, unsigned int last, osg::Vec3Array* vertices);
119        void addContour(osg::PrimitiveSet* primitive, osg::Vec3Array* vertices);
120        void handleNewVertices(osg::Geometry& geom,VertexPtrToIndexMap &vertexPtrToIndexMap);
121
122        void begin(GLenum mode);
123        void vertex(osg::Vec3* vertex);
124        void combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4]);
125        void end();
126        void error(GLenum errorCode);
127
128   
129        static void CALLBACK beginCallback(GLenum which, void* userData);
130        static void CALLBACK vertexCallback(GLvoid *data, void* userData);
131        static void CALLBACK combineCallback(GLdouble coords[3], void* vertex_data[4],
132                              GLfloat weight[4], void** outData,
133                              void* useData);
134        static void CALLBACK endCallback(void* userData);
135        static void CALLBACK errorCallback(GLenum errorCode, void* userData);
136       
137       
138        struct Vec3d
139        {
140            double _v[3];
141        };
142
143
144        struct NewVertex
145        {
146       
147            NewVertex():
148                _vpos(0),
149                _f1(0),
150                _v1(0),
151                _f2(0),
152                _v2(0),
153                _f3(0),
154                _v3(0),
155                _f4(0),
156                _v4(0) {}
157           
158            NewVertex(const NewVertex& nv):
159                _vpos(nv._vpos),
160                _f1(nv._f1),
161                _v1(nv._v1),
162                _f2(nv._f2),
163                _v2(nv._v2),
164                _f3(nv._f3),
165                _v3(nv._v3),
166                _f4(nv._f4),
167                _v4(nv._v4) {}
168
169            NewVertex(osg::Vec3* vx,
170                      float f1,osg::Vec3* v1,
171                      float f2,osg::Vec3* v2,
172                      float f3,osg::Vec3* v3,
173                      float f4,osg::Vec3* v4):
174                _vpos(vx),
175                _f1(f1),
176                _v1(v1),
177                _f2(f2),
178                _v2(v2),
179                _f3(f3),
180                _v3(v3),
181                _f4(f4),
182                _v4(v4) {}
183
184            osg::Vec3  *_vpos; // added gwm Jan 2004 the vertex coords s.t. NewVertex can be used in a std::vector
185       
186            float       _f1;
187            osg::Vec3*  _v1;
188
189            float       _f2;
190            osg::Vec3*  _v2;
191
192            float       _f3;
193            osg::Vec3*  _v3;
194
195            float       _f4;
196            osg::Vec3*  _v4;
197           
198        };
199       
200        //change NewVertexList from std::map<osg::Vec3*,NewVertex> NewVertexList;
201        // because this has undefined order of insertion for new vertices.
202        // which occasionally corrupted the texture mapping.
203        typedef std::vector<NewVertex> NewVertexList;
204        typedef std::vector<Vec3d*> Vec3dList;
205
206        GLUtesselator*  _tobj;
207        PrimList        _primList;
208        Vec3dList       _coordData;
209        NewVertexList   _newVertexList;
210        GLenum          _errorCode;
211
212        /** winding rule, which parts will become solid */
213        WindingType _wtype;
214
215        /** tesselation rule, which parts will become solid */
216        TesselationType _ttype;
217
218        bool _boundaryOnly; // see gluTessProperty - if true: make the boundary edges only.
219
220        /** number of vertices that are part of the 'original' set of contours */
221        unsigned int _numberVerts;
222
223        /** List of primitives that define the contours */
224        osg::Geometry::PrimitiveSetList                _Contours;
225
226        /** count number of primitives in a geometry to get right no. of norms/colurs etc for per_primitive attributes. */
227        unsigned int _index;
228};
229
230}
231
232#endif
Note: See TracBrowser for help on using the browser.