/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGUTIL_Tesselator #define OSGUTIL_Tesselator #include #include #include #include /* Win32 calling conventions. (or a least thats what the GLUT example tess.c uses.)*/ #ifndef CALLBACK #define CALLBACK #endif namespace osgUtil { /** A simple class for tessellating a single polygon boundary. * Currently uses old style glu tessellation functions for portability. * It be nice to use the modern glu tessellation functions or to find * a small set of code for doing this job better.*/ class OSGUTIL_EXPORT Tesselator { public: Tesselator(); ~Tesselator(); enum InputBoundaryDirection { CLOCK_WISE, COUNTER_CLOCK_WISE }; typedef std::vector VertexPointList; struct Prim : public osg::Referenced { Prim(GLenum mode):_mode(mode) {} typedef std::vector VecList; GLenum _mode; VecList _vertices; }; void beginTesselation(); void beginContour(); void addVertex(osg::Vec3* vertex); void endContour(); void endTesselation(); typedef std::vector< osg::ref_ptr > PrimList; PrimList& getPrimList() { return _primList; } void retesselatePolygons(osg::Geometry& geom); void reset(); protected: void begin(GLenum mode); void vertex(osg::Vec3* vertex); void combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4]); void end(); void error(GLenum errorCode); static void CALLBACK beginCallback(GLenum which, void* userData); static void CALLBACK vertexCallback(GLvoid *data, void* userData); static void CALLBACK combineCallback(GLdouble coords[3], void* vertex_data[4], GLfloat weight[4], void** outData, void* useData); static void CALLBACK endCallback(void* userData); static void CALLBACK errorCallback(GLenum errorCode, void* userData); struct Vec3d { double _v[3]; }; struct NewVertex { NewVertex(): _f1(0), _v1(0), _f2(0), _v2(0), _f3(0), _v3(0), _f4(0), _v4(0) {} NewVertex(const NewVertex& nv): _f1(nv._f1), _v1(nv._v1), _f2(nv._f2), _v2(nv._v2), _f3(nv._f3), _v3(nv._v3), _f4(nv._f4), _v4(nv._v4) {} NewVertex(float f1,osg::Vec3* v1, float f2,osg::Vec3* v2, float f3,osg::Vec3* v3, float f4,osg::Vec3* v4): _f1(f1), _v1(v1), _f2(f2), _v2(v2), _f3(f3), _v3(v3), _f4(f4), _v4(v4) {} float _f1; osg::Vec3* _v1; float _f2; osg::Vec3* _v2; float _f3; osg::Vec3* _v3; float _f4; osg::Vec3* _v4; }; typedef std::map NewVertexList; typedef std::vector Vec3dList; GLUtesselator* _tobj; PrimList _primList; Vec3dList _coordData; NewVertexList _newVertexList; GLenum _errorCode; }; } #endif