context: /*
  * Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
  * All rights reserved.*/
  
  /*
  ** License Applicability. Except to the extent portions of this file are
  ** made subject to an alternative license as permitted in the SGI Free
  ** Software License B, Version 1.1 (the "License"), the contents of this
  ** file are subject only to the provisions of the License. You may not use
  ** this file except in compliance with the License. You may obtain a copy
  ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
  ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
  **
  ** http://oss.sgi.com/projects/FreeB
  **
  ** Note that, as provided in the License, the Software is distributed on an
  ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
  ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
  ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
  ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
  **
  ** NOTE:  The Original Code (as defined below) has been licensed to Sun
  ** Microsystems, Inc. ("Sun") under the SGI Free Software License B
  ** (Version 1.1), shown above ("SGI License").   Pursuant to Section
  ** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
  ** you under an alternative license ("Alternative License").  This
  ** Alternative License includes all of the provisions of the SGI License
  ** except that Section 2.2 and 11 are omitted.  Any differences between
  ** the Alternative License and the SGI License are offered solely by Sun
  ** and not by SGI.
  **
  ** Original Code. The Original Code is: OpenGL Sample Implementation,
  ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
  ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
  ** Copyright in any portions created by third parties is as indicated
  ** elsewhere herein. All Rights Reserved.
  **
  ** Additional Notice Provisions: The application programming interfaces
  ** established by SGI in conjunction with the Original Code are The
  ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
  ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
  ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
  ** Window System(R) (Version 1.3), released October 19, 1998. This software
  ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
  ** published by SGI, but has not been independently verified as being
  ** compliant with the OpenGL(R) version 1.2.1 Specification.
  **
  ** Author: Eric Veach, July 1994
  ** Java Port: Pepijn Van Eeckhoudt, July 2003
  ** Java Port: Nathan Parker Burg, August 2003*/
  using System;
  using javax.media.opengl;
  using javax.media.opengl.glu;
  using Sxta.Render.Utils.GluTesselator;
  namespace Sxta.Render.Utils.GluTesselator
  {
  	
  	public class GLUtessellatorImpl : GLUtessellator
  	{
  		public const int TESS_MAX_CACHE = 100;
  		
  		private int state; /* what begin/end calls have we seen? */
  		
  		private GLUhalfEdge lastEdge; /* lastEdge->Org is the most recent vertex */
  		internal GLUmesh mesh; /* stores the input contours, and eventually
  		the tessellation itself */
  		
  		/// <summary> state needed for projecting onto the sweep plane **</summary>
  		
  		internal double[] normal = new double[3]; /* user-specified normal (if provided) */
  		internal double[] sUnit = new double[3]; /* unit vector in s-direction (debugging) */
  		internal double[] tUnit = new double[3]; /* unit vector in t-direction (debugging) */
  		
  		/// <summary> state needed for the line sweep **</summary>
  		
  		private double relTolerance; /* tolerance for merging features */
  		internal int windingRule; /* rule for determining polygon interior */
  		internal bool fatalError; /* fatal error: needed combine callback */
  		
  		internal Dict dict; /* edge dictionary for sweep line */
  		internal PriorityQ pq; /* priority queue of vertex events */
  		internal GLUvertex event_Renamed; /* current sweep event being processed */
  		
  		/// <summary> state needed for rendering callbacks (see render.c) **</summary>
  		
  		internal bool flagBoundary; /* mark boundary edges (use EdgeFlag) */
  		internal bool boundaryOnly; /* Extract contours, not triangles */
  		internal GLUface lonelyTriList;
  		/* list of triangles which could not be rendered as strips or fans */
  		
  		
  		
  		/// <summary> state needed to cache single-contour polygons for renderCache() </summary>
  		
  		private bool flushCacheOnNextVertex; /* empty cache on next vertex() call */
  		internal int cacheCount; /* number of cached vertices */
  		internal CachedVertex[] cache = new CachedVertex[TESS_MAX_CACHE]; /* the vertex data */
  		
  		/// <summary> rendering callbacks that also pass polygon data  **</summary>
  		private System.Object polygonData; /* client data for current polygon */
  		
  		private GLUtessellatorCallback callBegin;
  		private GLUtessellatorCallback callEdgeFlag;
  		private GLUtessellatorCallback callVertex;
  		private GLUtessellatorCallback callEnd;
  		//    private GLUtessellatorCallback callMesh;
  		private GLUtessellatorCallback callError;
  		private GLUtessellatorCallback callCombine;
  		
  		private GLUtessellatorCallback callBeginData;
  		private GLUtessellatorCallback callEdgeFlagData;
  		private GLUtessellatorCallback callVertexData;
  		private GLUtessellatorCallback callEndData;
  		//    private GLUtessellatorCallback callMeshData;
  		private GLUtessellatorCallback callErrorData;
  		private GLUtessellatorCallback callCombineData;
  		
  		private const double GLU_TESS_DEFAULT_TOLERANCE = 0.0;
  		//    private static final int GLU_TESS_MESH = 100112;	/* void (*)(GLUmesh *mesh)	    */
  		private static GLUtessellatorCallback NULL_CB = new GLUtessellatorCallbackAdapter();
  		
  		//    #define MAX_FAST_ALLOC	(MAX(sizeof(EdgePair), \
  		//                 MAX(sizeof(GLUvertex),sizeof(GLUface))))
  		
  		private GLUtessellatorImpl()
  		{
  			state = TessState.T_DORMANT;
  			
  			normal[0] = 0;
  			normal[1] = 0;
  			normal[2] = 0;
  			
  			relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
  			windingRule = GLU.GLU_TESS_WINDING_ODD;
  			flagBoundary = false;
  			boundaryOnly = false;
  			
  			callBegin = NULL_CB;
  			callEdgeFlag = NULL_CB;
  			callVertex = NULL_CB;
  			callEnd = NULL_CB;
  			callError = NULL_CB;
  			callCombine = NULL_CB;
  			//        callMesh = NULL_CB;
  			
  			callBeginData = NULL_CB;
  			callEdgeFlagData = NULL_CB;
  			callVertexData = NULL_CB;
  			callEndData = NULL_CB;
  			callErrorData = NULL_CB;
  			callCombineData = NULL_CB;
  			
  			polygonData = null;
  			
  			for (int i = 0; i < cache.Length; i++)
  			{
  				cache[i] = new CachedVertex();
  			}
  		}
  		
  		static public GLUtessellator gluNewTess()
  		{
  			return new GLUtessellatorImpl();
  		}
  		
  		
  		private void  makeDormant()
  		{
  			/* Return the tessellator to its original dormant state. */
  			
  			if (mesh != null)
  			{
  				Mesh.__gl_meshDeleteMesh(mesh);
  			}
  			state = TessState.T_DORMANT;
  			lastEdge = null;
  			mesh = null;
  		}
  		
  		private void  requireState(int newState)
  		{
  			if (state != newState)
  				gotoState(newState);
  		}
  		
  		private void  gotoState(int newState)
  		{
  			while (state != newState)
  			{
  				/* We change the current state one level at a time, to get to
  				* the desired state.
  				*/
  				if (state < newState)
  				{
  					if (state == TessState.T_DORMANT)
  					{
  						callErrorOrErrorData(GLU.GLU_TESS_MISSING_BEGIN_POLYGON);
  						gluTessBeginPolygon((System.Object) null);
  					}
  					else if (state == TessState.T_IN_POLYGON)
  					{
  						callErrorOrErrorData(GLU.GLU_TESS_MISSING_BEGIN_CONTOUR);
  						gluTessBeginContour();
  					}
  				}
  				else
  				{
  
gt: 					if (state == TessState.T_IN_CONTOUR)