diff --git a/internal/c/parts/core/glues/src/glu.h b/internal/c/parts/core/glues/src/glu.h deleted file mode 100644 index 1f3dcebb0..000000000 --- a/internal/c/parts/core/glues/src/glu.h +++ /dev/null @@ -1 +0,0 @@ -glues.h \ No newline at end of file diff --git a/internal/c/parts/core/glues/src/glues.h b/internal/c/parts/core/glues/src/glues.h deleted file mode 100644 index d17ec5b9a..000000000 --- a/internal/c/parts/core/glues/src/glues.h +++ /dev/null @@ -1,274 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES 1.0 CM port of part of GLU by Mike Gorchak - */ - -#ifndef __glues_h__ -#define __glues_h__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifndef APIENTRYP - #define APIENTRYP APIENTRY * -#endif /* APIENTRYP */ - -#ifdef __cplusplus - extern "C" { -#endif - -/*************************************************************/ - -/* Boolean */ -#define GLU_FALSE 0 -#define GLU_TRUE 1 - -/* Version */ -#define GLU_VERSION_1_1 1 -#define GLU_VERSION_1_2 1 -#define GLU_VERSION_1_3 1 - -/* StringName */ -#define GLU_VERSION 100800 -#define GLU_EXTENSIONS 100801 - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 -#define GLU_INCOMPATIBLE_GL_VERSION 100903 -#define GLU_INVALID_OPERATION 100904 - -/* QuadricDrawStyle */ -#define GLU_POINT 100010 -#define GLU_LINE 100011 -#define GLU_FILL 100012 -#define GLU_SILHOUETTE 100013 - -/* QuadricCallback */ -#define GLU_ERROR 100103 - -/* QuadricNormal */ -#define GLU_SMOOTH 100000 -#define GLU_FLAT 100001 -#define GLU_NONE 100002 - -/* QuadricOrientation */ -#define GLU_OUTSIDE 100020 -#define GLU_INSIDE 100021 - -/*************************************************************/ - - -#ifdef __cplusplus -class GLUquadric; -class GLUtesselator; -#else -typedef struct GLUquadric GLUquadric; -typedef struct GLUtesselator GLUtesselator; -#endif - -typedef GLUquadric GLUquadricObj; -typedef GLUtesselator GLUtesselatorObj; -typedef GLUtesselator GLUtriangulatorObj; - -/* Internal convenience typedefs */ -typedef void (APIENTRYP _GLUfuncptr)(); - -GLAPI GLboolean APIENTRY gluCheckExtension(const GLubyte* extName, const GLubyte* extString); -GLAPI void APIENTRY gluCylinder(GLUquadric* quad, GLfloat base, GLfloat top, GLfloat height, GLint slices, GLint stacks); -GLAPI void APIENTRY gluDeleteQuadric(GLUquadric* quad); -GLAPI void APIENTRY gluDisk(GLUquadric* quad, GLfloat inner, GLfloat outer, GLint slices, GLint loops); -GLAPI const GLubyte* APIENTRY gluErrorString(GLenum error); -GLAPI const GLubyte * APIENTRY gluGetString(GLenum name); -GLAPI void APIENTRY gluLookAt(GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat centerX, GLfloat centerY, GLfloat centerZ, GLfloat upX, GLfloat upY, GLfloat upZ); -GLAPI GLUquadric* APIENTRY gluNewQuadric(void); -GLAPI void APIENTRY gluOrtho2D(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); -GLAPI void APIENTRY gluPartialDisk(GLUquadric* quad, GLfloat inner, GLfloat outer, GLint slices, GLint loops, GLfloat start, GLfloat sweep); -GLAPI void APIENTRY gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); -GLAPI void APIENTRY gluPickMatrix(GLfloat x, GLfloat y, GLfloat delX, GLfloat delY, GLint *viewport); -GLAPI GLint APIENTRY gluProject(GLfloat objX, GLfloat objY, GLfloat objZ, const GLfloat *model, const GLfloat *proj, const GLint *view, GLfloat* winX, GLfloat* winY, GLfloat* winZ); -GLAPI void APIENTRY gluQuadricCallback(GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc); -GLAPI void APIENTRY gluQuadricDrawStyle(GLUquadric* quad, GLenum draw); -GLAPI void APIENTRY gluQuadricNormals(GLUquadric* quad, GLenum normal); -GLAPI void APIENTRY gluQuadricOrientation(GLUquadric* quad, GLenum orientation); -GLAPI void APIENTRY gluQuadricTexture(GLUquadric* quad, GLboolean texture); -GLAPI void APIENTRY gluSphere(GLUquadric* quad, GLfloat radius, GLint slices, GLint stacks); -GLAPI GLint APIENTRY gluUnProject(GLfloat winX, GLfloat winY, GLfloat winZ, const GLfloat *model, const GLfloat *proj, const GLint *view, GLfloat* objX, GLfloat* objY, GLfloat* objZ); -GLAPI GLint APIENTRY gluUnProject4(GLfloat winX, GLfloat winY, GLfloat winZ, GLfloat clipW, const GLfloat *model, const GLfloat *proj, const GLint *view, GLfloat nearVal, GLfloat farVal, GLfloat* objX, GLfloat* objY, GLfloat* objZ, GLfloat* objW); -GLAPI GLint APIENTRY gluScaleImage(GLenum format, GLsizei widthin, - GLsizei heightin, GLenum typein, - const void* datain, GLsizei widthout, - GLsizei heightout, GLenum typeout, void* dataout); -GLAPI GLint APIENTRY gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, - GLsizei width, GLsizei height, GLenum format, - GLenum type, GLint userLevel, GLint baseLevel, - GLint maxLevel, const void *data); -GLAPI GLint APIENTRY gluBuild2DMipmaps(GLenum target, GLint internalFormat, - GLsizei width, GLsizei height, GLenum format, - GLenum type, const void* data); - -#define GLU_TESS_MAX_COORD 1.0e37f - -/* TessCallback */ -#define GLU_TESS_BEGIN 100100 -#define GLU_BEGIN 100100 -#define GLU_TESS_VERTEX 100101 -#define GLU_VERTEX 100101 -#define GLU_TESS_END 100102 -#define GLU_END 100102 -#define GLU_TESS_ERROR 100103 -#define GLU_TESS_EDGE_FLAG 100104 -#define GLU_EDGE_FLAG 100104 -#define GLU_TESS_COMBINE 100105 -#define GLU_TESS_BEGIN_DATA 100106 -#define GLU_TESS_VERTEX_DATA 100107 -#define GLU_TESS_END_DATA 100108 -#define GLU_TESS_ERROR_DATA 100109 -#define GLU_TESS_EDGE_FLAG_DATA 100110 -#define GLU_TESS_COMBINE_DATA 100111 - -/* TessContour */ -#define GLU_CW 100120 -#define GLU_CCW 100121 -#define GLU_INTERIOR 100122 -#define GLU_EXTERIOR 100123 -#define GLU_UNKNOWN 100124 - -/* TessProperty */ -#define GLU_TESS_WINDING_RULE 100140 -#define GLU_TESS_BOUNDARY_ONLY 100141 -#define GLU_TESS_TOLERANCE 100142 - -/* TessError */ -#define GLU_TESS_ERROR1 100151 -#define GLU_TESS_ERROR2 100152 -#define GLU_TESS_ERROR3 100153 -#define GLU_TESS_ERROR4 100154 -#define GLU_TESS_ERROR5 100155 -#define GLU_TESS_ERROR6 100156 -#define GLU_TESS_ERROR7 100157 -#define GLU_TESS_ERROR8 100158 -#define GLU_TESS_MISSING_BEGIN_POLYGON 100151 -#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152 -#define GLU_TESS_MISSING_END_POLYGON 100153 -#define GLU_TESS_MISSING_END_CONTOUR 100154 -#define GLU_TESS_COORD_TOO_LARGE 100155 -#define GLU_TESS_NEED_COMBINE_CALLBACK 100156 - -/* TessWinding */ -#define GLU_TESS_WINDING_ODD 100130 -#define GLU_TESS_WINDING_NONZERO 100131 -#define GLU_TESS_WINDING_POSITIVE 100132 -#define GLU_TESS_WINDING_NEGATIVE 100133 -#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134 - -GLAPI void APIENTRY gluBeginPolygon(GLUtesselator* tess); -GLAPI void APIENTRY gluDeleteTess(GLUtesselator* tess); -GLAPI void APIENTRY gluEndPolygon(GLUtesselator* tess); -GLAPI void APIENTRY gluGetTessProperty(GLUtesselator* tess, GLenum which, GLfloat* data); -GLAPI GLUtesselator* APIENTRY gluNewTess(void); -GLAPI void APIENTRY gluNextContour(GLUtesselator* tess, GLenum type); -GLAPI void APIENTRY gluTessBeginContour(GLUtesselator* tess); -GLAPI void APIENTRY gluTessBeginPolygon(GLUtesselator* tess, GLvoid* data); -GLAPI void APIENTRY gluTessCallback(GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc); -GLAPI void APIENTRY gluTessEndContour(GLUtesselator* tess); -GLAPI void APIENTRY gluTessEndPolygon(GLUtesselator* tess); -GLAPI void APIENTRY gluTessNormal(GLUtesselator* tess, GLfloat valueX, GLfloat valueY, GLfloat valueZ); -GLAPI void APIENTRY gluTessProperty(GLUtesselator* tess, GLenum which, GLfloat data); -GLAPI void APIENTRY gluTessVertex(GLUtesselator* tess, GLfloat* location, GLvoid* data); - -/* NurbsError */ -#define GLU_NURBS_ERROR1 100251 -#define GLU_NURBS_ERROR2 100252 -#define GLU_NURBS_ERROR3 100253 -#define GLU_NURBS_ERROR4 100254 -#define GLU_NURBS_ERROR5 100255 -#define GLU_NURBS_ERROR6 100256 -#define GLU_NURBS_ERROR7 100257 -#define GLU_NURBS_ERROR8 100258 -#define GLU_NURBS_ERROR9 100259 -#define GLU_NURBS_ERROR10 100260 -#define GLU_NURBS_ERROR11 100261 -#define GLU_NURBS_ERROR12 100262 -#define GLU_NURBS_ERROR13 100263 -#define GLU_NURBS_ERROR14 100264 -#define GLU_NURBS_ERROR15 100265 -#define GLU_NURBS_ERROR16 100266 -#define GLU_NURBS_ERROR17 100267 -#define GLU_NURBS_ERROR18 100268 -#define GLU_NURBS_ERROR19 100269 -#define GLU_NURBS_ERROR20 100270 -#define GLU_NURBS_ERROR21 100271 -#define GLU_NURBS_ERROR22 100272 -#define GLU_NURBS_ERROR23 100273 -#define GLU_NURBS_ERROR24 100274 -#define GLU_NURBS_ERROR25 100275 -#define GLU_NURBS_ERROR26 100276 -#define GLU_NURBS_ERROR27 100277 -#define GLU_NURBS_ERROR28 100278 -#define GLU_NURBS_ERROR29 100279 -#define GLU_NURBS_ERROR30 100280 -#define GLU_NURBS_ERROR31 100281 -#define GLU_NURBS_ERROR32 100282 -#define GLU_NURBS_ERROR33 100283 -#define GLU_NURBS_ERROR34 100284 -#define GLU_NURBS_ERROR35 100285 -#define GLU_NURBS_ERROR36 100286 -#define GLU_NURBS_ERROR37 100287 - -#ifdef __cplusplus -} -#endif - -#endif /* __glues_h__ */ diff --git a/internal/c/parts/core/glues/src/glues_error.c b/internal/c/parts/core/glues/src/glues_error.c deleted file mode 100644 index ef370a875..000000000 --- a/internal/c/parts/core/glues/src/glues_error.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES 1.0 CM port of part of GLU by Mike Gorchak - */ - -#include -#include - -#include "glues_error.h" - -static unsigned char* __gluNurbsErrors[]= -{ - (unsigned char*) " ", - (unsigned char*) "spline order un-supported", - (unsigned char*) "too few knots", - (unsigned char*) "valid knot range is empty", - (unsigned char*) "decreasing knot sequence knot", - (unsigned char*) "knot multiplicity greater than order of spline", - (unsigned char*) "gluEndCurve() must follow gluBeginCurve()", - (unsigned char*) "gluBeginCurve() must precede gluEndCurve()", - (unsigned char*) "missing or extra geometric data", - (unsigned char*) "can't draw piecewise linear trimming curves", - (unsigned char*) "missing or extra domain data", - (unsigned char*) "missing or extra domain data", - (unsigned char*) "gluEndTrim() must precede gluEndSurface()", - (unsigned char*) "gluBeginSurface() must precede gluEndSurface()", - (unsigned char*) "curve of improper type passed as trim curve", - (unsigned char*) "gluBeginSurface() must precede gluBeginTrim()", - (unsigned char*) "gluEndTrim() must follow gluBeginTrim()", - (unsigned char*) "gluBeginTrim() must precede gluEndTrim()", - (unsigned char*) "invalid or missing trim curve", - (unsigned char*) "gluBeginTrim() must precede gluPwlCurve()", - (unsigned char*) "piecewise linear trimming curve referenced twice", - (unsigned char*) "piecewise linear trimming curve and nurbs curve mixed", - (unsigned char*) "improper usage of trim data type", - (unsigned char*) "nurbs curve referenced twice", - (unsigned char*) "nurbs curve and piecewise linear trimming curve mixed", - (unsigned char*) "nurbs surface referenced twice", - (unsigned char*) "invalid property", - (unsigned char*) "gluEndSurface() must follow gluBeginSurface()", - (unsigned char*) "intersecting or misoriented trim curves", - (unsigned char*) "intersecting trim curves", - (unsigned char*) "UNUSED", - (unsigned char*) "unconnected trim curves", - (unsigned char*) "unknown knot error", - (unsigned char*) "negative vertex count encountered", - (unsigned char*) "negative byte-stride encounteed", - (unsigned char*) "unknown type descriptor", - (unsigned char*) "null control point reference", - (unsigned char*) "duplicate point on piecewise linear trimming curve", -}; - -const unsigned char* __gluNURBSErrorString(int errnum) -{ - return __gluNurbsErrors[errnum]; -} - -static unsigned char* __gluTessErrors[]= -{ - (unsigned char*) " ", - (unsigned char*) "gluTessBeginPolygon() must precede a gluTessEndPolygon()", - (unsigned char*) "gluTessBeginContour() must precede a gluTessEndContour()", - (unsigned char*) "gluTessEndPolygon() must follow a gluTessBeginPolygon()", - (unsigned char*) "gluTessEndContour() must follow a gluTessBeginContour()", - (unsigned char*) "a coordinate is too large", - (unsigned char*) "need combine callback", -}; - -const unsigned char* __gluTessErrorString(int errnum) -{ - return __gluTessErrors[errnum]; -} - -struct token_string -{ - GLuint Token; - const char* String; -}; - -static const struct token_string Errors[]= -{ - /* GL */ - {GL_NO_ERROR, "no error"}, - {GL_INVALID_ENUM, "invalid enumerant"}, - {GL_INVALID_VALUE, "invalid value"}, - {GL_INVALID_OPERATION, "invalid operation"}, - {GL_STACK_OVERFLOW, "stack overflow"}, - {GL_STACK_UNDERFLOW, "stack underflow"}, - {GL_OUT_OF_MEMORY, "out of memory"}, - - /* GLU */ - { GLU_INVALID_ENUM, "invalid enumerant"}, - { GLU_INVALID_VALUE, "invalid value"}, - { GLU_OUT_OF_MEMORY, "out of memory"}, - { GLU_INCOMPATIBLE_GL_VERSION, "incompatible gl version"}, - { GLU_INVALID_OPERATION, "invalid operation"}, - { ~0, NULL } /* end of list indicator */ -}; - -GLAPI const GLubyte* APIENTRY gluErrorString(GLenum errorCode) -{ - int i; - - for (i=0; Errors[i].String; i++) - { - if (Errors[i].Token==errorCode) - { - return (const GLubyte*) Errors[i].String; - } - } - - if ((errorCode>=GLU_NURBS_ERROR1) && (errorCode<=GLU_NURBS_ERROR37)) - { - return (const GLubyte*)__gluNURBSErrorString(errorCode-(GLU_NURBS_ERROR1-1)); - } - if ((errorCode>=GLU_TESS_ERROR1) && (errorCode<=GLU_TESS_ERROR6)) - { - return (const GLubyte*) __gluTessErrorString(errorCode-(GLU_TESS_ERROR1-1)); - } - - return (const GLubyte*)0; -} diff --git a/internal/c/parts/core/glues/src/glues_error.h b/internal/c/parts/core/glues/src/glues_error.h deleted file mode 100644 index cf5fb43e5..000000000 --- a/internal/c/parts/core/glues/src/glues_error.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#ifndef __GLUES_REGISTRY_H__ -#define __GLUES_REGISTRY_H__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 -#define GLU_INCOMPATIBLE_GL_VERSION 100903 -#define GLU_INVALID_OPERATION 100904 - -/* TessError */ -#define GLU_TESS_ERROR1 100151 -#define GLU_TESS_ERROR2 100152 -#define GLU_TESS_ERROR3 100153 -#define GLU_TESS_ERROR4 100154 -#define GLU_TESS_ERROR5 100155 -#define GLU_TESS_ERROR6 100156 -#define GLU_TESS_ERROR7 100157 -#define GLU_TESS_ERROR8 100158 -#define GLU_TESS_MISSING_BEGIN_POLYGON 100151 -#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152 -#define GLU_TESS_MISSING_END_POLYGON 100153 -#define GLU_TESS_MISSING_END_CONTOUR 100154 -#define GLU_TESS_COORD_TOO_LARGE 100155 -#define GLU_TESS_NEED_COMBINE_CALLBACK 100156 - -/* NurbsError */ -#define GLU_NURBS_ERROR1 100251 -#define GLU_NURBS_ERROR2 100252 -#define GLU_NURBS_ERROR3 100253 -#define GLU_NURBS_ERROR4 100254 -#define GLU_NURBS_ERROR5 100255 -#define GLU_NURBS_ERROR6 100256 -#define GLU_NURBS_ERROR7 100257 -#define GLU_NURBS_ERROR8 100258 -#define GLU_NURBS_ERROR9 100259 -#define GLU_NURBS_ERROR10 100260 -#define GLU_NURBS_ERROR11 100261 -#define GLU_NURBS_ERROR12 100262 -#define GLU_NURBS_ERROR13 100263 -#define GLU_NURBS_ERROR14 100264 -#define GLU_NURBS_ERROR15 100265 -#define GLU_NURBS_ERROR16 100266 -#define GLU_NURBS_ERROR17 100267 -#define GLU_NURBS_ERROR18 100268 -#define GLU_NURBS_ERROR19 100269 -#define GLU_NURBS_ERROR20 100270 -#define GLU_NURBS_ERROR21 100271 -#define GLU_NURBS_ERROR22 100272 -#define GLU_NURBS_ERROR23 100273 -#define GLU_NURBS_ERROR24 100274 -#define GLU_NURBS_ERROR25 100275 -#define GLU_NURBS_ERROR26 100276 -#define GLU_NURBS_ERROR27 100277 -#define GLU_NURBS_ERROR28 100278 -#define GLU_NURBS_ERROR29 100279 -#define GLU_NURBS_ERROR30 100280 -#define GLU_NURBS_ERROR31 100281 -#define GLU_NURBS_ERROR32 100282 -#define GLU_NURBS_ERROR33 100283 -#define GLU_NURBS_ERROR34 100284 -#define GLU_NURBS_ERROR35 100285 -#define GLU_NURBS_ERROR36 100286 -#define GLU_NURBS_ERROR37 100287 - -GLAPI const GLubyte* APIENTRY gluErrorString(GLenum errorCode); - -#ifdef __cplusplus -} -#endif - -#endif /* __GLUES_REGISTRY_H__ */ diff --git a/internal/c/parts/core/glues/src/glues_mipmap.c b/internal/c/parts/core/glues/src/glues_mipmap.c deleted file mode 100644 index cca13f8c7..000000000 --- a/internal/c/parts/core/glues/src/glues_mipmap.c +++ /dev/null @@ -1,2275 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#include -#include -#include -#include -#include /* UINT_MAX */ -#include - -#include "glues_mipmap.h" - -typedef union -{ - unsigned char ub[4]; - unsigned short us[2]; - unsigned int ui; - char b[4]; - short s[2]; - int i; - float f; -} Type_Widget; - -/* Pixel storage modes */ -typedef struct -{ - GLint pack_alignment; - GLint pack_row_length; - GLint pack_skip_rows; - GLint pack_skip_pixels; - GLint pack_swap_bytes; - GLint pack_image_height; - - GLint unpack_alignment; - GLint unpack_row_length; - GLint unpack_skip_rows; - GLint unpack_skip_pixels; - GLint unpack_swap_bytes; - GLint unpack_image_height; -} PixelStorageModes; - -static int gluBuild2DMipmapLevelsCore(GLenum, GLint, GLsizei, GLsizei, - GLsizei, GLsizei, GLenum, GLenum, - GLint, GLint, GLint, const void*); - -/* - * internal function declarations - */ -static GLfloat bytes_per_element(GLenum type); -static GLint elements_per_group(GLenum format, GLenum type); -static GLint image_size(GLint width, GLint height, GLenum format, GLenum type); -static void fill_image(const PixelStorageModes*, - GLint width, GLint height, GLenum format, - GLenum type, GLboolean index_format, - const void* userdata, GLushort* newimage); -static void empty_image(const PixelStorageModes*, - GLint width, GLint height, GLenum format, - GLenum type, GLboolean index_format, - const GLushort* oldimage, void* userdata); -static void scale_internal(GLint components, GLint widthin, GLint heightin, - const GLushort* datain, - GLint widthout, GLint heightout, - GLushort* dataout); - -static void scale_internal_ubyte(GLint components, GLint widthin, - GLint heightin, const GLubyte* datain, - GLint widthout, GLint heightout, - GLubyte* dataout, GLint element_size, - GLint ysize, GLint group_size); - -static int checkMipmapArgs(GLenum, GLenum, GLenum); -static GLboolean legalFormat(GLenum); -static GLboolean legalType(GLenum); -static GLboolean isTypePackedPixel(GLenum); -static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum); -static GLboolean isLegalLevels(GLint, GLint, GLint, GLint); -static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum, - GLint*, GLint*); - -/* packedpixel type scale routines */ -static void extract565(int, const void*, GLfloat []); -static void shove565(const GLfloat [], int ,void*); -static void extract4444(int, const void*, GLfloat []); -static void shove4444(const GLfloat [], int ,void*); -static void extract5551(int, const void*, GLfloat []); -static void shove5551(const GLfloat [], int ,void*); -static void scaleInternalPackedPixel(int, - void (*)(int, const void*,GLfloat []), - void (*)(const GLfloat [],int, void*), - GLint,GLint, const void*, - GLint,GLint,void*,GLint,GLint,GLint); -static void halveImagePackedPixel(int, - void (*)(int, const void*,GLfloat []), - void (*)(const GLfloat [],int, void*), - GLint, GLint, const void*, - void*, GLint, GLint, GLint); -static void halve1DimagePackedPixel(int, - void (*)(int, const void*,GLfloat []), - void (*)(const GLfloat [],int, void*), - GLint, GLint, const void*, - void*, GLint, GLint, GLint); - -static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte*, - GLubyte*, GLint, GLint, GLint); - -static void retrieveStoreModes(PixelStorageModes* psm) -{ - psm->unpack_alignment=1; - psm->unpack_row_length=0; - psm->unpack_skip_rows=0; - psm->unpack_skip_pixels=0; - psm->unpack_swap_bytes=0; - - psm->pack_alignment=1; - psm->pack_row_length=0; - psm->pack_skip_rows=0; - psm->pack_skip_pixels=0; - psm->pack_swap_bytes=0; -} - -static int computeLog(GLuint value) -{ - int i=0; - - /* Error! */ - if (value==0) - { - return -1; - } - - for (;;) - { - if (value & 1) - { - /* Error ! */ - if (value!=1) - { - return -1; - } - return i; - } - value =value >> 1; - i++; - } -} - -/* -** Compute the nearest power of 2 number. This algorithm is a little -** strange, but it works quite well. -*/ -static int nearestPower(GLuint value) -{ - int i=1; - - /* Error! */ - if (value==0) - { - return -1; - } - - for (;;) - { - if (value==1) - { - return i; - } - else - { - if (value==3) - { - return i*4; - } - } - value=value>>1; - i*=2; - } -} - -#define __GLU_SWAP_2_BYTES(s)\ -(GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) - -#define __GLU_SWAP_4_BYTES(s)\ -(GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \ - ((GLuint)((const GLubyte*)(s))[2])<<16 | \ - ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) - -static void halveImage(GLint components, GLuint width, GLuint height, - const GLushort* datain, GLushort* dataout) -{ - int i, j, k; - int newwidth, newheight; - int delta; - GLushort* s; - const GLushort* t; - - newwidth=width/2; - newheight=height/2; - delta=width*components; - s=dataout; - t=datain; - - /* Piece o' cake! */ - for (i=0; iheightout) - { - highy=y+halfconvy; - lowy=y-halfconvy; - } - else - { - highy=y+0.5f; - lowy=y-0.5f; - } - for (j=0; jwidthout) - { - highx=x+halfconvx; - lowx=x-halfconvx; - } - else - { - highx=x+0.5f; - lowx=x-0.5f; - } - /* - ** Ok, now apply box filter to box that goes from (lowx, lowy) - ** to (highx, highy) on input data into this pixel on output - ** data. - */ - totals[0] = totals[1] = totals[2] = totals[3] = 0.0; - area = 0.0; - - y=lowy; - yint=(int)floor(y); - while (y=heightin) - { - highy_int=heightin-1; - } - lowx_int = 0; - lowx_float = 0; - highx_int = convx_int; - highx_float = convx_float; - - for (j=0; jlowy_int) && (highx_int>lowx_int)) - { - y_percent=1-lowy_float; - temp=(const char*)datain+xindex+lowy_int*ysize; - percent=y_percent*(1-lowx_float); - for (k=0, temp_index=temp; klowy_int) - { - x_percent=highx_float-lowx_float; - percent=(1-lowy_float)*x_percent; - temp=(const char*)datain+xindex+lowy_int*ysize; - for (k=0, temp_index=temp; klowx_int) - { - y_percent=highy_float-lowy_float; - percent=(1-lowx_float)*y_percent; - temp=(const char*)datain+xindex+lowy_int*ysize; - for (k=0, temp_index=temp; k1) - { - highx_float-=1.0; - highx_int++; - } - } - lowy_int=highy_int; - lowy_float=highy_float; - highy_int+=convy_int; - highy_float+=convy_float; - if (highy_float>1) - { - highy_float-=1.0; - highy_int++; - } - } -} - -static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type) -{ - if (!legalFormat(format) || !legalType(type)) - { - return GLU_INVALID_ENUM; - } - - if (!isLegalFormatForPackedPixelType(format, type)) - { - return GLU_INVALID_OPERATION; - } - - return 0; -} /* checkMipmapArgs() */ - -static GLboolean legalFormat(GLenum format) -{ - switch(format) - { - case GL_ALPHA: - case GL_RGB: - case GL_RGBA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - return GL_TRUE; - default: - return GL_FALSE; - } -} - -static GLboolean legalType(GLenum type) -{ - switch(type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - return GL_TRUE; - default: - return GL_FALSE; - } -} - -/* */ -static GLboolean isTypePackedPixel(GLenum type) -{ - assert(legalType(type)); - - if (type==GL_UNSIGNED_SHORT_5_6_5 || - type==GL_UNSIGNED_SHORT_4_4_4_4 || - type==GL_UNSIGNED_SHORT_5_5_5_1) - { - return 1; - } - else - { - return 0; - } -} /* isTypePackedPixel() */ - -/* Determines if the packed pixel type is compatible with the format */ -static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type) -{ - /* if not a packed pixel type then return true */ - if (!isTypePackedPixel(type)) - { - return GL_TRUE; - } - - /* 5_6_5 is only compatible with RGB */ - if ((type==GL_UNSIGNED_SHORT_5_6_5) && format!=GL_RGB) - { - return GL_FALSE; - } - - /* 4_4_4_4 & 5_5_5_1 - * are only compatible with RGBA - */ - if ((type==GL_UNSIGNED_SHORT_4_4_4_4 || type==GL_UNSIGNED_SHORT_5_5_5_1) && - (format != GL_RGBA)) - { - return GL_FALSE; - } - - return GL_TRUE; -} /* isLegalFormatForPackedPixelType() */ - -static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel, - GLint totalLevels) -{ - if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel || - totalLevels < maxLevel) - { - return GL_FALSE; - } - else - { - return GL_TRUE; - } -} /* isLegalLevels() */ - -/* Given user requested texture size, determine if it fits. If it - * doesn't then halve both sides and make the determination again - * until it does fit (for IR only). - */ -static void closestFit(GLenum target, GLint width, GLint height, - GLint internalFormat, GLenum format, GLenum type, - GLint *newWidth, GLint *newHeight) -{ - GLint maxsize; - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); - - /* clamp user's texture sizes to maximum sizes, if necessary */ - *newWidth=nearestPower(width); - if (*newWidth>maxsize) - { - *newWidth=maxsize; - } - *newHeight=nearestPower(height); - if (*newHeight>maxsize) - { - *newHeight = maxsize; - } -} /* closestFit() */ - -GLAPI GLint APIENTRY -gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin, - GLenum typein, const void* datain, GLsizei widthout, - GLsizei heightout, GLenum typeout, void* dataout) -{ - int components; - GLushort* beforeImage=NULL; - GLushort* afterImage=NULL; - PixelStorageModes psm; - - if (widthin==0 || heightin==0 || widthout==0 || heightout==0) - { - return 0; - } - - if (widthin<0 || heightin<0 || widthout<0 || heightout<0) - { - return GLU_INVALID_VALUE; - } - - if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) - { - return GLU_INVALID_ENUM; - } - if (!isLegalFormatForPackedPixelType(format, typein)) - { - return GLU_INVALID_OPERATION; - } - if (!isLegalFormatForPackedPixelType(format, typeout)) - { - return GLU_INVALID_OPERATION; - } - beforeImage=malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT)); - afterImage=malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT)); - if (beforeImage==NULL || afterImage==NULL) - { - if (beforeImage!=NULL) - { - free(beforeImage); - } - if (afterImage!=NULL) - { - free(afterImage); - } - return GLU_OUT_OF_MEMORY; - } - - retrieveStoreModes(&psm); - fill_image(&psm,widthin, heightin, format, typein, 0, datain, beforeImage); - components=elements_per_group(format, 0); - scale_internal(components, widthin, heightin, beforeImage, widthout, heightout, afterImage); - empty_image(&psm, widthout, heightout, format, typeout, 0, afterImage, dataout); - free((GLbyte*)beforeImage); - free((GLbyte*)afterImage); - - return 0; -} - -/* To make swapping images less error prone */ -#define __GLU_INIT_SWAP_IMAGE void* tmpImage -#define __GLU_SWAP_IMAGE(a,b) tmpImage=a; a=b; b=tmpImage; - -static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, - GLsizei width, GLsizei height, - GLsizei widthPowerOf2, - GLsizei heightPowerOf2, - GLenum format, GLenum type, - GLint userLevel, - GLint baseLevel,GLint maxLevel, - const void* data) -{ - GLint newwidth, newheight; - GLint level, levels; - const void* usersImage; /* passed from user. Don't touch! */ - void* srcImage; - void* dstImage; /* scratch area to build mipmapped images */ - __GLU_INIT_SWAP_IMAGE; - GLint memreq; - GLint cmpts; - - GLint myswap_bytes, groups_per_line, element_size, group_size; - GLint rowsize, padding; - PixelStorageModes psm; - - assert(checkMipmapArgs(internalFormat,format,type)==0); - assert(width>=1 && height>=1); - - srcImage=dstImage=NULL; - - newwidth=widthPowerOf2; - newheight=heightPowerOf2; - levels=computeLog(newwidth); - level=computeLog(newheight); - if (level>levels) - { - levels=level; - } - - levels+=userLevel; - - retrieveStoreModes(&psm); - myswap_bytes=psm.unpack_swap_bytes; - cmpts=elements_per_group(format,type); - if (psm.unpack_row_length>0) - { - groups_per_line=psm.unpack_row_length; - } - else - { - groups_per_line=width; - } - - element_size=(GLint)bytes_per_element(type); - group_size=element_size*cmpts; - if (element_size==1) - { - /* Nothing to swap */ - myswap_bytes=0; - } - - rowsize=groups_per_line*group_size; - padding=(rowsize%psm.unpack_alignment); - if (padding) - { - rowsize+=psm.unpack_alignment-padding; - } - usersImage=(const GLubyte*)data+psm.unpack_skip_rows*rowsize+psm.unpack_skip_pixels*group_size; - - level=userLevel; - - /* already power-of-two square */ - if (width==newwidth && height==newheight) - { - /* Use usersImage for level userLevel */ - if (baseLevel<=level && level<=maxLevel) - { - glTexImage2D(target, level, internalFormat, width, - height, 0, format, type, usersImage); - } - if (levels==0) - { - /* we're done. clean up and return */ - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return 0; - } - - { - int nextWidth=newwidth/2; - int nextHeight=newheight/2; - - /* clamp to 1 */ - if (nextWidth<1) - { - nextWidth=1; - } - if (nextHeight<1) - { - nextHeight=1; - } - memreq=image_size(nextWidth, nextHeight, format, type); - } - - switch(type) - { - case GL_UNSIGNED_BYTE: - dstImage = (GLubyte *)malloc(memreq); - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - dstImage = (GLushort *)malloc(memreq); - break; - default: - return GLU_INVALID_ENUM; - } - if (dstImage==NULL) - { - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return GLU_OUT_OF_MEMORY; - } - else - { - switch(type) - { - case GL_UNSIGNED_BYTE: - halveImage_ubyte(cmpts, width, height, (const GLubyte*)usersImage, - (GLubyte*)dstImage, element_size, rowsize, group_size); - break; - case GL_UNSIGNED_SHORT_5_6_5: - halveImagePackedPixel(3, extract565, shove565, width, height, - usersImage, dstImage, element_size, - rowsize, myswap_bytes); - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - halveImagePackedPixel(4, extract4444, shove4444, width, height, - usersImage, dstImage, element_size, - rowsize, myswap_bytes); - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - halveImagePackedPixel(4, extract5551, shove5551, width, height, - usersImage, dstImage, element_size, - rowsize, myswap_bytes); - break; - default: - assert(0); - break; - } - } - - newwidth=width/2; - newheight=height/2; - - /* clamp to 1 */ - if (newwidth<1) - { - newwidth=1; - } - if (newheight<1) - { - newheight=1; - } - - myswap_bytes=0; - rowsize=newwidth*group_size; - memreq=image_size(newwidth, newheight, format, type); - /* Swap srcImage and dstImage */ - __GLU_SWAP_IMAGE(srcImage,dstImage); - switch(type) - { - case GL_UNSIGNED_BYTE: - dstImage=(GLubyte*)malloc(memreq); - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - dstImage=(GLushort*)malloc(memreq); - break; - default: - return GLU_INVALID_ENUM; - } - if (dstImage==NULL) - { - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return GLU_OUT_OF_MEMORY; - } - - /* level userLevel+1 is in srcImage; level userLevel already saved */ - level = userLevel+1; - } - else - { - /* user's image is *not* nice power-of-2 sized square */ - memreq=image_size(newwidth, newheight, format, type); - switch(type) - { - case GL_UNSIGNED_BYTE: - dstImage=(GLubyte*)malloc(memreq); - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - dstImage=(GLushort*)malloc(memreq); - break; - default: - return GLU_INVALID_ENUM; - } - - if (dstImage==NULL) - { - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return GLU_OUT_OF_MEMORY; - } - - switch(type) - { - case GL_UNSIGNED_BYTE: - scale_internal_ubyte(cmpts, width, height, - (const GLubyte*)usersImage, newwidth, newheight, - (GLubyte*)dstImage, element_size, rowsize, group_size); - break; - case GL_UNSIGNED_SHORT_5_6_5: - scaleInternalPackedPixel(3, extract565, shove565, width, height, - usersImage, newwidth, newheight, (void*)dstImage, element_size, - rowsize, myswap_bytes); - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - scaleInternalPackedPixel(4, extract4444, shove4444, width, height, - usersImage, newwidth, newheight, (void*)dstImage, element_size, - rowsize,myswap_bytes); - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - scaleInternalPackedPixel(4,extract5551, shove5551, width, height, - usersImage, newwidth, newheight, (void*)dstImage, element_size, - rowsize, myswap_bytes); - break; - default: - assert(0); - break; - } - myswap_bytes=0; - rowsize=newwidth*group_size; - - /* Swap dstImage and srcImage */ - __GLU_SWAP_IMAGE(srcImage,dstImage); - - /* use as little memory as possible */ - if (levels!=0) - { - { - int nextWidth=newwidth/2; - int nextHeight=newheight/2; - - if (nextWidth<1) - { - nextWidth=1; - } - if (nextHeight<1) - { - nextHeight=1; - } - - memreq=image_size(nextWidth, nextHeight, format, type); - } - - switch(type) - { - case GL_UNSIGNED_BYTE: - dstImage = (GLubyte *)malloc(memreq); - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - dstImage = (GLushort *)malloc(memreq); - break; - default: - return GLU_INVALID_ENUM; - } - if (dstImage==NULL) - { - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return GLU_OUT_OF_MEMORY; - } - } - - /* level userLevel is in srcImage; nothing saved yet */ - level=userLevel; - } - - if (baseLevel<=level && level<=maxLevel) - { - glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, - format, type, (void*)srcImage); - } - - level++; /* update current level for the loop */ - for (; level<=levels; level++) - { - switch(type) - { - case GL_UNSIGNED_BYTE: - halveImage_ubyte(cmpts, newwidth, newheight, (GLubyte*)srcImage, - (GLubyte *)dstImage, element_size, rowsize, group_size); - break; - case GL_UNSIGNED_SHORT_5_6_5: - halveImagePackedPixel(3, extract565, shove565, newwidth, - newheight, srcImage, dstImage, element_size, rowsize, - myswap_bytes); - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - halveImagePackedPixel(4, extract4444, shove4444, newwidth, - newheight, srcImage, dstImage, element_size, rowsize, - myswap_bytes); - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - halveImagePackedPixel(4, extract5551, shove5551, newwidth, - newheight, srcImage, dstImage, element_size, rowsize, - myswap_bytes); - break; - default: - assert(0); - break; - } - - __GLU_SWAP_IMAGE(srcImage,dstImage); - - if (newwidth>1) - { - newwidth/=2; - rowsize/=2; - } - if (newheight>1) - { - newheight/=2; - } - - { - /* compute amount to pad per row, if any */ - int rowPad=rowsize%psm.unpack_alignment; - - /* should row be padded? */ - if (rowPad == 0) - { /* nope, row should not be padded */ - /* call tex image with srcImage untouched since it's not padded */ - if (baseLevel<=level && level<=maxLevel) - { - glTexImage2D(target, level, internalFormat, newwidth, newheight, - 0, format, type, (void*) srcImage); - } - } - else - { /* yes, row should be padded */ - /* compute length of new row in bytes, including padding */ - int newRowLength=rowsize+psm.unpack_alignment-rowPad; - int ii; - unsigned char* dstTrav; - unsigned char* srcTrav; /* indices for copying */ - - /* allocate new image for mipmap of size newRowLength x newheight */ - void* newMipmapImage=malloc((size_t)(newRowLength*newheight)); - if (newMipmapImage==NULL) - { - /* out of memory so return */ - glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); - return GLU_OUT_OF_MEMORY; - } - - /* copy image from srcImage into newMipmapImage by rows */ - for (ii=0, - dstTrav=(unsigned char*) newMipmapImage, - srcTrav=(unsigned char*) srcImage; - iilevels) - { - levels=level; - } - - levels+=userLevel; - if (!isLegalLevels(userLevel, baseLevel, maxLevel, levels)) - { - return GLU_INVALID_VALUE; - } - - return gluBuild2DMipmapLevelsCore(target, internalFormat, width, height, - width, height, format, type, - userLevel, baseLevel, maxLevel, data); -} /* gluBuild2DMipmapLevels() */ - -GLAPI GLint APIENTRY -gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void* data) -{ - GLint widthPowerOf2, heightPowerOf2; - int level, levels; - - int rc=checkMipmapArgs(internalFormat,format,type); - if (rc!=0) - { - return rc; - } - - if (width<1 || height<1) - { - return GLU_INVALID_VALUE; - } - - closestFit(target, width, height, internalFormat, format, type, - &widthPowerOf2,&heightPowerOf2); - - levels=computeLog(widthPowerOf2); - level=computeLog(heightPowerOf2); - if (level>levels) - { - levels=level; - } - - return gluBuild2DMipmapLevelsCore(target,internalFormat, width, height, - widthPowerOf2, heightPowerOf2, format, - type, 0, 0, levels, data); -} /* gluBuild2DMipmaps() */ - -/* - * Utility Routines - */ -static GLint elements_per_group(GLenum format, GLenum type) -{ - /* - * Return the number of elements per group of a specified format - */ - - /* If the type is packedpixels then answer is 1 (ignore format) */ - if (type==GL_UNSIGNED_SHORT_5_6_5 || - type==GL_UNSIGNED_SHORT_4_4_4_4 || - type==GL_UNSIGNED_SHORT_5_5_5_1) - { - return 1; - } - - /* Types are not packed pixels, so get elements per group */ - switch(format) - { - case GL_RGB: - return 3; - case GL_LUMINANCE_ALPHA: - return 2; - case GL_RGBA: - return 4; - default: - return 1; - } -} - -static GLfloat bytes_per_element(GLenum type) -{ - /* - * Return the number of bytes per element, based on the element type - */ - switch(type) - { - case GL_UNSIGNED_BYTE: - return(sizeof(GLubyte)); - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - return(sizeof(GLushort)); - default: - return 4; - } -} - -/* -** Compute memory required for internal packed array of data of given type -** and format. -*/ -static GLint image_size(GLint width, GLint height, GLenum format, GLenum type) -{ - int bytes_per_row; - int components; - - assert(width>0); - assert(height>0); - components=elements_per_group(format, type); - - bytes_per_row=(int)(bytes_per_element(type)*width); - - return bytes_per_row*height*components; -} - -/* -** Extract array from user's data applying all pixel store modes. -** The internal format used is an array of unsigned shorts. -*/ -static void fill_image(const PixelStorageModes* psm, - GLint width, GLint height, GLenum format, - GLenum type, GLboolean index_format, - const void* userdata, GLushort* newimage) -{ - GLint components; - GLint element_size; - GLint rowsize; - GLint padding; - GLint groups_per_line; - GLint group_size; - GLint elements_per_line; - const GLubyte* start; - const GLubyte* iter; - GLushort* iter2; - GLint i, j, k; - GLint myswap_bytes; - - myswap_bytes=psm->unpack_swap_bytes; - components=elements_per_group(format,type); - if (psm->unpack_row_length>0) - { - groups_per_line = psm->unpack_row_length; - } - else - { - groups_per_line = width; - } - - { - element_size=(GLint)bytes_per_element(type); - group_size=element_size*components; - if (element_size==1) - { - myswap_bytes=0; - } - - rowsize=groups_per_line*group_size; - padding=(rowsize%psm->unpack_alignment); - if (padding) - { - rowsize+=psm->unpack_alignment-padding; - } - start=(const GLubyte*)userdata+psm->unpack_skip_rows*rowsize+ - psm->unpack_skip_pixels*group_size; - elements_per_line=width*components; - - iter2=newimage; - for (i=0; iunpack_skip_rows*rowsize+psm->unpack_skip_pixels*group_size]); - - } -} - -/* -** Insert array into user's data applying all pixel store modes. -** The internal format is an array of unsigned shorts. -** empty_image() because it is the opposite of fill_image(). -*/ -static void empty_image(const PixelStorageModes* psm, GLint width, - GLint height, GLenum format, GLenum type, - GLboolean index_format, const GLushort* oldimage, - void* userdata) -{ - GLint components; - GLint element_size; - GLint rowsize; - GLint padding; - GLint groups_per_line; - GLint group_size; - GLint elements_per_line; - GLubyte* start; - GLubyte* iter; - const GLushort* iter2; - GLint i, j, k; - GLint myswap_bytes; - - myswap_bytes=psm->pack_swap_bytes; - components=elements_per_group(format, type); - if (psm->pack_row_length>0) - { - groups_per_line = psm->pack_row_length; - } - else - { - groups_per_line = width; - } - - { - float shoveComponents[4]; - - element_size=(GLint)bytes_per_element(type); - group_size=element_size*components; - if (element_size==1) - { - myswap_bytes = 0; - } - - rowsize=groups_per_line*group_size; - padding=(rowsize%psm->pack_alignment); - if (padding) - { - rowsize+=psm->pack_alignment-padding; - } - start=(GLubyte*) userdata+psm->pack_skip_rows*rowsize+psm->pack_skip_pixels*group_size; - elements_per_line=width*components; - - iter2=oldimage; - for (i=0; i>8; - break; - case GL_UNSIGNED_SHORT_5_6_5: - for (k=0; k<3; k++) - { - shoveComponents[k]=*iter2++/65535.0f; - } - shove565(shoveComponents, 0, (void*)&widget.us[0]); - if (myswap_bytes) - { - iter[0]=widget.ub[1]; - iter[1]=widget.ub[0]; - } - else - { - *(GLushort*)iter=widget.us[0]; - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - for (k=0; k<4; k++) - { - shoveComponents[k]=*iter2++/65535.0f; - } - shove4444(shoveComponents,0,(void *)&widget.us[0]); - if (myswap_bytes) - { - iter[0]=widget.ub[1]; - iter[1]=widget.ub[0]; - } - else - { - *(GLushort *)iter = widget.us[0]; - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - for (k=0; k<4; k++) - { - shoveComponents[k]=*iter2++/65535.0f; - } - shove5551(shoveComponents,0,(void *)&widget.us[0]); - if (myswap_bytes) - { - iter[0]=widget.ub[1]; - iter[1]=widget.ub[0]; - } - else - { - *(GLushort*)iter=widget.us[0]; - } - break; - } - iter+=element_size; - } /* for j */ - start+=rowsize; -#if 1 - /* want 'iter' pointing at start, not within, row for assertion - * purposes - */ - iter=start; -#endif - } /* for i */ - - /* iterators should be one byte past end */ - if (!isTypePackedPixel(type)) - { - assert(iter2==&oldimage[width*height*components]); - } - else - { - assert(iter2==&oldimage[width*height*elements_per_group(format, 0)]); - } - assert(iter==&((GLubyte *)userdata)[rowsize*height+psm->pack_skip_rows*rowsize+ - psm->pack_skip_pixels*group_size]); - - } -} /* empty_image() */ - -/*-------------------------------------------------------------------------- - * Decimation of packed pixel types - *-------------------------------------------------------------------------- - */ -static void extract565(int isSwap, const void* packedPixel, GLfloat extractComponents[]) -{ - GLushort ushort=*(const GLushort*)packedPixel; - - if (isSwap) - { - ushort=__GLU_SWAP_2_BYTES(packedPixel); - } - else - { - ushort=*(const GLushort*)packedPixel; - } - - /* 11111000,00000000 == 0xf800 */ - /* 00000111,11100000 == 0x07e0 */ - /* 00000000,00011111 == 0x001f */ - - extractComponents[0]=(float)((ushort&0xf800)>>11)/31.0f; /* 31 = 2^5-1*/ - extractComponents[1]=(float)((ushort&0x07e0)>>5)/63.0f; /* 63 = 2^6-1*/ - extractComponents[2]=(float)((ushort&0x001f))/31.0f; -} /* extract565() */ - -static void shove565(const GLfloat shoveComponents[], int index, void* packedPixel) -{ - /* 11111000,00000000 == 0xf800 */ - /* 00000111,11100000 == 0x07e0 */ - /* 00000000,00011111 == 0x001f */ - - assert(0.0<=shoveComponents[0] && shoveComponents[0]<=1.0); - assert(0.0<=shoveComponents[1] && shoveComponents[1]<=1.0); - assert(0.0<=shoveComponents[2] && shoveComponents[2]<=1.0); - - /* due to limited precision, need to round before shoving */ - ((GLushort*)packedPixel)[index]=((GLushort)((shoveComponents[0]*31)+0.5)<<11)&0xf800; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[1]*63)+0.5)<<5)&0x07e0; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[2]*31)+0.5))&0x001f; -} /* shove565() */ - -static void extract4444(int isSwap,const void* packedPixel, GLfloat extractComponents[]) -{ - GLushort ushort; - - if (isSwap) - { - ushort=__GLU_SWAP_2_BYTES(packedPixel); - } - else - { - ushort=*(const GLushort*)packedPixel; - } - - /* 11110000,00000000 == 0xf000 */ - /* 00001111,00000000 == 0x0f00 */ - /* 00000000,11110000 == 0x00f0 */ - /* 00000000,00001111 == 0x000f */ - - extractComponents[0]=(float)((ushort&0xf000)>>12)/15.0f;/* 15=2^4-1 */ - extractComponents[1]=(float)((ushort&0x0f00)>>8)/15.0f; - extractComponents[2]=(float)((ushort&0x00f0)>>4)/15.0f; - extractComponents[3]=(float)((ushort&0x000f))/15.0f; -} /* extract4444() */ - -static void shove4444(const GLfloat shoveComponents[], int index,void* packedPixel) -{ - assert(0.0<=shoveComponents[0] && shoveComponents[0]<=1.0); - assert(0.0<=shoveComponents[1] && shoveComponents[1]<=1.0); - assert(0.0<=shoveComponents[2] && shoveComponents[2]<=1.0); - assert(0.0<=shoveComponents[3] && shoveComponents[3]<=1.0); - - /* due to limited precision, need to round before shoving */ - ((GLushort*)packedPixel)[index]=((GLushort)((shoveComponents[0]*15)+0.5)<<12)&0xf000; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[1]*15)+0.5)<<8)&0x0f00; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[2]*15)+0.5)<<4)&0x00f0; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[3]*15)+0.5))&0x000f; -} /* shove4444() */ - -static void extract5551(int isSwap,const void* packedPixel, GLfloat extractComponents[]) -{ - GLushort ushort; - - if (isSwap) - { - ushort=__GLU_SWAP_2_BYTES(packedPixel); - } - else - { - ushort=*(const GLushort*)packedPixel; - } - - /* 11111000,00000000 == 0xf800 */ - /* 00000111,11000000 == 0x07c0 */ - /* 00000000,00111110 == 0x003e */ - /* 00000000,00000001 == 0x0001 */ - - extractComponents[0]=(float)((ushort&0xf800)>>11)/31.0f;/* 31 = 2^5-1*/ - extractComponents[1]=(float)((ushort&0x07c0)>>6)/31.0f; - extractComponents[2]=(float)((ushort&0x003e)>>1)/31.0f; - extractComponents[3]=(float)((ushort&0x0001)); -} /* extract5551() */ - -static void shove5551(const GLfloat shoveComponents[], int index,void* packedPixel) -{ - /* 11111000,00000000 == 0xf800 */ - /* 00000111,11000000 == 0x07c0 */ - /* 00000000,00111110 == 0x003e */ - /* 00000000,00000001 == 0x0001 */ - - assert(0.0<=shoveComponents[0] && shoveComponents[0]<=1.0); - assert(0.0<=shoveComponents[1] && shoveComponents[1]<=1.0); - assert(0.0<=shoveComponents[2] && shoveComponents[2]<=1.0); - assert(0.0<=shoveComponents[3] && shoveComponents[3]<=1.0); - - /* due to limited precision, need to round before shoving */ - ((GLushort*)packedPixel)[index]=((GLushort)((shoveComponents[0]*31)+0.5)<<11)&0xf800; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[1]*31)+0.5)<<6)&0x07c0; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[2]*31)+0.5)<<1)&0x003e; - ((GLushort*)packedPixel)[index]|=((GLushort)((shoveComponents[3])+0.5))&0x0001; -} /* shove5551() */ - -static void scaleInternalPackedPixel(int components, - void (*extractPackedPixel) - (int, const void*,GLfloat []), - void (*shovePackedPixel) - (const GLfloat [], int, void*), - GLint widthIn,GLint heightIn, - const void* dataIn, - GLint widthOut,GLint heightOut, - void* dataOut, - GLint pixelSizeInBytes, - GLint rowSizeInBytes, GLint isSwap) -{ - float convx; - float convy; - float percent; - - /* Max components in a format is 4, so... */ - float totals[4]; - float extractTotals[4], extractMoreTotals[4], shoveTotals[4]; - - float area; - int i,j,k,xindex; - - const char *temp, *temp0; - int outindex; - - int lowx_int, highx_int, lowy_int, highy_int; - float x_percent, y_percent; - float lowx_float, highx_float, lowy_float, highy_float; - float convy_float, convx_float; - int convy_int, convx_int; - int l, m; - const char* left; - const char* right; - - if (widthIn==widthOut*2 && heightIn==heightOut*2) - { - halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, - widthIn, heightIn, dataIn, dataOut, - pixelSizeInBytes,rowSizeInBytes,isSwap); - return; - } - convy=(float)heightIn/heightOut; - convx=(float)widthIn/widthOut; - convy_int=(int)floor(convy); - convy_float=convy-convy_int; - convx_int=(int)floor(convx); - convx_float=convx-convx_int; - - area=convx*convy; - - lowy_int=0; - lowy_float=0; - highy_int=convy_int; - highy_float=convy_float; - - for (i=0; ilowy_int) && (highx_int>lowx_int)) - { - y_percent=1-lowy_float; - temp=(const char*)dataIn+xindex+lowy_int*rowSizeInBytes; - percent=y_percent*(1-lowx_float); - (*extractPackedPixel)(isSwap, temp, extractTotals); - for (k=0; klowy_int) - { - x_percent=highx_float-lowx_float; - percent=(1-lowy_float)*x_percent; - temp=(const char*)dataIn+xindex+lowy_int*rowSizeInBytes; - (*extractPackedPixel)(isSwap, temp, extractTotals); - for (k=0; k lowx_int) - { - y_percent=highy_float-lowy_float; - percent=(1-lowx_float)*y_percent; - temp=(const char*)dataIn+xindex+lowy_int*rowSizeInBytes; - (*extractPackedPixel)(isSwap, temp, extractTotals); - for (k=0; k1) - { - highx_float-=1.0; - highx_int++; - } - } - lowy_int=highy_int; - lowy_float=highy_float; - highy_int+=convy_int; - highy_float+=convy_float; - - if (highy_float>1) - { - highy_float-=1.0; - highy_int++; - } - } - - assert(outindex==(widthOut*heightOut-1)); -} /* scaleInternalPackedPixel() */ - -/* rowSizeInBytes is at least the width (in bytes) due to padding on - * inputs; not always equal. Output NEVER has row padding. - */ -static void halveImagePackedPixel(int components, - void (*extractPackedPixel) - (int, const void*,GLfloat []), - void (*shovePackedPixel) - (const GLfloat [],int, void*), - GLint width, GLint height, - const void* dataIn, void* dataOut, - GLint pixelSizeInBytes, - GLint rowSizeInBytes, GLint isSwap) -{ - /* handle case where there is only 1 column/row */ - if (width==1 || height==1) - { - assert(!(width==1 && height==1)); /* can't be 1x1 */ - halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel, - width,height,dataIn,dataOut,pixelSizeInBytes, - rowSizeInBytes,isSwap); - return; - } - - { - int ii, jj; - - int halfWidth=width/2; - int halfHeight=height/2; - const char* src=(const char*)dataIn; - int padBytes=rowSizeInBytes-(width*pixelSizeInBytes); - int outIndex=0; - - for (ii=0; iiOO... - * but want -->OO... - * OO... - * ... - */ - src+=rowSizeInBytes; - } - - /* both pointers must reach one byte after the end */ - assert(src==&((const char*)dataIn)[rowSizeInBytes*height]); - assert(outIndex==halfWidth*halfHeight); - } -} /* halveImagePackedPixel() */ - -static void halve1DimagePackedPixel(int components, - void (*extractPackedPixel) - (int, const void*,GLfloat []), - void (*shovePackedPixel) - (const GLfloat [],int, void*), - GLint width, GLint height, - const void* dataIn, void* dataOut, - GLint pixelSizeInBytes, - GLint rowSizeInBytes, GLint isSwap) -{ - int halfWidth=width/2; - int halfHeight=height/2; - const char *src=(const char*)dataIn; - int jj; - - assert(width==1 || height==1); /* must be 1D */ - assert(width!= height); /* can't be square */ - - if (height==1) - { - /* 1 row */ - int outIndex=0; - - assert(width!=1); /* widthxheight can't be 1x1 */ - halfHeight=1; - - /* one horizontal row with possible pad bytes */ - for (jj=0; jj - */ - -#ifndef __GLUES_MIPMAP_H__ -#define __GLUES_MIPMAP_H__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 -#define GLU_INCOMPATIBLE_GL_VERSION 100903 -#define GLU_INVALID_OPERATION 100904 - -GLAPI GLint APIENTRY gluScaleImage(GLenum format, GLsizei widthin, - GLsizei heightin, GLenum typein, - const void* datain, GLsizei widthout, - GLsizei heightout, GLenum typeout, void* dataout); -GLAPI GLint APIENTRY gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, - GLsizei width, GLsizei height, GLenum format, - GLenum type, GLint userLevel, GLint baseLevel, - GLint maxLevel, const void *data); -GLAPI GLint APIENTRY gluBuild2DMipmaps(GLenum target, GLint internalFormat, - GLsizei width, GLsizei height, GLenum format, - GLenum type, const void* data); - -#ifdef __cplusplus -} -#endif - -#endif /* __GLUES_REGISTRY_H__ */ diff --git a/internal/c/parts/core/glues/src/glues_project.c b/internal/c/parts/core/glues/src/glues_project.c deleted file mode 100644 index 55bde70ce..000000000 --- a/internal/c/parts/core/glues/src/glues_project.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES 1.0 CM port of part of GLU by Mike Gorchak - */ - -#include -#include "glues_project.h" - -/* -** Make m an identity matrix -*/ - -static void __gluMakeIdentityf(GLfloat m[16]) -{ - m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; - m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; - m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; - m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; -} - -GLAPI void APIENTRY -gluOrtho2D(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top) -{ - glOrthof(left, right, bottom, top, -1, 1); -} - -#define __glPi 3.14159265358979323846 - -GLAPI void APIENTRY -gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) -{ - GLfloat m[4][4]; - GLfloat sine, cotangent, deltaZ; - GLfloat radians=(GLfloat)(fovy/2.0f*__glPi/180.0f); - - deltaZ=zFar-zNear; - sine=(GLfloat)sin(radians); - if ((deltaZ==0.0f) || (sine==0.0f) || (aspect==0.0f)) - { - return; - } - cotangent=(GLfloat)(cos(radians)/sine); - - __gluMakeIdentityf(&m[0][0]); - m[0][0] = cotangent / aspect; - m[1][1] = cotangent; - m[2][2] = -(zFar + zNear) / deltaZ; - m[2][3] = -1.0f; - m[3][2] = -2.0f * zNear * zFar / deltaZ; - m[3][3] = 0; - glMultMatrixf(&m[0][0]); -} - -static void normalize(GLfloat v[3]) -{ - GLfloat r; - - r=(GLfloat)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); - if (r==0.0f) - { - return; - } - - v[0]/=r; - v[1]/=r; - v[2]/=r; -} - -static void cross(GLfloat v1[3], GLfloat v2[3], GLfloat result[3]) -{ - result[0] = v1[1]*v2[2] - v1[2]*v2[1]; - result[1] = v1[2]*v2[0] - v1[0]*v2[2]; - result[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -GLAPI void APIENTRY -gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, - GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, - GLfloat upz) -{ - GLfloat forward[3], side[3], up[3]; - GLfloat m[4][4]; - - forward[0] = centerx - eyex; - forward[1] = centery - eyey; - forward[2] = centerz - eyez; - - up[0] = upx; - up[1] = upy; - up[2] = upz; - - normalize(forward); - - /* Side = forward x up */ - cross(forward, up, side); - normalize(side); - - /* Recompute up as: up = side x forward */ - cross(side, forward, up); - - __gluMakeIdentityf(&m[0][0]); - m[0][0] = side[0]; - m[1][0] = side[1]; - m[2][0] = side[2]; - - m[0][1] = up[0]; - m[1][1] = up[1]; - m[2][1] = up[2]; - - m[0][2] = -forward[0]; - m[1][2] = -forward[1]; - m[2][2] = -forward[2]; - - glMultMatrixf(&m[0][0]); - glTranslatef(-eyex, -eyey, -eyez); -} - -static void __gluMultMatrixVecf(const GLfloat matrix[16], const GLfloat in[4], - GLfloat out[4]) -{ - int i; - - for (i=0; i<4; i++) - { - out[i] = in[0] * matrix[0*4+i] + - in[1] * matrix[1*4+i] + - in[2] * matrix[2*4+i] + - in[3] * matrix[3*4+i]; - } -} - -/* -** Invert 4x4 matrix. -** Contributed by David Moore (See Mesa bug #6748) -*/ -static int __gluInvertMatrixf(const GLfloat m[16], GLfloat invOut[16]) -{ - GLfloat inv[16], det; - int i; - - inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] - + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10]; - inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] - - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10]; - inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] - + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9]; - inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] - - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9]; - inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] - - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10]; - inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] - + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10]; - inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] - - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9]; - inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] - + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9]; - inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] - + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6]; - inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] - - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6]; - inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] - + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5]; - inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] - - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5]; - inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] - - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6]; - inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] - + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6]; - inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] - - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5]; - inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] - + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5]; - - det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; - if (det == 0) - return GL_FALSE; - - det=1.0f/det; - - for (i = 0; i < 16; i++) - invOut[i] = inv[i] * det; - - return GL_TRUE; -} - -static void __gluMultMatricesf(const GLfloat a[16], const GLfloat b[16], - GLfloat r[16]) -{ - int i, j; - - for (i = 0; i < 4; i++) - { - for (j = 0; j < 4; j++) - { - r[i*4+j] = a[i*4+0]*b[0*4+j] + - a[i*4+1]*b[1*4+j] + - a[i*4+2]*b[2*4+j] + - a[i*4+3]*b[3*4+j]; - } - } -} - -GLAPI GLint APIENTRY -gluProject(GLfloat objx, GLfloat objy, GLfloat objz, - const GLfloat modelMatrix[16], - const GLfloat projMatrix[16], - const GLint viewport[4], - GLfloat* winx, GLfloat* winy, GLfloat* winz) -{ - GLfloat in[4]; - GLfloat out[4]; - - in[0]=objx; - in[1]=objy; - in[2]=objz; - in[3]=1.0; - __gluMultMatrixVecf(modelMatrix, in, out); - __gluMultMatrixVecf(projMatrix, out, in); - if (in[3] == 0.0) - { - return(GL_FALSE); - } - - in[0]/=in[3]; - in[1]/=in[3]; - in[2]/=in[3]; - /* Map x, y and z to range 0-1 */ - in[0]=in[0]*0.5f+0.5f; - in[1]=in[1]*0.5f+0.5f; - in[2]=in[2]*0.5f+0.5f; - - /* Map x,y to viewport */ - in[0]=in[0] * viewport[2] + viewport[0]; - in[1]=in[1] * viewport[3] + viewport[1]; - - *winx=in[0]; - *winy=in[1]; - *winz=in[2]; - - return(GL_TRUE); -} - -GLAPI GLint APIENTRY -gluUnProject(GLfloat winx, GLfloat winy, GLfloat winz, - const GLfloat modelMatrix[16], - const GLfloat projMatrix[16], - const GLint viewport[4], - GLfloat* objx, GLfloat* objy, GLfloat* objz) -{ - GLfloat finalMatrix[16]; - GLfloat in[4]; - GLfloat out[4]; - - __gluMultMatricesf(modelMatrix, projMatrix, finalMatrix); - if (!__gluInvertMatrixf(finalMatrix, finalMatrix)) - { - return(GL_FALSE); - } - - in[0]=winx; - in[1]=winy; - in[2]=winz; - in[3]=1.0; - - /* Map x and y from window coordinates */ - in[0] = (in[0] - viewport[0]) / viewport[2]; - in[1] = (in[1] - viewport[1]) / viewport[3]; - - /* Map to range -1 to 1 */ - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - __gluMultMatrixVecf(finalMatrix, in, out); - if (out[3] == 0.0) - { - return(GL_FALSE); - } - - out[0] /= out[3]; - out[1] /= out[3]; - out[2] /= out[3]; - *objx = out[0]; - *objy = out[1]; - *objz = out[2]; - - return(GL_TRUE); -} - -GLAPI GLint APIENTRY -gluUnProject4(GLfloat winx, GLfloat winy, GLfloat winz, GLfloat clipw, - const GLfloat modelMatrix[16], - const GLfloat projMatrix[16], - const GLint viewport[4], - GLclampf nearVal, GLclampf farVal, - GLfloat *objx, GLfloat *objy, GLfloat *objz, - GLfloat *objw) -{ - GLfloat finalMatrix[16]; - GLfloat in[4]; - GLfloat out[4]; - - __gluMultMatricesf(modelMatrix, projMatrix, finalMatrix); - if (!__gluInvertMatrixf(finalMatrix, finalMatrix)) - { - return(GL_FALSE); - } - - in[0]=winx; - in[1]=winy; - in[2]=winz; - in[3]=clipw; - - /* Map x and y from window coordinates */ - in[0] = (in[0] - viewport[0]) / viewport[2]; - in[1] = (in[1] - viewport[1]) / viewport[3]; - in[2] = (in[2] - nearVal) / (farVal - nearVal); - - /* Map to range -1 to 1 */ - in[0] = in[0] * 2 - 1; - in[1] = in[1] * 2 - 1; - in[2] = in[2] * 2 - 1; - - __gluMultMatrixVecf(finalMatrix, in, out); - if (out[3] == 0.0) - { - return(GL_FALSE); - } - - *objx = out[0]; - *objy = out[1]; - *objz = out[2]; - *objw = out[3]; - - return(GL_TRUE); -} - -GLAPI void APIENTRY -gluPickMatrix(GLfloat x, GLfloat y, GLfloat deltax, GLfloat deltay, - GLint viewport[4]) -{ - if (deltax <= 0 || deltay <= 0) - { - return; - } - - /* Translate and scale the picked region to the entire window */ - glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax, - (viewport[3] - 2 * (y - viewport[1])) / deltay, 0); - glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0); -} diff --git a/internal/c/parts/core/glues/src/glues_project.h b/internal/c/parts/core/glues/src/glues_project.h deleted file mode 100644 index e0c038cdb..000000000 --- a/internal/c/parts/core/glues/src/glues_project.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#ifndef __GLUES_PROJECT_H__ -#define __GLUES_PROJECT_H__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -GLAPI void APIENTRY gluOrtho2D(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top); -GLAPI void APIENTRY gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); -GLAPI void APIENTRY gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, - GLfloat centerx, GLfloat centery, GLfloat centerz, - GLfloat upx, GLfloat upy, GLfloat upz); -GLAPI GLint APIENTRY gluProject(GLfloat objx, GLfloat objy, GLfloat objz, - const GLfloat modelMatrix[16], const GLfloat projMatrix[16], - const GLint viewport[4], GLfloat* winx, GLfloat* winy, GLfloat* winz); -GLAPI GLint APIENTRY gluUnProject(GLfloat winx, GLfloat winy, GLfloat winz, - const GLfloat modelMatrix[16], const GLfloat projMatrix[16], - const GLint viewport[4], GLfloat* objx, GLfloat* objy, GLfloat* objz); -GLAPI GLint APIENTRY gluUnProject4(GLfloat winx, GLfloat winy, GLfloat winz, GLfloat clipw, - const GLfloat modelMatrix[16], const GLfloat projMatrix[16], - const GLint viewport[4], GLclampf nearVal, GLclampf farVal, - GLfloat* objx, GLfloat* objy, GLfloat* objz, GLfloat* objw); -GLAPI void APIENTRY gluPickMatrix(GLfloat x, GLfloat y, GLfloat deltax, GLfloat deltay, GLint viewport[4]); - -#ifdef __cplusplus -} -#endif - -#endif /* __GLUES_PROJECT_H__ */ diff --git a/internal/c/parts/core/glues/src/glues_quad.c b/internal/c/parts/core/glues/src/glues_quad.c deleted file mode 100644 index 7f070927f..000000000 --- a/internal/c/parts/core/glues/src/glues_quad.c +++ /dev/null @@ -1,1650 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak . - */ - -#include -#include -#include - -#include "glues_quad.h" - -/* Make it not a power of two to avoid cache thrashing on the chip */ -#define CACHE_SIZE 240 - -#undef PI -#define PI 3.14159265358979323846f - -struct GLUquadric -{ - GLint normals; - GLboolean textureCoords; - GLint orientation; - GLint drawStyle; - void (APIENTRY* errorCallback)( GLint ); -}; - -GLAPI GLUquadric* APIENTRY gluNewQuadric(void) -{ - GLUquadric *newstate; - - newstate=(GLUquadric*)malloc(sizeof(GLUquadric)); - if (newstate==NULL) - { - /* Can't report an error at this point... */ - return NULL; - } - - newstate->normals=GLU_SMOOTH; - newstate->textureCoords=GL_FALSE; - newstate->orientation=GLU_OUTSIDE; - newstate->drawStyle=GLU_FILL; - newstate->errorCallback=NULL; - - return newstate; -} - -GLAPI void APIENTRY gluDeleteQuadric(GLUquadric* state) -{ - if (state!=NULL) - { - free(state); - } -} - -static void gluQuadricError(GLUquadric* qobj, GLenum which) -{ - if (qobj->errorCallback) - { - qobj->errorCallback(which); - } -} - -GLAPI void APIENTRY gluQuadricCallback(GLUquadric* qobj, GLenum which, _GLUfuncptr fn) -{ - switch (which) - { - case GLU_ERROR: - qobj->errorCallback=(void(APIENTRY*)(GLint))fn; - break; - default: - gluQuadricError(qobj, GLU_INVALID_ENUM); - return; - } -} - -GLAPI void APIENTRY gluQuadricNormals(GLUquadric* qobj, GLenum normals) -{ - switch (normals) - { - case GLU_SMOOTH: - case GLU_FLAT: - case GLU_NONE: - break; - default: - gluQuadricError(qobj, GLU_INVALID_ENUM); - return; - } - qobj->normals=normals; -} - -GLAPI void APIENTRY gluQuadricTexture(GLUquadric* qobj, GLboolean textureCoords) -{ - qobj->textureCoords=textureCoords; -} - -GLAPI void APIENTRY gluQuadricOrientation(GLUquadric* qobj, GLenum orientation) -{ - switch(orientation) - { - case GLU_OUTSIDE: - case GLU_INSIDE: - break; - default: - gluQuadricError(qobj, GLU_INVALID_ENUM); - return; - } - - qobj->orientation=orientation; -} - -GLAPI void APIENTRY gluQuadricDrawStyle(GLUquadric* qobj, GLenum drawStyle) -{ - switch(drawStyle) - { - case GLU_POINT: - case GLU_LINE: - case GLU_FILL: - case GLU_SILHOUETTE: - break; - default: - gluQuadricError(qobj, GLU_INVALID_ENUM); - return; - } - - qobj->drawStyle=drawStyle; -} - -GLAPI void APIENTRY gluCylinder(GLUquadric* qobj, GLfloat baseRadius, - GLfloat topRadius, GLfloat height, - GLint slices, GLint stacks) -{ - GLint i, j; - GLfloat sinCache[CACHE_SIZE]; - GLfloat cosCache[CACHE_SIZE]; - GLfloat sinCache2[CACHE_SIZE]; - GLfloat cosCache2[CACHE_SIZE]; - GLfloat sinCache3[CACHE_SIZE]; - GLfloat cosCache3[CACHE_SIZE]; - GLfloat sintemp, costemp; - GLfloat vertices[(CACHE_SIZE+1)*2][3]; - GLfloat texcoords[(CACHE_SIZE+1)*2][2]; - GLfloat normals[(CACHE_SIZE+1)*2][3]; - GLfloat angle; - GLfloat zLow, zHigh; - GLfloat length; - GLfloat deltaRadius; - GLfloat zNormal; - GLfloat xyNormalRatio; - GLfloat radiusLow, radiusHigh; - int needCache2, needCache3; - GLboolean texcoord_enabled; - GLboolean normal_enabled; - GLboolean vertex_enabled; - GLboolean color_enabled; - - if (slices>=CACHE_SIZE) - { - slices=CACHE_SIZE-1; - } - - /* Avoid vertex array overflow */ - if (stacks>=CACHE_SIZE) - { - stacks=CACHE_SIZE-1; - } - - if (slices<2 || stacks<1 || baseRadius<0.0 || topRadius<0.0 || height<0.0) - { - gluQuadricError(qobj, GLU_INVALID_VALUE); - return; - } - - /* Compute length (needed for normal calculations) */ - deltaRadius=baseRadius-topRadius; - length=(GLfloat)sqrt(deltaRadius*deltaRadius+height*height); - - if (length==0.0) - { - gluQuadricError(qobj, GLU_INVALID_VALUE); - return; - } - - /* Cache is the vertex locations cache */ - /* Cache2 is the various normals at the vertices themselves */ - /* Cache3 is the various normals for the faces */ - needCache2=needCache3=0; - if (qobj->normals==GLU_SMOOTH) - { - needCache2=1; - } - - if (qobj->normals==GLU_FLAT) - { - if (qobj->drawStyle!=GLU_POINT) - { - needCache3=1; - } - if (qobj->drawStyle==GLU_LINE) - { - needCache2=1; - } - } - - zNormal=deltaRadius/length; - xyNormalRatio=height/length; - - for (i=0; iorientation==GLU_OUTSIDE) - { - sinCache2[i]=(GLfloat)(xyNormalRatio*sin(angle)); - cosCache2[i]=(GLfloat)(xyNormalRatio*cos(angle)); - } - else - { - sinCache2[i]=(GLfloat)(-xyNormalRatio*sin(angle)); - cosCache2[i]=(GLfloat)(-xyNormalRatio*cos(angle)); - } - } - - sinCache[i]=(GLfloat)sin(angle); - cosCache[i]=(GLfloat)cos(angle); - } - - if (needCache3) - { - for (i=0; iorientation==GLU_OUTSIDE) - { - sinCache3[i]=(GLfloat)(xyNormalRatio*sin(angle)); - cosCache3[i]=(GLfloat)(xyNormalRatio*cos(angle)); - } - else - { - sinCache3[i]=(GLfloat)(-xyNormalRatio*sin(angle)); - cosCache3[i]=(GLfloat)(-xyNormalRatio*cos(angle)); - } - } - } - - sinCache[slices]=sinCache[0]; - cosCache[slices]=cosCache[0]; - if (needCache2) - { - sinCache2[slices]=sinCache2[0]; - cosCache2[slices]=cosCache2[0]; - } - if (needCache3) - { - sinCache3[slices]=sinCache3[0]; - cosCache3[slices]=cosCache3[0]; - } - - /* Store status of enabled arrays */ - texcoord_enabled=GL_FALSE; //glIsEnabled(GL_TEXTURE_COORD_ARRAY); - normal_enabled=GL_FALSE; //glIsEnabled(GL_NORMAL_ARRAY); - vertex_enabled=GL_FALSE; //glIsEnabled(GL_VERTEX_ARRAY); - color_enabled=GL_FALSE; //glIsEnabled(GL_COLOR_ARRAY); - - /* Enable or disable arrays */ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vertices); - if (qobj->textureCoords) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, texcoords); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - if (qobj->normals!=GLU_NONE) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, normals); - } - else - { - glDisableClientState(GL_NORMAL_ARRAY); - } - glDisableClientState(GL_COLOR_ARRAY); - - switch (qobj->drawStyle) - { - case GLU_FILL: - for (j=0; jnormals) - { - case GLU_FLAT: - /* per vertex normals */ - normals[i*2][0]=sinCache3[i]; - normals[i*2][1]=cosCache3[i]; - normals[i*2][2]=zNormal; - normals[i*2+1][0]=sinCache3[i]; - normals[i*2+1][1]=cosCache3[i]; - normals[i*2+1][2]=zNormal; - break; - case GLU_SMOOTH: - /* per vertex normals */ - normals[i*2][0]=sinCache2[i]; - normals[i*2][1]=cosCache2[i]; - normals[i*2][2]=zNormal; - normals[i*2+1][0]=sinCache2[i]; - normals[i*2+1][1]=cosCache2[i]; - normals[i*2+1][2]=zNormal; - break; - case GLU_NONE: - default: - break; - } - if (qobj->orientation==GLU_OUTSIDE) - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=1-(GLfloat)i/slices; - texcoords[i*2][1]=(GLfloat)j/stacks; - } - vertices[i*2][0]=radiusLow*sinCache[i]; - vertices[i*2][1]=radiusLow*cosCache[i]; - vertices[i*2][2]=zLow; - - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=1-(GLfloat)i/slices; - texcoords[i*2+1][1]=(GLfloat)(j+1)/stacks; - } - vertices[i*2+1][0]=radiusHigh*sinCache[i]; - vertices[i*2+1][1]=radiusHigh*cosCache[i]; - vertices[i*2+1][2]=zHigh; - } - else - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=1-(GLfloat)i/slices; - texcoords[i*2][1]=(GLfloat)(j+1)/ stacks; - } - vertices[i*2][0]=radiusHigh*sinCache[i]; - vertices[i*2][1]=radiusHigh*cosCache[i]; - vertices[i*2][2]=zHigh; - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=1-(GLfloat)i/slices; - texcoords[i*2+1][1]=(GLfloat)j/stacks; - } - vertices[i*2+1][0]=radiusLow*sinCache[i]; - vertices[i*2+1][1]=radiusLow*cosCache[i]; - vertices[i*2+1][2]=zLow; - } - } - glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*(slices+1)); - } - break; - case GLU_POINT: - for (i=0; inormals) - { - case GLU_FLAT: - case GLU_SMOOTH: - normals[j][0]=sinCache2[i]; - normals[j][1]=cosCache2[i]; - normals[j][2]=zNormal; - break; - case GLU_NONE: - default: - break; - } - - zLow=j*height/stacks; - radiusLow=baseRadius-deltaRadius*((GLfloat)j/stacks); - - if (qobj->textureCoords) - { - texcoords[j][0]=1-(GLfloat)i/slices; - texcoords[j][1]=(GLfloat)j/stacks; - } - vertices[j][0]=radiusLow*sintemp; - vertices[j][1]=radiusLow*costemp; - vertices[j][2]=zLow; - } - glDrawArrays(GL_POINTS, 0, (stacks+1)); - } - break; - case GLU_LINE: - for (j=1; jnormals) - { - case GLU_FLAT: - normals[i][0]=sinCache3[i]; - normals[i][1]=cosCache3[i]; - normals[i][2]=zNormal; - break; - case GLU_SMOOTH: - normals[i][0]=sinCache2[i]; - normals[i][1]=cosCache2[i]; - normals[i][2]=zNormal; - break; - case GLU_NONE: - default: - break; - } - if (qobj->textureCoords) - { - texcoords[i][0]=1-(GLfloat)i/slices; - texcoords[i][1]=(GLfloat)j/stacks; - } - vertices[i][0]=radiusLow*sinCache[i]; - vertices[i][1]=radiusLow*cosCache[i]; - vertices[i][2]=zLow; - } - glDrawArrays(GL_LINE_STRIP, 0, (slices+1)); - } - /* Intentionally fall through here... */ - case GLU_SILHOUETTE: - for (j=0; j<=stacks; j+=stacks) - { - zLow=j*height/stacks; - radiusLow=baseRadius-deltaRadius*((GLfloat)j/stacks); - - for (i=0; i<=slices; i++) - { - switch(qobj->normals) - { - case GLU_FLAT: - normals[i][0]=sinCache3[i]; - normals[i][1]=cosCache3[i]; - normals[i][2]=zNormal; - break; - case GLU_SMOOTH: - normals[i][0]=sinCache2[i]; - normals[i][1]=cosCache2[i]; - normals[i][2]=zNormal; - break; - case GLU_NONE: - default: - break; - } - if (qobj->textureCoords) - { - texcoords[i][0]=1-(GLfloat)i/slices; - texcoords[i][1]=(GLfloat)j/stacks; - } - vertices[i][0]=radiusLow*sinCache[i]; - vertices[i][1]=radiusLow*cosCache[i]; - vertices[i][2]=zLow; - } - glDrawArrays(GL_LINE_STRIP, 0, (slices+1)); - } - - for (i=0; inormals) - { - case GLU_FLAT: - case GLU_SMOOTH: - normals[j][0]=sinCache2[i]; - normals[j][1]=cosCache2[i]; - normals[j][2]=0.0f; - break; - case GLU_NONE: - default: - break; - } - - zLow=j*height/stacks; - radiusLow=baseRadius-deltaRadius*((GLfloat)j/stacks); - - if (qobj->textureCoords) - { - texcoords[j][0]=1-(GLfloat)i/slices; - texcoords[j][1]=(GLfloat)j/stacks; - } - vertices[j][0]=radiusLow*sintemp; - vertices[j][1]=radiusLow*costemp; - vertices[j][2]=zLow; - } - glDrawArrays(GL_LINE_STRIP, 0, (stacks+1)); - } - break; - default: - break; - } - - /* Disable or re-enable arrays */ - if (vertex_enabled) - { - /* Re-enable vertex array */ - glEnableClientState(GL_VERTEX_ARRAY); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - } - - if (texcoord_enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (normal_enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - } - else - { - glDisableClientState(GL_NORMAL_ARRAY); - } - - if (color_enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - } - else - { - glDisableClientState(GL_COLOR_ARRAY); - } -} - -GLAPI void APIENTRY gluDisk(GLUquadric* qobj, GLfloat innerRadius, - GLfloat outerRadius, GLint slices, GLint loops) -{ - gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, 0.0, 360.0); -} - -GLAPI void APIENTRY gluPartialDisk(GLUquadric* qobj, GLfloat innerRadius, - GLfloat outerRadius, GLint slices, - GLint loops, GLfloat startAngle, - GLfloat sweepAngle) -{ - GLint i, j; - GLfloat sinCache[CACHE_SIZE]; - GLfloat cosCache[CACHE_SIZE]; - GLfloat angle; - GLfloat sintemp, costemp; - GLfloat vertices[(CACHE_SIZE+1)*2][3]; - GLfloat texcoords[(CACHE_SIZE+1)*2][2]; - GLfloat deltaRadius; - GLfloat radiusLow, radiusHigh; - GLfloat texLow = 0.0, texHigh = 0.0; - GLfloat angleOffset; - GLint slices2; - GLint finish; - GLboolean texcoord_enabled; - GLboolean normal_enabled; - GLboolean vertex_enabled; - GLboolean color_enabled; - - if (slices>=CACHE_SIZE) - { - slices=CACHE_SIZE-1; - } - - if (slices<2 || loops<1 || outerRadius<=0.0 || - innerRadius<0.0 ||innerRadius > outerRadius) - { - gluQuadricError(qobj, GLU_INVALID_VALUE); - return; - } - - if (sweepAngle<-360.0) - { - sweepAngle=-360.0; - } - if (sweepAngle>360.0) - { - sweepAngle=360.0; - } - - if (sweepAngle<0) - { - startAngle+=sweepAngle; - sweepAngle=-sweepAngle; - } - - if (sweepAngle==360.0) - { - slices2=slices; - } - else - { - slices2=slices+1; - } - - /* Compute length (needed for normal calculations) */ - deltaRadius=outerRadius-innerRadius; - - /* Cache is the vertex locations cache */ - angleOffset=startAngle/180.0f*PI; - for (i=0; i<=slices; i++) - { - angle=angleOffset+((PI*sweepAngle)/180.0f)*i/slices; - sinCache[i]=(GLfloat)sin(angle); - cosCache[i]=(GLfloat)cos(angle); - } - - if (sweepAngle==360.0) - { - sinCache[slices]=sinCache[0]; - cosCache[slices]=cosCache[0]; - } - - switch(qobj->normals) - { - case GLU_FLAT: - case GLU_SMOOTH: - if (qobj->orientation==GLU_OUTSIDE) - { - glNormal3f(0.0f, 0.0f, 1.0f); - } - else - { - glNormal3f(0.0f, 0.0f, -1.0f); - } - break; - default: - case GLU_NONE: - break; - } - - /* Store status of enabled arrays */ - texcoord_enabled=GL_FALSE; //glIsEnabled(GL_TEXTURE_COORD_ARRAY); - normal_enabled=GL_FALSE; //glIsEnabled(GL_NORMAL_ARRAY); - vertex_enabled=GL_FALSE; //glIsEnabled(GL_VERTEX_ARRAY); - color_enabled=GL_FALSE; //glIsEnabled(GL_COLOR_ARRAY); - - /* Enable arrays */ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vertices); - if (qobj->textureCoords) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, texcoords); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - switch (qobj->drawStyle) - { - case GLU_FILL: - if (innerRadius==0.0) - { - finish=loops-1; - - /* Triangle strip for inner polygons */ - if (qobj->textureCoords) - { - texcoords[0][0]=0.5f; - texcoords[0][1]=0.5f; - } - vertices[0][0]=0.0f; - vertices[0][1]=0.0f; - vertices[0][2]=0.0f; - radiusLow=outerRadius-deltaRadius*((GLfloat)(loops-1)/loops); - if (qobj->textureCoords) - { - texLow=radiusLow/outerRadius/2; - } - - if (qobj->orientation==GLU_OUTSIDE) - { - for (i=slices; i>=0; i--) - { - if (qobj->textureCoords) - { - texcoords[slices-i+1][0]=texLow*sinCache[i]+0.5f; - texcoords[slices-i+1][1]=texLow*cosCache[i]+0.5f; - } - vertices[slices-i+1][0]=radiusLow*sinCache[i]; - vertices[slices-i+1][1]=radiusLow*cosCache[i]; - vertices[slices-i+1][2]=0.0f; - } - } - else - { - for (i=0; i<=slices; i++) - { - if (qobj->textureCoords) - { - texcoords[i+1][0]=texLow*sinCache[i]+0.5f; - texcoords[i+1][1]=texLow*cosCache[i]+0.5f; - } - vertices[i+1][0]=radiusLow*sinCache[i]; - vertices[i+1][1]=radiusLow*cosCache[i]; - vertices[i+1][2]=0.0f; - } - } - glDrawArrays(GL_TRIANGLE_FAN, 0, (slices+2)); - } - else - { - finish=loops; - } - - for (j=0; jtextureCoords) - { - texLow=radiusLow/outerRadius/2; - texHigh=radiusHigh/outerRadius/2; - } - - for (i=0; i<=slices; i++) - { - if (qobj->orientation==GLU_OUTSIDE) - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=texLow*sinCache[i]+0.5f; - texcoords[i*2][1]=texLow*cosCache[i]+0.5f; - } - vertices[i*2][0]=radiusLow*sinCache[i]; - vertices[i*2][1]=radiusLow*cosCache[i]; - vertices[i*2][2]=0.0; - - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=texHigh*sinCache[i]+0.5f; - texcoords[i*2+1][1]=texHigh*cosCache[i]+0.5f; - } - vertices[i*2+1][0]=radiusHigh*sinCache[i]; - vertices[i*2+1][1]=radiusHigh*cosCache[i]; - vertices[i*2+1][2]=0.0; - } - else - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=texHigh*sinCache[i]+0.5f; - texcoords[i*2][1]=texHigh*cosCache[i]+0.5f; - } - vertices[i*2][0]=radiusHigh*sinCache[i]; - vertices[i*2][1]=radiusHigh*cosCache[i]; - vertices[i*2][2]=0.0; - - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=texLow*sinCache[i]+0.5f; - texcoords[i*2+1][1]=texLow*cosCache[i]+0.5f; - } - vertices[i*2+1][0]=radiusLow*sinCache[i]; - vertices[i*2+1][1]=radiusLow*cosCache[i]; - vertices[i*2+1][2]=0.0; - } - } - glDrawArrays(GL_TRIANGLE_STRIP, 0, ((slices+1)*2)); - } - break; - case GLU_POINT: - for (j=0; j<=loops; j++) - { - radiusLow=outerRadius-deltaRadius*((GLfloat)j/loops); - - for (i=0; itextureCoords) - { - texLow=radiusLow/outerRadius/2; - texcoords[i][0]=texLow*sinCache[i]+0.5f; - texcoords[i][1]=texLow*cosCache[i]+0.5f; - } - vertices[i][0]=radiusLow*sintemp; - vertices[i][1]=radiusLow*costemp; - vertices[i][2]=0.0f; - } - glDrawArrays(GL_POINTS, 0, slices2); - } - break; - case GLU_LINE: - if (innerRadius==outerRadius) - { - for (i=0; i<=slices; i++) - { - if (qobj->textureCoords) - { - texcoords[i][0]=sinCache[i]/2+0.5f; - texcoords[i][1]=cosCache[i]/2+0.5f; - } - vertices[i][0]=innerRadius*sinCache[i]; - vertices[i][1]=innerRadius*cosCache[i]; - vertices[i][2]=0.0f; - } - glDrawArrays(GL_LINE_STRIP, 0, slices+1); - break; - } - - for (j=0; j<=loops; j++) - { - radiusLow=outerRadius-deltaRadius*((GLfloat)j/loops); - if (qobj->textureCoords) - { - texLow=radiusLow/outerRadius/2; - } - - for (i=0; i<=slices; i++) - { - if (qobj->textureCoords) - { - texcoords[i][0]=texLow*sinCache[i]+0.5f; - texcoords[i][1]=texLow*cosCache[i]+0.5f; - } - vertices[i][0]=radiusLow*sinCache[i]; - vertices[i][1]=radiusLow*cosCache[i]; - vertices[i][2]=0.0f; - } - glDrawArrays(GL_LINE_STRIP, 0, slices+1); - } - - for (i=0; itextureCoords) - { - texLow=radiusLow/outerRadius/2; - } - - if (qobj->textureCoords) - { - texcoords[j][0]=texLow*sinCache[i]+0.5f; - texcoords[j][1]=texLow*cosCache[i]+0.5f; - } - vertices[j][0]=radiusLow*sintemp; - vertices[j][1]=radiusLow*costemp; - vertices[j][2]=0.0f; - } - glDrawArrays(GL_LINE_STRIP, 0, loops+1); - } - break; - case GLU_SILHOUETTE: - if (sweepAngle<360.0) - { - for (i=0; i<=slices; i+=slices) - { - sintemp=sinCache[i]; - costemp=cosCache[i]; - - for (j=0; j<=loops; j++) - { - radiusLow=outerRadius-deltaRadius*((GLfloat)j/loops); - - if (qobj->textureCoords) - { - texLow=radiusLow/outerRadius/2; - texcoords[j][0]=texLow*sinCache[i]+0.5f; - texcoords[j][1]=texLow*cosCache[i]+0.5f; - } - vertices[j][0]=radiusLow*sintemp; - vertices[j][1]=radiusLow*costemp; - vertices[j][2]=0.0f; - } - glDrawArrays(GL_LINE_STRIP, 0, loops+1); - } - } - - for (j=0; j<=loops; j+=loops) - { - radiusLow=outerRadius-deltaRadius*((GLfloat)j/loops); - if (qobj->textureCoords) - { - texLow=radiusLow/outerRadius/2; - } - - for (i=0; i<=slices; i++) - { - if (qobj->textureCoords) - { - texcoords[i][0]=texLow*sinCache[i]+0.5f; - texcoords[i][1]=texLow*cosCache[i]+0.5f; - } - vertices[i][0]=radiusLow*sinCache[i]; - vertices[i][1]=radiusLow*cosCache[i]; - vertices[i][2]=0.0f; - } - glDrawArrays(GL_LINE_STRIP, 0, slices+1); - - if (innerRadius==outerRadius) - { - break; - } - } - break; - default: - break; - } - - /* Disable or re-enable arrays */ - if (vertex_enabled) - { - /* Re-enable vertex array */ - glEnableClientState(GL_VERTEX_ARRAY); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - } - - if (texcoord_enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (normal_enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - } - else - { - glDisableClientState(GL_NORMAL_ARRAY); - } - - if (color_enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - } - else - { - glDisableClientState(GL_COLOR_ARRAY); - } -} - -GLAPI void APIENTRY gluSphere(GLUquadric* qobj, GLfloat radius, GLint slices, GLint stacks) -{ - GLint i, j; - GLfloat sinCache1a[CACHE_SIZE]; - GLfloat cosCache1a[CACHE_SIZE]; - GLfloat sinCache2a[CACHE_SIZE]; - GLfloat cosCache2a[CACHE_SIZE]; - GLfloat sinCache3a[CACHE_SIZE]; - GLfloat cosCache3a[CACHE_SIZE]; - GLfloat sinCache1b[CACHE_SIZE]; - GLfloat cosCache1b[CACHE_SIZE]; - GLfloat sinCache2b[CACHE_SIZE]; - GLfloat cosCache2b[CACHE_SIZE]; - GLfloat sinCache3b[CACHE_SIZE]; - GLfloat cosCache3b[CACHE_SIZE]; - GLfloat angle; - GLfloat zLow, zHigh; - GLfloat sintemp1 = 0.0, sintemp2 = 0.0, sintemp3 = 0.0, sintemp4 = 0.0; - GLfloat costemp1 = 0.0, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0; - GLfloat vertices[(CACHE_SIZE+1)*2][3]; - GLfloat texcoords[(CACHE_SIZE+1)*2][2]; - GLfloat normals[(CACHE_SIZE+1)*2][3]; - GLboolean needCache2, needCache3; - GLint start, finish; - GLboolean texcoord_enabled; - GLboolean normal_enabled; - GLboolean vertex_enabled; - GLboolean color_enabled; - - if (slices>=CACHE_SIZE) - { - slices=CACHE_SIZE-1; - } - - if (stacks>=CACHE_SIZE) - { - stacks=CACHE_SIZE-1; - } - - if (slices<2 || stacks<1 || radius<0.0) - { - gluQuadricError(qobj, GLU_INVALID_VALUE); - return; - } - - /* Cache is the vertex locations cache */ - /* Cache2 is the various normals at the vertices themselves */ - /* Cache3 is the various normals for the faces */ - needCache2=needCache3=GL_FALSE; - - if (qobj->normals==GLU_SMOOTH) - { - needCache2=GL_TRUE; - } - - if (qobj->normals==GLU_FLAT) - { - if (qobj->drawStyle!=GLU_POINT) - { - needCache3=GL_TRUE; - } - if (qobj->drawStyle==GLU_LINE) - { - needCache2=GL_TRUE; - } - } - - for (i=0; iorientation==GLU_OUTSIDE) - { - sinCache2b[j]=(GLfloat)sin(angle); - cosCache2b[j]=(GLfloat)cos(angle); - } - else - { - sinCache2b[j]=(GLfloat)-sin(angle); - cosCache2b[j]=(GLfloat)-cos(angle); - } - } - - sinCache1b[j]=(GLfloat)(radius*sin(angle)); - cosCache1b[j]=(GLfloat)(radius*cos(angle)); - } - - /* Make sure it comes to a point */ - sinCache1b[0]=0; - sinCache1b[stacks]=0; - - if (needCache3) - { - for (i=0; iorientation==GLU_OUTSIDE) - { - sinCache3b[j]=(GLfloat)sin(angle); - cosCache3b[j]=(GLfloat)cos(angle); - } - else - { - sinCache3b[j]=(GLfloat)-sin(angle); - cosCache3b[j]=(GLfloat)-cos(angle); - } - } - } - - sinCache1a[slices]=sinCache1a[0]; - cosCache1a[slices]=cosCache1a[0]; - if (needCache2) - { - sinCache2a[slices]=sinCache2a[0]; - cosCache2a[slices]=cosCache2a[0]; - } - if (needCache3) - { - sinCache3a[slices]=sinCache3a[0]; - cosCache3a[slices]=cosCache3a[0]; - } - - /* Store status of enabled arrays */ - texcoord_enabled=GL_FALSE; //glIsEnabled(GL_TEXTURE_COORD_ARRAY); - normal_enabled=GL_FALSE; //glIsEnabled(GL_NORMAL_ARRAY); - vertex_enabled=GL_FALSE; //glIsEnabled(GL_VERTEX_ARRAY); - color_enabled=GL_FALSE; //glIsEnabled(GL_COLOR_ARRAY); - - /* Enable arrays */ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vertices); - if (qobj->textureCoords) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, texcoords); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - if (qobj->normals!=GLU_NONE) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, normals); - } - else - { - glDisableClientState(GL_NORMAL_ARRAY); - } - glDisableClientState(GL_COLOR_ARRAY); - - switch (qobj->drawStyle) - { - case GLU_FILL: - if (!(qobj->textureCoords)) - { - start=1; - finish=stacks-1; - - /* Low end first (j == 0 iteration) */ - sintemp2=sinCache1b[1]; - zHigh=cosCache1b[1]; - - switch(qobj->normals) - { - case GLU_FLAT: - sintemp3=sinCache3b[1]; - costemp3=cosCache3b[1]; - normals[0][0]=sinCache3a[0]*sinCache3b[0]; - normals[0][1]=cosCache3a[0]*sinCache3b[0]; - normals[0][2]=cosCache3b[0]; - break; - case GLU_SMOOTH: - sintemp3=sinCache2b[1]; - costemp3=cosCache2b[1]; - normals[0][0]=sinCache2a[0]*sinCache2b[0]; - normals[0][1]=cosCache2a[0]*sinCache2b[0]; - normals[0][2]=cosCache2b[0]; - break; - default: - break; - } - - vertices[0][0]=0.0f; - vertices[0][1]=0.0f; - vertices[0][2]=radius; - - if (qobj->orientation==GLU_OUTSIDE) - { - for (i=slices; i>=0; i--) - { - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[slices-i+1][0]=sinCache2a[i]*sintemp3; - normals[slices-i+1][1]=cosCache2a[i]*sintemp3; - normals[slices-i+1][2]=costemp3; - break; - case GLU_FLAT: - if (i!=slices) - { - normals[slices-i+1][0]=sinCache3a[i+1]*sintemp3; - normals[slices-i+1][1]=cosCache3a[i+1]*sintemp3; - normals[slices-i+1][2]=costemp3; - } - else - { - /* We must add any normal here */ - normals[slices-i+1][0]=sinCache3a[i]*sintemp3; - normals[slices-i+1][1]=cosCache3a[i]*sintemp3; - normals[slices-i+1][2]=costemp3; - } - break; - case GLU_NONE: - default: - break; - } - vertices[slices-i+1][0]=sintemp2*sinCache1a[i]; - vertices[slices-i+1][1]=sintemp2*cosCache1a[i]; - vertices[slices-i+1][2]=zHigh; - } - } - else - { - for (i=0; i<=slices; i++) - { - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[i+1][0]=sinCache2a[i]*sintemp3; - normals[i+1][1]=cosCache2a[i]*sintemp3; - normals[i+1][2]=costemp3; - break; - case GLU_FLAT: - normals[i+1][0]=sinCache3a[i]*sintemp3; - normals[i+1][1]=cosCache3a[i]*sintemp3; - normals[i+1][2]=costemp3; - break; - case GLU_NONE: - default: - break; - } - vertices[i+1][0]=sintemp2*sinCache1a[i]; - vertices[i+1][1]=sintemp2*cosCache1a[i]; - vertices[i+1][2]=zHigh; - } - } - glDrawArrays(GL_TRIANGLE_FAN, 0, (slices+2)); - - /* High end next (j==stacks-1 iteration) */ - sintemp2=sinCache1b[stacks-1]; - zHigh=cosCache1b[stacks-1]; - switch(qobj->normals) - { - case GLU_FLAT: - sintemp3=sinCache3b[stacks]; - costemp3=cosCache3b[stacks]; - normals[0][0]=sinCache3a[stacks]*sinCache3b[stacks]; - normals[0][1]=cosCache3a[stacks]*sinCache3b[stacks]; - normals[0][2]=cosCache3b[stacks]; - break; - case GLU_SMOOTH: - sintemp3=sinCache2b[stacks-1]; - costemp3=cosCache2b[stacks-1]; - normals[0][0]=sinCache2a[stacks]*sinCache2b[stacks]; - normals[0][1]=cosCache2a[stacks]*sinCache2b[stacks]; - normals[0][2]=cosCache2b[stacks]; - break; - default: - break; - } - - vertices[0][0]=0.0f; - vertices[0][1]=0.0f; - vertices[0][2]=-radius; - - if (qobj->orientation==GLU_OUTSIDE) - { - for (i=0; i<=slices; i++) - { - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[i+1][0]=sinCache2a[i]*sintemp3; - normals[i+1][1]=cosCache2a[i]*sintemp3; - normals[i+1][2]=costemp3; - break; - case GLU_FLAT: - normals[i+1][0]=sinCache3a[i]*sintemp3; - normals[i+1][1]=cosCache3a[i]*sintemp3; - normals[i+1][2]=costemp3; - break; - case GLU_NONE: - default: - break; - } - vertices[i+1][0]=sintemp2*sinCache1a[i]; - vertices[i+1][1]=sintemp2*cosCache1a[i]; - vertices[i+1][2]=zHigh; - } - } - else - { - for (i=slices; i>=0; i--) - { - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[slices-i+1][0]=sinCache2a[i]*sintemp3; - normals[slices-i+1][1]=cosCache2a[i]*sintemp3; - normals[slices-i+1][2]=costemp3; - break; - case GLU_FLAT: - if (i!=slices) - { - normals[slices-i+1][0]=sinCache3a[i+1]*sintemp3; - normals[slices-i+1][1]=cosCache3a[i+1]*sintemp3; - normals[slices-i+1][2]=costemp3; - } - else - { - normals[slices-i+1][0]=sinCache3a[i]*sintemp3; - normals[slices-i+1][1]=cosCache3a[i]*sintemp3; - normals[slices-i+1][2]=costemp3; - } - break; - case GLU_NONE: - default: - break; - } - vertices[slices-i+1][0]=sintemp2*sinCache1a[i]; - vertices[slices-i+1][1]=sintemp2*cosCache1a[i]; - vertices[slices-i+1][2]=zHigh; - } - } - glDrawArrays(GL_TRIANGLE_FAN, 0, (slices+2)); - } - else - { - start=0; - finish=stacks; - } - - for (j=start; jnormals) - { - case GLU_FLAT: - sintemp4=sinCache3b[j+1]; - costemp4=cosCache3b[j+1]; - break; - case GLU_SMOOTH: - if (qobj->orientation==GLU_OUTSIDE) - { - sintemp3=sinCache2b[j+1]; - costemp3=cosCache2b[j+1]; - sintemp4=sinCache2b[j]; - costemp4=cosCache2b[j]; - } - else - { - sintemp3=sinCache2b[j]; - costemp3=cosCache2b[j]; - sintemp4=sinCache2b[j+1]; - costemp4=cosCache2b[j+1]; - } - break; - default: - break; - } - for (i=0; i<=slices; i++) - { - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[i*2][0]=sinCache2a[i]*sintemp3; - normals[i*2][1]=cosCache2a[i]*sintemp3; - normals[i*2][2]=costemp3; - break; - case GLU_FLAT: - normals[i*2][0]=sinCache3a[i]*sintemp4; - normals[i*2][1]=cosCache3a[i]*sintemp4; - normals[i*2][2]=costemp4; - break; - case GLU_NONE: - default: - break; - } - if (qobj->orientation==GLU_OUTSIDE) - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=1-(GLfloat)i/slices; - texcoords[i*2][1]=1-(GLfloat)(j+1)/stacks; - } - vertices[i*2][0]=sintemp2*sinCache1a[i]; - vertices[i*2][1]=sintemp2*cosCache1a[i]; - vertices[i*2][2]=zHigh; - } - else - { - if (qobj->textureCoords) - { - texcoords[i*2][0]=1-(GLfloat)i/slices; - texcoords[i*2][1]=1-(GLfloat)j/stacks; - } - vertices[i*2][0]=sintemp1*sinCache1a[i]; - vertices[i*2][1]=sintemp1*cosCache1a[i]; - vertices[i*2][2]=zLow; - } - switch(qobj->normals) - { - case GLU_SMOOTH: - normals[i*2+1][0]=sinCache2a[i]*sintemp4; - normals[i*2+1][1]=cosCache2a[i]*sintemp4; - normals[i*2+1][2]=costemp4; - break; - case GLU_FLAT: - normals[i*2+1][0]=sinCache3a[i]*sintemp4; - normals[i*2+1][1]=cosCache3a[i]*sintemp4; - normals[i*2+1][2]=costemp4; - break; - case GLU_NONE: - default: - break; - } - if (qobj->orientation==GLU_OUTSIDE) - { - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=1-(GLfloat)i/slices; - texcoords[i*2+1][1]=1-(GLfloat)j/stacks; - } - vertices[i*2+1][0]=sintemp1*sinCache1a[i]; - vertices[i*2+1][1]=sintemp1*cosCache1a[i]; - vertices[i*2+1][2]=zLow; - } - else - { - if (qobj->textureCoords) - { - texcoords[i*2+1][0]=1-(GLfloat)i/slices; - texcoords[i*2+1][1]=1-(GLfloat)(j+1)/stacks; - } - vertices[i*2+1][0]=sintemp2*sinCache1a[i]; - vertices[i*2+1][1]=sintemp2*cosCache1a[i]; - vertices[i*2+1][2]=zHigh; - } - } - glDrawArrays(GL_TRIANGLE_STRIP, 0, (slices+1)*2); - } - break; - case GLU_POINT: - for (j=0; j<=stacks; j++) - { - sintemp1=sinCache1b[j]; - costemp1=cosCache1b[j]; - switch(qobj->normals) - { - case GLU_FLAT: - case GLU_SMOOTH: - sintemp2=sinCache2b[j]; - costemp2=cosCache2b[j]; - break; - default: - break; - } - - for (i=0; inormals) - { - case GLU_FLAT: - case GLU_SMOOTH: - normals[i][0]=sinCache2a[i]*sintemp2; - normals[i][1]=cosCache2a[i]*sintemp2; - normals[i][2]=costemp2; - break; - case GLU_NONE: - default: - break; - } - zLow=j*radius/stacks; - if (qobj->textureCoords) - { - texcoords[i][0]=1-(GLfloat)i/slices; - texcoords[i][1]=1-(GLfloat)j/stacks; - } - vertices[i][0]=sintemp1*sinCache1a[i]; - vertices[i][1]=sintemp1*cosCache1a[i]; - vertices[i][2]=costemp1; - } - glDrawArrays(GL_POINTS, 0, slices); - } - break; - case GLU_LINE: - case GLU_SILHOUETTE: - for (j=1; jnormals) - { - case GLU_FLAT: - case GLU_SMOOTH: - sintemp2=sinCache2b[j]; - costemp2=cosCache2b[j]; - break; - default: - break; - } - - for (i=0; i<=slices; i++) - { - switch(qobj->normals) - { - case GLU_FLAT: - normals[i][0]=sinCache3a[i]*sintemp2; - normals[i][1]=cosCache3a[i]*sintemp2; - normals[i][2]=costemp2; - break; - case GLU_SMOOTH: - normals[i][0]=sinCache2a[i]*sintemp2; - normals[i][1]=cosCache2a[i]*sintemp2; - normals[i][2]=costemp2; - break; - case GLU_NONE: - default: - break; - } - if (qobj->textureCoords) - { - texcoords[i][0]=1-(GLfloat)i/slices; - texcoords[i][1]=1-(GLfloat)j/stacks; - } - vertices[i][0]=sintemp1*sinCache1a[i]; - vertices[i][1]=sintemp1*cosCache1a[i]; - vertices[i][2]=costemp1; - } - glDrawArrays(GL_LINE_STRIP, 0, slices+1); - } - - for (i=0; inormals) - { - case GLU_FLAT: - case GLU_SMOOTH: - sintemp2=sinCache2a[i]; - costemp2=cosCache2a[i]; - break; - default: - break; - } - - for (j=0; j<=stacks; j++) - { - switch(qobj->normals) - { - case GLU_FLAT: - normals[j][0]=sintemp2*sinCache3b[j]; - normals[j][1]=costemp2*sinCache3b[j]; - normals[j][2]=cosCache3b[j]; - break; - case GLU_SMOOTH: - normals[j][0]=sintemp2*sinCache2b[j]; - normals[j][1]=costemp2*sinCache2b[j]; - normals[j][2]=cosCache2b[j]; - break; - case GLU_NONE: - default: - break; - } - - if (qobj->textureCoords) - { - texcoords[j][0]=1-(GLfloat)i/slices; - texcoords[j][1]=1-(GLfloat)j/stacks; - } - vertices[j][0]=sintemp1*sinCache1b[j]; - vertices[j][1]=costemp1*sinCache1b[j]; - vertices[j][2]=cosCache1b[j]; - } - glDrawArrays(GL_LINE_STRIP, 0, stacks+1); - } - break; - default: - break; - } - - /* Disable or re-enable arrays */ - if (vertex_enabled) - { - /* Re-enable vertex array */ - glEnableClientState(GL_VERTEX_ARRAY); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - } - - if (texcoord_enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (normal_enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - } - else - { - glDisableClientState(GL_NORMAL_ARRAY); - } - - if (color_enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - } - else - { - glDisableClientState(GL_COLOR_ARRAY); - } -} diff --git a/internal/c/parts/core/glues/src/glues_quad.h b/internal/c/parts/core/glues/src/glues_quad.h deleted file mode 100644 index 614bfc0de..000000000 --- a/internal/c/parts/core/glues/src/glues_quad.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#ifndef __GLUES_QUAD_H__ -#define __GLUES_QUAD_H__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -/* ErrorCode */ -#define GLU_INVALID_ENUM 100900 -#define GLU_INVALID_VALUE 100901 -#define GLU_OUT_OF_MEMORY 100902 -#define GLU_INCOMPATIBLE_GL_VERSION 100903 -#define GLU_INVALID_OPERATION 100904 - -/* QuadricDrawStyle */ -#define GLU_POINT 100010 -#define GLU_LINE 100011 -#define GLU_FILL 100012 -#define GLU_SILHOUETTE 100013 - -/* QuadricCallback */ -#define GLU_ERROR 100103 - -/* QuadricNormal */ -#define GLU_SMOOTH 100000 -#define GLU_FLAT 100001 -#define GLU_NONE 100002 - -/* QuadricOrientation */ -#define GLU_OUTSIDE 100020 -#define GLU_INSIDE 100021 - -#ifdef __cplusplus -class GLUquadric; -#else -typedef struct GLUquadric GLUquadric; -#endif - -typedef GLUquadric GLUquadricObj; - -#ifndef APIENTRYP - #define APIENTRYP APIENTRY * -#endif /* APIENTRYP */ - -/* Internal convenience typedefs */ -typedef void (APIENTRYP _GLUfuncptr)(); - -GLAPI GLUquadric* APIENTRY gluNewQuadric(void); -GLAPI void APIENTRY gluDeleteQuadric(GLUquadric* state); -GLAPI void APIENTRY gluQuadricCallback(GLUquadric* qobj, GLenum which, - _GLUfuncptr fn); -GLAPI void APIENTRY gluQuadricNormals(GLUquadric* qobj, GLenum normals); -GLAPI void APIENTRY gluQuadricTexture(GLUquadric* qobj, GLboolean textureCoords); -GLAPI void APIENTRY gluQuadricOrientation(GLUquadric* qobj, GLenum orientation); -GLAPI void APIENTRY gluQuadricDrawStyle(GLUquadric* qobj, GLenum drawStyle); -GLAPI void APIENTRY gluCylinder(GLUquadric* qobj, GLfloat baseRadius, - GLfloat topRadius, GLfloat height, - GLint slices, GLint stacks); -GLAPI void APIENTRY gluDisk(GLUquadric* qobj, GLfloat innerRadius, - GLfloat outerRadius, GLint slices, GLint loops); -GLAPI void APIENTRY gluPartialDisk(GLUquadric* qobj, GLfloat innerRadius, - GLfloat outerRadius, GLint slices, - GLint loops, GLfloat startAngle, - GLfloat sweepAngle); -GLAPI void APIENTRY gluSphere(GLUquadric* qobj, GLfloat radius, GLint slices, - GLint stacks); - -#ifdef __cplusplus -} -#endif - -#endif /* __GLUES_QUAD_H__ */ diff --git a/internal/c/parts/core/glues/src/glues_registry.c b/internal/c/parts/core/glues/src/glues_registry.c deleted file mode 100644 index a74c33a7d..000000000 --- a/internal/c/parts/core/glues/src/glues_registry.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#include -#include -#include - -#include "glues_registry.h" - -#ifdef _WIN32 - #pragma warning(disable: 4996) -#endif /* _WIN32 */ - -static const GLubyte versionString[]="1.3"; -static const GLubyte extensionString[]=""; - -GLAPI const GLubyte* APIENTRY gluGetString(GLenum name) -{ - if (name==GLU_VERSION) - { - return versionString; - } - else - { - if (name==GLU_EXTENSIONS) - { - return extensionString; - } - } - - return NULL; -} - -/* extName is an extension name. - * extString is a string of extensions separated by blank(s). There may or - * may not be leading or trailing blank(s) in extString. - * This works in cases of extensions being prefixes of another like - * GL_EXT_texture and GL_EXT_texture3D. - * Returns GL_TRUE if extName is found otherwise it returns GL_FALSE. - */ -GLAPI GLboolean APIENTRY gluCheckExtension(const GLubyte* extName, const GLubyte* extString) -{ - GLboolean flag=GL_FALSE; - char* word; - char* lookHere; - char* deleteThis; - - if (extString==NULL) - { - return GL_FALSE; - } - - deleteThis=lookHere=(char*)malloc(strlen((const char*)extString)+1); - if (lookHere==NULL) - { - return GL_FALSE; - } - - /* strtok() will modify string, so copy it somewhere */ - strcpy(lookHere,(const char*)extString); - - while ((word=strtok(lookHere, " "))!=NULL) - { - if (strcmp(word,(const char*)extName)==0) - { - flag=GL_TRUE; - break; - } - lookHere=NULL; /* get next token */ - } - free((void*)deleteThis); - - return flag; -} diff --git a/internal/c/parts/core/glues/src/glues_registry.h b/internal/c/parts/core/glues/src/glues_registry.h deleted file mode 100644 index 30831c43c..000000000 --- a/internal/c/parts/core/glues/src/glues_registry.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - * - * OpenGL ES CM 1.0 port of part of GLU by Mike Gorchak - */ - -#ifndef __GLUES_REGISTRY_H__ -#define __GLUES_REGISTRY_H__ - -#if defined(__USE_SDL_GLES__) - #include - #ifndef GLAPI - #define GLAPI GL_API - #endif -#elif defined (__QNXNTO__) - #include -#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) - /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ - #include - #undef APIENTRY - #define APIENTRY - #if defined(GLUES_EXPORTS) - #define GLAPI __declspec(dllexport) - #else - #define GLAPI __declspec(dllimport) - #endif -#elif defined (ANDROID) - #include - #include - #define APIENTRY - #define GLAPI -#else - #error "Platform is unsupported" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -/* Version */ -#define GLU_VERSION_1_1 0x00000001 -#define GLU_VERSION_1_2 0x00000001 -#define GLU_VERSION_1_3 0x00000001 - -/* StringName */ -#define GLU_VERSION 100800 -#define GLU_EXTENSIONS 100801 - -GLAPI const GLubyte* APIENTRY gluGetString(GLenum name); -GLAPI GLboolean APIENTRY gluCheckExtension(const GLubyte* extName, const GLubyte* extString); - -#ifdef __cplusplus -} -#endif - -#endif /* __GLUES_REGISTRY_H__ */ diff --git a/internal/c/parts/core/glues/src/libtess/README b/internal/c/parts/core/glues/src/libtess/README deleted file mode 100644 index 60e1cb32d..000000000 --- a/internal/c/parts/core/glues/src/libtess/README +++ /dev/null @@ -1,446 +0,0 @@ -/* -*/ - -General Polygon Tesselation ---------------------------- - - This note describes a tesselator for polygons consisting of one or - more closed contours. It is backward-compatible with the current - OpenGL Utilities tesselator, and is intended to replace it. Here is - a summary of the major differences: - - - input contours can be intersecting, self-intersecting, or degenerate. - - - supports a choice of several winding rules for determining which parts - of the polygon are on the "interior". This makes it possible to do - CSG operations on polygons. - - - boundary extraction: instead of tesselating the polygon, returns a - set of closed contours which separate the interior from the exterior. - - - returns the output as a small number of triangle fans and strips, - rather than a list of independent triangles (when possible). - - - output is available as an explicit mesh (a quad-edge structure), - in addition to the normal callback interface. - - - the algorithm used is extremely robust. - - -The interface -------------- - - The tesselator state is maintained in a "tesselator object". - These are allocated and destroyed using - - GLUtesselator *gluNewTess( void ); - void gluDeleteTess( GLUtesselator *tess ); - - Several tesselator objects may be used simultaneously. - - Inputs - ------ - - The input contours are specified with the following routines: - - void gluTessBeginPolygon( GLUtesselator *tess ); - void gluTessBeginContour( GLUtesselator *tess ); - void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data ); - void gluTessEndContour( GLUtesselator *tess ); - void gluTessEndPolygon( GLUtesselator *tess ); - - Within each BeginPolygon/EndPolygon pair, there can be zero or more - calls to BeginContour/EndContour. Within each contour, there are zero - or more calls to gluTessVertex(). The vertices specify a closed - contour (the last vertex of each contour is automatically linked to - the first). - - "coords" give the coordinates of the vertex in 3-space. For useful - results, all vertices should lie in some plane, since the vertices - are projected onto a plane before tesselation. "data" is a pointer - to a user-defined vertex structure, which typically contains other - information such as color, texture coordinates, normal, etc. It is - used to refer to the vertex during rendering. - - The library can be compiled in single- or double-precision; the type - GLUcoord represents either "float" or "double" accordingly. The GLU - version will be available in double-precision only. Compile with - GLU_TESS_API_FLOAT defined to get the single-precision version. - - When EndPolygon is called, the tesselation algorithm determines - which regions are interior to the given contours, according to one - of several "winding rules" described below. The interior regions - are then tesselated, and the output is provided as callbacks. - - - Rendering Callbacks - ------------------- - - Callbacks are specified by the client using - - void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)()); - - If "fn" is NULL, any previously defined callback is discarded. - - The callbacks used to provide output are: /* which == */ - - void begin( GLenum type ); /* GLU_TESS_BEGIN */ - void edgeFlag( GLboolean flag ); /* GLU_TESS_EDGE_FLAG */ - void vertex( void *data ); /* GLU_TESS_VERTEX */ - void end( void ); /* GLU_TESS_END */ - - Any of the callbacks may be left undefined; if so, the corresponding - information will not be supplied during rendering. - - The "begin" callback indicates the start of a primitive; type is one - of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the - notes on "boundary extraction" below). - - It is followed by any number of "vertex" callbacks, which supply the - vertices in the same order as expected by the corresponding glBegin() - call. After the last vertex of a given primitive, there is a callback - to "end". - - If the "edgeFlag" callback is provided, no triangle fans or strips - will be used. When edgeFlag is called, if "flag" is GL_TRUE then each - vertex which follows begins an edge which lies on the polygon boundary - (ie. an edge which separates an interior region from an exterior one). - If "flag" is GL_FALSE, each vertex which follows begins an edge which lies - in the polygon interior. "edgeFlag" will be called before the first - call to "vertex". - - Other Callbacks - --------------- - - void mesh( GLUmesh *mesh ); /* GLU_TESS_MESH */ - - - Returns an explicit mesh, represented using the quad-edge structure - (Guibas/Stolfi '85). Other implementations of this interface might - use a different mesh structure, so this is available only only as an - SGI extension. When the mesh is no longer needed, it should be freed - using - - void gluDeleteMesh( GLUmesh *mesh ); - - There is a brief description of this data structure in the include - file "mesh.h". For the full details, see L. Guibas and J. Stolfi, - Primitives for the manipulation of general subdivisions and the - computation of Voronoi diagrams, ACM Transactions on Graphics, - 4(2):74-123, April 1985. For an introduction, see the course notes - for CS348a, "Mathematical Foundations of Computer Graphics", - available at the Stanford bookstore (and taught during the fall - quarter). - - void error( GLenum errno ); /* GLU_TESS_ERROR */ - - - errno is one of GLU_TESS_MISSING_BEGIN_POLYGON, - GLU_TESS_MISSING_END_POLYGON, - GLU_TESS_MISSING_BEGIN_CONTOUR, - GLU_TESS_MISSING_END_CONTOUR, - GLU_TESS_COORD_TOO_LARGE, - GLU_TESS_NEED_COMBINE_CALLBACK - - The first four are obvious. The interface recovers from these - errors by inserting the missing call(s). - - GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded - the predefined constant GLU_TESS_MAX_COORD in absolute value, and - that the value has been clamped. (Coordinate values must be small - enough so that two can be multiplied together without overflow.) - - GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an - intersection between two edges in the input data, and the "combine" - callback (below) was not provided. No output will be generated. - - - void combine( GLUcoord coords[3], void *data[4], /* GLU_TESS_COMBINE */ - GLUcoord weight[4], void **outData ); - - - When the algorithm detects an intersection, or wishes to merge - features, it needs to create a new vertex. The vertex is defined - as a linear combination of up to 4 existing vertices, referenced - by data[0..3]. The coefficients of the linear combination are - given by weight[0..3]; these weights always sum to 1.0. All vertex - pointers are valid even when some of the weights are zero. - "coords" gives the location of the new vertex. - - The user must allocate another vertex, interpolate parameters - using "data" and "weights", and return the new vertex pointer in - "outData". This handle is supplied during rendering callbacks. - For example, if the polygon lies in an arbitrary plane in 3-space, - and we associate a color with each vertex, the combine callback might - look like this: - - void myCombine( GLUcoord coords[3], VERTEX *d[4], - GLUcoord w[4], VERTEX **dataOut ) - { - VERTEX *new = new_vertex(); - - new->x = coords[0]; - new->y = coords[1]; - new->z = coords[2]; - new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r; - new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g; - new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b; - new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a; - *dataOut = new; - } - - If the algorithm detects an intersection, then the "combine" callback - must be defined, and must write a non-NULL pointer into "dataOut". - Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no - output is generated. This is the only error that can occur during - tesselation and rendering. - - - Control over Tesselation - ------------------------ - - void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value ); - - Properties defined: - - - GLU_TESS_WINDING_RULE. Possible values: - - GLU_TESS_WINDING_ODD - GLU_TESS_WINDING_NONZERO - GLU_TESS_WINDING_POSITIVE - GLU_TESS_WINDING_NEGATIVE - GLU_TESS_WINDING_ABS_GEQ_TWO - - The input contours parition the plane into regions. A winding - rule determines which of these regions are inside the polygon. - - For a single contour C, the winding number of a point x is simply - the signed number of revolutions we make around x as we travel - once around C (where CCW is positive). When there are several - contours, the individual winding numbers are summed. This - procedure associates a signed integer value with each point x in - the plane. Note that the winding number is the same for all - points in a single region. - - The winding rule classifies a region as "inside" if its winding - number belongs to the chosen category (odd, nonzero, positive, - negative, or absolute value of at least two). The current GLU - tesselator implements the "odd" rule. The "nonzero" rule is another - common way to define the interior. The other three rules are - useful for polygon CSG operations (see below). - - - GLU_TESS_BOUNDARY_ONLY. Values: TRUE (non-zero) or FALSE (zero). - - If TRUE, returns a set of closed contours which separate the - polygon interior and exterior (rather than a tesselation). - Exterior contours are oriented CCW with respect to the normal, - interior contours are oriented CW. The GLU_TESS_BEGIN callback - uses the type GL_LINE_LOOP for each contour. - - - GLU_TESS_TOLERANCE. Value: a real number between 0.0 and 1.0. - - This specifies a tolerance for merging features to reduce the size - of the output. For example, two vertices which are very close to - each other might be replaced by a single vertex. The tolerance - is multiplied by the largest coordinate magnitude of any input vertex; - this specifies the maximum distance that any feature can move as the - result of a single merge operation. If a single feature takes part - in several merge operations, the total distance moved could be larger. - - Feature merging is completely optional; the tolerance is only a hint. - The implementation is free to merge in some cases and not in others, - or to never merge features at all. The default tolerance is zero. - - The current implementation merges vertices only if they are exactly - coincident, regardless of the current tolerance. A vertex is - spliced into an edge only if the implementation is unable to - distinguish which side of the edge the vertex lies on. - Two edges are merged only when both endpoints are identical. - - - void gluTessNormal( GLUtesselator *tess, - GLUcoord x, GLUcoord y, GLUcoord z ) - - - Lets the user supply the polygon normal, if known. All input data - is projected into a plane perpendicular to the normal before - tesselation. All output triangles are oriented CCW with - respect to the normal (CW orientation can be obtained by - reversing the sign of the supplied normal). For example, if - you know that all polygons lie in the x-y plane, call - "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons. - - - If the supplied normal is (0,0,0) (the default value), the - normal is determined as follows. The direction of the normal, - up to its sign, is found by fitting a plane to the vertices, - without regard to how the vertices are connected. It is - expected that the input data lies approximately in plane; - otherwise projection perpendicular to the computed normal may - substantially change the geometry. The sign of the normal is - chosen so that the sum of the signed areas of all input contours - is non-negative (where a CCW contour has positive area). - - - The supplied normal persists until it is changed by another - call to gluTessNormal. - - - Backward compatibility with the GLU tesselator - ---------------------------------------------- - - The preferred interface is the one described above. The following - routines are obsolete, and are provided only for backward compatibility: - - typedef GLUtesselator GLUtriangulatorObj; /* obsolete name */ - - void gluBeginPolygon( GLUtesselator *tess ); - void gluNextContour( GLUtesselator *tess, GLenum type ); - void gluEndPolygon( GLUtesselator *tess ); - - "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or - GLU_UNKNOWN. It is ignored by the current GLU tesselator. - - GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined - as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END, - GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG. - - -Polygon CSG operations ----------------------- - - The features of the tesselator make it easy to find the union, difference, - or intersection of several polygons. - - First, assume that each polygon is defined so that the winding number - is 0 for each exterior region, and 1 for each interior region. Under - this model, CCW contours define the outer boundary of the polygon, and - CW contours define holes. Contours may be nested, but a nested - contour must be oriented oppositely from the contour that contains it. - - If the original polygons do not satisfy this description, they can be - converted to this form by first running the tesselator with the - GLU_TESS_BOUNDARY_ONLY property turned on. This returns a list of - contours satisfying the restriction above. By allocating two - tesselator objects, the callbacks from one tesselator can be fed - directly to the input of another. - - Given two or more polygons of the form above, CSG operations can be - implemented as follows: - - Union - Draw all the input contours as a single polygon. The winding number - of each resulting region is the number of original polygons - which cover it. The union can be extracted using the - GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules. - Note that with the nonzero rule, we would get the same result if - all contour orientations were reversed. - - Intersection (two polygons at a time only) - Draw a single polygon using the contours from both input polygons. - Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO. (Since this - winding rule looks at the absolute value, reversing all contour - orientations does not change the result.) - - Difference - - Suppose we want to compute A \ (B union C union D). Draw a single - polygon consisting of the unmodified contours from A, followed by - the contours of B,C,D with the vertex order reversed (this changes - the winding number of the interior regions to -1). To extract the - result, use the GLU_TESS_WINDING_POSITIVE rule. - - If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an - alternative to reversing the vertex order is to reverse the sign of - the supplied normal. For example in the x-y plane, call - gluTessNormal( tess, 0.0, 0.0, -1.0 ). - - -Performance ------------ - - The tesselator is not intended for immediate-mode rendering; when - possible the output should be cached in a user structure or display - list. General polygon tesselation is an inherently difficult problem, - especially given the goal of extreme robustness. - - The implementation makes an effort to output a small number of fans - and strips; this should improve the rendering performance when the - output is used in a display list. - - Single-contour input polygons are first tested to see whether they can - be rendered as a triangle fan with respect to the first vertex (to - avoid running the full decomposition algorithm on convex polygons). - Non-convex polygons may be rendered by this "fast path" as well, if - the algorithm gets lucky in its choice of a starting vertex. - - For best performance follow these guidelines: - - - supply the polygon normal, if available, using gluTessNormal(). - This represents about 10% of the computation time. For example, - if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1). - - - render many polygons using the same tesselator object, rather than - allocating a new tesselator for each one. (In a multi-threaded, - multi-processor environment you may get better performance using - several tesselators.) - - -Comparison with the GLU tesselator ----------------------------------- - - On polygons which make it through the "fast path", the tesselator is - 3 to 5 times faster than the GLU tesselator. - - On polygons which don't make it through the fast path (but which don't - have self-intersections or degeneracies), it is about 2 times slower. - - On polygons with self-intersections or degeneraces, there is nothing - to compare against. - - The new tesselator generates many more fans and strips, reducing the - number of vertices that need to be sent to the hardware. - - Key to the statistics: - - vert number of input vertices on all contours - cntr number of input contours - tri number of triangles in all output primitives - strip number of triangle strips - fan number of triangle fans - ind number of independent triangles - ms number of milliseconds for tesselation - (on a 150MHz R4400 Indy) - - Convex polygon examples: - -New: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.0459 ms -Old: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.149 ms -New: 4 vert, 1 cntr, 2 tri, 0 strip, 1 fan, 0 ind, 0.0459 ms -Old: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.161 ms -New: 36 vert, 1 cntr, 34 tri, 0 strip, 1 fan, 0 ind, 0.153 ms -Old: 36 vert, 1 cntr, 34 tri, 0 strip, 0 fan, 34 ind, 0.621 ms - - Concave single-contour polygons: - -New: 5 vert, 1 cntr, 3 tri, 0 strip, 1 fan, 0 ind, 0.052 ms -Old: 5 vert, 1 cntr, 3 tri, 0 strip, 0 fan, 3 ind, 0.252 ms -New: 19 vert, 1 cntr, 17 tri, 2 strip, 2 fan, 1 ind, 0.911 ms -Old: 19 vert, 1 cntr, 17 tri, 0 strip, 0 fan, 17 ind, 0.529 ms -New: 151 vert, 1 cntr, 149 tri, 13 strip, 18 fan, 3 ind, 6.82 ms -Old: 151 vert, 1 cntr, 149 tri, 0 strip, 3 fan, 143 ind, 2.7 ms -New: 574 vert, 1 cntr, 572 tri, 59 strip, 54 fan, 11 ind, 26.6 ms -Old: 574 vert, 1 cntr, 572 tri, 0 strip, 31 fan, 499 ind, 12.4 ms - - Multiple contours, but no intersections: - -New: 7 vert, 2 cntr, 7 tri, 1 strip, 0 fan, 0 ind, 0.527 ms -Old: 7 vert, 2 cntr, 7 tri, 0 strip, 0 fan, 7 ind, 0.274 ms -New: 81 vert, 6 cntr, 89 tri, 9 strip, 7 fan, 6 ind, 3.88 ms -Old: 81 vert, 6 cntr, 89 tri, 0 strip, 13 fan, 61 ind, 2.2 ms -New: 391 vert, 19 cntr, 413 tri, 37 strip, 32 fan, 26 ind, 20.2 ms -Old: 391 vert, 19 cntr, 413 tri, 0 strip, 25 fan, 363 ind, 8.68 ms - - Self-intersecting and degenerate examples: - -Bowtie: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.483 ms -Star: 5 vert, 1 cntr, 5 tri, 0 strip, 0 fan, 5 ind, 0.91 ms -Random: 24 vert, 7 cntr, 46 tri, 2 strip, 12 fan, 7 ind, 5.32 ms -Font: 333 vert, 2 cntr, 331 tri, 32 strip, 16 fan, 3 ind, 14.1 ms -: 167 vert, 35 cntr, 254 tri, 8 strip, 56 fan, 52 ind, 46.3 ms -: 78 vert, 1 cntr, 2675 tri, 148 strip, 207 fan, 180 ind, 243 ms -: 12480 vert, 2 cntr, 12478 tri, 736 strip,1275 fan, 5 ind, 1010 ms diff --git a/internal/c/parts/core/glues/src/libtess/alg-outline b/internal/c/parts/core/glues/src/libtess/alg-outline deleted file mode 100644 index e714a6c75..000000000 --- a/internal/c/parts/core/glues/src/libtess/alg-outline +++ /dev/null @@ -1,228 +0,0 @@ -/* -*/ - -This is only a very brief overview. There is quite a bit of -additional documentation in the source code itself. - - -Goals of robust tesselation ---------------------------- - -The tesselation algorithm is fundamentally a 2D algorithm. We -initially project all data into a plane; our goal is to robustly -tesselate the projected data. The same topological tesselation is -then applied to the input data. - -Topologically, the output should always be a tesselation. If the -input is even slightly non-planar, then some triangles will -necessarily be back-facing when viewed from some angles, but the goal -is to minimize this effect. - -The algorithm needs some capability of cleaning up the input data as -well as the numerical errors in its own calculations. One way to do -this is to specify a tolerance as defined above, and clean up the -input and output during the line sweep process. At the very least, -the algorithm must handle coincident vertices, vertices incident to an -edge, and coincident edges. - - -Phases of the algorithm ------------------------ - -1. Find the polygon normal N. -2. Project the vertex data onto a plane. It does not need to be - perpendicular to the normal, eg. we can project onto the plane - perpendicular to the coordinate axis whose dot product with N - is largest. -3. Using a line-sweep algorithm, partition the plane into x-monotone - regions. Any vertical line intersects an x-monotone region in - at most one interval. -4. Triangulate the x-monotone regions. -5. Group the triangles into strips and fans. - - -Finding the normal vector -------------------------- - -A common way to find a polygon normal is to compute the signed area -when the polygon is projected along the three coordinate axes. We -can't do this, since contours can have zero area without being -degenerate (eg. a bowtie). - -We fit a plane to the vertex data, ignoring how they are connected -into contours. Ideally this would be a least-squares fit; however for -our purpose the accuracy of the normal is not important. Instead we -find three vertices which are widely separated, and compute the normal -to the triangle they form. The vertices are chosen so that the -triangle has an area at least 1/sqrt(3) times the largest area of any -triangle formed using the input vertices. - -The contours do affect the orientation of the normal; after computing -the normal, we check that the sum of the signed contour areas is -non-negative, and reverse the normal if necessary. - - -Projecting the vertices ------------------------ - -We project the vertices onto a plane perpendicular to one of the three -coordinate axes. This helps numerical accuracy by removing a -transformation step between the original input data and the data -processed by the algorithm. The projection also compresses the input -data; the 2D distance between vertices after projection may be smaller -than the original 2D distance. However by choosing the coordinate -axis whose dot product with the normal is greatest, the compression -factor is at most 1/sqrt(3). - -Even though the *accuracy* of the normal is not that important (since -we are projecting perpendicular to a coordinate axis anyway), the -*robustness* of the computation is important. For example, if there -are many vertices which lie almost along a line, and one vertex V -which is well-separated from the line, then our normal computation -should involve V otherwise the results will be garbage. - -The advantage of projecting perpendicular to the polygon normal is -that computed intersection points will be as close as possible to -their ideal locations. To get this behavior, define TRUE_PROJECT. - - -The Line Sweep --------------- - -There are three data structures: the mesh, the event queue, and the -edge dictionary. - -The mesh is a "quad-edge" data structure which records the topology of -the current decomposition; for details see the include file "mesh.h". - -The event queue simply holds all vertices (both original and computed -ones), organized so that we can quickly extract the vertex with the -minimum x-coord (and among those, the one with the minimum y-coord). - -The edge dictionary describes the current intersection of the sweep -line with the regions of the polygon. This is just an ordering of the -edges which intersect the sweep line, sorted by their current order of -intersection. For each pair of edges, we store some information about -the monotone region between them -- these are call "active regions" -(since they are crossed by the current sweep line). - -The basic algorithm is to sweep from left to right, processing each -vertex. The processed portion of the mesh (left of the sweep line) is -a planar decomposition. As we cross each vertex, we update the mesh -and the edge dictionary, then we check any newly adjacent pairs of -edges to see if they intersect. - -A vertex can have any number of edges. Vertices with many edges can -be created as vertices are merged and intersection points are -computed. For unprocessed vertices (right of the sweep line), these -edges are in no particular order around the vertex; for processed -vertices, the topological ordering should match the geometric ordering. - -The vertex processing happens in two phases: first we process are the -left-going edges (all these edges are currently in the edge -dictionary). This involves: - - - deleting the left-going edges from the dictionary; - - relinking the mesh if necessary, so that the order of these edges around - the event vertex matches the order in the dictionary; - - marking any terminated regions (regions which lie between two left-going - edges) as either "inside" or "outside" according to their winding number. - -When there are no left-going edges, and the event vertex is in an -"interior" region, we need to add an edge (to split the region into -monotone pieces). To do this we simply join the event vertex to the -rightmost left endpoint of the upper or lower edge of the containing -region. - -Then we process the right-going edges. This involves: - - - inserting the edges in the edge dictionary; - - computing the winding number of any newly created active regions. - We can compute this incrementally using the winding of each edge - that we cross as we walk through the dictionary. - - relinking the mesh if necessary, so that the order of these edges around - the event vertex matches the order in the dictionary; - - checking any newly adjacent edges for intersection and/or merging. - -If there are no right-going edges, again we need to add one to split -the containing region into monotone pieces. In our case it is most -convenient to add an edge to the leftmost right endpoint of either -containing edge; however we may need to change this later (see the -code for details). - - -Invariants ----------- - -These are the most important invariants maintained during the sweep. -We define a function VertLeq(v1,v2) which defines the order in which -vertices cross the sweep line, and a function EdgeLeq(e1,e2; loc) -which says whether e1 is below e2 at the sweep event location "loc". -This function is defined only at sweep event locations which lie -between the rightmost left endpoint of {e1,e2}, and the leftmost right -endpoint of {e1,e2}. - -Invariants for the Edge Dictionary. - - - Each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2) - at any valid location of the sweep event. - - If EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2 - share a common endpoint. - - For each e in the dictionary, e->Dst has been processed but not e->Org. - - Each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org) - where "event" is the current sweep line event. - - No edge e has zero length. - - No two edges have identical left and right endpoints. - -Invariants for the Mesh (the processed portion). - - - The portion of the mesh left of the sweep line is a planar graph, - ie. there is *some* way to embed it in the plane. - - No processed edge has zero length. - - No two processed vertices have identical coordinates. - - Each "inside" region is monotone, ie. can be broken into two chains - of monotonically increasing vertices according to VertLeq(v1,v2) - - a non-invariant: these chains may intersect (slightly) due to - numerical errors, but this does not affect the algorithm's operation. - -Invariants for the Sweep. - - - If a vertex has any left-going edges, then these must be in the edge - dictionary at the time the vertex is processed. - - If an edge is marked "fixUpperEdge" (it is a temporary edge introduced - by ConnectRightVertex), then it is the only right-going edge from - its associated vertex. (This says that these edges exist only - when it is necessary.) - - -Robustness ----------- - -The key to the robustness of the algorithm is maintaining the -invariants above, especially the correct ordering of the edge -dictionary. We achieve this by: - - 1. Writing the numerical computations for maximum precision rather - than maximum speed. - - 2. Making no assumptions at all about the results of the edge - intersection calculations -- for sufficiently degenerate inputs, - the computed location is not much better than a random number. - - 3. When numerical errors violate the invariants, restore them - by making *topological* changes when necessary (ie. relinking - the mesh structure). - - -Triangulation and Grouping --------------------------- - -We finish the line sweep before doing any triangulation. This is -because even after a monotone region is complete, there can be further -changes to its vertex data because of further vertex merging. - -After triangulating all monotone regions, we want to group the -triangles into fans and strips. We do this using a greedy approach. -The triangulation itself is not optimized to reduce the number of -primitives; we just try to get a reasonable decomposition of the -computed triangulation. diff --git a/internal/c/parts/core/glues/src/libtess/dict-list.h b/internal/c/parts/core/glues/src/libtess/dict-list.h deleted file mode 100644 index 2977b2126..000000000 --- a/internal/c/parts/core/glues/src/libtess/dict-list.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __dict_list_h_ -#define __dict_list_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define DictKey DictListKey -#define Dict DictList -#define DictNode DictListNode - -#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq) -#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict) - -#define dictSearch(dict,key) __gl_dictListSearch(dict,key) -#define dictInsert(dict,key) __gl_dictListInsert(dict,key) -#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key) -#define dictDelete(dict,node) __gl_dictListDelete(dict,node) - -#define dictKey(n) __gl_dictListKey(n) -#define dictSucc(n) __gl_dictListSucc(n) -#define dictPred(n) __gl_dictListPred(n) -#define dictMin(d) __gl_dictListMin(d) -#define dictMax(d) __gl_dictListMax(d) - -typedef void *DictKey; -typedef struct Dict Dict; -typedef struct DictNode DictNode; - -Dict* dictNewDict(void *frame, - int (*leq)(void *frame, DictKey key1, DictKey key2)); -void dictDeleteDict(Dict *dict); - -/* Search returns the node with the smallest key greater than or equal - * to the given key. If there is no such key, returns a node whose - * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc. - */ -DictNode* dictSearch(Dict* dict, DictKey key); -DictNode* dictInsertBefore(Dict* dict, DictNode* node, DictKey key); -void dictDelete(Dict* dict, DictNode* node); - -#define __gl_dictListKey(n) ((n)->key) -#define __gl_dictListSucc(n) ((n)->next) -#define __gl_dictListPred(n) ((n)->prev) -#define __gl_dictListMin(d) ((d)->head.next) -#define __gl_dictListMax(d) ((d)->head.prev) -#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k))) - -/*** Private data structures ***/ - -struct DictNode -{ - DictKey key; - DictNode* next; - DictNode* prev; -}; - -struct Dict -{ - DictNode head; - void* frame; - int (*leq)(void *frame, DictKey key1, DictKey key2); -}; - -#endif /* __dict_list_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/dict.c b/internal/c/parts/core/glues/src/libtess/dict.c deleted file mode 100644 index 2605d8206..000000000 --- a/internal/c/parts/core/glues/src/libtess/dict.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include "dict-list.h" -#include "memalloc.h" - -/* really __gl_dictListNewDict */ -Dict* dictNewDict(void* frame, int (*leq)(void *frame, DictKey key1, DictKey key2)) -{ - Dict* dict=(Dict*)memAlloc(sizeof(Dict)); - DictNode* head; - - if (dict==NULL) - { - return NULL; - } - - head=&dict->head; - - head->key=NULL; - head->next=head; - head->prev=head; - - dict->frame=frame; - dict->leq=leq; - - return dict; -} - -/* really __gl_dictListDeleteDict */ -void dictDeleteDict(Dict* dict) -{ - DictNode* node; - DictNode* next; - - for (node=dict->head.next; node!=&dict->head; node=next) - { - next=node->next; - memFree(node); - } - - memFree(dict); -} - -/* really __gl_dictListInsertBefore */ -DictNode* dictInsertBefore(Dict* dict, DictNode* node, DictKey key) -{ - DictNode* newNode; - - do { - node=node->prev; - } while(node->key!=NULL && !(*dict->leq)(dict->frame, node->key, key)); - - newNode=(DictNode*)memAlloc(sizeof(DictNode)); - if (newNode==NULL) - { - return NULL; - } - - newNode->key=key; - newNode->next=node->next; - node->next->prev=newNode; - newNode->prev=node; - node->next=newNode; - - return newNode; -} - -/* really __gl_dictListDelete */ -void dictDelete(Dict* dict, DictNode* node) /*ARGSUSED*/ -{ - node->next->prev=node->prev; - node->prev->next=node->next; - memFree(node); -} - -/* really __gl_dictListSearch */ -DictNode* dictSearch(Dict* dict, DictKey key) -{ - DictNode* node=&dict->head; - - do { - node=node->next; - } while(node->key!=NULL && !(*dict->leq)(dict->frame, key, node->key)); - - return node; -} diff --git a/internal/c/parts/core/glues/src/libtess/dict.h b/internal/c/parts/core/glues/src/libtess/dict.h deleted file mode 100644 index a4ddf2d82..000000000 --- a/internal/c/parts/core/glues/src/libtess/dict.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __dict_list_h_ -#define __dict_list_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define DictKey DictListKey -#define Dict DictList -#define DictNode DictListNode - -#define dictNewDict(frame, leq) __gl_dictListNewDict(frame, leq) -#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict) - -#define dictSearch(dict, key) __gl_dictListSearch(dict, key) -#define dictInsert(dict, key) __gl_dictListInsert(dict, key) -#define dictInsertBefore(dict, node, key) __gl_dictListInsertBefore(dict, node, key) -#define dictDelete(dict, node) __gl_dictListDelete(dict, node) - -#define dictKey(n) __gl_dictListKey(n) -#define dictSucc(n) __gl_dictListSucc(n) -#define dictPred(n) __gl_dictListPred(n) -#define dictMin(d) __gl_dictListMin(d) -#define dictMax(d) __gl_dictListMax(d) - -typedef void* DictKey; -typedef struct Dict Dict; -typedef struct DictNode DictNode; - -Dict* dictNewDict(void* frame, int (*leq)(void* frame, DictKey key1, DictKey key2)); -void dictDeleteDict(Dict* dict); - -/* Search returns the node with the smallest key greater than or equal - * to the given key. If there is no such key, returns a node whose - * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc. - */ -DictNode* dictSearch(Dict* dict, DictKey key); -DictNode* dictInsertBefore(Dict* dict, DictNode* node, DictKey key); -void dictDelete(Dict* dict, DictNode* node); - -#define __gl_dictListKey(n) ((n)->key) -#define __gl_dictListSucc(n) ((n)->next) -#define __gl_dictListPred(n) ((n)->prev) -#define __gl_dictListMin(d) ((d)->head.next) -#define __gl_dictListMax(d) ((d)->head.prev) -#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k))) - -/*** Private data structures ***/ - -struct DictNode -{ - DictKey key; - DictNode* next; - DictNode* prev; -}; - -struct Dict -{ - DictNode head; - void* frame; - int (*leq)(void* frame, DictKey key1, DictKey key2); -}; - -#endif /* __dict_list_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/geom.c b/internal/c/parts/core/glues/src/libtess/geom.c deleted file mode 100644 index 30bc71304..000000000 --- a/internal/c/parts/core/glues/src/libtess/geom.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include "mesh.h" -#include "geom.h" - -int __gl_vertLeq(GLUvertex* u, GLUvertex* v) -{ - /* Returns TRUE if u is lexicographically <= v. */ - - return VertLeq(u, v); -} - -GLfloat __gl_edgeEval(GLUvertex* u, GLUvertex* v, GLUvertex* w) -{ - /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w), - * evaluates the t-coord of the edge uw at the s-coord of the vertex v. - * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v. - * If uw is vertical (and thus passes thru v), the result is zero. - * - * The calculation is extremely accurate and stable, even when v - * is very close to u or w. In particular if we set v->t = 0 and - * let r be the negated result (this evaluates (uw)(v->s)), then - * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t). - */ - GLfloat gapL, gapR; - - assert(VertLeq(u, v) && VertLeq(v, w)); - - gapL=v->s-u->s; - gapR=w->s-v->s; - - if (gapL+gapR>0) - { - if (gapLt-u->t)+(u->t-w->t)*(gapL/(gapL+gapR)); - } - else - { - return (v->t-w->t)+(w->t-u->t)*(gapR/(gapL+gapR)); - } - } - - /* vertical line */ - return 0; -} - -GLfloat __gl_edgeSign(GLUvertex* u, GLUvertex* v, GLUvertex* w) -{ - /* Returns a number whose sign matches EdgeEval(u,v,w) but which - * is cheaper to evaluate. Returns > 0, == 0 , or < 0 - * as v is above, on, or below the edge uw. - */ - GLfloat gapL, gapR; - - assert(VertLeq(u, v) && VertLeq(v, w)); - - gapL=v->s-u->s; - gapR=w->s-v->s; - - if (gapL+gapR>0) - { - return (v->t - w->t) * gapL + (v->t - u->t) * gapR; - } - - /* vertical line */ - return 0; -} - -/*********************************************************************** - * Define versions of EdgeSign, EdgeEval with s and t transposed. - */ - -GLfloat __gl_transEval(GLUvertex* u, GLUvertex* v, GLUvertex* w) -{ - /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w), - * evaluates the t-coord of the edge uw at the s-coord of the vertex v. - * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v. - * If uw is vertical (and thus passes thru v), the result is zero. - * - * The calculation is extremely accurate and stable, even when v - * is very close to u or w. In particular if we set v->s = 0 and - * let r be the negated result (this evaluates (uw)(v->t)), then - * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s). - */ - GLfloat gapL, gapR; - - assert(TransLeq(u, v) && TransLeq(v, w)); - - gapL=v->t-u->t; - gapR=w->t-v->t; - - if (gapL+gapR>0) - { - if (gapLs-u->s)+(u->s-w->s)*(gapL/(gapL+gapR)); - } - else - { - return (v->s-w->s)+(w->s-u->s)*(gapR/(gapL+gapR)); - } - } - - /* vertical line */ - return 0; -} - -GLfloat __gl_transSign(GLUvertex* u, GLUvertex* v, GLUvertex* w) -{ - /* Returns a number whose sign matches TransEval(u,v,w) but which - * is cheaper to evaluate. Returns > 0, == 0 , or < 0 - * as v is above, on, or below the edge uw. - */ - GLfloat gapL, gapR; - - assert(TransLeq(u, v) && TransLeq(v, w)); - - gapL=v->t-u->t; - gapR=w->t-v->t; - - if (gapL+gapR>0) - { - return (v->s-w->s)*gapL+(v->s-u->s)*gapR; - } - - /* vertical line */ - return 0; -} - - -int __gl_vertCCW(GLUvertex* u, GLUvertex* v, GLUvertex* w) -{ - /* For almost-degenerate situations, the results are not reliable. - * Unless the floating-point arithmetic can be performed without - * rounding errors, *any* implementation will give incorrect results - * on some degenerate inputs, so the client must have some way to - * handle this situation. - */ - return (u->s*(v->t-w->t)+v->s*(w->t-u->t)+w->s*(u->t-v->t))>=0; -} - -/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b), - * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces - * this in the rare case that one argument is slightly negative. - * The implementation is extremely stable numerically. - * In particular it guarantees that the result r satisfies - * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate - * even when a and b differ greatly in magnitude. - */ -#define RealInterpolate(a,x,b,y) \ - (a=(a<0) ? 0 : a,b=(b<0) ? 0 : b, \ - ((a<=b) ? ((b==0) ? ((x+y)/2) \ - : (x+(y-x)*(a/(a+b)))) \ - : (y+(x-y)*(b/(a+b))))) - -#ifndef FOR_TRITE_TEST_PROGRAM - #define Interpolate(a, x, b, y) RealInterpolate(a, x, b, y) -#else - -/* Claim: the ONLY property the sweep algorithm relies on is that - * MIN(x,y) <= r <= MAX(x,y). This is a nasty way to test that. - */ -#include -extern int RandomInterpolate; - -GLfloat Interpolate(GLfloat a, GLfloat x, GLfloat b, GLfloat y) -{ - printf("*********************%d\n",RandomInterpolate); - if (RandomInterpolate) - { - a=1.2*drand48()-0.1f; - a=(a<0) ? 0 : ((a>1) ? 1 : a); - b=1.0f-a; - } - - return RealInterpolate(a, x, b, y); -} - -#endif /* FOR_TRITE_TEST_PROGRAM */ - -#define Swap(a, b) if (1) { GLUvertex* t=a; a=b; b=t; } else - -void __gl_edgeIntersect(GLUvertex* o1, GLUvertex* d1, - GLUvertex* o2, GLUvertex* d2, - GLUvertex* v) -/* Given edges (o1,d1) and (o2,d2), compute their point of intersection. - * The computed point is guaranteed to lie in the intersection of the - * bounding rectangles defined by each edge. - */ -{ - GLfloat z1, z2; - - /* This is certainly not the most efficient way to find the intersection - * of two line segments, but it is very numerically stable. - * - * Strategy: find the two middle vertices in the VertLeq ordering, - * and interpolate the intersection s-value from these. Then repeat - * using the TransLeq ordering to find the intersection t-value. - */ - - if (!VertLeq(o1, d1)) - { - Swap(o1, d1 ); - } - if (!VertLeq(o2, d2)) - { - Swap(o2, d2); - } - if (!VertLeq(o1, o2)) - { - Swap(o1, o2); - Swap(d1, d2); - } - - if (!VertLeq(o2, d1)) - { - /* Technically, no intersection -- do our best */ - v->s=(o2->s+d1->s)/2; - } - else - { - if (VertLeq(d1, d2)) - { - /* Interpolate between o2 and d1 */ - z1=EdgeEval(o1, o2, d1); - z2=EdgeEval(o2, d1, d2); - if (z1+z2<0) - { - z1=-z1; z2=-z2; - } - v->s=Interpolate(z1, o2->s, z2, d1->s); - } - else - { - /* Interpolate between o2 and d2 */ - z1=EdgeSign(o1, o2, d1); - z2=-EdgeSign(o1, d2, d1); - if (z1+z2<0) - { - z1=-z1; z2=-z2; - } - v->s=Interpolate(z1, o2->s, z2, d2->s); - } - } - - /* Now repeat the process for t */ - if (!TransLeq(o1, d1)) - { - Swap(o1, d1); - } - if (!TransLeq(o2, d2)) - { - Swap(o2, d2); - } - if (!TransLeq(o1, o2)) - { - Swap(o1, o2); - Swap(d1, d2); - } - - if (!TransLeq(o2, d1)) - { - /* Technically, no intersection -- do our best */ - v->t=(o2->t+d1->t)/2; - } - else - { - if (TransLeq(d1, d2)) - { - /* Interpolate between o2 and d1 */ - z1=TransEval(o1, o2, d1); - z2=TransEval(o2, d1, d2); - if (z1+z2<0) - { - z1=-z1; z2=-z2; - } - v->t=Interpolate(z1, o2->t, z2, d1->t); - } - else - { - /* Interpolate between o2 and d2 */ - z1=TransSign(o1, o2, d1); - z2=-TransSign(o1, d2, d1); - if (z1+z2<0) - { - z1=-z1; z2=-z2; - } - v->t=Interpolate(z1, o2->t, z2, d2->t); - } - } -} diff --git a/internal/c/parts/core/glues/src/libtess/geom.h b/internal/c/parts/core/glues/src/libtess/geom.h deleted file mode 100644 index b596dc193..000000000 --- a/internal/c/parts/core/glues/src/libtess/geom.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __geom_h_ -#define __geom_h_ - -#include "mesh.h" - -#ifdef NO_BRANCH_CONDITIONS -/* MIPS architecture has special instructions to evaluate boolean - * conditions -- more efficient than branching, IF you can get the - * compiler to generate the right instructions (SGI compiler doesn't) - */ -#define VertEq(u, v) (((u)->s == (v)->s) & ((u)->t == (v)->t)) -#define VertLeq(u, v) (((u)->s < (v)->s) | \ - ((u)->s == (v)->s & (u)->t <= (v)->t)) -#else - -#define VertEq(u, v) ((u)->s == (v)->s && (u)->t == (v)->t) -#define VertLeq(u, v) (((u)->s < (v)->s) || \ - ((u)->s == (v)->s && (u)->t <= (v)->t)) -#endif - -#define EdgeEval(u, v, w) __gl_edgeEval(u, v, w) -#define EdgeSign(u, v, w) __gl_edgeSign(u, v, w) - -/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */ - -#define TransLeq(u,v) (((u)->t < (v)->t) || \ - ((u)->t == (v)->t && (u)->s <= (v)->s)) -#define TransEval(u,v,w) __gl_transEval(u,v,w) -#define TransSign(u,v,w) __gl_transSign(u,v,w) - -#define EdgeGoesLeft(e) VertLeq((e)->Dst, (e)->Org) -#define EdgeGoesRight(e) VertLeq((e)->Org, (e)->Dst) - -#undef ABS -#define ABS(x) ((x)<0 ? -(x) : (x)) -#define VertL1dist(u, v) (ABS(u->s-v->s)+ABS(u->t-v->t)) - -#define VertCCW(u, v, w) __gl_vertCCW(u, v, w) - -int __gl_vertLeq(GLUvertex* u, GLUvertex* v); -GLfloat __gl_edgeEval(GLUvertex* u, GLUvertex* v, GLUvertex* w); -GLfloat __gl_edgeSign(GLUvertex* u, GLUvertex* v, GLUvertex* w); -GLfloat __gl_transEval(GLUvertex* u, GLUvertex* v, GLUvertex* w); -GLfloat __gl_transSign(GLUvertex* u, GLUvertex* v, GLUvertex* w); -int __gl_vertCCW(GLUvertex* u, GLUvertex* v, GLUvertex* w); -void __gl_edgeIntersect(GLUvertex* o1, GLUvertex* d1, - GLUvertex* o2, GLUvertex* d2, - GLUvertex* v); - -#endif /* __geom_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/memalloc.c b/internal/c/parts/core/glues/src/libtess/memalloc.c deleted file mode 100644 index 32d848bba..000000000 --- a/internal/c/parts/core/glues/src/libtess/memalloc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "memalloc.h" -#include "string.h" - -int __gl_memInit(size_t maxFast) -{ - #ifndef NO_MALLOPT - /* mallopt( M_MXFAST, maxFast );*/ - #ifdef MEMORY_DEBUG - mallopt(M_DEBUG, 1); - #endif - #endif - - return 1; -} - -#ifdef MEMORY_DEBUG -void* __gl_memAlloc(size_t n) -{ - return memset(malloc(n), 0xA5, n); -} -#endif /* MEMORY_DEBUG */ diff --git a/internal/c/parts/core/glues/src/libtess/memalloc.h b/internal/c/parts/core/glues/src/libtess/memalloc.h deleted file mode 100644 index d783474d9..000000000 --- a/internal/c/parts/core/glues/src/libtess/memalloc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __memalloc_simple_h_ -#define __memalloc_simple_h_ - -#include - -#define memRealloc realloc -#define memFree free - -#define memInit __gl_memInit -extern int __gl_memInit(size_t); - -#ifndef MEMORY_DEBUG - #define memAlloc malloc -#else - #define memAlloc __gl_memAlloc - extern void* __gl_memAlloc(size_t); -#endif /* MEMORY_DEBUG */ - -#endif /* __memalloc_simple_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/mesh.c b/internal/c/parts/core/glues/src/libtess/mesh.c deleted file mode 100644 index 6049e1f90..000000000 --- a/internal/c/parts/core/glues/src/libtess/mesh.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include "mesh.h" -#include "memalloc.h" - -#define TRUE 1 -#define FALSE 0 - -static GLUvertex* allocVertex() -{ - return (GLUvertex*)memAlloc(sizeof(GLUvertex)); -} - -static GLUface* allocFace() -{ - return (GLUface*)memAlloc(sizeof(GLUface)); -} - -/************************ Utility Routines ************************/ - -/* Allocate and free half-edges in pairs for efficiency. - * The *only* place that should use this fact is allocation/free. - */ -typedef struct -{ - GLUhalfEdge e; - GLUhalfEdge eSym; -} EdgePair; - -/* MakeEdge creates a new pair of half-edges which form their own loop. - * No vertex or face structures are allocated, but these must be assigned - * before the current edge operation is completed. - */ -static GLUhalfEdge* MakeEdge(GLUhalfEdge* eNext) -{ - GLUhalfEdge* e; - GLUhalfEdge* eSym; - GLUhalfEdge* ePrev; - EdgePair* pair=(EdgePair*)memAlloc(sizeof(EdgePair)); - - if (pair==NULL) - { - return NULL; - } - - e=&pair->e; - eSym=&pair->eSym; - - /* Make sure eNext points to the first edge of the edge pair */ - if (eNext->SymSym; - } - - /* Insert in circular doubly-linked list before eNext. - * Note that the prev pointer is stored in Sym->next. - */ - ePrev=eNext->Sym->next; - eSym->next=ePrev; - ePrev->Sym->next=e; - e->next=eNext; - eNext->Sym->next=eSym; - - e->Sym=eSym; - e->Onext=e; - e->Lnext=eSym; - e->Org=NULL; - e->Lface=NULL; - e->winding=0; - e->activeRegion=NULL; - - eSym->Sym=e; - eSym->Onext=eSym; - eSym->Lnext=e; - eSym->Org=NULL; - eSym->Lface=NULL; - eSym->winding=0; - eSym->activeRegion=NULL; - - return e; -} - -/* Splice(a, b) is best described by the Guibas/Stolfi paper or the - * CS348a notes (see mesh.h). Basically it modifies the mesh so that - * a->Onext and b->Onext are exchanged. This can have various effects - * depending on whether a and b belong to different face or vertex rings. - * For more explanation see __gl_meshSplice() below. - */ -static void Splice(GLUhalfEdge* a, GLUhalfEdge* b) -{ - GLUhalfEdge* aOnext=a->Onext; - GLUhalfEdge* bOnext=b->Onext; - - aOnext->Sym->Lnext=b; - bOnext->Sym->Lnext=a; - a->Onext=bOnext; - b->Onext=aOnext; -} - -/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the - * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives - * a place to insert the new vertex in the global vertex list. We insert - * the new vertex *before* vNext so that algorithms which walk the vertex - * list will not see the newly created vertices. - */ -static void MakeVertex(GLUvertex* newVertex, GLUhalfEdge* eOrig, GLUvertex* vNext) -{ - GLUhalfEdge* e; - GLUvertex* vPrev; - GLUvertex* vNew=newVertex; - - assert(vNew!=NULL); - - /* insert in circular doubly-linked list before vNext */ - vPrev=vNext->prev; - vNew->prev=vPrev; - vPrev->next=vNew; - vNew->next=vNext; - vNext->prev=vNew; - - vNew->anEdge=eOrig; - vNew->data=NULL; - - /* leave coords, s, t undefined */ - - /* fix other edges on this vertex loop */ - e=eOrig; - do { - e->Org=vNew; - e=e->Onext; - } while(e!=eOrig); -} - -/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left - * face of all edges in the face loop to which eOrig belongs. "fNext" gives - * a place to insert the new face in the global face list. We insert - * the new face *before* fNext so that algorithms which walk the face - * list will not see the newly created faces. - */ -static void MakeFace(GLUface* newFace, GLUhalfEdge* eOrig, GLUface* fNext) -{ - GLUhalfEdge* e; - GLUface* fPrev; - GLUface* fNew=newFace; - - assert(fNew!=NULL); - - /* insert in circular doubly-linked list before fNext */ - fPrev=fNext->prev; - fNew->prev=fPrev; - fPrev->next=fNew; - fNew->next=fNext; - fNext->prev=fNew; - - fNew->anEdge=eOrig; - fNew->data=NULL; - fNew->trail=NULL; - fNew->marked=FALSE; - - /* The new face is marked "inside" if the old one was. This is a - * convenience for the common case where a face has been split in two. - */ - fNew->inside=fNext->inside; - - /* fix other edges on this face loop */ - e=eOrig; - do { - e->Lface=fNew; - e=e->Lnext; - } while(e!=eOrig); -} - -/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym), - * and removes from the global edge list. - */ -static void KillEdge(GLUhalfEdge* eDel) -{ - GLUhalfEdge* ePrev; - GLUhalfEdge* eNext; - - /* Half-edges are allocated in pairs, see EdgePair above */ - if (eDel->SymSym; - } - - /* delete from circular doubly-linked list */ - eNext=eDel->next; - ePrev=eDel->Sym->next; - eNext->Sym->next=ePrev; - ePrev->Sym->next=eNext; - - memFree(eDel); -} - -/* KillVertex(vDel) destroys a vertex and removes it from the global - * vertex list. It updates the vertex loop to point to a given new vertex. - */ -static void KillVertex(GLUvertex* vDel, GLUvertex* newOrg) -{ - GLUhalfEdge* e, *eStart=vDel->anEdge; - GLUvertex* vPrev; - GLUvertex* vNext; - - /* change the origin of all affected edges */ - e=eStart; - do { - e->Org=newOrg; - e=e->Onext; - } while(e!=eStart); - - /* delete from circular doubly-linked list */ - vPrev=vDel->prev; - vNext=vDel->next; - vNext->prev=vPrev; - vPrev->next=vNext; - - memFree(vDel); -} - -/* KillFace(fDel) destroys a face and removes it from the global face - * list. It updates the face loop to point to a given new face. - */ -static void KillFace(GLUface* fDel, GLUface* newLface) -{ - GLUhalfEdge* e, *eStart=fDel->anEdge; - GLUface* fPrev; - GLUface* fNext; - - /* change the left face of all affected edges */ - e=eStart; - do { - e->Lface=newLface; - e=e->Lnext; - } while(e!=eStart); - - /* delete from circular doubly-linked list */ - fPrev=fDel->prev; - fNext=fDel->next; - fNext->prev=fPrev; - fPrev->next=fNext; - - memFree(fDel); -} - -/****************** Basic Edge Operations **********************/ -/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face). - * The loop consists of the two new half-edges. - */ -GLUhalfEdge* __gl_meshMakeEdge(GLUmesh* mesh) -{ - GLUvertex* newVertex1=allocVertex(); - GLUvertex* newVertex2=allocVertex(); - GLUface* newFace=allocFace(); - GLUhalfEdge* e; - - /* if any one is null then all get freed */ - if (newVertex1==NULL || newVertex2==NULL || newFace==NULL) - { - if (newVertex1!=NULL) - { - memFree(newVertex1); - } - if (newVertex2!=NULL) - { - memFree(newVertex2); - } - if (newFace!=NULL) - { - memFree(newFace); - } - return NULL; - } - - e=MakeEdge(&mesh->eHead); - if (e==NULL) - { - return NULL; - } - - MakeVertex(newVertex1, e, &mesh->vHead); - MakeVertex(newVertex2, e->Sym, &mesh->vHead); - MakeFace(newFace, e, &mesh->fHead); - - return e; -} - -/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the - * mesh connectivity and topology. It changes the mesh so that - * eOrg->Onext <- OLD(eDst->Onext) - * eDst->Onext <- OLD(eOrg->Onext) - * where OLD(...) means the value before the meshSplice operation. - * - * This can have two effects on the vertex structure: - * - if eOrg->Org != eDst->Org, the two vertices are merged together - * - if eOrg->Org == eDst->Org, the origin is split into two vertices - * In both cases, eDst->Org is changed and eOrg->Org is untouched. - * - * Similarly (and independently) for the face structure, - * - if eOrg->Lface == eDst->Lface, one loop is split into two - * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one - * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. - * - * Some special cases: - * If eDst == eOrg, the operation has no effect. - * If eDst == eOrg->Lnext, the new face will have a single edge. - * If eDst == eOrg->Lprev, the old face will have a single edge. - * If eDst == eOrg->Onext, the new vertex will have a single edge. - * If eDst == eOrg->Oprev, the old vertex will have a single edge. - */ -int __gl_meshSplice(GLUhalfEdge* eOrg, GLUhalfEdge* eDst) -{ - int joiningLoops=FALSE; - int joiningVertices=FALSE; - - if (eOrg==eDst) - { - return 1; - } - - if (eDst->Org!=eOrg->Org) - { - /* We are merging two disjoint vertices -- destroy eDst->Org */ - joiningVertices=TRUE; - KillVertex(eDst->Org, eOrg->Org); - } - - if (eDst->Lface!=eOrg->Lface) - { - /* We are connecting two disjoint loops -- destroy eDst->Lface */ - joiningLoops=TRUE; - KillFace(eDst->Lface, eOrg->Lface); - } - - /* Change the edge structure */ - Splice(eDst, eOrg); - - if (!joiningVertices) - { - GLUvertex* newVertex=allocVertex(); - if (newVertex==NULL) - { - return 0; - } - - /* We split one vertex into two -- the new vertex is eDst->Org. - * Make sure the old vertex points to a valid half-edge. - */ - MakeVertex(newVertex, eDst, eOrg->Org); - eOrg->Org->anEdge=eOrg; - } - - if (!joiningLoops) - { - GLUface* newFace=allocFace(); - if (newFace==NULL) - { - return 0; - } - - /* We split one loop into two -- the new loop is eDst->Lface. - * Make sure the old face points to a valid half-edge. - */ - MakeFace(newFace, eDst, eOrg->Lface); - eOrg->Lface->anEdge=eOrg; - } - - return 1; -} - -/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: - * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop - * eDel->Lface is deleted. Otherwise, we are splitting one loop into two; - * the newly created loop will contain eDel->Dst. If the deletion of eDel - * would create isolated vertices, those are deleted as well. - * - * This function could be implemented as two calls to __gl_meshSplice - * plus a few calls to memFree, but this would allocate and delete - * unnecessary vertices and faces. - */ -int __gl_meshDelete(GLUhalfEdge* eDel) -{ - GLUhalfEdge* eDelSym=eDel->Sym; - int joiningLoops=FALSE; - - /* First step: disconnect the origin vertex eDel->Org. We make all - * changes to get a consistent mesh in this "intermediate" state. - */ - if (eDel->Lface!=eDel->Rface) - { - /* We are joining two loops into one -- remove the left face */ - joiningLoops=TRUE; - KillFace(eDel->Lface, eDel->Rface); - } - - if (eDel->Onext==eDel) - { - KillVertex(eDel->Org, NULL); - } - else - { - /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */ - eDel->Rface->anEdge=eDel->Oprev; - eDel->Org->anEdge=eDel->Onext; - - Splice(eDel, eDel->Oprev); - if (!joiningLoops) - { - GLUface* newFace=allocFace(); - if (newFace==NULL) - { - return 0; - } - - /* We are splitting one loop into two -- create a new loop for eDel. */ - MakeFace(newFace, eDel, eDel->Lface); - } - } - - /* Claim: the mesh is now in a consistent state, except that eDel->Org - * may have been deleted. Now we disconnect eDel->Dst. - */ - if (eDelSym->Onext==eDelSym) - { - KillVertex(eDelSym->Org, NULL); - KillFace(eDelSym->Lface, NULL); - } - else - { - /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */ - eDel->Lface->anEdge=eDelSym->Oprev; - eDelSym->Org->anEdge=eDelSym->Onext; - Splice(eDelSym, eDelSym->Oprev); - } - - /* Any isolated vertices or faces have already been freed. */ - KillEdge(eDel); - - return 1; -} - -/******************** Other Edge Operations **********************/ - -/* All these routines can be implemented with the basic edge - * operations above. They are provided for convenience and efficiency. - */ - -/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that - * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. - * eOrg and eNew will have the same left face. - */ -GLUhalfEdge* __gl_meshAddEdgeVertex(GLUhalfEdge* eOrg) -{ - GLUhalfEdge* eNewSym; - GLUhalfEdge* eNew=MakeEdge(eOrg); - - if (eNew==NULL) - { - return NULL; - } - - eNewSym=eNew->Sym; - - /* Connect the new edge appropriately */ - Splice(eNew, eOrg->Lnext); - - /* Set the vertex and face information */ - eNew->Org=eOrg->Dst; - { - GLUvertex* newVertex=allocVertex(); - if (newVertex==NULL) - { - return NULL; - } - - MakeVertex(newVertex, eNewSym, eNew->Org); - } - eNew->Lface=eNewSym->Lface=eOrg->Lface; - - return eNew; -} - -/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, - * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org. - * eOrg and eNew will have the same left face. - */ -GLUhalfEdge* __gl_meshSplitEdge(GLUhalfEdge* eOrg) -{ - GLUhalfEdge* eNew; - GLUhalfEdge* tempHalfEdge=__gl_meshAddEdgeVertex(eOrg); - if (tempHalfEdge==NULL) - { - return NULL; - } - - eNew=tempHalfEdge->Sym; - - /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */ - Splice(eOrg->Sym, eOrg->Sym->Oprev); - Splice(eOrg->Sym, eNew); - - /* Set the vertex and face information */ - eOrg->Dst=eNew->Org; - eNew->Dst->anEdge=eNew->Sym; /* may have pointed to eOrg->Sym */ - eNew->Rface=eOrg->Rface; - eNew->winding=eOrg->winding; /* copy old winding information */ - eNew->Sym->winding=eOrg->Sym->winding; - - return eNew; -} - -/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst - * to eDst->Org, and returns the corresponding half-edge eNew. - * If eOrg->Lface == eDst->Lface, this splits one loop into two, - * and the newly created loop is eNew->Lface. Otherwise, two disjoint - * loops are merged into one, and the loop eDst->Lface is destroyed. - * - * If (eOrg == eDst), the new face will have only two edges. - * If (eOrg->Lnext == eDst), the old face is reduced to a single edge. - * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges. - */ -GLUhalfEdge* __gl_meshConnect(GLUhalfEdge* eOrg, GLUhalfEdge* eDst) -{ - GLUhalfEdge* eNewSym; - int joiningLoops=FALSE; - GLUhalfEdge* eNew=MakeEdge(eOrg); - - if (eNew==NULL) - { - return NULL; - } - - eNewSym=eNew->Sym; - - if (eDst->Lface!=eOrg->Lface) - { - /* We are connecting two disjoint loops -- destroy eDst->Lface */ - joiningLoops=TRUE; - KillFace(eDst->Lface, eOrg->Lface); - } - - /* Connect the new edge appropriately */ - Splice(eNew, eOrg->Lnext); - Splice(eNewSym, eDst); - - /* Set the vertex and face information */ - eNew->Org=eOrg->Dst; - eNewSym->Org=eDst->Org; - eNew->Lface=eNewSym->Lface=eOrg->Lface; - - /* Make sure the old face points to a valid half-edge */ - eOrg->Lface->anEdge=eNewSym; - - if (!joiningLoops) - { - GLUface* newFace=allocFace(); - - if (newFace==NULL) - { - return NULL; - } - - /* We split one loop into two -- the new loop is eNew->Lface */ - MakeFace(newFace, eNew, eOrg->Lface); - } - - return eNew; -} - -/******************** Other Operations **********************/ -/* __gl_meshZapFace(fZap) destroys a face and removes it from the - * global face list. All edges of fZap will have a NULL pointer as their - * left face. Any edges which also have a NULL pointer as their right face - * are deleted entirely (along with any isolated vertices this produces). - * An entire mesh can be deleted by zapping its faces, one at a time, - * in any order. Zapped faces cannot be used in further mesh operations! - */ -void __gl_meshZapFace(GLUface* fZap) -{ - GLUhalfEdge* eStart=fZap->anEdge; - GLUhalfEdge* e, *eNext, *eSym; - GLUface* fPrev, *fNext; - - /* walk around face, deleting edges whose right face is also NULL */ - eNext=eStart->Lnext; - do { - e=eNext; - eNext=e->Lnext; - - e->Lface=NULL; - if (e->Rface==NULL) - { - /* delete the edge -- see __gl_MeshDelete above */ - if (e->Onext==e) - { - KillVertex(e->Org, NULL); - } - else - { - /* Make sure that e->Org points to a valid half-edge */ - e->Org->anEdge=e->Onext; - Splice(e, e->Oprev); - } - eSym=e->Sym; - if (eSym->Onext==eSym) - { - KillVertex(eSym->Org, NULL); - } - else - { - /* Make sure that eSym->Org points to a valid half-edge */ - eSym->Org->anEdge=eSym->Onext; - Splice(eSym, eSym->Oprev); - } - KillEdge(e); - } - } while(e!=eStart); - - /* delete from circular doubly-linked list */ - fPrev=fZap->prev; - fNext=fZap->next; - fNext->prev=fPrev; - fPrev->next=fNext; - - memFree(fZap); -} - -/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices, - * and no loops (what we usually call a "face"). - */ -GLUmesh* __gl_meshNewMesh(void) -{ - GLUvertex* v; - GLUface* f; - GLUhalfEdge* e; - GLUhalfEdge* eSym; - GLUmesh* mesh=(GLUmesh*)memAlloc(sizeof(GLUmesh)); - - if (mesh==NULL) - { - return NULL; - } - - v=&mesh->vHead; - f=&mesh->fHead; - e=&mesh->eHead; - eSym=&mesh->eHeadSym; - - v->next=v->prev=v; - v->anEdge=NULL; - v->data=NULL; - - f->next=f->prev=f; - f->anEdge=NULL; - f->data=NULL; - f->trail=NULL; - f->marked=FALSE; - f->inside=FALSE; - - e->next=e; - e->Sym=eSym; - e->Onext=NULL; - e->Lnext=NULL; - e->Org=NULL; - e->Lface=NULL; - e->winding=0; - e->activeRegion=NULL; - - eSym->next=eSym; - eSym->Sym=e; - eSym->Onext=NULL; - eSym->Lnext=NULL; - eSym->Org=NULL; - eSym->Lface=NULL; - eSym->winding=0; - eSym->activeRegion=NULL; - - return mesh; -} - -/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in - * both meshes, and returns the new mesh (the old meshes are destroyed). - */ -GLUmesh* __gl_meshUnion(GLUmesh* mesh1, GLUmesh* mesh2) -{ - GLUface* f1=&mesh1->fHead; - GLUvertex* v1=&mesh1->vHead; - GLUhalfEdge* e1=&mesh1->eHead; - GLUface* f2=&mesh2->fHead; - GLUvertex* v2=&mesh2->vHead; - GLUhalfEdge* e2=&mesh2->eHead; - - /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */ - if (f2->next!=f2) - { - f1->prev->next=f2->next; - f2->next->prev=f1->prev; - f2->prev->next=f1; - f1->prev=f2->prev; - } - - if (v2->next!=v2) - { - v1->prev->next=v2->next; - v2->next->prev=v1->prev; - v2->prev->next=v1; - v1->prev=v2->prev; - } - - if (e2->next!=e2) - { - e1->Sym->next->Sym->next=e2->next; - e2->next->Sym->next=e1->Sym->next; - e2->Sym->next->Sym->next=e1; - e1->Sym->next=e2->Sym->next; - } - - memFree(mesh2); - - return mesh1; -} - -#ifdef DELETE_BY_ZAPPING - -/* __gl_meshDeleteMesh(mesh) will free all storage for any valid mesh. - */ -void __gl_meshDeleteMesh( GLUmesh *mesh ) -{ - GLUface* fHead=&mesh->fHead; - - while(fHead->next!=fHead) - { - __gl_meshZapFace(fHead->next); - } - assert(mesh->vHead.next==&mesh->vHead); - - memFree(mesh); -} - -#else /* DELETE_BY_ZAPPING */ - -/* __gl_meshDeleteMesh(mesh) will free all storage for any valid mesh. - */ -void __gl_meshDeleteMesh( GLUmesh *mesh ) -{ - GLUface* f; - GLUface* fNext; - GLUvertex* v; - GLUvertex* vNext; - GLUhalfEdge* e; - GLUhalfEdge* eNext; - - for (f=mesh->fHead.next; f!=&mesh->fHead; f=fNext) - { - fNext=f->next; - memFree(f); - } - - for (v=mesh->vHead.next; v!=&mesh->vHead; v=vNext) - { - vNext=v->next; - memFree(v); - } - - for (e=mesh->eHead.next; e!=&mesh->eHead; e=eNext) - { - /* One call frees both e and e->Sym (see EdgePair above) */ - eNext=e->next; - memFree(e); - } - - memFree(mesh); -} - -#endif /* DELETE_BY_ZAPPING */ - -#ifndef NDEBUG - -/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. - */ -void __gl_meshCheckMesh(GLUmesh* mesh) -{ - GLUface *fHead=&mesh->fHead; - GLUvertex *vHead=&mesh->vHead; - GLUhalfEdge *eHead=&mesh->eHead; - GLUface* f; - GLUface* fPrev; - GLUvertex* v; - GLUvertex* vPrev; - GLUhalfEdge* e; - GLUhalfEdge* ePrev; - - fPrev=fHead; - for (fPrev=fHead; (f=fPrev->next)!=fHead; fPrev=f) - { - assert(f->prev==fPrev); - e=f->anEdge; - do { - assert(e->Sym!=e); - assert(e->Sym->Sym==e); - assert(e->Lnext->Onext->Sym==e); - assert(e->Onext->Sym->Lnext==e); - assert(e->Lface==f); - e=e->Lnext; - } while(e!=f->anEdge); - } - assert(f->prev==fPrev && f->anEdge==NULL && f->data==NULL); - - vPrev=vHead; - for (vPrev=vHead; (v=vPrev->next)!=vHead; vPrev=v) - { - assert(v->prev==vPrev); - e=v->anEdge; - do { - assert(e->Sym!=e); - assert(e->Sym->Sym==e); - assert(e->Lnext->Onext->Sym==e); - assert(e->Onext->Sym->Lnext==e); - assert(e->Org==v); - e=e->Onext; - } while(e!=v->anEdge); - } - assert(v->prev==vPrev && v->anEdge==NULL && v->data==NULL); - - ePrev=eHead; - for (ePrev=eHead; (e=ePrev->next)!=eHead; ePrev=e) - { - assert(e->Sym->next==ePrev->Sym); - assert(e->Sym!=e); - assert(e->Sym->Sym==e); - assert(e->Org!=NULL); - assert(e->Dst!=NULL); - assert(e->Lnext->Onext->Sym==e); - assert(e->Onext->Sym->Lnext==e); - } - assert(e->Sym->next==ePrev->Sym && e->Sym==&mesh->eHeadSym && - e->Sym->Sym==e && e->Org==NULL && e->Dst==NULL && - e->Lface==NULL && e->Rface==NULL); -} - -#endif /* NDEBUG */ diff --git a/internal/c/parts/core/glues/src/libtess/mesh.h b/internal/c/parts/core/glues/src/libtess/mesh.h deleted file mode 100644 index 70168843b..000000000 --- a/internal/c/parts/core/glues/src/libtess/mesh.h +++ /dev/null @@ -1,269 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __mesh_h_ -#define __mesh_h_ - -#include "glues.h" - -typedef struct GLUmesh GLUmesh; - -typedef struct GLUvertex GLUvertex; -typedef struct GLUface GLUface; -typedef struct GLUhalfEdge GLUhalfEdge; - -typedef struct ActiveRegion ActiveRegion; /* Internal data */ - -/* The mesh structure is similar in spirit, notation, and operations - * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives - * for the manipulation of general subdivisions and the computation of - * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985). - * For a simplified description, see the course notes for CS348a, - * "Mathematical Foundations of Computer Graphics", available at the - * Stanford bookstore (and taught during the fall quarter). - * The implementation also borrows a tiny subset of the graph-based approach - * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction - * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988). - * - * The fundamental data structure is the "half-edge". Two half-edges - * go together to make an edge, but they point in opposite directions. - * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym), - * its origin vertex (Org), the face on its left side (Lface), and the - * adjacent half-edges in the CCW direction around the origin vertex - * (Onext) and around the left face (Lnext). There is also a "next" - * pointer for the global edge list (see below). - * - * The notation used for mesh navigation: - * Sym = the mate of a half-edge (same edge, but opposite direction) - * Onext = edge CCW around origin vertex (keep same origin) - * Dnext = edge CCW around destination vertex (keep same dest) - * Lnext = edge CCW around left face (dest becomes new origin) - * Rnext = edge CCW around right face (origin becomes new dest) - * - * "prev" means to substitute CW for CCW in the definitions above. - * - * The mesh keeps global lists of all vertices, faces, and edges, - * stored as doubly-linked circular lists with a dummy header node. - * The mesh stores pointers to these dummy headers (vHead, fHead, eHead). - * - * The circular edge list is special; since half-edges always occur - * in pairs (e and e->Sym), each half-edge stores a pointer in only - * one direction. Starting at eHead and following the e->next pointers - * will visit each *edge* once (ie. e or e->Sym, but not both). - * e->Sym stores a pointer in the opposite direction, thus it is - * always true that e->Sym->next->Sym->next == e. - * - * Each vertex has a pointer to next and previous vertices in the - * circular list, and a pointer to a half-edge with this vertex as - * the origin (NULL if this is the dummy header). There is also a - * field "data" for client data. - * - * Each face has a pointer to the next and previous faces in the - * circular list, and a pointer to a half-edge with this face as - * the left face (NULL if this is the dummy header). There is also - * a field "data" for client data. - * - * Note that what we call a "face" is really a loop; faces may consist - * of more than one loop (ie. not simply connected), but there is no - * record of this in the data structure. The mesh may consist of - * several disconnected regions, so it may not be possible to visit - * the entire mesh by starting at a half-edge and traversing the edge - * structure. - * - * The mesh does NOT support isolated vertices; a vertex is deleted along - * with its last edge. Similarly when two faces are merged, one of the - * faces is deleted (see __gl_meshDelete below). For mesh operations, - * all face (loop) and vertex pointers must not be NULL. However, once - * mesh manipulation is finished, __gl_MeshZapFace can be used to delete - * faces of the mesh, one at a time. All external faces can be "zapped" - * before the mesh is returned to the client; then a NULL face indicates - * a region which is not part of the output polygon. - */ - -struct GLUvertex -{ - GLUvertex* next; /* next vertex (never NULL) */ - GLUvertex* prev; /* previous vertex (never NULL) */ - GLUhalfEdge* anEdge; /* a half-edge with this origin */ - void* data; /* client's data */ - - /* Internal data (keep hidden) */ - GLfloat coords[3]; /* vertex location in 3D */ - GLfloat s, t; /* projection onto the sweep plane */ - long pqHandle; /* to allow deletion from priority queue */ -}; - -struct GLUface -{ - GLUface* next; /* next face (never NULL) */ - GLUface* prev; /* previous face (never NULL) */ - GLUhalfEdge* anEdge; /* a half edge with this left face */ - void* data; /* room for client's data */ - - /* Internal data (keep hidden) */ - GLUface* trail; /* "stack" for conversion to strips */ - GLboolean marked; /* flag for conversion to strips */ - GLboolean inside; /* this face is in the polygon interior */ -}; - -struct GLUhalfEdge -{ - GLUhalfEdge* next; /* doubly-linked list (prev==Sym->next) */ - GLUhalfEdge* Sym; /* same edge, opposite direction */ - GLUhalfEdge* Onext; /* next edge CCW around origin */ - GLUhalfEdge* Lnext; /* next edge CCW around left face */ - GLUvertex* Org; /* origin vertex (Overtex too long) */ - GLUface* Lface; /* left face */ - - /* Internal data (keep hidden) */ - ActiveRegion* activeRegion; /* a region with this upper edge (sweep.c) */ - int winding; /* change in winding number when crossing - from the right face to the left face */ -}; - -#define Rface Sym->Lface -#define Dst Sym->Org - -#define Oprev Sym->Lnext -#define Lprev Onext->Sym -#define Dprev Lnext->Sym -#define Rprev Sym->Onext -#define Dnext Rprev->Sym /* 3 pointers */ -#define Rnext Oprev->Sym /* 3 pointers */ - -struct GLUmesh -{ - GLUvertex vHead; /* dummy header for vertex list */ - GLUface fHead; /* dummy header for face list */ - GLUhalfEdge eHead; /* dummy header for edge list */ - GLUhalfEdge eHeadSym; /* and its symmetric counterpart */ -}; - -/* The mesh operations below have three motivations: completeness, - * convenience, and efficiency. The basic mesh operations are MakeEdge, - * Splice, and Delete. All the other edge operations can be implemented - * in terms of these. The other operations are provided for convenience - * and/or efficiency. - * - * When a face is split or a vertex is added, they are inserted into the - * global list *before* the existing vertex or face (ie. e->Org or e->Lface). - * This makes it easier to process all vertices or faces in the global lists - * without worrying about processing the same data twice. As a convenience, - * when a face is split, the "inside" flag is copied from the old face. - * Other internal data (v->data, v->activeRegion, f->data, f->marked, - * f->trail, e->winding) is set to zero. - * - * ********************** Basic Edge Operations ************************** - * - * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop. - * The loop (face) consists of the two new half-edges. - * - * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the - * mesh connectivity and topology. It changes the mesh so that - * eOrg->Onext <- OLD(eDst->Onext) - * eDst->Onext <- OLD(eOrg->Onext) - * where OLD(...) means the value before the meshSplice operation. - * - * This can have two effects on the vertex structure: - * - if eOrg->Org != eDst->Org, the two vertices are merged together - * - if eOrg->Org == eDst->Org, the origin is split into two vertices - * In both cases, eDst->Org is changed and eOrg->Org is untouched. - * - * Similarly (and independently) for the face structure, - * - if eOrg->Lface == eDst->Lface, one loop is split into two - * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one - * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. - * - * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: - * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop - * eDel->Lface is deleted. Otherwise, we are splitting one loop into two; - * the newly created loop will contain eDel->Dst. If the deletion of eDel - * would create isolated vertices, those are deleted as well. - * - * ********************** Other Edge Operations ************************** - * - * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that - * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. - * eOrg and eNew will have the same left face. - * - * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, - * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org. - * eOrg and eNew will have the same left face. - * - * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst - * to eDst->Org, and returns the corresponding half-edge eNew. - * If eOrg->Lface == eDst->Lface, this splits one loop into two, - * and the newly created loop is eNew->Lface. Otherwise, two disjoint - * loops are merged into one, and the loop eDst->Lface is destroyed. - * - * ************************ Other Operations ***************************** - * - * __gl_meshNewMesh() creates a new mesh with no edges, no vertices, - * and no loops (what we usually call a "face"). - * - * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in - * both meshes, and returns the new mesh (the old meshes are destroyed). - * - * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. - * - * __gl_meshZapFace( fZap ) destroys a face and removes it from the - * global face list. All edges of fZap will have a NULL pointer as their - * left face. Any edges which also have a NULL pointer as their right face - * are deleted entirely (along with any isolated vertices this produces). - * An entire mesh can be deleted by zapping its faces, one at a time, - * in any order. Zapped faces cannot be used in further mesh operations! - * - * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. - */ - -GLUhalfEdge* __gl_meshMakeEdge(GLUmesh* mesh); -int __gl_meshSplice(GLUhalfEdge* eOrg, GLUhalfEdge* eDst); -int __gl_meshDelete(GLUhalfEdge* eDel); - -GLUhalfEdge* __gl_meshAddEdgeVertex(GLUhalfEdge* eOrg); -GLUhalfEdge* __gl_meshSplitEdge(GLUhalfEdge* eOrg); -GLUhalfEdge* __gl_meshConnect(GLUhalfEdge* eOrg, GLUhalfEdge* eDst); - -GLUmesh* __gl_meshNewMesh(void); -GLUmesh* __gl_meshUnion(GLUmesh* mesh1, GLUmesh* mesh2); -void __gl_meshDeleteMesh(GLUmesh* mesh); -void __gl_meshZapFace(GLUface* fZap); - -#ifdef NDEBUG - #define __gl_meshCheckMesh(mesh) -#else - void __gl_meshCheckMesh(GLUmesh* mesh); -#endif - -#endif /* __mesh_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/normal.c b/internal/c/parts/core/glues/src/libtess/normal.c deleted file mode 100644 index 887ddc3c1..000000000 --- a/internal/c/parts/core/glues/src/libtess/normal.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include "mesh.h" -#include "tess.h" -#include "normal.h" -#include -#include - -#define TRUE 1 -#define FALSE 0 - -#define Dot(u, v) (u[0]*v[0]+u[1]*v[1]+u[2]*v[2]) - -#undef ABS -#define ABS(x) ((x)<0 ? -(x) : (x)) - -static int LongAxis(GLfloat v[3]) -{ - int i=0; - - if (ABS(v[1])>ABS(v[0])) - { - i=1; - } - if (ABS(v[2])>ABS(v[i])) - { - i=2; - } - - return i; -} - -static void ComputeNormal(GLUtesselator* tess, GLfloat norm[3]) -{ - GLUvertex* v, *v1, *v2; - GLfloat c, tLen2, maxLen2; - GLfloat maxVal[3], minVal[3], d1[3], d2[3], tNorm[3]; - GLUvertex* maxVert[3], *minVert[3]; - GLUvertex* vHead=&tess->mesh->vHead; - int i; - - maxVal[0]=maxVal[1]=maxVal[2]=-2*GLU_TESS_MAX_COORD; - minVal[0]=minVal[1]=minVal[2]=2*GLU_TESS_MAX_COORD; - - for (v=vHead->next; v!=vHead; v=v->next) - { - for (i=0; i<3; ++i) - { - c=v->coords[i]; - if (cmaxVal[i]) - { - maxVal[i]=c; - maxVert[i]=v; - } - } - } - - /* Find two vertices separated by at least 1/sqrt(3) of the maximum - * distance between any two vertices - */ - i=0; - if (maxVal[1]-minVal[1]>maxVal[0]-minVal[0]) - { - i=1; - } - if (maxVal[2]-minVal[2]>maxVal[i]-minVal[i]) - { - i=2; - } - if (minVal[i]>=maxVal[i]) - { - /* All vertices are the same -- normal doesn't matter */ - norm[0]=0; norm[1]=0; norm[2]=1; - return; - } - - /* Look for a third vertex which forms the triangle with maximum area - * (Length of normal == twice the triangle area) - */ - maxLen2 = 0; - v1=minVert[i]; - v2=maxVert[i]; - d1[0]=v1->coords[0]-v2->coords[0]; - d1[1]=v1->coords[1]-v2->coords[1]; - d1[2]=v1->coords[2]-v2->coords[2]; - for (v=vHead->next; v!=vHead; v=v->next) - { - d2[0]=v->coords[0]-v2->coords[0]; - d2[1]=v->coords[1]-v2->coords[1]; - d2[2]=v->coords[2]-v2->coords[2]; - tNorm[0]=d1[1]*d2[2]-d1[2]*d2[1]; - tNorm[1]=d1[2]*d2[0]-d1[0]*d2[2]; - tNorm[2]=d1[0]*d2[1]-d1[1]*d2[0]; - tLen2=tNorm[0]*tNorm[0]+tNorm[1]*tNorm[1]+tNorm[2]*tNorm[2]; - if (tLen2>maxLen2) - { - maxLen2=tLen2; - norm[0]=tNorm[0]; - norm[1]=tNorm[1]; - norm[2]=tNorm[2]; - } - } - - if (maxLen2<=0) - { - /* All points lie on a single line -- any decent normal will do */ - norm[0]=norm[1]=norm[2]=0; - norm[LongAxis(d1)]=1; - } -} - -static void CheckOrientation(GLUtesselator* tess) -{ - GLfloat area; - GLUface* f, *fHead=&tess->mesh->fHead; - GLUvertex* v, *vHead=&tess->mesh->vHead; - GLUhalfEdge* e; - - /* When we compute the normal automatically, we choose the orientation - * so that the the sum of the signed areas of all contours is non-negative. - */ - area=0; - for (f=fHead->next; f!=fHead; f=f->next) - { - e=f->anEdge; - if (e->winding<=0) - { - continue; - } - - do { - area+=(e->Org->s-e->Dst->s)*(e->Org->t+e->Dst->t); - e=e->Lnext; - } while(e!=f->anEdge); - } - if (area<0) - { - /* Reverse the orientation by flipping all the t-coordinates */ - for (v=vHead->next; v!=vHead; v=v->next) - { - v->t=-v->t; - } - tess->tUnit[0]=-tess->tUnit[0]; - tess->tUnit[1]=-tess->tUnit[1]; - tess->tUnit[2]=-tess->tUnit[2]; - } -} - -#ifdef FOR_TRITE_TEST_PROGRAM -#include - -extern int RandomSweep; -#define S_UNIT_X (RandomSweep ? (2*drand48()-1) : 1.0f) -#define S_UNIT_Y (RandomSweep ? (2*drand48()-1) : 0.0f) -#else /* FOR_TRITE_TEST_PROGRAM */ -#if defined(SLANTED_SWEEP) -/* The "feature merging" is not intended to be complete. There are - * special cases where edges are nearly parallel to the sweep line - * which are not implemented. The algorithm should still behave - * robustly (ie. produce a reasonable tesselation) in the presence - * of such edges, however it may miss features which could have been - * merged. We could minimize this effect by choosing the sweep line - * direction to be something unusual (ie. not parallel to one of the - * coordinate axes). - */ -#define S_UNIT_X 0.50941539564955385f /* Pre-normalized */ -#define S_UNIT_Y 0.86052074622010633f -#else /* SLANTED_SWEEP */ -#define S_UNIT_X 1.0f -#define S_UNIT_Y 0.0f -#endif /* SLANTED_SWEEP */ -#endif /* FOR_TRITE_TEST_PROGRAM */ - -/* Determine the polygon normal and project vertices onto the plane - * of the polygon. - */ -void __gl_projectPolygon(GLUtesselator* tess) -{ - GLUvertex *v, *vHead=&tess->mesh->vHead; - GLfloat norm[3]; - GLfloat* sUnit; - GLfloat* tUnit; - int i; - int computedNormal=FALSE; - - norm[0]=tess->normal[0]; - norm[1]=tess->normal[1]; - norm[2]=tess->normal[2]; - - if (norm[0]==0 && norm[1]==0 && norm[2]==0) - { - ComputeNormal(tess, norm); - computedNormal=TRUE; - } - sUnit=tess->sUnit; - tUnit=tess->tUnit; - i=LongAxis(norm); - -#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT) - /* Choose the initial sUnit vector to be approximately perpendicular - * to the normal. - */ - Normalize(norm); - - sUnit[i]=0; - sUnit[(i+1)%3]=S_UNIT_X; - sUnit[(i+2)%3]=S_UNIT_Y; - - /* Now make it exactly perpendicular */ - w=Dot(sUnit, norm); - sUnit[0]-=w*norm[0]; - sUnit[1]-=w*norm[1]; - sUnit[2]-=w*norm[2]; - Normalize(sUnit); - - /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ - tUnit[0]=norm[1]*sUnit[2]-norm[2]*sUnit[1]; - tUnit[1]=norm[2]*sUnit[0]-norm[0]*sUnit[2]; - tUnit[2]=norm[0]*sUnit[1]-norm[1]*sUnit[0]; - Normalize(tUnit); -#else /* FOR_TRITE_TEST_PROGRAM || TRUE_PROJECT */ - /* Project perpendicular to a coordinate axis -- better numerically */ - sUnit[i]=0; - sUnit[(i+1)%3]=S_UNIT_X; - sUnit[(i+2)%3]=S_UNIT_Y; - - tUnit[i]=0; - tUnit[(i+1)%3]=(norm[i]>0) ? -S_UNIT_Y : S_UNIT_Y; - tUnit[(i+2)%3]=(norm[i]>0) ? S_UNIT_X : -S_UNIT_X; -#endif /* FOR_TRITE_TEST_PROGRAM || TRUE_PROJECT */ - - /* Project the vertices onto the sweep plane */ - for (v=vHead->next; v!=vHead; v=v->next) - { - v->s=Dot(v->coords, sUnit); - v->t=Dot(v->coords, tUnit); - } - if (computedNormal) - { - CheckOrientation(tess); - } -} diff --git a/internal/c/parts/core/glues/src/libtess/normal.h b/internal/c/parts/core/glues/src/libtess/normal.h deleted file mode 100644 index b25516dd3..000000000 --- a/internal/c/parts/core/glues/src/libtess/normal.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __normal_h_ -#define __normal_h_ - -#include "tess.h" - -/* __gl_projectPolygon( tess ) determines the polygon normal - * and project vertices onto the plane of the polygon. - */ -void __gl_projectPolygon(GLUtesselator* tess); - -#endif /* __normal_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/priorityq-heap.h b/internal/c/parts/core/glues/src/libtess/priorityq-heap.h deleted file mode 100644 index 68e01eff1..000000000 --- a/internal/c/parts/core/glues/src/libtess/priorityq-heap.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_heap_h_ -#define __priorityq_heap_h_ - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQHeapKey -#define PQhandle PQHeapHandle -#define PriorityQ PriorityQHeap - -#define pqNewPriorityQ(leq) __gl_pqHeapNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqHeapDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqHeapInit(pq) -#define pqInsert(pq,key) __gl_pqHeapInsert(pq,key) -#define pqMinimum(pq) __gl_pqHeapMinimum(pq) -#define pqExtractMin(pq) __gl_pqHeapExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqHeapDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqHeapIsEmpty(pq) - - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef void* PQkey; -typedef long PQhandle; -typedef struct PriorityQ PriorityQ; - -typedef struct -{ - PQhandle handle; -} PQnode; - -typedef struct -{ - PQkey key; - PQhandle node; -} PQhandleElem; - -struct PriorityQ -{ - PQnode* nodes; - PQhandleElem* handles; - long size; - long max; - PQhandle freeList; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2)); -void pqDeletePriorityQ(PriorityQ* pq); - -void pqInit(PriorityQ* pq); -PQhandle pqInsert(PriorityQ* pq, PQkey key); -PQkey pqExtractMin(PriorityQ* pq); -void pqDelete(PriorityQ* pq, PQhandle handle); - -#define __gl_pqHeapMinimum(pq) ((pq)->handles[(pq)->nodes[1].handle].key) -#define __gl_pqHeapIsEmpty(pq) ((pq)->size==0) - -#endif /* __priorityq_heap_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/priorityq-heap.i b/internal/c/parts/core/glues/src/libtess/priorityq-heap.i deleted file mode 100644 index 4faed4480..000000000 --- a/internal/c/parts/core/glues/src/libtess/priorityq-heap.i +++ /dev/null @@ -1,276 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include /* LONG_MAX */ -#include "priorityq-heap.h" -#include "memalloc.h" - -#define INIT_SIZE 32 - -#define TRUE 1 -#define FALSE 0 - -#ifdef FOR_TRITE_TEST_PROGRAM - #define LEQ(x, y) (*pq->leq)(x,y) -#else - /* Violates modularity, but a little faster */ - #include "geom.h" - #define LEQ(x, y) VertLeq((GLUvertex*)x, (GLUvertex*)y) -#endif /* FOR_TRITE_TEST_PROGRAM */ - -/* really __gl_pqHeapNewPriorityQ */ -PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2)) -{ - PriorityQ* pq=(PriorityQ*)memAlloc(sizeof(PriorityQ)); - if (pq==NULL) - { - return NULL; - } - - pq->size=0; - pq->max=INIT_SIZE; - pq->nodes=(PQnode*)memAlloc((INIT_SIZE+1)*sizeof(pq->nodes[0])); - if (pq->nodes==NULL) - { - memFree(pq); - return NULL; - } - - pq->handles=(PQhandleElem*)memAlloc((INIT_SIZE+1)*sizeof(pq->handles[0])); - if (pq->handles==NULL) - { - memFree(pq->nodes); - memFree(pq); - return NULL; - } - - pq->initialized=FALSE; - pq->freeList=0; - pq->leq=leq; - - /* so that Minimum() returns NULL */ - pq->nodes[1].handle=1; - pq->handles[1].key=NULL; - - return pq; -} - -/* really __gl_pqHeapDeletePriorityQ */ -void pqDeletePriorityQ(PriorityQ* pq) -{ - memFree(pq->handles); - memFree(pq->nodes); - memFree(pq); -} - -static void FloatDown(PriorityQ* pq, long curr) -{ - PQnode* n=pq->nodes; - PQhandleElem* h=pq->handles; - PQhandle hCurr, hChild; - long child; - - hCurr=n[curr].handle; - for(;;) - { - child=curr<<1; - if (childsize && LEQ(h[n[child+1].handle].key, h[n[child].handle].key)) - { - ++child; - } - - assert(child<=pq->max); - - hChild = n[child].handle; - if (child>pq->size || LEQ(h[hCurr].key, h[hChild].key)) - { - n[curr].handle=hCurr; - h[hCurr].node=curr; - break; - } - n[curr].handle=hChild; - h[hChild].node=curr; - curr=child; - } -} - -static void FloatUp(PriorityQ* pq, long curr) -{ - PQnode* n=pq->nodes; - PQhandleElem* h=pq->handles; - PQhandle hCurr, hParent; - long parent; - - hCurr=n[curr].handle; - for(;;) - { - parent=curr>>1; - hParent=n[parent].handle; - - if (parent==0 || LEQ(h[hParent].key, h[hCurr].key)) - { - n[curr].handle=hCurr; - h[hCurr].node=curr; - break; - } - n[curr].handle=hParent; - h[hParent].node=curr; - curr=parent; - } -} - -/* really __gl_pqHeapInit */ -void pqInit(PriorityQ* pq) -{ - long i; - - /* This method of building a heap is O(n), rather than O(n lg n). */ - for(i=pq->size; i>=1; --i) - { - FloatDown(pq, i); - } - pq->initialized=TRUE; -} - -/* really __gl_pqHeapInsert */ -/* returns LONG_MAX iff out of memory */ -PQhandle pqInsert(PriorityQ* pq, PQkey keyNew) -{ - long curr; - PQhandle free; - - curr=++pq->size; - if ((curr*2)>pq->max) - { - PQnode* saveNodes=pq->nodes; - PQhandleElem* saveHandles=pq->handles; - - /* If the heap overflows, double its size. */ - pq->max<<=1; - pq->nodes=(PQnode*)memRealloc(pq->nodes, (size_t)((pq->max+1)*sizeof(pq->nodes[0]))); - if (pq->nodes==NULL) - { - /* restore ptr to free upon return */ - pq->nodes=saveNodes; - return LONG_MAX; - } - pq->handles=(PQhandleElem*)memRealloc(pq->handles, (size_t)((pq->max+1)*sizeof(pq->handles[0]))); - if (pq->handles==NULL) - { - /* restore ptr to free upon return */ - pq->handles=saveHandles; - return LONG_MAX; - } - } - - if (pq->freeList==0) - { - free=curr; - } - else - { - free=pq->freeList; - pq->freeList=pq->handles[free].node; - } - - pq->nodes[curr].handle=free; - pq->handles[free].node=curr; - pq->handles[free].key=keyNew; - - if (pq->initialized) - { - FloatUp(pq, curr); - } - - assert(free!=LONG_MAX); - - return free; -} - -/* really __gl_pqHeapExtractMin */ -PQkey pqExtractMin(PriorityQ* pq) -{ - PQnode* n=pq->nodes; - PQhandleElem* h=pq->handles; - PQhandle hMin=n[1].handle; - PQkey min=h[hMin].key; - - if (pq->size>0) - { - n[1].handle=n[pq->size].handle; - h[n[1].handle].node=1; - - h[hMin].key=NULL; - h[hMin].node=pq->freeList; - pq->freeList=hMin; - - if (--pq->size>0) - { - FloatDown(pq, 1); - } - } - - return min; -} - -/* really __gl_pqHeapDelete */ -void pqDelete(PriorityQ* pq, PQhandle hCurr) -{ - PQnode* n=pq->nodes; - PQhandleElem* h=pq->handles; - long curr; - - assert(hCurr>=1 && hCurr<=pq->max && h[hCurr].key!=NULL); - - curr=h[hCurr].node; - n[curr].handle=n[pq->size].handle; - h[n[curr].handle].node=curr; - - if (curr<=--pq->size) - { - if (curr<=1 || LEQ(h[n[curr>>1].handle].key, h[n[curr].handle].key)) - { - FloatDown(pq, curr); - } - else - { - FloatUp(pq, curr); - } - } - h[hCurr].key=NULL; - h[hCurr].node=pq->freeList; - pq->freeList=hCurr; -} diff --git a/internal/c/parts/core/glues/src/libtess/priorityq-sort.h b/internal/c/parts/core/glues/src/libtess/priorityq-sort.h deleted file mode 100644 index 9de7cd409..000000000 --- a/internal/c/parts/core/glues/src/libtess/priorityq-sort.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_sort_h_ -#define __priorityq_sort_h_ - -#include "priorityq-heap.h" - -#undef PQkey -#undef PQhandle -#undef PriorityQ -#undef pqNewPriorityQ -#undef pqDeletePriorityQ -#undef pqInit -#undef pqInsert -#undef pqMinimum -#undef pqExtractMin -#undef pqDelete -#undef pqIsEmpty - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQSortKey -#define PQhandle PQSortHandle -#define PriorityQ PriorityQSort - -#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqSortInit(pq) -#define pqInsert(pq,key) __gl_pqSortInsert(pq,key) -#define pqMinimum(pq) __gl_pqSortMinimum(pq) -#define pqExtractMin(pq) __gl_pqSortExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq) - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef PQHeapKey PQkey; -typedef PQHeapHandle PQhandle; -typedef struct PriorityQ PriorityQ; - -struct PriorityQ -{ - PriorityQHeap* heap; - PQkey* keys; - PQkey** order; - PQhandle size; - PQhandle max; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2)); -void pqDeletePriorityQ(PriorityQ* pq); - -int pqInit(PriorityQ* pq); -PQhandle pqInsert(PriorityQ* pq, PQkey key); -PQkey pqExtractMin(PriorityQ* pq); -void pqDelete(PriorityQ* pq, PQhandle handle); - -PQkey pqMinimum(PriorityQ* pq); -int pqIsEmpty(PriorityQ* pq); - -#endif /* __priorityq_sort_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/priorityq.c b/internal/c/parts/core/glues/src/libtess/priorityq.c deleted file mode 100644 index 59d47059c..000000000 --- a/internal/c/parts/core/glues/src/libtess/priorityq.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include /* LONG_MAX */ -#include "memalloc.h" - -/* Include all the code for the regular heap-based queue here. */ - -#include "priorityq-heap.i" - -/* Now redefine all the function names to map to their "Sort" versions. */ - -#include "priorityq-sort.h" - -/* really __gl_pqSortNewPriorityQ */ -PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2)) -{ - PriorityQ* pq=(PriorityQ*)memAlloc(sizeof(PriorityQ)); - if (pq==NULL) - { - return NULL; - } - - pq->heap=__gl_pqHeapNewPriorityQ(leq); - if (pq->heap==NULL) - { - memFree(pq); - return NULL; - } - - pq->keys=(PQHeapKey*)memAlloc(INIT_SIZE*sizeof(pq->keys[0])); - if (pq->keys==NULL) - { - __gl_pqHeapDeletePriorityQ(pq->heap); - memFree(pq); - return NULL; - } - - pq->size=0; - pq->max=INIT_SIZE; - pq->initialized=FALSE; - pq->leq=leq; - - return pq; -} - -/* really __gl_pqSortDeletePriorityQ */ -void pqDeletePriorityQ(PriorityQ* pq) -{ - assert(pq!=NULL); - if (pq->heap!=NULL) - { - __gl_pqHeapDeletePriorityQ(pq->heap); - } - if (pq->order!=NULL) - { - memFree(pq->order); - } - if (pq->keys!=NULL) - { - memFree(pq->keys); - } - memFree(pq); -} - -#define LT(x,y) (!LEQ(y,x)) -#define GT(x,y) (!LEQ(x,y)) -#define Swap(a, b) if(1) { PQkey* tmp=*a; *a=*b; *b=tmp; } else - -/* really __gl_pqSortInit */ -int pqInit(PriorityQ* pq) -{ - PQkey**p, **r, **i, **j, *piv; - struct - { - PQkey** p; - PQkey** r; - } Stack[50], *top=Stack; - unsigned long seed=2016473283; - - /* Create an array of indirect pointers to the keys, so that we - * the handles we have returned are still valid. - */ - /* - pq->order = (PQHeapKey **)memAlloc( (size_t) - (pq->size * sizeof(pq->order[0])) ); - */ - pq->order=(PQHeapKey**)memAlloc((size_t)((pq->size+1)*sizeof(pq->order[0]))); - /* the previous line is a patch to compensate for the fact that IBM */ - /* machines return a null on a malloc of zero bytes (unlike SGI), */ - /* so we have to put in this defense to guard against a memory */ - /* fault four lines down. from fossum@austin.ibm.com. */ - if (pq->order==NULL) - { - return 0; - } - - p=pq->order; - r=p+pq->size-1; - for (piv=pq->keys, i=p; i<=r; ++piv, ++i) - { - *i=piv; - } - - /* Sort the indirect pointers in descending order, - * using randomized Quicksort - */ - top->p=p; top->r=r; ++top; - while (--top>=Stack) - { - p=top->p; - r=top->r; - while (r>p+10) - { - seed=seed*1539415821+1; - i=p+seed%(r-p+1); - piv=*i; - *i=*p; - *p=piv; - i=p-1; - j=r+1; - do { - do { - ++i; - } while(GT(**i, *piv)); - do { - --j; - } while(LT(**j, *piv)); - Swap(i, j); - } while(ip=j+1; - top->r=r; - ++top; - r=i-1; - } - else - { - top->p=p; - top->r=i-1; - ++top; - p=j+1; - } - } - - /* Insertion sort small lists */ - for (i=p+1; i<=r; ++i) - { - piv=*i; - for (j=i; j>p && LT(**(j-1), *piv); --j) - { - *j=*(j-1); - } - *j=piv; - } - } - - pq->max=pq->size; - pq->initialized=TRUE; - __gl_pqHeapInit(pq->heap); /* always succeeds */ - -#ifndef NDEBUG - p=pq->order; - r=p+pq->size-1; - - for (i=p; iinitialized) - { - return __gl_pqHeapInsert(pq->heap, keyNew); - } - - curr=pq->size; - if (++pq->size>=pq->max) - { - PQkey* saveKey=pq->keys; - - /* If the heap overflows, double its size. */ - pq->max<<=1; - pq->keys=(PQHeapKey*)memRealloc(pq->keys, (size_t)(pq->max*sizeof(pq->keys[0]))); - if (pq->keys==NULL) - { - /* restore ptr to free upon return */ - pq->keys=saveKey; - return LONG_MAX; - } - } - assert(curr!=LONG_MAX); - pq->keys[curr]=keyNew; - - /* Negative handles index the sorted array. */ - return -(curr+1); -} - -/* really __gl_pqSortExtractMin */ -PQkey pqExtractMin(PriorityQ* pq) -{ - PQkey sortMin, heapMin; - - if (pq->size==0) - { - return __gl_pqHeapExtractMin(pq->heap); - } - - sortMin=*(pq->order[pq->size-1]); - if (!__gl_pqHeapIsEmpty(pq->heap)) - { - heapMin=__gl_pqHeapMinimum(pq->heap); - if (LEQ(heapMin, sortMin)) - { - return __gl_pqHeapExtractMin(pq->heap); - } - } - do { - --pq->size; - } while(pq->size>0 && *(pq->order[pq->size-1])==NULL); - - return sortMin; -} - -/* really __gl_pqSortMinimum */ -PQkey pqMinimum(PriorityQ* pq) -{ - PQkey sortMin, heapMin; - - if (pq->size==0) - { - return __gl_pqHeapMinimum(pq->heap); - } - - sortMin=*(pq->order[pq->size-1]); - if (!__gl_pqHeapIsEmpty(pq->heap)) - { - heapMin=__gl_pqHeapMinimum(pq->heap); - if (LEQ(heapMin, sortMin)) - { - return heapMin; - } - } - - return sortMin; -} - -/* really __gl_pqSortIsEmpty */ -int pqIsEmpty(PriorityQ* pq) -{ - return (pq->size==0) && __gl_pqHeapIsEmpty(pq->heap); -} - -/* really __gl_pqSortDelete */ -void pqDelete(PriorityQ* pq, PQhandle curr) -{ - if (curr>=0) - { - __gl_pqHeapDelete(pq->heap, curr); - return; - } - - curr=-(curr+1); - assert(currmax && pq->keys[curr]!=NULL); - - pq->keys[curr]=NULL; - - while(pq->size>0 && *(pq->order[pq->size-1])==NULL) - { - --pq->size; - } -} diff --git a/internal/c/parts/core/glues/src/libtess/priorityq.h b/internal/c/parts/core/glues/src/libtess/priorityq.h deleted file mode 100644 index da35d89ce..000000000 --- a/internal/c/parts/core/glues/src/libtess/priorityq.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __priorityq_sort_h_ -#define __priorityq_sort_h_ - -#include "priorityq-heap.h" - -#undef PQkey -#undef PQhandle -#undef PriorityQ -#undef pqNewPriorityQ -#undef pqDeletePriorityQ -#undef pqInit -#undef pqInsert -#undef pqMinimum -#undef pqExtractMin -#undef pqDelete -#undef pqIsEmpty - -/* Use #define's so that another heap implementation can use this one */ - -#define PQkey PQSortKey -#define PQhandle PQSortHandle -#define PriorityQ PriorityQSort - -#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq) -#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq) - -/* The basic operations are insertion of a new key (pqInsert), - * and examination/extraction of a key whose value is minimum - * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete); - * for this purpose pqInsert returns a "handle" which is supplied - * as the argument. - * - * An initial heap may be created efficiently by calling pqInsert - * repeatedly, then calling pqInit. In any case pqInit must be called - * before any operations other than pqInsert are used. - * - * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key. - * This may also be tested with pqIsEmpty. - */ -#define pqInit(pq) __gl_pqSortInit(pq) -#define pqInsert(pq,key) __gl_pqSortInsert(pq,key) -#define pqMinimum(pq) __gl_pqSortMinimum(pq) -#define pqExtractMin(pq) __gl_pqSortExtractMin(pq) -#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle) -#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq) - -/* Since we support deletion the data structure is a little more - * complicated than an ordinary heap. "nodes" is the heap itself; - * active nodes are stored in the range 1..pq->size. When the - * heap exceeds its allocated size (pq->max), its size doubles. - * The children of node i are nodes 2i and 2i+1. - * - * Each node stores an index into an array "handles". Each handle - * stores a key, plus a pointer back to the node which currently - * represents that key (ie. nodes[handles[i].node].handle == i). - */ - -typedef PQHeapKey PQkey; -typedef PQHeapHandle PQhandle; -typedef struct PriorityQ PriorityQ; - -struct PriorityQ -{ - PriorityQHeap* heap; - PQkey* keys; - PQkey** order; - PQhandle size; - PQhandle max; - int initialized; - int (*leq)(PQkey key1, PQkey key2); -}; - -PriorityQ* pqNewPriorityQ(int (*leq)(PQkey key1, PQkey key2)); -void pqDeletePriorityQ(PriorityQ* pq); - -int pqInit( PriorityQ* pq); -PQhandle pqInsert(PriorityQ* pq, PQkey key); -PQkey pqExtractMin(PriorityQ* pq); -void pqDelete(PriorityQ* pq, PQhandle handle); - -PQkey pqMinimum(PriorityQ* pq); -int pqIsEmpty(PriorityQ* pq); - -#endif /* __priorityq_sort_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/render.c b/internal/c/parts/core/glues/src/libtess/render.c deleted file mode 100644 index c0385f943..000000000 --- a/internal/c/parts/core/glues/src/libtess/render.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include "mesh.h" -#include "tess.h" -#include "render.h" - -#define TRUE 1 -#define FALSE 0 - -/* This structure remembers the information we need about a primitive - * to be able to render it later, once we have determined which - * primitive is able to use the most triangles. - */ -struct FaceCount -{ - long size; /* number of triangles used */ - GLUhalfEdge* eStart; /* edge where this primitive starts */ - void (*render)(GLUtesselator*, GLUhalfEdge*, long); - /* routine to render this primitive */ -}; - -static struct FaceCount MaximumFan(GLUhalfEdge* eOrig); -static struct FaceCount MaximumStrip(GLUhalfEdge* eOrig); - -static void RenderFan(GLUtesselator* tess, GLUhalfEdge* eStart, long size); -static void RenderStrip(GLUtesselator* tess, GLUhalfEdge* eStart, long size); -static void RenderTriangle(GLUtesselator* tess, GLUhalfEdge* eStart, long size); - -static void RenderMaximumFaceGroup(GLUtesselator* tess, GLUface* fOrig); -static void RenderLonelyTriangles(GLUtesselator* tess, GLUface* head); - -/************************ Strips and Fans decomposition ******************/ -/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle - * fans, strips, and separate triangles. A substantial effort is made - * to use as few rendering primitives as possible (ie. to make the fans - * and strips as large as possible). - * - * The rendering output is provided as callbacks (see the api). - */ -void __gl_renderMesh(GLUtesselator* tess, GLUmesh* mesh) -{ - GLUface* f; - - /* Make a list of separate triangles so we can render them all at once */ - tess->lonelyTriList=NULL; - - for (f=mesh->fHead.next; f!=&mesh->fHead; f=f->next) - { - f->marked=FALSE; - } - for (f=mesh->fHead.next; f!=&mesh->fHead; f=f->next) - { - /* We examine all faces in an arbitrary order. Whenever we find - * an unprocessed face F, we output a group of faces including F - * whose size is maximum. - */ - if (f->inside && !f->marked) - { - RenderMaximumFaceGroup(tess, f); - assert(f->marked); - } - } - if (tess->lonelyTriList!=NULL) - { - RenderLonelyTriangles(tess, tess->lonelyTriList); - tess->lonelyTriList=NULL; - } -} - -static void RenderMaximumFaceGroup(GLUtesselator* tess, GLUface* fOrig) -{ - /* We want to find the largest triangle fan or strip of unmarked faces - * which includes the given face fOrig. There are 3 possible fans - * passing through fOrig (one centered at each vertex), and 3 possible - * strips (one for each CCW permutation of the vertices). Our strategy - * is to try all of these, and take the primitive which uses the most - * triangles (a greedy approach). - */ - GLUhalfEdge* e=fOrig->anEdge; - struct FaceCount max, newFace; - - max.size=1; - max.eStart=e; - max.render=&RenderTriangle; - - if (!tess->flagBoundary) - { - newFace=MaximumFan(e ); - if (newFace.size>max.size) - { - max=newFace; - } - newFace=MaximumFan(e->Lnext); - if (newFace.size>max.size) - { - max=newFace; - } - newFace=MaximumFan(e->Lprev); - if (newFace.size>max.size) - { - max=newFace; - } - - newFace=MaximumStrip(e); - if (newFace.size>max.size) - { - max=newFace; - } - newFace=MaximumStrip(e->Lnext); - if (newFace.size>max.size) - { - max=newFace; - } - newFace=MaximumStrip(e->Lprev); - if (newFace.size>max.size) - { - max=newFace; - } - } - (*(max.render))(tess, max.eStart, max.size); -} - -/* Macros which keep track of faces we have marked temporarily, and allow - * us to backtrack when necessary. With triangle fans, this is not - * really necessary, since the only awkward case is a loop of triangles - * around a single origin vertex. However with strips the situation is - * more complicated, and we need a general tracking method like the - * one here. - */ -#define Marked(f) (!(f)->inside || (f)->marked) - -#define AddToTrail(f,t) ((f)->trail=(t), (t)=(f), (f)->marked=TRUE) - -#define FreeTrail(t) if (1) \ - { \ - while( (t) != NULL ) \ - { \ - (t)->marked=FALSE; t=(t)->trail; \ - } \ - } else /* absorb trailing semicolon */ - -static struct FaceCount MaximumFan(GLUhalfEdge* eOrig) -{ - /* eOrig->Lface is the face we want to render. We want to find the size - * of a maximal fan around eOrig->Org. To do this we just walk around - * the origin vertex as far as possible in both directions. - */ - struct FaceCount newFace={0, NULL, &RenderFan}; - GLUface* trail=NULL; - GLUhalfEdge* e; - - for (e=eOrig; !Marked(e->Lface); e=e->Onext) - { - AddToTrail(e->Lface, trail); - ++newFace.size; - } - for (e=eOrig; !Marked(e->Rface); e=e->Oprev) - { - AddToTrail( e->Rface, trail); - ++newFace.size; - } - - newFace.eStart=e; - - /*LINTED*/ - FreeTrail(trail); - return newFace; -} - -#define IsEven(n) (((n) & 1)==0) - -static struct FaceCount MaximumStrip(GLUhalfEdge* eOrig) -{ - /* Here we are looking for a maximal strip that contains the vertices - * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the - * reverse, such that all triangles are oriented CCW). - * - * Again we walk forward and backward as far as possible. However for - * strips there is a twist: to get CCW orientations, there must be - * an *even* number of triangles in the strip on one side of eOrig. - * We walk the strip starting on a side with an even number of triangles; - * if both side have an odd number, we are forced to shorten one side. - */ - struct FaceCount newFace={0, NULL, &RenderStrip}; - long headSize=0, tailSize=0; - GLUface* trail=NULL; - GLUhalfEdge* e; - GLUhalfEdge* eTail; - GLUhalfEdge* eHead; - - for (e=eOrig; !Marked(e->Lface); ++tailSize, e=e->Onext) - { - AddToTrail(e->Lface, trail); - ++tailSize; - e=e->Dprev; - if (Marked(e->Lface)) - { - break; - } - AddToTrail(e->Lface, trail); - } - eTail=e; - - for (e=eOrig; !Marked(e->Rface); ++headSize, e=e->Dnext) - { - AddToTrail(e->Rface, trail); - ++headSize; - e=e->Oprev; - - if (Marked(e->Rface)) - { - break; - } - AddToTrail(e->Rface, trail); - } - eHead=e; - - newFace.size=tailSize+headSize; - if (IsEven(tailSize)) - { - newFace.eStart=eTail->Sym; - } - else - { - if (IsEven(headSize)) - { - newFace.eStart=eHead; - } - else - { - /* Both sides have odd length, we must shorten one of them. In fact, - * we must start from eHead to guarantee inclusion of eOrig->Lface. - */ - --newFace.size; - newFace.eStart=eHead->Onext; - } - } - - /*LINTED*/ - FreeTrail(trail); - return newFace; -} - -static void RenderTriangle(GLUtesselator* tess, GLUhalfEdge* e, long size) -{ - /* Just add the triangle to a triangle list, so we can render all - * the separate triangles at once. - */ - assert(size==1); - AddToTrail(e->Lface, tess->lonelyTriList); -} - -static void RenderLonelyTriangles(GLUtesselator* tess, GLUface* f) -{ - /* Now we render all the separate triangles which could not be - * grouped into a triangle fan or strip. - */ - GLUhalfEdge* e; - int newState; - int edgeState=-1; /* force edge state output for first vertex */ - - CALL_BEGIN_OR_BEGIN_DATA(GL_TRIANGLES); - - for (; f!=NULL; f=f->trail) - { - /* Loop once for each edge (there will always be 3 edges) */ - - e=f->anEdge; - do { - if (tess->flagBoundary) - { - /* Set the "edge state" to TRUE just before we output the - * first vertex of each edge on the polygon boundary. - */ - newState=!e->Rface->inside; - if (edgeState!=newState) - { - edgeState=newState; - CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(edgeState); - } - } - CALL_VERTEX_OR_VERTEX_DATA(e->Org->data); - - e=e->Lnext; - } while(e!=f->anEdge); - } - CALL_END_OR_END_DATA(); -} - -static void RenderFan(GLUtesselator* tess, GLUhalfEdge* e, long size) -{ - /* Render as many CCW triangles as possible in a fan starting from - * edge "e". The fan *should* contain exactly "size" triangles - * (otherwise we've goofed up somewhere). - */ - CALL_BEGIN_OR_BEGIN_DATA(GL_TRIANGLE_FAN); - CALL_VERTEX_OR_VERTEX_DATA(e->Org->data); - CALL_VERTEX_OR_VERTEX_DATA(e->Dst->data); - - while(!Marked(e->Lface)) - { - e->Lface->marked=TRUE; - --size; - e=e->Onext; - CALL_VERTEX_OR_VERTEX_DATA(e->Dst->data); - } - - assert(size==0); - CALL_END_OR_END_DATA(); -} - -static void RenderStrip(GLUtesselator* tess, GLUhalfEdge* e, long size) -{ - /* Render as many CCW triangles as possible in a strip starting from - * edge "e". The strip *should* contain exactly "size" triangles - * (otherwise we've goofed up somewhere). - */ - CALL_BEGIN_OR_BEGIN_DATA(GL_TRIANGLE_STRIP); - CALL_VERTEX_OR_VERTEX_DATA(e->Org->data); - CALL_VERTEX_OR_VERTEX_DATA(e->Dst->data); - - while(!Marked(e->Lface)) - { - e->Lface->marked=TRUE; - --size; - e=e->Dprev; - CALL_VERTEX_OR_VERTEX_DATA(e->Org->data); - if (Marked(e->Lface)) - { - break; - } - - e->Lface->marked=TRUE; - --size; - e=e->Onext; - CALL_VERTEX_OR_VERTEX_DATA(e->Dst->data); - } - - assert(size==0); - CALL_END_OR_END_DATA(); -} - -/************************ Boundary contour decomposition ******************/ -/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one - * contour for each face marked "inside". The rendering output is - * provided as callbacks (see the api). - */ -void __gl_renderBoundary(GLUtesselator* tess, GLUmesh* mesh) -{ - GLUface* f; - GLUhalfEdge* e; - - for (f=mesh->fHead.next; f!=&mesh->fHead; f=f->next) - { - if (f->inside) - { - CALL_BEGIN_OR_BEGIN_DATA(GL_LINE_LOOP); - e=f->anEdge; - do { - CALL_VERTEX_OR_VERTEX_DATA(e->Org->data); - e=e->Lnext; - } while(e!=f->anEdge); - CALL_END_OR_END_DATA(); - } - } -} - -/************************ Quick-and-dirty decomposition ******************/ - -#define SIGN_INCONSISTENT 2 - -static int ComputeNormal(GLUtesselator* tess, GLfloat norm[3], int check) -/* - * If check==FALSE, we compute the polygon normal and place it in norm[]. - * If check==TRUE, we check that each triangle in the fan from v0 has a - * consistent orientation with respect to norm[]. If triangles are - * consistently oriented CCW, return 1; if CW, return -1; if all triangles - * are degenerate return 0; otherwise (no consistent orientation) return - * SIGN_INCONSISTENT. - */ -{ - CachedVertex* v0=tess->cache; - CachedVertex* vn=v0+tess->cacheCount; - CachedVertex* vc; - GLfloat dot, xc, yc, zc, xp, yp, zp, n[3]; - int sign=0; - - /* Find the polygon normal. It is important to get a reasonable - * normal even when the polygon is self-intersecting (eg. a bowtie). - * Otherwise, the computed normal could be very tiny, but perpendicular - * to the true plane of the polygon due to numerical noise. Then all - * the triangles would appear to be degenerate and we would incorrectly - * decompose the polygon as a fan (or simply not render it at all). - * - * We use a sum-of-triangles normal algorithm rather than the more - * efficient sum-of-trapezoids method (used in CheckOrientation() - * in normal.c). This lets us explicitly reverse the signed area - * of some triangles to get a reasonable normal in the self-intersecting - * case. - */ - - if (!check) - { - norm[0]=norm[1]=norm[2]=0.0f; - } - - vc=v0+1; - xc=vc->coords[0]-v0->coords[0]; - yc=vc->coords[1]-v0->coords[1]; - zc=vc->coords[2]-v0->coords[2]; - while(++vccoords[0]-v0->coords[0]; - yc=vc->coords[1]-v0->coords[1]; - zc=vc->coords[2]-v0->coords[2]; - - /* Compute (vp-v0) cross (vc-v0) */ - n[0]=yp*zc-zp*yc; - n[1]=zp*xc-xp*zc; - n[2]=xp*yc-yp*xc; - - dot=n[0]*norm[0]+n[1]*norm[1]+n[2]*norm[2]; - if (!check) - { - /* Reverse the contribution of back-facing triangles to get - * a reasonable normal for self-intersecting polygons (see above) - */ - if (dot>=0) - { - norm[0]+=n[0]; norm[1]+=n[1]; norm[2]+=n[2]; - } - else - { - norm[0]-=n[0]; norm[1]-=n[1]; norm[2]-=n[2]; - } - } - else - { - if (dot!=0) - { - /* Check the new orientation for consistency with previous triangles */ - if (dot>0) - { - if (sign<0) - { - return SIGN_INCONSISTENT; - } - sign=1; - } - else - { - if (sign>0) - { - return SIGN_INCONSISTENT; - } - sign=-1; - } - } - } - } - - return sign; -} - -/* __gl_renderCache( tess ) takes a single contour and tries to render it - * as a triangle fan. This handles convex polygons, as well as some - * non-convex polygons if we get lucky. - * - * Returns TRUE if the polygon was successfully rendered. The rendering - * output is provided as callbacks (see the api). - */ -GLboolean __gl_renderCache(GLUtesselator* tess) -{ - CachedVertex* v0=tess->cache; - CachedVertex* vn=v0+tess->cacheCount; - CachedVertex* vc; - GLfloat norm[3]; - int sign; - - if (tess->cacheCount<3) - { - /* Degenerate contour -- no output */ - return TRUE; - } - - norm[0]=tess->normal[0]; - norm[1]=tess->normal[1]; - norm[2]=tess->normal[2]; - if (norm[0]==0 && norm[1]==0 && norm[2]==0) - { - ComputeNormal(tess, norm, FALSE); - } - - sign=ComputeNormal(tess, norm, TRUE); - if (sign==SIGN_INCONSISTENT) - { - /* Fan triangles did not have a consistent orientation */ - return FALSE; - } - if (sign==0) - { - /* All triangles were degenerate */ - return TRUE; - } - - /* Make sure we do the right thing for each winding rule */ - switch(tess->windingRule) - { - case GLU_TESS_WINDING_ODD: - case GLU_TESS_WINDING_NONZERO: - break; - case GLU_TESS_WINDING_POSITIVE: - if (sign<0) - { - return TRUE; - } - break; - case GLU_TESS_WINDING_NEGATIVE: - if (sign>0) - { - return TRUE; - } - break; - case GLU_TESS_WINDING_ABS_GEQ_TWO: - return TRUE; - } - - CALL_BEGIN_OR_BEGIN_DATA(tess->boundaryOnly ? GL_LINE_LOOP : - (tess->cacheCount>3) ? GL_TRIANGLE_FAN : GL_TRIANGLES); - - CALL_VERTEX_OR_VERTEX_DATA(v0->data); - if (sign>0) - { - for (vc=v0+1; vcdata); - } - } - else - { - for (vc=vn-1; vc>v0; --vc) - { - CALL_VERTEX_OR_VERTEX_DATA(vc->data); - } - } - - CALL_END_OR_END_DATA(); - return TRUE; -} diff --git a/internal/c/parts/core/glues/src/libtess/render.h b/internal/c/parts/core/glues/src/libtess/render.h deleted file mode 100644 index 3596ec8c0..000000000 --- a/internal/c/parts/core/glues/src/libtess/render.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __render_h_ -#define __render_h_ - -#include "mesh.h" - -/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle - * fans, strips, and separate triangles. A substantial effort is made - * to use as few rendering primitives as possible (ie. to make the fans - * and strips as large as possible). - * - * The rendering output is provided as callbacks (see the api). - */ -void __gl_renderMesh(GLUtesselator* tess, GLUmesh* mesh); -void __gl_renderBoundary(GLUtesselator* tess, GLUmesh* mesh); - -GLboolean __gl_renderCache(GLUtesselator* tess); - -#endif /* __render_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/sweep.c b/internal/c/parts/core/glues/src/libtess/sweep.c deleted file mode 100644 index 8145aefaf..000000000 --- a/internal/c/parts/core/glues/src/libtess/sweep.c +++ /dev/null @@ -1,1701 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include /* longjmp */ -#include /* LONG_MAX */ - -#include "mesh.h" -#include "geom.h" -#include "tess.h" -#include "dict.h" -#include "priorityq.h" -#include "memalloc.h" -#include "sweep.h" - -#define TRUE 1 -#define FALSE 0 - -#ifdef FOR_TRITE_TEST_PROGRAM - extern void DebugEvent(GLUtesselator* tess); -#else - #define DebugEvent(tess) -#endif - -/* - * Invariants for the Edge Dictionary. - * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2) - * at any valid location of the sweep event - * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2 - * share a common endpoint - * - for each e, e->Dst has been processed, but not e->Org - * - each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org) - * where "event" is the current sweep line event. - * - no edge e has zero length - * - * Invariants for the Mesh (the processed portion). - * - the portion of the mesh left of the sweep line is a planar graph, - * ie. there is *some* way to embed it in the plane - * - no processed edge has zero length - * - no two processed vertices have identical coordinates - * - each "inside" region is monotone, ie. can be broken into two chains - * of monotonically increasing vertices according to VertLeq(v1,v2) - * - a non-invariant: these chains may intersect (very slightly) - * - * Invariants for the Sweep. - * - if none of the edges incident to the event vertex have an activeRegion - * (ie. none of these edges are in the edge dictionary), then the vertex - * has only right-going edges. - * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced - * by ConnectRightVertex), then it is the only right-going edge from - * its associated vertex. (This says that these edges exist only - * when it is necessary.) - */ - -#undef MAX -#undef MIN -#define MAX(x, y) ((x)>=(y) ? (x) : (y)) -#define MIN(x, y) ((x)<=(y) ? (x) : (y)) - -/* When we merge two edges into one, we need to compute the combined - * winding of the new edge. - */ -#define AddWinding(eDst,eSrc) (eDst->winding+=eSrc->winding, \ - eDst->Sym->winding += eSrc->Sym->winding) - -static void SweepEvent(GLUtesselator* tess, GLUvertex* vEvent); -static void WalkDirtyRegions(GLUtesselator* tess, ActiveRegion* regUp); -static int CheckForRightSplice(GLUtesselator* tess, ActiveRegion* regUp); - -/* - * Both edges must be directed from right to left (this is the canonical - * direction for the upper edge of each region). - * - * The strategy is to evaluate a "t" value for each edge at the - * current sweep line position, given by tess->event. The calculations - * are designed to be very stable, but of course they are not perfect. - * - * Special case: if both edge destinations are at the sweep event, - * we sort the edges by slope (they would otherwise compare equally). - */ -static int EdgeLeq(GLUtesselator* tess, ActiveRegion* reg1, ActiveRegion* reg2) -{ - GLUvertex* event=tess->event; - GLUhalfEdge* e1; - GLUhalfEdge* e2; - GLfloat t1, t2; - - e1=reg1->eUp; - e2=reg2->eUp; - - if (e1->Dst==event) - { - if (e2->Dst==event) - { - /* Two edges right of the sweep line which meet at the sweep event. - * Sort them by slope. - */ - if (VertLeq(e1->Org, e2->Org)) - { - return EdgeSign(e2->Dst, e1->Org, e2->Org)<=0; - } - - return EdgeSign(e1->Dst, e2->Org, e1->Org)>=0; - } - return EdgeSign( e2->Dst, event, e2->Org ) <= 0; - } - - if (e2->Dst==event) - { - return EdgeSign(e1->Dst, event, e1->Org)>=0; - } - - /* General case - compute signed distance *from* e1, e2 to event */ - t1=EdgeEval(e1->Dst, event, e1->Org); - t2=EdgeEval(e2->Dst, event, e2->Org); - - return (t1>=t2); -} - -static void DeleteRegion(GLUtesselator* tess, ActiveRegion* reg) -{ - if (reg->fixUpperEdge) - { - /* It was created with zero winding number, so it better be - * deleted with zero winding number (ie. it better not get merged - * with a real edge). - */ - assert(reg->eUp->winding==0); - } - reg->eUp->activeRegion=NULL; - dictDelete(tess->dict, reg->nodeUp); /* __gl_dictListDelete */ - memFree(reg); -} - -/* - * Replace an upper edge which needs fixing (see ConnectRightVertex). - */ -static int FixUpperEdge(ActiveRegion* reg, GLUhalfEdge* newEdge) -{ - assert(reg->fixUpperEdge); - if (!__gl_meshDelete(reg->eUp)) - { - return 0; - } - reg->fixUpperEdge=FALSE; - reg->eUp=newEdge; - newEdge->activeRegion=reg; - - return 1; -} - -static ActiveRegion* TopLeftRegion(ActiveRegion* reg) -{ - GLUvertex* org=reg->eUp->Org; - GLUhalfEdge* e; - - /* Find the region above the uppermost edge with the same origin */ - do { - reg=RegionAbove(reg); - } while(reg->eUp->Org==org); - - /* If the edge above was a temporary edge introduced by ConnectRightVertex, - * now is the time to fix it. - */ - if (reg->fixUpperEdge) - { - e=__gl_meshConnect(RegionBelow(reg)->eUp->Sym, reg->eUp->Lnext); - if (e==NULL) - { - return NULL; - } - if (!FixUpperEdge(reg, e)) - { - return NULL; - } - reg=RegionAbove(reg); - } - return reg; -} - -static ActiveRegion* TopRightRegion(ActiveRegion* reg) -{ - GLUvertex* dst=reg->eUp->Dst; - - /* Find the region above the uppermost edge with the same destination */ - do { - reg=RegionAbove(reg); - } while(reg->eUp->Dst==dst); - - return reg; -} - -/* - * Add a new active region to the sweep line, *somewhere* below "regAbove" - * (according to where the new edge belongs in the sweep-line dictionary). - * The upper edge of the new region will be "eNewUp". - * Winding number and "inside" flag are not updated. - */ -static ActiveRegion* AddRegionBelow(GLUtesselator* tess, ActiveRegion* regAbove, - GLUhalfEdge* eNewUp) -{ - ActiveRegion* regNew=(ActiveRegion*)memAlloc(sizeof(ActiveRegion)); - if (regNew==NULL) - { - longjmp(tess->env, 1); - } - - regNew->eUp=eNewUp; - /* __gl_dictListInsertBefore */ - regNew->nodeUp=dictInsertBefore(tess->dict, regAbove->nodeUp, regNew); - if (regNew->nodeUp==NULL) - { - longjmp(tess->env, 1); - } - regNew->fixUpperEdge=FALSE; - regNew->sentinel=FALSE; - regNew->dirty=FALSE; - - eNewUp->activeRegion=regNew; - - return regNew; -} - -static GLboolean IsWindingInside(GLUtesselator* tess, int n) -{ - switch (tess->windingRule) - { - case GLU_TESS_WINDING_ODD: - return (n&1); - case GLU_TESS_WINDING_NONZERO: - return (n!=0); - case GLU_TESS_WINDING_POSITIVE: - return (n>0); - case GLU_TESS_WINDING_NEGATIVE: - return (n<0); - case GLU_TESS_WINDING_ABS_GEQ_TWO: - return (n>=2) || (n<=-2); - } - - /*LINTED*/ - assert(FALSE); - - /*NOTREACHED*/ - /* avoid compiler complaints */ - return GL_FALSE; -} - -static void ComputeWinding(GLUtesselator* tess, ActiveRegion* reg) -{ - reg->windingNumber=RegionAbove(reg)->windingNumber+reg->eUp->winding; - reg->inside=IsWindingInside(tess, reg->windingNumber); -} - -/* - * Delete a region from the sweep line. This happens when the upper - * and lower chains of a region meet (at a vertex on the sweep line). - * The "inside" flag is copied to the appropriate mesh face (we could - * not do this before -- since the structure of the mesh is always - * changing, this face may not have even existed until now). - */ -static void FinishRegion(GLUtesselator* tess, ActiveRegion* reg) -{ - GLUhalfEdge* e=reg->eUp; - GLUface* f=e->Lface; - - f->inside=reg->inside; - /* optimization for __gl_meshTessellateMonoRegion() */ - f->anEdge=e; - DeleteRegion(tess, reg); -} - -/* - * We are given a vertex with one or more left-going edges. All affected - * edges should be in the edge dictionary. Starting at regFirst->eUp, - * we walk down deleting all regions where both edges have the same - * origin vOrg. At the same time we copy the "inside" flag from the - * active region to the face, since at this point each face will belong - * to at most one region (this was not necessarily true until this point - * in the sweep). The walk stops at the region above regLast; if regLast - * is NULL we walk as far as possible. At the same time we relink the - * mesh if necessary, so that the ordering of edges around vOrg is the - * same as in the dictionary. - */ -static GLUhalfEdge* FinishLeftRegions(GLUtesselator* tess, ActiveRegion* regFirst, - ActiveRegion* regLast) -{ - ActiveRegion* reg; - ActiveRegion* regPrev; - GLUhalfEdge* e; - GLUhalfEdge* ePrev; - - regPrev=regFirst; - ePrev=regFirst->eUp; - while (regPrev!=regLast) - { - /* placement was OK */ - regPrev->fixUpperEdge=FALSE; - reg=RegionBelow(regPrev); - e=reg->eUp; - if (e->Org!=ePrev->Org) - { - if (!reg->fixUpperEdge) - { - /* Remove the last left-going edge. Even though there are no further - * edges in the dictionary with this origin, there may be further - * such edges in the mesh (if we are adding left edges to a vertex - * that has already been processed). Thus it is important to call - * FinishRegion rather than just DeleteRegion. - */ - FinishRegion(tess, regPrev); - break; - } - - /* If the edge below was a temporary edge introduced by - * ConnectRightVertex, now is the time to fix it. - */ - e=__gl_meshConnect(ePrev->Lprev, e->Sym); - if (e==NULL) - { - longjmp(tess->env, 1); - } - if (!FixUpperEdge(reg, e)) - { - longjmp(tess->env, 1); - } - } - - /* Relink edges so that ePrev->Onext == e */ - if (ePrev->Onext!=e) - { - if (!__gl_meshSplice(e->Oprev, e)) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(ePrev, e)) - { - longjmp(tess->env, 1); - } - } - - /* may change reg->eUp */ - FinishRegion(tess, regPrev); - ePrev=reg->eUp; - regPrev=reg; - } - - return ePrev; -} - -/* - * Purpose: insert right-going edges into the edge dictionary, and update - * winding numbers and mesh connectivity appropriately. All right-going - * edges share a common origin vOrg. Edges are inserted CCW starting at - * eFirst; the last edge inserted is eLast->Oprev. If vOrg has any - * left-going edges already processed, then eTopLeft must be the edge - * such that an imaginary upward vertical segment from vOrg would be - * contained between eTopLeft->Oprev and eTopLeft; otherwise eTopLeft - * should be NULL. - */ -static void AddRightEdges(GLUtesselator* tess, ActiveRegion* regUp, - GLUhalfEdge* eFirst, GLUhalfEdge* eLast, GLUhalfEdge* eTopLeft, - GLboolean cleanUp) -{ - ActiveRegion* reg; - ActiveRegion* regPrev; - GLUhalfEdge* e; - GLUhalfEdge* ePrev; - int firstTime=TRUE; - - /* Insert the new right-going edges in the dictionary */ - e=eFirst; - do { - assert(VertLeq(e->Org, e->Dst)); - AddRegionBelow(tess, regUp, e->Sym); - e=e->Onext; - } while (e!=eLast); - - /* Walk *all* right-going edges from e->Org, in the dictionary order, - * updating the winding numbers of each region, and re-linking the mesh - * edges to match the dictionary ordering (if necessary). - */ - if (eTopLeft==NULL) - { - eTopLeft=RegionBelow(regUp)->eUp->Rprev; - } - regPrev=regUp; - ePrev=eTopLeft; - - for (;;) - { - reg=RegionBelow(regPrev); - e=reg->eUp->Sym; - if (e->Org!=ePrev->Org) - { - break; - } - - if (e->Onext!=ePrev) - { - /* Unlink e from its current position, and relink below ePrev */ - if (!__gl_meshSplice(e->Oprev, e)) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(ePrev->Oprev, e)) - { - longjmp(tess->env, 1); - } - } - - /* Compute the winding number and "inside" flag for the new regions */ - reg->windingNumber=regPrev->windingNumber-e->winding; - reg->inside=IsWindingInside(tess,reg->windingNumber); - - /* Check for two outgoing edges with same slope -- process these - * before any intersection tests (see example in __gl_computeInterior). - */ - regPrev->dirty=TRUE; - if (!firstTime && CheckForRightSplice(tess, regPrev)) - { - AddWinding(e, ePrev); - DeleteRegion(tess, regPrev); - if (!__gl_meshDelete(ePrev)) - { - longjmp(tess->env, 1); - } - } - firstTime=FALSE; - regPrev=reg; - ePrev=e; - } - regPrev->dirty=TRUE; - assert(regPrev->windingNumber-e->winding==reg->windingNumber); - - if (cleanUp) - { - /* Check for intersections between newly adjacent edges. */ - WalkDirtyRegions(tess, regPrev); - } -} - -static void CallCombine(GLUtesselator* tess, GLUvertex* isect, - void* data[4], GLfloat weights[4], int needed) -{ - GLfloat coords[3]; - - /* Copy coord data in case the callback changes it. */ - coords[0]=isect->coords[0]; - coords[1]=isect->coords[1]; - coords[2]=isect->coords[2]; - - isect->data=NULL; - CALL_COMBINE_OR_COMBINE_DATA(coords, data, weights, &isect->data); - - if (isect->data==NULL) - { - if (!needed) - { - isect->data=data[0]; - } - else - { - if (!tess->fatalError) - { - /* The only way fatal error is when two edges are found to intersect, - * but the user has not provided the callback necessary to handle - * generated intersection points. - */ - CALL_ERROR_OR_ERROR_DATA(GLU_TESS_NEED_COMBINE_CALLBACK); - tess->fatalError=TRUE; - } - } - } -} - -/* - * Two vertices with idential coordinates are combined into one. - * e1->Org is kept, while e2->Org is discarded. - */ -static void SpliceMergeVertices(GLUtesselator* tess, GLUhalfEdge *e1, GLUhalfEdge* e2) -{ - void* data[4]={NULL, NULL, NULL, NULL}; - GLfloat weights[4]={0.5f, 0.5f, 0.0f, 0.0f}; - - data[0]=e1->Org->data; - data[1]=e2->Org->data; - CallCombine(tess, e1->Org, data, weights, FALSE); - if (!__gl_meshSplice(e1, e2)) - { - longjmp(tess->env, 1); - } -} - -/* - * Find some weights which describe how the intersection vertex is - * a linear combination of "org" and "dest". Each of the two edges - * which generated "isect" is allocated 50% of the weight; each edge - * splits the weight between its org and dst according to the - * relative distance to "isect". - */ -static void VertexWeights(GLUvertex* isect, GLUvertex* org, GLUvertex* dst, - GLfloat* weights) -{ - GLfloat t1=VertL1dist(org, isect); - GLfloat t2=VertL1dist(dst, isect); - - weights[0]=0.5f*t2/(t1+t2); - weights[1]=0.5f*t1/(t1+t2); - isect->coords[0]+=weights[0]*org->coords[0]+weights[1]*dst->coords[0]; - isect->coords[1]+=weights[0]*org->coords[1]+weights[1]*dst->coords[1]; - isect->coords[2]+=weights[0]*org->coords[2]+weights[1]*dst->coords[2]; -} - -/* - * We've computed a new intersection point, now we need a "data" pointer - * from the user so that we can refer to this new vertex in the - * rendering callbacks. - */ -static void GetIntersectData(GLUtesselator* tess, GLUvertex* isect, - GLUvertex* orgUp, GLUvertex* dstUp, - GLUvertex* orgLo, GLUvertex* dstLo) -{ - void* data[4]; - GLfloat weights[4]; - - data[0]=orgUp->data; - data[1]=dstUp->data; - data[2]=orgLo->data; - data[3]=dstLo->data; - - isect->coords[0]=isect->coords[1]=isect->coords[2]=0; - VertexWeights(isect, orgUp, dstUp, &weights[0]); - VertexWeights(isect, orgLo, dstLo, &weights[2]); - - CallCombine(tess, isect, data, weights, TRUE); -} - -/* - * Check the upper and lower edge of "regUp", to make sure that the - * eUp->Org is above eLo, or eLo->Org is below eUp (depending on which - * origin is leftmost). - * - * The main purpose is to splice right-going edges with the same - * dest vertex and nearly identical slopes (ie. we can't distinguish - * the slopes numerically). However the splicing can also help us - * to recover from numerical errors. For example, suppose at one - * point we checked eUp and eLo, and decided that eUp->Org is barely - * above eLo. Then later, we split eLo into two edges (eg. from - * a splice operation like this one). This can change the result of - * our test so that now eUp->Org is incident to eLo, or barely below it. - * We must correct this condition to maintain the dictionary invariants. - * - * One possibility is to check these edges for intersection again - * (ie. CheckForIntersect). This is what we do if possible. However - * CheckForIntersect requires that tess->event lies between eUp and eLo, - * so that it has something to fall back on when the intersection - * calculation gives us an unusable answer. So, for those cases where - * we can't check for intersection, this routine fixes the problem - * by just splicing the offending vertex into the other edge. - * This is a guaranteed solution, no matter how degenerate things get. - * Basically this is a combinatorial solution to a numerical problem. - */ -static int CheckForRightSplice(GLUtesselator* tess, ActiveRegion* regUp) -{ - ActiveRegion* regLo=RegionBelow(regUp); - GLUhalfEdge* eUp=regUp->eUp; - GLUhalfEdge* eLo=regLo->eUp; - - if (VertLeq(eUp->Org, eLo->Org)) - { - if (EdgeSign(eLo->Dst, eUp->Org, eLo->Org)>0) - { - return FALSE; - } - - /* eUp->Org appears to be below eLo */ - if (!VertEq(eUp->Org, eLo->Org)) - { - /* Splice eUp->Org into eLo */ - if ( __gl_meshSplitEdge(eLo->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eUp, eLo->Oprev)) - { - longjmp(tess->env, 1); - } - regUp->dirty=regLo->dirty=TRUE; - } - else - { - if (eUp->Org!=eLo->Org) - { - /* merge the two vertices, discarding eUp->Org */ - pqDelete(tess->pq, eUp->Org->pqHandle); /* __gl_pqSortDelete */ - SpliceMergeVertices(tess, eLo->Oprev, eUp); - } - } - } - else - { - if (EdgeSign(eUp->Dst, eLo->Org, eUp->Org)<0) - { - return FALSE; - } - - /* eLo->Org appears to be above eUp, so splice eLo->Org into eUp */ - RegionAbove(regUp)->dirty=regUp->dirty=TRUE; - if (__gl_meshSplitEdge(eUp->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eLo->Oprev, eUp)) - { - longjmp(tess->env, 1); - } - } - - return TRUE; -} - -/* - * Check the upper and lower edge of "regUp", to make sure that the - * eUp->Dst is above eLo, or eLo->Dst is below eUp (depending on which - * destination is rightmost). - * - * Theoretically, this should always be true. However, splitting an edge - * into two pieces can change the results of previous tests. For example, - * suppose at one point we checked eUp and eLo, and decided that eUp->Dst - * is barely above eLo. Then later, we split eLo into two edges (eg. from - * a splice operation like this one). This can change the result of - * the test so that now eUp->Dst is incident to eLo, or barely below it. - * We must correct this condition to maintain the dictionary invariants - * (otherwise new edges might get inserted in the wrong place in the - * dictionary, and bad stuff will happen). - * - * We fix the problem by just splicing the offending vertex into the - * other edge. - */ -static int CheckForLeftSplice(GLUtesselator* tess, ActiveRegion* regUp) -{ - ActiveRegion* regLo=RegionBelow(regUp); - GLUhalfEdge* eUp=regUp->eUp; - GLUhalfEdge* eLo=regLo->eUp; - GLUhalfEdge* e; - - assert(!VertEq(eUp->Dst, eLo->Dst)); - - if (VertLeq(eUp->Dst, eLo->Dst)) - { - if (EdgeSign(eUp->Dst, eLo->Dst, eUp->Org)<0) - { - return FALSE; - } - - /* eLo->Dst is above eUp, so splice eLo->Dst into eUp */ - RegionAbove(regUp)->dirty=regUp->dirty=TRUE; - e=__gl_meshSplitEdge(eUp); - if (e==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eLo->Sym, e)) - { - longjmp(tess->env, 1); - } - e->Lface->inside = regUp->inside; - } - else - { - if (EdgeSign(eLo->Dst, eUp->Dst, eLo->Org)>0) - { - return FALSE; - } - - /* eUp->Dst is below eLo, so splice eUp->Dst into eLo */ - regUp->dirty=regLo->dirty=TRUE; - e=__gl_meshSplitEdge(eLo); - if (e==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eUp->Lnext, eLo->Sym)) - { - longjmp(tess->env, 1); - } - e->Rface->inside=regUp->inside; - } - - return TRUE; -} - -/* - * Check the upper and lower edges of the given region to see if - * they intersect. If so, create the intersection and add it - * to the data structures. - * - * Returns TRUE if adding the new intersection resulted in a recursive - * call to AddRightEdges(); in this case all "dirty" regions have been - * checked for intersections, and possibly regUp has been deleted. - */ -static int CheckForIntersect(GLUtesselator* tess, ActiveRegion* regUp) -{ - ActiveRegion* regLo=RegionBelow(regUp); - GLUhalfEdge* eUp=regUp->eUp; - GLUhalfEdge* eLo=regLo->eUp; - GLUvertex* orgUp=eUp->Org; - GLUvertex* orgLo=eLo->Org; - GLUvertex* dstUp=eUp->Dst; - GLUvertex* dstLo=eLo->Dst; - GLfloat tMinUp, tMaxLo; - GLUvertex isect; - GLUvertex* orgMin; - GLUhalfEdge* e; - - assert(!VertEq(dstLo, dstUp)); - assert(EdgeSign(dstUp, tess->event, orgUp)<=0); - assert(EdgeSign(dstLo, tess->event, orgLo)>=0); - assert(orgUp!=tess->event && orgLo!=tess->event); - assert(!regUp->fixUpperEdge && !regLo->fixUpperEdge); - - if (orgUp==orgLo) - { - /* right endpoints are the same */ - return FALSE; - } - - tMinUp=MIN(orgUp->t, dstUp->t); - tMaxLo=MAX(orgLo->t, dstLo->t); - if (tMinUp>tMaxLo) - { - /* t ranges do not overlap */ - return FALSE; - } - - if (VertLeq(orgUp, orgLo)) - { - if (EdgeSign(dstLo, orgUp, orgLo)>0) - { - return FALSE; - } - } - else - { - if (EdgeSign(dstUp, orgLo, orgUp)<0) - { - return FALSE; - } - } - - /* At this point the edges intersect, at least marginally */ - DebugEvent(tess); - - __gl_edgeIntersect(dstUp, orgUp, dstLo, orgLo, &isect); - /* The following properties are guaranteed: */ - assert(MIN(orgUp->t, dstUp->t)<=isect.t); - assert(isect.t<=MAX(orgLo->t, dstLo->t)); - assert(MIN(dstLo->s, dstUp->s)<=isect.s); - assert(isect.s<=MAX(orgLo->s, orgUp->s)); - - if (VertLeq(&isect, tess->event)) - { - /* The intersection point lies slightly to the left of the sweep line, - * so move it until it''s slightly to the right of the sweep line. - * (If we had perfect numerical precision, this would never happen - * in the first place). The easiest and safest thing to do is - * replace the intersection by tess->event. - */ - isect.s=tess->event->s; - isect.t=tess->event->t; - } - - /* Similarly, if the computed intersection lies to the right of the - * rightmost origin (which should rarely happen), it can cause - * unbelievable inefficiency on sufficiently degenerate inputs. - * (If you have the test program, try running test54.d with the - * "X zoom" option turned on). - */ - orgMin=VertLeq(orgUp, orgLo) ? orgUp : orgLo; - if (VertLeq(orgMin, &isect)) - { - isect.s=orgMin->s; - isect.t=orgMin->t; - } - - if (VertEq(&isect, orgUp) || VertEq(&isect, orgLo)) - { - /* Easy case -- intersection at one of the right endpoints */ - (void) CheckForRightSplice(tess, regUp); - return FALSE; - } - - if ((!VertEq( dstUp, tess->event) && EdgeSign(dstUp, tess->event, &isect)>=0) - || (!VertEq(dstLo, tess->event) && EdgeSign(dstLo, tess->event, &isect)<= 0)) - { - /* Very unusual -- the new upper or lower edge would pass on the - * wrong side of the sweep event, or through it. This can happen - * due to very small numerical errors in the intersection calculation. - */ - if (dstLo==tess->event) - { - /* Splice dstLo into eUp, and process the new region(s) */ - if (__gl_meshSplitEdge(eUp->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eLo->Sym, eUp)) - { - longjmp(tess->env, 1); - } - regUp=TopLeftRegion(regUp); - if (regUp==NULL) - { - longjmp(tess->env, 1); - } - eUp=RegionBelow(regUp)->eUp; - FinishLeftRegions(tess, RegionBelow(regUp), regLo); - AddRightEdges(tess, regUp, eUp->Oprev, eUp, eUp, TRUE); - return TRUE; - } - - if (dstUp==tess->event) - { - /* Splice dstUp into eLo, and process the new region(s) */ - if (__gl_meshSplitEdge(eLo->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eUp->Lnext, eLo->Oprev)) - { - longjmp(tess->env, 1); - } - regLo=regUp; - regUp=TopRightRegion(regUp); - e=RegionBelow(regUp)->eUp->Rprev; - regLo->eUp=eLo->Oprev; - eLo=FinishLeftRegions(tess, regLo, NULL); - AddRightEdges(tess, regUp, eLo->Onext, eUp->Rprev, e, TRUE); - - return TRUE; - } - - /* Special case: called from ConnectRightVertex. If either - * edge passes on the wrong side of tess->event, split it - * (and wait for ConnectRightVertex to splice it appropriately). - */ - if (EdgeSign(dstUp, tess->event, &isect)>=0) - { - RegionAbove(regUp)->dirty=regUp->dirty=TRUE; - if (__gl_meshSplitEdge(eUp->Sym)==NULL) - { - longjmp(tess->env, 1); - } - eUp->Org->s=tess->event->s; - eUp->Org->t=tess->event->t; - } - - if (EdgeSign(dstLo, tess->event, &isect)<=0) - { - regUp->dirty=regLo->dirty=TRUE; - if (__gl_meshSplitEdge(eLo->Sym)==NULL) - { - longjmp(tess->env, 1); - } - eLo->Org->s=tess->event->s; - eLo->Org->t=tess->event->t; - } - - /* leave the rest for ConnectRightVertex */ - return FALSE; - } - - /* General case -- split both edges, splice into new vertex. - * When we do the splice operation, the order of the arguments is - * arbitrary as far as correctness goes. However, when the operation - * creates a new face, the work done is proportional to the size of - * the new face. We expect the faces in the processed part of - * the mesh (ie. eUp->Lface) to be smaller than the faces in the - * unprocessed original contours (which will be eLo->Oprev->Lface). - */ - if (__gl_meshSplitEdge(eUp->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (__gl_meshSplitEdge(eLo->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (!__gl_meshSplice(eLo->Oprev, eUp)) - { - longjmp(tess->env, 1); - } - eUp->Org->s=isect.s; - eUp->Org->t=isect.t; - - eUp->Org->pqHandle=pqInsert(tess->pq, eUp->Org); /* __gl_pqSortInsert */ - if (eUp->Org->pqHandle==LONG_MAX) - { - pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */ - tess->pq=NULL; - longjmp(tess->env, 1); - } - GetIntersectData(tess, eUp->Org, orgUp, dstUp, orgLo, dstLo); - RegionAbove(regUp)->dirty=regUp->dirty=regLo->dirty=TRUE; - - return FALSE; -} - -/* - * When the upper or lower edge of any region changes, the region is - * marked "dirty". This routine walks through all the dirty regions - * and makes sure that the dictionary invariants are satisfied - * (see the comments at the beginning of this file). Of course - * new dirty regions can be created as we make changes to restore - * the invariants. - */ -static void WalkDirtyRegions(GLUtesselator* tess, ActiveRegion* regUp) -{ - ActiveRegion* regLo=RegionBelow(regUp); - GLUhalfEdge* eUp; - GLUhalfEdge* eLo; - - for(;;) - { - /* Find the lowest dirty region (we walk from the bottom up). */ - while (regLo->dirty) - { - regUp=regLo; - regLo=RegionBelow(regLo); - } - if (!regUp->dirty) - { - regLo=regUp; - regUp=RegionAbove(regUp); - if (regUp==NULL || !regUp->dirty) - { - /* We've walked all the dirty regions */ - return; - } - } - regUp->dirty=FALSE; - eUp=regUp->eUp; - eLo=regLo->eUp; - - if (eUp->Dst!=eLo->Dst) - { - /* Check that the edge ordering is obeyed at the Dst vertices. */ - if (CheckForLeftSplice(tess, regUp)) - { - /* If the upper or lower edge was marked fixUpperEdge, then - * we no longer need it (since these edges are needed only for - * vertices which otherwise have no right-going edges). - */ - if (regLo->fixUpperEdge) - { - DeleteRegion(tess, regLo); - if (!__gl_meshDelete(eLo)) - { - longjmp(tess->env, 1); - } - regLo=RegionBelow(regUp); - eLo=regLo->eUp; - } - else - { - if (regUp->fixUpperEdge) - { - DeleteRegion(tess, regUp); - if (!__gl_meshDelete(eUp)) - { - longjmp(tess->env, 1); - } - regUp=RegionAbove(regLo); - eUp=regUp->eUp; - } - } - } - } - - if (eUp->Org != eLo->Org) - { - if (eUp->Dst != eLo->Dst && !regUp->fixUpperEdge && - !regLo->fixUpperEdge && (eUp->Dst==tess->event || - eLo->Dst==tess->event)) - { - /* When all else fails in CheckForIntersect(), it uses tess->event - * as the intersection location. To make this possible, it requires - * that tess->event lie between the upper and lower edges, and also - * that neither of these is marked fixUpperEdge (since in the worst - * case it might splice one of these edges into tess->event, and - * violate the invariant that fixable edges are the only right-going - * edge from their associated vertex). - */ - if (CheckForIntersect(tess, regUp)) - { - /* WalkDirtyRegions() was called recursively; we're done */ - return; - } - } - else - { - /* Even though we can't use CheckForIntersect(), the Org vertices - * may violate the dictionary edge ordering. Check and correct this. - */ - (void) CheckForRightSplice(tess, regUp); - } - } - - if (eUp->Org==eLo->Org && eUp->Dst==eLo->Dst) - { - /* A degenerate loop consisting of only two edges -- delete it. */ - AddWinding(eLo, eUp); - DeleteRegion(tess, regUp); - if (!__gl_meshDelete(eUp)) - { - longjmp(tess->env, 1); - } - regUp=RegionAbove(regLo); - } - } -} - -/* - * Purpose: connect a "right" vertex vEvent (one where all edges go left) - * to the unprocessed portion of the mesh. Since there are no right-going - * edges, two regions (one above vEvent and one below) are being merged - * into one. "regUp" is the upper of these two regions. - * - * There are two reasons for doing this (adding a right-going edge): - * - if the two regions being merged are "inside", we must add an edge - * to keep them separated (the combined region would not be monotone). - * - in any case, we must leave some record of vEvent in the dictionary, - * so that we can merge vEvent with features that we have not seen yet. - * For example, maybe there is a vertical edge which passes just to - * the right of vEvent; we would like to splice vEvent into this edge. - * - * However, we don't want to connect vEvent to just any vertex. We don''t - * want the new edge to cross any other edges; otherwise we will create - * intersection vertices even when the input data had no self-intersections. - * (This is a bad thing; if the user's input data has no intersections, - * we don't want to generate any false intersections ourselves.) - * - * Our eventual goal is to connect vEvent to the leftmost unprocessed - * vertex of the combined region (the union of regUp and regLo). - * But because of unseen vertices with all right-going edges, and also - * new vertices which may be created by edge intersections, we don''t - * know where that leftmost unprocessed vertex is. In the meantime, we - * connect vEvent to the closest vertex of either chain, and mark the region - * as "fixUpperEdge". This flag says to delete and reconnect this edge - * to the next processed vertex on the boundary of the combined region. - * Quite possibly the vertex we connected to will turn out to be the - * closest one, in which case we won''t need to make any changes. - */ -static void ConnectRightVertex(GLUtesselator* tess, ActiveRegion* regUp, - GLUhalfEdge* eBottomLeft) -{ - GLUhalfEdge* eNew; - GLUhalfEdge* eTopLeft=eBottomLeft->Onext; - ActiveRegion* regLo=RegionBelow(regUp); - GLUhalfEdge* eUp=regUp->eUp; - GLUhalfEdge* eLo=regLo->eUp; - int degenerate=FALSE; - - if (eUp->Dst!=eLo->Dst) - { - (void)CheckForIntersect(tess, regUp); - } - - /* Possible new degeneracies: upper or lower edge of regUp may pass - * through vEvent, or may coincide with new intersection vertex - */ - if (VertEq(eUp->Org, tess->event)) - { - if (!__gl_meshSplice(eTopLeft->Oprev, eUp)) - { - longjmp(tess->env, 1); - } - regUp=TopLeftRegion(regUp); - if (regUp==NULL) - { - longjmp(tess->env, 1); - } - eTopLeft=RegionBelow(regUp)->eUp; - FinishLeftRegions(tess, RegionBelow(regUp), regLo); - degenerate=TRUE; - } - - if (VertEq(eLo->Org, tess->event)) - { - if (!__gl_meshSplice(eBottomLeft, eLo->Oprev)) - { - longjmp(tess->env, 1); - } - eBottomLeft=FinishLeftRegions(tess, regLo, NULL); - degenerate=TRUE; - } - - if (degenerate) - { - AddRightEdges(tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE); - return; - } - - /* Non-degenerate situation -- need to add a temporary, fixable edge. - * Connect to the closer of eLo->Org, eUp->Org. - */ - if (VertLeq(eLo->Org, eUp->Org)) - { - eNew=eLo->Oprev; - } - else - { - eNew = eUp; - } - eNew=__gl_meshConnect(eBottomLeft->Lprev, eNew); - if (eNew==NULL) - { - longjmp(tess->env, 1); - } - - /* Prevent cleanup, otherwise eNew might disappear before we've even - * had a chance to mark it as a temporary edge. - */ - AddRightEdges(tess, regUp, eNew, eNew->Onext, eNew->Onext, FALSE); - eNew->Sym->activeRegion->fixUpperEdge=TRUE; - WalkDirtyRegions(tess, regUp); -} - -/* Because vertices at exactly the same location are merged together - * before we process the sweep event, some degenerate cases can't occur. - * However if someone eventually makes the modifications required to - * merge features which are close together, the cases below marked - * TOLERANCE_NONZERO will be useful. They were debugged before the - * code to merge identical vertices in the main loop was added. - */ -#define TOLERANCE_NONZERO FALSE - -/* - * The event vertex lies exacty on an already-processed edge or vertex. - * Adding the new vertex involves splicing it into the already-processed - * part of the mesh. - */ -static void ConnectLeftDegenerate(GLUtesselator* tess, - ActiveRegion* regUp, GLUvertex* vEvent) -{ - GLUhalfEdge* e; - GLUhalfEdge* eTopLeft; - GLUhalfEdge* eTopRight; - GLUhalfEdge* eLast; - ActiveRegion* reg; - - e=regUp->eUp; - if (VertEq(e->Org, vEvent)) - { - /* e->Org is an unprocessed vertex - just combine them, and wait - * for e->Org to be pulled from the queue - */ - assert(TOLERANCE_NONZERO); - SpliceMergeVertices(tess, e, vEvent->anEdge); - return; - } - - if (!VertEq(e->Dst, vEvent)) - { - /* General case -- splice vEvent into edge e which passes through it */ - if (__gl_meshSplitEdge(e->Sym)==NULL) - { - longjmp(tess->env, 1); - } - if (regUp->fixUpperEdge) - { - /* This edge was fixable -- delete unused portion of original edge */ - if (!__gl_meshDelete(e->Onext)) - { - longjmp(tess->env, 1); - } - regUp->fixUpperEdge=FALSE; - } - if (!__gl_meshSplice(vEvent->anEdge, e)) - { - longjmp(tess->env, 1); - } - SweepEvent(tess, vEvent); /* recurse */ - return; - } - - /* vEvent coincides with e->Dst, which has already been processed. - * Splice in the additional right-going edges. - */ - assert(TOLERANCE_NONZERO); - regUp=TopRightRegion(regUp); - reg=RegionBelow(regUp); - eTopRight=reg->eUp->Sym; - eTopLeft=eLast=eTopRight->Onext; - if (reg->fixUpperEdge) - { - /* Here e->Dst has only a single fixable edge going right. - * We can delete it since now we have some real right-going edges. - */ - assert(eTopLeft!=eTopRight); /* there are some left edges too */ - DeleteRegion(tess, reg); - if (!__gl_meshDelete(eTopRight)) - { - longjmp(tess->env, 1); - } - eTopRight=eTopLeft->Oprev; - } - if (!__gl_meshSplice(vEvent->anEdge, eTopRight)) - { - longjmp(tess->env, 1); - } - if(!EdgeGoesLeft(eTopLeft)) - { - /* e->Dst had no left-going edges -- indicate this to AddRightEdges() */ - eTopLeft=NULL; - } - AddRightEdges(tess, regUp, eTopRight->Onext, eLast, eTopLeft, TRUE); -} - -/* - * Purpose: connect a "left" vertex (one where both edges go right) - * to the processed portion of the mesh. Let R be the active region - * containing vEvent, and let U and L be the upper and lower edge - * chains of R. There are two possibilities: - * - * - the normal case: split R into two regions, by connecting vEvent to - * the rightmost vertex of U or L lying to the left of the sweep line - * - * - the degenerate case: if vEvent is close enough to U or L, we - * merge vEvent into that edge chain. The subcases are: - * - merging with the rightmost vertex of U or L - * - merging with the active edge of U or L - * - merging with an already-processed portion of U or L - */ -static void ConnectLeftVertex(GLUtesselator* tess, GLUvertex* vEvent) -{ - ActiveRegion* regUp; - ActiveRegion* regLo; - ActiveRegion* reg; - GLUhalfEdge* eUp; - GLUhalfEdge* eLo; - GLUhalfEdge* eNew; - ActiveRegion tmp; - - /* Get a pointer to the active region containing vEvent */ - tmp.eUp=vEvent->anEdge->Sym; - /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */ - regUp=(ActiveRegion*)dictKey(dictSearch(tess->dict, &tmp)); - regLo=RegionBelow(regUp); - eUp=regUp->eUp; - eLo=regLo->eUp; - - /* Try merging with U or L first */ - if (EdgeSign(eUp->Dst, vEvent, eUp->Org)==0) - { - ConnectLeftDegenerate(tess, regUp, vEvent); - return; - } - - /* Connect vEvent to rightmost processed vertex of either chain. - * e->Dst is the vertex that we will connect to vEvent. - */ - reg=VertLeq(eLo->Dst, eUp->Dst) ? regUp : regLo; - - if (regUp->inside || reg->fixUpperEdge) - { - if (reg==regUp) - { - eNew=__gl_meshConnect(vEvent->anEdge->Sym, eUp->Lnext); - if (eNew==NULL) - { - longjmp(tess->env, 1); - } - } - else - { - GLUhalfEdge* tempHalfEdge=__gl_meshConnect(eLo->Dnext, vEvent->anEdge); - if (tempHalfEdge==NULL) - { - longjmp(tess->env, 1); - } - - eNew=tempHalfEdge->Sym; - } - if (reg->fixUpperEdge) - { - if (!FixUpperEdge(reg, eNew)) - { - longjmp(tess->env, 1); - } - } - else - { - ComputeWinding(tess, AddRegionBelow(tess, regUp, eNew)); - } - SweepEvent(tess, vEvent); - } - else - { - /* The new vertex is in a region which does not belong to the polygon. - * We don''t need to connect this vertex to the rest of the mesh. - */ - AddRightEdges(tess, regUp, vEvent->anEdge, vEvent->anEdge, NULL, TRUE); - } -} - -/* - * Does everything necessary when the sweep line crosses a vertex. - * Updates the mesh and the edge dictionary. - */ -static void SweepEvent(GLUtesselator* tess, GLUvertex* vEvent) -{ - ActiveRegion* regUp; - ActiveRegion* reg; - GLUhalfEdge* e; - GLUhalfEdge* eTopLeft; - GLUhalfEdge* eBottomLeft; - - tess->event=vEvent; /* for access in EdgeLeq() */ - DebugEvent(tess); - - /* Check if this vertex is the right endpoint of an edge that is - * already in the dictionary. In this case we don't need to waste - * time searching for the location to insert new edges. - */ - e=vEvent->anEdge; - - while(e->activeRegion==NULL) - { - e=e->Onext; - if(e==vEvent->anEdge) - { - /* All edges go right -- not incident to any processed edges */ - ConnectLeftVertex(tess, vEvent); - return; - } - } - - /* Processing consists of two phases: first we "finish" all the - * active regions where both the upper and lower edges terminate - * at vEvent (ie. vEvent is closing off these regions). - * We mark these faces "inside" or "outside" the polygon according - * to their winding number, and delete the edges from the dictionary. - * This takes care of all the left-going edges from vEvent. - */ - regUp=TopLeftRegion(e->activeRegion); - if (regUp==NULL) - { - longjmp(tess->env, 1); - } - reg=RegionBelow(regUp); - eTopLeft=reg->eUp; - eBottomLeft=FinishLeftRegions(tess, reg, NULL); - - /* Next we process all the right-going edges from vEvent. This - * involves adding the edges to the dictionary, and creating the - * associated "active regions" which record information about the - * regions between adjacent dictionary edges. - */ - if (eBottomLeft->Onext==eTopLeft) - { - /* No right-going edges -- add a temporary "fixable" edge */ - ConnectRightVertex(tess, regUp, eBottomLeft); - } - else - { - AddRightEdges(tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE); - } -} - -/* Make the sentinel coordinates big enough that they will never be - * merged with real input features. (Even with the largest possible - * input contour and the maximum tolerance of 1.0, no merging will be - * done with coordinates larger than 3 * GLU_TESS_MAX_COORD). - */ -#define SENTINEL_COORD (4.0f*GLU_TESS_MAX_COORD) - -/* - * We add two sentinel edges above and below all other edges, - * to avoid special cases at the top and bottom. - */ -static void AddSentinel(GLUtesselator* tess, GLfloat t) -{ - GLUhalfEdge* e; - ActiveRegion* reg=(ActiveRegion*)memAlloc(sizeof(ActiveRegion)); - if (reg==NULL) - { - longjmp(tess->env, 1); - } - - e=__gl_meshMakeEdge(tess->mesh); - if (e==NULL) - { - longjmp(tess->env, 1); - } - - e->Org->s=SENTINEL_COORD; - e->Org->t=t; - e->Dst->s=-SENTINEL_COORD; - e->Dst->t=t; - tess->event=e->Dst; /* initialize it */ - - reg->eUp=e; - reg->windingNumber=0; - reg->inside=FALSE; - reg->fixUpperEdge=FALSE; - reg->sentinel=TRUE; - reg->dirty=FALSE; - reg->nodeUp=dictInsert(tess->dict, reg); /* __gl_dictListInsertBefore */ - - if (reg->nodeUp==NULL) - { - longjmp(tess->env, 1); - } -} - -/* - * We maintain an ordering of edge intersections with the sweep line. - * This order is maintained in a dynamic dictionary. - */ -static void InitEdgeDict(GLUtesselator* tess) -{ - /* __gl_dictListNewDict */ - tess->dict=dictNewDict(tess, (int (*)(void*, DictKey, DictKey))EdgeLeq); - if (tess->dict==NULL) - { - longjmp(tess->env, 1); - } - - AddSentinel(tess, -SENTINEL_COORD); - AddSentinel(tess, SENTINEL_COORD); -} - -static void DoneEdgeDict(GLUtesselator* tess) -{ - ActiveRegion* reg; -#ifndef NDEBUG - int fixedEdges=0; -#endif - - /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ - while ((reg=(ActiveRegion*)dictKey(dictMin(tess->dict)))!=NULL) - { - /* - * At the end of all processing, the dictionary should contain - * only the two sentinel edges, plus at most one "fixable" edge - * created by ConnectRightVertex(). - */ - if (!reg->sentinel) - { - assert(reg->fixUpperEdge); - assert(++fixedEdges==1); - } - assert(reg->windingNumber==0); - DeleteRegion(tess, reg); - } - dictDeleteDict(tess->dict); /* __gl_dictListDeleteDict */ -} - -/* - * Remove zero-length edges, and contours with fewer than 3 vertices. - */ -static void RemoveDegenerateEdges(GLUtesselator* tess) -{ - GLUhalfEdge* e; - GLUhalfEdge* eNext; - GLUhalfEdge* eLnext; - GLUhalfEdge* eHead=&tess->mesh->eHead; - - /*LINTED*/ - for(e=eHead->next; e!=eHead; e=eNext) - { - eNext=e->next; - eLnext=e->Lnext; - - if (VertEq(e->Org, e->Dst) && e->Lnext->Lnext!=e) - { - /* Zero-length edge, contour has at least 3 edges */ - SpliceMergeVertices(tess, eLnext, e); /* deletes e->Org */ - if (!__gl_meshDelete(e)) - { - longjmp(tess->env, 1); /* e is a self-loop */ - } - e=eLnext; - eLnext=e->Lnext; - } - - if (eLnext->Lnext==e) - { - /* Degenerate contour (one or two edges) */ - if (eLnext!=e) - { - if (eLnext==eNext || eLnext==eNext->Sym) - { - eNext=eNext->next; - } - if (!__gl_meshDelete(eLnext)) - { - longjmp(tess->env, 1); - } - } - if (e==eNext || e==eNext->Sym) - { - eNext=eNext->next; - } - if (!__gl_meshDelete(e)) - { - longjmp(tess->env, 1); - } - } - } -} - -/* - * Insert all vertices into the priority queue which determines the - * order in which vertices cross the sweep line. - */ -static int InitPriorityQ(GLUtesselator* tess) -{ - PriorityQ* pq; - GLUvertex* v; - GLUvertex* vHead; - - /* __gl_pqSortNewPriorityQ */ - pq=tess->pq=pqNewPriorityQ((int (*)(PQkey, PQkey))__gl_vertLeq); - if (pq==NULL) - { - return 0; - } - - vHead=&tess->mesh->vHead; - for(v=vHead->next; v!=vHead; v=v->next) - { - v->pqHandle=pqInsert(pq, v); /* __gl_pqSortInsert */ - if (v->pqHandle==LONG_MAX) - { - break; - } - } - - if (v!=vHead || !pqInit(pq)) - { /* __gl_pqSortInit */ - pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */ - tess->pq=NULL; - return 0; - } - - return 1; -} - -static void DonePriorityQ(GLUtesselator* tess) -{ - pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */ -} - -/* - * Delete any degenerate faces with only two edges. WalkDirtyRegions() - * will catch almost all of these, but it won't catch degenerate faces - * produced by splice operations on already-processed edges. - * The two places this can happen are in FinishLeftRegions(), when - * we splice in a "temporary" edge produced by ConnectRightVertex(), - * and in CheckForLeftSplice(), where we splice already-processed - * edges to ensure that our dictionary invariants are not violated - * by numerical errors. - * - * In both these cases it is *very* dangerous to delete the offending - * edge at the time, since one of the routines further up the stack - * will sometimes be keeping a pointer to that edge. - */ -static int RemoveDegenerateFaces(GLUmesh* mesh) -{ - GLUface* f; - GLUface* fNext; - GLUhalfEdge* e; - - /* LINTED */ - for(f=mesh->fHead.next; f!=&mesh->fHead; f=fNext) - { - fNext=f->next; - e=f->anEdge; - assert(e->Lnext!=e); - - if (e->Lnext->Lnext==e) - { - /* A face with only two edges */ - AddWinding(e->Onext, e); - if (!__gl_meshDelete(e)) - { - return 0; - } - } - } - - return 1; -} - -int __gl_computeInterior(GLUtesselator* tess) -/* - * __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ -{ - GLUvertex* v; - GLUvertex* vNext; - - tess->fatalError=FALSE; - - /* Each vertex defines an event for our sweep line. Start by inserting - * all the vertices in a priority queue. Events are processed in - * lexicographic order, ie. - * - * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y) - */ - RemoveDegenerateEdges(tess); - if (!InitPriorityQ(tess)) - { - return 0; /* if error */ - } - InitEdgeDict(tess); - - /* __gl_pqSortExtractMin */ - while((v=(GLUvertex*)pqExtractMin(tess->pq))!=NULL) - { - for (;;) - { - vNext=(GLUvertex*)pqMinimum(tess->pq); /* __gl_pqSortMinimum */ - if (vNext==NULL || !VertEq(vNext, v)) - { - break; - } - - /* Merge together all vertices at exactly the same location. - * This is more efficient than processing them one at a time, - * simplifies the code (see ConnectLeftDegenerate), and is also - * important for correct handling of certain degenerate cases. - * For example, suppose there are two identical edges A and B - * that belong to different contours (so without this code they would - * be processed by separate sweep events). Suppose another edge C - * crosses A and B from above. When A is processed, we split it - * at its intersection point with C. However this also splits C, - * so when we insert B we may compute a slightly different - * intersection point. This might leave two edges with a small - * gap between them. This kind of error is especially obvious - * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY). - */ - vNext=(GLUvertex*)pqExtractMin(tess->pq); /* __gl_pqSortExtractMin*/ - SpliceMergeVertices(tess, v->anEdge, vNext->anEdge); - } - SweepEvent(tess, v); - } - - /* Set tess->event for debugging purposes */ - /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ - tess->event=((ActiveRegion*)dictKey(dictMin(tess->dict)))->eUp->Org; - DebugEvent(tess); - DoneEdgeDict(tess); - DonePriorityQ(tess); - - if (!RemoveDegenerateFaces(tess->mesh)) - { - return 0; - } - __gl_meshCheckMesh(tess->mesh); - - return 1; -} diff --git a/internal/c/parts/core/glues/src/libtess/sweep.h b/internal/c/parts/core/glues/src/libtess/sweep.h deleted file mode 100644 index 8f27bf9c3..000000000 --- a/internal/c/parts/core/glues/src/libtess/sweep.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __sweep_h_ -#define __sweep_h_ - -#include "mesh.h" - -/* __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ -int __gl_computeInterior(GLUtesselator* tess); - -/* The following is here *only* for access by debugging routines */ - -#include "dict.h" - -/* For each pair of adjacent edges crossing the sweep line, there is - * an ActiveRegion to represent the region between them. The active - * regions are kept in sorted order in a dynamic dictionary. As the - * sweep line crosses each vertex, we update the affected regions. - */ - -struct ActiveRegion -{ - GLUhalfEdge* eUp; /* upper edge, directed right to left */ - DictNode* nodeUp; /* dictionary node corresponding to eUp */ - int windingNumber; /* used to determine which regions are - * inside the polygon */ - GLboolean inside; /* is this region inside the polygon? */ - GLboolean sentinel; /* marks fake edges at t = +/-infinity */ - GLboolean dirty; /* marks regions where the upper or lower - * edge has changed, but we haven't checked - * whether they intersect yet */ - GLboolean fixUpperEdge; /* marks temporary edges introduced when - * we process a "right vertex" (one without - * any edges leaving to the right) */ -}; - -#define RegionBelow(r) ((ActiveRegion*)dictKey(dictPred((r)->nodeUp))) -#define RegionAbove(r) ((ActiveRegion*)dictKey(dictSucc((r)->nodeUp))) - -#endif /* __sweep_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/tess.c b/internal/c/parts/core/glues/src/libtess/tess.c deleted file mode 100644 index 3c1500b3a..000000000 --- a/internal/c/parts/core/glues/src/libtess/tess.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include -#include -#include "memalloc.h" -#include "tess.h" -#include "mesh.h" -#include "normal.h" -#include "sweep.h" -#include "tessmono.h" -#include "render.h" - -#define GLU_TESS_DEFAULT_TOLERANCE 0.0f -#define GLU_TESS_MESH 100112 /* void (*)(GLUmesh *mesh) */ - -#define TRUE 1 -#define FALSE 0 - -/*ARGSUSED*/ static void APIENTRY noBegin(GLenum type) {} -/*ARGSUSED*/ static void APIENTRY noEdgeFlag(GLboolean boundaryEdge ) {} -/*ARGSUSED*/ static void APIENTRY noVertex(void* data) {} -/*ARGSUSED*/ static void APIENTRY noEnd(void) {} -/*ARGSUSED*/ static void APIENTRY noError(GLenum errnum) {} -/*ARGSUSED*/ static void APIENTRY noCombine(GLfloat coords[3], void *data[4], - GLfloat weight[4], void **dataOut) {} -/*ARGSUSED*/ static void APIENTRY noMesh(GLUmesh* mesh) {} - -/*ARGSUSED*/ void APIENTRY __gl_noBeginData(GLenum type, void* polygonData) {} -/*ARGSUSED*/ void APIENTRY __gl_noEdgeFlagData(GLboolean boundaryEdge, void* polygonData) {} -/*ARGSUSED*/ void APIENTRY __gl_noVertexData(void* data, void* polygonData) {} -/*ARGSUSED*/ void APIENTRY __gl_noEndData(void* polygonData) {} -/*ARGSUSED*/ void APIENTRY __gl_noErrorData( GLenum errnum, void* polygonData) {} -/*ARGSUSED*/ void APIENTRY __gl_noCombineData(GLfloat coords[3], void* data[4], - GLfloat weight[4], void** outData, - void* polygonData) {} - -/* Half-edges are allocated in pairs (see mesh.c) */ -typedef struct {GLUhalfEdge e, eSym;} EdgePair; - -#undef MAX -#define MAX(a, b) ((a)>(b) ? (a): (b)) -#define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \ - MAX(sizeof(GLUvertex), sizeof(GLUface)))) - -GLAPI GLUtesselator* APIENTRY gluNewTess(void) -{ - GLUtesselator* tess; - - /* Only initialize fields which can be changed by the api. Other fields - * are initialized where they are used. - */ - - if (memInit(MAX_FAST_ALLOC)==0) - { - return 0; /* out of memory */ - } - tess=(GLUtesselator*)memAlloc(sizeof(GLUtesselator)); - if (tess==NULL) - { - return 0; /* out of memory */ - } - - tess->state=T_DORMANT; - - tess->normal[0]=0; - tess->normal[1]=0; - tess->normal[2]=0; - - tess->relTolerance=GLU_TESS_DEFAULT_TOLERANCE; - tess->windingRule=GLU_TESS_WINDING_ODD; - tess->flagBoundary=FALSE; - tess->boundaryOnly=FALSE; - - tess->callBegin=&noBegin; - tess->callEdgeFlag=&noEdgeFlag; - tess->callVertex=&noVertex; - tess->callEnd=&noEnd; - - tess->callError=&noError; - tess->callCombine=&noCombine; - tess->callMesh=&noMesh; - - tess->callBeginData=&__gl_noBeginData; - tess->callEdgeFlagData=&__gl_noEdgeFlagData; - tess->callVertexData=&__gl_noVertexData; - tess->callEndData=&__gl_noEndData; - tess->callErrorData=&__gl_noErrorData; - tess->callCombineData=&__gl_noCombineData; - - tess->polygonData=NULL; - - return tess; -} - -static void MakeDormant( GLUtesselator *tess ) -{ - /* Return the tessellator to its original dormant state. */ - if (tess->mesh!=NULL) - { - __gl_meshDeleteMesh(tess->mesh); - } - tess->state=T_DORMANT; - tess->lastEdge=NULL; - tess->mesh=NULL; -} - -#define RequireState(tess, s) if (tess->state!=s) { GotoState(tess, s); } - -static void GotoState(GLUtesselator* tess, enum TessState newState) -{ - while (tess->state!=newState) - { - /* We change the current state one level at a time, to get to - * the desired state. - */ - if (tess->statestate) - { - case T_DORMANT: - CALL_ERROR_OR_ERROR_DATA(GLU_TESS_MISSING_BEGIN_POLYGON); - gluTessBeginPolygon(tess, NULL); - break; - case T_IN_POLYGON: - CALL_ERROR_OR_ERROR_DATA(GLU_TESS_MISSING_BEGIN_CONTOUR); - gluTessBeginContour(tess); - break; - default: - break; - } - } - else - { - switch (tess->state) - { - case T_IN_CONTOUR: - CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR ); - gluTessEndContour(tess); - break; - case T_IN_POLYGON: - CALL_ERROR_OR_ERROR_DATA(GLU_TESS_MISSING_END_POLYGON); - /* gluTessEndPolygon(tess) is too much work! */ - MakeDormant(tess); - break; - default: - break; - } - } - } -} - -GLAPI void APIENTRY gluDeleteTess(GLUtesselator* tess) -{ - RequireState(tess, T_DORMANT); - memFree(tess); -} - -GLAPI void APIENTRY gluTessProperty(GLUtesselator* tess, GLenum which, GLfloat value) -{ - GLenum windingRule; - - switch (which) - { - case GLU_TESS_TOLERANCE: - if (value<0.0f || value>1.0f) - { - break; - } - tess->relTolerance = value; - return; - case GLU_TESS_WINDING_RULE: - windingRule=(GLenum)value; - if (windingRule!=value) - { - break; /* not an integer */ - } - - switch (windingRule) - { - case GLU_TESS_WINDING_ODD: - case GLU_TESS_WINDING_NONZERO: - case GLU_TESS_WINDING_POSITIVE: - case GLU_TESS_WINDING_NEGATIVE: - case GLU_TESS_WINDING_ABS_GEQ_TWO: - tess->windingRule=windingRule; - return; - default: - break; - } - break; - case GLU_TESS_BOUNDARY_ONLY: - tess->boundaryOnly=(value!=0); - return; - default: - CALL_ERROR_OR_ERROR_DATA(GLU_INVALID_ENUM); - return; - } - - CALL_ERROR_OR_ERROR_DATA(GLU_INVALID_VALUE); -} - -/* Returns tessellator property */ -GLAPI void APIENTRY gluGetTessProperty(GLUtesselator* tess, GLenum which, GLfloat* value) -{ - switch (which) - { - case GLU_TESS_TOLERANCE: - /* tolerance should be in range [0..1] */ - assert(0.0f<=tess->relTolerance && tess->relTolerance<=1.0f); - *value=tess->relTolerance; - break; - case GLU_TESS_WINDING_RULE: - assert(tess->windingRule==GLU_TESS_WINDING_ODD || - tess->windingRule==GLU_TESS_WINDING_NONZERO || - tess->windingRule==GLU_TESS_WINDING_POSITIVE || - tess->windingRule==GLU_TESS_WINDING_NEGATIVE || - tess->windingRule==GLU_TESS_WINDING_ABS_GEQ_TWO); - *value=(GLfloat)tess->windingRule; - break; - case GLU_TESS_BOUNDARY_ONLY: - assert(tess->boundaryOnly==TRUE || tess->boundaryOnly==FALSE); - *value=tess->boundaryOnly; - break; - default: - *value=0.0f; - CALL_ERROR_OR_ERROR_DATA(GLU_INVALID_ENUM); - break; - } -} - -GLAPI void APIENTRY gluTessNormal(GLUtesselator* tess, GLfloat x, GLfloat y, GLfloat z) -{ - tess->normal[0]=x; - tess->normal[1]=y; - tess->normal[2]=z; -} - -GLAPI void APIENTRY gluTessCallback(GLUtesselator* tess, GLenum which, _GLUfuncptr fn) -{ - switch (which) - { - case GLU_TESS_BEGIN: - tess->callBegin=(fn==NULL) ? &noBegin: (void (APIENTRY*)(GLenum))fn; - return; - case GLU_TESS_BEGIN_DATA: - tess->callBeginData=(fn==NULL) ? - &__gl_noBeginData: (void (APIENTRY*)(GLenum, void*))fn; - return; - case GLU_TESS_EDGE_FLAG: - tess->callEdgeFlag=(fn==NULL) ? &noEdgeFlag: (void (APIENTRY*)(GLboolean))fn; - /* If the client wants boundary edges to be flagged, - * we render everything as separate triangles (no strips or fans). - */ - tess->flagBoundary=(fn!=NULL); - return; - case GLU_TESS_EDGE_FLAG_DATA: - tess->callEdgeFlagData=(fn==NULL) ? - &__gl_noEdgeFlagData: (void (APIENTRY*)(GLboolean, void*))fn; - /* If the client wants boundary edges to be flagged, - * we render everything as separate triangles (no strips or fans). - */ - tess->flagBoundary=(fn!=NULL); - return; - case GLU_TESS_VERTEX: - tess->callVertex=(fn==NULL) ? &noVertex: (void (APIENTRY*)(void*))fn; - return; - case GLU_TESS_VERTEX_DATA: - tess->callVertexData=(fn==NULL) ? - &__gl_noVertexData: (void (APIENTRY*)(void*, void*))fn; - return; - case GLU_TESS_END: - tess->callEnd=(fn==NULL) ? &noEnd: (void (APIENTRY*)(void))fn; - return; - case GLU_TESS_END_DATA: - tess->callEndData=(fn==NULL) ? &__gl_noEndData: (void (APIENTRY*)(void*))fn; - return; - case GLU_TESS_ERROR: - tess->callError=(fn==NULL) ? &noError: (void (APIENTRY*)(GLenum))fn; - return; - case GLU_TESS_ERROR_DATA: - tess->callErrorData=(fn==NULL) ? &__gl_noErrorData: (void (APIENTRY*)(GLenum, void*))fn; - return; - case GLU_TESS_COMBINE: - tess->callCombine=(fn==NULL) ? &noCombine: - (void (APIENTRY*)(GLfloat[3], void*[4], GLfloat[4], void**))fn; - return; - case GLU_TESS_COMBINE_DATA: - tess->callCombineData=(fn==NULL) ? &__gl_noCombineData: - (void (APIENTRY*)(GLfloat [3], void*[4], GLfloat[4], void**, void*))fn; - return; - case GLU_TESS_MESH: - tess->callMesh=(fn==NULL) ? &noMesh: (void (APIENTRY*)(GLUmesh*))fn; - return; - default: - CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM ); - return; - } -} - -static int AddVertex(GLUtesselator* tess, GLfloat coords[3], void* data) -{ - GLUhalfEdge* e=NULL; - - e=tess->lastEdge; - if (e==NULL) - { - /* Make a self-loop (one vertex, one edge). */ - e=__gl_meshMakeEdge(tess->mesh); - if (e==NULL) - { - return 0; - } - if (!__gl_meshSplice(e, e->Sym)) - { - return 0; - } - } - else - { - /* Create a new vertex and edge which immediately follow e - * in the ordering around the left face. - */ - if (__gl_meshSplitEdge(e)==NULL) - { - return 0; - } - e=e->Lnext; - } - - /* The new vertex is now e->Org. */ - e->Org->data=data; - e->Org->coords[0]=coords[0]; - e->Org->coords[1]=coords[1]; - e->Org->coords[2]=coords[2]; - - /* The winding of an edge says how the winding number changes as we - * cross from the edge''s right face to its left face. We add the - * vertices in such an order that a CCW contour will add +1 to - * the winding number of the region inside the contour. - */ - e->winding=1; - e->Sym->winding=-1; - - tess->lastEdge=e; - - return 1; -} - -static void CacheVertex(GLUtesselator* tess, GLfloat coords[3], void* data) -{ - CachedVertex* v=&tess->cache[tess->cacheCount]; - - v->data=data; - v->coords[0]=coords[0]; - v->coords[1]=coords[1]; - v->coords[2]=coords[2]; - ++tess->cacheCount; -} - -static int EmptyCache(GLUtesselator* tess) -{ - CachedVertex* v=tess->cache; - CachedVertex* vLast; - - tess->mesh=__gl_meshNewMesh(); - if (tess->mesh==NULL) - { - return 0; - } - - for(vLast=v+tess->cacheCount; vcoords, v->data)) - { - return 0; - } - } - tess->cacheCount=0; - tess->emptyCache=FALSE; - - return 1; -} - - -void APIENTRY gluTessVertex(GLUtesselator* tess, GLfloat coords[3], void* data) -{ - int i; - int tooLarge=FALSE; - GLfloat x, clamped[3]; - - RequireState(tess, T_IN_CONTOUR); - - if (tess->emptyCache) - { - if (!EmptyCache(tess)) - { - CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY ); - return; - } - tess->lastEdge=NULL; - } - - for (i=0; i<3; ++i) - { - x=coords[i]; - if (x<-GLU_TESS_MAX_COORD) - { - x=-GLU_TESS_MAX_COORD; - tooLarge=TRUE; - } - if (x>GLU_TESS_MAX_COORD) - { - x=GLU_TESS_MAX_COORD; - tooLarge=TRUE; - } - clamped[i]=x; - } - if (tooLarge) - { - CALL_ERROR_OR_ERROR_DATA(GLU_TESS_COORD_TOO_LARGE); - } - - if (tess->mesh==NULL) - { - if (tess->cacheCountstate=T_IN_POLYGON; - tess->cacheCount=0; - tess->emptyCache=FALSE; - tess->mesh=NULL; - - tess->polygonData=data; -} - -void APIENTRY gluTessBeginContour(GLUtesselator* tess) -{ - RequireState(tess, T_IN_POLYGON); - - tess->state=T_IN_CONTOUR; - tess->lastEdge=NULL; - if (tess->cacheCount>0) - { - /* Just set a flag so we don't get confused by empty contours - * -- these can be generated accidentally with the obsolete - * NextContour() interface. - */ - tess->emptyCache=TRUE; - } -} - -void APIENTRY gluTessEndContour(GLUtesselator* tess) -{ - RequireState(tess, T_IN_CONTOUR); - tess->state=T_IN_POLYGON; -} - -void APIENTRY gluTessEndPolygon(GLUtesselator* tess) -{ - GLUmesh* mesh; - - if (setjmp(tess->env)!=0) - { - /* come back here if out of memory */ - CALL_ERROR_OR_ERROR_DATA(GLU_OUT_OF_MEMORY); - return; - } - - RequireState(tess, T_IN_POLYGON); - tess->state=T_DORMANT; - - if (tess->mesh==NULL) - { - if (!tess->flagBoundary && tess->callMesh==&noMesh) - { - /* Try some special code to make the easy cases go quickly - * (eg. convex polygons). This code does NOT handle multiple contours, - * intersections, edge flags, and of course it does not generate - * an explicit mesh either. - */ - if (__gl_renderCache(tess)) - { - tess->polygonData= NULL; - return; - } - } - if (!EmptyCache(tess)) - { - longjmp(tess->env, 1); /* could've used a label */ - } - } - - /* Determine the polygon normal and project vertices onto the plane - * of the polygon. - */ - __gl_projectPolygon(tess); - - /* __gl_computeInterior( tess ) computes the planar arrangement specified - * by the given contours, and further subdivides this arrangement - * into regions. Each region is marked "inside" if it belongs - * to the polygon, according to the rule given by tess->windingRule. - * Each interior region is guaranteed be monotone. - */ - if (!__gl_computeInterior(tess)) - { - longjmp(tess->env, 1); /* could've used a label */ - } - - mesh=tess->mesh; - if (!tess->fatalError) - { - int rc=1; - - /* If the user wants only the boundary contours, we throw away all edges - * except those which separate the interior from the exterior. - * Otherwise we tessellate all the regions marked "inside". - */ - if (tess->boundaryOnly) - { - rc=__gl_meshSetWindingNumber(mesh, 1, TRUE); - } - else - { - rc=__gl_meshTessellateInterior(mesh); - } - if (rc==0) - { - longjmp(tess->env,1); /* could've used a label */ - } - - __gl_meshCheckMesh(mesh); - - if (tess->callBegin!=&noBegin || tess->callEnd!=&noEnd || - tess->callVertex!=&noVertex || tess->callEdgeFlag!=&noEdgeFlag || - tess->callBeginData!=&__gl_noBeginData || tess->callEndData!=&__gl_noEndData || - tess->callVertexData!=&__gl_noVertexData || tess->callEdgeFlagData!=&__gl_noEdgeFlagData) - { - if (tess->boundaryOnly) - { - __gl_renderBoundary(tess, mesh); /* output boundary contours */ - } - else - { - __gl_renderMesh(tess, mesh); /* output strips and fans */ - } - } - - if (tess->callMesh!=&noMesh) - { - /* Throw away the exterior faces, so that all faces are interior. - * This way the user doesn't have to check the "inside" flag, - * and we don't need to even reveal its existence. It also leaves - * the freedom for an implementation to not generate the exterior - * faces in the first place. - */ - __gl_meshDiscardExterior(mesh); - (*tess->callMesh)(mesh); /* user wants the mesh itself */ - tess->mesh = NULL; - tess->polygonData= NULL; - return; - } - } - __gl_meshDeleteMesh(mesh); - tess->polygonData=NULL; - tess->mesh=NULL; -} - -/*******************************************************/ - -/* Obsolete calls -- for backward compatibility */ -void APIENTRY gluBeginPolygon(GLUtesselator* tess) -{ - gluTessBeginPolygon(tess, NULL); - gluTessBeginContour(tess); -} - -/*ARGSUSED*/ -void APIENTRY gluNextContour(GLUtesselator* tess, GLenum type) -{ - gluTessEndContour(tess); - gluTessBeginContour(tess); -} - -void APIENTRY gluEndPolygon(GLUtesselator* tess) -{ - gluTessEndContour(tess); - gluTessEndPolygon(tess); -} diff --git a/internal/c/parts/core/glues/src/libtess/tess.h b/internal/c/parts/core/glues/src/libtess/tess.h deleted file mode 100644 index be63b58d5..000000000 --- a/internal/c/parts/core/glues/src/libtess/tess.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __tess_h_ -#define __tess_h_ - -#include "glues.h" -#include -#include "mesh.h" -#include "dict.h" -#include "priorityq.h" - -/* The begin/end calls must be properly nested. We keep track of - * the current state to enforce the ordering. - */ -enum TessState {T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR}; - -/* We cache vertex data for single-contour polygons so that we can - * try a quick-and-dirty decomposition first. - */ -#define TESS_MAX_CACHE 100 - -typedef struct CachedVertex -{ - GLfloat coords[3]; - void* data; -} CachedVertex; - -struct GLUtesselator -{ - /*** state needed for collecting the input data ***/ - enum TessState state; /* what begin/end calls have we seen? */ - - GLUhalfEdge* lastEdge; /* lastEdge->Org is the most recent vertex */ - GLUmesh* mesh; /* stores the input contours, and eventually - the tessellation itself */ - - void (APIENTRY* callError)(GLenum errnum); - - /*** state needed for projecting onto the sweep plane ***/ - GLfloat normal[3]; /* user-specified normal (if provided) */ - GLfloat sUnit[3]; /* unit vector in s-direction (debugging) */ - GLfloat tUnit[3]; /* unit vector in t-direction (debugging) */ - - /*** state needed for the line sweep ***/ - GLfloat relTolerance; /* tolerance for merging features */ - GLenum windingRule; /* rule for determining polygon interior */ - GLboolean fatalError; /* fatal error: needed combine callback */ - - Dict* dict; /* edge dictionary for sweep line */ - PriorityQ* pq; /* priority queue of vertex events */ - GLUvertex* event; /* current sweep event being processed */ - - void (APIENTRY* callCombine)(GLfloat coords[3], void* data[4], - GLfloat weight[4], void** outData); - - /*** state needed for rendering callbacks (see render.c) ***/ - GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */ - GLboolean boundaryOnly; /* Extract contours, not triangles */ - /* list of triangles which could not be rendered as strips or fans */ - GLUface* lonelyTriList; - - void (APIENTRY* callBegin)(GLenum type); - void (APIENTRY* callEdgeFlag)(GLboolean boundaryEdge); - void (APIENTRY* callVertex)(void* data); - void (APIENTRY* callEnd)(void); - void (APIENTRY* callMesh)(GLUmesh* mesh); - - /*** state needed to cache single-contour polygons for renderCache() */ - - GLboolean emptyCache; /* empty cache on next vertex() call */ - int cacheCount; /* number of cached vertices */ - CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */ - - /*** rendering callbacks that also pass polygon data ***/ - void (APIENTRY* callBeginData)(GLenum type, void* polygonData); - void (APIENTRY* callEdgeFlagData)(GLboolean boundaryEdge, void* polygonData); - void (APIENTRY* callVertexData)(void* data, void* polygonData); - void (APIENTRY* callEndData)(void* polygonData); - void (APIENTRY* callErrorData)(GLenum errnum, void *polygonData); - void (APIENTRY* callCombineData)(GLfloat coords[3], void* data[4], - GLfloat weight[4], void** outData, - void* polygonData); - - jmp_buf env; /* place to jump to when memAllocs fail */ - - void* polygonData; /* client data for current polygon */ -}; - -GLAPI void APIENTRY __gl_noBeginData(GLenum type, void* polygonData); -GLAPI void APIENTRY __gl_noEdgeFlagData(GLboolean boundaryEdge, void* polygonData); -GLAPI void APIENTRY __gl_noVertexData(void* data, void* polygonData); -GLAPI void APIENTRY __gl_noEndData(void* polygonData); -GLAPI void APIENTRY __gl_noErrorData(GLenum errnum, void* polygonData); -GLAPI void APIENTRY __gl_noCombineData(GLfloat coords[3], void* data[4], - GLfloat weight[4], void** outData, - void* polygonData); - -#define CALL_BEGIN_OR_BEGIN_DATA(a) \ - if (tess->callBeginData != &__gl_noBeginData) \ - (*tess->callBeginData)((a),tess->polygonData); \ - else (*tess->callBegin)((a)); - -#define CALL_VERTEX_OR_VERTEX_DATA(a) \ - if (tess->callVertexData != &__gl_noVertexData) \ - (*tess->callVertexData)((a),tess->polygonData); \ - else (*tess->callVertex)((a)); - -#define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \ - if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \ - (*tess->callEdgeFlagData)((a),tess->polygonData); \ - else (*tess->callEdgeFlag)((a)); - -#define CALL_END_OR_END_DATA() \ - if (tess->callEndData != &__gl_noEndData) \ - (*tess->callEndData)(tess->polygonData); \ - else (*tess->callEnd)(); - -#define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \ - if (tess->callCombineData != &__gl_noCombineData) \ - (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \ - else (*tess->callCombine)((a),(b),(c),(d)); - -#define CALL_ERROR_OR_ERROR_DATA(a) \ - if (tess->callErrorData != &__gl_noErrorData) \ - (*tess->callErrorData)((a),tess->polygonData); \ - else (*tess->callError)((a)); - -#endif /* __tess_h_ */ diff --git a/internal/c/parts/core/glues/src/libtess/tessmono.c b/internal/c/parts/core/glues/src/libtess/tessmono.c deleted file mode 100644 index 8f2df2d5b..000000000 --- a/internal/c/parts/core/glues/src/libtess/tessmono.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#include -#include "geom.h" -#include "mesh.h" -#include "tessmono.h" -#include - -#define AddWinding(eDst, eSrc) (eDst->winding+=eSrc->winding, \ - eDst->Sym->winding+=eSrc->Sym->winding) - -/* __gl_meshTessellateMonoRegion(face) tessellates a monotone region - * (what else would it do??) The region must consist of a single - * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this - * case means that any vertical line intersects the interior of the - * region in a single interval. - * - * Tessellation consists of adding interior edges (actually pairs of - * half-edges), to split the region into non-overlapping triangles. - * - * The basic idea is explained in Preparata and Shamos (which I don''t - * have handy right now), although their implementation is more - * complicated than this one. The are two edge chains, an upper chain - * and a lower chain. We process all vertices from both chains in order, - * from right to left. - * - * The algorithm ensures that the following invariant holds after each - * vertex is processed: the untessellated region consists of two - * chains, where one chain (say the upper) is a single edge, and - * the other chain is concave. The left vertex of the single edge - * is always to the left of all vertices in the concave chain. - * - * Each step consists of adding the rightmost unprocessed vertex to one - * of the two chains, and forming a fan of triangles from the rightmost - * of two chain endpoints. Determining whether we can add each triangle - * to the fan is a simple orientation test. By making the fan as large - * as possible, we restore the invariant (check it yourself). - */ -int __gl_meshTessellateMonoRegion(GLUface* face) -{ - GLUhalfEdge* up; - GLUhalfEdge* lo; - - /* All edges are oriented CCW around the boundary of the region. - * First, find the half-edge whose origin vertex is rightmost. - * Since the sweep goes from left to right, face->anEdge should - * be close to the edge we want. - */ - up=face->anEdge; - assert(up->Lnext!=up && up->Lnext->Lnext!=up); - - for(; VertLeq(up->Dst, up->Org); up=up->Lprev); - for(; VertLeq(up->Org, up->Dst); up=up->Lnext); - lo=up->Lprev; - - while(up->Lnext!=lo) - { - if (VertLeq(up->Dst, lo->Org)) - { - /* up->Dst is on the left. It is safe to form triangles from lo->Org. - * The EdgeGoesLeft test guarantees progress even when some triangles - * are CW, given that the upper and lower chains are truly monotone. - */ - while (lo->Lnext!=up && (EdgeGoesLeft(lo->Lnext) || EdgeSign(lo->Org, lo->Dst, lo->Lnext->Dst)<=0)) - { - GLUhalfEdge* tempHalfEdge=__gl_meshConnect(lo->Lnext, lo); - if (tempHalfEdge==NULL) - { - return 0; - } - lo=tempHalfEdge->Sym; - } - lo=lo->Lprev; - } - else - { - /* lo->Org is on the left. We can make CCW triangles from up->Dst. */ - while(lo->Lnext!=up && (EdgeGoesRight(up->Lprev) || EdgeSign(up->Dst, up->Org, up->Lprev->Org)>=0)) - { - GLUhalfEdge* tempHalfEdge=__gl_meshConnect(up, up->Lprev); - if (tempHalfEdge==NULL) - { - return 0; - } - up=tempHalfEdge->Sym; - } - up=up->Lnext; - } - } - - /* Now lo->Org == up->Dst == the leftmost vertex. The remaining region - * can be tessellated in a fan from this leftmost vertex. - */ - assert(lo->Lnext!=up); - while(lo->Lnext->Lnext!=up) - { - GLUhalfEdge* tempHalfEdge=__gl_meshConnect(lo->Lnext, lo); - if (tempHalfEdge==NULL) - { - return 0; - } - lo=tempHalfEdge->Sym; - } - - return 1; -} - -/* __gl_meshTessellateInterior( mesh ) tessellates each region of - * the mesh which is marked "inside" the polygon. Each such region - * must be monotone. - */ -int __gl_meshTessellateInterior(GLUmesh* mesh) -{ - GLUface* f; - GLUface* next; - - /*LINTED*/ - for (f=mesh->fHead.next; f!=&mesh->fHead; f=next) - { - /* Make sure we don''t try to tessellate the new triangles. */ - next=f->next; - if (f->inside) - { - if (!__gl_meshTessellateMonoRegion(f)) - { - return 0; - } - } - } - - return 1; -} - - -/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces - * which are not marked "inside" the polygon. Since further mesh operations - * on NULL faces are not allowed, the main purpose is to clean up the - * mesh so that exterior loops are not represented in the data structure. - */ -void __gl_meshDiscardExterior(GLUmesh* mesh) -{ - GLUface* f; - GLUface* next; - - /*LINTED*/ - for (f=mesh->fHead.next; f!=&mesh->fHead; f=next) - { - /* Since f will be destroyed, save its next pointer. */ - next=f->next; - if (!f->inside) - { - __gl_meshZapFace(f); - } - } -} - -#define MARKED_FOR_DELETION 0x7fffffff - -/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the - * winding numbers on all edges so that regions marked "inside" the - * polygon have a winding number of "value", and regions outside - * have a winding number of 0. - * - * If keepOnlyBoundary is TRUE, it also deletes all edges which do not - * separate an interior region from an exterior one. - */ -int __gl_meshSetWindingNumber(GLUmesh* mesh, int value, GLboolean keepOnlyBoundary) -{ - GLUhalfEdge* e; - GLUhalfEdge* eNext; - - for (e=mesh->eHead.next; e!=&mesh->eHead; e=eNext) - { - eNext=e->next; - if (e->Rface->inside!=e->Lface->inside) - { - /* This is a boundary edge (one side is interior, one is exterior). */ - e->winding=(e->Lface->inside) ? value : -value; - } - else - { - /* Both regions are interior, or both are exterior. */ - if (!keepOnlyBoundary) - { - e->winding = 0; - } - else - { - if (!__gl_meshDelete(e)) - { - return 0; - } - } - } - } - - return 1; -} diff --git a/internal/c/parts/core/glues/src/libtess/tessmono.h b/internal/c/parts/core/glues/src/libtess/tessmono.h deleted file mode 100644 index 53feb17ee..000000000 --- a/internal/c/parts/core/glues/src/libtess/tessmono.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Except as contained in this notice, the name of Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ -/* -** Author: Eric Veach, July 1994. -** -*/ - -#ifndef __tessmono_h_ -#define __tessmono_h_ - -/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region - * (what else would it do??) The region must consist of a single - * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this - * case means that any vertical line intersects the interior of the - * region in a single interval. - * - * Tessellation consists of adding interior edges (actually pairs of - * half-edges), to split the region into non-overlapping triangles. - * - * __gl_meshTessellateInterior( mesh ) tessellates each region of - * the mesh which is marked "inside" the polygon. Each such region - * must be monotone. - * - * __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces - * which are not marked "inside" the polygon. Since further mesh operations - * on NULL faces are not allowed, the main purpose is to clean up the - * mesh so that exterior loops are not represented in the data structure. - * - * __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the - * winding numbers on all edges so that regions marked "inside" the - * polygon have a winding number of "value", and regions outside - * have a winding number of 0. - * - * If keepOnlyBoundary is TRUE, it also deletes all edges which do not - * separate an interior region from an exterior one. - */ - -int __gl_meshTessellateMonoRegion(GLUface* face); -int __gl_meshTessellateInterior(GLUmesh* mesh); -void __gl_meshDiscardExterior(GLUmesh* mesh); -int __gl_meshSetWindingNumber(GLUmesh* mesh, int value, GLboolean keepOnlyBoundary); - -#endif /* __tessmono_h_ */