diff --git a/project/jni/SettingsTemplate.mk b/project/jni/SettingsTemplate.mk index 2b41aa3a6..7606ec220 100644 --- a/project/jni/SettingsTemplate.mk +++ b/project/jni/SettingsTemplate.mk @@ -3,7 +3,7 @@ APP_MODULES := application sdl-1.2 sdl_main stlport jpeg png ogg flac vorbis freetype tremor ogg # To filter out static libs from all libs in makefile -APP_AVAILABLE_STATIC_LIBS := jpeg png tremor freetype xerces ogg tremor vorbis flac boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread +APP_AVAILABLE_STATIC_LIBS := jpeg png tremor freetype xerces ogg tremor vorbis flac boost_date_time boost_filesystem boost_iostreams boost_program_options boost_regex boost_signals boost_system boost_thread glu APP_ABI := armeabi diff --git a/project/jni/glu/Android.mk b/project/jni/glu/Android.mk new file mode 100644 index 000000000..db8d7b21d --- /dev/null +++ b/project/jni/glu/Android.mk @@ -0,0 +1,21 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := glu + +APP_SUBDIRS := src + +APP_SUBDIRS := $(patsubst $(LOCAL_PATH)/%, %, $(shell find $(LOCAL_PATH)/src -type d)) + +LOCAL_C_INCLUDES := $(foreach D, $(APP_SUBDIRS), $(LOCAL_PATH)/$(D)) +LOCAL_CFLAGS := -O3 -std=gnu99 + +LOCAL_CPP_EXTENSION := .cpp + +LOCAL_SRC_FILES := $(foreach F, $(APP_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.cpp)))) +LOCAL_SRC_FILES += $(foreach F, $(APP_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.c)))) + +LOCAL_SHARED_LIBRARIES := + +include $(BUILD_STATIC_LIBRARY) diff --git a/project/jni/glu/LICENSE b/project/jni/glu/LICENSE new file mode 100644 index 000000000..78b6de44f --- /dev/null +++ b/project/jni/glu/LICENSE @@ -0,0 +1,27 @@ +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. diff --git a/project/jni/glu/README b/project/jni/glu/README new file mode 100644 index 000000000..28c3a8d4d --- /dev/null +++ b/project/jni/glu/README @@ -0,0 +1,25 @@ + +GLU ES (version 1.5) + +This port is based on original GLU 1.3 and has original libutil, libtess and +and nurbs libraries. + +Currently QNX 6.4.x native target builds and Win32 (for PowerVR OpenGL ES 1.1 +emulator) are supported. + +History: + +1.5 - NURBS support has added. Updated HTML documentation to reflect the + changes. New tests were added for NURBS. +1.4 - miscellaneous non-critical fixes, HTML documentation has been added. + Support for PowerVR OpenGL ES 1.1 emulator for Win32 has been added. +1.3 - libtess and tesselation tests (QNX native and SDL 1.3) have been added. +1.2 - SDL 1.3 based tests were added. +1.1 - Removed some texture formats, which are not supported by OpenGL ES 1.x, + added arrays manipulation to the quadric functions. Sphere flat shading + fixes. Disk texturing with inner radius more than 0.0f fixes. Updated + tests. +1.0 - Initial public release. + +// 11.11.2009 +// Mike Gorchak , diff --git a/project/jni/glu/include/GL/glu.h b/project/jni/glu/include/GL/glu.h new file mode 120000 index 000000000..91417d843 --- /dev/null +++ b/project/jni/glu/include/GL/glu.h @@ -0,0 +1 @@ +../../src/glues.h \ No newline at end of file diff --git a/project/jni/glu/src/glu.h b/project/jni/glu/src/glu.h new file mode 120000 index 000000000..1f3dcebb0 --- /dev/null +++ b/project/jni/glu/src/glu.h @@ -0,0 +1 @@ +glues.h \ No newline at end of file diff --git a/project/jni/glu/src/glues.h b/project/jni/glu/src/glues.h new file mode 100644 index 000000000..6f7ce924c --- /dev/null +++ b/project/jni/glu/src/glues.h @@ -0,0 +1,406 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#elif defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64)) + /* mainly for PowerVR OpenGL ES 1.x win32 emulator */ + #include + #include + #undef APIENTRY + #define APIENTRY + #if defined(GLUES_EXPORTS) + #define GLAPI __declspec(dllexport) + #else + #define GLAPI __declspec(dllimport) + #endif +#else + #error "Platform is unsupported" +#endif + +#ifndef APIENTRYP + #define APIENTRYP APIENTRY * +#endif /* APIENTRYP */ + +#ifdef __cplusplus + extern "C" { +#endif + +/*************************************************************/ + +/* Extensions */ +#define GLU_EXT_object_space_tess 1 +#define GLU_EXT_nurbs_tessellator 1 + +/* 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; +class GLUnurbs; +#else +typedef struct GLUquadric GLUquadric; +typedef struct GLUtesselator GLUtesselator; +typedef struct GLUnurbs GLUnurbs; +#endif + +typedef GLUquadric GLUquadricObj; +typedef GLUtesselator GLUtesselatorObj; +typedef GLUtesselator GLUtriangulatorObj; +typedef GLUnurbs GLUnurbsObj; + +/* 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); + +/* NurbsDisplay */ +/* GLU_FILL */ +#define GLU_OUTLINE_POLYGON 100240 +#define GLU_OUTLINE_PATCH 100241 + +/* NurbsCallback */ +#define GLU_NURBS_ERROR 100103 +#define GLU_ERROR 100103 +#define GLU_NURBS_BEGIN 100164 +#define GLU_NURBS_BEGIN_EXT 100164 +#define GLU_NURBS_VERTEX 100165 +#define GLU_NURBS_VERTEX_EXT 100165 +#define GLU_NURBS_NORMAL 100166 +#define GLU_NURBS_NORMAL_EXT 100166 +#define GLU_NURBS_COLOR 100167 +#define GLU_NURBS_COLOR_EXT 100167 +#define GLU_NURBS_TEXTURE_COORD 100168 +#define GLU_NURBS_TEX_COORD_EXT 100168 +#define GLU_NURBS_END 100169 +#define GLU_NURBS_END_EXT 100169 +#define GLU_NURBS_BEGIN_DATA 100170 +#define GLU_NURBS_BEGIN_DATA_EXT 100170 +#define GLU_NURBS_VERTEX_DATA 100171 +#define GLU_NURBS_VERTEX_DATA_EXT 100171 +#define GLU_NURBS_NORMAL_DATA 100172 +#define GLU_NURBS_NORMAL_DATA_EXT 100172 +#define GLU_NURBS_COLOR_DATA 100173 +#define GLU_NURBS_COLOR_DATA_EXT 100173 +#define GLU_NURBS_TEXTURE_COORD_DATA 100174 +#define GLU_NURBS_TEX_COORD_DATA_EXT 100174 +#define GLU_NURBS_END_DATA 100175 +#define GLU_NURBS_END_DATA_EXT 100175 + +/* 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 + +/* NurbsProperty */ +#define GLU_AUTO_LOAD_MATRIX 100200 +#define GLU_CULLING 100201 +#define GLU_SAMPLING_TOLERANCE 100203 +#define GLU_DISPLAY_MODE 100204 +#define GLU_PARAMETRIC_TOLERANCE 100202 +#define GLU_SAMPLING_METHOD 100205 +#define GLU_U_STEP 100206 +#define GLU_V_STEP 100207 +#define GLU_NURBS_MODE 100160 +#define GLU_NURBS_MODE_EXT 100160 +#define GLU_NURBS_TESSELLATOR 100161 +#define GLU_NURBS_TESSELLATOR_EXT 100161 +#define GLU_NURBS_RENDERER 100162 +#define GLU_NURBS_RENDERER_EXT 100162 + +/* NurbsSampling */ +#define GLU_OBJECT_PARAMETRIC_ERROR 100208 +#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208 +#define GLU_OBJECT_PATH_LENGTH 100209 +#define GLU_OBJECT_PATH_LENGTH_EXT 100209 +#define GLU_PATH_LENGTH 100215 +#define GLU_PARAMETRIC_ERROR 100216 +#define GLU_DOMAIN_DISTANCE 100217 + +/* NurbsTrim */ +#define GLU_MAP1_TRIM_2 100210 +#define GLU_MAP1_TRIM_3 100211 + +GLAPI void APIENTRY gluBeginCurve(GLUnurbs* nurb); +GLAPI void APIENTRY gluBeginSurface(GLUnurbs* nurb); +GLAPI void APIENTRY gluBeginTrim(GLUnurbs* nurb); +GLAPI void APIENTRY gluDeleteNurbsRenderer(GLUnurbs* nurb); +GLAPI void APIENTRY gluEndCurve(GLUnurbs* nurb); +GLAPI void APIENTRY gluEndSurface(GLUnurbs* nurb); +GLAPI void APIENTRY gluEndTrim(GLUnurbs* nurb); +GLAPI void APIENTRY gluGetNurbsProperty(GLUnurbs* nurb, GLenum property, GLfloat* data); +GLAPI void APIENTRY gluLoadSamplingMatrices(GLUnurbs* nurb, const GLfloat* model, const GLfloat* perspective, const GLint* view); +GLAPI GLUnurbs* APIENTRY gluNewNurbsRenderer(void); +GLAPI void APIENTRY gluNurbsCallback(GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc); +GLAPI void APIENTRY gluNurbsCallbackData(GLUnurbs* nurb, GLvoid* userData); +GLAPI void APIENTRY gluNurbsCallbackDataEXT(GLUnurbs* nurb, GLvoid* userData); +GLAPI void APIENTRY gluNurbsCurve(GLUnurbs* nurb, GLint knotCount, GLfloat* knots, GLint stride, GLfloat* control, GLint order, GLenum type); +GLAPI void APIENTRY gluNurbsProperty(GLUnurbs* nurb, GLenum property, GLfloat value); +GLAPI void APIENTRY gluNurbsSurface(GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type); +GLAPI void APIENTRY gluPwlCurve(GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type); + +/* OpenGL (and OpenGL ES 1.1 for OpenGL ES 1.0) emulation layer */ +#define GLU_AUTO_NORMAL 0x0D80 + +#define GLU_MAP1_COLOR_4 0x0D90 +#define GLU_MAP1_INDEX 0x0D91 +#define GLU_MAP1_NORMAL 0x0D92 +#define GLU_MAP1_TEXTURE_COORD_1 0x0D93 +#define GLU_MAP1_TEXTURE_COORD_2 0x0D94 +#define GLU_MAP1_TEXTURE_COORD_3 0x0D95 +#define GLU_MAP1_TEXTURE_COORD_4 0x0D96 +#define GLU_MAP1_VERTEX_3 0x0D97 +#define GLU_MAP1_VERTEX_4 0x0D98 +#define GLU_MAP2_COLOR_4 0x0DB0 +#define GLU_MAP2_INDEX 0x0DB1 +#define GLU_MAP2_NORMAL 0x0DB2 +#define GLU_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GLU_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GLU_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GLU_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GLU_MAP2_VERTEX_3 0x0DB7 +#define GLU_MAP2_VERTEX_4 0x0DB8 + +#ifndef GL_MODELVIEW_MATRIX + #define GL_MODELVIEW_MATRIX 0x0BA6 +#endif /* GL_MODELVIEW_MATRIX */ + +#ifndef GL_PROJECTION_MATRIX + #define GL_PROJECTION_MATRIX 0x0BA7 +#endif /* GL_PROJECTION_MATRIX */ + +#ifndef GL_VIEWPORT + #define GL_VIEWPORT 0x0BA2 +#endif /* GL_VIEWPORT */ + +GLAPI void APIENTRY gluEnable(GLenum cap); +GLAPI void APIENTRY gluDisable(GLenum cap); +GLAPI void APIENTRY gluGetFloatv(GLenum pname, GLfloat* params); +GLAPI void APIENTRY gluGetIntegerv(GLenum pname, GLint* params); +GLAPI void APIENTRY gluViewport(GLint x, GLint y, GLsizei width, GLsizei height); + +#ifdef __cplusplus +} +#endif + +#endif /* __glues_h__ */ diff --git a/project/jni/glu/src/glues_error.c b/project/jni/glu/src/glues_error.c new file mode 100644 index 000000000..128587e1b --- /dev/null +++ b/project/jni/glu/src/glues_error.c @@ -0,0 +1,149 @@ +/* + * 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 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/project/jni/glu/src/glues_error.h b/project/jni/glu/src/glues_error.h new file mode 100644 index 000000000..979d2b160 --- /dev/null +++ b/project/jni/glu/src/glues_error.h @@ -0,0 +1,139 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#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 +#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/project/jni/glu/src/glues_mipmap.c b/project/jni/glu/src/glues_mipmap.c new file mode 100644 index 000000000..54baa86b4 --- /dev/null +++ b/project/jni/glu/src/glues_mipmap.c @@ -0,0 +1,2275 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#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 +#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/project/jni/glu/src/glues_project.c b/project/jni/glu/src/glues_project.c new file mode 100644 index 000000000..66464f752 --- /dev/null +++ b/project/jni/glu/src/glues_project.c @@ -0,0 +1,378 @@ +/* + * 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 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/project/jni/glu/src/glues_project.h b/project/jni/glu/src/glues_project.h new file mode 100644 index 000000000..4826b20ca --- /dev/null +++ b/project/jni/glu/src/glues_project.h @@ -0,0 +1,92 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#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 +#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/project/jni/glu/src/glues_quad.c b/project/jni/glu/src/glues_quad.c new file mode 100644 index 000000000..4e9e785ee --- /dev/null +++ b/project/jni/glu/src/glues_quad.c @@ -0,0 +1,1650 @@ +/* + * 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 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/project/jni/glu/src/glues_quad.h b/project/jni/glu/src/glues_quad.h new file mode 100644 index 000000000..fb18b0c61 --- /dev/null +++ b/project/jni/glu/src/glues_quad.h @@ -0,0 +1,135 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#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 +#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/project/jni/glu/src/glues_registry.c b/project/jni/glu/src/glues_registry.c new file mode 100644 index 000000000..ff3947fbc --- /dev/null +++ b/project/jni/glu/src/glues_registry.c @@ -0,0 +1,99 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#include +#include +#include + +#include "glues_registry.h" + +static const GLubyte versionString[]="1.3 GLU ES-CM"; +static const GLubyte extensionString[]="GLU_EXT_object_space_tess GLU_EXT_nurbs_tessellator"; + +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/project/jni/glu/src/glues_registry.h b/project/jni/glu/src/glues_registry.h new file mode 100644 index 000000000..ff66f2c67 --- /dev/null +++ b/project/jni/glu/src/glues_registry.h @@ -0,0 +1,87 @@ +/* + * 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 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__) || defined (__ANDROID__) + #include + #include + #ifndef GLAPI + #define GLAPI GL_API + #endif + #ifndef APIENTRY + #define APIENTRY GL_APIENTRY + #endif + #ifndef APIENTRYP + #define APIENTRYP GL_APIENTRYP + #endif +#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 +#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/project/jni/glu/src/libnurbs/interface/bezierEval.cc b/project/jni/glu/src/libnurbs/interface/bezierEval.cc new file mode 100644 index 000000000..88f935d1c --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/bezierEval.cc @@ -0,0 +1,249 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include +#include + +#include "bezierEval.h" + +#ifdef __WATCOMC__ + #pragma warning 14 10 +#endif + +#define TOLERANCE 0.0001 + +#ifndef MAX_ORDER + #define MAX_ORDER 16 +#endif + +#ifndef MAX_DIMENSION + #define MAX_DIMENSION 4 +#endif + +static void normalize(float vec[3]); +static void crossProduct(float x[3], float y[3], float ret[3]); + +static float binomialCoefficients[8][8]= +{ + {1, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0}, + {1, 2, 1, 0, 0, 0, 0, 0}, + {1, 3, 3, 1, 0, 0, 0, 0}, + {1, 4, 6, 4, 1, 0, 0, 0}, + {1, 5, 10, 10, 5, 1, 0, 0}, + {1, 6, 15, 20, 15, 6, 1, 0}, + {1, 7, 21, 35, 35, 21, 7, 1} +}; + +void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]) +{ + float uprime=(u-u0)/(u1-u0); + float* ctlptr=ctlpoints; + float oneMinusX=1.0f-uprime; + float XPower=1.0f; + + int i, k; + + for(k=0; k=1. */ +void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]) +{ + int i, k; + float width=u1-u0; + float* ctlptr=ctlpoints; + float buf[MAX_ORDER][MAX_DIMENSION]; + + if (order==1) + { + for(k=0; k=3 && dimension <=4); + bezierSurfEvalDerGen(1,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialU); + bezierSurfEvalDerGen(0,1, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialV); + + if (dimension == 3) /* inhomogeneous */ + { + crossProduct(partialU, partialV, retNormal); + normalize(retNormal); + return; + } + else /* homogeneous */ + { + float val[4]; /* the point coordinates (without derivative) */ + float newPartialU[MAX_DIMENSION]; + float newPartialV[MAX_DIMENSION]; + int i; + + bezierSurfEvalDerGen(0,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, val); + + for(i=0; i<=2; i++) + { + newPartialU[i]=partialU[i]*val[3]-val[i]*partialU[3]; + newPartialV[i]=partialV[i]*val[3]-val[i]*partialV[3]; + } + crossProduct(newPartialU, newPartialV, retNormal); + normalize(retNormal); + } +} + +/* if size is 0, then nothing is done */ +static void normalize(float vec[3]) +{ + float size=(float)sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); + + if (size +*/ + +#ifndef _BEZIEREVAL_H +#define _BEZIEREVAL_H + +void bezierCurveEval(float u0, float u1, int order, float* ctlpoints, int stride, int dimension, float u, float retpoint[]); +void bezierCurveEvalDer(float u0, float u1, int order, float* ctlpoints, int stride, int dimension, float u, float retDer[]); +void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float* ctlpoints, int stride, int dimension, float u, float retDer[]); +void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float* ctlpoints, int ustride, int vstride, float u, float v, float ret[]); +void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float* ctlpoints, int ustride, int vstride, float u, float v, float ret[]); +void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float* ctlpoints, int ustride, int vstride, float u, float v, float retNormal[]); + +#endif /* _BEZIEREVAL_H */ diff --git a/project/jni/glu/src/libnurbs/interface/bezierPatch.cc b/project/jni/glu/src/libnurbs/interface/bezierPatch.cc new file mode 100644 index 000000000..169378082 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/bezierPatch.cc @@ -0,0 +1,176 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include + +#include "bezierPatch.h" +#include "bezierEval.h" + +/* + * allocate an instance of bezierPatch. The control points are unknown. But + * the space of this array is allocated with size of + * uorder*vorder*dimension + * + */ +bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension) +{ + bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch)); + assert(ret); + ret->umin=umin; + ret->vmin=vmin; + ret->umax=umax; + ret->vmax=vmax; + ret->uorder=uorder; + ret->vorder=vorder; + ret->dimension=dimension; + ret->ctlpoints=(float*)malloc(sizeof(float)*dimension*uorder*vorder); + assert(ret->ctlpoints); + + ret->next=NULL; + + return ret; +} + +bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension, int ustride, int vstride, float* ctlpoints) +{ + bezierPatch* ret=(bezierPatch*)malloc(sizeof(bezierPatch)); + assert(ret); + ret->umin=umin; + ret->vmin=vmin; + ret->umax=umax; + ret->vmax=vmax; + ret->uorder=uorder; + ret->vorder=vorder; + ret->dimension=dimension; + ret->ctlpoints=(float*)malloc(sizeof(float)*dimension*uorder*vorder); + assert(ret->ctlpoints); + + /* copy the control points there */ + int the_ustride=vorder*dimension; + int the_vstride=dimension; + + for(int i=0; ictlpoints[i*the_ustride+j*the_vstride+k]=ctlpoints[i*ustride+j*vstride+k]; + } + } + } + + ret->next=NULL; + + return ret; +} + +/* + * deallocate the space as allocated by Make + */ +void bezierPatchDelete(bezierPatch* b) +{ + free(b->ctlpoints); + free(b); +} + +/* delete the whole linked list */ +void bezierPatchDeleteList(bezierPatch* b) +{ + bezierPatch* temp; + + while (b!=NULL) + { + temp=b; + b=b->next; + bezierPatchDelete(temp); + } +} + +bezierPatch* bezierPatchInsert(bezierPatch* list, bezierPatch* b) +{ + b->next=list; + + return b; +} + +void bezierPatchEval(bezierPatch* b, float u, float v, float ret[]) +{ + if (u>=b->umin && u<=b->umax && v>=b->vmin && v<=b->vmax) + { + bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension*b->vorder, b->dimension, u, v, ret); + } + else + { + if (b->next!=NULL) + { + bezierPatchEval(b->next, u, v, ret); + } + else + { + bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension*b->vorder, b->dimension, u, v, ret); + } + } +} + +/* the returned normal is normlized + */ +void bezierPatchEvalNormal(bezierPatch* b, float u, float v, float ret[]) +{ + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + + if (u>=b->umin && u<=b->umax && v>=b->vmin && v<=b->vmax) + { + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + } + else + { + if (b->next!=NULL) + { + bezierPatchEvalNormal(b->next, u, v, ret); + } + else + { + bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret); + } + } +} diff --git a/project/jni/glu/src/libnurbs/interface/bezierPatch.h b/project/jni/glu/src/libnurbs/interface/bezierPatch.h new file mode 100644 index 000000000..c43cc83ba --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/bezierPatch.h @@ -0,0 +1,87 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _BEZIERPATCH_H +#define _BEZIERPATCH_H + +typedef struct bezierPatch +{ + float umin, vmin, umax, vmax; + int uorder; /* order= degree + 1 */ + int vorder; + + /* + * the control points are stored in a one dimensional array. + * the surface is defined as: + * s(u,v) = sum_{i,j} P(i,j) * B_i(u) * B_j(v). + * where P(i,j) are the control points, B_i(.) are Bezier + * basis functions. + * Each control point can have dimension 3 or 4: (x,y,z,w). + * The components of P(i,j) are stored in a one dimensional + * array: + * ctlpoints[] + * in the order of: + * P[0,0], P[0,1], ..., P[0,vorder-1], + * P[1,0], P[1,1], ..., P[1,vorder-1], + * ... + * P[uorder-1,0], P[uorder-1,1], ..., P[uorder-1,vorder-1]. + */ + int dimension; + float* ctlpoints; + + /* + * in case we have to manage multiple bezierPatches. + */ + struct bezierPatch* next; +} bezierPatch; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension); +bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension, int ustride, int vstride, float* ctlpoints); +bezierPatch* bezierPatchInsert(bezierPatch* list, bezierPatch* b); +void bezierPatchDelete(bezierPatch* b); +void bezierPatchDeleteList(bezierPatch* b); +void bezierPatchEval(bezierPatch* b, float u, float v, float ret[]); +void bezierPatchEvalNormal(bezierPatch* b, float u, float v, float retNormal[]); +void bezierPatchEval(bezierPatch* b, float u, float v, float ret[]); +void bezierPatchEvalNormal(bezierPatch* b, float u, float v, float ret[]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BEZIERPATCH_H */ diff --git a/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.cc b/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.cc new file mode 100644 index 000000000..f9bd32992 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.cc @@ -0,0 +1,588 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include +#include + +#include "bezierEval.h" +#include "bezierPatchMesh.h" + +#include "gles_evaluator.h" + +static int isDegenerate(float A[2], float B[2], float C[2]); + +void bezierPatchMeshListDelDeg(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for (temp=list; temp!=NULL; temp=temp->next) + { + bezierPatchMeshDelDeg(temp); + } +} + +void bezierPatchMeshListDelete(bezierPatchMesh* list) +{ + if (list==NULL) + { + return; + } + bezierPatchMeshListDelete(list->next); + bezierPatchMeshDelete(list); +} + +bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list) +{ + bezierPatchMesh* ret=NULL; + bezierPatchMesh* temp; + bezierPatchMesh* nextone; + + for(temp=list; temp!=NULL; temp=nextone) + { + nextone=temp->next; + ret=bezierPatchMeshListInsert(ret, temp); + } + + return ret; +} + +/* maptype is either GLU_MAP2_VERTEX_3 or GLU_MAP2_VERTEX_4 */ +bezierPatchMesh* bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float* ctlpoints, int size_UVarray, int size_length_array) +{ + int i, j, k; + int dimension; + int the_ustride; + int the_vstride; + + if (maptype==GLU_MAP2_VERTEX_3) + { + dimension=3; + } + else + { + if (maptype==GLU_MAP2_VERTEX_4) + { + dimension = 4; + } + else + { + fprintf(stderr, "error in inMap2f, maptype=%i is wrong, maptype,map is invalid\n", maptype); + return NULL; + } + } + + bezierPatchMesh* ret=(bezierPatchMesh*)malloc(sizeof(bezierPatchMesh)); + assert(ret); + + ret->bpatch_normal=NULL; + ret->bpatch_color=NULL; + ret->bpatch_texcoord=NULL; + ret->bpatch=bezierPatchMake(umin, vmin, umax, vmax, uorder, vorder, dimension); + + /* copy the control points there */ + the_ustride = vorder * dimension; + the_vstride = dimension; + + for(i=0; ibpatch->ctlpoints[i*the_ustride+j*the_vstride+k]=ctlpoints[i*ustride+j*vstride+k]; + } + } + } + + ret->size_UVarray=size_UVarray; + ret->size_length_array=size_length_array; + ret->UVarray=(float*)malloc(sizeof(float)*size_UVarray); + assert(ret->UVarray); + ret->length_array=(int*)malloc(sizeof(int)*size_length_array); + assert(ret->length_array); + ret->type_array=(GLenum*)malloc(sizeof(GLenum)*size_length_array); + assert(ret->type_array); + + ret->index_UVarray=0; + ret->index_length_array=0; + + ret->vertex_array=NULL; + ret->normal_array=NULL; + ret->color_array=NULL; + ret->texcoord_array=NULL; + + ret->next=NULL; + + return ret; +} + +bezierPatchMesh* bezierPatchMeshMake2(int size_UVarray, int size_length_array) +{ + bezierPatchMesh* ret=(bezierPatchMesh*)malloc(sizeof(bezierPatchMesh)); + assert(ret); + + ret->bpatch=NULL; + ret->bpatch_normal=NULL; + ret->bpatch_color=NULL; + ret->bpatch_texcoord=NULL; + + ret->size_UVarray=size_UVarray; + ret->size_length_array=size_length_array; + ret->UVarray=(float*)malloc(sizeof(float)*size_UVarray); + assert(ret->UVarray); + ret->length_array=(int*)malloc(sizeof(int)*size_length_array); + assert(ret->length_array); + ret->type_array=(GLenum*)malloc(sizeof(GLenum)*size_length_array); + assert(ret->type_array); + + ret->index_UVarray=0; + ret->index_length_array=0; + + ret->vertex_array=NULL; + ret->normal_array=NULL; + ret->color_array=NULL; + ret->texcoord_array=NULL; + + ret->next=NULL; + + return ret; +} + +void bezierPatchMeshPutPatch(bezierPatchMesh* bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float* ctlpoints) +{ + switch(maptype) + { + case GLU_MAP2_VERTEX_3: + bpm->bpatch=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_VERTEX_4: + bpm->bpatch=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4,ustride, vstride, ctlpoints); + break; + case GLU_MAP2_NORMAL: + bpm->bpatch_normal=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_INDEX: + bpm->bpatch_color=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_COLOR_4: + bpm->bpatch_color=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_TEXTURE_COORD_1: + bpm->bpatch_texcoord=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_TEXTURE_COORD_2: + bpm->bpatch_texcoord=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 2, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_TEXTURE_COORD_3: + bpm->bpatch_texcoord=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints); + break; + case GLU_MAP2_TEXTURE_COORD_4: + bpm->bpatch_texcoord=bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints); + break; + default: + fprintf(stderr, "error in bezierPatchMeshPutPatch, maptype=%i is wrong, maptype,map is invalid\n", maptype); + } +} + +/* delete everything including the arrays. So if you want to output the + * pointers of the arrays, you should not use this function to deallocate space. + * you should dealocate manually + */ +void bezierPatchMeshDelete(bezierPatchMesh* bpm) +{ + if(bpm->bpatch!=NULL) + { + bezierPatchDelete(bpm->bpatch); + } + if (bpm->bpatch_normal!=NULL) + { + bezierPatchDelete(bpm->bpatch_normal); + } + if (bpm->bpatch_color!=NULL) + { + bezierPatchDelete(bpm->bpatch_color); + } + if (bpm->bpatch_texcoord!=NULL) + { + bezierPatchDelete(bpm->bpatch_texcoord); + } + + free(bpm->UVarray); + free(bpm->length_array); + free(bpm->vertex_array); + free(bpm->normal_array); + free(bpm->type_array); + free(bpm); +} + +/* begin a strip + * type is the primitive type: + */ +void bezierPatchMeshBeginStrip(bezierPatchMesh* bpm, GLenum type) +{ + bpm->counter=0; + bpm->type=type; +} + +/* signal the end of the current strip */ +void bezierPatchMeshEndStrip(bezierPatchMesh* bpm) +{ + int i; + + /* if there are no vertices in this strip, then nothing needs to be done */ + if (bpm->counter==0) + { + return; + } + + /* if the length_array is full, it should be expanded */ + if(bpm->index_length_array>=bpm->size_length_array) + { + int* temp=(int*)malloc(sizeof(int)*(bpm->size_length_array*2+1)); + assert(temp); + GLenum* temp_type=(GLenum*)malloc(sizeof(GLenum)*(bpm->size_length_array*2+1)); + assert(temp_type); + + /* update the size */ + bpm->size_length_array = bpm->size_length_array*2 + 1; + + /* copy */ + for(i=0; iindex_length_array; i++) + { + temp[i]=bpm->length_array[i]; + temp_type[i]=bpm->type_array[i]; + } + + /* deallocate old array */ + free(bpm->length_array); + free(bpm->type_array); + + /* point to the new array which is twice as bigger */ + bpm->length_array=temp; + bpm->type_array=temp_type; + } + bpm->type_array[bpm->index_length_array]=bpm->type; + bpm->length_array[bpm->index_length_array++]=bpm->counter; +} + +/* insert (u,v) */ +void bezierPatchMeshInsertUV(bezierPatchMesh* bpm, float u, float v) +{ + int i; + + /* if the UVarray is full, it should be expanded */ + if (bpm->index_UVarray+1>=bpm->size_UVarray) + { + float* temp=(float*)malloc(sizeof(float)*(bpm->size_UVarray*2+2)); + assert(temp); + + /* update the size */ + bpm->size_UVarray=bpm->size_UVarray*2+2; + + /* copy */ + for (i=0; iindex_UVarray; i++) + { + temp[i]=bpm->UVarray[i]; + } + + /* deallocate old array */ + free(bpm->UVarray); + + /* pointing to the new arrays */ + bpm->UVarray=temp; + } + + /*insert the new UV*/ + bpm->UVarray[bpm->index_UVarray]=u; + bpm->index_UVarray++; + bpm->UVarray[bpm->index_UVarray]=v; + bpm->index_UVarray++; + + /* update counter: one more vertex */ + bpm->counter++; +} + +/* insert a new patch in front of the current linked list and return the new list */ +bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm) +{ + bpm->next=list; + return bpm; +} + +int bezierPatchMeshListTotalStrips(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh* temp; + + for(temp=list; temp!=NULL; temp=temp->next) + { + sum+=temp->index_length_array; + } + + return sum; +} + +int bezierPatchMeshListTotalVert(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh* temp; + + for(temp=list; temp!=NULL; temp=temp->next) + { + sum+=temp->index_UVarray; + } + + return sum/2; +} + +int bezierPatchMeshListNumTriangles(bezierPatchMesh* list) +{ + int sum=0; + bezierPatchMesh* temp; + + for(temp=list; temp!=NULL; temp=temp->next) + { + sum+=bezierPatchMeshNumTriangles(temp); + } + + return sum; +} + +int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm) +{ + int i; + int sum=0; + + for(i=0; iindex_length_array; i++) + { + switch(bpm->type_array[i]) + { + case GL_TRIANGLES: + sum+=bpm->length_array[i]/3; + break; + case GL_TRIANGLE_FAN: + if (bpm->length_array[i]>2) + { + sum+=bpm->length_array[i]-2; + } + break; + case GL_TRIANGLE_STRIP: + if(bpm->length_array[i]>2) + { + sum+=bpm->length_array[i]-2; + } + break; + default: + fprintf(stderr, "error in bezierPatchMeshListNumTriangles, type invalid\n"); + break; + } + } + + return sum; +} + +/*delete degenerate triangles*/ +void bezierPatchMeshDelDeg(bezierPatchMesh* bpm) +{ + if (bpm==NULL) + { + return; + } + + int i, j, k; + int* new_length_array; + GLenum* new_type_array; + int index_new_length_array; + float* new_UVarray; + int index_new_UVarray; + + new_length_array=(int*)malloc(sizeof(int)*bpm->index_length_array); + assert(new_length_array); + new_type_array=(GLenum*)malloc(sizeof(GLenum)*bpm->index_length_array); + assert(new_length_array); + new_UVarray=(float*)malloc(sizeof(float)*bpm->index_UVarray); + assert(new_UVarray); + + index_new_length_array=0; + index_new_UVarray=0; + k=0; + + for(i=0; iindex_length_array; i++) + { + /* (if not degenerate, we have to copy */ + if ((bpm->length_array[i]!=3) || (!isDegenerate(bpm->UVarray+k, bpm->UVarray+k+2, bpm->UVarray+k+4))) + { + for(j=0; j<2*bpm->length_array[i]; j++) + { + new_UVarray[index_new_UVarray++]=bpm->UVarray[k++]; + } + + new_length_array[index_new_length_array]=bpm->length_array[i]; + new_type_array[index_new_length_array]=bpm->type_array[i]; + index_new_length_array++; + } + else + { + k+=6; + } + } + + free(bpm->UVarray); + free(bpm->length_array); + free(bpm->type_array); + + bpm->UVarray=new_UVarray; + bpm->length_array=new_length_array; + bpm->type_array=new_type_array; + bpm->index_UVarray=index_new_UVarray; + bpm->index_length_array=index_new_length_array; +} + +/* (u,v) to XYZ + * the xyz and normals are stored in vertex_array, + * and normal_array. the spaces of both are allocated here + */ +void bezierPatchMeshEval(bezierPatchMesh* bpm) +{ + int i, j, k, l; + float u, v; + float u0=bpm->bpatch->umin; + float u1=bpm->bpatch->umax; + int uorder=bpm->bpatch->uorder; + float v0=bpm->bpatch->vmin; + float v1=bpm->bpatch->vmax; + int vorder=bpm->bpatch->vorder; + int dimension=bpm->bpatch->dimension; + int ustride=dimension*vorder; + int vstride=dimension; + float* ctlpoints=bpm->bpatch->ctlpoints; + + bpm->vertex_array=(float*)malloc(sizeof(float)*(bpm->index_UVarray/2)*3); + assert(bpm->vertex_array); + bpm->normal_array=(float*)malloc(sizeof(float)*(bpm->index_UVarray/2)*3); + assert(bpm->normal_array); + + k=0; + l=0; + + for (i=0; iindex_length_array; i++) + { + for(j=0; jlength_array[i]; j++) + { + u=bpm->UVarray[k]; + v=bpm->UVarray[k+1]; + bezierSurfEval(u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, bpm->vertex_array+l); + bezierSurfEvalNormal(u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, bpm->normal_array+l); + k+=2; + l+=3; + } + } +} + +void bezierPatchMeshListEval(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + + for(temp=list; temp!=NULL; temp=temp->next) + { + bezierPatchMeshEval(temp); + } +} + +void bezierPatchMeshListCollect(bezierPatchMesh* list, float** vertex_array, float** normal_array, int** length_array, GLenum** type_array, int* num_strips) +{ + int i, j, k, l; + bezierPatchMesh* temp; + int total_num_vertices=bezierPatchMeshListTotalVert(list); + (*vertex_array)=(float*)malloc(sizeof(float)*total_num_vertices*3); + assert(*vertex_array); + (*normal_array)=(float*)malloc(sizeof(float)*total_num_vertices*3); + assert(*normal_array); + + *num_strips=bezierPatchMeshListTotalStrips(list); + + *length_array=(int*)malloc(sizeof(int)*(*num_strips)); + assert(*length_array); + + *type_array=(GLenum*)malloc(sizeof(GLenum)*(*num_strips)); + assert(*type_array); + + k=0; + l=0; + + for(temp=list; temp!=NULL; temp=temp->next) + { + int x=0; + + for(i=0; iindex_length_array; i++) + { + for(j=0; jlength_array[i]; j++) + { + (*vertex_array)[k]=temp->vertex_array[x]; + (*vertex_array)[k+1]=temp->vertex_array[x+1]; + (*vertex_array)[k+2]=temp->vertex_array[x+2]; + + (*normal_array)[k]=temp->normal_array[x]; + (*normal_array)[k+1]=temp->normal_array[x+1]; + (*normal_array)[k+2]=temp->normal_array[x+2]; + + x+=3; + k+=3; + } + (*type_array)[l]=temp->type_array[i]; + (*length_array)[l++]=temp->length_array[i]; + } + } +} + +static int isDegenerate(float A[2], float B[2], float C[2]) +{ + if ((A[0]==B[0] && A[1]==B[1]) || + (A[0]==C[0] && A[1]==C[1]) || + (B[0]==C[0] && B[1]==C[1])) + { + return 1; + } + else + { + return 0; + } +} diff --git a/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.h b/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.h new file mode 100644 index 000000000..15fec4e66 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/bezierPatchMesh.h @@ -0,0 +1,106 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _BEZIERPATCHMESH_H +#define _BEZIERPATCHMESH_H + +#include "bezierPatch.h" + +typedef struct bezierPatchMesh +{ + bezierPatch* bpatch; /* vertex */ + bezierPatch* bpatch_normal; + bezierPatch* bpatch_texcoord; /* s,t,r,q */ + bezierPatch* bpatch_color; /* RGBA */ + + float* UVarray; /* all UV components of all vertices of all strips */ + int* length_array; /* [i] is the number of vertices in the ith strip */ + GLenum* type_array; /* [i] is the type of the ith primitive */ + + /* to support dynamic insertion */ + int size_UVarray; + int index_UVarray; + int size_length_array; + int index_length_array; + + int counter; /* track the current strip size */ + GLenum type; /* track the current type: 0: GL_TRIANGLES, 1: GL_TRIANGLE_STRIP */ + + /* we eventually want to evaluate from (u,v) to (x,y,z) and draw them */ + float* vertex_array; /* each vertex contains three components */ + float* normal_array; /* each normal contains three components */ + float* color_array; + float* texcoord_array; + + /*in case we need a linked list*/ + struct bezierPatchMesh* next; +} bezierPatchMesh; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +bezierPatchMesh* bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints, int size_UVarray, int size_length_array); + +/*initilize patches to be null*/ +bezierPatchMesh* bezierPatchMeshMake2(int size_UVarray, int size_length_array); + +void bezierPatchMeshPutPatch(bezierPatchMesh* bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float* ctlpoints); +void bezierPatchMeshDelete(bezierPatchMesh* bpm); +void bezierPatchMeshBeginStrip(bezierPatchMesh* bpm, GLenum type); +void bezierPatchMeshEndStrip(bezierPatchMesh* bpm); +void bezierPatchMeshInsertUV(bezierPatchMesh* bpm, float u, float v); + +bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm); + +int bezierPatchMeshListTotalStrips(bezierPatchMesh* list); + +int bezierPatchMeshListTotalVert(bezierPatchMesh* list); +int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm); +int bezierPatchMeshListNumTriangles(bezierPatchMesh* list); + +void bezierPatchMeshDelDeg(bezierPatchMesh* bpm); +void bezierPatchMeshEval(bezierPatchMesh* bpm); +void bezierPatchMeshListEval(bezierPatchMesh* list); +void bezierPatchMeshListCollect(bezierPatchMesh* list, float** vertex_array, float** normal_array, int** length_array, GLenum** type_array, int* num_strips); + +void bezierPatchMeshListDelDeg(bezierPatchMesh* list); +void bezierPatchMeshListDelete(bezierPatchMesh* list); +bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BEZIERPATCHMESH_H */ diff --git a/project/jni/glu/src/libnurbs/interface/glcurveval.cc b/project/jni/glu/src/libnurbs/interface/glcurveval.cc new file mode 100644 index 000000000..43eb4ef7d --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glcurveval.cc @@ -0,0 +1,459 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak + */ + +/* Polynomial Evaluator Interface */ + +#include "glues.h" +#include "gles_evaluator.h" +#include "glimports.h" +#include "glrenderer.h" +#include "glcurveval.h" +#include "nurbsconsts.h" + +OpenGLCurveEvaluator::OpenGLCurveEvaluator(void) +{ + // no default callback functions + beginCallBackN=NULL; + endCallBackN=NULL; + vertexCallBackN=NULL; + normalCallBackN=NULL; + colorCallBackN=NULL; + texcoordCallBackN=NULL; + beginCallBackData=NULL; + endCallBackData=NULL; + vertexCallBackData=NULL; + normalCallBackData=NULL; + colorCallBackData=NULL; + texcoordCallBackData=NULL; + + userData=NULL; + + vertex_flag=0; + normal_flag=0; + color_flag=0; + texcoord_flag=0; + + em_vertex.uprime=-1.0; + em_normal.uprime=-1.0; + em_color.uprime=-1.0; + em_texcoord.uprime=-1.0; + + // don't output triangles by default + output_triangles=0; +} + +OpenGLCurveEvaluator::~OpenGLCurveEvaluator(void) +{ +} + +/* added nonsense to avoid the warning messages at compile time */ +void OpenGLCurveEvaluator::addMap(CurveMap* m) +{ + m=m; +} + +void OpenGLCurveEvaluator::range1f(long type, REAL* from, REAL* to) +{ + type=type; + from=from; + to=to; +} + +void OpenGLCurveEvaluator::domain1f(REAL ulo, REAL uhi) +{ + ulo=ulo; + uhi=uhi; +} + +void OpenGLCurveEvaluator::bgnline(void) +{ + if (output_triangles) + { + beginCallBack(GL_LINE_STRIP, userData); + } +} + +void OpenGLCurveEvaluator::endline(void) +{ + if (output_triangles) + { + endCallBack(userData); + } +} + +/*--------------------------------------------------------------------------- + * disable - turn off a curve map + *--------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::disable(long type) +{ + gluDisable((GLenum)type); +} + +/*--------------------------------------------------------------------------- + * enable - turn on a curve map + *--------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::enable(long type) +{ + gluEnable((GLenum)type); +} + +/*------------------------------------------------------------------------- + * mapgrid1f - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::mapgrid1f(long nu, REAL u0, REAL u1) +{ + if (output_triangles) + { + global_grid_u0=u0; + global_grid_u1=u1; + global_grid_nu=(int)nu; + } + else + { + global_grid_u0=u0; + global_grid_u1=u1; + global_grid_nu=(int)nu; + } +} + +/*------------------------------------------------------------------------- + * bgnmap1 - preamble to curve definition and evaluations + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::bgnmap1f(long) +{ + if (output_triangles) + { + // initialized so that no maps are set initially + vertex_flag=0; + normal_flag=0; + color_flag=0; + texcoord_flag=0; + } +} + +/*------------------------------------------------------------------------- + * endmap1 - postamble to a curve map + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::endmap1f(void) +{ + if (output_triangles) + { + } +} + +/*------------------------------------------------------------------------- + * map1f - pass a desription of a curve map + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::map1f(long type, /* map type */ + REAL ulo, /* lower parametric bound */ + REAL uhi, /* upper parametric bound */ + long stride, /* distance to next point in REALS */ + long order, /* parametric order */ + REAL* pts) /* control points */ +{ + if (output_triangles) + { + int dimension=0; + int which=0; + + switch(type) + { + case GLU_MAP1_VERTEX_3: + which=0; + dimension=3; + break; + case GLU_MAP1_VERTEX_4: + which=0; + dimension=4; + break; + case GLU_MAP1_INDEX: + which=2; + dimension=1; + break; + case GLU_MAP1_COLOR_4: + which=2; + dimension=4; + break; + case GLU_MAP1_NORMAL: + which=1; + dimension=3; + break; + case GLU_MAP1_TEXTURE_COORD_1: + which=3; + dimension=1; + break; + case GLU_MAP1_TEXTURE_COORD_2: + which=3; + dimension=2; + break; + case GLU_MAP1_TEXTURE_COORD_3: + which=3; + dimension=3; + break; + case GLU_MAP1_TEXTURE_COORD_4: + which=3; + dimension=4; + break; + } + inMap1f(which, dimension, ulo, uhi, stride, order, pts); + } + else + { + int dimension=0; + int which=0; + + switch(type) + { + case GLU_MAP1_VERTEX_3: + which=0; + dimension=3; + break; + case GLU_MAP1_VERTEX_4: + which=0; + dimension=4; + break; + case GLU_MAP1_INDEX: + which=2; + dimension=1; + break; + case GLU_MAP1_COLOR_4: + which=2; + dimension=4; + break; + case GLU_MAP1_NORMAL: + which=1; + dimension=3; + break; + case GLU_MAP1_TEXTURE_COORD_1: + which=3; + dimension=1; + break; + case GLU_MAP1_TEXTURE_COORD_2: + which=3; + dimension=2; + break; + case GLU_MAP1_TEXTURE_COORD_3: + which=3; + dimension=3; + break; + case GLU_MAP1_TEXTURE_COORD_4: + which=3; + dimension=4; + break; + } + inMap1fr(which, dimension, ulo, uhi, stride, order, pts); + } +} + +/*------------------------------------------------------------------------- + * mapmesh1f - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::mapmesh1f(long style, long from, long to) +{ + output_style=style; + + if (output_triangles) + { + inMapMesh1f((int)from, (int)to); + } + else + { + inMapMesh1fr((int)from, (int)to); + } +} + +/*------------------------------------------------------------------------- + * evalpoint1i - evaluate a point on a curve + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::evalpoint1i(long i) +{ +} + +/*------------------------------------------------------------------------- + * evalcoord1f - evaluate a point on a curve + *------------------------------------------------------------------------- + */ +void OpenGLCurveEvaluator::evalcoord1f(long, REAL u) +{ +} + +void +#ifdef _WIN32 +OpenGLCurveEvaluator::putCallBack(GLenum which, void (APIENTRY *fn)()) +#else +OpenGLCurveEvaluator::putCallBack(GLenum which, _GLUfuncptr fn) +#endif +{ + switch (which) + { + case GLU_NURBS_BEGIN: + beginCallBackN=(void (APIENTRY*)(GLenum))fn; + break; + case GLU_NURBS_END: + endCallBackN=(void (APIENTRY*)(void))fn; + break; + case GLU_NURBS_VERTEX: + vertexCallBackN=(void (APIENTRY*)(const GLfloat*))fn; + break; + case GLU_NURBS_NORMAL: + normalCallBackN=(void (APIENTRY*)(const GLfloat*))fn; + break; + case GLU_NURBS_COLOR: + colorCallBackN=(void (APIENTRY *)(const GLfloat*))fn; + break; + case GLU_NURBS_TEXTURE_COORD: + texcoordCallBackN=(void (APIENTRY*)(const GLfloat*))fn; + break; + case GLU_NURBS_BEGIN_DATA: + beginCallBackData=(void (APIENTRY*)(GLenum, void*))fn; + break; + case GLU_NURBS_END_DATA: + endCallBackData=(void (APIENTRY*)(void*))fn; + break; + case GLU_NURBS_VERTEX_DATA: + vertexCallBackData=(void (APIENTRY*)(const GLfloat*, void*))fn; + break; + case GLU_NURBS_NORMAL_DATA: + normalCallBackData=(void (APIENTRY*)(const GLfloat*, void*))fn; + break; + case GLU_NURBS_COLOR_DATA: + colorCallBackData=(void (APIENTRY*)(const GLfloat*, void*))fn; + break; + case GLU_NURBS_TEXTURE_COORD_DATA: + texcoordCallBackData=(void (APIENTRY*)(const GLfloat*, void*))fn; + break; + } +} + +void OpenGLCurveEvaluator::beginCallBack(GLenum which, void* data) +{ + if (beginCallBackData) + { + beginCallBackData(which, data); + } + else + { + if (beginCallBackN) + { + beginCallBackN(which); + } + } +} + +void OpenGLCurveEvaluator::endCallBack(void* data) +{ + if (endCallBackData) + { + endCallBackData(data); + } + else + { + if (endCallBackN) + { + endCallBackN(); + } + } +} + +void OpenGLCurveEvaluator::vertexCallBack(const GLfloat* vert, void* data) +{ + if (vertexCallBackData) + { + vertexCallBackData(vert, data); + } + else + { + if (vertexCallBackN) + { + vertexCallBackN(vert); + } + } +} + +void OpenGLCurveEvaluator::normalCallBack(const GLfloat* normal, void* data) +{ + if (normalCallBackData) + { + normalCallBackData(normal, data); + } + else + { + if (normalCallBackN) + { + normalCallBackN(normal); + } + } +} + +void OpenGLCurveEvaluator::colorCallBack(const GLfloat* color, void* data) +{ + if (colorCallBackData) + { + colorCallBackData(color, data); + } + else + { + if (colorCallBackN) + { + colorCallBackN(color); + } + } +} + +void OpenGLCurveEvaluator::texcoordCallBack(const GLfloat* texcoord, void* data) +{ + if (texcoordCallBackData) + { + texcoordCallBackData(texcoord, data); + } + else + { + if (texcoordCallBackN) + { + texcoordCallBackN(texcoord); + } + } +} diff --git a/project/jni/glu/src/libnurbs/interface/glcurveval.h b/project/jni/glu/src/libnurbs/interface/glcurveval.h new file mode 100644 index 000000000..17f5c31f1 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glcurveval.h @@ -0,0 +1,154 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluglcurveval_h_ +#define __gluglcurveval_h_ + +#include "glues.h" + +#include "basiccrveval.h" + +class CurveMap; + +/*for internal evaluator callback stuff*/ +#ifndef IN_MAX_BEZIER_ORDER + #define IN_MAX_BEZIER_ORDER 40 /* XXX should be bigger than machine order */ +#endif + +#ifndef IN_MAX_DIMENSION + #define IN_MAX_DIMENSION 4 +#endif + +typedef struct curveEvalMachine +{ + REAL uprime; // cached previously evaluated uprime + int k; // the dimension + REAL u1; + REAL u2; + int ustride; + int uorder; + REAL ctlpoints[IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + REAL ucoeff[IN_MAX_BEZIER_ORDER]; // cache the polynomial values +} curveEvalMachine; + +class OpenGLCurveEvaluator: public BasicCurveEvaluator +{ + long output_style; // N_MESHFILL or N_MESHLINE or N_MESHPOINT + + public: + OpenGLCurveEvaluator(void); + virtual ~OpenGLCurveEvaluator(void); + void range1f(long, REAL*, REAL*); + void domain1f(REAL, REAL); + void addMap(CurveMap*); + + void enable(long); + void disable(long); + void bgnmap1f(long); + void map1f(long, REAL, REAL, long, long, REAL*); + void mapgrid1f(long, REAL, REAL); + void mapmesh1f(long, long, long); + void evalpoint1i(long); + void evalcoord1f(long, REAL); + void endmap1f(void); + + void bgnline(void); + void endline(void); + + void put_vertices_call_back(int flag) + { + output_triangles=flag; + } +#ifdef _WIN32 + void putCallBack(GLenum which, void (APIENTRY* fn)()); +#else + void putCallBack(GLenum which, _GLUfuncptr fn); +#endif + void set_callback_userData(void* data) + { + userData=data; + } + + /*------------------begin for curveEvalMachine------------*/ + curveEvalMachine em_vertex; + curveEvalMachine em_normal; + curveEvalMachine em_color; + curveEvalMachine em_texcoord; + int vertex_flag; // whether there is a vertex map or not + int normal_flag; // whether there is a normal map or not + int color_flag; // whether there is a color map or not + int texcoord_flag; // whether there is a texture map or not + + REAL global_grid_u0; + REAL global_grid_u1; + int global_grid_nu; + + void inMap1f(int which, int dimension, REAL ulower, REAL uupper, int ustride, int uorder, REAL* ctlpoints); + void inMap1fr(int which, int dimension, REAL ulower, REAL uupper, int ustride, int uorder, REAL* ctlpoints); + void inPreEvaluate(int order, REAL vprime, REAL* coeff); + void inDoDomain1(curveEvalMachine* em, REAL u, REAL* retPoint); + void inDoEvalCoord1(REAL u); + void inDoEvalCoord1r(REAL u, REAL* retPoint); + void inMapMesh1f(int umin, int umax); + void inMapMesh1fr(int umin, int umax); + + void (APIENTRY* beginCallBackN)(GLenum type); + void (APIENTRY* endCallBackN)(void); + void (APIENTRY* vertexCallBackN)(const GLfloat* vert); + void (APIENTRY* normalCallBackN)(const GLfloat* normal); + void (APIENTRY* colorCallBackN)(const GLfloat* color); + void (APIENTRY* texcoordCallBackN)(const GLfloat* texcoord); + + void (APIENTRY* beginCallBackData)(GLenum type, void* data); + void (APIENTRY* endCallBackData)(void* data); + void (APIENTRY* vertexCallBackData)(const GLfloat* vert, void* data); + void (APIENTRY* normalCallBackData)(const GLfloat* normal, void* data); + void (APIENTRY* colorCallBackData)(const GLfloat* color, void* data); + void (APIENTRY* texcoordCallBackData)(const GLfloat* texcoord, void* data); + + void* userData; // the opaque pointer for Data callback functions + void beginCallBack(GLenum type, void* data); + void endCallBack(void* data); + void vertexCallBack(const GLfloat* vert, void *data); + void normalCallBack(const GLfloat* normal, void* data); + void colorCallBack(const GLfloat* color, void* data); + void texcoordCallBack(const GLfloat* texcoord, void* data); + +/*------------------end for curveEvalMachine------------*/ + + private: + int output_triangles; // true 1; false 0 +}; + +#endif /* __gluglcurveval_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/gles_evaluator.cc b/project/jni/glu/src/libnurbs/interface/gles_evaluator.cc new file mode 100644 index 000000000..1a89a7c53 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/gles_evaluator.cc @@ -0,0 +1,268 @@ +/* + * 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. + */ + +/* + * gles_evaluator.cc + * Author: Mike Gorchak, 2009. mike@malva.ua, lestat@i.com.ua + * + */ + +#include "glues.h" +#include "gles_evaluator.h" + +#include + +#include + +GLAPI void APIENTRY gluEnable(GLenum cap) +{ + switch (cap) + { + case GLU_MAP1_COLOR_4: + case GLU_MAP1_INDEX: + case GLU_MAP1_NORMAL: + case GLU_MAP1_TEXTURE_COORD_1: + case GLU_MAP1_TEXTURE_COORD_2: + case GLU_MAP1_TEXTURE_COORD_3: + case GLU_MAP1_TEXTURE_COORD_4: + case GLU_MAP1_VERTEX_3: + case GLU_MAP1_VERTEX_4: + case GLU_MAP2_COLOR_4: + case GLU_MAP2_INDEX: + case GLU_MAP2_NORMAL: + case GLU_MAP2_TEXTURE_COORD_1: + case GLU_MAP2_TEXTURE_COORD_2: + case GLU_MAP2_TEXTURE_COORD_3: + case GLU_MAP2_TEXTURE_COORD_4: + case GLU_MAP2_VERTEX_3: + case GLU_MAP2_VERTEX_4: + case GLU_AUTO_NORMAL: + break; + default: + glEnable(cap); + break; + } +} + +GLAPI void APIENTRY gluDisable(GLenum cap) +{ + switch (cap) + { + case GLU_MAP1_COLOR_4: + case GLU_MAP1_INDEX: + case GLU_MAP1_NORMAL: + case GLU_MAP1_TEXTURE_COORD_1: + case GLU_MAP1_TEXTURE_COORD_2: + case GLU_MAP1_TEXTURE_COORD_3: + case GLU_MAP1_TEXTURE_COORD_4: + case GLU_MAP1_VERTEX_3: + case GLU_MAP1_VERTEX_4: + case GLU_MAP2_COLOR_4: + case GLU_MAP2_INDEX: + case GLU_MAP2_NORMAL: + case GLU_MAP2_TEXTURE_COORD_1: + case GLU_MAP2_TEXTURE_COORD_2: + case GLU_MAP2_TEXTURE_COORD_3: + case GLU_MAP2_TEXTURE_COORD_4: + case GLU_MAP2_VERTEX_3: + case GLU_MAP2_VERTEX_4: + case GLU_AUTO_NORMAL: + break; + default: + glDisable(cap); + break; + } +} + +GLfloat lg2table[63]= +{ + 0.0000000004656612873077392578125f, + 0.000000000931322574615478515625f, + 0.00000000186264514923095703125f, + 0.0000000037252902984619140625f, + 0.000000007450580596923828125f, + 0.00000001490116119384765625f, + 0.0000000298023223876953125f, + 0.000000059604644775390625f, + + 0.00000011920928955078125f, + 0.0000002384185791015625f, + 0.000000476837158203125f, + 0.00000095367431640625f, + 0.0000019073486328125f, + 0.000003814697265625f, + 0.00000762939453125f, + 0.0000152587890625f, + + 0.000030517578125f, + 0.00006103515625f, + 0.0001220703125f, + 0.000244140625f, + 0.00048828125f, + 0.0009765625f, + 0.001953125f, /* 1/512 */ + 0.00390625f, /* 1/256 */ + + 0.0078125f, /* 1/128 */ + 0.015625f, /* 1/64 */ + 0.03125f, /* 1/32 */ + 0.0625f, /* 1/16 */ + 0.125f, /* 1/8 */ + 0.25f, /* 1/4 */ + 0.5f, /* 1/2 */ + + 0x00000001, /* zero */ + 0x00000002, + 0x00000004, + 0x00000008, + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000080, + + 0x00000100, + 0x00000200, + 0x00000400, + 0x00000800, + 0x00001000, + 0x00002000, + 0x00004000, + 0x00008000, + + 0x00010000, + 0x00020000, + 0x00040000, + 0x00080000, + 0x00100000, + 0x00200000, + 0x00400000, + 0x00800000, + + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000 +}; + +GLAPI void APIENTRY gluGetFloatv(GLenum pname, GLfloat* params) +{ + switch (pname) + { + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + /* Check if OpenGL ES 1.1 is used, then call glGetFloatv directly */ + #if defined(GL_VERSION_ES_CM_1_1) + /* Just passthrough the request to OpenGL ES 1.1 */ + glGetFloatv(pname, params); + return; + #endif /* GL_VERSION_ES_CM_1_1 */ + /* Check if OpenGL ES 1.0 is used, then try to emulate glGetFloatv */ + #if (defined(GL_OES_VERSION_1_0) || defined(GL_VERSION_ES_CM_1_0)) && !defined(GL_VERSION_ES_CM_1_1) + /* Check for query_matrix extension, which is very usefull in OpenGL ES 1.0 to obtain */ + /* GLES 1.0 dynamic state */ + #if defined(GL_OES_query_matrix) + { + GLfixed mantissa[16]; + GLint exponent[16]; + + /* Clear the output data, in case if glQueryMatrixxOES() will fail */ + memset(params, 0x00, 16*sizeof(GLfloat)); + + /* Since OpenGL ES 1.0 has no GL_MATRIX_MODE for glGet() we will try to setup */ + /* required matrix and then restore modelview matrix, because it must be default */ + /* current matrix mode for rendering process. */ + switch (pname) + { + case GL_MODELVIEW_MATRIX: + glMatrixMode(GL_MODELVIEW); + break; + case GL_PROJECTION_MATRIX: + glMatrixMode(GL_PROJECTION); + break; + } + + /* Query current matrix content */ + if (glQueryMatrixxOES(mantissa, exponent)==0) + { + for (int it=0; it<16; it++) + { + params[it]=FX2F(mantissa[it])*lg2table[exponent[it]+31]; + } + } + + /* Restore "default" matrix mode */ + glMatrixMode(GL_MODELVIEW); + } + #else + #error "Do not know how to query modelview and projection matrices" + #endif /* GL_OES_query_matrix */ + #endif /* GL_OES_VERSION_1_0 or GL_VERSION_ES_CM_1_0 only */ + break; + } + + #if defined(GL_VERSION_ES_CM_1_1) + /* Just passthrough the request to OpenGL ES 1.1 */ + /* In OpenGL ES 1.0 all other Float requests will be ignored */ + glGetFloatv(pname, params); + #endif /* GL_VERSION_ES_CM_1_1 */ +} + +GLint glu_viewport[4]; + +GLAPI void APIENTRY gluGetIntegerv(GLenum pname, GLint* params) +{ + switch (pname) + { + case GL_VIEWPORT: + #if (defined(GL_OES_VERSION_1_0) || defined(GL_VERSION_ES_CM_1_0)) && !defined(GL_VERSION_ES_CM_1_1) + params[0]=glu_viewport[0]; + params[1]=glu_viewport[1]; + params[2]=glu_viewport[2]; + params[3]=glu_viewport[3]; + return; + #endif /* GL_OES_VERSION_1_0 or GL_VERSION_ES_CM_1_0 only */ + break; + + } + + glGetIntegerv(pname, params); +} + +GLAPI void APIENTRY gluViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + glu_viewport[0]=x; + glu_viewport[1]=y; + glu_viewport[2]=(GLint)width; + glu_viewport[3]=(GLint)height; +} diff --git a/project/jni/glu/src/libnurbs/interface/gles_evaluator.h b/project/jni/glu/src/libnurbs/interface/gles_evaluator.h new file mode 100644 index 000000000..e33f66dbf --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/gles_evaluator.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +/* + * gles_evaluator.h + * Author: Mike Gorchak, 2009. mike@malva.ua, lestat@i.com.ua + * + */ + +#ifndef __gles_evaluator_h_ +#define __gles_evaluator_h_ + +/* Fixed point to float point conversion */ +#define FX2F(fx) (GLfloat(fx)/65536.0f) + +#endif /* __gles_evaluator_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/glimports.h b/project/jni/glu/src/libnurbs/interface/glimports.h new file mode 100644 index 000000000..5be399a03 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glimports.h @@ -0,0 +1,41 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluimports_h_ +#define __gluimports_h_ + +#include "mystdlib.h" +#include "mystdio.h" + +#endif /* __gluimports_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/glinterface.cc b/project/jni/glu/src/libnurbs/interface/glinterface.cc new file mode 100644 index 000000000..243c43275 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glinterface.cc @@ -0,0 +1,463 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include "gles_evaluator.h" + +#include + +#include "glimports.h" +#include "glrenderer.h" +#include "nurbsconsts.h" + +GLUnurbs* APIENTRY gluNewNurbsRenderer(void) +{ + GLUnurbs* t; + + t=new GLUnurbs(); + + return t; +} + +void APIENTRY gluDeleteNurbsRenderer(GLUnurbs* r) +{ + delete r; +} + +extern "C" void APIENTRY gluDeleteNurbsTessellatorEXT(GLUnurbsObj* r) +{ + delete r; +} + +void APIENTRY gluBeginSurface(GLUnurbs* r) +{ + r->bgnsurface(0); +} + +void APIENTRY gluBeginCurve(GLUnurbs* r) +{ + r->bgncurve(0); +} + +void APIENTRY gluEndCurve(GLUnurbs* r) +{ + r->endcurve(); +} + +void APIENTRY gluEndSurface(GLUnurbs* r) +{ + r->endsurface(); +} + +void APIENTRY gluBeginTrim(GLUnurbs* r) +{ + r->bgntrim(); +} + +void APIENTRY gluEndTrim(GLUnurbs* r) +{ + r->endtrim(); +} + +void APIENTRY gluPwlCurve(GLUnurbs* r, GLint count, INREAL array[], GLint stride, GLenum type) +{ + int realType; + + switch(type) + { + case GLU_MAP1_TRIM_2: + realType=N_P2D; + break; + case GLU_MAP1_TRIM_3: + realType=N_P2DR; + break; + default: + realType = type; + break; + } + r->pwlcurve(count, array, sizeof(INREAL)*stride, realType); +} + +void APIENTRY gluNurbsCurve(GLUnurbs* r, GLint nknots, INREAL knot[], GLint stride, + INREAL ctlarray[], GLint order, GLenum type) +{ + int realType; + + switch(type) + { + case GLU_MAP1_TRIM_2: + realType=N_P2D; + break; + case GLU_MAP1_TRIM_3: + realType=N_P2DR; + break; + default: + realType=type; + break; + } + + r->nurbscurve(nknots, knot, sizeof(INREAL)*stride, ctlarray, order, realType); +} + +void APIENTRY gluNurbsSurface(GLUnurbs* r, GLint sknot_count, GLfloat* sknot, + GLint tknot_count, GLfloat* tknot, GLint s_stride, + GLint t_stride, GLfloat* ctlarray, GLint sorder, + GLint torder, GLenum type) +{ + r->nurbssurface(sknot_count, sknot, tknot_count, tknot, + sizeof(INREAL)*s_stride, sizeof(INREAL)*t_stride, + ctlarray, sorder, torder, type); +} + +void APIENTRY gluLoadSamplingMatrices(GLUnurbs* r, const GLfloat modelMatrix[16], + const GLfloat projMatrix[16], const GLint viewport[4]) +{ + r->useGLMatrices(modelMatrix, projMatrix, viewport); +} + +void APIENTRY gluNurbsProperty(GLUnurbs* r, GLenum property, GLfloat value) +{ + GLfloat nurbsValue; + + switch(property) + { + case GLU_AUTO_LOAD_MATRIX: + r->setautoloadmode(value); + return; + + case GLU_CULLING: + if (value != 0.0) + { + nurbsValue=N_CULLINGON; + } + else + { + nurbsValue = N_NOCULLING; + } + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_CULLING, nurbsValue); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_CULLING, nurbsValue); + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_CULLING, nurbsValue); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_CULLING, nurbsValue); + return; + + case GLU_SAMPLING_METHOD: + if (value==GLU_PATH_LENGTH) + { + nurbsValue=N_PATHLENGTH; + } + else + { + if (value==GLU_PARAMETRIC_ERROR) + { + nurbsValue=N_PARAMETRICDISTANCE; + } + else + { + if (value==GLU_DOMAIN_DISTANCE) + { + nurbsValue=N_DOMAINDISTANCE; + r->set_is_domain_distance_sampling(1); // optimzing untrimmed case + + } + else + { + if (value==GLU_OBJECT_PARAMETRIC_ERROR) + { + nurbsValue=N_OBJECTSPACE_PARA; + r->setautoloadmode(0.0f); + r->setSamplingMatrixIdentity(); + } + else + { + if (value==GLU_OBJECT_PATH_LENGTH) + { + nurbsValue = N_OBJECTSPACE_PATH; + r->setautoloadmode(0.0f); + r->setSamplingMatrixIdentity(); + } + else + { + r->postError(GLU_INVALID_VALUE); + return; + } + } + } + } + } + + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue); + return; + + case GLU_SAMPLING_TOLERANCE: + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, value); + return; + + case GLU_PARAMETRIC_TOLERANCE: + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_ERROR_TOLERANCE, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_ERROR_TOLERANCE, value); + return; + + case GLU_DISPLAY_MODE: + if (value==GLU_FILL) + { + nurbsValue=N_FILL; + } + else + { + if (value==GLU_OUTLINE_POLYGON) + { + nurbsValue=N_OUTLINE_POLY; + } + else + { + if (value==GLU_OUTLINE_PATCH) + { + nurbsValue=N_OUTLINE_PATCH; + } + else + { + r->postError(GLU_INVALID_VALUE); + return; + } + } + } + + r->setnurbsproperty(N_DISPLAY, nurbsValue); + break; + + case GLU_U_STEP: + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_S_STEPS, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_S_STEPS, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_S_STEPS, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_S_STEPS, value); + + // added for optimizing untrimmed case + r->set_domain_distance_u_rate(value); + break; + + case GLU_V_STEP: + r->setnurbsproperty(GLU_MAP1_VERTEX_3, N_T_STEPS, value); + r->setnurbsproperty(GLU_MAP1_VERTEX_4, N_T_STEPS, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_3, N_T_STEPS, value); + r->setnurbsproperty(GLU_MAP2_VERTEX_4, N_T_STEPS, value); + + //added for optimizing untrimmed case + r->set_domain_distance_v_rate(value); + break; + + case GLU_NURBS_MODE: + if (value==GLU_NURBS_RENDERER) + { + r->put_callbackFlag(0); + } + else + { + if (value==GLU_NURBS_TESSELLATOR) + { + r->put_callbackFlag(1); + } + else + { + r->postError(GLU_INVALID_ENUM); + } + } + break; + + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +void APIENTRY +gluGetNurbsProperty(GLUnurbs *r, GLenum property, GLfloat *value) +{ + GLfloat nurbsValue; + + switch(property) + { + case GLU_AUTO_LOAD_MATRIX: + if (r->getautoloadmode()) + { + *value=GL_TRUE; + } + else + { + *value=GL_FALSE; + } + break; + case GLU_CULLING: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_CULLING, &nurbsValue); + if (nurbsValue==N_CULLINGON) + { + *value=GL_TRUE; + } + else + { + *value = GL_FALSE; + } + break; + case GLU_SAMPLING_METHOD: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_SAMPLINGMETHOD, value); + if (*value==N_PATHLENGTH) + { + *value=GLU_PATH_LENGTH; + } + else + { + if (*value==N_PARAMETRICDISTANCE) + { + *value=GLU_PARAMETRIC_ERROR; + } + else + { + if (*value==N_DOMAINDISTANCE) + { + *value=GLU_DOMAIN_DISTANCE; + } + else + { + if (*value==N_OBJECTSPACE_PATH) + { + *value=GLU_OBJECT_PATH_LENGTH; + } + else + { + if (*value==N_OBJECTSPACE_PARA) + { + *value=GLU_OBJECT_PARAMETRIC_ERROR; + } + } + } + } + } + break; + case GLU_SAMPLING_TOLERANCE: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value); + break; + case GLU_PARAMETRIC_TOLERANCE: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value); + break; + case GLU_U_STEP: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_S_STEPS, value); + break; + case GLU_V_STEP: + r->getnurbsproperty(GLU_MAP2_VERTEX_3, N_T_STEPS, value); + break; + case GLU_DISPLAY_MODE: + r->getnurbsproperty(N_DISPLAY, &nurbsValue); + if (nurbsValue==N_FILL) + { + *value=GLU_FILL; + } + else + { + if (nurbsValue==N_OUTLINE_POLY) + { + *value=GLU_OUTLINE_POLYGON; + } + else + { + *value=GLU_OUTLINE_PATCH; + } + } + break; + + case GLU_NURBS_MODE: + if (r->is_callback()) + { + *value=GLU_NURBS_TESSELLATOR; + } + else + { + *value=GLU_NURBS_RENDERER; + } + break; + + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +extern "C" void APIENTRY gluNurbsCallback(GLUnurbs* r, GLenum which, _GLUfuncptr fn) +{ + switch(which) + { + case GLU_NURBS_BEGIN: + case GLU_NURBS_END: + case GLU_NURBS_VERTEX: + case GLU_NURBS_NORMAL: + case GLU_NURBS_TEXTURE_COORD: + case GLU_NURBS_COLOR: + case GLU_NURBS_BEGIN_DATA: + case GLU_NURBS_END_DATA: + case GLU_NURBS_VERTEX_DATA: + case GLU_NURBS_NORMAL_DATA: + case GLU_NURBS_TEXTURE_COORD_DATA: + case GLU_NURBS_COLOR_DATA: + r->putSurfCallBack(which, fn); + break; + case GLU_NURBS_ERROR: + r->errorCallback=(void (APIENTRY*)(GLenum e)) fn; + break; + default: + r->postError(GLU_INVALID_ENUM); + return; + } +} + +extern "C" void APIENTRY gluNurbsCallbackDataEXT(GLUnurbs* r, void* userData) +{ + r->setNurbsCallbackData(userData); +} + +extern "C" void APIENTRY gluNurbsCallbackData(GLUnurbs* r, void* userData) +{ + gluNurbsCallbackDataEXT(r,userData); +} diff --git a/project/jni/glu/src/libnurbs/interface/glrenderer.cc b/project/jni/glu/src/libnurbs/interface/glrenderer.cc new file mode 100644 index 000000000..3cb6aca33 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glrenderer.cc @@ -0,0 +1,277 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" +#include "gles_evaluator.h" +#include "glimports.h" +#include "glrenderer.h" + +GLUnurbs::GLUnurbs(): NurbsTessellator(curveEvaluator, surfaceEvaluator) +{ + redefineMaps(); + defineMap(GLU_MAP2_NORMAL, 0, 3); + defineMap(GLU_MAP1_NORMAL, 0, 3); + defineMap(GLU_MAP2_TEXTURE_COORD_1, 0, 1); + defineMap(GLU_MAP1_TEXTURE_COORD_1, 0, 1); + defineMap(GLU_MAP2_TEXTURE_COORD_2, 0, 2); + defineMap(GLU_MAP1_TEXTURE_COORD_2, 0, 2); + defineMap(GLU_MAP2_TEXTURE_COORD_3, 0, 3); + defineMap(GLU_MAP1_TEXTURE_COORD_3, 0, 3); + defineMap(GLU_MAP2_TEXTURE_COORD_4, 1, 4); + defineMap(GLU_MAP1_TEXTURE_COORD_4, 1, 4); + defineMap(GLU_MAP2_VERTEX_4, 1, 4); + defineMap(GLU_MAP1_VERTEX_4, 1, 4); + defineMap(GLU_MAP2_VERTEX_3, 0, 3); + defineMap(GLU_MAP1_VERTEX_3, 0, 3); + defineMap(GLU_MAP2_COLOR_4, 0, 4); + defineMap(GLU_MAP1_COLOR_4, 0, 4); + defineMap(GLU_MAP2_INDEX, 0, 1); + defineMap(GLU_MAP1_INDEX, 0, 1); + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_SAMPLINGMETHOD, (GLfloat)N_PATHLENGTH); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_SAMPLINGMETHOD, (GLfloat)N_PATHLENGTH); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_SAMPLINGMETHOD, (GLfloat)N_PATHLENGTH); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_SAMPLINGMETHOD, (GLfloat)N_PATHLENGTH); + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, (GLfloat)50.0f); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, (GLfloat)50.0f); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, (GLfloat)50.0f); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, (GLfloat)50.0f); + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_ERROR_TOLERANCE, (GLfloat)0.50f); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_ERROR_TOLERANCE, (GLfloat)0.50f); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_ERROR_TOLERANCE, (GLfloat)0.50f); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_ERROR_TOLERANCE, (GLfloat)0.50f); + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_S_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_S_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_S_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_S_STEPS, (GLfloat)100.0f); + + // added for optimizing untrimmed case + set_domain_distance_u_rate(100.0f); + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_T_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_T_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_T_STEPS, (GLfloat)100.0f); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_T_STEPS, (GLfloat)100.0f); + + // added for optimizing untrimmed case + set_domain_distance_v_rate(100.0f); + set_is_domain_distance_sampling(0); // since the default is path_length + + // default autoloadmode is true + autoloadmode=1; + + // default callbackFlag is 0 + callbackFlag=0; + + errorCallback=NULL; +} + +void GLUnurbs::bgnrender(void) +{ + if (autoloadmode) + { + loadGLMatrices(); + } +} + +void GLUnurbs::endrender(void) +{ +} + +void GLUnurbs::errorHandler(int i) +{ + int gluError; + + gluError=i+(GLU_NURBS_ERROR1-1); + postError(gluError); +} + +void GLUnurbs::loadGLMatrices(void) +{ + GLfloat vmat[4][4]; + GLint viewport[4]; + + grabGLMatrix((GLfloat(*)[4])vmat); + loadCullingMatrix((GLfloat(*)[4])vmat); + gluGetIntegerv((GLenum)GL_VIEWPORT, (GLint*)viewport); + loadSamplingMatrix((const GLfloat(*)[4])vmat, (const GLint*)viewport); +} + +void GLUnurbs::useGLMatrices(const GLfloat modelMatrix[16], const GLfloat projMatrix[16], + const GLint viewport[4]) +{ + GLfloat vmat[4][4]; + + multmatrix4d(vmat, (const GLfloat (*)[4])modelMatrix, (const GLfloat (*)[4])projMatrix); + loadCullingMatrix((GLfloat (*)[4])vmat); + loadSamplingMatrix((const GLfloat (*)[4])vmat, (const GLint *)viewport); +} + +/*-------------------------------------------------------------------------- + * grabGLMatrix + *-------------------------------------------------------------------------- + */ + +void GLUnurbs::grabGLMatrix(GLfloat vmat[4][4]) +{ + GLfloat m1[4][4], m2[4][4]; + + gluGetFloatv((GLenum) GL_MODELVIEW_MATRIX, (GLfloat*)&(m1[0][0])); + gluGetFloatv((GLenum) GL_PROJECTION_MATRIX, (GLfloat*)&(m2[0][0])); + + multmatrix4d((GLfloat (*)[4])vmat, (const GLfloat (*)[4])m1, (const GLfloat (*)[4])m2); +} + +// for object space tesselation: view independent +void GLUnurbs::setSamplingMatrixIdentity(void) +{ + INREAL smat[4][4]= + { + {1,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,1} + }; + const long rstride=sizeof(smat[0])/sizeof(smat[0][0]); + const long cstride=1; + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); +} + + +void GLUnurbs::loadSamplingMatrix(const GLfloat vmat[4][4], const GLint viewport[4]) +{ + /* rescale the mapping to correspond to pixels in x/y */ + REAL xsize = 0.5f * (REAL) (viewport[2]); + REAL ysize = 0.5f * (REAL) (viewport[3]); + + INREAL smat[4][4]; + smat[0][0] = vmat[0][0] * xsize; + smat[1][0] = vmat[1][0] * xsize; + smat[2][0] = vmat[2][0] * xsize; + smat[3][0] = vmat[3][0] * xsize; + + smat[0][1] = vmat[0][1] * ysize; + smat[1][1] = vmat[1][1] * ysize; + smat[2][1] = vmat[2][1] * ysize; + smat[3][1] = vmat[3][1] * ysize; + + smat[0][2] = 0.0; + smat[1][2] = 0.0; + smat[2][2] = 0.0; + smat[3][2] = 0.0; + + smat[0][3] = vmat[0][3]; + smat[1][3] = vmat[1][3]; + smat[2][3] = vmat[2][3]; + smat[3][3] = vmat[3][3]; + + const long rstride=sizeof(smat[0])/sizeof(smat[0][0]); + const long cstride=1; + + setnurbsproperty(GLU_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride, cstride); +} + +void GLUnurbs::loadCullingMatrix(GLfloat vmat[4][4]) +{ + INREAL cmat[4][4]; + + cmat[0][0]=vmat[0][0]; + cmat[0][1]=vmat[0][1]; + cmat[0][2]=vmat[0][2]; + cmat[0][3]=vmat[0][3]; + + cmat[1][0]=vmat[1][0]; + cmat[1][1]=vmat[1][1]; + cmat[1][2]=vmat[1][2]; + cmat[1][3]=vmat[1][3]; + + cmat[2][0]=vmat[2][0]; + cmat[2][1]=vmat[2][1]; + cmat[2][2]=vmat[2][2]; + cmat[2][3]=vmat[2][3]; + + cmat[3][0]=vmat[3][0]; + cmat[3][1]=vmat[3][1]; + cmat[3][2]=vmat[3][2]; + cmat[3][3]=vmat[3][3]; + + const long rstride=sizeof(cmat[0])/sizeof(cmat[0][0]); + const long cstride=1; + + setnurbsproperty(GLU_MAP2_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP2_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride, cstride); + + // added for curves by zl + setnurbsproperty(GLU_MAP1_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride, cstride); + setnurbsproperty(GLU_MAP1_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride, cstride); +} + +/*--------------------------------------------------------------------- + * A = B * MAT ; transform a 4d vector through a 4x4 matrix + *--------------------------------------------------------------------- + */ +void GLUnurbs::transform4d(GLfloat A[4], GLfloat B[4], GLfloat mat[4][4]) +{ + A[0]=B[0]*mat[0][0]+B[1]*mat[1][0]+B[2]*mat[2][0]+B[3]*mat[3][0]; + A[1]=B[0]*mat[0][1]+B[1]*mat[1][1]+B[2]*mat[2][1]+B[3]*mat[3][1]; + A[2]=B[0]*mat[0][2]+B[1]*mat[1][2]+B[2]*mat[2][2]+B[3]*mat[3][2]; + A[3]=B[0]*mat[0][3]+B[1]*mat[1][3]+B[2]*mat[2][3]+B[3]*mat[3][3]; +} + +/*--------------------------------------------------------------------- + * new = [left][right] ; multiply two matrices together + *--------------------------------------------------------------------- + */ +void GLUnurbs::multmatrix4d(GLfloat n[4][4], const GLfloat left[4][4], const GLfloat right[4][4]) +{ + transform4d((GLfloat*)n[0], (GLfloat*)left[0], (GLfloat(*)[4])right); + transform4d((GLfloat*)n[1], (GLfloat*)left[1], (GLfloat(*)[4])right); + transform4d((GLfloat*)n[2], (GLfloat*)left[2], (GLfloat(*)[4])right); + transform4d((GLfloat*)n[3], (GLfloat*)left[3], (GLfloat(*)[4])right); +} diff --git a/project/jni/glu/src/libnurbs/interface/glrenderer.h b/project/jni/glu/src/libnurbs/interface/glrenderer.h new file mode 100644 index 000000000..bb6ea362e --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glrenderer.h @@ -0,0 +1,140 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluglrenderer_h_ +#define __gluglrenderer_h_ + +#include "glues.h" + +#include "nurbstess.h" +#include "glsurfeval.h" +#include "glcurveval.h" + +extern "C" +{ + typedef void (APIENTRY* errorCallbackType)(GLenum); +} + +class GLUnurbs: public NurbsTessellator +{ + public: + GLUnurbs(void); + void loadGLMatrices(void); + void useGLMatrices(const GLfloat modelMatrix[16], const GLfloat projMatrix[16], + const GLint viewport[4]); + void setSamplingMatrixIdentity(void); + + void errorHandler(int); + void bgnrender(void); + void endrender(void); + void setautoloadmode(INREAL value) + { + if (value) + { + autoloadmode=GL_TRUE; + } + else + { + autoloadmode=GL_FALSE; + } + } + GLboolean getautoloadmode(void) { return autoloadmode; } + + errorCallbackType errorCallback; + + void postError(int which) + { + if (errorCallback) + { + (errorCallback)((GLenum)which); + } + } +#ifdef _WIN32 + void putSurfCallBack(GLenum which, void (APIENTRY* fn)()) +#else + void putSurfCallBack(GLenum which, _GLUfuncptr fn) +#endif + { + curveEvaluator.putCallBack(which, fn); + surfaceEvaluator.putCallBack(which, fn); + } + int get_vertices_call_back() + { + return surfaceEvaluator.get_vertices_call_back(); + } + void put_vertices_call_back(int flag) + { + surfaceEvaluator.put_vertices_call_back(flag); + } + int get_callback_auto_normal() + { + return surfaceEvaluator.get_callback_auto_normal(); + } + void put_callback_auto_normal(int flag) + { + surfaceEvaluator.put_callback_auto_normal(flag); + } + void setNurbsCallbackData(void* userData) + { + curveEvaluator.set_callback_userData(userData); + surfaceEvaluator.set_callback_userData(userData); + } + + // NEWCALLBACK + int is_callback() + { + return callbackFlag; + } + void put_callbackFlag(int flag) + { + callbackFlag=flag; + surfaceEvaluator.put_vertices_call_back(flag); + curveEvaluator.put_vertices_call_back(flag); + } + + private: + GLboolean autoloadmode; + OpenGLSurfaceEvaluator surfaceEvaluator; + OpenGLCurveEvaluator curveEvaluator; + + void loadSamplingMatrix(const GLfloat vmat[4][4], const GLint viewport[4]); + void loadCullingMatrix(GLfloat vmat[4][4]); + static void grabGLMatrix(GLfloat vmat[4][4]); + static void transform4d(GLfloat A[4], GLfloat B[4], GLfloat mat[4][4]); + static void multmatrix4d(GLfloat n[4][4], const GLfloat left[4][4], const GLfloat right[4][4]); + + int callbackFlag; +}; + +#endif /* __gluglrenderer_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/glsurfeval.cc b/project/jni/glu/src/libnurbs/interface/glsurfeval.cc new file mode 100644 index 000000000..6b8e79270 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glsurfeval.cc @@ -0,0 +1,1002 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +/* Polynomial Evaluator Interface */ +#include "glues.h" + +#include + +#include "glimports.h" +#include "glrenderer.h" +#include "glsurfeval.h" +#include "nurbsconsts.h" +#include "bezierPatchMesh.h" +#include "gles_evaluator.h" + +/* use internal evaluator */ +#define USE_INTERNAL_EVAL + +OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator() +{ + int i; + + for (i=0; i=n_upper) /* case1: no more in upper */ + { + if (j=n_lower) /* case2: no more in lower */ + { + if (i=i; k--) /* reverse order for two-side lighting */ + { + coord2f(upper_val[k], v_upper); + } + + endtfan(); + } + break; /* exit the main loop */ + } + else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output */ + { + if (upper_val[i]<=lower_val[j]) + { + bgntfan(); + coord2f(lower_val[j], v_lower); + + /* find the last k>=i such that + * upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + + while (klower_val[j]) + { + break; + } + k++; + } + k--; + + for(l=k; l>=i; l--) /* the reverse is for two-side lighting */ + { + coord2f(upper_val[l], v_upper); + } + + coord2f(leftMostV[0], leftMostV[1]); + endtfan(); + + /* update i and leftMostV for next loop */ + i=k+1; + + leftMostV[0]=upper_val[k]; + leftMostV[1]=v_upper; + } + else /* upperVerts[i][0] > lowerVerts[j][0] */ + { + bgntfan(); + + coord2f(upper_val[i], v_upper); + coord2f(leftMostV[0], leftMostV[1]); + + /* find the last k>=j such that + * lowerverts[k][0] < upperverts[i][0] + */ + k=j; + + while (k=upper_val[i]) + { + break; + } + coord2f(lower_val[k], v_lower); + + k++; + } + endtfan(); + + /* update j and leftMostV for next loop */ + j=k; + leftMostV[0]=lower_val[j-1]; + leftMostV[1]=v_lower; + } + } + } + } +#endif /* USE_INTERNAL_EVAL */ +} + +void OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) +{ +#ifdef USE_INTERNAL_EVAL + inEvalVStrip(n_left, u_left, left_val, n_right, u_right, right_val); +#else + int i, j, k, l; + REAL botMostV[2]; + /* + * the algorithm works by scanning from bot to top. + * botMostV: the bot most of the remaining verteces (on both left and right). + * it could an element of leftVerts or rightVerts. + *i: leftVerts[i] is the first vertex to the top of botMostV on left line + *j: rightVerts[j] is the first vertex to the top of botMostV on rightline + */ + + /*initialize i,j,and botMostV */ + if(left_val[0]<=right_val[0]) + { + i=1; + j=0; + + botMostV[0]=u_left; + botMostV[1]=left_val[0]; + } + else + { + i=0; + j=1; + + botMostV[0]=u_right; + botMostV[1]=right_val[0]; + } + + /* the main loop. + * the invariance is that: + * at the beginning of each loop, the meaning of i,j,and botMostV are + * maintained + */ + while(1) + { + if (i>=n_left) /* case1: no more in left */ + { + if (j=n_right) /* case2: no more in right */ + { + if (i=i; k--) /* reverse order for two-side lighting */ + { + coord2f(u_left, left_val[k]); + } + + endtfan(); + } + break; /* exit the main loop */ + } + else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output */ + { + if (left_val[i]<=right_val[j]) + { + bgntfan(); + coord2f(u_right, right_val[j]); + + /* find the last k>=i such that + * leftverts[k][0] <= rightverts[j][0] + */ + k=i; + + while (kright_val[j]) + break; + k++; + } + k--; + + + for(l=k; l>=i; l--) /* the reverse is for two-side lighting */ + { + coord2f(u_left, left_val[l]); + } + coord2f(botMostV[0], botMostV[1]); + + endtfan(); + + /* update i and botMostV for next loop */ + i=k+1; + + botMostV[0]=u_left; + botMostV[1]=left_val[k]; + } + else /* left_val[i] > right_val[j]) */ + { + bgntfan(); + + coord2f(u_left, left_val[i]); + coord2f(botMostV[0], botMostV[1]); + + /* find the last k>=j such that + * rightverts[k][0] < leftverts[i][0] + */ + k=j; + + while (k=left_val[i]) + { + break; + } + coord2f(u_right, right_val[k]); + + k++; + } + endtfan(); + + /* update j and botMostV for next loop */ + j=k; + botMostV[0]=u_right; + botMostV[1]=right_val[j-1]; + } + } + } + } +#endif /* USE_INTERNAL_EVAL */ +} + +void OpenGLSurfaceEvaluator::bgnqstrip(void) +{ + if (output_triangles) + { + bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_STRIP); + } +} + +void OpenGLSurfaceEvaluator::endqstrip(void) +{ + if (output_triangles) + { + bezierPatchMeshEndStrip(global_bpm); + } +} + +/*------------------------------------------------------------------------- + * bgnmap2f - preamble to surface definition and evaluations + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::bgnmap2f(long) +{ + if (output_triangles) + { + /* deallocate the space which may has been + * allocated by global_bpm previously + */ + if (global_bpm!=NULL) + { + bezierPatchMeshListDelete(global_bpm); + global_bpm=NULL; + } + + // NEWCALLBACK + // if one of the two normal callback functions are set, + // then set + if (normalCallBackN!=NULL || normalCallBackData!=NULL) + { + auto_normal_flag=1; + } + else + { + auto_normal_flag=0; + } + + // initialize so that no maps initially + vertex_flag=0; + normal_flag=0; + color_flag=0; + texcoord_flag=0; + } +} + +/*------------------------------------------------------------------------- + * endmap2f - postamble to a map + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::endmap2f(void) +{ + if (output_triangles) + { + inBPMListEvalEM(global_bpm); + + bezierPatchMeshListDelete(global_bpm); + global_bpm = NULL; + } +} + +/*------------------------------------------------------------------------- + * map2f - pass a desription of a surface map + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::map2f(long _type, + REAL _ulower, /* u lower domain coord */ + REAL _uupper, /* u upper domain coord */ + long _ustride, /* interpoint distance */ + long _uorder, /* parametric order */ + REAL _vlower, /* v lower domain coord */ + REAL _vupper, /* v upper domain coord */ + long _vstride, /* interpoint distance */ + long _vorder, /* parametric order */ + REAL* pts) /* control points */ +{ +#ifdef USE_INTERNAL_EVAL + inMap2f((int)_type, (REAL)_ulower, (REAL)_uupper, (int)_ustride, (int)_uorder, + (REAL)_vlower, (REAL)_vupper, (int)_vstride, (int)_vorder, (REAL*)pts); +#else + if (output_triangles) + { + if (global_bpm==NULL) + { + global_bpm=bezierPatchMeshMake2(10, 10); + } + if((global_bpm->bpatch==NULL && + (_type == GLU_MAP2_VERTEX_3 || _type==GLU_MAP2_VERTEX_4)) || + (global_bpm->bpatch_normal==NULL && (_type==GLU_MAP2_NORMAL)) || + (global_bpm->bpatch_color==NULL && (_type==GLU_MAP2_INDEX || _type==GLU_MAP2_COLOR_4)) || + (global_bpm->bpatch_texcoord==NULL && (_type==GLU_MAP2_TEXTURE_COORD_1 || + _type==GLU_MAP2_TEXTURE_COORD_2 || _type==GLU_MAP2_TEXTURE_COORD_3 || _type==GLU_MAP2_TEXTURE_COORD_4))) + { + bezierPatchMeshPutPatch(global_bpm, (int)_type, _ulower, _uupper, (int)_ustride, (int)_uorder, _vlower, _vupper, (int)_vstride, (int)_vorder, pts); + } + else /* new surface patch (with multiple maps) starts */ + { + bezierPatchMesh* temp=bezierPatchMeshMake2(10, 10); + bezierPatchMeshPutPatch(temp, (int)_type, _ulower, _uupper, (int)_ustride, (int)_uorder, _vlower, _vupper, (int)_vstride, (int)_vorder, pts); + global_bpm=bezierPatchMeshListInsert(global_bpm, temp); + } + } + else /* not output triangles */ + { + gluMap2f((GLenum)_type, (GLfloat)_ulower, (GLfloat)_uupper, (GLint)_ustride, (GLint)_uorder, + (GLfloat)_vlower, (GLfloat)_vupper, (GLint)_vstride, (GLint)_vorder, (const GLfloat*)pts); + } +#endif +} + + +/*------------------------------------------------------------------------- + * mapmesh2f - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax) +{ +#ifdef USE_INTERNAL_EVAL + inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax); +#else /* USE_INTERNAL_EVAL */ + if (output_triangles) + { + REAL du, dv; + long i, j; + + if (global_grid_nu==0 || global_grid_nv==0) + { + return; /* no points need to be output */ + } + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + dv=(global_grid_v1-global_grid_v0)/(REAL)global_grid_nv; + + if (global_grid_nu>=global_grid_nv) + { + for(i=umin; i=vmin; j--) + { + REAL v1=(j==global_grid_nv)?global_grid_v1:(global_grid_v0+j*dv); + + coord2f(u1, v1); + coord2f(u2, v1); + } + endqstrip(); + } + } + else + { + for(i=vmin; i=umin; j--) + { + REAL u1=(j==global_grid_nu)?global_grid_u1:(global_grid_u0+j*du); + + coord2f(u1, v2); + coord2f(u1, v1); + } + + endqstrip(); + } + } + } + else + { + switch (style) + { + default: + case N_MESHFILL: + gluEvalMesh2((GLenum)GL_FILL, (GLint)umin, (GLint)umax, (GLint)vmin, (GLint)vmax); + break; + case N_MESHLINE: + gluEvalMesh2((GLenum)GL_LINE, (GLint)umin, (GLint)umax, (GLint)vmin, (GLint)vmax); + break; + case N_MESHPOINT: + gluEvalMesh2((GLenum)GL_POINT, (GLint)umin, (GLint)umax, (GLint)vmin, (GLint)vmax); + break; + } + } +#endif /* USE_INTERNAL_EVAL */ +} + +/*------------------------------------------------------------------------- + * evalcoord2f - evaluate a point on a surface + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ + newtmeshvert(u, v, retPoint, retNormal); +} + +/*------------------------------------------------------------------------- + * evalpoint2i - evaluate a grid point + *------------------------------------------------------------------------- + */ +void OpenGLSurfaceEvaluator::evalpoint2i(long u, long v) +{ + newtmeshvert(u, v); +} + +void OpenGLSurfaceEvaluator::point2i(long u, long v) +{ +#ifdef USE_INTERNAL_EVAL + inEvalPoint2((int)u, (int)v); +#else + if (output_triangles) + { + REAL du, dv; + REAL fu, fv; + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + dv=(global_grid_v1-global_grid_v0)/(REAL)global_grid_nv; + fu=(u==global_grid_nu)?global_grid_u1:(global_grid_u0+u*du); + fv=(v==global_grid_nv)?global_grid_v1:(global_grid_v0+v*dv); + coord2f(fu, fv); + } + else + { + gluEvalPoint2((GLint)u, (GLint)v); + } +#endif /* USE_INTERNAL_EVAL */ +} + +void OpenGLSurfaceEvaluator::coord2f(REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ +#ifdef USE_INTERNAL_EVAL + inEvalCoord2f(u, v, retPoint, retNormal); +#else + if (output_triangles) + { + bezierPatchMeshInsertUV(global_bpm, u, v); + } + else + { + gluEvalCoord2f((GLfloat)u, (GLfloat)v); + } +#endif /* USE_INTERNAL_EVAL */ +} + +void OpenGLSurfaceEvaluator::newtmeshvert(long u, long v) +{ + if (tmeshing) + { + if (vcount==2) + { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + point2i(u, v); + } + else + { + vcount++; + } + + vertexCache[which]->saveEvalPoint(u, v); + which=1-which; + } + else + { + point2i(u, v); + } +} + +void OpenGLSurfaceEvaluator::newtmeshvert(REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ + if (tmeshing) + { + if (vcount==2) + { + vertexCache[0]->invoke(this); + vertexCache[1]->invoke(this); + coord2f(u, v, retPoint, retNormal); + } + else + { + vcount++; + } + + vertexCache[which]->saveEvalCoord(u, v); + which=1-which; + } + else + { + coord2f(u, v, retPoint, retNormal); + } +} + +#ifdef _WIN32 +void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (APIENTRY* fn)()) +#else +void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn) +#endif +{ + switch(which) + { + case GLU_NURBS_BEGIN: + beginCallBackN = (void (APIENTRY *) (GLenum)) fn; + break; + case GLU_NURBS_END: + endCallBackN = (void (APIENTRY *) (void)) fn; + break; + case GLU_NURBS_VERTEX: + vertexCallBackN = (void (APIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_NORMAL: + normalCallBackN = (void (APIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_COLOR: + colorCallBackN = (void (APIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD: + texcoordCallBackN = (void (APIENTRY *) (const GLfloat*)) fn; + break; + case GLU_NURBS_BEGIN_DATA: + beginCallBackData = (void (APIENTRY *) (GLenum, void*)) fn; + break; + case GLU_NURBS_END_DATA: + endCallBackData = (void (APIENTRY *) (void*)) fn; + break; + case GLU_NURBS_VERTEX_DATA: + vertexCallBackData = (void (APIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_NORMAL_DATA: + normalCallBackData = (void (APIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_COLOR_DATA: + colorCallBackData = (void (APIENTRY *) (const GLfloat*, void*)) fn; + break; + case GLU_NURBS_TEXTURE_COORD_DATA: + texcoordCallBackData = (void (APIENTRY *) (const GLfloat*, void*)) fn; + break; + + } +} + +void OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void* data) +{ + if(beginCallBackData) + { + beginCallBackData(which, data); + } + else + { + if(beginCallBackN) + { + beginCallBackN(which); + } + } +} + +void OpenGLSurfaceEvaluator::endCallBack(void* data) +{ + if (endCallBackData) + { + endCallBackData(data); + } + else + { + if (endCallBackN) + { + endCallBackN(); + } + } +} + +void OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat* vert, void* data) +{ + if (vertexCallBackData) + { + vertexCallBackData(vert, data); + } + else + { + if (vertexCallBackN) + { + vertexCallBackN(vert); + } + } +} + +void OpenGLSurfaceEvaluator::normalCallBack(const GLfloat* normal, void* data) +{ + if (normalCallBackData) + { + normalCallBackData(normal, data); + } + else + { + if (normalCallBackN) + { + normalCallBackN(normal); + } + } +} + +void OpenGLSurfaceEvaluator::colorCallBack(const GLfloat* color, void* data) +{ + if (colorCallBackData) + { + colorCallBackData(color, data); + } + else + { + if (colorCallBackN) + { + colorCallBackN(color); + } + } +} + +void OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat* texcoord, void* data) +{ + if (texcoordCallBackData) + { + texcoordCallBackData(texcoord, data); + } + else + { + if (texcoordCallBackN) + { + texcoordCallBackN(texcoord); + } + } +} diff --git a/project/jni/glu/src/libnurbs/interface/glsurfeval.h b/project/jni/glu/src/libnurbs/interface/glsurfeval.h new file mode 100644 index 000000000..eb30de102 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/glsurfeval.h @@ -0,0 +1,357 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluglsurfeval_h_ +#define __gluglsurfeval_h_ + +#include "basicsurfeval.h" +#include "bezierPatchMesh.h" //in case output triangles + +#include "glues.h" + +class SurfaceMap; +class OpenGLSurfaceEvaluator; +class StoredVertex; + +#define TYPECOORD 1 +#define TYPEPOINT 2 + +/* Cache up to 3 vertices from tmeshes */ +#define VERTEX_CACHE_SIZE 3 + +/* for internal evaluator callback stuff */ +#ifndef IN_MAX_BEZIER_ORDER + #define IN_MAX_BEZIER_ORDER 40 /* should be bigger than machine order */ +#endif + +#ifndef IN_MAX_DIMENSION + #define IN_MAX_DIMENSION 4 +#endif + +typedef struct surfEvalMachine +{ + REAL uprime; /* cached previusly evaluated uprime. */ + REAL vprime; + int k; /* the dimension */ + REAL u1; + REAL u2; + int ustride; + int uorder; + REAL v1; + REAL v2; + int vstride; + int vorder; + REAL ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + REAL ucoeff[IN_MAX_BEZIER_ORDER]; /* cache the polynomial values */ + REAL vcoeff[IN_MAX_BEZIER_ORDER]; + REAL ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /* cache the polynomial derivatives */ + REAL vcoeffDeriv[IN_MAX_BEZIER_ORDER]; +} surfEvalMachine; + +class StoredVertex +{ + public: + StoredVertex() {type=0;} + ~StoredVertex(void) {} + void saveEvalCoord(REAL x, REAL y) + {coord[0]=x; coord[1]=y; type=TYPECOORD;} + void saveEvalPoint(long x, long y) + {point[0]=x; point[1]=y; type=TYPEPOINT;} + void invoke(OpenGLSurfaceEvaluator* eval); + private: + int type; + REAL coord[2]; + long point[2]; +}; + +class OpenGLSurfaceEvaluator: public BasicSurfaceEvaluator +{ + public: + OpenGLSurfaceEvaluator(); + virtual ~OpenGLSurfaceEvaluator(void); + void polymode(long style); + long get_output_style(); + void range2f(long, REAL*, REAL*); + void domain2f(REAL, REAL, REAL, REAL); + void addMap(SurfaceMap*) { } + + void enable(long); + void disable(long); + void bgnmap2f(long); + void map2f(long, REAL, REAL, long, long, REAL, REAL, long, long, REAL*); + void mapgrid2f(long, REAL, REAL, long, REAL, REAL); + void mapmesh2f(long, long, long, long, long); + void evalcoord2f(long, REAL, REAL, REAL*, REAL*); + void evalpoint2i(long, long); + void endmap2f(void); + + void bgnline(void); + void endline(void); + void bgnclosedline(void); + void endclosedline(void); + void bgntmesh(void); + void swaptmesh(void); + void endtmesh(void); + void bgnqstrip(void); + void endqstrip(void); + + void bgntfan(void); + void endtfan(void); + void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val); + void evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val); + + void coord2f(REAL, REAL, REAL* retPoint, REAL* retNormal); + void point2i(long, long); + + void newtmeshvert(REAL, REAL, REAL*, REAL*); + void newtmeshvert(long, long); + +#ifdef _WIN32 + void putCallBack(GLenum which, void (APIENTRY* fn)()); +#else + void putCallBack(GLenum which, _GLUfuncptr fn); +#endif + + int get_vertices_call_back() + { + return output_triangles; + } + void put_vertices_call_back(int flag) + { + output_triangles=flag; + } + + void put_callback_auto_normal(int flag) + { + callback_auto_normal=flag; + } + + int get_callback_auto_normal() + { + return callback_auto_normal; + } + + void set_callback_userData(void* data) + { + userData=data; + } + + private: + StoredVertex* vertexCache[VERTEX_CACHE_SIZE]; + int tmeshing; + int which; + int vcount; + + GLint gl_polygon_mode[2]; // to save and restore so that no side effect + bezierPatchMesh* global_bpm; // for output triangles + int output_triangles; // true 1 or false 0 + long output_style; // N_MESHFILL or N_MESHLINE or N_MESHPOINT + + void (APIENTRY* beginCallBackN)(GLenum type); + void (APIENTRY* endCallBackN)(void); + void (APIENTRY* vertexCallBackN)(const GLfloat* vert); + void (APIENTRY* normalCallBackN)(const GLfloat* normal); + void (APIENTRY* colorCallBackN)(const GLfloat* color); + void (APIENTRY* texcoordCallBackN)(const GLfloat* texcoord); + + void (APIENTRY* beginCallBackData)(GLenum type, void* data); + void (APIENTRY* endCallBackData)(void* data); + void (APIENTRY* vertexCallBackData)(const GLfloat* vert, void* data); + void (APIENTRY* normalCallBackData)(const GLfloat* normal, void* data); + void (APIENTRY* colorCallBackData)(const GLfloat* color, void* data); + void (APIENTRY* texcoordCallBackData)(const GLfloat* texcoord, void* data); + + void beginCallBack(GLenum type, void* data); + void endCallBack(void* data); + void vertexCallBack(const GLfloat* vert, void* data); + void normalCallBack(const GLfloat* normal, void* data); + void colorCallBack(const GLfloat* color, void* data); + void texcoordCallBack(const GLfloat* texcoord, void* data); + + void* userData; // the opaque pointer for Data callback functions. + + /*************begin for internal evaluators*****************/ + + /* the following global variables are only defined in this file. + * They are used to cache the precomputed Bezier polynomial values. + * These calues may be used consecutively in which case we don't have + * recompute these values again. + */ + int global_uorder; /* store the uorder in the previous evaluation */ + int global_vorder; /* store the vorder in the previous evaluation */ + REAL global_uprime; + REAL global_vprime; + REAL global_vprime_BV; + REAL global_uprime_BU; + int global_uorder_BV; /* store the uorder in the previous evaluation */ + int global_vorder_BV; /* store the vorder in the previous evaluation */ + int global_uorder_BU; /* store the uorder in the previous evaluation */ + int global_vorder_BU; /* store the vorder in the previous evaluation */ + + REAL global_ucoeff[IN_MAX_BEZIER_ORDER]; /* cache the polynomial values */ + REAL global_vcoeff[IN_MAX_BEZIER_ORDER]; + REAL global_ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /* cache the polynomial derivatives */ + REAL global_vcoeffDeriv[IN_MAX_BEZIER_ORDER]; + + REAL global_BV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_PBV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_BU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL global_PBU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION]; + REAL* global_baseData; + + int global_ev_k; /* the dimension */ + REAL global_ev_u1; + REAL global_ev_u2; + int global_ev_ustride; + int global_ev_uorder; + REAL global_ev_v1; + REAL global_ev_v2; + int global_ev_vstride; + int global_ev_vorder; + REAL global_ev_ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION]; + + REAL global_grid_u0; + REAL global_grid_u1; + int global_grid_nu; + REAL global_grid_v0; + REAL global_grid_v1; + int global_grid_nv; + + /* functions */ + void inDoDomain2WithDerivs(int k, REAL u, REAL v, REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, REAL* baseData, + REAL* retPoint, REAL* retdu, REAL* retdv); + void inPreEvaluate(int order, REAL vprime, REAL* coeff); + void inPreEvaluateWithDeriv(int order, REAL vprime, REAL* coeff, REAL* coeffDeriv); + void inComputeFirstPartials(REAL* p, REAL* pu, REAL* pv); + void inComputeNormal2(REAL* pu, REAL* pv, REAL* n); + void inDoEvalCoord2(REAL u, REAL v, REAL* retPoint, REAL* retNormal); + void inDoEvalCoord2NOGE(REAL u, REAL v, REAL* retPoint, REAL* retNormal); + void inMap2f(int k, REAL ulower, REAL uupper, int ustride, int uorder, + REAL vlower, REAL vupper, int vstride, int vorder, REAL* ctlPoints); + + void inMapGrid2f(int nu, REAL u0, REAL u1, int nv, REAL v0, REAL v1); + + void inEvalMesh2(int lowU, int lowV, int highU, int highV); + void inEvalPoint2(int i, int j); + void inEvalCoord2f(REAL u, REAL v, REAL* retPoint, REAL* retNormal); + + void inEvalULine(int n_points, REAL v, REAL* u_vals, int stride, + REAL ret_points[][3], REAL ret_normals[][3]); + + void inEvalVLine(int n_points, REAL u, REAL* v_vals, int stride, + REAL ret_points[][3], REAL ret_normals[][3]); + + void inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val); + void inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, + REAL u_right, REAL* right_val); + + void inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL* baseData); + void inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL* baseData); + void inPreEvaluateBV_intfac(REAL v) + { + inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints); + } + + void inPreEvaluateBU_intfac(REAL u) + { + inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints); + } + + void inDoDomain2WithDerivsBV(int k, REAL u, REAL v, REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, REAL* baseData, + REAL* retPoint, REAL* retdu, REAL *retdv); + + void inDoDomain2WithDerivsBU(int k, REAL u, REAL v, REAL u1, REAL u2, int uorder, + REAL v1, REAL v2, int vorder, REAL* baseData, + REAL* retPoint, REAL* retdu, REAL *retdv); + + void inDoEvalCoord2NOGE_BV(REAL u, REAL v, REAL* retPoint, REAL* retNormal); + + void inDoEvalCoord2NOGE_BU(REAL u, REAL v, REAL* retPoint, REAL* retNormal); + + void inBPMEval(bezierPatchMesh* bpm); + void inBPMListEval(bezierPatchMesh* list); + + /*-------------begin for surfEvalMachine -------------*/ + surfEvalMachine em_vertex; + surfEvalMachine em_normal; + surfEvalMachine em_color; + surfEvalMachine em_texcoord; + + int auto_normal_flag; // whether to output normal or not in callback + // determined by GLU_AUTO_NORMAL and callback_auto_normal + int callback_auto_normal; // GLU_CALLBACK_AUTO_NORMAL_EXT + int vertex_flag; + int normal_flag; + int color_flag; + int texcoord_flag; + + void inMap2fEM(int which, int dimension, REAL ulower, REAL uupper, int ustride, + int uorder, REAL vlower, REAL vupper, int vstride, int vorder, REAL* ctlPoints); + + void inDoDomain2WithDerivsEM(surfEvalMachine* em, REAL u, REAL v, REAL* retPoint, + REAL* retdu, REAL* retdv); + void inDoDomain2EM(surfEvalMachine* em, REAL u, REAL v, REAL* retPoint); + void inDoEvalCoord2EM(REAL u, REAL v); + + void inBPMEvalEM(bezierPatchMesh* bpm); + void inBPMListEvalEM(bezierPatchMesh* list); + + /*-------------end for surfEvalMachine -------------*/ + /*************end for internal evaluators*****************/ +}; + +inline void StoredVertex::invoke(OpenGLSurfaceEvaluator* eval) +{ + REAL retPoint[4]; + REAL retNormal[3]; + + switch(type) + { + case TYPECOORD: + eval->coord2f(coord[0], coord[1], retPoint, retNormal); + break; + case TYPEPOINT: + eval->point2i(point[0], point[1]); + break; + default: + break; + } +} + +#endif /* __gluglsurfeval_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/incurveeval.cc b/project/jni/glu/src/libnurbs/interface/incurveeval.cc new file mode 100644 index 000000000..c0a98a205 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/incurveeval.cc @@ -0,0 +1,387 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include + +#include "glcurveval.h" + +/* + *compute the Bezier polynomials C[n,j](v) for all j at v with + *return values stored in coeff[], where + * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j), + * j=0,1,2,...,n. + *order : n+1 + *vprime: v + *coeff : coeff[j]=C[n,j](v), this array store the returned values. + *The algorithm is a recursive scheme: + * C[0,0]=1; + * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1 + *This code is copied from opengl/soft/so_eval.c:PreEvaluate + */ +void OpenGLCurveEvaluator::inPreEvaluate(int order, REAL vprime, REAL* coeff) +{ + int i, j; + REAL oldval, temp; + REAL oneMinusvprime; + + /* + * Minor optimization + * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to + * their i==1 loop values to avoid the initialization and the i==1 loop. + */ + if (order==1) + { + coeff[0]=1.0f; + return; + } + + oneMinusvprime=1-vprime; + coeff[0]=oneMinusvprime; + coeff[1]=vprime; + + if (order==2) + { + return; + } + + for (i=2; ictlpoints; + temp_em->uprime=-1; // initialized + temp_em->k=k; + temp_em->u1=ulower; + temp_em->u2=uupper; + temp_em->ustride=ustride; + temp_em->uorder=uorder; + + /* copy the control points */ + for(i=0; ictlpoints; + temp_em->uprime=-1; // initialized + temp_em->k=k; + temp_em->u1=ulower; + temp_em->u2=uupper; + temp_em->ustride=ustride; + temp_em->uorder=uorder; + + /* copy the control points */ + for(i=0; iu2==em->u1) + { + return; + } + the_uprime=(u-em->u1)/(em->u2-em->u1); + + /* use already cached values if possible */ + if (em->uprime!=the_uprime) + { + inPreEvaluate(em->uorder, the_uprime, em->ucoeff); + em->uprime = the_uprime; + } + + for(j=0; jk; j++) + { + data=em->ctlpoints+j; + retPoint[j]=0.0f; + for (row=0; rowuorder; row++) + { + retPoint[j]+=em->ucoeff[row]*(*data); + data+=em->k; + } + } +} + +void OpenGLCurveEvaluator::inDoEvalCoord1(REAL u) +{ + REAL temp_vertex[4]; + REAL temp_normal[3]; + REAL temp_color[4]; + REAL temp_texcoord[4]; + + if (texcoord_flag) // there is a texture map + { + inDoDomain1(&em_texcoord, u, temp_texcoord); + texcoordCallBack(temp_texcoord, userData); + } + if (color_flag) // there is a color map + { + inDoDomain1(&em_color, u, temp_color); + colorCallBack(temp_color, userData); + } + if (normal_flag) // there is a normal map + { + inDoDomain1(&em_normal, u, temp_normal); + normalCallBack(temp_normal, userData); + } + if (vertex_flag) + { + inDoDomain1(&em_vertex, u, temp_vertex); + vertexCallBack(temp_vertex, userData); + } +} + +void OpenGLCurveEvaluator::inDoEvalCoord1r(REAL u, REAL* retPoint) +{ + inDoDomain1(&em_vertex, u, retPoint); +} + +void OpenGLCurveEvaluator::inMapMesh1f(int umin, int umax) +{ + REAL du, u; + int i; + + if (global_grid_nu==0) + { + return; // no points to output + } + + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + + bgnline(); + + for(i=umin; i<=umax; i++) + { + u=(i==global_grid_nu)?global_grid_u1:global_grid_u0+i*du; + inDoEvalCoord1(u); + } + + endline(); +} + +void OpenGLCurveEvaluator::inMapMesh1fr(int umin, int umax) +{ + REAL du, u; + REAL retPoint[4]; + REAL* vertices=NULL; + int i; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + if (global_grid_nu==0) + { + return; // no points to output + } + + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + + vertices=(REAL*)malloc((umax-umin+1)*3*sizeof(REAL)); + + bgnline(); + + for(i=umin; i<=umax; i++) + { + u=(i==global_grid_nu)?global_grid_u1:global_grid_u0+i*du; + inDoEvalCoord1r(u, retPoint); + + vertices[(i-umin)*3 + 0]=retPoint[0]; + vertices[(i-umin)*3 + 1]=retPoint[1]; + vertices[(i-umin)*3 + 2]=retPoint[2]; + } + + endline(); + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + /* Perform rendering */ + if (output_style==N_MESHPOINT) + { + /* Output as points */ + glDrawArrays(GL_POINTS, 0, umax-umin+1); + } + else + { + /* Output as line strip */ + glDrawArrays(GL_LINE_STRIP, 0, umax-umin+1); + } + + /* 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); + } + + free(vertices); +} diff --git a/project/jni/glu/src/libnurbs/interface/insurfeval.cc b/project/jni/glu/src/libnurbs/interface/insurfeval.cc new file mode 100644 index 000000000..cfe6d5408 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/insurfeval.cc @@ -0,0 +1,2585 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include +#include +#include + +#include "glsurfeval.h" + +#include "gles_evaluator.h" + +#define AVOID_ZERO_NORMAL + +#ifdef AVOID_ZERO_NORMAL +#define myabs(x) ((x>0)? x: (-x)) +#define MYZERO 0.000001f +#define MYDELTA 0.001f +#endif + +void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + for(temp=list; temp!=NULL; temp=temp->next) + { + inBPMEval(temp); + } +} + +void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm) +{ + int i, j, k, l; + float u, v; + + int ustride=bpm->bpatch->dimension*bpm->bpatch->vorder; + int vstride=bpm->bpatch->dimension; + + inMap2f((bpm->bpatch->dimension == 3)? GLU_MAP2_VERTEX_3 : GLU_MAP2_VERTEX_4, + bpm->bpatch->umin, bpm->bpatch->umax, ustride, bpm->bpatch->uorder, + bpm->bpatch->vmin, bpm->bpatch->vmax, vstride, bpm->bpatch->vorder, + bpm->bpatch->ctlpoints); + + /* in case the origional dimenion is 4, then we need 4 space to pass to evaluator. */ + bpm->vertex_array=(float*)malloc(sizeof(float)*(bpm->index_UVarray/2)*3+1); + assert(bpm->vertex_array); + bpm->normal_array=(float*)malloc(sizeof(float)*(bpm->index_UVarray/2)*3); + assert(bpm->normal_array); + + k=0; + l=0; + + for(i=0; iindex_length_array; i++) + { + beginCallBack(bpm->type_array[i], userData); + for(j=0; jlength_array[i]; j++) + { + u=bpm->UVarray[k]; + v=bpm->UVarray[k+1]; + inDoEvalCoord2NOGE(u,v, bpm->vertex_array+l, bpm->normal_array+l); + + normalCallBack(bpm->normal_array+l, userData); + vertexCallBack(bpm->vertex_array+l, userData); + + k+=2; + l+=3; + } + endCallBack(userData); + } +} + +void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j) +{ + REAL du, dv; + REAL point[4]; + REAL normal[3]; + REAL u,v; + + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + dv=(global_grid_v1-global_grid_v0)/(REAL)global_grid_nv; + u=(i==global_grid_nu)?global_grid_u1:(global_grid_u0+i*du); + v=(j==global_grid_nv)?global_grid_v1:(global_grid_v0+j*dv); + + inDoEvalCoord2(u, v, point, normal); +} + +void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ + inDoEvalCoord2(u, v, retPoint, retNormal); +} + +/* define a grid. store the values into the global variabls: + * global_grid_* + * These values will be used later by evaluating functions + */ +void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1, int nv, REAL v0, REAL v1) +{ + global_grid_u0=u0; + global_grid_u1=u1; + global_grid_nu=nu; + global_grid_v0=v0; + global_grid_v1=v1; + global_grid_nv=nv; +} + +void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV) +{ + REAL du, dv; + int i, j; + int it; + REAL point[4]; + REAL normal[3]; + REAL* normals=NULL; + REAL* vertices=NULL; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + if (global_grid_nu==0 || global_grid_nv==0) + { + return; /* no points need to be output */ + } + + /* 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); */ + + normals=(REAL*)malloc(sizeof(REAL)*3*2*((highU-lowU)>(highV-lowV)?(highU-lowU+1):(highV-lowV+1))); + assert(normals); + vertices=(REAL*)malloc(sizeof(REAL)*3*2*((highU-lowU)>(highV-lowV)?(highU-lowU+1):(highV-lowV+1))); + assert(vertices); + + /* Enable needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + du=(global_grid_u1-global_grid_u0)/(REAL)global_grid_nu; + dv=(global_grid_v1-global_grid_v0)/(REAL)global_grid_nv; + + if (global_grid_nu>=global_grid_nv) + { + for(i=lowU; i=lowV; j--) + { + REAL v1=(j==global_grid_nv)?global_grid_v1:(global_grid_v0+j*dv); + + if (((it%4==2) || (it%4==3)) && (output_style==N_MESHLINE)) + { + inDoEvalCoord2(u2, v1, point, normal); + } + else + { + inDoEvalCoord2(u1, v1, point, normal); + } + if (!output_triangles) + { + vertices[it*3+0]=point[0]; + vertices[it*3+1]=point[1]; + vertices[it*3+2]=point[2]; + normals[it*3+0]=normal[0]; + normals[it*3+1]=normal[1]; + normals[it*3+2]=normal[2]; + it++; + } + if (((it%4==2) || (it%4==3)) && (output_style==N_MESHLINE)) + { + inDoEvalCoord2(u1, v1, point, normal); + } + else + { + inDoEvalCoord2(u2, v1, point, normal); + } + if (!output_triangles) + { + vertices[it*3+0]=point[0]; + vertices[it*3+1]=point[1]; + vertices[it*3+2]=point[2]; + normals[it*3+0]=normal[0]; + normals[it*3+1]=normal[1]; + normals[it*3+2]=normal[2]; + it++; + } + } + + endqstrip(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_STRIP, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt<=it-4; jt+=2) + { + glDrawArrays(GL_LINE_LOOP, jt, 4); + } + } + break; + } + } + } + } + else + { + for(i=lowV; i=lowU; j--) + { + REAL u1=(j==global_grid_nu)?global_grid_u1:(global_grid_u0+j*du); + + if (((it%4==2) || (it%4==3)) && (output_style==N_MESHLINE)) + { + inDoEvalCoord2(u1, v1, point, normal); + } + else + { + inDoEvalCoord2(u1, v2, point, normal); + } + if (!output_triangles) + { + vertices[it*3+0]=point[0]; + vertices[it*3+1]=point[1]; + vertices[it*3+2]=point[2]; + normals[it*3+0]=normal[0]; + normals[it*3+1]=normal[1]; + normals[it*3+2]=normal[2]; + it++; + } + if (((it%4==2) || (it%4==3)) && (output_style==N_MESHLINE)) + { + inDoEvalCoord2(u1, v2, point, normal); + } + else + { + inDoEvalCoord2(u1, v1, point, normal); + } + if (!output_triangles) + { + vertices[it*3+0]=point[0]; + vertices[it*3+1]=point[1]; + vertices[it*3+2]=point[2]; + normals[it*3+0]=normal[0]; + normals[it*3+1]=normal[1]; + normals[it*3+2]=normal[2]; + it++; + } + } + + endqstrip(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_STRIP, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt<=it-4; jt+=2) + { + glDrawArrays(GL_LINE_LOOP, jt, 4); + } + } + 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); + } + + free(vertices); + free(normals); +} + +void OpenGLSurfaceEvaluator::inMap2f(int k, REAL ulower, REAL uupper, int ustride, + int uorder, REAL vlower, REAL vupper, int vstride, + int vorder, REAL* ctlPoints) +{ + int i, j, x; + REAL* data=global_ev_ctlPoints; + + if (k==GLU_MAP2_VERTEX_3) + { + k=3; + } + else + { + if (k==GLU_MAP2_VERTEX_4) + { + k=4; + } + else + { + printf("error in inMap2f, maptype=%i is wrong, k, map is not updated\n", k); + return; + } + } + + global_ev_k=k; + global_ev_u1=ulower; + global_ev_u2=uupper; + global_ev_ustride=ustride; + global_ev_uorder=uorder; + global_ev_v1=vlower; + global_ev_v2=vupper; + global_ev_vstride=vstride; + global_ev_vorder=vorder; + + /* copy the contrl points from ctlPoints to global_ev_ctlPoints */ + for (i=0; i0.0f) + { + n[0]/=mag; + n[1]/=mag; + n[2]/=mag; + } +} + +/* Compute point and normal + * see the head of inDoDomain2WithDerivs + * for the meaning of the arguments + */ +void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ + REAL du[4]; + REAL dv[4]; + + assert(global_ev_k>=3 && global_ev_k<=4); + /* compute homegeneous point and partial derivatives */ + inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if (myabs(dv[0])<=MYZERO && myabs(dv[1])<=MYZERO && myabs(dv[2])<=MYZERO) + { + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1=global_ev_u1; + REAL u2=global_ev_u2; + + if (u-MYDELTA*(u2-u1)=3 && global_ev_k<=4); + /* compute homegeneous point and partial derivatives */ + inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if (myabs(dv[0])<=MYZERO && myabs(dv[1])<=MYZERO && myabs(dv[2])<=MYZERO) + { + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1 = global_ev_u1; + REAL u2 = global_ev_u2; + + if (u-MYDELTA*(u2-u1)=3 && global_ev_k<=4); + /* compute homegeneous point and partial derivatives */ + inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if (myabs(dv[0])<=MYZERO && myabs(dv[1])<=MYZERO && myabs(dv[2])<=MYZERO) + { + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1=global_ev_u1; + REAL u2=global_ev_u2; + if (u-MYDELTA*(u2-u1)=3 && global_ev_k<=4); + /* compute homegeneous point and partial derivatives */ + inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if (myabs(dv[0])<=MYZERO && myabs(dv[1])<=MYZERO && myabs(dv[2])<=MYZERO) + { + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1=global_ev_u1; + REAL u2=global_ev_u2; + + if (u-MYDELTA*(u2-u1)=1 + *This code is copied from opengl/soft/so_eval.c:PreEvaluate + */ +void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL* coeff) +{ + int i, j; + REAL oldval, temp; + REAL oneMinusvprime; + + /* + * Minor optimization + * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to + * their i==1 loop values to avoid the initialization and the i==1 loop. + */ + if (order==1) + { + coeff[0]=1.0f; + return; + } + + oneMinusvprime=1-vprime; + coeff[0]=oneMinusvprime; + coeff[1]=vprime; + + if (order==2) + { + return; + } + + for (i=2; i=1 + * n_lower >=1 + */ +void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val) +{ + int i, j, k, l; + REAL leftMostV[2]; + typedef REAL REAL3[3]; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + REAL3* upperXYZ=(REAL3*)malloc(sizeof(REAL3)*n_upper); + assert(upperXYZ); + REAL3* upperNormal=(REAL3*)malloc(sizeof(REAL3)*n_upper); + assert(upperNormal); + REAL3* lowerXYZ=(REAL3*)malloc(sizeof(REAL3)*n_lower); + assert(lowerXYZ); + REAL3* lowerNormal=(REAL3*)malloc(sizeof(REAL3)*n_lower); + assert(lowerNormal); + REAL3* normals=(REAL3*)malloc(sizeof(REAL3)*((n_lower>n_upper?n_lower:n_upper)*3)); + assert(normals); + REAL3* vertices=(REAL3*)malloc(sizeof(REAL3)*((n_lower>n_upper?n_lower:n_upper)*3)); + assert(vertices); + + inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal); + inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal); + + REAL* leftMostXYZ; + REAL* leftMostNormal; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + /* + * the algorithm works by scanning from left to right. + * leftMostV: the left most of the remaining verteces (on both upper and lower). + * it could an element of upperVerts or lowerVerts. + * i: upperVerts[i] is the first vertex to the right of leftMostV on upper line *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line + */ + + /* initialize i,j,and leftMostV */ + if (upper_val[0]<=lower_val[0]) + { + i=1; + j=0; + + leftMostV[0]=upper_val[0]; + leftMostV[1]=v_upper; + leftMostXYZ=upperXYZ[0]; + leftMostNormal=upperNormal[0]; + } + else + { + i=0; + j=1; + + leftMostV[0]=lower_val[0]; + leftMostV[1]=v_lower; + + leftMostXYZ=lowerXYZ[0]; + leftMostNormal=lowerNormal[0]; + } + + /* the main loop. + * the invariance is that: + * at the beginning of each loop, the meaning of i,j,and leftMostV are + * maintained + */ + + while(1) + { + if (i>=n_upper) /* case1: no more in upper */ + { + if (j=n_lower) /* case2: no more in lower */ + { + if (i=i; k--) /* reverse order for two-side lighting */ + { + if ((output_style==N_MESHLINE) && (it%3==0)) + { + /* Fill up start vertex for triangle fan */ + *((REAL*)(normals+it)+0)=*((REAL*)leftMostNormal+0); + *((REAL*)(normals+it)+1)=*((REAL*)leftMostNormal+1); + *((REAL*)(normals+it)+2)=*((REAL*)leftMostNormal+2); + *((REAL*)(vertices+it)+0)=*((REAL*)leftMostXYZ+0); + *((REAL*)(vertices+it)+1)=*((REAL*)leftMostXYZ+1); + *((REAL*)(vertices+it)+2)=*((REAL*)leftMostXYZ+2); + it++; + /* Fill up previous vertex */ + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+k-1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+k-1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+k-1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+k-1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+k-1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+k-1)+2); + it++; + } + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+k)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+k)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+k)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+k)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+k)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+k)+2); + it++; + } + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt=i such that + * upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + + while(klower_val[j]) + { + break; + } + k++; + } + k--; + + for(l=k; l>=i; l--) /* the reverse is for two-side lighting */ + { + if ((output_style==N_MESHLINE) && (it%3==0)) + { + if (!output_triangles) + { + /* Fill up start vertex for triangle fan */ + *((REAL*)(normals+it)+0)=*((REAL*)(lowerNormal+j)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(lowerNormal+j)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(lowerNormal+j)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(lowerXYZ+j)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(lowerXYZ+j)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(lowerXYZ+j)+2); + it++; + /* Fill up previous vertex */ + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+l+1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+l+1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+l+1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+l+1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+l+1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+l+1)+2); + it++; + } + } + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+l)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+l)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+l)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+l)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+l)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+l)+2); + it++; + } + } + + if ((output_style==N_MESHLINE) && (it%3==0)) + { + if (!output_triangles) + { + /* Fill up start vertex for triangle fan */ + *((REAL*)(normals+it)+0)=*((REAL*)(lowerNormal+j)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(lowerNormal+j)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(lowerNormal+j)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(lowerXYZ+j)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(lowerXYZ+j)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(lowerXYZ+j)+2); + it++; + /* Fill up previous vertex */ + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+l+1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+l+1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+l+1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+l+1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+l+1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+l+1)+2); + it++; + } + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)leftMostNormal+0); + *((REAL*)(normals+it)+1)=*((REAL*)leftMostNormal+1); + *((REAL*)(normals+it)+2)=*((REAL*)leftMostNormal+2); + *((REAL*)(vertices+it)+0)=*((REAL*)leftMostXYZ+0); + *((REAL*)(vertices+it)+1)=*((REAL*)leftMostXYZ+1); + *((REAL*)(vertices+it)+2)=*((REAL*)leftMostXYZ+2); + it++; + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt lowerVerts[j][0] */ + { + int it=0; + + bgntfan(); + + if (!output_triangles) + { + /* Fill up start vertex for triangle fan */ + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+i)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+i)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+i)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+i)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+i)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+i)+2); + it++; + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)leftMostNormal+0); + *((REAL*)(normals+it)+1)=*((REAL*)leftMostNormal+1); + *((REAL*)(normals+it)+2)=*((REAL*)leftMostNormal+2); + *((REAL*)(vertices+it)+0)=*((REAL*)leftMostXYZ+0); + *((REAL*)(vertices+it)+1)=*((REAL*)leftMostXYZ+1); + *((REAL*)(vertices+it)+2)=*((REAL*)leftMostXYZ+2); + it++; + } + + /* find the last k>=j such that + * lowerverts[k][0] < upperverts[i][0] + */ + k=j; + while(k=upper_val[i]) + { + break; + } + + if ((output_style==N_MESHLINE) && (it%3==0)) + { + if (!output_triangles) + { + /* Fill up start vertex for triangle fan */ + *((REAL*)(normals+it)+0)=*((REAL*)(upperNormal+i)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(upperNormal+i)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(upperNormal+i)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(upperXYZ+i)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(upperXYZ+i)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(upperXYZ+i)+2); + it++; + /* Fill up previous vertex */ + *((REAL*)(normals+it)+0)=*((REAL*)(lowerNormal+k-1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(lowerNormal+k-1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(lowerNormal+k-1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(lowerXYZ+k-1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(lowerXYZ+k-1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(lowerXYZ+k-1)+2); + it++; + } + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(lowerNormal+k)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(lowerNormal+k)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(lowerNormal+k)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(lowerXYZ+k)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(lowerXYZ+k)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(lowerXYZ+k)+2); + it++; + } + k++; + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt=1 + * n_right >=1 + */ +void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val) +{ + int i, j, k, l; + REAL botMostV[2]; + typedef REAL REAL3[3]; + int it; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + REAL3* leftXYZ=(REAL3*)malloc(sizeof(REAL3)*n_left); + assert(leftXYZ); + REAL3* leftNormal=(REAL3*)malloc(sizeof(REAL3)*n_left); + assert(leftNormal); + REAL3* rightXYZ=(REAL3*) malloc(sizeof(REAL3)*n_right); + assert(rightXYZ); + REAL3* rightNormal=(REAL3*)malloc(sizeof(REAL3)*n_right); + assert(rightNormal); + REAL3* normals=(REAL3*)malloc(sizeof(REAL3)*((n_left>n_right?n_left:n_right)*3)); + assert(normals); + REAL3* vertices=(REAL3*)malloc(sizeof(REAL3)*((n_left>n_right?n_left:n_right)*3)); + assert(vertices); + + inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal); + inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal); + + REAL* botMostXYZ; + REAL* botMostNormal; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + /* + * the algorithm works by scanning from bot to top. + * botMostV: the bot most of the remaining verteces (on both left and right). + * it could an element of leftVerts or rightVerts. + * i: leftVerts[i] is the first vertex to the top of botMostV on left line + * j: rightVerts[j] is the first vertex to the top of botMostV on rightline */ + + /* initialize i,j,and botMostV */ + if (left_val[0]<=right_val[0]) + { + i=1; + j=0; + + botMostV[0]=u_left; + botMostV[1]=left_val[0]; + botMostXYZ=leftXYZ[0]; + botMostNormal=leftNormal[0]; + } + else + { + i=0; + j=1; + + botMostV[0]=u_right; + botMostV[1]=right_val[0]; + + botMostXYZ=rightXYZ[0]; + botMostNormal=rightNormal[0]; + } + + /* the main loop. + * the invariance is that: + * at the beginning of each loop, the meaning of i,j,and botMostV are + * maintained + */ + while(1) + { + if (i>=n_left) /* case1: no more in left */ + { + if (j=n_right) /* case2: no more in right */ + { + if (i=i; k--) /* reverse order for two-side lighting */ + { + if ((output_style==N_MESHLINE) && (it%3==0)) + { + *((REAL*)(normals+it)+0)=*((REAL*)(botMostNormal+0)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(botMostNormal+0)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(botMostNormal+0)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(botMostXYZ+0)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(botMostXYZ+0)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(botMostXYZ+0)+2); + it++; + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+k+1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+k+1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+k+1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+k+1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+k+1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+k+1)+2); + it++; + } + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+k)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+k)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+k)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+k)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+k)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+k)+2); + it++; + } + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt=i such that + * leftverts[k][0] <= rightverts[j][0] + */ + k=i; + + while(kright_val[j]) + { + break; + } + k++; + } + k--; + + for(l=k; l>=i; l--) /* the reverse is for two-side lighting */ + { + if ((output_style==N_MESHLINE) && (it%3==0)) + { + *((REAL*)(normals+it)+0)=*((REAL*)(rightNormal+j)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(rightNormal+j)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(rightNormal+j)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(rightXYZ+j)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(rightXYZ+j)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(rightXYZ+j)+2); + it++; + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+l+1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+l+1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+l+1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+l+1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+l+1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+l+1)+2); + it++; + } + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+l)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+l)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+l)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+l)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+l)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+l)+2); + it++; + } + } + + if ((output_style==N_MESHLINE) && (it%3==0)) + { + *((REAL*)(normals+it)+0)=*((REAL*)(rightNormal+j)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(rightNormal+j)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(rightNormal+j)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(rightXYZ+j)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(rightXYZ+j)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(rightXYZ+j)+2); + it++; + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+l+1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+l+1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+l+1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+l+1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+l+1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+l+1)+2); + it++; + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(botMostNormal+0)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(botMostNormal+0)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(botMostNormal+0)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(botMostXYZ+0)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(botMostXYZ+0)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(botMostXYZ+0)+2); + it++; + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jt right_val[j]) */ + { + it=0; + + bgntfan(); + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+i)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+i)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+i)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+i)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+i)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+i)+2); + it++; + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(botMostNormal+0)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(botMostNormal+0)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(botMostNormal+0)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(botMostXYZ+0)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(botMostXYZ+0)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(botMostXYZ+0)+2); + it++; + } + + /* find the last k>=j such that + * rightverts[k][0] < leftverts[i][0] + */ + k=j; + while(k=left_val[i]) + { + break; + } + + if ((output_style==N_MESHLINE) && (it%3==0)) + { + *((REAL*)(normals+it)+0)=*((REAL*)(leftNormal+i)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(leftNormal+i)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(leftNormal+i)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(leftXYZ+i)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(leftXYZ+i)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(leftXYZ+i)+2); + it++; + *((REAL*)(normals+it)+0)=*((REAL*)(rightNormal+k-1)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(rightNormal+k-1)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(rightNormal+k-1)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(rightXYZ+k-1)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(rightXYZ+k-1)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(rightXYZ+k-1)+2); + it++; + } + + if (!output_triangles) + { + *((REAL*)(normals+it)+0)=*((REAL*)(rightNormal+k)+0); + *((REAL*)(normals+it)+1)=*((REAL*)(rightNormal+k)+1); + *((REAL*)(normals+it)+2)=*((REAL*)(rightNormal+k)+2); + *((REAL*)(vertices+it)+0)=*((REAL*)(rightXYZ+k)+0); + *((REAL*)(vertices+it)+1)=*((REAL*)(rightXYZ+k)+1); + *((REAL*)(vertices+it)+2)=*((REAL*)(rightXYZ+k)+2); + it++; + } + k++; + } + + endtfan(); + + if (!output_triangles) + { + switch (output_style) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jtctlPoints; + + temp_em->uprime=-1; // initilized + temp_em->vprime=-1; + + temp_em->k=k; + temp_em->u1=ulower; + temp_em->u2=uupper; + temp_em->ustride=ustride; + temp_em->uorder=uorder; + temp_em->v1=vlower; + temp_em->v2=vupper; + temp_em->vstride=vstride; + temp_em->vorder=vorder; + + /* copy the contrl points from ctlPoints to global_ev_ctlPoints */ + for (i=0; iu2==em->u1)||(em->v2==em->v1)) + { + return; + } + + the_uprime=(u-em->u1)/(em->u2-em->u1); + the_vprime=(v-em->v1)/(em->v2-em->v1); + + /* Compute coefficients for values and derivs */ + + /* Use already cached values if possible */ + if (em->uprime!=the_uprime) + { + inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv); + em->uprime=the_uprime; + } + + if (em->vprime!=the_vprime) + { + inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv); + em->vprime=the_vprime; + } + + for (j=0; jk; j++) + { + data=em->ctlPoints+j; + retPoint[j]=retdu[j]=retdv[j]=0.0f; + for (row=0; rowuorder; row++) + { + /* + ** Minor optimization. + ** The col == 0 part of the loop is extracted so we don't + ** have to initialize p and pdv to 0. + */ + p=em->vcoeff[0]*(*data); + pdv=em->vcoeffDeriv[0]*(*data); + data+=em->k; + for (col=1; colvorder; col++) + { + /* Incrementally build up p, pdv value */ + p+=em->vcoeff[col]*(*data); + pdv+=em->vcoeffDeriv[col]*(*data); + data+=em->k; + } + + /* Use p, pdv value to incrementally add up r, du, dv */ + retPoint[j]+=em->ucoeff[row]*p; + retdu[j]+=em->ucoeffDeriv[row]*p; + retdv[j]+=em->ucoeff[row]*pdv; + } + } +} + +void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine* em, REAL u, REAL v, REAL* retPoint) +{ + int j, row, col; + REAL the_uprime; + REAL the_vprime; + REAL p; + REAL* data; + + if ((em->u2==em->u1) || (em->v2==em->v1)) + { + return; + } + + the_uprime=(u-em->u1)/(em->u2-em->u1); + the_vprime=(v-em->v1)/(em->v2-em->v1); + + /* Compute coefficients for values and derivs */ + + /* Use already cached values if possible */ + if (em->uprime!=the_uprime) + { + inPreEvaluate(em->uorder, the_uprime, em->ucoeff); + em->uprime=the_uprime; + } + + if (em->vprime!=the_vprime) + { + inPreEvaluate(em->vorder, the_vprime, em->vcoeff); + em->vprime=the_vprime; + } + + for (j=0; jk; j++) + { + data=em->ctlPoints+j; + retPoint[j]=0.0f; + + for (row=0; rowuorder; row++) + { + /* + ** Minor optimization. + ** The col == 0 part of the loop is extracted so we don't + ** have to initialize p and pdv to 0. + */ + p=em->vcoeff[0]*(*data); + data+=em->k; + + for (col=1; colvorder; col++) + { + /* Incrementally build up p, pdv value */ + p+=em->vcoeff[col]*(*data); + data+=em->k; + } + /* Use p, pdv value to incrementally add up r, du, dv */ + retPoint[j]+=em->ucoeff[row]*p; + } + } +} + +void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v) +{ + REAL temp_vertex[5]; + REAL temp_normal[3]; + REAL temp_color[4]; + REAL temp_texcoord[4]; + + if (texcoord_flag) + { + inDoDomain2EM(&em_texcoord, u,v, temp_texcoord); + texcoordCallBack(temp_texcoord, userData); + } + if (color_flag) + { + inDoDomain2EM(&em_color, u,v, temp_color); + colorCallBack(temp_color, userData); + } + + if (normal_flag) // there is a normal map + { + inDoDomain2EM(&em_normal, u,v, temp_normal); + normalCallBack(temp_normal, userData); + + if(vertex_flag) + { + inDoDomain2EM(&em_vertex, u, v, temp_vertex); + if (em_vertex.k==4) + { + temp_vertex[0]/=temp_vertex[3]; + temp_vertex[1]/=temp_vertex[3]; + temp_vertex[2]/=temp_vertex[3]; + } + temp_vertex[3]=u; + temp_vertex[4]=v; + vertexCallBack(temp_vertex, userData); + } + } + else + { + if (auto_normal_flag) // no normal map but there is a normal callbackfunctin + { + REAL du[4]; + REAL dv[4]; + + /* compute homegeneous point and partial derivatives */ + inDoDomain2WithDerivsEM(&em_vertex, u, v, temp_vertex, du, dv); + + if (em_vertex.k==4) + { + inComputeFirstPartials(temp_vertex, du, dv); + +#ifdef AVOID_ZERO_NORMAL + if (myabs(dv[0])<=MYZERO && myabs(dv[1])<=MYZERO && myabs(dv[2])<=MYZERO) + { + REAL tempdu[4]; + REAL tempdata[4]; + REAL u1=em_vertex.u1; + REAL u2=em_vertex.u2; + + if (u-MYDELTA*(u2-u1)bpatch!=NULL) + { + bezierPatch* p=bpm->bpatch; + ustride=p->dimension*p->vorder; + vstride=p->dimension; + inMap2fEM(0, p->dimension, p->umin, p->umax, ustride, p->uorder, p->vmin, + p->vmax, vstride, p->vorder, p->ctlpoints); + } + + if (bpm->bpatch_normal!=NULL) + { + bezierPatch* p = bpm->bpatch_normal; + ustride=p->dimension*p->vorder; + vstride=p->dimension; + inMap2fEM(1, p->dimension, p->umin, p->umax, ustride, p->uorder, p->vmin, + p->vmax, vstride, p->vorder, p->ctlpoints); + } + + if (bpm->bpatch_color!=NULL) + { + bezierPatch* p=bpm->bpatch_color; + ustride=p->dimension*p->vorder; + vstride=p->dimension; + inMap2fEM(2, p->dimension, p->umin, p->umax, ustride, p->uorder, p->vmin, + p->vmax, vstride, p->vorder, p->ctlpoints); + } + + if (bpm->bpatch_texcoord!=NULL) + { + bezierPatch* p=bpm->bpatch_texcoord; + ustride=p->dimension * p->vorder; + vstride=p->dimension; + inMap2fEM(3, p->dimension, p->umin, p->umax, ustride, p->uorder, p->vmin, + p->vmax, vstride, p->vorder, p->ctlpoints); + } + + k=0; + + for(i=0; iindex_length_array; i++) + { + beginCallBack(bpm->type_array[i], userData); + + for(j=0; jlength_array[i]; j++) + { + u=bpm->UVarray[k]; + v=bpm->UVarray[k+1]; + inDoEvalCoord2EM(u, v); + + k+=2; + } + endCallBack(userData); + } +} + +void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list) +{ + bezierPatchMesh* temp; + + for (temp=list; temp!=NULL; temp=temp->next) + { + inBPMEvalEM(temp); + } +} + diff --git a/project/jni/glu/src/libnurbs/interface/mystdio.h b/project/jni/glu/src/libnurbs/interface/mystdio.h new file mode 100644 index 000000000..90e9a53ec --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/mystdio.h @@ -0,0 +1,55 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glumystdio_h_ +#define __glumystdio_h_ + +#ifdef LIBRARYBUILD + #ifndef NDEBUG + #include + #define _glu_dprintf printf + #else + inline void _glu_dprintf(const char *, ...) { } + #endif +#endif + +#ifdef GLBUILD + inline void _glu_dprintf(const char *, ...) { } +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#endif /* __glumystdio_h_ */ diff --git a/project/jni/glu/src/libnurbs/interface/mystdlib.h b/project/jni/glu/src/libnurbs/interface/mystdlib.h new file mode 100644 index 000000000..72536d677 --- /dev/null +++ b/project/jni/glu/src/libnurbs/interface/mystdlib.h @@ -0,0 +1,49 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glumystdlib_h_ +#define __glumystdlib_h_ + +#ifdef LIBRARYBUILD +#include +#endif + +#ifdef GLBUILD +typedef unsigned int size_t; +extern "C" void abort(void); +extern "C" void* malloc(size_t); +extern "C" void free(void*); +#endif + +#endif /* __glumystdlib_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/arc.cc b/project/jni/glu/src/libnurbs/internals/arc.cc new file mode 100644 index 000000000..f807efc2c --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arc.cc @@ -0,0 +1,290 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak + */ + +#include +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arc.h" +#include "bin.h" +#include "bezierarc.h" +#include "pwlarc.h" +#include "simplemath.h" + +/* local preprocessor definitions */ +#define ZERO 0.00001 /* 0.000001 */ + +const int Arc::bezier_tag=(1<<13); +const int Arc::arc_tag=(1<<3); +const int Arc::tail_tag=(1<<6); + +/*-------------------------------------------------------------------------- + * makeSide - attach a pwl arc to an arc and mark it as a border arc + *-------------------------------------------------------------------------- + */ + +void Arc::makeSide(PwlArc* pwl, arc_side side) +{ + assert(pwl!=0); + assert(pwlArc==0); + assert(pwl->npts>0); + assert(pwl->pts!=0); + pwlArc=pwl; + clearbezier(); + setside(side); +} + + +/*-------------------------------------------------------------------------- + * numpts - count number of points on arc loop + *-------------------------------------------------------------------------- + */ + +int Arc::numpts(void) +{ + Arc_ptr jarc=this; + int npts=0; + + do { + npts+=jarc->pwlArc->npts; + jarc=jarc->next; + } while(jarc!=this); + + return npts; +} + +/*-------------------------------------------------------------------------- + * markverts - mark each point with id of arc + *-------------------------------------------------------------------------- + */ + +void Arc::markverts(void) +{ + Arc_ptr jarc=this; + + do { + TrimVertex* p=jarc->pwlArc->pts; + for (int i=0; ipwlArc->npts; i++) + { + p[i].nuid=jarc->nuid; + } + jarc=jarc->next; + } while(jarc!=this); +} + +/*-------------------------------------------------------------------------- + * getextrema - find axis extrema on arc loop + *-------------------------------------------------------------------------- + */ + +void Arc::getextrema(Arc_ptr extrema[4]) +{ + REAL leftpt, botpt, rightpt, toppt; + + extrema[0]=extrema[1]=extrema[2]=extrema[3]=this; + + leftpt=rightpt=this->tail()[0]; + botpt=toppt=this->tail()[1]; + + for (Arc_ptr jarc=this->next; jarc!=this; jarc=jarc->next) + { + if (jarc->tail()[0]tail()[0]<=leftpt && jarc->rhead()[0]<=leftpt)) + { + leftpt=jarc->pwlArc->pts->param[0]; + extrema[1]=jarc; + } + if (jarc->tail()[0]>rightpt || (jarc->tail()[0]>=rightpt && jarc->rhead()[0]>=rightpt)) + { + rightpt=jarc->pwlArc->pts->param[0]; + extrema[3]=jarc; + } + if (jarc->tail()[1]tail()[1]<=botpt && jarc->rhead()[1]<=botpt)) + { + botpt=jarc->pwlArc->pts->param[1]; + extrema[2]=jarc; + } + if (jarc->tail()[1]>toppt || (jarc->tail()[1]>=toppt && jarc->rhead()[1]>=toppt)) + { + toppt=jarc->pwlArc->pts->param[1]; + extrema[0]=jarc; + } + } +} + +/*------------------------------------------------------------------------- + * isDisconnected - check if tail of arc and head of prev meet + *------------------------------------------------------------------------- + */ + +int Arc::isDisconnected(void) +{ + if (pwlArc==0) + { + return 0; + } + if (prev->pwlArc==0) + { + return 0; + } + + REAL* p0=tail(); + REAL* p1=prev->rhead(); + + if (((p0[0]-p1[0])>ZERO) || ((p1[0]-p0[0])>ZERO) || + ((p0[1]-p1[1])>ZERO) || ((p1[1]-p0[1])>ZERO)) + { + return 1; + } + else + { + /* average two points together */ + p0[0]=p1[0]=(p1[0]+p0[0])*0.5f; + p0[1]=p1[1]=(p1[1]+p0[1])*0.5f; + return 0; + } +} + +/*------------------------------------------------------------------------- + * neq_vert - assert that two 2D vertices are not equal + *------------------------------------------------------------------------- + */ + +inline static int neq_vert(REAL* v1, REAL* v2) +{ + return ((v1[0]!=v2[0]) || (v1[1]!=v2[1])) ? 1 : 0; +} + +/*------------------------------------------------------------------------- + * check - verify consistency of a loop, including + * 1) if pwl, no two consecutive vertices are identical + * 2) the circular link pointers are valid + * 3) the geometric info at the head and tail are consistent + *------------------------------------------------------------------------- + */ + +int Arc::check(void) +{ + if (this==0) + { + return 1; + } + + Arc_ptr jarc=this; + + do { + assert((jarc->pwlArc!=0) || (jarc->bezierArc!=0)); + + if (jarc->prev==0 || jarc->next==0) + { + return 0; + } + + if (jarc->next->prev!=jarc) + { + return 0; + } + + if (jarc->pwlArc) + { + if (jarc->prev->pwlArc) + { + if (jarc->tail()[1]!=jarc->prev->rhead()[1]) + { + return 0; + } + if (jarc->tail()[0]!=jarc->prev->rhead()[0]) + { + return 0; + } + } + + if (jarc->next->pwlArc) + { + if (jarc->next->tail()[0]!=jarc->rhead()[0]) + { + return 0; + } + if (jarc->next->tail()[1]!=jarc->rhead()[1]) + { + return 0; + } + } + if (jarc->isbezier()) + { + assert(jarc->pwlArc->npts==2); + assert((jarc->pwlArc->pts[0].param[0]== \ + jarc->pwlArc->pts[1].param[0]) || \ + (jarc->pwlArc->pts[0].param[1] == \ + jarc->pwlArc->pts[1].param[1])); + } + } + jarc=jarc->next; + } while (jarc!=this); + + return 1; +} + +#define TOL 0.00001 + +inline long tooclose(REAL x, REAL y) +{ + return (glu_abs(x-y)next; + prev=jarc; + next->prev=prev->next=this; + } + else + { + next=prev=this; + } + + return this; +} + diff --git a/project/jni/glu/src/libnurbs/internals/arc.h b/project/jni/glu/src/libnurbs/internals/arc.h new file mode 100644 index 000000000..d2b162198 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arc.h @@ -0,0 +1,135 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluarc_h_ +#define __gluarc_h_ + +#include "myassert.h" +#include "bufpool.h" +#include "mystdio.h" +#include "types.h" +#include "pwlarc.h" +#include "trimvertex.h" + +class Bin; +class Arc; +struct BezierArc; + +typedef class Arc* Arc_ptr; + +enum arc_side +{ + arc_none=0, + arc_right, + arc_top, + arc_left, + arc_bottom +}; + +/* an arc, in two list, the trim list and bin */ +class Arc: public PooledObj +{ + public: + static const int bezier_tag; + static const int arc_tag; + static const int tail_tag; + Arc_ptr prev; /* trim list pointer */ + Arc_ptr next; /* trim list pointer */ + Arc_ptr link; /* bin pointers */ + BezierArc* bezierArc; /* associated bezier arc */ + PwlArc* pwlArc; /* associated pwl arc */ + long type; /* curve type */ + long nuid; + + inline Arc(Arc*, PwlArc*); + inline Arc(arc_side, long); + + Arc_ptr append(Arc_ptr); + int check(void); + int isMonotone(void); + int isDisconnected(void); + int numpts(void); + void markverts(void); + void getextrema(Arc_ptr[4]); + void makeSide(PwlArc*, arc_side); + inline int isTessellated() { return pwlArc ? 1 : 0; } + inline long isbezier() { return type & bezier_tag; } + inline void setbezier() { type |= bezier_tag; } + inline void clearbezier() { type &= ~bezier_tag; } + inline long npts() { return pwlArc->npts; } + inline TrimVertex* pts() { return pwlArc->pts; } + inline REAL* tail() { return pwlArc->pts[0].param; } + inline REAL* head() { return next->pwlArc->pts[0].param; } + inline REAL* rhead() { return pwlArc->pts[pwlArc->npts-1].param; } + inline long ismarked() { return type & arc_tag; } + inline void setmark() { type |= arc_tag; } + inline void clearmark() { type &= (~arc_tag); } + inline void clearside() { type &= ~(0x7 << 8); } + inline void setside(arc_side s) { clearside(); type |= (((long)s)<<8); } + inline arc_side getside() { return (arc_side) ((type>>8) & 0x7); } + inline int getitail() { return type & tail_tag; } + inline void setitail() { type |= tail_tag; } + inline void clearitail() { type &= (~tail_tag); } +}; + +/*-------------------------------------------------------------------------- + * Arc - initialize a new Arc with the same type and uid of + * a given Arc and a given pwl arc + *-------------------------------------------------------------------------- + */ + +inline Arc::Arc(Arc* j, PwlArc* p) +{ + bezierArc=NULL; + pwlArc=p; + type=j->type; + nuid=j->nuid; +} + +/*-------------------------------------------------------------------------- + * Arc - initialize a new Arc with the same type and uid of + * a given Arc and a given pwl arc + *-------------------------------------------------------------------------- + */ + +inline Arc::Arc(arc_side side, long _nuid) +{ + bezierArc=NULL; + pwlArc=NULL; + type=0; + setside(side); + nuid=_nuid; +} + +#endif /* __gluarc_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/arcsorter.cc b/project/jni/glu/src/libnurbs/internals/arcsorter.cc new file mode 100644 index 000000000..123dc8ae0 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arcsorter.cc @@ -0,0 +1,197 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#ifndef __gluarcsorter_c_ +#define __gluarcsorter_c_ + +#include "glimports.h" +#include "arc.h" +#include "arcsorter.h" +#include "subdivider.h" + +ArcSorter::ArcSorter(Subdivider &s): Sorter(sizeof(Arc**)), subdivider(s) +{ +} + +int ArcSorter::qscmp(char*, char*) +{ + return 0; +} + +void ArcSorter::qsort(Arc** a, int n) +{ + Sorter::qsort((void*)a, n); +} + +void ArcSorter::qsexc(char* i, char* j) // i<-j, j<-i +{ + Arc** jarc1=(Arc**)i; + Arc** jarc2=(Arc**)j; + Arc* tmp=*jarc1; + + *jarc1=*jarc2; + *jarc2=tmp; +} + +void ArcSorter::qstexc(char* i, char* j, char* k) // i<-k, k<-j, j<-i +{ + Arc** jarc1=(Arc**)i; + Arc** jarc2=(Arc**)j; + Arc** jarc3=(Arc**)k; + Arc* tmp=*jarc1; + + *jarc1=*jarc3; + *jarc3=*jarc2; + *jarc2=tmp; +} + +ArcSdirSorter::ArcSdirSorter(Subdivider& s): ArcSorter(s) +{ +} + +int ArcSdirSorter::qscmp(char* i, char* j) +{ + Arc* jarc1=*(Arc**)i; + Arc* jarc2=*(Arc**)j; + + int v1=(jarc1->getitail() ? 0 : (jarc1->pwlArc->npts-1)); + int v2=(jarc2->getitail() ? 0 : (jarc2->pwlArc->npts-1)); + + REAL diff=jarc1->pwlArc->pts[v1].param[1] - + jarc2->pwlArc->pts[v2].param[1]; + + if (diff<0.0) + { + return -1; + } + else + { + if (diff>0.0) + { + return 1; + } + else + { + if (v1==0) + { + if (jarc2->tail()[0]tail()[0]) + { + return subdivider.ccwTurn_sl(jarc2, jarc1) ? 1 : -1; + } + else + { + return subdivider.ccwTurn_sr(jarc2, jarc1) ? -1 : 1; + } + } + else + { + if (jarc2->head()[0]head()[0]) + { + return subdivider.ccwTurn_sl(jarc1, jarc2) ? -1 : 1; + } + else + { + return subdivider.ccwTurn_sr( jarc1, jarc2 ) ? 1 : -1; + } + } + } + } +} + +ArcTdirSorter::ArcTdirSorter(Subdivider& s): ArcSorter(s) +{ +} + +/*---------------------------------------------------------------------------- + * ArcTdirSorter::qscmp - + * compare two axis monotone arcs that are incident + * to the line T == compare_value. Determine which of the + * two intersects that line with a LESSER S value. If + * jarc1 does, return 1. If jarc2 does, return -1. + *--------------------------------------------------------------------------- + */ +int ArcTdirSorter::qscmp(char* i, char* j) +{ + Arc* jarc1=*(Arc**)i; + Arc* jarc2=*(Arc**)j; + + int v1=(jarc1->getitail() ? 0 : (jarc1->pwlArc->npts-1)); + int v2=(jarc2->getitail() ? 0 : (jarc2->pwlArc->npts-1)); + + REAL diff=jarc1->pwlArc->pts[v1].param[0]- + jarc2->pwlArc->pts[v2].param[0]; + + if (diff<0.0) + { + return 1; + } + else + { + if (diff>0.0) + { + return -1; + } + else + { + if (v1==0) + { + if (jarc2->tail()[1]tail()[1]) + { + return subdivider.ccwTurn_tl(jarc2, jarc1) ? 1 : -1; + } + else + { + return subdivider.ccwTurn_tr(jarc2, jarc1) ? -1 : 1; + } + } + else + { + if (jarc2->head()[1]head()[1]) + { + return subdivider.ccwTurn_tl(jarc1, jarc2) ? -1 : 1; + } + else + { + return subdivider.ccwTurn_tr(jarc1, jarc2) ? 1 : -1; + } + } + } + } +} + +#endif /* __gluarcsorter_c_ */ diff --git a/project/jni/glu/src/libnurbs/internals/arcsorter.h b/project/jni/glu/src/libnurbs/internals/arcsorter.h new file mode 100644 index 000000000..4d16d8b65 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arcsorter.h @@ -0,0 +1,73 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluarcsorter_h_ +#define __gluarcsorter_h_ + +#include "sorter.h" +#include "arcsorter.h" + +class Arc; +class Subdivider; + +class ArcSorter: private Sorter +{ + public: + ArcSorter(Subdivider &); + void qsort(Arc** a, int n); + protected: + virtual int qscmp(char*, char*); + Subdivider& subdivider; + private: + void qsexc(char* i, char* j ); // i<-j, j<-i + void qstexc(char* i, char* j, char* k); // i<-k, k<-j, j<-i +}; + +class ArcSdirSorter: public ArcSorter +{ + public: + ArcSdirSorter(Subdivider&); + private: + int qscmp(char*, char*); +}; + +class ArcTdirSorter: public ArcSorter +{ + public: + ArcTdirSorter(Subdivider&); + private: + int qscmp(char*, char*); +}; + +#endif /* __gluarcsorter_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/arctess.cc b/project/jni/glu/src/libnurbs/internals/arctess.cc new file mode 100644 index 000000000..863efcb66 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arctess.cc @@ -0,0 +1,626 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arctess.h" +#include "bufpool.h" +#include "simplemath.h" +#include "bezierarc.h" +#include "trimvertex.h" +#include "trimvertpool.h" + +#include + +#define NOELIMINATION + +#define steps_function(large, small, rate) (max(1, 1+(int)((large-small)/rate))); + +/*----------------------------------------------------------------------------- + * ArcTessellator - construct an ArcTessellator + *----------------------------------------------------------------------------- + */ + +ArcTessellator::ArcTessellator( TrimVertexPool& t, Pool& p) + :pwlarcpool(p), trimvertexpool(t) +{ +} + +/*----------------------------------------------------------------------------- + * ~ArcTessellator - destroy an ArcTessellator + *----------------------------------------------------------------------------- + */ + +ArcTessellator::~ArcTessellator(void) +{ +} + +/*----------------------------------------------------------------------------- + * bezier - construct a bezier arc and attach it to an Arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::bezier(Arc* arc, REAL s1, REAL s2, REAL t1, REAL t2) +{ + assert(arc!=0); + assert(!arc->isTessellated()); + + TrimVertex* p=trimvertexpool.get(2); + arc->pwlArc=new(pwlarcpool) PwlArc(2, p); + p[0].param[0]=s1; + p[0].param[1]=t1; + p[1].param[0]=s2; + p[1].param[1]=t2; + assert((s1==s2) || (t1==t2)); + arc->setbezier(); +} + +/*----------------------------------------------------------------------------- + * pwl_left - construct a left boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::pwl_left(Arc* arc, REAL s, REAL t1, REAL t2, REAL rate) +{ + assert(t20; i--) + { + newvert[i].param[0]=s; + newvert[i].param[1]=t2; + t2+=stepsize; + } + newvert[i].param[0]=s; + newvert[i].param[1]=t1; + + arc->makeSide(new(pwlarcpool)PwlArc(nsteps+1, newvert), arc_left); +} + +/*----------------------------------------------------------------------------- + * pwl_right - construct a right boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::pwl_right(Arc* arc, REAL s, REAL t1, REAL t2, REAL rate) +{ + assert(t1256) + { + nsteps=256; + } + REAL stepsize=(t2-t1)/(REAL)nsteps; + + TrimVertex* newvert=trimvertexpool.get(nsteps+1); + + int i; + + for (i=0; imakeSide(new(pwlarcpool)PwlArc(nsteps+1, newvert), arc_right); +} + +/*----------------------------------------------------------------------------- + * pwl_top - construct a top boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::pwl_top(Arc* arc, REAL t, REAL s1, REAL s2, REAL rate) +{ + assert(s20; i--) + { + newvert[i].param[0]=s2; + newvert[i].param[1]=t; + s2+=stepsize; + } + newvert[i].param[0]=s1; + newvert[i].param[1]=t; + + arc->makeSide(new(pwlarcpool)PwlArc(nsteps+1, newvert), arc_top); +} + +/*----------------------------------------------------------------------------- + * pwl_bottom - construct a bottom boundary pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void +ArcTessellator::pwl_bottom(Arc* arc, REAL t, REAL s1, REAL s2, REAL rate) +{ + assert(s1makeSide(new(pwlarcpool)PwlArc(nsteps+1, newvert), arc_bottom); +} + +/*----------------------------------------------------------------------------- + * pwl - construct a pwl arc and attach it to an arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::pwl(Arc* arc, REAL s1, REAL s2, REAL t1, REAL t2, REAL rate) +{ + int snsteps=1+(int)(glu_abs(s2-s1)/rate); + int tnsteps=1+(int)(glu_abs(t2-t1)/rate); + int nsteps=max(1, max(snsteps, tnsteps)); + + REAL sstepsize=(s2-s1)/(REAL)nsteps; + REAL tstepsize=(t2-t1)/(REAL)nsteps; + + TrimVertex* newvert=trimvertexpool.get(nsteps+1); + long i; + for (i=0; ipwlArc=new(pwlarcpool)PwlArc(nsteps+1, newvert); + + arc->clearbezier(); + arc->clearside(); +} + +/*----------------------------------------------------------------------------- + * tessellateLinear - constuct a linear pwl arc and attach it to an Arc + *----------------------------------------------------------------------------- + */ + +void ArcTessellator::tessellateLinear(Arc* arc, REAL geo_stepsize, REAL arc_stepsize, int isrational) +{ + assert(arc->pwlArc==NULL); + REAL s1, s2, t1, t2; + + //we don't need to scale by arc_stepsize if the trim curve + //is piecewise linear. Reason: In pwl_right, pwl_left, pwl_top, pwl_left, + //and pwl, the nsteps is computed by deltaU (or V) /stepsize. + //The quantity deltaU/arc_stepsize doesn't have any meaning. And + //it causes problems: see bug 517641 + REAL stepsize=geo_stepsize; /* * arc_stepsize*/; + + BezierArc* b=arc->bezierArc; + + if (isrational) + { + s1=b->cpts[0]/b->cpts[2]; + t1=b->cpts[1]/b->cpts[2]; + s2=b->cpts[b->stride+0]/b->cpts[b->stride+2]; + t2=b->cpts[b->stride+1]/b->cpts[b->stride+2]; + } + else + { + s1=b->cpts[0]; + t1=b->cpts[1]; + s2=b->cpts[b->stride+0]; + t2=b->cpts[b->stride+1]; + } + if (s1==s2) + { + if (t1pwlArc==NULL); + + REAL stepsize=geo_stepsize*arc_stepsize; + + BezierArc* bezierArc=arc->bezierArc; + + REAL size; //bounding box size of the curve in UV + { + int i, j; + REAL min_u, min_v, max_u,max_v; + min_u=max_u=bezierArc->cpts[0]; + min_v=max_v=bezierArc->cpts[1]; + + for(i=1, j=bezierArc->stride; iorder; i++, j+=bezierArc->stride) + { + if (bezierArc->cpts[j]cpts[j]; + } + if (bezierArc->cpts[j]>max_u) + { + max_u=bezierArc->cpts[j]; + } + if (bezierArc->cpts[j+1]cpts[j+1]; + } + if (bezierArc->cpts[j+1]>max_v) + { + max_v=bezierArc->cpts[j+1]; + } + } + + size=max_u-min_u; + if (sizepwlArc=new(pwlarcpool) PwlArc(); + arc->pwlArc->pts=vert; + + if (isrational) + { + REAL pow_u[MAXORDER], pow_v[MAXORDER], pow_w[MAXORDER]; + trim_power_coeffs(bezierArc, pow_u, 0); + trim_power_coeffs(bezierArc, pow_v, 1); + trim_power_coeffs(bezierArc, pow_w, 2); + + /* compute first point exactly */ + REAL* b=bezierArc->cpts; + vert->param[0]=b[0]/b[2]; + vert->param[1]=b[1]/b[2]; + + /* strength reduction on p = dp * step would introduce error */ + int step; +#ifndef NOELIMINATION + int ocanremove=0; +#endif + register long order=bezierArc->order; + for(step=1, ++vert; stepparam[0]=u/w; + vert->param[1]=v/w; +#ifndef NOELIMINATION + REAL ds=glu_abs(vert[0].param[0]-vert[-1].param[0]); + REAL dt=glu_abs(vert[0].param[1]-vert[-1].param[1]); + int canremove=(dsstride; + vert->param[0] = b[0]/b[2]; + vert->param[1] = b[1]/b[2]; + } + else + { + REAL pow_u[MAXORDER], pow_v[MAXORDER]; + trim_power_coeffs(bezierArc, pow_u, 0); + trim_power_coeffs(bezierArc, pow_v, 1); + + /* compute first point exactly */ + REAL* b=bezierArc->cpts; + vert->param[0]=b[0]; + vert->param[1]=b[1]; + + /* strength reduction on p = dp * step would introduce error */ + int step; +#ifndef NOELIMINATION + int ocanremove=0; +#endif + register long order=bezierArc->order; + + for (step=1, ++vert; steporder; i++) + { + u=u*p+pow_u[i]; + v=v*p+pow_v[i]; + } + vert->param[0]=u; + vert->param[1]=v; +#ifndef NOELIMINATION + REAL ds=glu_abs(vert[0].param[0]-vert[-1].param[0]); + REAL dt=glu_abs(vert[0].param[1]-vert[-1].param[1]); + int canremove=(dsstride; + vert->param[0]=b[0]; + vert->param[1]=b[1]; + } + arc->pwlArc->npts=(int)(vert-arc->pwlArc->pts+1); +} + +const REAL ArcTessellator::gl_Bernstein[][MAXORDER][MAXORDER]= +{ + { + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {-1, 1, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {1, -2, 1, 0, 0, 0, 0, 0}, + {-2, 2, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {-1, 3, -3, 1, 0, 0, 0, 0}, + {3, -6, 3, 0, 0, 0, 0, 0}, + {-3, 3, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {1, -4, 6, -4, 1, 0, 0, 0}, + {-4, 12, -12, 4, 0, 0, 0, 0}, + {6, -12, 6, 0, 0, 0, 0, 0}, + {-4, 4, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {-1, 5, -10, 10, -5, 1, 0, 0}, + {5, -20, 30, -20, 5, 0, 0, 0}, + {-10, 30, -30, 10, 0, 0, 0, 0}, + {10, -20, 10, 0, 0, 0, 0, 0}, + {-5, 5, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {1, -6, 15, -20, 15, -6, 1, 0}, + {-6, 30, -60, 60, -30, 6, 0, 0}, + {15, -60, 90, -60, 15, 0, 0, 0}, + {-20, 60, -60, 20, 0, 0, 0, 0}, + {15, -30, 15, 0, 0, 0, 0, 0}, + {-6, 6, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} + }, + { + {-1, 7, -21, 35, -35, 21, -7, 1}, + {7, -42, 105, -140, 105, -42, 7, 0}, + {-21, 105, -210, 210, -105, 21, 0, 0}, + {35, -140, 210, -140, 35, 0, 0, 0}, + {-35, 105, -105, 35, 0, 0, 0, 0}, + {21, -42, 21, 0, 0, 0, 0, 0}, + {-7, 7, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0} + } +}; + +/*----------------------------------------------------------------------------- + * trim_power_coeffs - compute power basis coefficients from bezier coeffients + *----------------------------------------------------------------------------- + */ +void ArcTessellator::trim_power_coeffs(BezierArc* bez_arc, REAL* p, int coord) +{ + register int stride=bez_arc->stride; + register int order=bez_arc->order; + register REAL* base=bez_arc->cpts+coord; + + REAL const (*mat)[MAXORDER][MAXORDER]=&gl_Bernstein[order-1]; + REAL const (*lrow)[MAXORDER]=&(*mat)[order]; + + /* WIN32 didn't like the following line within the for-loop */ + REAL const (*row)[MAXORDER]=&(*mat)[0]; + + for (; row!=lrow; row++) + { + register REAL s=0.0; + register REAL* point=base; + register REAL const* mlast=*row+order; + + for (REAL const* m=*row; m!=mlast; m++, point+=stride) + { + s+=*(m)*(*point); + } + *(p++)=s; + } +} diff --git a/project/jni/glu/src/libnurbs/internals/arctess.h b/project/jni/glu/src/libnurbs/internals/arctess.h new file mode 100644 index 000000000..e5c3030a4 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/arctess.h @@ -0,0 +1,67 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluarctess_h_ +#define __gluarctess_h_ + +#include "defines.h" +#include "types.h" +#include "arc.h" + +struct BezierArc; +class Pool; +class TrimVertexPool; + +class ArcTessellator +{ + public: + ArcTessellator(TrimVertexPool&, Pool&); + ~ArcTessellator(void); + void bezier(Arc_ptr, REAL, REAL, REAL, REAL); + void pwl(Arc_ptr, REAL, REAL, REAL, REAL, REAL); + void pwl_left(Arc_ptr, REAL, REAL, REAL, REAL); + void pwl_right(Arc_ptr, REAL, REAL, REAL, REAL); + void pwl_top(Arc_ptr, REAL, REAL, REAL, REAL); + void pwl_bottom(Arc_ptr, REAL, REAL, REAL, REAL); + void tessellateLinear(Arc_ptr, REAL, REAL, int); + void tessellateNonlinear(Arc_ptr, REAL, REAL, int); + + private: + static const REAL gl_Bernstein[][MAXORDER][MAXORDER]; + Pool& pwlarcpool; + TrimVertexPool& trimvertexpool; + static void trim_power_coeffs(BezierArc*, REAL[MAXORDER], int); +}; + +#endif /* __gluarctess_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/backend.cc b/project/jni/glu/src/libnurbs/internals/backend.cc new file mode 100644 index 000000000..29583dfa5 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/backend.cc @@ -0,0 +1,481 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +/* Bezier surface backend - interprets display mode (wireframe, shaded, ...) */ +#include +#include "glimports.h" +#include "mystdio.h" +#include "backend.h" +#include "basiccrveval.h" +#include "basicsurfeval.h" +#include "nurbsconsts.h" + +#include "gles_evaluator.h" +#include "glues.h" + +/*------------------------------------------------------------------------- + * bgnsurf - preamble to surface definition and evaluations + *------------------------------------------------------------------------- + */ +void Backend::bgnsurf(int wiretris, int wirequads, long nuid) +{ + wireframetris=wiretris; + wireframequads=wirequads; + + /* in the spec, GLU_DISPLAY_MODE is either + * GLU_FILL + * GLU_OUTLINE_POLY + * GLU_OUTLINE_PATCH. + * In fact, GLU_FILL has the same effect as + * set GL_FRONT_AND_BACK to be GL_FILL + * and GLU_OUTLINE_POLY is the same as set + * GL_FRONT_AND_BACK to be GL_LINE + * It is more efficient to do this once at the beginning of + * each surface than to do it for each primitive. + * The internal has more options: outline_triangle and outline_quad + * can be seperated. But since this is not in spec, and more importantly, + * this is not so useful, so we don't need to keep this option. + */ + + surfaceEvaluator.bgnmap2f(nuid); + + if (wiretris) + { + surfaceEvaluator.polymode(N_MESHLINE); + } + else + { + surfaceEvaluator.polymode(N_MESHFILL); + } +} + +void Backend::patch(REAL ulo, REAL uhi, REAL vlo, REAL vhi) +{ + surfaceEvaluator.domain2f(ulo, uhi, vlo, vhi); +} + +void Backend::surfbbox(long type, REAL* from, REAL* to) +{ + surfaceEvaluator.range2f(type, from, to); +} + +/*------------------------------------------------------------------------- + * surfpts - pass a desription of a surface map + *------------------------------------------------------------------------- + */ +void Backend::surfpts(long type, /* geometry, color, texture, normal */ + REAL* pts, /* control points */ + long ustride, /* distance to next point in u direction */ + long vstride, /* distance to next point in v direction */ + int uorder, /* u parametric order */ + int vorder, /* v parametric order */ + REAL ulo, /* u lower bound */ + REAL uhi, /* u upper bound */ + REAL vlo, /* v lower bound */ + REAL vhi) /* v upper bound */ +{ + surfaceEvaluator.map2f(type, ulo, uhi, ustride, uorder, vlo, vhi, vstride, vorder, pts); + surfaceEvaluator.enable(type); +} + +/*------------------------------------------------------------------------- + * surfgrid - define a lattice of points with origin and offset + *------------------------------------------------------------------------- + */ +void Backend::surfgrid(REAL u0, REAL u1, long nu, REAL v0, REAL v1, long nv) +{ + surfaceEvaluator.mapgrid2f(nu, u0, u1, nv, v0, v1); +} + +/*------------------------------------------------------------------------- + * surfmesh - evaluate a mesh of points on lattice + *------------------------------------------------------------------------- + */ +void Backend::surfmesh(long u, long v, long n, long m) +{ + if (wireframequads) + { + surfaceEvaluator.mapmesh2f(N_MESHLINE, u, u+n, v, v+m); + } + else + { + surfaceEvaluator.mapmesh2f(N_MESHFILL, u, u+n, v, v+m); + } +} + +/*------------------------------------------------------------------------- + * endsurf - postamble to surface + *------------------------------------------------------------------------- + */ +void Backend::endsurf(void) +{ + surfaceEvaluator.endmap2f(); +} + +/***************************************/ +void Backend::bgntfan(void) +{ + surfaceEvaluator.bgntfan(); +} + +void Backend::endtfan(void) +{ + surfaceEvaluator.endtfan(); +} + +void Backend::bgnqstrip(void) +{ + surfaceEvaluator.bgnqstrip(); +} + +void Backend::endqstrip(void) +{ + surfaceEvaluator.endqstrip(); +} + +void Backend::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, + int n_lower, REAL v_lower, REAL* lower_val) +{ + surfaceEvaluator.evalUStrip(n_upper, v_upper, upper_val, n_lower, v_lower, lower_val); +} + +void Backend::evalVStrip(int n_left, REAL u_left, REAL* left_val, + int n_right, REAL u_right, REAL* right_val) +{ + surfaceEvaluator.evalVStrip(n_left, u_left, left_val, n_right, u_right, right_val); +} + +/*------------------------------------------------------------------------- + * bgntmesh - preamble to a triangle mesh + *------------------------------------------------------------------------- + */ +void Backend::bgntmesh(const char* name) +{ + if (wireframetris) + { + surfaceEvaluator.bgntmesh(); + surfaceEvaluator.polymode(N_MESHLINE); + } + else + { + surfaceEvaluator.bgntmesh(); + surfaceEvaluator.polymode(N_MESHFILL); + } +} + +void Backend::tmeshvert(GridTrimVertex* v) +{ + REAL retPoint[4]; + REAL retNormal[3]; + + if (v->isGridVert()) + { + tmeshvert(v->g); + } + else + { + tmeshvert(v->t, retPoint, retNormal); + } +} + +void Backend::tmeshvertNOGE(TrimVertex* t) +{ +} + +// opt for a line with the same u. +void Backend::tmeshvertNOGE_BU(TrimVertex* t) +{ +} + +// opt for a line with the same v. +void Backend::tmeshvertNOGE_BV(TrimVertex* t) +{ +} + +void Backend::preEvaluateBU(REAL u) +{ + surfaceEvaluator.inPreEvaluateBU_intfac(u); +} + +void Backend::preEvaluateBV(REAL v) +{ + surfaceEvaluator.inPreEvaluateBV_intfac(v); +} + +/*------------------------------------------------------------------------- + * tmeshvert - evaluate a point on a triangle mesh + *------------------------------------------------------------------------- + */ +void Backend::tmeshvert(TrimVertex* t, REAL* retPoint, REAL* retNormal) +{ + const REAL u=t->param[0]; + const REAL v=t->param[1]; + + surfaceEvaluator.evalcoord2f(0, u, v, retPoint, retNormal); +} + +// the same as tmeshvert(trimvertex), for efficiency purpose +void Backend::tmeshvert(REAL u, REAL v, REAL* retPoint, REAL* retNormal) +{ + surfaceEvaluator.evalcoord2f(0, u, v, retPoint, retNormal); +} + +/*------------------------------------------------------------------------- + * tmeshvert - evaluate a grid point of a triangle mesh + *------------------------------------------------------------------------- + */ +void Backend::tmeshvert(GridVertex* g) +{ + const long u=g->gparam[0]; + const long v=g->gparam[1]; + + surfaceEvaluator.evalpoint2i(u, v); +} + +/*------------------------------------------------------------------------- + * swaptmesh - perform a swap of the triangle mesh pointers + *------------------------------------------------------------------------- + */ +void Backend::swaptmesh(void) +{ + surfaceEvaluator.swaptmesh(); +} + +/*------------------------------------------------------------------------- + * endtmesh - postamble to triangle mesh + *------------------------------------------------------------------------- + */ +void Backend::endtmesh(void) +{ + surfaceEvaluator.endtmesh(); +} + +/*------------------------------------------------------------------------- + * bgnoutline - preamble to outlined rendering + *------------------------------------------------------------------------- + */ +void Backend::bgnoutline(void) +{ + surfaceEvaluator.bgnline(); +} + +/*------------------------------------------------------------------------- + * linevert - evaluate a point on an outlined contour + *------------------------------------------------------------------------- + */ +void Backend::linevert(TrimVertex* t, REAL* retPoint, REAL* retNormal) +{ + surfaceEvaluator.evalcoord2f(t->nuid, t->param[0], t->param[1], retPoint, retNormal); +} + +/*------------------------------------------------------------------------- + * linevert - evaluate a grid point of an outlined contour + *------------------------------------------------------------------------- + */ +void Backend::linevert(GridVertex* g) +{ + surfaceEvaluator.evalpoint2i(g->gparam[0], g->gparam[1]); +} + +/*------------------------------------------------------------------------- + * endoutline - postamble to outlined rendering + *------------------------------------------------------------------------- + */ +void Backend::endoutline(void) +{ + surfaceEvaluator.endline(); +} + +/*------------------------------------------------------------------------- + * triangle - output a triangle + *------------------------------------------------------------------------- + */ +void Backend::triangle(TrimVertex* a, TrimVertex* b, TrimVertex* c) +{ + REAL retPoint[4]; + REAL retNormal[3]; + REAL vertices[3*3]; + REAL normals[3*3]; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + bgntfan(); + tmeshvert(a, retPoint, retNormal); + vertices[0]=retPoint[0]; + vertices[1]=retPoint[1]; + vertices[2]=retPoint[2]; + normals[0]=retNormal[0]; + normals[1]=retNormal[1]; + normals[2]=retNormal[2]; + tmeshvert(b, retPoint, retNormal); + vertices[3]=retPoint[0]; + vertices[4]=retPoint[1]; + vertices[5]=retPoint[2]; + normals[3]=retNormal[0]; + normals[4]=retNormal[1]; + normals[5]=retNormal[2]; + tmeshvert(c, retPoint, retNormal); + vertices[6]=retPoint[0]; + vertices[7]=retPoint[1]; + vertices[8]=retPoint[2]; + normals[6]=retNormal[0]; + normals[7]=retNormal[1]; + normals[8]=retNormal[2]; + endtfan(); + + if (get_output_style()==N_MESHLINE) + { + glDrawArrays(GL_LINE_LOOP, 0, 3); + } + else + { + glDrawArrays(GL_TRIANGLE_FAN, 0, 3); + } + + /* 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); + } +} + +long Backend::get_output_style(void) +{ + return surfaceEvaluator.get_output_style(); +} + +void Backend::bgncurv(void) +{ + curveEvaluator.bgnmap1f(0); +} + +void Backend::segment(REAL ulo, REAL uhi) +{ + curveEvaluator.domain1f(ulo, uhi); +} + +void Backend::curvpts(long type, /* geometry, color, texture, normal */ + REAL* pts, /* control points */ + long stride, /* distance to next point */ + int order, /* parametric order */ + REAL ulo, /* lower parametric bound */ + REAL uhi) /* upper parametric bound */ + +{ + curveEvaluator.map1f(type, ulo, uhi, stride, order, pts); + curveEvaluator.enable(type); +} + +void Backend::curvgrid(REAL u0, REAL u1, long nu) +{ + curveEvaluator.mapgrid1f(nu, u0, u1); +} + +void Backend::curvmesh(long from, long n) +{ + curveEvaluator.mapmesh1f(N_MESHFILL, from, from+n); +} + +void Backend::curvpt(REAL u) +{ + curveEvaluator.evalcoord1f(0, u); +} + +void Backend::bgnline(void) +{ + curveEvaluator.bgnline(); +} + +void Backend::endline(void) +{ + curveEvaluator.endline(); +} + +void Backend::endcurv(void) +{ + curveEvaluator.endmap1f(); +} diff --git a/project/jni/glu/src/libnurbs/internals/backend.h b/project/jni/glu/src/libnurbs/internals/backend.h new file mode 100644 index 000000000..4a93a58b9 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/backend.h @@ -0,0 +1,108 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glubackend_h_ +#define __glubackend_h_ + +#include "trimvertex.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" + +class BasicCurveEvaluator; +class BasicSurfaceEvaluator; + +class Backend +{ + private: + BasicCurveEvaluator& curveEvaluator; + BasicSurfaceEvaluator& surfaceEvaluator; + + public: + Backend(BasicCurveEvaluator& c, BasicSurfaceEvaluator& e): + curveEvaluator(c), surfaceEvaluator(e) { } + + /* surface backend routines */ + void bgnsurf(int, int, long); + void patch(REAL, REAL, REAL, REAL); + void surfpts(long, REAL*, long, long, int, int, REAL, REAL, REAL, REAL); + void surfbbox(long, REAL*, REAL*); + void surfgrid(REAL, REAL, long, REAL, REAL, long); + void surfmesh(long, long, long, long); + void bgntmesh(const char*); + void endtmesh(void); + void swaptmesh(void); + void tmeshvert(GridTrimVertex*); + void tmeshvert(TrimVertex*, REAL*, REAL*); + void tmeshvert(GridVertex*); + void tmeshvert(REAL u, REAL v, REAL*, REAL*); + void linevert(TrimVertex*, REAL*, REAL*); + void linevert(GridVertex*); + void bgnoutline(void); + void endoutline(void); + void endsurf(void); + void triangle(TrimVertex*, TrimVertex*, TrimVertex*); + long get_output_style(void); + + void bgntfan(); + void endtfan(); + void bgnqstrip(); + void endqstrip(); + void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val); + void evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL v_right, REAL* right_val); + void tmeshvertNOGE(TrimVertex* t); + void tmeshvertNOGE_BU(TrimVertex* t); + void tmeshvertNOGE_BV(TrimVertex* t); + void preEvaluateBU(REAL u); + void preEvaluateBV(REAL v); + + /* curve backend routines */ + void bgncurv(void); + void segment(REAL, REAL); + void curvpts(long, REAL*, long, int, REAL, REAL); + void curvgrid(REAL, REAL, long); + void curvmesh(long, long); + void curvpt(REAL); + void bgnline(void); + void endline(void); + void endcurv(void); + + private: + int wireframetris; + int wireframequads; + int npts; + REAL mesh[3][4]; + int meshindex; +}; + +#endif /* __glubackend_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/basiccrveval.cc b/project/jni/glu/src/libnurbs/internals/basiccrveval.cc new file mode 100644 index 000000000..8aa00124c --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/basiccrveval.cc @@ -0,0 +1,89 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "mystdio.h" +#include "types.h" +#include "basiccrveval.h" + +void BasicCurveEvaluator::domain1f(REAL, REAL) +{ +} + +void BasicCurveEvaluator::range1f(long , REAL*, REAL*) +{ +} + +void BasicCurveEvaluator::enable(long) +{ +} + +void BasicCurveEvaluator::disable(long) +{ +} + +void BasicCurveEvaluator::bgnmap1f(long) +{ +} + +void BasicCurveEvaluator::map1f(long, REAL, REAL, long, long, REAL*) +{ +} + +void BasicCurveEvaluator::mapgrid1f(long, REAL, REAL) +{ +} + +void BasicCurveEvaluator::mapmesh1f(long, long, long) +{ +} + +void BasicCurveEvaluator::evalcoord1f(long, REAL) +{ +} + +void BasicCurveEvaluator::endmap1f(void) +{ +} + +void BasicCurveEvaluator::bgnline(void) +{ +} + +void BasicCurveEvaluator::endline(void) +{ +} diff --git a/project/jni/glu/src/libnurbs/internals/basiccrveval.h b/project/jni/glu/src/libnurbs/internals/basiccrveval.h new file mode 100644 index 000000000..8b53f3b75 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/basiccrveval.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +/* + * basiccurveeval.h + * + */ + +#ifndef __glubasiccrveval_h_ +#define __glubasiccrveval_h_ + +#include "types.h" +#include "displaymode.h" +#include "cachingeval.h" + +class BasicCurveEvaluator: public CachingEvaluator +{ + public: + virtual ~BasicCurveEvaluator() { /* silence warning*/ } + virtual void domain1f(REAL, REAL); + virtual void range1f(long, REAL*, REAL*); + + virtual void enable(long); + virtual void disable(long); + virtual void bgnmap1f(long); + virtual void map1f(long, REAL, REAL, long, long, REAL*); + virtual void mapgrid1f(long, REAL, REAL); + virtual void mapmesh1f(long, long, long); + virtual void evalcoord1f(long, REAL); + virtual void endmap1f(void); + + virtual void bgnline(void); + virtual void endline(void); +}; + +#endif /* __glubasiccrveval_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/basicsurfeval.cc b/project/jni/glu/src/libnurbs/internals/basicsurfeval.cc new file mode 100644 index 000000000..e1305c0c8 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/basicsurfeval.cc @@ -0,0 +1,143 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "mystdio.h" +#include "types.h" +#include "basicsurfeval.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +void BasicSurfaceEvaluator::domain2f(REAL, REAL, REAL, REAL) +{ +} + +void BasicSurfaceEvaluator::polymode(long) +{ +} + +long BasicSurfaceEvaluator::get_output_style() +{ + return N_MESHFILL; +} + +void BasicSurfaceEvaluator::range2f(long type, REAL* from, REAL* to) +{ +} + +void BasicSurfaceEvaluator::enable(long) +{ +} + +void BasicSurfaceEvaluator::disable(long) +{ +} + +void BasicSurfaceEvaluator::bgnmap2f(long) +{ +} + +void BasicSurfaceEvaluator::endmap2f(void) +{ +} + +void BasicSurfaceEvaluator::map2f(long, REAL, REAL, long, long, + REAL, REAL, long, long, REAL*) +{ +} + +void BasicSurfaceEvaluator::mapgrid2f(long, REAL, REAL, long, REAL, REAL) +{ +} + +void BasicSurfaceEvaluator::mapmesh2f(long, long, long, long, long) +{ +} + +void BasicSurfaceEvaluator::evalcoord2f(long, REAL, REAL, REAL*, REAL*) +{ +} + +void BasicSurfaceEvaluator::evalpoint2i(long, long) +{ +} + +void BasicSurfaceEvaluator::bgnline(void) +{ +} + +void BasicSurfaceEvaluator::endline(void) +{ +} + +void BasicSurfaceEvaluator::bgnclosedline(void) +{ +} + +void BasicSurfaceEvaluator::endclosedline(void) +{ +} + +void BasicSurfaceEvaluator::bgntfan(void) +{ +} + +void BasicSurfaceEvaluator::endtfan(void) +{ +} + +void BasicSurfaceEvaluator::bgntmesh(void) +{ +} + +void BasicSurfaceEvaluator::swaptmesh(void) +{ +} + +void BasicSurfaceEvaluator::endtmesh(void) +{ +} + +void BasicSurfaceEvaluator::bgnqstrip(void) +{ +} + +void BasicSurfaceEvaluator::endqstrip(void) +{ +} diff --git a/project/jni/glu/src/libnurbs/internals/basicsurfeval.h b/project/jni/glu/src/libnurbs/internals/basicsurfeval.h new file mode 100644 index 000000000..1c3a4fcfa --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/basicsurfeval.h @@ -0,0 +1,84 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glubasicsurfeval_h_ +#define __glubasicsurfeval_h_ + +#include "types.h" +#include "displaymode.h" +#include "cachingeval.h" + +class BasicSurfaceEvaluator: public CachingEvaluator +{ + public: + virtual ~BasicSurfaceEvaluator() { /* silence warning*/ } + virtual void range2f(long, REAL*, REAL*); + virtual void domain2f(REAL, REAL, REAL, REAL); + + virtual void enable(long); + virtual void disable(long); + virtual void bgnmap2f(long); + virtual void map2f(long, REAL, REAL, long, long, REAL, REAL, long, long, REAL*); + virtual void mapgrid2f(long, REAL, REAL, long, REAL, REAL); + virtual void mapmesh2f(long, long, long, long, long); + virtual void evalcoord2f(long, REAL, REAL, REAL*, REAL*); + virtual void evalpoint2i(long, long); + virtual void endmap2f(void); + + virtual void polymode(long); + virtual long get_output_style(); + virtual void bgnline(void); + virtual void endline(void); + virtual void bgnclosedline(void); + virtual void endclosedline(void); + virtual void bgntmesh(void); + virtual void swaptmesh(void); + virtual void endtmesh(void); + virtual void bgnqstrip(void); + virtual void endqstrip(void); + + virtual void bgntfan(void); + virtual void endtfan(void); + + virtual void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)=0; + + virtual void evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)=0; + virtual void inDoEvalCoord2NOGE(REAL u, REAL v, REAL* ret_point, REAL* ret_normal)=0; + virtual void inDoEvalCoord2NOGE_BU(REAL u, REAL v, REAL* ret_point, REAL* ret_normal)=0; + virtual void inDoEvalCoord2NOGE_BV(REAL u, REAL v, REAL* ret_point, REAL* ret_normal)=0; + virtual void inPreEvaluateBV_intfac(REAL v)=0; + virtual void inPreEvaluateBU_intfac(REAL u)=0; +}; + +#endif /* __glubasicsurfeval_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/bezierarc.h b/project/jni/glu/src/libnurbs/internals/bezierarc.h new file mode 100644 index 000000000..869b7790b --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/bezierarc.h @@ -0,0 +1,52 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glubezierarc_h +#define __glubezierarc_h + +#include "myassert.h" + +class Mapdesc; + +/* a bezier arc */ +struct BezierArc: public PooledObj +{ + REAL* cpts; /* control points of arc */ + int order; /* order of arc */ + int stride; /* REAL distance between points */ + long type; /* curve type */ + Mapdesc* mapdesc; +}; + +#endif /* __glubezierarc_h */ diff --git a/project/jni/glu/src/libnurbs/internals/bin.cc b/project/jni/glu/src/libnurbs/internals/bin.cc new file mode 100644 index 000000000..e94d1232f --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/bin.cc @@ -0,0 +1,131 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "bin.h" + +/*---------------------------------------------------------------------------- + * Constructor and destructor + *---------------------------------------------------------------------------- + */ +Bin::Bin() +{ + head=NULL; +} + +Bin::~Bin() +{ + assert(head==NULL); +} + +/*---------------------------------------------------------------------------- + * remove_this_arc - remove given Arc_ptr from bin + *---------------------------------------------------------------------------- + */ + +void Bin::remove_this_arc(Arc_ptr arc) +{ + Arc_ptr* j; + for (j=&(head); (*j!=0) && (*j!=arc); j=&((*j)->link)); + + if (*j!=0) + { + if (*j==current) + { + current=(*j)->link; + } + *j=(*j)->link; + } +} + +/*---------------------------------------------------------------------------- + * numarcs - count number of arcs in bin + *---------------------------------------------------------------------------- + */ + +int Bin::numarcs() +{ + long count=0; + + for (Arc_ptr jarc=firstarc(); jarc; jarc=nextarc()) + { + count++; + } + + return count; +} + +/*---------------------------------------------------------------------------- + * adopt - place an orphaned arcs into their new parents bin + *---------------------------------------------------------------------------- + */ + +void Bin::adopt() +{ + markall(); + + Arc_ptr orphan; + while ((orphan=removearc())!=NULL) + { + for (Arc_ptr parent=orphan->next; parent!=orphan; parent=parent->next) + { + if (!parent->ismarked()) + { + orphan->link=parent->link; + parent->link=orphan; + orphan->clearmark(); + break; + } + } + } +} + +/*---------------------------------------------------------------------------- + * markall - mark all arcs with an identifying tag + *---------------------------------------------------------------------------- + */ + +void Bin::markall() +{ + for (Arc_ptr jarc=firstarc(); jarc; jarc=nextarc()) + { + jarc->setmark(); + } +} diff --git a/project/jni/glu/src/libnurbs/internals/bin.h b/project/jni/glu/src/libnurbs/internals/bin.h new file mode 100644 index 000000000..9bc2ff81d --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/bin.h @@ -0,0 +1,121 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glubin_h_ +#define __glubin_h_ + +#include "myassert.h" +#include "arc.h" +#include "defines.h" + +/* a linked list of jordan arcs */ +class Bin +{ + private: + Arc_ptr head; /*first arc on list */ + Arc_ptr current; /* current arc on list */ + + public: + Bin(); + ~Bin(); + inline Arc_ptr firstarc(void); + inline Arc_ptr nextarc(void); + inline Arc_ptr removearc(void); + inline int isnonempty(void) { return (head ? 1 : 0); } + inline void addarc(Arc_ptr); + void remove_this_arc(Arc_ptr); + int numarcs(void); + void adopt(void); + void markall(void); +}; + +/*---------------------------------------------------------------------------- + * Bin::addarc - add an Arc_ptr to head of linked list of Arc_ptr + *---------------------------------------------------------------------------- + */ + +inline void Bin::addarc(Arc_ptr jarc) +{ + jarc->link=head; + head=jarc; +} + +/*---------------------------------------------------------------------------- + * Bin::removearc - remove first Arc_ptr from bin + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr Bin::removearc(void) +{ + Arc_ptr jarc=head; + + if (jarc) + { + head=jarc->link; + } + + return jarc; +} + + +/*---------------------------------------------------------------------------- + * BinIter::nextarc - return current arc in bin and advance pointer to next arc + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr Bin::nextarc(void) +{ + Arc_ptr jarc=current; + + if (jarc) + { + current=jarc->link; + } + + return jarc; +} + +/*---------------------------------------------------------------------------- + * BinIter::firstarc - set current arc to first arc of bin advance to next arc + *---------------------------------------------------------------------------- + */ + +inline Arc_ptr Bin::firstarc(void) +{ + current=head; + + return nextarc(); +} + +#endif /* __glubin_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/bufpool.cc b/project/jni/glu/src/libnurbs/internals/bufpool.cc new file mode 100644 index 000000000..2786fd8df --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/bufpool.cc @@ -0,0 +1,116 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "myassert.h" +#include "bufpool.h" + +/*----------------------------------------------------------------------------- + * Pool - allocate a new pool of buffers + *----------------------------------------------------------------------------- + */ +Pool::Pool(int _buffersize, int initpoolsize, const char* n) +{ + if ((unsigned)_buffersizeinitsize) + { + nextsize/=2; + } +} diff --git a/project/jni/glu/src/libnurbs/internals/bufpool.h b/project/jni/glu/src/libnurbs/internals/bufpool.h new file mode 100644 index 000000000..f43b9555e --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/bufpool.h @@ -0,0 +1,142 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glubufpool_h_ +#define __glubufpool_h_ + +#include "myassert.h" +#include "mystdlib.h" + +#define NBLOCKS 32 + +class Buffer +{ + friend class Pool; + Buffer* next; /* next buffer on free list */ +}; + +class Pool +{ + public: + Pool(int, int, const char*); + ~Pool(void); + inline void* new_buffer(void); + inline void free_buffer(void*); + void clear(void); + + private: + void grow(void); + + protected: + Buffer* freelist; /* linked list of free buffers */ + char* blocklist[NBLOCKS]; /* blocks of malloced memory */ + int nextblock; /* next free block index */ + char* curblock; /* last malloced block */ + int buffersize; /* bytes per buffer */ + int nextsize; /* size of next block of memory */ + int nextfree; /* byte offset past next free buffer */ + int initsize; + enum Magic {is_allocated=0xf3a1, is_free=0xf1a2}; + const char* name; /* name of the pool */ + Magic magic; /* marker for valid pool */ +}; + +/*----------------------------------------------------------------------------- + * Pool::free_buffer - return a buffer to a pool + *----------------------------------------------------------------------------- + */ + +inline void Pool::free_buffer(void* b) +{ + assert((this!=0) && (magic==is_allocated)); + + /* add buffer to singly connected free list */ + + ((Buffer*)b)->next=freelist; + freelist=(Buffer*)b; +} + + +/*----------------------------------------------------------------------------- + * Pool::new_buffer - allocate a buffer from a pool + *----------------------------------------------------------------------------- + */ + +inline void* Pool::new_buffer(void) +{ + void* buffer; + + assert((this!=0) && (magic==is_allocated)); + + /* find free buffer */ + if (freelist) + { + buffer=(void*)freelist; + freelist=freelist->next; + } + else + { + if (!nextfree) + { + grow(); + } + nextfree-=buffersize;; + buffer=(void*)(curblock+nextfree); + } + + return buffer; +} + +class PooledObj +{ + public: + inline void* operator new(size_t, Pool&); + inline void* operator new(size_t, void*); + inline void* operator new(size_t s) {return ::new char[s];} + inline void operator delete(void*) {assert(0);} + inline void operator delete(void*, Pool&) {assert(0);} + inline void deleteMe(Pool&); +}; + +inline void* PooledObj::operator new(size_t, Pool& pool) +{ + return pool.new_buffer(); +} + +inline void PooledObj::deleteMe(Pool& pool) +{ + pool.free_buffer((void*) this); +} + +#endif /* __glubufpool_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/cachingeval.cc b/project/jni/glu/src/libnurbs/internals/cachingeval.cc new file mode 100644 index 000000000..790819a70 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/cachingeval.cc @@ -0,0 +1,70 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "cachingeval.h" + +int CachingEvaluator::canRecord(void) +{ + return 0; +} + +int CachingEvaluator::canPlayAndRecord(void) +{ + return 0; +} + +int CachingEvaluator::createHandle(int) +{ + return 0; +} + +void CachingEvaluator::beginOutput(ServiceMode, int) +{ +} + +void CachingEvaluator::endOutput(void) +{ +} + +void CachingEvaluator::discardRecording(int) +{ +} + +void CachingEvaluator::playRecording(int) +{ +} diff --git a/project/jni/glu/src/libnurbs/internals/cachingeval.h b/project/jni/glu/src/libnurbs/internals/cachingeval.h new file mode 100644 index 000000000..78152c15e --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/cachingeval.h @@ -0,0 +1,52 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glucachingval_h_ +#define __glucachingval_h_ + +class CachingEvaluator +{ + public: + virtual ~CachingEvaluator() { /* silence warning*/ } + enum ServiceMode { play, record, playAndRecord }; + virtual int canRecord(void); + virtual int canPlayAndRecord(void); + virtual int createHandle(int handle); + virtual void beginOutput(ServiceMode, int handle); + virtual void endOutput(void); + virtual void discardRecording(int handle); + virtual void playRecording(int handle); +}; + +#endif /* __glucachingval_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/ccw.cc b/project/jni/glu/src/libnurbs/internals/ccw.cc new file mode 100644 index 000000000..7becf3ca8 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/ccw.cc @@ -0,0 +1,427 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * ccw.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "subdivider.h" +#include "types.h" +#include "arc.h" +#include "trimvertex.h" +#include "simplemath.h" + +inline int Subdivider::bbox(TrimVertex* a, TrimVertex* b, TrimVertex* c, int p) +{ + return bbox(a->param[p], b->param[p], c->param[p], a->param[1-p], b->param[1-p], c->param[1-p]); +} + +int Subdivider::ccwTurn_sr(Arc_ptr j1, Arc_ptr j2) // dir = 1 +{ + register TrimVertex* v1=&j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex* v1last=&j1->pwlArc->pts[0]; + register TrimVertex* v2=&j2->pwlArc->pts[0]; + register TrimVertex* v2last=&j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex* v1next=v1-1; + register TrimVertex* v2next=v2+1; + int sgn; + + assert(v1!=v1last); + assert(v2!=v2last); + + // the arcs lie on the line (0 == v1->param[0]) + if (v1->param[0]==v1next->param[0] && v2->param[0]==v2next->param[0]) + { + return 0; + } + + if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[1] < v2->param[1] ) + return 0; + else if( v1->param[1] > v2->param[1] ) + return 1; + + while( 1 ) { + if( v1next->param[0] < v2next->param[0] ) { + assert( v1->param[0] <= v1next->param[0] ); + assert( v2->param[0] <= v1next->param[0] ); + switch( bbox( v2, v2next, v1next, 1 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) { + return sgn; + } else { + v1 = v1next--; + if( v1 == v1last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else if( v1next->param[0] > v2next->param[0] ) { + assert( v1->param[0] <= v2next->param[0] ); + assert( v2->param[0] <= v2next->param[0] ); + switch( bbox( v1, v1next, v2next, 1 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) { + return sgn; + } else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else { + if( v1next->param[1] < v2next->param[1] ) + return 0; + else if( v1next->param[1] > v2next->param[1] ) + return 1; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0 +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + + // the arcs lie on the line (0 == v1->param[0]) + if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] ) + return 0; + + if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[1] < v2->param[1] ) + return 1; + else if( v1->param[1] > v2->param[1] ) + return 0; + + while( 1 ) { + if( v1next->param[0] > v2next->param[0] ) { + assert( v1->param[0] >= v1next->param[0] ); + assert( v2->param[0] >= v1next->param[0] ); + switch( bbox( v2next, v2, v1next, 1 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) + return sgn; + else { + v1 = v1next--; + if( v1 == v1last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else if( v1next->param[0] < v2next->param[0] ) { + assert( v1->param[0] >= v2next->param[0] ); + assert( v2->param[0] >= v2next->param[0] ); + switch( bbox( v1next, v1, v2next, 1 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) + return sgn; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else { + if( v1next->param[1] < v2next->param[1] ) + return 1; + else if( v1next->param[1] > v2next->param[1] ) + return 0; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1 +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + + // the arcs lie on the line (1 == v1->param[1]) + if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) + return 0; + + if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[0] < v2->param[0] ) + return 1; + else if( v1->param[0] > v2->param[0] ) + return 0; + + while( 1 ) { + if( v1next->param[1] < v2next->param[1] ) { + assert( v1->param[1] <= v1next->param[1] ); + assert( v2->param[1] <= v1next->param[1] ); + switch( bbox( v2, v2next, v1next, 0 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) { + return sgn; + } else { + v1 = v1next--; + if( v1 == v1last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else if( v1next->param[1] > v2next->param[1] ) { + assert( v1->param[1] <= v2next->param[1] ); + assert( v2->param[1] <= v2next->param[1] ); + switch( bbox( v1, v1next, v2next, 0 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) { + return sgn; + } else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else { + if( v1next->param[0] < v2next->param[0] ) + return 1; + else if( v1next->param[0] > v2next->param[0] ) + return 0; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + } + } +} + +int +Subdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 ) +{ + register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; + register TrimVertex *v1last = &j1->pwlArc->pts[0]; + register TrimVertex *v2 = &j2->pwlArc->pts[0]; + register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; + register TrimVertex *v1next = v1-1; + register TrimVertex *v2next = v2+1; + int sgn; + + assert( v1 != v1last ); + assert( v2 != v2last ); + + // the arcs lie on the line (1 == v1->param[1]) + if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) + return 0; + + if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] ) + ::mylongjmp( jumpbuffer, 28 ); + + if( v1->param[0] < v2->param[0] ) + return 0; + else if( v1->param[0] > v2->param[0] ) + return 1; + + while( 1 ) { + if( v1next->param[1] > v2next->param[1] ) { + assert( v1->param[1] >= v1next->param[1] ); + assert( v2->param[1] >= v1next->param[1] ); + switch( bbox( v2next, v2, v1next, 0 ) ) { + case -1: + return 0; + case 0: + sgn = ccw( v1next, v2, v2next ); + if( sgn != -1 ) + return sgn; + else { + v1 = v1next--; + if( v1 == v1last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 1; + } + } else if( v1next->param[1] < v2next->param[1] ) { + switch( bbox( v1next, v1, v2next, 0 ) ) { + case -1: + return 1; + case 0: + sgn = ccw( v1next, v1, v2next ); + if( sgn != -1 ) + return sgn; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + break; + case 1: + return 0; + } + } else { + if( v1next->param[0] < v2next->param[0] ) + return 0; + else if( v1next->param[0] > v2next->param[0] ) + return 1; + else { + v2 = v2next++; + if( v2 == v2last ) { + return 0; // ill-conditioned, guess answer + } + } + } + } +} + + +int +Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc, + register REAL , register REAL , register REAL ) +{ + if( sa < sb ) { + if( sc <= sa ) { + return -1; + } else if( sb <= sc ) { + return 1; + } else { + return 0; + } + } else if( sa > sb ) { + if( sc >= sa ) { + return 1; + } else if( sb >= sc ) { + return -1; + } else { + return 0; + } + } else { + if( sc > sa ) { + return 1; + } else if( sb > sc ) { + return -1; + } else { + return 0; + } + } +} + +/*---------------------------------------------------------------------------- + * ccw - determine how three points are oriented by computing their + * determinant. + * Return 1 if the vertices are ccw oriented, + * 0 if they are cw oriented, or + * -1 if the computation is ill-conditioned. + *---------------------------------------------------------------------------- + */ +int +Subdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c ) +{ + REAL d = det3( a, b, c ); + if( glu_abs(d) < 0.0001 ) return -1; + return (d < 0.0) ? 0 : 1; +} diff --git a/project/jni/glu/src/libnurbs/internals/coveandtiler.cc b/project/jni/glu/src/libnurbs/internals/coveandtiler.cc new file mode 100644 index 000000000..019371a55 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/coveandtiler.cc @@ -0,0 +1,442 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * coveandtiler.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "coveandtiler.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" +#include "uarray.h" +#include "backend.h" + +#include + +const int CoveAndTiler::MAXSTRIPSIZE = 1000; + +CoveAndTiler::CoveAndTiler( Backend& b ) + : backend( b ) +{ } + +CoveAndTiler::~CoveAndTiler( void ) +{ } + +inline void +CoveAndTiler::output( GridVertex &gv ) +{ + backend.tmeshvert( &gv ); +} + +inline void CoveAndTiler::output(TrimVertex* tv) +{ + REAL retPoint[4]; + REAL retNormal[3]; + + backend.tmeshvert(tv, retPoint, retNormal); +} + +inline void +CoveAndTiler::output( GridTrimVertex& g ) +{ + backend.tmeshvert( &g ); +} + +void +CoveAndTiler::coveAndTile( void ) +{ + long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart; + long uend = (top.uend <= bot.uend) ? top.uend : bot.uend; + if( ustart <= uend ) { + tile( bot.vindex, ustart, uend ); + if( top.ustart >= bot.ustart ) + coveUpperLeft(); + else + coveLowerLeft(); + + if( top.uend <= bot.uend ) + coveUpperRight(); + else + coveLowerRight(); + } else { + TrimVertex blv, tlv, *bl, *tl; + GridTrimVertex bllv, tllv; + TrimVertex *lf = left.first(); + TrimVertex *ll = left.last(); + if( lf->param[0] >= ll->param[0] ) { + blv.param[0] = lf->param[0]; + blv.param[1] = ll->param[1]; + blv.nuid = 0; // XXX + assert( blv.param[1] == bot.vval ); + bl = &blv; + tl = lf; + tllv.set( lf ); + if( ll->param[0] > uarray.uarray[top.ustart-1] ) { + bllv.set( ll ); + assert( ll->param[0] <= uarray.uarray[bot.ustart] ); + } else { + bllv.set( top.ustart-1, bot.vindex ); + } + coveUpperLeftNoGrid( bl ); + } else { + tlv.param[0] = ll->param[0]; + tlv.param[1] = lf->param[1]; + tlv.nuid = 0; // XXX + assert( tlv.param[1] == top.vval ); + tl = &tlv; + bl = ll; + bllv.set( ll ); + if( lf->param[0] > uarray.uarray[bot.ustart-1] ) { + assert( lf->param[0] <= uarray.uarray[bot.ustart] ); + tllv.set( lf ); + } else { + tllv.set( bot.ustart-1, top.vindex ); + } + coveLowerLeftNoGrid( tl ); + } + + TrimVertex brv, trv, *br, *tr; + GridTrimVertex brrv, trrv; + TrimVertex *rf = right.first(); + TrimVertex *rl = right.last(); + + if( rf->param[0] <= rl->param[0] ) { + brv.param[0] = rf->param[0]; + brv.param[1] = rl->param[1]; + brv.nuid = 0; // XXX + assert( brv.param[1] == bot.vval ); + br = &brv; + tr = rf; + trrv.set( rf ); + if( rl->param[0] < uarray.uarray[top.uend+1] ) { + assert( rl->param[0] >= uarray.uarray[top.uend] ); + brrv.set( rl ); + } else { + brrv.set( top.uend+1, bot.vindex ); + } + coveUpperRightNoGrid( br ); + } else { + trv.param[0] = rl->param[0]; + trv.param[1] = rf->param[1]; + trv.nuid = 0; // XXX + assert( trv.param[1] == top.vval ); + tr = &trv; + br = rl; + brrv.set( rl ); + if( rf->param[0] < uarray.uarray[bot.uend+1] ) { + assert( rf->param[0] >= uarray.uarray[bot.uend] ); + trrv.set( rf ); + } else { + trrv.set( bot.uend+1, top.vindex ); + } + coveLowerRightNoGrid( tr ); + } + + backend.bgntmesh( "doit" ); + output(trrv); + output(tllv); + output( tr ); + output( tl ); + output( br ); + output( bl ); + output(brrv); + output(bllv); + backend.endtmesh(); + } +} + +void +CoveAndTiler::tile( long vindex, long ustart, long uend ) +{ + long numsteps = uend - ustart; + + if( numsteps == 0 ) return; + + if( numsteps > MAXSTRIPSIZE ) { + long umid = ustart + (uend - ustart) / 2; + tile( vindex, ustart, umid ); + tile( vindex, umid, uend ); + } else { + backend.surfmesh( ustart, vindex-1, numsteps, 1 ); + } +} + +void +CoveAndTiler::coveUpperRight( void ) +{ + GridVertex tgv( top.uend, top.vindex ); + GridVertex gv( top.uend, bot.vindex ); + + right.first(); + backend.bgntmesh( "coveUpperRight" ); + output( right.next() ); + output( tgv ); + backend.swaptmesh(); + output( gv ); + coveUR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUpperRightNoGrid( TrimVertex* br ) +{ + backend.bgntmesh( "coveUpperRight" ); + output( right.first() ); + output( right.next() ); + backend.swaptmesh(); + output( br ); + coveUR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUR( ) +{ + GridVertex gv( top.uend, bot.vindex ); + TrimVertex *vert = right.next(); + if( vert == NULL ) return; + + assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] ); + + if( gv.nextu() >= bot.uend ) { + for( ; vert; vert = right.next() ) { + output( vert ); + backend.swaptmesh(); + } + } else while( 1 ) { + if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) { + output( vert ); + backend.swaptmesh(); + vert = right.next(); + if( vert == NULL ) break; + } else { + backend.swaptmesh(); + output( gv ); + if( gv.nextu() == bot.uend ) { + for( ; vert; vert = right.next() ) { + output( vert ); + backend.swaptmesh(); + } + break; + } + } + } +} + +void +CoveAndTiler::coveUpperLeft( void ) +{ + GridVertex tgv( top.ustart, top.vindex ); + GridVertex gv( top.ustart, bot.vindex ); + + left.first(); + backend.bgntmesh( "coveUpperLeft" ); + output( tgv ); + output( left.next() ); + output( gv ); + backend.swaptmesh(); + coveUL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl ) +{ + backend.bgntmesh( "coveUpperLeftNoGrid" ); + output( left.first() ); + output( left.next() ); + output( bl ); + backend.swaptmesh(); + coveUL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveUL() +{ + GridVertex gv( top.ustart, bot.vindex ); + TrimVertex *vert = left.next(); + if( vert == NULL ) return; + assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] ); + + if( gv.prevu() <= bot.ustart ) { + for( ; vert; vert = left.next() ) { + backend.swaptmesh(); + output( vert ); + } + } else while( 1 ) { + if( vert->param[0] > uarray.uarray[gv.gparam[0]] ) { + backend.swaptmesh(); + output( vert ); + vert = left.next(); + if( vert == NULL ) break; + } else { + output( gv ); + backend.swaptmesh(); + if( gv.prevu() == bot.ustart ) { + for( ; vert; vert = left.next() ) { + backend.swaptmesh(); + output( vert ); + } + break; + } + } + } +} + +void +CoveAndTiler::coveLowerLeft( void ) +{ + GridVertex bgv( bot.ustart, bot.vindex ); + GridVertex gv( bot.ustart, top.vindex ); + + left.last(); + backend.bgntmesh( "coveLowerLeft" ); + output( left.prev() ); + output( bgv ); + backend.swaptmesh(); + output( gv ); + coveLL(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl ) +{ + backend.bgntmesh( "coveLowerLeft" ); + output( left.last() ); + output( left.prev() ); + backend.swaptmesh(); + output( tl ); + coveLL( ); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLL() +{ + GridVertex gv( bot.ustart, top.vindex ); + TrimVertex *vert = left.prev(); + if( vert == NULL ) return; + assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] ); + + if( gv.prevu() <= top.ustart ) { + for( ; vert; vert = left.prev() ) { + output( vert ); + backend.swaptmesh(); + } + } else while( 1 ) { + if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){ + output( vert ); + backend.swaptmesh(); + vert = left.prev(); + if( vert == NULL ) break; + } else { + backend.swaptmesh(); + output( gv ); + if( gv.prevu() == top.ustart ) { + for( ; vert; vert = left.prev() ) { + output( vert ); + backend.swaptmesh(); + } + break; + } + } + } +} + +void CoveAndTiler::coveLowerRight(void) +{ + GridVertex bgv(bot.uend, bot.vindex); + GridVertex gv(bot.uend, top.vindex); + + right.last(); + backend.bgntmesh("coveLowerRight"); + output(bgv); + output(right.prev()); + output(gv); + backend.swaptmesh(); + coveLR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr ) +{ + backend.bgntmesh( "coveLowerRIght" ); + output( right.last() ); + output( right.prev() ); + output( tr ); + backend.swaptmesh(); + coveLR(); + backend.endtmesh(); +} + +void +CoveAndTiler::coveLR( ) +{ + GridVertex gv( bot.uend, top.vindex ); + TrimVertex *vert = right.prev(); + if( vert == NULL ) return; + assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] ); + + if( gv.nextu() >= top.uend ) { + for( ; vert; vert = right.prev() ) { + backend.swaptmesh(); + output( vert ); + } + } else while( 1 ) { + if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) { + backend.swaptmesh(); + output( vert ); + vert = right.prev(); + if( vert == NULL ) break; + } else { + output( gv ); + backend.swaptmesh(); + if( gv.nextu() == top.uend ) { + for( ; vert; vert = right.prev() ) { + backend.swaptmesh(); + output( vert ); + } + break; + } + } + } +} + diff --git a/project/jni/glu/src/libnurbs/internals/coveandtiler.h b/project/jni/glu/src/libnurbs/internals/coveandtiler.h new file mode 100644 index 000000000..d454202e6 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/coveandtiler.h @@ -0,0 +1,72 @@ +/* + * 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. + */ + +/* + * coveandtiler.h + * + */ + +#ifndef __glucoveandtiler_h +#define __glucoveandtiler_h + +#include "trimregion.h" +#include "trimvertex.h" +#include "gridvertex.h" + +class Backend; +class GridTrimVertex; + +class CoveAndTiler : virtual public TrimRegion { +public: + CoveAndTiler( Backend& ); + ~CoveAndTiler( void ); + void coveAndTile( void ); +private: + Backend& backend; + static const int MAXSTRIPSIZE; + void tile( long, long, long ); + void coveLowerLeft( void ); + void coveLowerRight( void ); + void coveUpperLeft( void ); + void coveUpperRight( void ); + void coveUpperLeftNoGrid( TrimVertex * ); + void coveUpperRightNoGrid( TrimVertex * ); + void coveLowerLeftNoGrid( TrimVertex * ); + void coveLowerRightNoGrid( TrimVertex * ); + void coveLL( void ); + void coveLR( void ); + void coveUL( void ); + void coveUR( void ); + inline void output( GridTrimVertex& ); + inline void output( GridVertex& ); + inline void output( TrimVertex* ); +}; + +#endif /* __glucoveandtiler_h */ diff --git a/project/jni/glu/src/libnurbs/internals/curve.cc b/project/jni/glu/src/libnurbs/internals/curve.cc new file mode 100644 index 000000000..76f83ab22 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/curve.cc @@ -0,0 +1,198 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curve.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mymath.h" +#include "curve.h" +#include "mapdesc.h" +#include "types.h" +#include "quilt.h" +#include "nurbsconsts.h" + +/*-------------------------------------------------------------------------- + * Curve::Curve - copy curve from quilt and transform control points + *-------------------------------------------------------------------------- + */ + +Curve::Curve( Quilt_ptr geo, REAL pta, REAL ptb, Curve *c ) +{ + mapdesc = geo->mapdesc; + next = c; + needsSampling = mapdesc->isRangeSampling() ? 1 : 0; + cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; + order = geo->qspec[0].order; + stride = MAXCOORDS; + + REAL *ps = geo->cpts; + Quiltspec_ptr qs = geo->qspec; + ps += qs->offset; + ps += qs->index * qs->order * qs->stride; + + if( needsSampling ) + mapdesc->xformSampling( ps, qs->order, qs->stride, spts, stride ); + + if( cullval == CULL_ACCEPT ) + mapdesc->xformCulling( ps, qs->order, qs->stride, cpts, stride ); + + /* set untrimmed curve range */ + range[0] = qs->breakpoints[qs->index]; + range[1] = qs->breakpoints[qs->index+1]; + range[2] = range[1] - range[0]; + + if( range[0] != pta ) { + Curve lower( *this, pta, 0 ); + lower.next = next; + *this = lower; + } + if( range[1] != ptb ) { + Curve lower( *this, ptb, 0 ); + } +} + +/*-------------------------------------------------------------------------- + * Curve::Curve - subdivide a curve along an isoparametric line + *-------------------------------------------------------------------------- + */ + +Curve::Curve( Curve& upper, REAL value, Curve *c ) +{ + Curve &lower = *this; + + lower.next = c; + lower.mapdesc = upper.mapdesc; + lower.needsSampling = upper.needsSampling; + lower.order = upper.order; + lower.stride = upper.stride; + lower.cullval = upper.cullval; + + REAL d = (value - upper.range[0]) / upper.range[2]; + + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, upper.stride, upper.order ); + + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, upper.stride, upper.order ); + + lower.range[0] = upper.range[0]; + lower.range[1] = value; + lower.range[2] = value - upper.range[0]; + upper.range[0] = value; + upper.range[2] = upper.range[1] - value; +} + + +/*-------------------------------------------------------------------------- + * Curve::clamp - clamp the sampling rate to a given maximum + *-------------------------------------------------------------------------- + */ + +void +Curve::clamp( void ) +{ + if( stepsize < minstepsize ) + stepsize = mapdesc->clampfactor * minstepsize; +} + +void +Curve::setstepsize( REAL max ) +{ + stepsize = ( max >= 1.0 ) ? (range[2] / max) : range[2]; + minstepsize = stepsize; +} + +void +Curve::getstepsize( void ) +{ + minstepsize= 0; + + if( mapdesc->isConstantSampling() ) { + // fixed number of samples per patch in each direction + // maxrate is number of s samples per patch + setstepsize( mapdesc->maxrate ); + } else if( mapdesc->isDomainSampling() ) { + // maxrate is number of s samples per unit s length of domain + setstepsize( mapdesc->maxrate * range[2] ); + } else { + // upper bound on path length between sample points + + assert( order <= MAXORDER ); + + /* points have been transformed, therefore they are homogeneous */ + REAL tmp[MAXORDER][MAXCOORDS]; + const int tstride = sizeof(tmp[0]) / sizeof(REAL); + int val = mapdesc->project( spts, stride, &tmp[0][0], tstride, order ); + + if( val == 0 ) { + // control points cross infinity, therefore derivatives are undefined + setstepsize( mapdesc->maxrate ); + } else { + REAL t = mapdesc->getProperty( N_PIXEL_TOLERANCE ); + if( mapdesc->isParametricDistanceSampling() ) { + REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 2, range[2] ); + stepsize = (d > 0.0) ? sqrtf( 8.0 * t / d ) : range[2]; + minstepsize = ( mapdesc->maxrate > 0.0f ) ? (range[2] / mapdesc->maxrate) : 0.0f; + } else if( mapdesc->isPathLengthSampling() ) { + // t is upper bound on path (arc) length + REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 1, range[2] ); + stepsize = ( d > 0.0 ) ? (t / d) : range[2]; + minstepsize = ( mapdesc->maxrate > 0.0f ) ? (range[2] / mapdesc->maxrate) : 0.0f; + } else { + // control points cross infinity, therefore partials are undefined + setstepsize( mapdesc->maxrate ); + } + } + } +} + +int +Curve::needsSamplingSubdivision( void ) +{ + return ( stepsize < minstepsize ) ? 1 : 0; +} + +int +Curve::cullCheck( void ) +{ + if( cullval == CULL_ACCEPT ) + cullval = mapdesc->cullCheck( cpts, order, stride ); + return cullval; +} + diff --git a/project/jni/glu/src/libnurbs/internals/curve.h b/project/jni/glu/src/libnurbs/internals/curve.h new file mode 100644 index 000000000..0da81c721 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/curve.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +/* + * curve.h + * + */ + +#ifndef __glucurve_h_ +#define __glucurve_h_ + +#include "types.h" +#include "defines.h" + +class Mapdesc; +class Quilt; + + +class Curve { +public: +friend class Curvelist; + Curve( Quilt *, REAL, REAL, Curve * ); + Curve( Curve&, REAL, Curve * ); + Curve * next; +private: + Mapdesc * mapdesc; + int stride; + int order; + int cullval; + int needsSampling; + REAL cpts[MAXORDER*MAXCOORDS]; + REAL spts[MAXORDER*MAXCOORDS]; + REAL stepsize; + REAL minstepsize; + REAL range[3]; + + void clamp( void ); + void setstepsize( REAL ); + void getstepsize( void ); + int cullCheck( void ); + int needsSamplingSubdivision( void ); +}; +#endif /* __glucurve_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/curvelist.cc b/project/jni/glu/src/libnurbs/internals/curvelist.cc new file mode 100644 index 000000000..872eb5816 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/curvelist.cc @@ -0,0 +1,110 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curvelist.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "quilt.h" +#include "curvelist.h" +#include "curve.h" +#include "nurbsconsts.h" +#include "types.h" + +Curvelist::Curvelist( Quilt *quilts, REAL pta, REAL ptb ) +{ + curve = 0; + for( Quilt *q = quilts; q; q = q->next ) + curve = new Curve( q, pta, ptb, curve ); + range[0] = pta; + range[1] = ptb; + range[2] = ptb - pta; +} + +Curvelist::Curvelist( Curvelist &upper, REAL value ) +{ + Curvelist &lower = *this; + curve = 0; + for( Curve *c = upper.curve; c; c = c->next ) + curve = new Curve( *c, value, curve ); + + lower.range[0] = upper.range[0]; + lower.range[1] = value; + lower.range[2] = value - upper.range[0]; + upper.range[0] = value; + upper.range[2] = upper.range[1] - value; +} + +Curvelist::~Curvelist() +{ + while( curve ) { + Curve *c = curve; + curve = curve->next; + delete c; + } +} + +int +Curvelist::cullCheck( void ) +{ + for( Curve *c = curve; c; c = c->next ) + if( c->cullCheck() == CULL_TRIVIAL_REJECT ) + return CULL_TRIVIAL_REJECT; + return CULL_ACCEPT; +} + +void +Curvelist::getstepsize( void ) +{ + stepsize = range[2]; + Curve *c; + for( c = curve; c; c = c->next ) { + c->getstepsize(); + c->clamp(); + stepsize = ((c->stepsize < stepsize) ? c->stepsize : stepsize); + if( c->needsSamplingSubdivision() ) break; + } + needsSubdivision = ( c ) ? 1 : 0; +} + +int +Curvelist::needsSamplingSubdivision( void ) +{ + return needsSubdivision; +} + diff --git a/project/jni/glu/src/libnurbs/internals/curvelist.h b/project/jni/glu/src/libnurbs/internals/curvelist.h new file mode 100644 index 000000000..733a5115d --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/curvelist.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * curvelist.h + * + */ + +#ifndef __glucurvelist_h_ +#define __glucurvelist_h_ + +#include "types.h" +#include "defines.h" + +class Mapdesc; +class Quilt; +class Curve; + +class Curvelist +{ +friend class Subdivider; +public: + Curvelist( Quilt *, REAL, REAL ); + Curvelist( Curvelist &, REAL ); + ~Curvelist( void ); + int cullCheck( void ); + void getstepsize( void ); + int needsSamplingSubdivision(); +private: + Curve *curve; + float range[3]; + int needsSubdivision; + float stepsize; +}; +#endif /* __glucurvelist_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/curvesub.cc b/project/jni/glu/src/libnurbs/internals/curvesub.cc new file mode 100644 index 000000000..18b525d10 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/curvesub.cc @@ -0,0 +1,103 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * curvesub.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "renderhints.h" +#include "backend.h" +#include "quilt.h" +#include "curvelist.h" +#include "curve.h" +#include "nurbsconsts.h" + +/*-------------------------------------------------------------------------- + * drawCurves - main curve rendering entry point + *-------------------------------------------------------------------------- + */ + +void Subdivider::drawCurves(void) +{ + REAL from[1], to[1]; + Flist bpts; + qlist->getRange(from, to, bpts); + + renderhints.init(); + + backend.bgncurv(); + for(int i=bpts.start; idownloadAll(&pta, &ptb, backend); + + Curvelist curvelist(qlist, pta, ptb); + samplingSplit(curvelist, renderhints.maxsubdivisions); + } + backend.endcurv(); +} + + +/*-------------------------------------------------------------------------- + * samplingSplit - recursively subdivide patch, cull check each subpatch + *-------------------------------------------------------------------------- + */ + +void +Subdivider::samplingSplit( Curvelist& curvelist, int subdivisions ) +{ + if( curvelist.cullCheck() == CULL_TRIVIAL_REJECT ) return; + + curvelist.getstepsize(); + + if( curvelist.needsSamplingSubdivision() && (subdivisions > 0) ) { + REAL mid = ( curvelist.range[0] + curvelist.range[1] ) * 0.5f; + Curvelist lowerlist( curvelist, mid ); + samplingSplit( lowerlist, subdivisions-1 ); // lower + samplingSplit( curvelist, subdivisions-1 ); // upper + } else { + long nu = 1 + ((long) (curvelist.range[2] / curvelist.stepsize)); + backend.curvgrid( curvelist.range[0], curvelist.range[1], nu ); + backend.curvmesh( 0, nu ); + } +} + diff --git a/project/jni/glu/src/libnurbs/internals/dataTransform.cc b/project/jni/glu/src/libnurbs/internals/dataTransform.cc new file mode 100644 index 000000000..530a8f07e --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/dataTransform.cc @@ -0,0 +1,113 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include +#include +#include "glimports.h" +#include "myassert.h" +#include "nurbsconsts.h" +#include "trimvertex.h" +#include "dataTransform.h" + +extern directedLine* arcLoopToDLineLoop(Arc_ptr loop); + +directedLine* bin_to_DLineLoops(Bin& bin) +{ + directedLine *ret=NULL; + directedLine *temp; + bin.markall(); + for(Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()){ + if(jarc->ismarked()) { + assert(jarc->check() != 0); + Arc_ptr jarchead = jarc; + do { + jarc->clearmark(); + jarc = jarc->next; + } while(jarc != jarchead); + temp = arcLoopToDLineLoop(jarc); + ret = temp->insertPolygon(ret); + } + } + return ret; +} + +directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl) +{ + directedLine* ret = original; + for(Int i=0; inpts-1; i++) + { + sampledLine* sline = new sampledLine(2); + sline->setPoint(0, pwl->pts[i].param); + sline->setPoint(1, pwl->pts[i+1].param); + directedLine* dline = new directedLine(INCREASING, sline); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + } + return ret; +} + +directedLine* o_curve_to_DLineLoop(O_curve* cur) +{ + directedLine *ret; + if(cur == NULL) + return NULL; + assert(cur->curvetype == ct_pwlcurve); + ret = o_pwlcurve_to_DLines(NULL, cur->curve.o_pwlcurve); + for(O_curve* temp = cur->next; temp != NULL; temp = temp->next) + { + assert(temp->curvetype == ct_pwlcurve); + ret = o_pwlcurve_to_DLines(ret, temp->curve.o_pwlcurve); + } + return ret; +} + +directedLine* o_trim_to_DLineLoops(O_trim* trim) +{ + O_trim* temp; + directedLine *ret; + if(trim == NULL) + return NULL; + ret = o_curve_to_DLineLoop(trim->o_curve); + + for(temp=trim->next; temp != NULL; temp = temp->next) + { + ret = ret->insertPolygon(o_curve_to_DLineLoop(temp->o_curve)); + } + return ret; +} diff --git a/project/jni/glu/src/libnurbs/internals/dataTransform.h b/project/jni/glu/src/libnurbs/internals/dataTransform.h new file mode 100644 index 000000000..7898df754 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/dataTransform.h @@ -0,0 +1,59 @@ +/* + * 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. + */ +/* +*/ + +#ifndef _DATA_TRANSFORM_H +#define _DATA_TRANSFORM_H + +#include "reader.h" +#include "directedLine.h" +#include "bin.h" +directedLine* bin_to_DLineLoops(Bin& bin); + +/*transform the pwlcurve into a number of directedline lines + *insert these directedlines into orignal which is supposed to be + *the part of the trimming loop obtained so far. + *return the updated trimkming loop. + */ +directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl); + +/*transform a trim loop (curve) into a directedLine loop + */ +directedLine* o_curve_to_DLineLoop(O_curve* curve); + +/*transform a list of trim loops (trim) into + *a list of polygons represented as directedLine*. + */ +directedLine* o_trim_to_DLineLoops(O_trim* trim); + + +#endif + diff --git a/project/jni/glu/src/libnurbs/internals/defines.h b/project/jni/glu/src/libnurbs/internals/defines.h new file mode 100644 index 000000000..f586306fc --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/defines.h @@ -0,0 +1,50 @@ +/* + * 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. + */ + +/* + * defines.h + * + */ + +#ifndef __gludefines_h_ +#define __gludefines_h_ + +/* culling constants */ +#define CULL_TRIVIAL_REJECT 0 +#define CULL_TRIVIAL_ACCEPT 1 +#define CULL_ACCEPT 2 + +/* maximum order of a B-Spline */ +#define MAXORDER 24 + +/* maximum dimension of any B-spline range space */ +#define MAXCOORDS 5 + +#endif /* __gludefines_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/displaylist.cc b/project/jni/glu/src/libnurbs/internals/displaylist.cc new file mode 100644 index 000000000..48593c637 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/displaylist.cc @@ -0,0 +1,82 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * displaylist.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "nurbstess.h" +#include "displaylist.h" + + +DisplayList::DisplayList( NurbsTessellator *_nt ) : + dlnodePool( sizeof( Dlnode ), 1, "dlnodepool" ) +{ + lastNode = &nodes; + nt = _nt; +} + +DisplayList::~DisplayList( void ) +{ + for( Dlnode *nextNode; nodes; nodes = nextNode ) { + nextNode = nodes->next; + if( nodes->cleanup != 0 ) (nt->*nodes->cleanup)( nodes->arg ); + //nodes->deleteMe(dlnodePool); + } +} + +void +DisplayList::play( void ) +{ + for( Dlnode *node = nodes; node; node = node->next ) + if( node->work != 0 ) (nt->*node->work)( node->arg ); +} + +void +DisplayList::endList( void ) +{ + *lastNode = 0; +} + +void +DisplayList::append( PFVS work, void *arg, PFVS cleanup ) +{ + Dlnode *node = new(dlnodePool) Dlnode( work, arg, cleanup ); + *lastNode = node; + lastNode = &(node->next); +} + diff --git a/project/jni/glu/src/libnurbs/internals/displaylist.h b/project/jni/glu/src/libnurbs/internals/displaylist.h new file mode 100644 index 000000000..22cbec378 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/displaylist.h @@ -0,0 +1,78 @@ +/* + * 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. + */ + +/* + * displaylist.h + * + */ + +#ifndef __gludisplaylist_h_ +#define __gludisplaylist_h_ + +#include "glimports.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "bufpool.h" + +class NurbsTessellator; + +typedef void (NurbsTessellator::*PFVS)( void * ); + +struct Dlnode : public PooledObj { + Dlnode( PFVS, void *, PFVS ); + PFVS work; + void * arg; + PFVS cleanup; + Dlnode * next; +}; + +inline +Dlnode::Dlnode( PFVS _work, void *_arg, PFVS _cleanup ) +{ + work = _work; + arg = _arg; + cleanup = _cleanup; +} + +class DisplayList { +public: + DisplayList( NurbsTessellator * ); + ~DisplayList( void ); + void play( void ); + void append( PFVS work, void *arg, PFVS cleanup ); + void endList( void ); +private: + Dlnode *nodes; + Pool dlnodePool; + Dlnode **lastNode; + NurbsTessellator *nt; +}; + +#endif /* __gludisplaylist_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/displaymode.h b/project/jni/glu/src/libnurbs/internals/displaymode.h new file mode 100644 index 000000000..c3ae6a4d8 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/displaymode.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef __gludisplaymode_h_ +#define __gludisplaymode_h_ + +#define N_MESHFILL 0 +#define N_MESHLINE 1 +#define N_MESHPOINT 2 + +#endif /* __gludisplaymode_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/flist.cc b/project/jni/glu/src/libnurbs/internals/flist.cc new file mode 100644 index 000000000..4c29fbb7a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/flist.cc @@ -0,0 +1,129 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * flist.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "flist.h" + +/*---------------------------------------------------------------------------- + * Flist::Flist - initialize a REAL number array + *---------------------------------------------------------------------------- + */ +Flist::Flist(void) +{ + npts=0; + pts=0; + start=end=0; +} + +/*---------------------------------------------------------------------------- + * Flist::~Flist - free a REAL number array + *---------------------------------------------------------------------------- + */ +Flist::~Flist(void) +{ + if (npts) + { + delete[]pts; + } +} + +void Flist::add(REAL x) +{ + pts[end++]=x; + assert(end<=npts); +} + +/*---------------------------------------------------------------------------- + * Flist::filter - remove duplicate numbers from array + *---------------------------------------------------------------------------- + */ +void Flist::filter(void) +{ + sorter.qsort(pts, end); + start=0; + + int j=0; + for (int i=1; iparam[0] <= llast->param[0] ) { + fakeleft.init( left.first() ); + upper.left = &fakeleft; + lower.left = &left; + } else { + fakeleft.init( left.last() ); + lower.left = &fakeleft; + upper.left = &left; + } + upper.left->last(); + lower.left->first(); + + if( top.ustart <= top.uend ) { + upper.line = ⊤ + upper.index = top.ustart; + } else + upper.line = 0; + + if( bot.ustart <= bot.uend ) { + lower.line = ⊥ + lower.index = bot.ustart; + } else + lower.line = 0; + + TrimVertex *rfirst = right.first(); + TrimVertex *rlast = right.last(); + if( rfirst->param[0] <= rlast->param[0] ) { + fakeright.init( right.last() ); + lower.right = &fakeright; + upper.right = &right; + } else { + fakeright.init( right.first() ); + upper.right = &fakeright; + lower.right = &right; + } + upper.right->first(); + lower.right->last(); +} + +/*---------------------------------------------------------------------- + * nextupper - find next vertex on upper hull of trim region. + * - if vertex is on trim curve, set vtop point to + * that vertex. if vertex is on grid, set vtop to + * point to temporary area and stuff coordinants into + * temporary vertex. Also, place grid coords in temporary + * grid vertex. + *---------------------------------------------------------------------- + */ +GridTrimVertex * +Hull::nextupper( GridTrimVertex *gv ) +{ + if( upper.left ) { + gv->set( upper.left->prev() ); + if( gv->isTrimVert() ) return gv; + upper.left = 0; + } + + if( upper.line ) { + assert( upper.index <= upper.line->uend ); + gv->set( uarray.uarray[upper.index], upper.line->vval ); + gv->set( upper.index, upper.line->vindex ); + if( upper.index++ == upper.line->uend ) upper.line = 0; + return gv; + } + + if( upper.right ) { + gv->set( upper.right->next() ); + if( gv->isTrimVert() ) return gv; + upper.right = 0; + } + + return 0; +} + +GridTrimVertex * +Hull::nextlower( register GridTrimVertex *gv ) +{ + if( lower.left ) { + gv->set( lower.left->next() ); + if( gv->isTrimVert() ) return gv; + lower.left = 0; + } + + if( lower.line ) { + gv->set( uarray.uarray[lower.index], lower.line->vval ); + gv->set( lower.index, lower.line->vindex ); + if( lower.index++ == lower.line->uend ) lower.line = 0; + return gv; + } + + if( lower.right ) { + gv->set( lower.right->prev() ); + if( gv->isTrimVert() ) return gv; + lower.right = 0; + } + + return 0; +} + diff --git a/project/jni/glu/src/libnurbs/internals/hull.h b/project/jni/glu/src/libnurbs/internals/hull.h new file mode 100644 index 000000000..dfe865267 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/hull.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +/* + * hull.h + * + */ + +#ifndef __gluhull_h_ +#define __gluhull_h_ + +#include "trimline.h" +#include "trimregion.h" +#include "trimvertex.h" +#include "gridtrimvertex.h" + +struct Gridline; +class Uarray; + +class Hull : virtual public TrimRegion { +public: + Hull( void ); + ~Hull( void ); + void init( void ); + GridTrimVertex * nextlower( GridTrimVertex * ); + GridTrimVertex * nextupper( GridTrimVertex * ); +private: + struct Side { + Trimline *left; + Gridline *line; + Trimline *right; + long index; + }; + + Side lower; + Side upper; + Trimline fakeleft; + Trimline fakeright; +}; + + +#endif /* __gluhull_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/intersect.cc b/project/jni/glu/src/libnurbs/internals/intersect.cc new file mode 100644 index 000000000..35ac678f7 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/intersect.cc @@ -0,0 +1,619 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * intersect.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arc.h" +#include "bin.h" +#include "backend.h" +#include "trimvertpool.h" + +/*#define NOTDEF*/ + +enum i_result { INTERSECT_VERTEX, INTERSECT_EDGE }; + +/* local functions */ +static enum i_result pwlarc_intersect( PwlArc *, int, REAL, int, int[3] ); + +void +Subdivider::partition( Bin & bin, Bin & left, Bin & intersections, + Bin & right, Bin & unknown, int param, REAL value ) +{ + Bin headonleft, headonright, tailonleft, tailonright; + + for( Arc_ptr jarc = bin.removearc(); jarc; jarc = bin.removearc() ) { + + REAL tdiff = jarc->tail()[param] - value; + REAL hdiff = jarc->head()[param] - value; + + if( tdiff > 0.0 ) { + if( hdiff > 0.0 ) { + right.addarc( jarc ); + } else if( hdiff == 0.0 ) { + tailonright.addarc( jarc ); + } else { + Arc_ptr jtemp; + switch( arc_split(jarc, param, value, 0) ) { + case 2: + tailonright.addarc( jarc ); + headonleft.addarc( jarc->next ); + break; + case 31: + assert( jarc->head()[param] > value ); + right.addarc( jarc ); + tailonright.addarc( jtemp = jarc->next ); + headonleft.addarc( jtemp->next ); + break; + case 32: + assert( jarc->head()[param] <= value ); + tailonright .addarc( jarc ); + headonleft.addarc( jtemp = jarc->next ); + left.addarc( jtemp->next ); + break; + case 4: + right.addarc( jarc ); + tailonright.addarc( jtemp = jarc->next ); + headonleft.addarc( jtemp = jtemp->next ); + left.addarc( jtemp->next ); + } + } + } else if( tdiff == 0.0 ) { + if( hdiff > 0.0 ) { + headonright.addarc( jarc ); + } else if( hdiff == 0.0 ) { + unknown.addarc( jarc ); + } else { + headonleft.addarc( jarc ); + } + } else { + if( hdiff > 0.0 ) { + Arc_ptr jtemp; + switch( arc_split(jarc, param, value, 1) ) { + case 2: + tailonleft.addarc( jarc ); + headonright.addarc( jarc->next ); + break; + case 31: + assert( jarc->head()[param] < value ); + left.addarc( jarc ); + tailonleft.addarc( jtemp = jarc->next ); + headonright.addarc( jtemp->next ); + break; + case 32: + assert( jarc->head()[param] >= value ); + tailonleft.addarc( jarc ); + headonright.addarc( jtemp = jarc->next ); + right.addarc( jtemp->next ); + break; + case 4: + left.addarc( jarc ); + tailonleft.addarc( jtemp = jarc->next ); + headonright.addarc( jtemp = jtemp->next ); + right.addarc( jtemp->next ); + } + } else if( hdiff == 0.0 ) { + tailonleft.addarc( jarc ); + } else { + left.addarc( jarc ); + } + } + } + if( param == 0 ) { + classify_headonleft_s( headonleft, intersections, left, value ); + classify_tailonleft_s( tailonleft, intersections, left, value ); + classify_headonright_s( headonright, intersections, right, value ); + classify_tailonright_s( tailonright, intersections, right, value ); + } else { + classify_headonleft_t( headonleft, intersections, left, value ); + classify_tailonleft_t( tailonleft, intersections, left, value ); + classify_headonright_t( headonright, intersections, right, value ); + classify_tailonright_t( tailonright, intersections, right, value ); + } +} + +inline static void +vert_interp( TrimVertex *n, TrimVertex *l, TrimVertex *r, int p, REAL val ) +{ + assert( val > l->param[p]); + assert( val < r->param[p]); + + n->nuid = l->nuid; + + n->param[p] = val; + if( l->param[1-p] != r->param[1-p] ) { + REAL ratio = (val - l->param[p]) / (r->param[p] - l->param[p]); + n->param[1-p] = l->param[1-p] + + ratio * (r->param[1-p] - l->param[1-p]); + } else { + n->param[1-p] = l->param[1-p]; + } +} + +int Subdivider::arc_split(Arc_ptr jarc, int param, REAL value, int dir) +{ + int maxvertex = jarc->pwlArc->npts; + Arc_ptr jarc1; + TrimVertex* v = jarc->pwlArc->pts; + + int loc[3]; + switch( pwlarc_intersect( jarc->pwlArc, param, value, dir, loc ) ) { + + // When the parameter value lands on a vertex, life is sweet + case INTERSECT_VERTEX: { + jarc1 = new(arcpool) Arc( jarc, new( pwlarcpool) PwlArc( maxvertex-loc[1], &v[loc[1]] ) ); + jarc->pwlArc->npts = loc[1] + 1; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + return 2; + } + + // When the parameter value intersects an edge, we have to + // interpolate a new vertex. There are special cases + // if the new vertex is adjacent to one or both of the + // endpoints of the arc. + case INTERSECT_EDGE: { + int i, j; + if( dir == 0 ) { + i = loc[0]; + j = loc[2]; + } else { + i = loc[2]; + j = loc[0]; + } + +#ifndef NOTDEF + // The split is between vertices at index j and i, in that + // order (j < i) + + // JEB: This code is my idea of how to do the split without + // increasing the number of links. I'm doing this so that + // the is_rect routine can recognize rectangles created by + // subdivision. In exchange for simplifying the curve list, + // however, it costs in allocated space and vertex copies. + + TrimVertex *newjunk = trimvertexpool.get(maxvertex -i+1 /*-j*/); + int k; + for(k=0; knuid; + } + + TrimVertex *vcopy = trimvertexpool.get(maxvertex); + for(k=0; kpwlArc->pts=vcopy; + + v[i].nuid = jarc->nuid; + v[j].nuid = jarc->nuid; + vert_interp( &newjunk[0], &v[loc[0]], &v[loc[2]], param, value ); + + if( showingDegenerate() ) + backend.triangle( &v[i], &newjunk[0], &v[j] ); + + vcopy[j+1].param[0]=newjunk[0].param[0]; + vcopy[j+1].param[1]=newjunk[0].param[1]; + + + jarc1 = new(arcpool) Arc( jarc, + new(pwlarcpool) PwlArc(maxvertex-i+1 , newjunk ) ); + + jarc->pwlArc->npts = j+2; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + + return 2; +#endif //not NOTDEF + // JEB: This is the original version: +#ifdef NOTDEF + Arc_ptr jarc2, jarc3; + + TrimVertex *newjunk = trimvertexpool.get(3); + v[i].nuid = jarc->nuid; + v[j].nuid = jarc->nuid; + newjunk[0] = v[j]; + newjunk[2] = v[i]; + vert_interp( &newjunk[1], &v[loc[0]], &v[loc[2]], param, value ); + + if( showingDegenerate() ) + backend.triangle( &newjunk[2], &newjunk[1], &newjunk[0] ); + + // New vertex adjacent to both endpoints + if (maxvertex == 2) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc->pwlArc->npts = 2; + jarc->pwlArc->pts = newjunk; + jarc1->next = jarc->next; + jarc1->next->prev = jarc1; + jarc->next = jarc1; + jarc1->prev = jarc; + assert(jarc->check() != 0); + + return 2; + + // New vertex adjacent to ending point of arc + } else if (maxvertex - j == 2) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); + jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc->pwlArc->npts = maxvertex-1; + jarc2->next = jarc->next; + jarc2->next->prev = jarc2; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + assert(jarc->check() != 0); + return 31; + + // New vertex adjacent to starting point of arc + } else if (i == 1) { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc2 = new(arcpool) Arc( jarc, + new(pwlarcpool) PwlArc( maxvertex-1, &jarc->pwlArc->pts[1] ) ); + jarc->pwlArc->npts = 2; + jarc->pwlArc->pts = newjunk; + jarc2->next = jarc->next; + jarc2->next->prev = jarc2; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + assert(jarc->check() != 0); + return 32; + + // It's somewhere in the middle + } else { + jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); + jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); + jarc3 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( maxvertex-i, v+i ) ); + jarc->pwlArc->npts = j + 1; + jarc3->next = jarc->next; + jarc3->next->prev = jarc3; + jarc->next = jarc1; + jarc1->prev = jarc; + jarc1->next = jarc2; + jarc2->prev = jarc1; + jarc2->next = jarc3; + jarc3->prev = jarc2; + assert(jarc->check() != 0); + return 4; + } +#endif // NOTDEF + } + default: + return -1; //picked -1 since it's not used + } +} + +/*---------------------------------------------------------------------------- + * pwlarc_intersect - find intersection of pwlArc and isoparametric line + *---------------------------------------------------------------------------- + */ + +static enum i_result +pwlarc_intersect( + PwlArc *pwlArc, + int param, + REAL value, + int dir, + int loc[3] ) +{ + assert( pwlArc->npts > 0 ); + + if( dir ) { + TrimVertex *v = pwlArc->pts; + int imin = 0; + int imax = pwlArc->npts - 1; + assert( value > v[imin].param[param] ); + assert( value < v[imax].param[param] ); + while( (imax - imin) > 1 ) { + int imid = (imax + imin)/2; + if( v[imid].param[param] > value ) + imax = imid; + else if( v[imid].param[param] < value ) + imin = imid; + else { + loc[1] = imid; + return INTERSECT_VERTEX; + } + } + loc[0] = imin; + loc[2] = imax; + return INTERSECT_EDGE; + } else { + TrimVertex *v = pwlArc->pts; + int imax = 0; + int imin = pwlArc->npts - 1; + assert( value > v[imin].param[param] ); + assert( value < v[imax].param[param] ); + while( (imin - imax) > 1 ) { + int imid = (imax + imin)/2; + if( v[imid].param[param] > value ) + imax = imid; + else if( v[imid].param[param] < value ) + imin = imid; + else { + loc[1] = imid; + return INTERSECT_VERTEX; + } + } + loc[0] = imin; + loc[2] = imax; + return INTERSECT_EDGE; + } +} + +/*---------------------------------------------------------------------------- + * arc_classify - determine which side of a line a jarc lies + *---------------------------------------------------------------------------- + */ + +void +Subdivider::classify_tailonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at left, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x02 ); + j->clearitail(); + + REAL diff = j->next->head()[0] - val; + if( diff > 0.0 ) { + in.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_sl( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->next->tail()[1] > j->next->head()[1] ) + in.addarc(j); + else + out.addarc(j); + } + } +} + +void +Subdivider::classify_tailonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at left, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x02 ); + j->clearitail(); + + REAL diff = j->next->head()[1] - val; + if( diff > 0.0 ) { + in.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_tl( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if (j->next->tail()[0] > j->next->head()[0] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_headonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at left */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x20 ); + + j->setitail(); + + REAL diff = j->prev->tail()[0] - val; + if( diff > 0.0 ) { + out.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_sl( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->prev->tail()[1] > j->prev->head()[1] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + +void +Subdivider::classify_headonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at left */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x20 ); + j->setitail(); + + REAL diff = j->prev->tail()[1] - val; + if( diff > 0.0 ) { + out.addarc( j ); + } else if( diff < 0.0 ) { + if( ccwTurn_tl( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else { + if( j->prev->tail()[0] > j->prev->head()[0] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + + +void +Subdivider::classify_tailonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at right, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x12); + + j->clearitail(); + + REAL diff = j->next->head()[0] - val; + if( diff > 0.0 ) { + if( ccwTurn_sr( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + in.addarc( j ); + } else { + if( j->next->tail()[1] > j->next->head()[1] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_tailonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail at right, head on line */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x12); + + j->clearitail(); + + REAL diff = j->next->head()[1] - val; + if( diff > 0.0 ) { + if( ccwTurn_tr( j, j->next ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + in.addarc( j ); + } else { + if( j->next->tail()[0] > j->next->head()[0] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + +void +Subdivider::classify_headonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at right */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 0, val ) == 0x21 ); + + j->setitail(); + + REAL diff = j->prev->tail()[0] - val; + if( diff > 0.0 ) { + if( ccwTurn_sr( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + out.addarc( j ); + } else { + if( j->prev->tail()[1] > j->prev->head()[1] ) + out.addarc( j ); + else + in.addarc( j ); + } + } +} + +void +Subdivider::classify_headonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) +{ + /* tail on line, head at right */ + Arc_ptr j; + + while( (j = bin.removearc()) != NULL ) { + assert( arc_classify( j, 1, val ) == 0x21 ); + + j->setitail(); + + REAL diff = j->prev->tail()[1] - val; + if( diff > 0.0 ) { + if( ccwTurn_tr( j->prev, j ) ) + out.addarc( j ); + else + in.addarc( j ); + } else if( diff < 0.0 ) { + out.addarc( j ); + } else { + if( j->prev->tail()[0] > j->prev->head()[0] ) + in.addarc( j ); + else + out.addarc( j ); + } + } +} + diff --git a/project/jni/glu/src/libnurbs/internals/jarcloc.h b/project/jni/glu/src/libnurbs/internals/jarcloc.h new file mode 100644 index 000000000..5297036fa --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/jarcloc.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +/* + * jarcloc.h + * + */ + +#ifndef __glujarcloc_h_ +#define __glujarcloc_h_ + +#include "arc.h" + +class Jarcloc { +private: + Arc_ptr arc; + TrimVertex *p; + TrimVertex *plast; +public: + inline void init( Arc_ptr a, long first, long last ) { arc = a; p=&a->pwlArc->pts[first]; plast = &a->pwlArc->pts[last]; } + inline TrimVertex * getnextpt( void ); + inline TrimVertex * getprevpt( void ); + inline void reverse(); +}; + +inline void +Jarcloc::reverse() +{ + if( plast == &arc->pwlArc->pts[0] ) + plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + else + plast = &arc->pwlArc->pts[0]; +} + +inline TrimVertex * +Jarcloc::getnextpt() +{ + assert( p <= plast ); + if( p == plast ) { + arc = arc->next; + p = &arc->pwlArc->pts[0]; + plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + assert( p < plast ); + } + return p++; +} + +inline TrimVertex * +Jarcloc::getprevpt() +{ + assert( p >= plast ); + if( p == plast ) { + arc = arc->prev; + p = &arc->pwlArc->pts[arc->pwlArc->npts - 1]; + plast = &arc->pwlArc->pts[0]; + assert( p > plast ); + } + return p--; +} +#endif /* __glujarcloc_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/knotvector.cc b/project/jni/glu/src/libnurbs/internals/knotvector.cc new file mode 100644 index 000000000..a2805f84d --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/knotvector.cc @@ -0,0 +1,132 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * knotvector.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "knotvector.h" +#include "defines.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +void Knotvector::init( long _knotcount, long _stride, long _order, INREAL *_knotlist ) +{ + knotcount = _knotcount; + stride = _stride; + order = _order; + knotlist = new Knot[_knotcount]; + assert( knotlist != 0 ); + + for( int i = 0; i != _knotcount; i++ ) + knotlist[i] = (Knot) _knotlist[i]; +} + +Knotvector::Knotvector( void ) +{ + knotlist = 0; +} + +Knotvector::~Knotvector( void ) +{ + if( knotlist ) delete[] knotlist; +} + +int Knotvector::validate( void ) +{ + /* kindex is used as an array index so subtract one first, + * this propagates throughout the code so study carefully */ + long kindex = knotcount-1; + + if( order < 1 || order > MAXORDER ) { + // spline order un-supported + return( 1 ); + } + + if( knotcount < (2 * order) ) { + // too few knots + return( 2 ); + } + + if( identical( knotlist[kindex-(order-1)], knotlist[order-1]) ) { + // valid knot range is empty + return( 3 ); + } + + for( long i = 0; i < kindex; i++) + if( knotlist[i] > knotlist[i+1] ) { + // decreasing knot sequence + return( 4 ); + } + + /* check for valid multiplicity */ + + /* kindex is currently the index of the last knot. + * In the next loop it is decremented to ignore the last knot + * and the loop stops when kindex is 2 so as to ignore the first + * knot as well. These knots are not used in computing + * knot multiplicities. + */ + + long multi = 1; + for( ; kindex >= 1; kindex-- ) { + if( knotlist[kindex] - knotlist[kindex-1] < TOLERANCE ) { + multi++; + continue; + } + if ( multi > order ) { + // knot multiplicity greater than order of spline + return( 5 ); + } + multi = 1; + } + + if ( multi > order ) { + // knot multiplicity greater than order of spline + return( 5 ); + } + + return 0; +} + +void Knotvector::show( const char *msg ) +{ +} + diff --git a/project/jni/glu/src/libnurbs/internals/knotvector.h b/project/jni/glu/src/libnurbs/internals/knotvector.h new file mode 100644 index 000000000..85b162f6f --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/knotvector.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * knotvector.h + * + */ + +#ifndef __gluknotvector_h_ +#define __gluknotvector_h_ + +#include "types.h" + +struct Knotvector { /* a knot vector */ + Knotvector( void ); + ~Knotvector( void ); + void init( long, long, long, INREAL * ); + int validate( void ); + void show( const char * ); + + long order; /* order of spline */ + long knotcount; /* number of knots */ + long stride; /* bytes between points */ + Knot * knotlist; /* global knot vector */ +}; + +/* tolerance to test knot coincidence */ +#define TOLERANCE 1.0e-5 + +inline int +identical( Knot x, Knot y ) +{ + return ((x-y) < TOLERANCE) ? 1 : 0; +} +#endif /* __gluknotvector_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mapdesc.cc b/project/jni/glu/src/libnurbs/internals/mapdesc.cc new file mode 100644 index 000000000..9d5d7d085 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mapdesc.cc @@ -0,0 +1,841 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mapdesc.c++ + * + */ + +#include +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mystring.h" +#include "mymath.h" +#include "backend.h" +#include "nurbsconsts.h" +#include "mapdesc.h" + +Mapdesc::Mapdesc( long _type, int _israt, int _ncoords, Backend& b ) + : backend( b ) +{ + type = _type; + isrational = _israt; + ncoords = _ncoords; + hcoords = _ncoords + (_israt ? 0 : 1 ); + inhcoords = _ncoords - (_israt ? 1 : 0 ); + mask = ((1<<(inhcoords*2))-1); + next = 0; + + assert( hcoords <= MAXCOORDS ); + assert( inhcoords >= 1 ); + + pixel_tolerance = 1.0; + error_tolerance = 1.0; + bbox_subdividing = N_NOBBOXSUBDIVISION; + culling_method = N_NOCULLING; + sampling_method = N_NOSAMPLING; + clampfactor = N_NOCLAMPING; + minsavings = N_NOSAVINGSSUBDIVISION; + s_steps = 0.0; + t_steps = 0.0; + maxrate = ( s_steps < 0.0f ) ? 0.0f : s_steps; + maxsrate = ( s_steps < 0.0f ) ? 0.0f : s_steps; + maxtrate = ( t_steps < 0.0f ) ? 0.0f : t_steps; + identify( bmat ); + identify( cmat ); + identify( smat ); + for( int i = 0; i != inhcoords; i++ ) + bboxsize[i] = 1.0; +} + +void +Mapdesc::setBboxsize( INREAL *mat ) +{ + for( int i = 0; i != inhcoords; i++ ) + bboxsize[i] = (REAL) mat[i]; +} + +void +Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] ) +{ + memset( dest, 0, sizeof( dest ) ); + for( int i=0; i != hcoords; i++ ) + dest[i][i] = 1.0; +} + +void +Mapdesc::surfbbox( REAL bb[2][MAXCOORDS] ) +{ + backend.surfbbox( type, bb[0], bb[1] ); +} + +void +Mapdesc::copy( REAL dest[MAXCOORDS][MAXCOORDS], long n, INREAL *src, + long rstride, long cstride ) +{ + assert( n >= 0 ); + for( int i=0; i != n; i++ ) + for( int j=0; j != n; j++ ) + dest[i][j] = src[i*rstride + j*cstride]; +} + +/*-------------------------------------------------------------------------- + * copyPt - copy a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::copyPt( REAL *d, REAL *s ) +{ + assert( hcoords > 0 ); + switch( hcoords ) { + case 4: + d[3] = s[3]; + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + case 3: + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + case 2: + d[1] = s[1]; + d[0] = s[0]; + break; + case 1: + d[0] = s[0]; + break; + case 5: + d[4] = s[4]; + d[3] = s[3]; + d[2] = s[2]; + d[1] = s[1]; + d[0] = s[0]; + break; + default: + memcpy( d, s, hcoords * sizeof( REAL ) ); + break; + } +} + +/*-------------------------------------------------------------------------- + * sumPt - compute affine combination of two homogeneous points + *-------------------------------------------------------------------------- + */ +void +Mapdesc::sumPt( REAL *dst, REAL *src1, REAL *src2, register REAL alpha, register REAL beta ) +{ + assert( hcoords > 0 ); + switch( hcoords ) { + case 4: + dst[3] = src1[3] * alpha + src2[3] * beta; + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 3: + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 2: + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 1: + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + case 5: + dst[4] = src1[4] * alpha + src2[4] * beta; + dst[3] = src1[3] * alpha + src2[3] * beta; + dst[2] = src1[2] * alpha + src2[2] * beta; + dst[1] = src1[1] * alpha + src2[1] * beta; + dst[0] = src1[0] * alpha + src2[0] * beta; + break; + default: { + for( int i = 0; i != hcoords; i++ ) + dst[i] = src1[i] * alpha + src2[i] * beta; + } + break; + } +} + +/*-------------------------------------------------------------------------- + * clipbits - compute bit-vector indicating point/window position + * of a (transformed) homogeneous point + *-------------------------------------------------------------------------- + */ +unsigned int +Mapdesc::clipbits( REAL *p ) +{ + assert( inhcoords >= 0 ); + assert( inhcoords <= 3 ); + + register int nc = inhcoords; + register REAL pw = p[nc]; + register REAL nw = -pw; + register unsigned int bits = 0; + + if( pw == 0.0 ) return mask; + + if( pw > 0.0 ) { + switch( nc ) { + case 3: + if( p[2] <= pw ) bits |= (1<<5); + if( p[2] >= nw ) bits |= (1<<4); + if( p[1] <= pw ) bits |= (1<<3); + if( p[1] >= nw ) bits |= (1<<2); + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + case 2: + if( p[1] <= pw ) bits |= (1<<3); + if( p[1] >= nw ) bits |= (1<<2); + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + case 1: + if( p[0] <= pw ) bits |= (1<<1); + if( p[0] >= nw ) bits |= (1<<0); + return bits; + default: { + int bit = 1; + for( int i=0; i= nw ) bits |= bit; + bit <<= 1; + if( p[i] <= pw ) bits |= bit; + bit <<= 1; + } + abort(); + break; + } + } + } else { + switch( nc ) { + case 3: + if( p[2] <= nw ) bits |= (1<<5); + if( p[2] >= pw ) bits |= (1<<4); + if( p[1] <= nw ) bits |= (1<<3); + if( p[1] >= pw ) bits |= (1<<2); + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + case 2: + if( p[1] <= nw ) bits |= (1<<3); + if( p[1] >= pw ) bits |= (1<<2); + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + case 1: + if( p[0] <= nw ) bits |= (1<<1); + if( p[0] >= pw ) bits |= (1<<0); + return bits; + default: { + int bit = 1; + for( int i=0; i= pw ) bits |= bit; + bit <<= 1; + if( p[i] <= nw ) bits |= bit; + bit <<= 1; + } + abort(); + break; + } + } + } + return bits; +} + +/*-------------------------------------------------------------------------- + * xformRational - transform a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformRational( Maxmatrix mat, REAL *d, REAL *s ) +{ + assert( hcoords >= 0 ); + + if( hcoords == 3 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]; + } else if( hcoords == 4 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + REAL w = s[3]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+w*mat[3][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+w*mat[3][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+w*mat[3][2]; + d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+w*mat[3][3]; + } else { + for( int i=0; i != hcoords; i++ ) { + d[i] = 0; + for( int j = 0; j != hcoords; j++ ) + d[i] += s[j] * mat[j][i]; + } + } +} + +/*-------------------------------------------------------------------------- + * xformNonrational - transform a inhomogeneous point to a homogeneous point + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformNonrational( Maxmatrix mat, REAL *d, REAL *s ) +{ + if( inhcoords == 2 ) { + REAL x = s[0]; + REAL y = s[1]; + d[0] = x*mat[0][0]+y*mat[1][0]+mat[2][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+mat[2][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+mat[2][2]; + } else if( inhcoords == 3 ) { + REAL x = s[0]; + REAL y = s[1]; + REAL z = s[2]; + d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+mat[3][0]; + d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+mat[3][1]; + d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+mat[3][2]; + d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+mat[3][3]; + } else { + assert( inhcoords >= 0 ); + for( int i=0; i != hcoords; i++ ) { + d[i] = mat[inhcoords][i]; + for( int j = 0; j < inhcoords; j++ ) + d[i] += s[j] * mat[j][i]; + } + } +} + +/*-------------------------------------------------------------------------- + * xformAndCullCheck - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description and + * check if they are either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::xformAndCullCheck( + REAL *pts, int uorder, int ustride, int vorder, int vstride ) +{ + assert( uorder > 0 ); + assert( vorder > 0 ); + + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) { + REAL *q = p; + for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) { + REAL cpts[MAXCOORDS]; + xformCulling( cpts, q ); + unsigned int bits = clipbits( cpts ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * cullCheck - check if a set of homogeneous transformed points are + * either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::cullCheck( REAL *pts, int uorder, int ustride, int vorder, int vstride ) +{ + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) { + REAL *q = p; + for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) { + unsigned int bits = clipbits( q ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * cullCheck - check if a set of homogeneous transformed points are + * either completely inside, completely outside, + * or intersecting the viewing frustrum. + *-------------------------------------------------------------------------- + */ +int +Mapdesc::cullCheck( REAL *pts, int order, int stride ) +{ + unsigned int inbits = mask; + unsigned int outbits = 0; + + REAL *p = pts; + for( REAL *pend = p + order * stride; p != pend; p += stride ) { + unsigned int bits = clipbits( p ); + outbits |= bits; + inbits &= bits; + if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT; + } + + if( outbits != (unsigned int)mask ) { + return CULL_TRIVIAL_REJECT; + } else if( inbits == (unsigned int)mask ) { + return CULL_TRIVIAL_ACCEPT; + } else { + return CULL_ACCEPT; + } +} + +/*-------------------------------------------------------------------------- + * xformSampling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into sampling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformSampling( REAL *pts, int order, int stride, REAL *sp, int outstride ) +{ + xformMat( smat, pts, order, stride, sp, outstride ); +} + +void +Mapdesc::xformBounding( REAL *pts, int order, int stride, REAL *sp, int outstride ) +{ + xformMat( bmat, pts, order, stride, sp, outstride ); +} + +/*-------------------------------------------------------------------------- + * xformCulling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into culling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformCulling( REAL *pts, int order, int stride, REAL *cp, int outstride ) +{ + xformMat( cmat, pts, order, stride, cp, outstride ); +} + +/*-------------------------------------------------------------------------- + * xformCulling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into culling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformCulling( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *cp, int outustride, int outvstride ) +{ + xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride ); +} + +/*-------------------------------------------------------------------------- + * xformSampling - transform a set of points that may be EITHER + * homogeneous or inhomogeneous depending on the map description + * into sampling space + *-------------------------------------------------------------------------- + */ +void +Mapdesc::xformSampling( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *sp, int outustride, int outvstride ) +{ + xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride ); +} + +void +Mapdesc::xformBounding( REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *sp, int outustride, int outvstride ) +{ + xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride ); +} + +void +Mapdesc::xformMat( + Maxmatrix mat, + REAL * pts, + int order, + int stride, + REAL * cp, + int outstride ) +{ + if( isrational ) { + REAL *pend = pts + order * stride; + for( REAL *p = pts ; p != pend; p += stride ) { + xformRational( mat, cp, p ); + cp += outstride; + } + } else { + REAL *pend = pts + order * stride; + for( REAL *p = pts ; p != pend; p += stride ) { + xformNonrational( mat, cp, p ); + cp += outstride; + } + } +} + +void +Mapdesc::xformMat( Maxmatrix mat, REAL *pts, + int uorder, int ustride, + int vorder, int vstride, + REAL *cp, int outustride, int outvstride ) +{ + if( isrational ) { + REAL *pend = pts + uorder * ustride; + for( REAL *p = pts ; p != pend; p += ustride ) { + REAL *cpts2 = cp; + REAL *qend = p + vorder * vstride; + for( REAL *q = p; q != qend; q += vstride ) { + xformRational( mat, cpts2, q ); + cpts2 += outvstride; + } + cp += outustride; + } + } else { + REAL *pend = pts + uorder * ustride; + for( REAL *p = pts ; p != pend; p += ustride ) { + REAL *cpts2 = cp; + REAL *qend = p + vorder * vstride; + for( REAL *q = p; q != qend; q += vstride ) { + xformNonrational( mat, cpts2, q ); + cpts2 += outvstride; + } + cp += outustride; + } + } +} + +/*-------------------------------------------------------------------------- + * subdivide - subdivide a curve along an isoparametric line + *-------------------------------------------------------------------------- + */ + +void +Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, int stride, int order ) +{ + REAL mv = 1.0f - v; + + for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) { + copyPt( dst, src ); + REAL *qpnt = src + stride; + for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride ) + sumPt( qp, qp, qpnt, mv, v ); + } +} + +/*-------------------------------------------------------------------------- + * subdivide - subdivide a patch along an isoparametric line + *-------------------------------------------------------------------------- + */ + +void +Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, + int so, int ss, int to, int ts ) +{ + REAL mv = 1.0f - v; + + for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) { + REAL *sp = src; + REAL *dp = dst; + for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) { + copyPt( dp, sp ); + REAL *qp = sp; + for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts ) + sumPt( qp, qp, qpnt, mv, v ); + } + } +} + + +#define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0)) + +/*-------------------------------------------------------------------------- + * project - project a set of homogeneous coordinates into inhomogeneous ones + *-------------------------------------------------------------------------- + */ +int +Mapdesc::project( REAL *src, int rstride, int cstride, + REAL *dest, int trstride, int tcstride, + int nrows, int ncols ) +{ + int s = sign( src[inhcoords] ); + REAL *rlast = src + nrows * rstride; + REAL *trptr = dest; + for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) { + REAL *clast = rptr + ncols * cstride; + REAL *tcptr = trptr; + for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) { + REAL *coordlast = cptr + inhcoords; + if( sign( *coordlast ) != s ) return 0; + REAL *tcoord = tcptr; + for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) { + *tcoord = *coord / *coordlast; + } + } + } + return 1; +} + +/*-------------------------------------------------------------------------- + * project - project a set of homogeneous coordinates into inhomogeneous ones + *-------------------------------------------------------------------------- + */ +int +Mapdesc::project( REAL *src, int stride, REAL *dest, int tstride, int ncols ) +{ + int s = sign( src[inhcoords] ); + + REAL *clast = src + ncols * stride; + for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) { + REAL *coordlast = cptr + inhcoords; + if( sign( *coordlast ) != s ) return 0; + for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ ) + *tcoord = *coord / *coordlast; + } + + return 1; +} + +int +Mapdesc::bboxTooBig( + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols, + REAL bb[2][MAXCOORDS] ) +{ + REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS]; + const int trstride = sizeof(bbpts[0]) / sizeof(REAL); + const int tcstride = sizeof(bbpts[0][0]) / sizeof(REAL); + + // points have been transformed, therefore they are homogeneous + // project points + int val = project( p, rstride, cstride, + &bbpts[0][0][0], trstride, tcstride, nrows, ncols ); + if( val == 0 ) return -1; + + // compute bounding box + bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols ); + + // find out if bounding box can't fit in unit cube + if( bbox_subdividing == N_BBOXROUND ) { + for( int k=0; k != inhcoords; k++ ) + if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] ) return 1; + } else { + for( int k=0; k != inhcoords; k++ ) + if( bb[1][k] - bb[0][k] > bboxsize[k] ) return 1; + } + return 0; +} + +void +Mapdesc::bbox( + REAL bb[2][MAXCOORDS], + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols ) +{ + int k; + for( k=0; k != inhcoords; k++ ) + bb[0][k] = bb[1][k] = p[k]; + + for( int i=0; i != nrows; i++ ) + for( int j=0; j != ncols; j++ ) + for( k=0; k != inhcoords; k++ ) { + REAL x = p[i*rstride + j*cstride + k]; + if( x < bb[0][k] ) bb[0][k] = x; + else if( x > bb[1][k] ) bb[1][k] = x; + } +} + +/*-------------------------------------------------------------------------- + * calcVelocityRational - calculate upper bound on first partial derivative + * of a homogeneous set of points and bounds on each row of points. + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcVelocityRational( REAL *p, int stride, int ncols ) +{ + REAL tmp[MAXORDER][MAXCOORDS]; + + assert( ncols <= MAXORDER ); + + const int tstride = sizeof(tmp[0]) / sizeof(REAL); + + if( project( p, stride, &tmp[0][0], tstride, ncols ) ) { + return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 ); + } else { /* XXX */ + return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 ); + } +} + +/*-------------------------------------------------------------------------- + * calcVelocityNonrational - calculate upper bound on first partial + * derivative of a inhomogeneous set of points. + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcVelocityNonrational( REAL *pts, int stride, int ncols ) +{ + return calcPartialVelocity( pts, stride, ncols, 1, 1.0 ); +} + +int +Mapdesc::isProperty( long property ) +{ + switch ( property ) { + case N_PIXEL_TOLERANCE: + case N_ERROR_TOLERANCE: + case N_CULLING: + case N_BBOX_SUBDIVIDING: + case N_S_STEPS: + case N_T_STEPS: + case N_SAMPLINGMETHOD: + case N_CLAMPFACTOR: + case N_MINSAVINGS: + return 1; + default: + return 0; + } +} + +REAL +Mapdesc::getProperty( long property ) +{ + switch ( property ) { + case N_PIXEL_TOLERANCE: + return pixel_tolerance; + case N_ERROR_TOLERANCE: + return error_tolerance; + case N_CULLING: + return culling_method; + case N_BBOX_SUBDIVIDING: + return bbox_subdividing; + case N_S_STEPS: + return s_steps; + case N_T_STEPS: + return t_steps; + case N_SAMPLINGMETHOD: + return sampling_method; + case N_CLAMPFACTOR: + return clampfactor; + case N_MINSAVINGS: + return minsavings; + default: + abort(); + return -1; //not necessary, needed to shut up compiler + } +} + +void +Mapdesc::setProperty( long property, REAL value ) +{ + + switch ( property ) { + case N_PIXEL_TOLERANCE: + pixel_tolerance = value; + break; + case N_ERROR_TOLERANCE: + error_tolerance = value; + break; + case N_CULLING: + culling_method = value; + break; + case N_BBOX_SUBDIVIDING: + if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION; + bbox_subdividing = value; + break; + case N_S_STEPS: + if( value < 0.0f ) value = 0.0f; + s_steps = value; + maxrate = ( value < 0.0f ) ? 0.0f : value; + maxsrate = ( value < 0.0f ) ? 0.0f : value; + break; + case N_T_STEPS: + if( value < 0.0f ) value = 0.0f; + t_steps = value; + maxtrate = ( value < 0.0f ) ? 0.0f : value; + break; + case N_SAMPLINGMETHOD: + sampling_method = value; + break; + case N_CLAMPFACTOR: + if( value <= 0.0 ) value = N_NOCLAMPING; + clampfactor = value; + break; + case N_MINSAVINGS: + if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION; + minsavings = value; + break; + default: + abort(); + break; + } +} + diff --git a/project/jni/glu/src/libnurbs/internals/mapdesc.h b/project/jni/glu/src/libnurbs/internals/mapdesc.h new file mode 100644 index 000000000..6f06154f9 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mapdesc.h @@ -0,0 +1,271 @@ +/* + * 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. + */ + +/* + * mapdesc.h + * + */ + +#ifndef __glumapdesc_h_ +#define __glumapdesc_h_ + +#include "mystdio.h" +#include "types.h" +#include "defines.h" +#include "bufpool.h" +#include "nurbsconsts.h" + +typedef REAL Maxmatrix[MAXCOORDS][MAXCOORDS]; + +class Backend; + +class Mapdesc : public PooledObj { + friend class Maplist; + +public: + Mapdesc( long, int, int, Backend & ); + int isProperty( long ); + REAL getProperty( long ); + void setProperty( long, REAL ); + int isConstantSampling( void ); + int isDomainSampling( void ); + int isRangeSampling( void ); + int isSampling( void ); + int isParametricDistanceSampling( void ); + int isObjectSpaceParaSampling( void ); + int isObjectSpacePathSampling( void ); + int isSurfaceAreaSampling( void ); + int isPathLengthSampling( void ); + int isCulling( void ); + int isBboxSubdividing( void ); + long getType( void ); + + /* curve routines */ + void subdivide( REAL *, REAL *, REAL, int, int ); + int cullCheck( REAL *, int, int ); + void xformBounding( REAL *, int, int, REAL *, int ); + void xformCulling( REAL *, int, int, REAL *, int ); + void xformSampling( REAL *, int, int, REAL *, int ); + void xformMat( Maxmatrix, REAL *, int, int, REAL *, int ); + REAL calcPartialVelocity ( REAL *, int, int, int, REAL ); + int project( REAL *, int, REAL *, int, int ); + REAL calcVelocityRational( REAL *, int, int ); + REAL calcVelocityNonrational( REAL *, int, int ); + + /* surface routines */ + void subdivide( REAL *, REAL *, REAL, int, int, int, int ); + int cullCheck( REAL *, int, int, int, int ); + void xformBounding( REAL *, int, int, int, int, REAL *, int, int ); + void xformCulling( REAL *, int, int, int, int, REAL *, int, int ); + void xformSampling( REAL *, int, int, int, int, REAL *, int, int ); + void xformMat( Maxmatrix, REAL *, int, int, int, int, REAL *, int, int ); + REAL calcPartialVelocity ( REAL *, REAL *, int, int, int, int, int, int, REAL, REAL, int ); + int project( REAL *, int, int, REAL *, int, int, int, int); + void surfbbox( REAL bb[2][MAXCOORDS] ); + + int bboxTooBig( REAL *, int, int, int, int, REAL [2][MAXCOORDS] ); + int xformAndCullCheck( REAL *, int, int, int, int ); + + void identify( REAL[MAXCOORDS][MAXCOORDS] ); + void setBboxsize( INREAL *); + inline void setBmat( INREAL*, long, long ); + inline void setCmat( INREAL*, long, long ); + inline void setSmat( INREAL*, long, long ); + inline int isRational( void ); + inline int getNcoords( void ); + + REAL pixel_tolerance; /* pathlength sampling tolerance */ + REAL error_tolerance; /* parametric error sampling tolerance*/ + REAL object_space_error_tolerance; /* object space tess*/ + REAL clampfactor; + REAL minsavings; + REAL maxrate; + REAL maxsrate; + REAL maxtrate; + REAL bboxsize[MAXCOORDS]; + +private: + long type; + int isrational; + int ncoords; + int hcoords; + int inhcoords; + int mask; + Maxmatrix bmat; + Maxmatrix cmat; + Maxmatrix smat; + REAL s_steps; /* max samples in s direction */ + REAL t_steps; /* max samples in t direction */ + REAL sampling_method; + REAL culling_method; /* check for culling */ + REAL bbox_subdividing; + Mapdesc * next; + Backend & backend; + + void bbox( REAL [2][MAXCOORDS], REAL *, int, int, int, int ); + REAL maxDifference( int, REAL *, int ); + static void copy( Maxmatrix, long, INREAL *, long, long ); + + /* individual control point routines */ + static void transform4d( float[4], float[4], float[4][4] ); + static void multmatrix4d ( float[4][4], const float[4][4], + const float[4][4] ); + void copyPt( REAL *, REAL * ); + void sumPt( REAL *, REAL *, REAL *, REAL, REAL ); + void xformSampling( REAL *, REAL * ); + void xformCulling( REAL *, REAL * ); + void xformRational( Maxmatrix, REAL *, REAL * ); + void xformNonrational( Maxmatrix, REAL *, REAL * ); + unsigned int clipbits( REAL * ); +}; + +inline void +Mapdesc::setBmat( INREAL *mat, long rstride, long cstride ) +{ + copy( bmat, hcoords, mat, rstride, cstride ); +} + +inline void +Mapdesc::setCmat( INREAL *mat, long rstride, long cstride ) +{ + copy( cmat, hcoords, mat, rstride, cstride ); +} + +inline void +Mapdesc::setSmat( INREAL *mat, long rstride, long cstride ) +{ + copy( smat, hcoords, mat, rstride, cstride ); +} + +inline long +Mapdesc::getType( void ) +{ + return type; +} + +inline void +Mapdesc::xformCulling( REAL *d, REAL *s ) +{ + if( isrational ) + xformRational( cmat, d, s ); + else + xformNonrational( cmat, d, s ); +} + +inline void +Mapdesc::xformSampling( REAL *d, REAL *s ) +{ + if( isrational ) + xformRational( smat, d, s ); + else + xformNonrational( smat, d, s ); +} + +inline int +Mapdesc::isRational( void ) +{ + return isrational ? 1 : 0; +} + +inline int +Mapdesc::getNcoords( void ) +{ + return ncoords; +} + +inline int +Mapdesc::isConstantSampling( void ) +{ + return ((sampling_method == N_FIXEDRATE) ? 1 : 0); +} + +inline int +Mapdesc::isDomainSampling( void ) +{ + return ((sampling_method == N_DOMAINDISTANCE) ? 1 : 0); +} + +inline int +Mapdesc::isParametricDistanceSampling( void ) +{ + return ((sampling_method == N_PARAMETRICDISTANCE) ? 1 : 0); +} + +inline int +Mapdesc::isObjectSpaceParaSampling( void ) +{ + return ((sampling_method == N_OBJECTSPACE_PARA) ? 1 : 0); +} + +inline int +Mapdesc::isObjectSpacePathSampling( void ) +{ + return ((sampling_method == N_OBJECTSPACE_PATH) ? 1 : 0); +} + +inline int +Mapdesc::isSurfaceAreaSampling( void ) +{ + return ((sampling_method == N_SURFACEAREA) ? 1 : 0); +} + +inline int +Mapdesc::isPathLengthSampling( void ) +{ + return ((sampling_method == N_PATHLENGTH) ? 1 : 0); +} + +inline int +Mapdesc::isRangeSampling( void ) +{ + return ( isParametricDistanceSampling() || isPathLengthSampling() || + isSurfaceAreaSampling() || + isObjectSpaceParaSampling() || + isObjectSpacePathSampling()); +} + +inline int +Mapdesc::isSampling( void ) +{ + return isRangeSampling() || isConstantSampling() || isDomainSampling(); +} + +inline int +Mapdesc::isCulling( void ) +{ + return ((culling_method != N_NOCULLING) ? 1 : 0); +} + +inline int +Mapdesc::isBboxSubdividing( void ) +{ + return ((bbox_subdividing != N_NOBBOXSUBDIVISION) ? 1 : 0); +} +#endif /* __glumapdesc_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mapdescv.cc b/project/jni/glu/src/libnurbs/internals/mapdescv.cc new file mode 100644 index 000000000..d7748f185 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mapdescv.cc @@ -0,0 +1,243 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mapdescv.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mystring.h" +#include "mymath.h" +#include "nurbsconsts.h" +#include "mapdesc.h" + +/*-------------------------------------------------------------------------- + * calcPartialVelocity - calculate maximum magnitude of a given partial + * derivative + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcPartialVelocity ( + REAL *p, + int stride, + int ncols, + int partial, + REAL range ) +{ + REAL tmp[MAXORDER][MAXCOORDS]; + REAL mag[MAXORDER]; + + assert( ncols <= MAXORDER ); + + int j, k, t; + // copy inhomogeneous control points into temporary array + for( j=0; j != ncols; j++ ) + for( k=0; k != inhcoords; k++ ) + tmp[j][k] = p[j*stride + k]; + + for( t=0; t != partial; t++ ) + for( j=0; j != ncols-t-1; j++ ) + for( k=0; k != inhcoords; k++ ) + tmp[j][k] = tmp[j+1][k] - tmp[j][k]; + + // compute magnitude and store in mag array + for( j=0; j != ncols-partial; j++ ) { + mag[j] = 0.0; + for( k=0; k != inhcoords; k++ ) + mag[j] += tmp[j][k] * tmp[j][k]; + } + + // compute scale factor + REAL fac = 1.0f; + REAL invt = 1.0f / range; + for( t = ncols-1; t != ncols-1-partial; t-- ) + fac *= t * invt; + + // compute max magnitude of all entries in array + REAL max = 0.0; + for( j=0; j != ncols-partial; j++ ) + if( mag[j] > max ) max = mag[j]; + max = fac * sqrtf( (float) max ); + + return max; +} + +/*-------------------------------------------------------------------------- + * calcPartialVelocity - calculate maximum magnitude of a given partial + * derivative + *-------------------------------------------------------------------------- + */ +REAL +Mapdesc::calcPartialVelocity ( + REAL *dist, + REAL *p, + int rstride, + int cstride, + int nrows, + int ncols, + int spartial, + int tpartial, + REAL srange, + REAL trange, + int side ) +{ + REAL tmp[MAXORDER][MAXORDER][MAXCOORDS]; + REAL mag[MAXORDER][MAXORDER]; + + assert( nrows <= MAXORDER ); + assert( ncols <= MAXORDER ); + + REAL *tp = &tmp[0][0][0]; + REAL *mp = &mag[0][0]; + const int istride = sizeof( tmp[0]) / sizeof( tmp[0][0][0] ); + const int jstride = sizeof( tmp[0][0]) / sizeof( tmp[0][0][0] ); + /* + const int kstride = sizeof( tmp[0][0][0]) / sizeof( tmp[0][0][0] ); + */ + const int mistride = sizeof( mag[0]) / sizeof( mag[0][0] ); + const int mjstride = sizeof( mag[0][0]) / sizeof( mag[0][0] ); + const int idist = nrows * istride; + const int jdist = ncols * jstride; + /* + const int kdist = inhcoords * kstride; + */ + const int id = idist - spartial * istride; + const int jd = jdist - tpartial * jstride; + + { + // copy control points + REAL *ti = tp; + REAL *qi = p; + REAL *til = tp + idist; + for( ; ti != til; ) { + REAL *tj = ti; + REAL *qj = qi; + REAL *tjl = ti + jdist; + for( ; tj != tjl; ) { + for( int k=0; k != inhcoords; k++ ) { + tj[k] = qj[k]; + } + tj += jstride; + qj += cstride; + } + ti += istride; + qi += rstride; + } + } + + { + // compute (s)-partial derivative control points + REAL *til = tp + idist - istride; + const REAL *till = til - ( spartial * istride ); + for( ; til != till; til -= istride ) + for( REAL *ti = tp; ti != til; ti += istride ) + for( REAL *tj = ti, *tjl = tj + jdist; tj != tjl; tj += jstride ) + for( int k=0; k != inhcoords; k++ ) + tj[k] = tj[k+istride] - tj[k]; + } + + { + // compute (s,t)-partial derivative control points + REAL *tjl = tp + jdist - jstride; + const REAL *tjll = tjl - ( tpartial * jstride ); + for( ; tjl != tjll; tjl -= jstride ) + for( REAL *tj = tp; tj != tjl; tj += jstride ) + for( REAL *ti = tj, *til = ti + id; ti != til; ti += istride ) + for( int k=0; k != inhcoords; k++ ) + ti[k] = ti[k+jstride] - ti[k]; + + } + + REAL max = 0.0; + { + // compute magnitude and store in mag array + memset( (void *) mp, 0, sizeof( mag ) ); + for( REAL *ti = tp, *mi = mp, *til = tp + id; ti != til; ti += istride, mi += mistride ) + for( REAL *tj = ti, *mj = mi, *tjl = ti + jd; tj != tjl; tj += jstride, mj += mjstride ) { + for( int k=0; k != inhcoords; k++ ) + *mj += tj[k] * tj[k]; + if( *mj > max ) max = *mj; + } + + } + + int i, j; + + // compute scale factor + REAL fac = 1.0f; + { + REAL invs = 1.0f / srange; + REAL invt = 1.0f / trange; + for( int s = nrows-1, slast = s-spartial; s != slast; s-- ) + fac *= s * invs; + for( int t = ncols-1, tlast = t-tpartial; t != tlast; t-- ) + fac *= t * invt; + } + + if( side == 0 ) { + // compute max magnitude of first and last column + dist[0] = 0.0; + dist[1] = 0.0; + for( i=0; i != nrows-spartial; i++ ) { + j = 0; + if( mag[i][j] > dist[0] ) dist[0] = mag[i][j]; + + j = ncols-tpartial-1; + if( mag[i][j] > dist[1] ) dist[1] = mag[i][j]; + } + dist[0] = fac * sqrtf( dist[0] ); + dist[1] = fac * sqrtf( dist[1] ); + } else if( side == 1 ) { + // compute max magnitude of first and last row + dist[0] = 0.0; + dist[1] = 0.0; + for( j=0; j != ncols-tpartial; j++ ) { + i = 0; + if( mag[i][j] > dist[0] ) dist[0] = mag[i][j]; + + i = nrows-spartial-1; + if( mag[i][j] > dist[1] ) dist[1] = mag[i][j]; + } + dist[0] = fac * sqrtf( dist[0] ); + dist[1] = fac * sqrtf( dist[1] ); + } + + max = fac * sqrtf( (float) max ); + + return max; +} + diff --git a/project/jni/glu/src/libnurbs/internals/maplist.cc b/project/jni/glu/src/libnurbs/internals/maplist.cc new file mode 100644 index 000000000..6421bac12 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/maplist.cc @@ -0,0 +1,113 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * maplist.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mymath.h" +#include "nurbsconsts.h" +#include "maplist.h" +#include "mapdesc.h" +#include "backend.h" + +Maplist::Maplist( Backend& b ) + : mapdescPool( sizeof( Mapdesc ), 10, "mapdesc pool" ), + backend( b ) +{ + maps = 0; lastmap = &maps; +} + +void +Maplist::initialize( void ) +{ + freeMaps(); + define( N_P2D, 0, 2 ); + define( N_P2DR, 1, 3 ); +} + +void +Maplist::add( long type, int israt, int ncoords ) +{ + *lastmap = new(mapdescPool) Mapdesc( type, israt, ncoords, backend ); + lastmap = &((*lastmap)->next); +} + +void +Maplist::define( long type, int israt, int ncoords ) +{ + add( type, israt, ncoords ); +} + +void +Maplist::remove( Mapdesc *m ) +{ + for( Mapdesc **curmap = &maps; *curmap; curmap = &((*curmap)->next) ) { + if( *curmap == m ) { + *curmap = m->next; + m->deleteMe( mapdescPool ); + return; + } + } + abort(); +} + +void +Maplist::freeMaps( void ) +{ + mapdescPool.clear(); + maps = 0; + lastmap = &maps; +} + +Mapdesc * +Maplist::find( long type ) +{ + Mapdesc *val = locate( type ); + assert( val != 0 ); + return val; +} + +Mapdesc * +Maplist::locate( long type ) +{ + Mapdesc *m; + for( m = maps; m; m = m->next ) + if( m->getType() == type ) break; + return m; +} diff --git a/project/jni/glu/src/libnurbs/internals/maplist.h b/project/jni/glu/src/libnurbs/internals/maplist.h new file mode 100644 index 000000000..49720e49b --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/maplist.h @@ -0,0 +1,81 @@ +/* + * 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. + */ + +/* + * maplist.h + * + */ + +#ifndef __glumaplist_h_ +#define __glumaplist_h_ + +#include "types.h" +#include "defines.h" +#include "bufpool.h" + +class Backend; +class Mapdesc; + +class Maplist { +public: + Maplist( Backend & ); + void define( long, int, int ); + inline void undefine( long ); + inline int isMap( long ); + + void initialize( void ); + Mapdesc * find( long ); + Mapdesc * locate( long ); + +private: + Pool mapdescPool; + Mapdesc * maps; + Mapdesc ** lastmap; + Backend & backend; + + void add( long, int, int ); + void remove( Mapdesc * ); + void freeMaps( void ); +}; + +inline int +Maplist::isMap( long type ) +{ + return (locate( type ) ? 1 : 0); +} + +inline void +Maplist::undefine( long type ) +{ + Mapdesc *m = locate( type ); + assert( m != 0 ); + remove( m ); +} +#endif /* __glumaplist_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mesher.cc b/project/jni/glu/src/libnurbs/internals/mesher.cc new file mode 100644 index 000000000..8473b8db8 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mesher.cc @@ -0,0 +1,483 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * mesher.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "gridvertex.h" +#include "gridtrimvertex.h" +#include "jarcloc.h" +#include "gridline.h" +#include "trimline.h" +#include "uarray.h" +#include "backend.h" +#include "mesher.h" + +#include + +const float Mesher::ZERO = 0.0; + +Mesher::Mesher( Backend& b ) + : backend( b ), + p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" ) +{ + stacksize = 0; + vdata = 0; + lastedge = 0; //needed to prevent purify UMR +} + +Mesher::~Mesher( void ) +{ + if( vdata ) delete[] vdata; +} + +void +Mesher::init( unsigned int npts ) +{ + p.clear(); + if( stacksize < npts ) { + stacksize = 2 * npts; + if( vdata ) delete[] vdata; + vdata = new GridTrimVertex_p[stacksize]; + } +} + +inline void +Mesher::push( GridTrimVertex *gt ) +{ + assert( itop+1 != (int)stacksize ); + vdata[++itop] = gt; +} + +inline void +Mesher::pop( long ) +{ +} + +inline void Mesher::openMesh() +{ + backend.bgntmesh("addedge"); +} + +inline void Mesher::closeMesh() +{ + backend.endtmesh(); +} + +inline void Mesher::swapMesh() +{ + backend.swaptmesh(); +} + +inline void Mesher::clearStack() +{ + itop = -1; + last[0] = 0; +} + +void +Mesher::finishLower( GridTrimVertex *gtlower ) +{ + for( push(gtlower); + nextlower( gtlower=new(p) GridTrimVertex ); + push(gtlower) ) + addLower(); + addLast(); +} + +void +Mesher::finishUpper( GridTrimVertex *gtupper ) +{ + for( push(gtupper); + nextupper( gtupper=new(p) GridTrimVertex ); + push(gtupper) ) + addUpper(); + addLast(); +} + +void +Mesher::mesh( void ) +{ + GridTrimVertex *gtlower, *gtupper; + + Hull::init( ); + nextupper( gtupper = new(p) GridTrimVertex ); + nextlower( gtlower = new(p) GridTrimVertex ); + + clearStack(); + openMesh(); + push(gtupper); + + nextupper( gtupper = new(p) GridTrimVertex ); + nextlower( gtlower ); + + assert( gtupper->t && gtlower->t ); + + if( gtupper->t->param[0] < gtlower->t->param[0] ) { + push(gtupper); + lastedge = 1; + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { + push(gtlower); + lastedge = 0; + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } else { + if( lastedge == 0 ) { + push(gtupper); + lastedge = 1; + if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) { + finishLower(gtlower); + return; + } + } else { + push(gtlower); + lastedge = 0; + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } + } + + while ( 1 ) { + if( gtupper->t->param[0] < gtlower->t->param[0] ) { + push(gtupper); + addUpper(); + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { + push(gtlower); + addLower(); + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } else { + if( lastedge == 0 ) { + push(gtupper); + addUpper(); + if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { + finishLower(gtlower); + return; + } + } else { + push(gtlower); + addLower(); + if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { + finishUpper(gtupper); + return; + } + } + } + } +} + +inline int +Mesher::isCcw( int ilast ) +{ + REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); + return (area < ZERO) ? 0 : 1; +} + +inline int +Mesher::isCw( int ilast ) +{ + REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); + return (area > -ZERO) ? 0 : 1; +} + +inline int +Mesher::equal( int x, int y ) +{ + return( last[0] == vdata[x] && last[1] == vdata[y] ); +} + +inline void +Mesher::copy( int x, int y ) +{ + last[0] = vdata[x]; last[1] = vdata[y]; +} + +inline void +Mesher::move( int x, int y ) +{ + vdata[x] = vdata[y]; +} + +inline void +Mesher::output( int x ) +{ + backend.tmeshvert( vdata[x] ); +} + +/*--------------------------------------------------------------------------- + * addedge - addedge an edge to the triangulation + * + * This code has been re-written to generate large triangle meshes + * from a monotone polygon. Although smaller triangle meshes + * could be generated faster and with less code, larger meshes + * actually give better SYSTEM performance. This is because + * vertices are processed in the backend slower than they are + * generated by this code and any decrease in the number of vertices + * results in a decrease in the time spent in the backend. + *--------------------------------------------------------------------------- + */ + +void +Mesher::addLast( ) +{ + register int ilast = itop; + + if( lastedge == 0 ) { + if( equal( 0, 1 ) ) { + output( ilast ); + swapMesh(); + for( register int i = 2; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } else if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i = ilast-3; i >= 0; i-- ) { + output( i ); + swapMesh(); + } + copy( 0, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( 0 ); + for( register int i = 1; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } + } else { + if( equal( 1, 0) ) { + swapMesh(); + output( ilast ); + for( register int i = 2; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } else if( equal( ilast-1, ilast-2) ) { + output( ilast ); + swapMesh(); + for( register int i = ilast-3; i >= 0; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, 0 ); + } else { + closeMesh(); openMesh(); + output( 0 ); + output( ilast ); + for( register int i = 1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } + } + closeMesh(); + //for( register long k=0; k<=ilast; k++ ) pop( k ); +} + +void +Mesher::addUpper( ) +{ + register int ilast = itop; + + if( lastedge == 0 ) { + if( equal( 0, 1 ) ) { + output( ilast ); + swapMesh(); + for( register int i = 2; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } else if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i = ilast-3; i >= 0; i-- ) { + output( i ); + swapMesh(); + } + copy( 0, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( 0 ); + for( register int i = 1; i < ilast; i++ ) { + swapMesh(); + output( i ); + } + copy( ilast, ilast-1 ); + } + lastedge = 1; + //for( register long k=0; k 1) && isCcw( ilast ) ); + + if( equal( ilast-1, ilast-2 ) ) { + output( ilast ); + swapMesh(); + for( register int i=ilast-3; i>=itop-1; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, itop-1 ); + } else if( equal( itop, itop-1 ) ) { + swapMesh(); + output( ilast ); + for( register int i = itop+1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } else { + closeMesh(); openMesh(); + output( ilast ); + output( ilast-1 ); + for( register int i=ilast-2; i>=itop-1; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, itop-1 ); + } + //for( register int k=itop; k= 0; i-- ) { + swapMesh(); + output( i ); + } + copy( ilast, 0 ); + } else { + closeMesh(); openMesh(); + output( 0 ); + output( ilast ); + for( register int i = 1; i < ilast; i++ ) { + output( i ); + swapMesh(); + } + copy( ilast-1, ilast ); + } + + lastedge = 0; + //for( register long k=0; k 1) && isCw( ilast ) ); + + if( equal( ilast-2, ilast-1) ) { + swapMesh(); + output( ilast ); + for( register int i=ilast-3; i>=itop-1; i--) { + output( i ); + swapMesh( ); + } + copy( itop-1, ilast ); + } else if( equal( itop-1, itop) ) { + output( ilast ); + swapMesh(); + for( register int i=itop+1; i=itop-1; i-- ) { + output( i ); + swapMesh( ); + } + copy( itop-1, ilast ); + } + //for( register int k=itop; k + +void reflexChain::outputFan(Real v[2], Backend* backend) +{ + Int i; + REAL retPoint[4]; + REAL retNormal[3]; + int it=0; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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); */ + + backend->bgntfan(); + + if (backend->get_output_style()==N_MESHLINE) + { + REAL* vertices=(REAL*)malloc(sizeof(REAL)*3*(index_queue+1)*3); + assert(vertices); + REAL* normals=(REAL*)malloc(sizeof(REAL)*3*(index_queue+1)*3); + assert(normals); + + /* Enable needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + backend->tmeshvert(v[0], v[1], retPoint, retNormal); + /* Store triangle fan center vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + + if (isIncreasing) + { + for(i=0; itmeshvert(v[0], v[1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + /* Store previous vertex */ + backend->tmeshvert(queue[i-1][0], queue[i-1][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + /* Store new vertex */ + backend->tmeshvert(queue[i][0], queue[i][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + else + { + for(i=index_queue-1; i>=0; i--) + { + if (it%3==0) + { + /* Store triangle fan center vertex */ + backend->tmeshvert(v[0], v[1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + /* Store previous vertex */ + backend->tmeshvert(queue[i+1][0], queue[i+1][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + backend->tmeshvert(queue[i][0], queue[i][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + + int jt; + + for (jt=0; jttmeshvert(v[0], v[1], retPoint, retNormal); + /* Store triangle fan center vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + + if (isIncreasing) + { + for(i=0; itmeshvert(queue[i][0], queue[i][1], retPoint, retNormal); + /* Store calculated vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + else + { + for(i=index_queue-1; i>=0; i--) + { + backend->tmeshvert(queue[i][0], queue[i][1], retPoint, retNormal); + /* Store calculated vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + + free(normals); + free(vertices); + } + + backend->endtfan(); + + /* 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); + } +} + +void reflexChain::processNewVertex(Real v[2], Backend* backend) +{ + Int i, j, k; + Int isReflex; + REAL retPoint[4]; + REAL retNormal[3]; + int it=0; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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); */ + + /* TrimVertex trimVert; */ + /* if there are at most one vertex in the queue, then simply insert */ + if (index_queue<=1) + { + insert(v); + return; + } + + /* there are at least two vertices in the queue */ + j=index_queue-1; + + for(i=j; i>=1; i--) + { + if (isIncreasing) + { + isReflex=(area(queue[i-1], queue[i], v)<=0.0f); + } + else /* decreasing */ + { + isReflex=(area(v, queue[i], queue[i-1])<=0.0f); + } + + if (isReflex) + { + break; + } + } + + /* + * if ibgntfan(); + + if (backend->get_output_style()==N_MESHLINE) + { + REAL* vertices=(REAL*)malloc(sizeof(REAL)*3*(index_queue+1)*3); + assert(vertices); + REAL* normals=(REAL*)malloc(sizeof(REAL)*3*(index_queue+1)*3); + assert(normals); + int jt; + + /* Enable needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + backend->tmeshvert(v[0], v[1], retPoint, retNormal); + /* Store triangle fan center vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + + if (isIncreasing) + { + for(k=i; k<=j; k++) + { + if (it%3==0) + { + /* Store triangle fan center vertex */ + backend->tmeshvert(v[0], v[1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + /* Store previous vertex */ + backend->tmeshvert(queue[k-1][0], queue[k-1][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + backend->tmeshvert(queue[k][0], queue[k][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + else + { + for(k=j; k>=i; k--) + { + if (it%3==0) + { + /* Store triangle fan center vertex */ + backend->tmeshvert(v[0], v[1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + /* Store previous vertex */ + backend->tmeshvert(queue[k+1][0], queue[k+1][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + backend->tmeshvert(queue[k][0], queue[k][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + + for (jt=0; jttmeshvert(v[0], v[1], retPoint, retNormal); + /* Store triangle fan center vertex */ + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + + if (isIncreasing) + { + for(k=i; k<=j; k++) + { + backend->tmeshvert(queue[k][0], queue[k][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + else + { + for(k=j; k>=i; k--) + { + backend->tmeshvert(queue[k][0], queue[k][1], retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + } + + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + + /* free the arrays */ + free(normals); + free(vertices); + } + + backend->endtfan(); + + /* 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); + } + } + + /* delete vertices i+1--j from the queue */ + index_queue=i+1; + /* finally insert v at the end of the queue */ + insert(v); +} + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Backend* backend) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, backend); + for(i=dec_current; i 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, backend); + for(i=inc_current; i0) + rChain.processNewVertex(inc_array[i], backend); + else + break; + } + rChain.outputFan(dec_array[dec_current], backend); + monoTriangulationRec(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + backend); + } + }/*end case neither is empty*/ +} + + +void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + Arc_ptr tempV; + Arc_ptr topV; + Arc_ptr botV; + topV = botV = loop; + for(tempV = loop->next; tempV != loop; tempV = tempV->next) + { + if(compFun(topV->tail(), tempV->tail())<0) { + topV = tempV; + } + if(compFun(botV->tail(), tempV->tail())>0) { + botV = tempV; + } + } + + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->pwlArc->npts-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->pwlArc->pts[i].param); + } + for(tempV = topV->next; tempV != botV; tempV = tempV->next) + { + for(i=0; i<=tempV->pwlArc->npts-2; i++){ + inc_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->prev; tempV != botV; tempV = tempV->prev) + { + for(i=tempV->pwlArc->npts-2; i>=0; i--){ + dec_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + } + for(i=botV->pwlArc->npts-2; i>=1; i--){ + dec_chain.appendVertex(tempV->pwlArc->pts[i].param); + } + + monoTriangulationRecFunBackend(topV->tail(), botV->tail(), &inc_chain, 0, &dec_chain, 0, compFun, backend); + +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + Backend* backend) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, backend); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, backend); + for(i=dec_current; i 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, backend); + for(i=inc_current; i0) + rChain.processNewVertex(inc_array[i], backend); + else + break; + } + rChain.outputFan(dec_array[dec_current], backend); + monoTriangulationRecFunBackend(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + compFun, + backend); + } + }/*end case neither is empty*/ +} diff --git a/project/jni/glu/src/libnurbs/internals/monotonizer.cc b/project/jni/glu/src/libnurbs/internals/monotonizer.cc new file mode 100644 index 000000000..98baf86a6 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/monotonizer.cc @@ -0,0 +1,254 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * monotonizer.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "arc.h" +#include "arctess.h" +#include "bezierarc.h" +#include "bin.h" +#include "mapdesc.h" +#include "nurbsconsts.h" +#include "subdivider.h" + +/*----------------------------------------------------------------------------- + * Subdivider::decompose - break all curves into monotone arcs + *----------------------------------------------------------------------------- + */ +int +Subdivider::decompose( Bin& bin, REAL geo_stepsize ) +{ + Arc_ptr jarc; + for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + if( ! jarc->isTessellated() ) { + /* points have not been transformed, therefore they may be either + homogeneous or inhomogeneous */ + tessellate( jarc, geo_stepsize ); + if( jarc->isDisconnected() || jarc->next->isDisconnected() ) + return 1; + } + } + + for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) { + monotonize( jarc, bin ); + } + + return 0; +} + +void +Subdivider::tessellate( Arc_ptr jarc, REAL geo_stepsize ) +{ + BezierArc *b = jarc->bezierArc; + Mapdesc *mapdesc = b->mapdesc; + + if( mapdesc->isRational() ) { + REAL max = mapdesc->calcVelocityRational( b->cpts, b->stride, b->order ); + REAL arc_stepsize = (max > 1.0f) ? (1.0f/max) : 1.0f; + if( jarc->bezierArc->order != 2 ) + arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 1 ); + else { + arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 1 ); + } + } else { + REAL max = mapdesc->calcVelocityNonrational( b->cpts, b->stride, b->order ); + REAL arc_stepsize = (max > 1.0f) ? (1.0f/max) : 1.0f; + if( jarc->bezierArc->order != 2 ) + arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 0 ); + else { + arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 0 ); + } + } +} + +/*------------------------------------------------------------------------- + * Subdivider::monotonize - break up a jordan arc into s,t-monotone + * components. This code will remove degenerate segments, including + * arcs of only a single point. + *------------------------------------------------------------------------- + */ +void +Subdivider::monotonize( Arc_ptr jarc, Bin& bin ) +{ + TrimVertex *firstvert = jarc->pwlArc->pts; + TrimVertex *lastvert = firstvert + (jarc->pwlArc->npts - 1); + long uid = jarc->nuid; + arc_side side = jarc->getside(); + dir sdir = none; + dir tdir = none; + int degenerate = 1; + + int nudegenerate; + int change; + + TrimVertex *vert; + for( vert = firstvert; vert != lastvert; vert++ ) { + + nudegenerate = 1; + change = 0; + + /* check change relative to s axis, clear degenerate bit if needed */ + REAL sdiff = vert[1].param[0] - vert[0].param[0]; + if( sdiff == 0 ) { + if( sdir != same ) { + sdir = same; + change = 1; + } + } else if( sdiff < 0.0 ) { + if( sdir != down ) { + sdir = down; + change = 1; + } + nudegenerate = 0; + } else { + if( sdir != up ) { + sdir = up; + change = 1; + } + nudegenerate = 0; + } + + /* check change relative to t axis, clear degenerate bit if needed */ + REAL tdiff = vert[1].param[1] - vert[0].param[1]; + if( tdiff == 0 ) { + if( tdir != same ) { + tdir = same; + change = 1; + } + } else if( tdiff < 0.0 ) { + if( tdir != down ) { + tdir = down; + change = 1; + } + nudegenerate = 0; + } else { + if( tdir != up ) { + tdir = up; + change = 1; + } + nudegenerate = 0; + } + + if( change ) { + if( ! degenerate ) { + /* make last segment into separate pwl curve */ + jarc->pwlArc->npts = (int)(vert - firstvert + 1); + jarc = (new(arcpool) Arc( side, uid ))->append( jarc ); + jarc->pwlArc = new(pwlarcpool) PwlArc(); + bin.addarc( jarc ); + } + firstvert = jarc->pwlArc->pts = vert; + degenerate = nudegenerate; + } + } + jarc->pwlArc->npts = (int)(vert - firstvert + 1); + + if( degenerate ) { + /* remove jarc from circularly linked list */ + jarc->prev->next = jarc->next; + jarc->next->prev = jarc->prev; + + assert( jarc->prev->check( ) != 0 ); + assert( jarc->next->check( ) != 0 ); + + /* remove jarc from bin */ + bin.remove_this_arc( jarc ); + + jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0; + jarc->deleteMe( arcpool ); + } +} + +/*------------------------------------------------------------------------- + * Subdivider::isMonotone - return true if arc is monotone AND non-degenerate + *------------------------------------------------------------------------- + */ +int +Subdivider::isMonotone( Arc_ptr jarc ) +{ + TrimVertex *firstvert = jarc->pwlArc->pts; + TrimVertex *lastvert = firstvert + (jarc->pwlArc->npts - 1); + + if( firstvert == lastvert ) return 1; + + TrimVertex *vert = firstvert; + enum dir sdir; + enum dir tdir; + + REAL diff = vert[1].param[0] - vert[0].param[0]; + if( diff == 0.0 ) + sdir = same; + else if( diff < 0.0 ) + sdir = down; + else + sdir = up; + + diff = vert[1].param[1] - vert[0].param[1]; + if( diff == 0.0 ) + tdir = same; + else if( diff < 0.0 ) + tdir = down; + else + tdir = up; + + if( (sdir == same) && (tdir == same) ) return 0; + + for( ++vert ; vert != lastvert; vert++ ) { + diff = vert[1].param[0] - vert[0].param[0]; + if( diff == 0.0 ) { + if( sdir != same ) return 0; + } else if( diff < 0.0 ) { + if( sdir != down ) return 0; + } else { + if( sdir != up ) return 0; + } + + diff = vert[1].param[1] - vert[0].param[1]; + if( diff == 0.0 ) { + if( tdir != same ) return 0; + } else if( diff < 0.0 ) { + if( tdir != down ) return 0; + } else { + if( tdir != up ) return 0; + } + } + return 1; +} + diff --git a/project/jni/glu/src/libnurbs/internals/monotonizer.h b/project/jni/glu/src/libnurbs/internals/monotonizer.h new file mode 100644 index 000000000..e951084ff --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/monotonizer.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +/* + * monotonizer.h + * + */ + +#ifndef __glumonotonizer_h_ +#define __glumonotonizer_h_ + +#include "mysetjmp.h" +#include "types.h" + +class Arc; +class ArcTessellator; +class Pool; +class Bin; +class PwlArcPool; +class Mapdesc; + +class Monotonizer { + ArcTessellator& arctessellator; + Pool& arcpool; + Pool& pwlarcpool; + jmp_buf& nurbsJmpBuf; + + enum dir { down, same, up, none }; + void tessellate( Arc *, REAL ); + void monotonize( Arc *, Bin & ); + int isMonotone( Arc * ); +public: + Monotonizer( ArcTessellator& at, Pool& ap, Pool& p, jmp_buf& j ) + : arctessellator(at), arcpool(ap), pwlarcpool(p), nurbsJmpBuf(j) {} + int decompose( Bin &, REAL ); +}; +#endif /* __glumonotonizer_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/myassert.h b/project/jni/glu/src/libnurbs/internals/myassert.h new file mode 100644 index 000000000..8726e5642 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/myassert.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +/* + * myassert.h + * + */ + +#ifndef __glumyassert_h_ +#define __glumyassert_h_ + +#define assert(EX) ((void)0) + +#endif /* __glumyassert_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mycode.cc b/project/jni/glu/src/libnurbs/internals/mycode.cc new file mode 100644 index 000000000..3625cacd7 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mycode.cc @@ -0,0 +1,67 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* +*/ + +#include "mymath.h" + +#ifdef NEEDCEILF + +float ceilf( float x ) +{ + if( x < 0 ) { + float nx = -x; + int ix = (int) nx; + return (float) -ix; + } else { + int ix = (int) x; + if( x == (float) ix ) return x; + return (float) (ix+1); + } +} + +float floorf( float x ) +{ + if( x < 0 ) { + float nx = -x; + int ix = (int) nx; + if( nx == (float) ix ) return x; + return (float) -(ix+1); + } else { + int ix = (int) x; + return (float) ix; + } +} +#endif diff --git a/project/jni/glu/src/libnurbs/internals/mymath.h b/project/jni/glu/src/libnurbs/internals/mymath.h new file mode 100644 index 000000000..c4a8fe6df --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mymath.h @@ -0,0 +1,67 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#ifndef __glumymath_h_ +#define __glumymath_h_ + +#ifdef GLBUILD + #define sqrtf gl_fsqrt +#endif + +#if defined(GLBUILD) +#define M_SQRT2 1.41421356237309504880 +#define ceilf myceilf +#define floorf myfloorf +#define sqrtf sqrt +extern "C" double sqrt(double); +extern "C" float ceilf(float); +extern "C" float floorf(float); +#define NEEDCEILF +#endif + +#ifdef LIBRARYBUILD + #include +#endif + +#if !defined sqrtf + #define sqrtf(x) ((float)sqrt(x)) +#endif +#if !defined ceilf + #define ceilf(x) ((float)ceil(x)) +#endif +#if !defined floorf + #define floorf(x) ((float)floor(x)) +#endif + +#endif /* __glumymath_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mysetjmp.h b/project/jni/glu/src/libnurbs/internals/mysetjmp.h new file mode 100644 index 000000000..24082bf9a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mysetjmp.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/* + * mysetjmp.h + * + */ + +#ifndef __glumysetjmp_h_ +#define __glumysetjmp_h_ + +#ifdef GLBUILD +#define setjmp gl_setjmp +#define longjmp gl_longjmp +#endif + +#if defined(LIBRARYBUILD) || defined(GLBUILD) +#include +#include + +struct JumpBuffer +{ + jmp_buf buf; +}; + +inline JumpBuffer* newJumpbuffer(void) +{ + return (JumpBuffer*)malloc(sizeof(JumpBuffer)); +} + +inline void deleteJumpbuffer(JumpBuffer* jb) +{ + free((void*)jb); +} + +inline void mylongjmp(JumpBuffer* j, int code) +{ + ::longjmp(j->buf, code); +} + +inline int mysetjmp(JumpBuffer* j) +{ + return setjmp(j->buf); +} +#endif /* LIBRARYBUILD || GLBUILD */ + +#endif /* __glumysetjmp_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/mystring.h b/project/jni/glu/src/libnurbs/internals/mystring.h new file mode 100644 index 000000000..06c869a63 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/mystring.h @@ -0,0 +1,50 @@ +/* + * 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. + */ + +/* + * mystring.h + * + */ + +#ifndef __glumystring_h_ +#define __glumystring_h_ + +#ifdef GLBUILD + #define memcpy(a,b,c) bcopy(b,a,c) + #define memset(a,b,c) bzero(a,c) + extern "C" void bcopy(const void*, void*, int); + extern "C" void bzero(void*, int); +#endif + +#ifdef LIBRARYBUILD + #include +#endif + +#endif /* __glumystring_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/nurbsconsts.h b/project/jni/glu/src/libnurbs/internals/nurbsconsts.h new file mode 100644 index 000000000..cd8b3f08f --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/nurbsconsts.h @@ -0,0 +1,119 @@ +/* + * 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. + */ + +/* + * nurbsconsts.h + * + */ + +#ifndef __glunurbsconsts_h_ +#define __glunurbsconsts_h_ + +/* NURBS Properties - one set per map, + each takes a single INREAL arg */ +#define N_SAMPLING_TOLERANCE 1 +#define N_S_RATE 6 +#define N_T_RATE 7 +#define N_CLAMPFACTOR 13 +#define N_NOCLAMPING 0.0 +#define N_MINSAVINGS 14 +#define N_NOSAVINGSSUBDIVISION 0.0 + +/* NURBS Properties - one set per map, + each takes an enumerated value */ +#define N_CULLING 2 +#define N_NOCULLING 0.0 +#define N_CULLINGON 1.0 +#define N_SAMPLINGMETHOD 10 +#define N_NOSAMPLING 0.0 +#define N_FIXEDRATE 3.0 +#define N_DOMAINDISTANCE 2.0 +#define N_PARAMETRICDISTANCE 5.0 +#define N_PATHLENGTH 6.0 +#define N_SURFACEAREA 7.0 +#define N_OBJECTSPACE_PARA 8.0 +#define N_OBJECTSPACE_PATH 9.0 +#define N_BBOX_SUBDIVIDING 17 +#define N_NOBBOXSUBDIVISION 0.0 +#define N_BBOXTIGHT 1.0 +#define N_BBOXROUND 2.0 + +/* NURBS Rendering Properties - one set per renderer + each takes an enumerated value */ +#define N_DISPLAY 3 +#define N_FILL 1.0 +#define N_OUTLINE_POLY 2.0 +#define N_OUTLINE_TRI 3.0 +#define N_OUTLINE_QUAD 4.0 +#define N_OUTLINE_PATCH 5.0 +#define N_OUTLINE_PARAM 6.0 +#define N_OUTLINE_PARAM_S 7.0 +#define N_OUTLINE_PARAM_ST 8.0 +#define N_OUTLINE_SUBDIV 9.0 +#define N_OUTLINE_SUBDIV_S 10.0 +#define N_OUTLINE_SUBDIV_ST 11.0 +#define N_ISOLINE_S 12.0 +#define N_ERRORCHECKING 4 +#define N_NOMSG 0.0 +#define N_MSG 1.0 + +/* GL 4.0 propeties not defined above */ +#ifndef N_PIXEL_TOLERANCE +#define N_PIXEL_TOLERANCE N_SAMPLING_TOLERANCE +#define N_ERROR_TOLERANCE 20 +#define N_SUBDIVISIONS 5 +#define N_TILES 8 +#define N_TMP1 9 +#define N_TMP2 N_SAMPLINGMETHOD +#define N_TMP3 11 +#define N_TMP4 12 +#define N_TMP5 N_CLAMPFACTOR +#define N_TMP6 N_MINSAVINGS +#define N_S_STEPS N_S_RATE +#define N_T_STEPS N_T_RATE +#endif + +/* NURBS Rendering Properties - one set per map, + each takes an INREAL matrix argument */ +#define N_CULLINGMATRIX 1 +#define N_SAMPLINGMATRIX 2 +#define N_BBOXMATRIX 3 + +/* NURBS Rendering Properties - one set per map, + each takes an INREAL vector argument */ +#define N_BBOXSIZE 4 + +/* type argument for trimming curves */ +#ifndef N_P2D +#define N_P2D 0x8 +#define N_P2DR 0xd +#endif + +#endif /* __glunurbsconsts_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/nurbsinterfac.cc b/project/jni/glu/src/libnurbs/internals/nurbsinterfac.cc new file mode 100644 index 000000000..488ad409a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/nurbsinterfac.cc @@ -0,0 +1,532 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * nurbsinterfac.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "nurbsconsts.h" +#include "nurbstess.h" +#include "bufpool.h" +#include "quilt.h" +#include "displaylist.h" +#include "knotvector.h" +#include "mapdesc.h" + +#define THREAD(work, arg, cleanup) \ + if (dl) \ + { \ + arg->save=1; \ + dl->append((PFVS)&NurbsTessellator::work, (void*) arg, (PFVS)&NurbsTessellator::cleanup); \ + } \ + else \ + { \ + arg->save=0; \ + work(arg); \ + } + +#define THREAD2(work) \ + if (dl) \ + { \ + dl->append((PFVS)&NurbsTessellator::work, 0, 0 ); \ + } \ + else \ + { \ + work(); \ + } + +NurbsTessellator::NurbsTessellator(BasicCurveEvaluator& c, BasicSurfaceEvaluator& e): + maplist(backend), backend(c, e), subdivider(renderhints, backend), + o_pwlcurvePool(sizeof(O_pwlcurve), 32, "o_pwlcurvePool"), + o_nurbscurvePool(sizeof(O_nurbscurve), 32, "o_nurbscurvePool"), + o_curvePool(sizeof(O_curve), 32, "o_curvePool"), + o_trimPool(sizeof(O_trim), 32, "o_trimPool"), + o_surfacePool(sizeof(O_surface), 1, "o_surfacePool"), + o_nurbssurfacePool(sizeof(O_nurbssurface), 4, "o_nurbssurfacePool"), + propertyPool(sizeof(Property), 32, "propertyPool"), + quiltPool(sizeof(Quilt), 32, "quiltPool") +{ + dl=0; + inSurface=0; + inCurve=0; + inTrim=0; + playBack=0; + jumpbuffer=newJumpbuffer(); + subdivider.setJumpbuffer(jumpbuffer); +} + +NurbsTessellator::~NurbsTessellator(void) +{ + if (inTrim) + { + do_nurbserror(12); + endtrim(); + } + + if (inSurface) + { + *nextNurbssurface=0; + do_freeall(); + } + + if (jumpbuffer) + { + deleteJumpbuffer(jumpbuffer); + jumpbuffer=0; + } +} + +/*----------------------------------------------------------------------------- + * bgnsurface - allocate and initialize an o_surface structure + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::bgnsurface(long nuid) +{ + O_surface* o_surface=new(o_surfacePool)O_surface; + o_surface->nuid=nuid; + THREAD(do_bgnsurface, o_surface, do_freebgnsurface); +} + +/*----------------------------------------------------------------------------- + * bgncurve - allocate an initialize an o_curve structure + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::bgncurve(long nuid) +{ + O_curve* o_curve=new(o_curvePool)O_curve; + o_curve->nuid=nuid; + THREAD(do_bgncurve, o_curve, do_freebgncurve); +} +/*----------------------------------------------------------------------------- + * endcurve - + * + * Client: + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::endcurve(void) +{ + THREAD2(do_endcurve); +} + +/*----------------------------------------------------------------------------- + * endsurface - user level end of surface call + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::endsurface(void) +{ + THREAD2(do_endsurface); +} + + +/*----------------------------------------------------------------------------- + * bgntrim - allocate and initialize a new trim loop structure (o_trim ) + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::bgntrim(void) +{ + O_trim* o_trim=new(o_trimPool)O_trim; + THREAD(do_bgntrim, o_trim, do_freebgntrim); +} + +/*----------------------------------------------------------------------------- + * endtrim - + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::endtrim(void) +{ + THREAD2(do_endtrim); +} + +/*----------------------------------------------------------------------------- + * pwlcurve - + * + * count - number of points on curve + * array - array of points on curve + * byte_stride - distance between points in bytes + * type - valid data flag + * + * Client: Gl user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::pwlcurve(long count, INREAL array[], long byte_stride, long type) +{ + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + isDataValid=0; + return; + } + + if ((type!=N_P2D) && (type!=N_P2DR)) + { + do_nurbserror(22); + isDataValid=0; + return; + } + + if (count<0) + { + do_nurbserror(33); + isDataValid=0; + return; + } + + if (byte_stride<0) + { + do_nurbserror(34); + isDataValid=0; + return; + } + + O_pwlcurve* o_pwlcurve=new(o_pwlcurvePool)O_pwlcurve(type, count, array, byte_stride, extTrimVertexPool.get((int)count)); + THREAD(do_pwlcurve, o_pwlcurve, do_freepwlcurve); +} + + +/*----------------------------------------------------------------------------- + * nurbscurve - + * + * Client: GL user + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::nurbscurve(long nknots, /* number of p knots */ + INREAL knot[], /* nondecreasing knot values in p */ + long byte_stride, /* distance in bytes between control points */ + INREAL ctlarray[], /* pointer to first control point */ + long order, /* order of spline */ + long type) /* description of range space */ +{ + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + isDataValid=0; + return; + } + + if (ctlarray==0) + { + do_nurbserror(36); + isDataValid=0; + return; + } + + if (byte_stride<0) + { + do_nurbserror(34); + isDataValid=0; + return; + } + + Knotvector knots; + + knots.init(nknots, byte_stride, order, knot); + if (do_check_knots(&knots, "curve")) + { + return; + } + + O_nurbscurve* o_nurbscurve=new(o_nurbscurvePool)O_nurbscurve(type); + o_nurbscurve->bezier_curves=new(quiltPool)Quilt(mapdesc); + o_nurbscurve->bezier_curves->toBezier(knots,ctlarray, mapdesc->getNcoords()); + + THREAD(do_nurbscurve, o_nurbscurve, do_freenurbscurve); +} + + +/*----------------------------------------------------------------------------- + * nurbssurface - + * + * Client: User routine + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::nurbssurface(long sknot_count, /* number of s knots */ + INREAL sknot[], /* nondecreasing knot values in s */ + long tknot_count, /* number of t knots */ + INREAL tknot[], /* nondecreasing knot values in t */ + long s_byte_stride, /* s step size in memory bytes */ + long t_byte_stride, /* t step size in memory bytes */ + INREAL ctlarray[], /* pointer to first control point */ + long sorder, /* order of the spline in s parameter */ + long torder, /* order of the spline in t parameter */ + long type) /* description of range space */ +{ + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + isDataValid=0; + return; + } + + if (s_byte_stride<0) + { + do_nurbserror(34); + isDataValid=0; + return; + } + + if (t_byte_stride<0) + { + do_nurbserror(34); + isDataValid=0; + return; + } + + Knotvector sknotvector, tknotvector; + + sknotvector.init(sknot_count, s_byte_stride, sorder, sknot); + if (do_check_knots(&sknotvector, "surface")) + { + return; + } + + tknotvector.init(tknot_count, t_byte_stride, torder, tknot); + if (do_check_knots(&tknotvector, "surface")) + { + return; + } + + O_nurbssurface* o_nurbssurface=new(o_nurbssurfacePool)O_nurbssurface(type); + o_nurbssurface->bezier_patches=new(quiltPool)Quilt(mapdesc); + + o_nurbssurface->bezier_patches->toBezier(sknotvector, tknotvector, ctlarray, mapdesc->getNcoords()); + THREAD(do_nurbssurface, o_nurbssurface, do_freenurbssurface); +} + + +/*----------------------------------------------------------------------------- + * setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::setnurbsproperty( long tag, INREAL value ) +{ + if (!renderhints.isProperty(tag)) + { + do_nurbserror(26); + } + else + { + Property* prop=new(propertyPool) Property(tag, value); + THREAD(do_setnurbsproperty, prop, do_freenurbsproperty); + } +} + +/*----------------------------------------------------------------------------- + * setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::setnurbsproperty(long type, long tag, INREAL value) +{ + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + return; + } + + if (!mapdesc->isProperty(tag)) + { + do_nurbserror(26); + return; + } + + Property* prop=new(propertyPool)Property(type, tag, value); + THREAD(do_setnurbsproperty2, prop, do_freenurbsproperty); +} + + +/*----------------------------------------------------------------------------- + * getnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::getnurbsproperty(long tag, INREAL* value) +{ + if (renderhints.isProperty(tag)) + { + *value=renderhints.getProperty(tag); + } + else + { + do_nurbserror(26); + } +} + +/*----------------------------------------------------------------------------- + * getnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::getnurbsproperty(long type, long tag, INREAL* value) +{ + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + } + + if (mapdesc->isProperty(tag)) + { + *value=mapdesc->getProperty(tag); + } + else + { + do_nurbserror(26); + } +} + +/*-------------------------------------------------------------------------- + * setnurbsproperty - accept a user supplied matrix as culling or sampling mat + *-------------------------------------------------------------------------- + */ + +void NurbsTessellator::setnurbsproperty(long type, long purpose, INREAL* mat) +{ + // XXX - cannot be put in display list + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + isDataValid=0; + } + else + { + if (purpose==N_BBOXSIZE) + { + mapdesc->setBboxsize(mat); + } + } +} + +/*-------------------------------------------------------------------------- + * setnurbsproperty - accept a user supplied matrix as culling or sampling mat + *-------------------------------------------------------------------------- + */ + +void NurbsTessellator::setnurbsproperty(long type, long purpose, INREAL* mat, long rstride, long cstride) +{ + // XXX - cannot be put in display list + Mapdesc* mapdesc=maplist.locate(type); + + if (mapdesc==0) + { + do_nurbserror(35); + isDataValid=0; + } + else + { + if (purpose==N_CULLINGMATRIX) + { + mapdesc->setCmat(mat, rstride, cstride); + } + else + { + if (purpose==N_SAMPLINGMATRIX) + { + mapdesc->setSmat(mat, rstride, cstride); + } + else + { + if (purpose==N_BBOXMATRIX) + { + mapdesc->setBmat(mat, rstride, cstride); + } + } + } + } +} + +void NurbsTessellator::redefineMaps(void) +{ + maplist.initialize(); +} + +void NurbsTessellator::defineMap(long type, long rational, long ncoords) +{ + maplist.define(type, (int)rational, (int)ncoords); +} + +void NurbsTessellator::discardRecording(void* _dl) +{ + delete (DisplayList*) _dl; +} + +void* NurbsTessellator::beginRecording(void) +{ + dl=new DisplayList(this); + + return (void*)dl; +} + +void NurbsTessellator::endRecording(void) +{ + dl->endList(); + dl=0; +} + +void NurbsTessellator::playRecording(void* _dl) +{ + playBack=1; + bgnrender(); + ((DisplayList*)_dl)->play(); + endrender(); + playBack=0; +} + diff --git a/project/jni/glu/src/libnurbs/internals/nurbstess.cc b/project/jni/glu/src/libnurbs/internals/nurbstess.cc new file mode 100644 index 000000000..a01ab6f87 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/nurbstess.cc @@ -0,0 +1,790 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * nurbstess.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "nurbsconsts.h" +#include "nurbstess.h" +#include "bufpool.h" +#include "quilt.h" +#include "knotvector.h" +#include "mapdesc.h" +#include "maplist.h" + +void NurbsTessellator::set_domain_distance_u_rate(REAL u_rate) +{ + subdivider.set_domain_distance_u_rate(u_rate); +} + +void NurbsTessellator::set_domain_distance_v_rate(REAL v_rate) +{ + subdivider.set_domain_distance_v_rate(v_rate); +} + +void NurbsTessellator::set_is_domain_distance_sampling(int flag) +{ + subdivider.set_is_domain_distance_sampling(flag); +} + +void NurbsTessellator::resetObjects(void) +{ + subdivider.clear(); +} + +void NurbsTessellator::makeobj(int) +{ +} + +void NurbsTessellator::closeobj(void) +{ +} + +void NurbsTessellator::bgnrender(void) +{ +} + +void NurbsTessellator::endrender(void) +{ +} + +/*----------------------------------------------------------------------------- + * do_freebgnsurface - free o_surface structure + * + * Client: do_freeall(), bgnsurface() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_freebgnsurface(O_surface* o_surface) +{ + o_surface->deleteMe(o_surfacePool); +} + +/*----------------------------------------------------------------------------- + * do_bgnsurface - begin the display of a surface + * + * Client: bgnsurface() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_bgnsurface(O_surface* o_surface) +{ + if (inSurface) + { + do_nurbserror(27); + endsurface(); + } + inSurface=1; + + if (!playBack) + { + bgnrender(); + } + + isTrimModified=0; + isSurfaceModified=0; + isDataValid=1; + numTrims=0; + currentSurface=o_surface; + nextTrim=&(currentSurface->o_trim); + nextNurbssurface=&(currentSurface->o_nurbssurface); +} + +/*----------------------------------------------------------------------------- + * do_bgncurve - begin the display of a curve + * + * Client: bgncurve() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_bgncurve(O_curve* o_curve) +{ + if (inCurve) + { + do_nurbserror(6); + endcurve(); + } + + inCurve=1; + currentCurve=o_curve; + currentCurve->curvetype=ct_none; + + if (inTrim) + { + if (*nextCurve!=o_curve) + { + isCurveModified=1; + *nextCurve=o_curve; + } + } + else + { + if (!playBack) + { + bgnrender(); + } + isDataValid=1; + } + + nextCurve=&(o_curve->next); + nextPwlcurve=&(o_curve->curve.o_pwlcurve); + nextNurbscurve=&(o_curve->curve.o_nurbscurve); +} + +/*----------------------------------------------------------------------------- + * do_endcurve - + * + * Client: endcurve() + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::do_endcurve(void) +{ + if (!inCurve) + { + do_nurbserror(7); + return; + } + inCurve=0; + + *nextCurve=0; + if (currentCurve->curvetype==ct_nurbscurve) + { + *nextNurbscurve=0; + } + else + { + *nextPwlcurve=0; + } + + if (!inTrim) + { + if (!isDataValid) + { + do_freecurveall(currentCurve); + return; + } + + int errval; + errval=::mysetjmp(jumpbuffer); + + if (errval==0) + { + if (currentCurve->curvetype==ct_nurbscurve) + { + subdivider.beginQuilts(); + for (O_nurbscurve* n=currentCurve->curve.o_nurbscurve; n!=0; n=n->next) + { + subdivider.addQuilt(n->bezier_curves); + } + subdivider.endQuilts(); + subdivider.drawCurves(); + if (!playBack) + { + endrender(); + } + } + else + { + /* XXX */ + if (!playBack) + { + endrender(); + } + /* do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */; + do_nurbserror(9); + } + } + else + { + if (!playBack) + { + endrender(); + } + do_nurbserror(errval); + } + do_freecurveall( currentCurve ); + resetObjects(); + } +} + +/*----------------------------------------------------------------------------- + * do_endsurface - mark end of surface, display surface, free immediate data + * + * Client: + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_endsurface(void) +{ + if (inTrim) + { + do_nurbserror(12); + endtrim(); + } + + if (!inSurface) + { + do_nurbserror(13); + return; + } + inSurface=0; + + *nextNurbssurface=0; + + if (!isDataValid) + { + do_freeall(); + return; + } + + if (*nextTrim!=0) + { + isTrimModified=1; + *nextTrim=0; + } + + int errval; + + errval=::mysetjmp(jumpbuffer); + if (errval==0) + { + if (numTrims>0) + { + subdivider.beginTrims(); + for (O_trim* trim=currentSurface->o_trim; trim; trim=trim->next) + { + subdivider.beginLoop(); + for (O_curve* curve=trim->o_curve; curve; curve=curve->next) + { + curve->used=0; + assert(curve->curvetype!=ct_none); + if (curve->curvetype==ct_pwlcurve) + { + O_pwlcurve* c=curve->curve.o_pwlcurve; + subdivider.addArc(c->npts, c->pts, curve->nuid); + } + else + { + Quilt* quilt=curve->curve.o_nurbscurve->bezier_curves; + Quiltspec* qspec=quilt->qspec; + REAL* cpts=quilt->cpts+qspec->offset; + REAL* cptsend=cpts+(qspec->width*qspec->order*qspec->stride); + for (; cpts!=cptsend; cpts+=qspec->order*qspec->stride) + { + subdivider.addArc(cpts, quilt, curve->nuid); + } + } + } + subdivider.endLoop(); + } + subdivider.endTrims(); + } + + subdivider.beginQuilts(); + for (O_nurbssurface* n=currentSurface->o_nurbssurface; n; n=n->next) + { + subdivider.addQuilt(n->bezier_patches); + } + subdivider.endQuilts(); + subdivider.drawSurfaces(currentSurface->nuid); + if (!playBack) + { + endrender(); + } + } + else + { + if (!playBack) + { + endrender(); + } + do_nurbserror(errval); + } + + do_freeall(); + resetObjects(); +} + +/*----------------------------------------------------------------------------- + * do_freeall - free all data allocated in immediate mode + * + * Client: + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_freeall(void) +{ + for (O_trim* o_trim=currentSurface->o_trim; o_trim;) + { + O_trim* next_o_trim=o_trim->next; + for (O_curve* curve=o_trim->o_curve; curve;) + { + O_curve* next_o_curve=curve->next; + do_freecurveall(curve); + curve=next_o_curve; + } + if (o_trim->save==0) + { + do_freebgntrim(o_trim); + } + o_trim=next_o_trim; + } + + O_nurbssurface* nurbss; + O_nurbssurface* next_nurbss; + + for (nurbss=currentSurface->o_nurbssurface; nurbss; nurbss=next_nurbss) + { + next_nurbss=nurbss->next; + if (nurbss->save==0) + { + do_freenurbssurface(nurbss); + } + else + { + nurbss->used=0; + } + } + + if (currentSurface->save==0) + { + do_freebgnsurface(currentSurface); + } +} + +void NurbsTessellator::do_freecurveall(O_curve* curve) +{ + assert(curve->curvetype!=ct_none); + + if (curve->curvetype==ct_nurbscurve) + { + O_nurbscurve* ncurve; + O_nurbscurve* next_ncurve; + + for (ncurve=curve->curve.o_nurbscurve; ncurve; ncurve=next_ncurve) + { + next_ncurve=ncurve->next; + if (ncurve->save==0) + { + do_freenurbscurve(ncurve); + } + else + { + ncurve->used=0; + } + } + } + else + { + O_pwlcurve* pcurve; + O_pwlcurve* next_pcurve; + + for (pcurve=curve->curve.o_pwlcurve; pcurve; pcurve=next_pcurve) + { + next_pcurve=pcurve->next; + if (pcurve->save==0) + { + do_freepwlcurve(pcurve); + } + else + { + pcurve->used = 0; + } + } + } + + if (curve->save==0) + { + do_freebgncurve(curve); + } +} + + +/*----------------------------------------------------------------------------- + * do_freebgntrim - free the space allocated for a trim loop + * + * Client: + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_freebgntrim(O_trim* o_trim) +{ + o_trim->deleteMe(o_trimPool); +} + +/*----------------------------------------------------------------------------- + * do_bgntrim - link in a trim loop to the current trimmed surface description + * + * Client: bgntrim() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_bgntrim(O_trim* o_trim) +{ + if (!inSurface) + { + do_nurbserror(15); + bgnsurface(0); + inSurface=2; + } + + if (inTrim) + { + do_nurbserror(16); + endtrim(); + } + inTrim=1; + + if (*nextTrim!=o_trim) + { + isTrimModified=1; + *nextTrim=o_trim; + } + + currentTrim=o_trim; + nextTrim=&(o_trim->next); + nextCurve=&(o_trim->o_curve); +} + +/*----------------------------------------------------------------------------- + * do_endtrim - mark the end of the current trim loop + * + * Client: endtrim() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_endtrim(void) +{ + if (!inTrim) + { + do_nurbserror(17); + return; + } + inTrim=0; + + if (currentTrim->o_curve==0) + { + do_nurbserror(18); + isDataValid=0; + } + + numTrims++; + + if (*nextCurve!=0) + { + isTrimModified=1; + *nextCurve=0; + } +} + +/*----------------------------------------------------------------------------- + * do_freepwlcurve - + * + * Client: + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_freepwlcurve(O_pwlcurve* o_pwlcurve) +{ + o_pwlcurve->deleteMe(o_pwlcurvePool); +} + +void NurbsTessellator::do_freebgncurve(O_curve* o_curve) +{ + o_curve->deleteMe(o_curvePool); +} + +/*----------------------------------------------------------------------------- + * do_pwlcurve - link in pwl trim loop to the current surface description + * + * Client: pwlcurve() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_pwlcurve(O_pwlcurve* o_pwlcurve) +{ + if (!inTrim) + { + do_nurbserror(19); + if (o_pwlcurve->save==0) + { + do_freepwlcurve(o_pwlcurve); + } + return; + } + + if (!inCurve) + { + bgncurve(0); + inCurve=2; + } + + if (o_pwlcurve->used) + { + do_nurbserror(20); + isDataValid=0; + return; + } + else + { + o_pwlcurve->used = 1; + } + + if (currentCurve->curvetype==ct_none) + { + currentCurve->curvetype=ct_pwlcurve; + } + else + { + if (currentCurve->curvetype!=ct_pwlcurve) + { + do_nurbserror(21); + isDataValid=0; + return; + } + } + + if (*nextPwlcurve!=o_pwlcurve) + { + isCurveModified=1; + *nextPwlcurve=o_pwlcurve; + } + nextPwlcurve=&(o_pwlcurve->next); + + if (o_pwlcurve->owner!=currentCurve) + { + isCurveModified=1; + o_pwlcurve->owner=currentCurve; + } + + if ((inCurve==2)) + { + endcurve(); + } +} + +/*----------------------------------------------------------------------------- + * do_freenurbscurve - + * + * Client: + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_freenurbscurve(O_nurbscurve* o_nurbscurve) +{ + o_nurbscurve->bezier_curves->deleteMe(quiltPool); + o_nurbscurve->deleteMe(o_nurbscurvePool); +} + +/*----------------------------------------------------------------------------- + * do_nurbscurve - + * + * Client: nurbscurve() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_nurbscurve(O_nurbscurve* o_nurbscurve) +{ + if (!inCurve) + { + bgncurve(0); + inCurve=2; + } + + if (o_nurbscurve->used) + { + /* error - curve was already called in current surface */ + do_nurbserror(23); + isDataValid=0; + return; + } + else + { + o_nurbscurve->used=1; + } + + if (currentCurve->curvetype==ct_none) + { + currentCurve->curvetype=ct_nurbscurve; + } + else + { + if (currentCurve->curvetype!=ct_nurbscurve) + { + do_nurbserror(24); + isDataValid=0; + return; + } + } + + if (*nextNurbscurve!=o_nurbscurve) + { + isCurveModified=1; + *nextNurbscurve=o_nurbscurve; + } + + nextNurbscurve=&(o_nurbscurve->next); + + if (o_nurbscurve->owner!=currentCurve) + { + isCurveModified=1; + o_nurbscurve->owner=currentCurve; + } + + if (o_nurbscurve->owner==0) + { + isCurveModified=1; + } + + if (inCurve==2) + { + endcurve(); + } +} + + +/*----------------------------------------------------------------------------- + * do_freenurbssurface - + * + * Client: + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::do_freenurbssurface(O_nurbssurface* o_nurbssurface) +{ + o_nurbssurface->bezier_patches->deleteMe(quiltPool); + o_nurbssurface->deleteMe(o_nurbssurfacePool); +} + +/*----------------------------------------------------------------------------- + * do_nurbssurface - + * + * Client: nurbssurface() + *----------------------------------------------------------------------------- + */ +void NurbsTessellator::do_nurbssurface(O_nurbssurface* o_nurbssurface) +{ + if (!inSurface) + { + bgnsurface(0); + inSurface=2; + } + + if (o_nurbssurface->used) + { + /* error - surface was already called in current block */ + do_nurbserror(25); + isDataValid=0; + return; + } + else + { + o_nurbssurface->used=1; + } + + if (*nextNurbssurface!=o_nurbssurface) + { + isSurfaceModified=1; + *nextNurbssurface=o_nurbssurface; + } + + if (o_nurbssurface->owner!=currentSurface) + { + isSurfaceModified=1; + o_nurbssurface->owner=currentSurface; + } + nextNurbssurface=&(o_nurbssurface->next); + + if (inSurface==2) + { + endsurface(); + } +} + +/*----------------------------------------------------------------------------- + * do_freenurbsproperty + * + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::do_freenurbsproperty(Property* prop) +{ + prop->deleteMe(propertyPool); +} + +/*----------------------------------------------------------------------------- + * do_setnurbsproperty - + * + *----------------------------------------------------------------------------- + */ + +void NurbsTessellator::do_setnurbsproperty(Property* prop) +{ + renderhints.setProperty(prop->tag, prop->value); + if (prop->save==0) + { + do_freenurbsproperty(prop); + } +} + +void NurbsTessellator::do_setnurbsproperty2(Property* prop) +{ + Mapdesc* mapdesc=maplist.find(prop->type); + + mapdesc->setProperty(prop->tag, prop->value); + if (prop->save==0) + { + do_freenurbsproperty(prop); + } +} + +void NurbsTessellator::errorHandler(int) +{ +} + +void NurbsTessellator::do_nurbserror(int msg) +{ + errorHandler(msg); +} + +int NurbsTessellator::do_check_knots(Knotvector* knots, const char* msg) +{ + int status=knots->validate(); + + if (status) + { + do_nurbserror(status); + if (renderhints.errorchecking!=N_NOMSG) + { + knots->show(msg); + } + } + + return status; +} diff --git a/project/jni/glu/src/libnurbs/internals/nurbstess.h b/project/jni/glu/src/libnurbs/internals/nurbstess.h new file mode 100644 index 000000000..17a306856 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/nurbstess.h @@ -0,0 +1,170 @@ +/* + * 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. + */ + +/* + * nurbstess.h + * + */ + +#ifndef __glunurbstess_h_ +#define __glunurbstess_h_ + +#include "mysetjmp.h" +#include "subdivider.h" +#include "renderhints.h" +#include "backend.h" +#include "maplist.h" +#include "reader.h" +#include "nurbsconsts.h" + +struct Knotvector; +class Quilt; +class DisplayList; +class BasicCurveEvaluator; +class BasicSurfaceEvaluator; + +class NurbsTessellator +{ + public: + NurbsTessellator(BasicCurveEvaluator& c, BasicSurfaceEvaluator& e); + virtual ~NurbsTessellator(void); + + void getnurbsproperty(long, INREAL*); + void getnurbsproperty(long, long, INREAL*); + void setnurbsproperty(long, INREAL); + void setnurbsproperty(long, long, INREAL); + void setnurbsproperty(long, long, INREAL*); + void setnurbsproperty(long, long, INREAL*, long, long); + + // called before a tessellation begins/ends + virtual void bgnrender(void); + virtual void endrender(void); + + // called to make a display list of the output vertices + virtual void makeobj(int n); + virtual void closeobj(void); + + // called when a error occurs + virtual void errorHandler(int); + + void bgnsurface(long); + void endsurface(void); + void bgntrim(void); + void endtrim(void); + void bgncurve(long); + void endcurve(void); + void pwlcurve(long, INREAL[], long, long); + void nurbscurve(long, INREAL[], long, INREAL[], long, long); + void nurbssurface(long, INREAL[], long, INREAL[], long, long, INREAL[], long, long, long); + + void defineMap(long, long, long); + void redefineMaps(void); + + // recording of input description + void discardRecording(void*); + void* beginRecording(void); + void endRecording(void); + void playRecording(void*); + + // for optimizing untrimmed nurbs in the case of domain distance sampling + void set_domain_distance_u_rate(REAL u_rate); + void set_domain_distance_v_rate(REAL v_rate); + void set_is_domain_distance_sampling(int flag); + + protected: + Renderhints renderhints; + Maplist maplist; + Backend backend; + + private: + void resetObjects(void); + int do_check_knots(Knotvector*, const char*); + void do_nurbserror(int); + void do_bgncurve(O_curve*); + void do_endcurve(void); + void do_freeall(void); + void do_freecurveall(O_curve*); + void do_freebgntrim(O_trim*); + void do_freebgncurve(O_curve*); + void do_freepwlcurve(O_pwlcurve*); + void do_freenurbscurve(O_nurbscurve*); + void do_freenurbssurface(O_nurbssurface*); + void do_freebgnsurface(O_surface*); + void do_bgnsurface(O_surface*); + void do_endsurface(void); + void do_bgntrim(O_trim*); + void do_endtrim(void); + void do_pwlcurve(O_pwlcurve*); + void do_nurbscurve(O_nurbscurve*); + void do_nurbssurface(O_nurbssurface*); + void do_freenurbsproperty(Property*); + void do_setnurbsproperty(Property*); + void do_setnurbsproperty2(Property*); + + Subdivider subdivider; + JumpBuffer* jumpbuffer; + Pool o_pwlcurvePool; + Pool o_nurbscurvePool; + Pool o_curvePool; + Pool o_trimPool; + Pool o_surfacePool; + Pool o_nurbssurfacePool; + Pool propertyPool; + + public: + Pool quiltPool; + + private: + TrimVertexPool extTrimVertexPool; + + int inSurface; /* bgnsurface seen */ + int inCurve; /* bgncurve seen */ + int inTrim; /* bgntrim seen */ + int isCurveModified; /* curve changed */ + int isTrimModified; /* trim curves changed */ + int isSurfaceModified; /* surface changed */ + int isDataValid; /* all data is good */ + int numTrims; /* valid trim regions */ + int playBack; + + O_trim** nextTrim; /* place to link o_trim */ + O_curve** nextCurve; /* place to link o_curve */ + O_nurbscurve** nextNurbscurve; /* place to link o_nurbscurve */ + O_pwlcurve** nextPwlcurve; /* place to link o_pwlcurve */ + O_nurbssurface** nextNurbssurface; /* place to link o_nurbssurface */ + + O_surface* currentSurface; + O_trim* currentTrim; + O_curve* currentCurve; + + DisplayList* dl; +}; + +#endif /* __glunurbstess_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/patch.cc b/project/jni/glu/src/libnurbs/internals/patch.cc new file mode 100644 index 000000000..012e7e8e2 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/patch.cc @@ -0,0 +1,492 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * patch.c++ + * + */ + +#include +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "mymath.h" +#include "mystring.h" +#include "patch.h" +#include "mapdesc.h" +#include "quilt.h" +#include "nurbsconsts.h" +#include "simplemath.h" //for glu_abs function in ::singleStep(); + + +/*-------------------------------------------------------------------------- + * Patch - copy patch from quilt and transform control points + *-------------------------------------------------------------------------- + */ + +Patch::Patch(Quilt_ptr geo, REAL* pta, REAL* ptb, Patch* n) +{ + /* pspec[i].range is uninit here */ + mapdesc = geo->mapdesc; + cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; + notInBbox = mapdesc->isBboxSubdividing() ? 1 : 0; + needsSampling = mapdesc->isRangeSampling() ? 1 : 0; + pspec[0].order = geo->qspec[0].order; + pspec[1].order = geo->qspec[1].order; + pspec[0].stride = pspec[1].order * MAXCOORDS; + pspec[1].stride = MAXCOORDS; + + /* transform control points to sampling and culling spaces */ + REAL *ps = geo->cpts; + geo->select( pta, ptb ); + ps += geo->qspec[0].offset; + ps += geo->qspec[1].offset; + ps += geo->qspec[0].index * geo->qspec[0].order * geo->qspec[0].stride; + ps += geo->qspec[1].index * geo->qspec[1].order * geo->qspec[1].stride; + + if( needsSampling ) { + mapdesc->xformSampling( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + spts, pspec[0].stride, pspec[1].stride ); + } + + if( cullval == CULL_ACCEPT ) { + mapdesc->xformCulling( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + cpts, pspec[0].stride, pspec[1].stride ); + } + + if( notInBbox ) { + mapdesc->xformBounding( ps, geo->qspec[0].order, geo->qspec[0].stride, + geo->qspec[1].order, geo->qspec[1].stride, + bpts, pspec[0].stride, pspec[1].stride ); + } + + /* set scale range */ + pspec[0].range[0] = geo->qspec[0].breakpoints[geo->qspec[0].index]; + pspec[0].range[1] = geo->qspec[0].breakpoints[geo->qspec[0].index+1]; + pspec[0].range[2] = pspec[0].range[1] - pspec[0].range[0]; + + pspec[1].range[0] = geo->qspec[1].breakpoints[geo->qspec[1].index]; + pspec[1].range[1] = geo->qspec[1].breakpoints[geo->qspec[1].index+1]; + pspec[1].range[2] = pspec[1].range[1] - pspec[1].range[0]; + + // may need to subdivide to match range of sub-patch + if( pspec[0].range[0] != pta[0] ) { + assert( pspec[0].range[0] < pta[0] ); + Patch lower( *this, 0, pta[0], 0 ); + *this = lower; + } + + if( pspec[0].range[1] != ptb[0] ) { + assert( pspec[0].range[1] > ptb[0] ); + Patch upper( *this, 0, ptb[0], 0 ); + } + + if( pspec[1].range[0] != pta[1] ) { + assert( pspec[1].range[0] < pta[1] ); + Patch lower( *this, 1, pta[1], 0 ); + *this = lower; + } + + if( pspec[1].range[1] != ptb[1] ) { + assert( pspec[1].range[1] > ptb[1] ); + Patch upper( *this, 1, ptb[1], 0 ); + } + checkBboxConstraint(); + next = n; +} + +/*-------------------------------------------------------------------------- + * Patch - subdivide a patch along an isoparametric line + *-------------------------------------------------------------------------- + */ + +Patch::Patch( Patch& upper, int param, REAL value, Patch *n ) +{ + Patch& lower = *this; + + lower.cullval = upper.cullval; + lower.mapdesc = upper.mapdesc; + lower.notInBbox = upper.notInBbox; + lower.needsSampling = upper.needsSampling; + lower.pspec[0].order = upper.pspec[0].order; + lower.pspec[1].order = upper.pspec[1].order; + lower.pspec[0].stride = upper.pspec[0].stride; + lower.pspec[1].stride = upper.pspec[1].stride; + lower.next = n; + + /* reset scale range */ + switch( param ) { + case 0: { + REAL d = (value-upper.pspec[0].range[0]) / upper.pspec[0].range[2]; + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + if( notInBbox ) + mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[1].order, + pspec[1].stride, pspec[0].order, pspec[0].stride ); + + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = value; + lower.pspec[0].range[2] = value - upper.pspec[0].range[0]; + upper.pspec[0].range[0] = value; + upper.pspec[0].range[2] = upper.pspec[0].range[1] - value; + + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = upper.pspec[1].range[1]; + lower.pspec[1].range[2] = upper.pspec[1].range[2]; + break; + } + case 1: { + REAL d = (value-upper.pspec[1].range[0]) / upper.pspec[1].range[2]; + if( needsSampling ) + mapdesc->subdivide( upper.spts, lower.spts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + if( cullval == CULL_ACCEPT ) + mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + if( notInBbox ) + mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[0].order, + pspec[0].stride, pspec[1].order, pspec[1].stride ); + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = upper.pspec[0].range[1]; + lower.pspec[0].range[2] = upper.pspec[0].range[2]; + + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = value; + lower.pspec[1].range[2] = value - upper.pspec[1].range[0]; + upper.pspec[1].range[0] = value; + upper.pspec[1].range[2] = upper.pspec[1].range[1] - value; + break; + } + } + + // inherit bounding box + if( mapdesc->isBboxSubdividing() && ! notInBbox ) + memcpy( lower.bb, upper.bb, sizeof( bb ) ); + + lower.checkBboxConstraint(); + upper.checkBboxConstraint(); +} + +/*-------------------------------------------------------------------------- + * clamp - clamp the sampling rate to a given maximum + *-------------------------------------------------------------------------- + */ + +void +Patch::clamp( void ) +{ + if( mapdesc->clampfactor != N_NOCLAMPING ) { + pspec[0].clamp( mapdesc->clampfactor ); + pspec[1].clamp( mapdesc->clampfactor ); + } +} + +void +Patchspec::clamp( REAL clampfactor ) +{ + if( sidestep[0] < minstepsize ) + sidestep[0] = clampfactor * minstepsize; + if( sidestep[1] < minstepsize ) + sidestep[1] = clampfactor * minstepsize; + if( stepsize < minstepsize ) + stepsize = clampfactor * minstepsize; +} + +void +Patch::checkBboxConstraint( void ) +{ + if( notInBbox && + mapdesc->bboxTooBig( bpts, pspec[0].stride, pspec[1].stride, + pspec[0].order, pspec[1].order, bb ) != 1 ) { + notInBbox = 0; + } +} + +void +Patch::bbox( void ) +{ + if( mapdesc->isBboxSubdividing() ) + mapdesc->surfbbox( bb ); +} + +/*-------------------------------------------------------------------------- + * getstepsize - compute the sampling density across the patch + * and determine if patch needs to be subdivided + *-------------------------------------------------------------------------- + */ + +void +Patch::getstepsize( void ) +{ + pspec[0].minstepsize = pspec[1].minstepsize = 0; + pspec[0].needsSubdivision = pspec[1].needsSubdivision = 0; + + if( mapdesc->isConstantSampling() ) { + // fixed number of samples per patch in each direction + // maxsrate is number of s samples per patch + // maxtrate is number of t samples per patch + pspec[0].getstepsize( mapdesc->maxsrate ); + pspec[1].getstepsize( mapdesc->maxtrate ); + + } else if( mapdesc->isDomainSampling() ) { + // maxsrate is number of s samples per unit s length of domain + // maxtrate is number of t samples per unit t length of domain + pspec[0].getstepsize( mapdesc->maxsrate * pspec[0].range[2] ); + pspec[1].getstepsize( mapdesc->maxtrate * pspec[1].range[2] ); + + } else if( ! needsSampling ) { + pspec[0].singleStep(); + pspec[1].singleStep(); + } else { + // upper bound on path length between sample points + REAL tmp[MAXORDER][MAXORDER][MAXCOORDS]; + const int trstride = sizeof(tmp[0]) / sizeof(REAL); + const int tcstride = sizeof(tmp[0][0]) / sizeof(REAL); + + assert( pspec[0].order <= MAXORDER ); + + /* points have been transformed, therefore they are homogeneous */ + + int val = mapdesc->project( spts, pspec[0].stride, pspec[1].stride, + &tmp[0][0][0], trstride, tcstride, + pspec[0].order, pspec[1].order ); + if( val == 0 ) { + // control points cross infinity, therefore partials are undefined + pspec[0].getstepsize( mapdesc->maxsrate ); + pspec[1].getstepsize( mapdesc->maxtrate ); + } else { + REAL t1 = mapdesc->getProperty( N_PIXEL_TOLERANCE ); +// REAL t2 = mapdesc->getProperty( N_ERROR_TOLERANCE ); + pspec[0].minstepsize = ( mapdesc->maxsrate > 0.0f ) ? + (pspec[0].range[2] / mapdesc->maxsrate) : 0.0f; + pspec[1].minstepsize = ( mapdesc->maxtrate > 0.0f ) ? + (pspec[1].range[2] / mapdesc->maxtrate) : 0.0f; + if( mapdesc->isParametricDistanceSampling() || + mapdesc->isObjectSpaceParaSampling() ) { + + REAL t2; + t2 = mapdesc->getProperty( N_ERROR_TOLERANCE ); + + // t2 is upper bound on the distance between surface and tessellant + REAL ssv[2], ttv[2]; + REAL ss = mapdesc->calcPartialVelocity( ssv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 2, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL st = mapdesc->calcPartialVelocity( 0, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 1, pspec[0].range[2], pspec[1].range[2], -1 ); + REAL tt = mapdesc->calcPartialVelocity( ttv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 2, pspec[0].range[2], pspec[1].range[2], 1 ); + //make sure that ss st and tt are nonnegative: + if(ss <0) ss = -ss; + if(st <0) st = -st; + if(tt <0) tt = -tt; + + if( ss != 0.0 && tt != 0.0 ) { + REAL ttq = sqrtf( (float) ss ); + REAL ssq = sqrtf( (float) tt ); + REAL ds = sqrtf( 4 * t2 * ttq / ( ss * ttq + st * ssq ) ); + REAL dt = sqrtf( 4 * t2 * ssq / ( tt * ssq + st * ttq ) ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + REAL scutoff = 2.0f * t2 / ( pspec[0].range[2] * pspec[0].range[2]); + pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2]; + pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + REAL tcutoff = 2.0f * t2 / ( pspec[1].range[2] * pspec[1].range[2]); + pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2]; + pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2]; + } else if( ss != 0.0 ) { + REAL x = pspec[1].range[2] * st; + REAL ds = ( sqrtf( x * x + 8.0 * t2 * ss ) - x ) / ss; + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + REAL scutoff = 2.0f * t2 / ( pspec[0].range[2] * pspec[0].range[2]); + pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2]; + pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2]; + pspec[1].singleStep(); + } else if( tt != 0.0f ) { + REAL x = pspec[0].range[2] * st; + REAL dt = ( sqrtf( x * x + 8.0f * t2 * tt ) - x ) / tt; + pspec[0].singleStep(); + REAL tcutoff = 2.0f * t2 / ( pspec[1].range[2] * pspec[1].range[2]); + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2]; + pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2]; + } else { + if( 4.0f * t2 > st * pspec[0].range[2] * pspec[1].range[2] ) { + pspec[0].singleStep(); + pspec[1].singleStep(); + } else { + REAL area = 4.0f * t2 / st; + REAL ds = sqrtf( area * pspec[0].range[2] / pspec[1].range[2] ); + REAL dt = sqrtf( area * pspec[1].range[2] / pspec[0].range[2] ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = pspec[0].range[2]; + pspec[0].sidestep[1] = pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = pspec[1].range[2]; + pspec[1].sidestep[1] = pspec[1].range[2]; + } + } + } else if( mapdesc->isPathLengthSampling() || + mapdesc->isObjectSpacePathSampling()) { + // t1 is upper bound on path length + REAL msv[2], mtv[2]; + REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 ); + REAL side_scale = 1.0; + + if( ms != 0.0f ) { + if( mt != 0.0f ) { + REAL ds = t1 / (2.0f*ms); + REAL dt = t1 / (2.0f*mt); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[1]) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].stepsize = ( t1 < ms * pspec[0].range[2] ) ? (t1 / ms) : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (t1 / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (t1 / msv[1]) : pspec[0].range[2]; + + pspec[1].singleStep(); + } + } else { + if( mt != 0.0 ) { + pspec[0].singleStep(); + + pspec[1].stepsize = ( t1 < mt * pspec[1].range[2] ) ? (t1 / mt) : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (t1 / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (t1 / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } + } + } else if( mapdesc->isSurfaceAreaSampling() ) { + // t is the square root of area +/* + REAL msv[2], mtv[2]; + REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 ); + REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 ); + if( ms != 0.0 && mt != 0.0 ) { + REAL d = 1.0 / (ms * mt); + t *= M_SQRT2; + REAL ds = t * sqrtf( d * pspec[0].range[2] / pspec[1].range[2] ); + REAL dt = t * sqrtf( d * pspec[1].range[2] / pspec[0].range[2] ); + pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2]; + pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t ) ? (t / msv[0]) : pspec[0].range[2]; + pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t ) ? (t / msv[1]) : pspec[0].range[2]; + + pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2]; + pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t ) ? (t / mtv[0]) : pspec[1].range[2]; + pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t ) ? (t / mtv[1]) : pspec[1].range[2]; + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } +*/ + } else { + pspec[0].singleStep(); + pspec[1].singleStep(); + } + } + } + + if( mapdesc->minsavings != N_NOSAVINGSSUBDIVISION ) { + REAL savings = 1.0f/(pspec[0].stepsize * pspec[1].stepsize) ; + savings-= (2.0f/( pspec[0].sidestep[0] + pspec[0].sidestep[1] )) * + (2.0f/( pspec[1].sidestep[0] + pspec[1].sidestep[1] )); + + savings *= pspec[0].range[2] * pspec[1].range[2]; + if( savings > mapdesc->minsavings ) { + pspec[0].needsSubdivision = pspec[1].needsSubdivision = 1; + } + } + + if( pspec[0].stepsize < pspec[0].minstepsize ) pspec[0].needsSubdivision = 1; + if( pspec[1].stepsize < pspec[1].minstepsize ) pspec[1].needsSubdivision = 1; + needsSampling = (needsSampling ? needsSamplingSubdivision() : 0); +} + +void +Patchspec::singleStep() +{ + stepsize = sidestep[0] = sidestep[1] = glu_abs(range[2]); +} + +void +Patchspec::getstepsize( REAL max ) // max is number of samples for entire patch +{ + stepsize = ( max >= 1.0 ) ? range[2] / max : range[2]; + if (stepsize < 0.0) { + stepsize = -stepsize; + } + sidestep[0] = sidestep[1] = minstepsize = stepsize; +} + +int +Patch::needsSamplingSubdivision( void ) +{ + return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0; +} + +int +Patch::needsNonSamplingSubdivision( void ) +{ + return notInBbox; +} + +int +Patch::needsSubdivision( int param ) +{ + return pspec[param].needsSubdivision; +} + +int +Patch::cullCheck( void ) +{ + if( cullval == CULL_ACCEPT ) + cullval = mapdesc->cullCheck( cpts, pspec[0].order, pspec[0].stride, + pspec[1].order, pspec[1].stride ); + return cullval; +} + diff --git a/project/jni/glu/src/libnurbs/internals/patch.h b/project/jni/glu/src/libnurbs/internals/patch.h new file mode 100644 index 000000000..324a25938 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/patch.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/* + * patch.h + * + */ + +#ifndef __glupatch_h_ +#define __glupatch_h_ + +#include "types.h" +#include "defines.h" + +class Quilt; +class Mapdesc; + + +struct Pspec { + REAL range[3]; + REAL sidestep[2]; + REAL stepsize; + REAL minstepsize; + int needsSubdivision; +}; + +struct Patchspec : public Pspec { + int order; + int stride; + void clamp( REAL ); + void getstepsize( REAL ); + void singleStep( void ); +}; + +class Patch { +public: +friend class Subdivider; +friend class Quilt; +friend class Patchlist; + Patch( Quilt *, REAL*, REAL *, Patch * ); + Patch( Patch &, int, REAL, Patch * ); + void bbox( void ); + void clamp( void ); + void getstepsize( void ); + int cullCheck( void ); + int needsSubdivision( int ); + int needsSamplingSubdivision( void ); + int needsNonSamplingSubdivision( void ); + + int get_uorder() {return pspec[0].order;} + int get_vorder() {return pspec[1].order;} + +private: + + Mapdesc* mapdesc; + Patch* next; + int cullval; + int notInBbox; + int needsSampling; + REAL cpts[MAXORDER*MAXORDER*MAXCOORDS]; //culling pts + REAL spts[MAXORDER*MAXORDER*MAXCOORDS]; //sampling pts + REAL bpts[MAXORDER*MAXORDER*MAXCOORDS]; //bbox pts + Patchspec pspec[2]; + void checkBboxConstraint( void ); + REAL bb[2][MAXCOORDS]; +}; +#endif /* __glupatch_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/patchlist.cc b/project/jni/glu/src/libnurbs/internals/patchlist.cc new file mode 100644 index 000000000..989d2dd00 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/patchlist.cc @@ -0,0 +1,170 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * patchlist.c++ + * + */ + +#include +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "quilt.h" +#include "patchlist.h" +#include "patch.h" +#include "nurbsconsts.h" + +Patchlist::Patchlist( Quilt *quilts, REAL *pta, REAL *ptb ) +{ + patch = 0; + for( Quilt *q = quilts; q; q = q->next ) + patch = new Patch( q, pta, ptb, patch ); + pspec[0].range[0] = pta[0]; + pspec[0].range[1] = ptb[0]; + pspec[0].range[2] = ptb[0] - pta[0]; + + pspec[1].range[0] = pta[1]; + pspec[1].range[1] = ptb[1]; + pspec[1].range[2] = ptb[1] - pta[1]; +} + +Patchlist::Patchlist( Patchlist &upper, int param, REAL value) +{ + Patchlist &lower = *this; + patch = 0; + for( Patch *p = upper.patch; p; p = p->next ) + patch = new Patch( *p, param, value, patch ); + + if( param == 0 ) { + lower.pspec[0].range[0] = upper.pspec[0].range[0]; + lower.pspec[0].range[1] = value; + lower.pspec[0].range[2] = value - upper.pspec[0].range[0]; + upper.pspec[0].range[0] = value; + upper.pspec[0].range[2] = upper.pspec[0].range[1] - value; + lower.pspec[1] = upper.pspec[1]; + } else { + lower.pspec[0] = upper.pspec[0]; + lower.pspec[1].range[0] = upper.pspec[1].range[0]; + lower.pspec[1].range[1] = value; + lower.pspec[1].range[2] = value - upper.pspec[1].range[0]; + upper.pspec[1].range[0] = value; + upper.pspec[1].range[2] = upper.pspec[1].range[1] - value; + } +} + +Patchlist::~Patchlist() +{ + while( patch ) { + Patch *p = patch; + patch = patch->next; + delete p; + } +} + +int +Patchlist::cullCheck( void ) +{ + for( Patch *p = patch; p; p = p->next ) + if( p->cullCheck() == CULL_TRIVIAL_REJECT ) + return CULL_TRIVIAL_REJECT; + return CULL_ACCEPT; +} + +void +Patchlist::getRanges(REAL ranges[4]) +{ + ranges[0] = pspec[0].range[0]; + ranges[1] = pspec[0].range[1]; + ranges[2] = pspec[1].range[0]; + ranges[3] = pspec[1].range[1]; +} + +void +Patchlist::getstepsize( void ) +{ + pspec[0].stepsize = pspec[0].range[2]; + pspec[0].sidestep[0] = pspec[0].range[2]; + pspec[0].sidestep[1] = pspec[0].range[2]; + + pspec[1].stepsize = pspec[1].range[2]; + pspec[1].sidestep[0] = pspec[1].range[2]; + pspec[1].sidestep[1] = pspec[1].range[2]; + + for( Patch *p = patch; p; p = p->next ) { + p->getstepsize(); + p->clamp(); + pspec[0].stepsize = ((p->pspec[0].stepsize < pspec[0].stepsize) ? p->pspec[0].stepsize : pspec[0].stepsize); + pspec[0].sidestep[0] = ((p->pspec[0].sidestep[0] < pspec[0].sidestep[0]) ? p->pspec[0].sidestep[0] : pspec[0].sidestep[0]); + pspec[0].sidestep[1] = ((p->pspec[0].sidestep[1] < pspec[0].sidestep[1]) ? p->pspec[0].sidestep[1] : pspec[0].sidestep[1]); + pspec[1].stepsize = ((p->pspec[1].stepsize < pspec[1].stepsize) ? p->pspec[1].stepsize : pspec[1].stepsize); + pspec[1].sidestep[0] = ((p->pspec[1].sidestep[0] < pspec[1].sidestep[0]) ? p->pspec[1].sidestep[0] : pspec[1].sidestep[0]); + pspec[1].sidestep[1] = ((p->pspec[1].sidestep[1] < pspec[1].sidestep[1]) ? p->pspec[1].sidestep[1] : pspec[1].sidestep[1]); + } +} + +void +Patchlist::bbox( void ) +{ + for( Patch *p = patch; p; p = p->next ) + p->bbox(); +} + +int +Patchlist::needsNonSamplingSubdivision( void ) +{ + notInBbox = 0; + for( Patch *p = patch; p; p = p->next ) + notInBbox |= p->needsNonSamplingSubdivision(); + return notInBbox; +} + +int +Patchlist::needsSamplingSubdivision( void ) +{ + pspec[0].needsSubdivision = 0; + pspec[1].needsSubdivision = 0; + + for( Patch *p = patch; p; p = p->next ) { + pspec[0].needsSubdivision |= p->pspec[0].needsSubdivision; + pspec[1].needsSubdivision |= p->pspec[0].needsSubdivision; + } + return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0; +} + +int +Patchlist::needsSubdivision( int param ) +{ + return pspec[param].needsSubdivision; +} diff --git a/project/jni/glu/src/libnurbs/internals/patchlist.h b/project/jni/glu/src/libnurbs/internals/patchlist.h new file mode 100644 index 000000000..9bfc5b47a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/patchlist.h @@ -0,0 +1,92 @@ +/* + * 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. + */ + +/* + * patchlist.h + * + */ + +#ifndef __glupatchlist_h_ +#define __glupatchlist_h_ + +#include "types.h" +#include "defines.h" +#include "patch.h" + +class Quilt; + +class Patchlist { +friend class Subdivider; +public: + Patchlist( Quilt *, REAL *, REAL * ); + Patchlist( Patchlist &, int , REAL ); + ~Patchlist(); + void bbox(); + int cullCheck( void ); + void getstepsize( void ); + int needsNonSamplingSubdivision( void ); + int needsSamplingSubdivision( void ); + int needsSubdivision( int ); + REAL getStepsize( int ); + void getRanges(REAL ranges[4]); + + int get_uorder(); + int get_vorder(); +private: + Patch *patch; + int notInBbox; + int needsSampling; + Pspec pspec[2]; +}; + +inline REAL +Patchlist::getStepsize( int param ) +{ + return pspec[param].stepsize; +} + +inline int +Patchlist::get_uorder() +{ + return patch->get_uorder(); + +} + +inline int + Patchlist::get_vorder() +{ + return patch->get_vorder(); +} + + + + + +#endif /* __glupatchlist_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/pwlarc.h b/project/jni/glu/src/libnurbs/internals/pwlarc.h new file mode 100644 index 000000000..4e11954fe --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/pwlarc.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + +/* + * pwlarc.h + * + */ + +#ifndef __glupwlarc_h_ +#define __glupwlarc_h_ + +#include "myassert.h" +#include "nurbsconsts.h" + +class TrimVertex; + +/* a piecewise-linear arc */ +class PwlArc: public PooledObj +{ + public: + TrimVertex* pts; /* sample points */ + int npts; /* number of sample points */ + long type; /* curve type */ + inline PwlArc(void); + inline PwlArc(int, TrimVertex*); + inline PwlArc(int, TrimVertex*, long); +}; + +inline PwlArc::PwlArc(void) +{ + type=N_P2D; + pts=0; + npts=-1; +} + +inline PwlArc::PwlArc(int _npts, TrimVertex* _pts) +{ + pts=_pts; + npts=_npts; + type=N_P2D; +} + +inline PwlArc::PwlArc(int _npts, TrimVertex* _pts, long _type) +{ + pts=_pts; + npts=_npts; + type=_type; +} + +#endif /* __glupwlarc_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/quilt.cc b/project/jni/glu/src/libnurbs/internals/quilt.cc new file mode 100644 index 000000000..5b933cb15 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/quilt.cc @@ -0,0 +1,253 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * quilt.c++ + * + */ + +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "quilt.h" +#include "backend.h" +#include "mapdesc.h" +#include "flist.h" +#include "knotvector.h" +#include "patchlist.h" +#include "math.h" //fglu_abs() +#include "simplemath.h" //min() + +/* local preprocessor definitions */ +#define DEF_PATCH_STEPSIZE 0.4f +#define fsizeof(x) (sizeof(x)/sizeof(REAL)) + +Quilt::Quilt( Mapdesc *_mapdesc ) +{ + mapdesc = _mapdesc; +} + +void +Quilt::deleteMe( Pool& p ) +{ + for( Quiltspec *q=qspec; q != eqspec; q++ ) { + if( q->breakpoints) delete[] q->breakpoints; + q->breakpoints = 0; + } + if( cpts ) delete[] cpts; + cpts = 0; + PooledObj::deleteMe( p ); +} + +void +Quilt::show( void ) +{ +} + +/*-------------------------------------------------------------------------- + * Quilt::select - find which map in each quilt contains the points + * pta and ptb with pta[i] < ptb[i] + *-------------------------------------------------------------------------- + */ + +void +Quilt::select( REAL *pta, REAL *ptb ) +{ + int dim = (int)(eqspec - qspec); + int i, j; + for( i=0; i=0; j-- ) + if( (qspec[i].breakpoints[j] <= pta[i] ) && + (ptb[i] <= qspec[i].breakpoints[j+1] ) ) + break; + assert( j != -1 ); + qspec[i].index = j; + } +} + +void +Quilt::download( Backend &backend ) +{ + if( getDimension() == 2 ) { + REAL *ps = cpts; + ps += qspec[0].offset; + ps += qspec[1].offset; + ps += qspec[0].index * qspec[0].order * qspec[0].stride; + ps += qspec[1].index * qspec[1].order * qspec[1].stride; + backend.surfpts( mapdesc->getType(), ps, + qspec[0].stride, + qspec[1].stride, + qspec[0].order, + qspec[1].order, + qspec[0].breakpoints[qspec[0].index], + qspec[0].breakpoints[qspec[0].index+1], + qspec[1].breakpoints[qspec[1].index], + qspec[1].breakpoints[qspec[1].index+1] ); + } else { + REAL *ps = cpts; + ps += qspec[0].offset; + ps += qspec[0].index * qspec[0].order * qspec[0].stride; + backend.curvpts( mapdesc->getType(), ps, + qspec[0].stride, + qspec[0].order, + qspec[0].breakpoints[qspec[0].index], + qspec[0].breakpoints[qspec[0].index+1] ); + } +} + +/*-------------------------------------------------------------------------- + * Quilt::downloadAll - download each map that contains the current patch + *-------------------------------------------------------------------------- + */ + +void +Quilt::downloadAll( REAL *pta, REAL *ptb, Backend &backend ) +{ + for( Quilt *m = this; m; m=m->next ) { + m->select( pta, ptb ); + m->download( backend ); + } +} + +/*-------------------------------------------------------------------------- + * Quilt::isCulled - determine if an entire quilt is trivially rejected. + *-------------------------------------------------------------------------- + */ + +int +Quilt::isCulled( void ) +{ + if( mapdesc->isCulling() ) + return mapdesc->xformAndCullCheck( cpts + qspec[0].offset + qspec[1].offset, + qspec[0].order * qspec[0].width, qspec[0].stride, + qspec[1].order * qspec[1].width, qspec[1].stride ); + else + return CULL_ACCEPT; +} + +/*--------------------------------------------------------------------------- + * Quilt::getRange - retrieve the valid paramater range of a set of quilts + *--------------------------------------------------------------------------- + */ +void +Quilt::getRange( REAL *from, REAL *to, Flist& slist, Flist &tlist ) +{ + getRange( from, to, 0, slist ); + getRange( from, to, 1, tlist ); +} + +/*--------------------------------------------------------------------------- + * Quilt::getRange - retrieve the valid paramater range of a set of quilts + *--------------------------------------------------------------------------- + */ +void +Quilt::getRange( REAL *from, REAL *to, int i, Flist &list ) +{ + Quilt *maps = this; + from[i] = maps->qspec[i].breakpoints[0]; + to[i] = maps->qspec[i].breakpoints[maps->qspec[i].width]; + int maxpts = 0; + Quilt_ptr m; + for( m=maps; m; m=m->next ) { + if( m->qspec[i].breakpoints[0] > from[i] ) + from[i] = m->qspec[i].breakpoints[0]; + if( m->qspec[i].breakpoints[m->qspec[i].width] < to[i] ) + to[i] = m->qspec[i].breakpoints[m->qspec[i].width]; + maxpts += m->qspec[i].width + 1; + } + + list.grow( maxpts ); + + for( m=maps; m; m=m->next ) + for( int j=0; j<=m->qspec[i].width; j++ ) { + list.add( m->qspec[i].breakpoints[j] ); + } + + list.filter( ); + list.taper( from[i], to[i] ); +} + +void +Quilt::getRange( REAL *from, REAL *to, Flist& slist ) +{ + getRange( from, to, 0, slist ); +} + +void +Quilt::findRates( Flist& slist, Flist& tlist, REAL rate[2] ) +{ + findSampleRates( slist, tlist ); + rate[0] = qspec[0].step_size; + rate[1] = qspec[1].step_size; + + for( Quilt *q = next; q; q = q->next ) { + q->findSampleRates( slist, tlist ); + if( q->qspec[0].step_size < rate[0] ) + rate[0] = q->qspec[0].step_size; + if( q->qspec[1].step_size < rate[1] ) + rate[1] = q->qspec[1].step_size; + } +} + +void +Quilt::findSampleRates( Flist& slist, Flist& tlist ) +{ + qspec[0].step_size = DEF_PATCH_STEPSIZE * + (qspec[0].breakpoints[qspec[0].width] - qspec[0].breakpoints[0]); + qspec[1].step_size = DEF_PATCH_STEPSIZE * + (qspec[1].breakpoints[qspec[1].width] - qspec[1].breakpoints[0]); + + for( int i = slist.start; i < slist.end-1; i++ ) { + for( int j = tlist.start; j < tlist.end-1; j++ ) { + + REAL pta[2], ptb[2]; + pta[0] = slist.pts[i]; + ptb[0] = slist.pts[i+1]; + pta[1] = tlist.pts[j]; + ptb[1] = tlist.pts[j+1]; + Patchlist patchlist( this, pta, ptb ); + patchlist.getstepsize(); + + { + float edge_len_s = min(glu_abs(ptb[0]-pta[0]),1.0); + float edge_len_t = min(glu_abs(ptb[1]-pta[1]),1.0); + + if( patchlist.getStepsize(0)/edge_len_s < qspec[0].step_size ) + qspec[0].step_size = patchlist.getStepsize(0)/edge_len_s; + if( patchlist.getStepsize(1)/edge_len_t < qspec[1].step_size ) + qspec[1].step_size = patchlist.getStepsize(1)/edge_len_t; + } + } + } +} diff --git a/project/jni/glu/src/libnurbs/internals/quilt.h b/project/jni/glu/src/libnurbs/internals/quilt.h new file mode 100644 index 000000000..1dc24ef39 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/quilt.h @@ -0,0 +1,96 @@ +/* + * 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. + */ + +/* + * quilt.h + * + */ + +#ifndef __gluquilt_h_ +#define __gluquilt_h_ + +#include "defines.h" +#include "bufpool.h" +#include "types.h" + +class Backend; +class Mapdesc; +class Flist; +struct Knotvector; + +/* constants for memory allocation of NURBS to Bezier conversion */ +#define MAXDIM 2 + +/* a specification for a dimension of a quilt */ +struct Quiltspec +{ + int stride; /* words between points */ + int width; /* number of segments */ + int offset; /* words to first point */ + int order; /* order */ + int index; /* current segment number */ + int bdry[2]; /* boundary edge flag */ + REAL step_size; + Knot* breakpoints; +}; + +typedef Quiltspec* Quiltspec_ptr; + +/* an array of bezier patches */ +class Quilt: public PooledObj +{ + public: + Quilt(Mapdesc*); + Mapdesc* mapdesc; /* map descriptor */ + REAL* cpts; /* control points */ + Quiltspec qspec[MAXDIM]; /* the dimensional data */ + Quiltspec_ptr eqspec; /* qspec trailer */ + Quilt* next; /* next quilt in linked list */ + + public: + void deleteMe(Pool&); + void toBezier(Knotvector&, INREAL*, long); + void toBezier(Knotvector&, Knotvector&, INREAL*, long); + void select(REAL*, REAL*); + int getDimension(void){ return (int)(eqspec-qspec); } + void download(Backend&); + void downloadAll(REAL*, REAL*, Backend&); + int isCulled(void); + void getRange(REAL*, REAL*, Flist&, Flist&); + void getRange(REAL*, REAL*, int, Flist&); + void getRange(REAL*, REAL*, Flist&); + void findRates(Flist& slist, Flist& tlist, REAL[2]); + void findSampleRates(Flist& slist, Flist& tlist); + void show(); +}; + +typedef class Quilt* Quilt_ptr; + +#endif /* __gluquilt_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/reader.cc b/project/jni/glu/src/libnurbs/internals/reader.cc new file mode 100644 index 000000000..6135eef60 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/reader.cc @@ -0,0 +1,146 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * reader.c++ + * + */ + +#include +#include "glimports.h" +#include "nurbsconsts.h" +#include "reader.h" +#include "trimvertex.h" +#include "simplemath.h" + +//when read a pwlCurve, if two consecutive points are the same, then +//eliminate one of them. This makes the tessellator more robust. The spec +//assumes the application makes sure there are no redundant points. +//but in Inspector, the trim curves seem to have redundant points a lot. +//I guess other similar users may have the same problem. + +#define ELIMINATE_REDUNDANT_POINTS + +#ifdef ELIMINATE_REDUNDANT_POINTS +#define equal(x,y) ( glu_abs(x-y) <= 0.00001) +#endif + +#ifdef ELIMINATE_REDUNDANT_POINTS +O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts ) +{ + next = 0; + used = 0; + owner = 0; + pts = trimpts; + npts = (int) count; + int i; + + /* copy user data into internal trimming data structures */ + switch( _type ) { + case N_P2D: { + TrimVertex *v = pts; + TrimVertex *prev = NULL; + int num = 0; + int doit; + for(i=0; iparam[0], array[0]) && equal(prev->param[1], array[1])) + { + doit = 0; + } + } + + if(doit) + { + v->param[0] = (REAL) array[0]; + v->param[1] = (REAL) array[1]; + prev = v; + v++; + num++; + } + array = (INREAL *) (((char *) array) + byte_stride); + } + npts = num; + break; + } + case N_P2DR: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0] / (REAL) array[2]; + v->param[1] = (REAL) array[1] / (REAL) array[2]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + } +} +#else +O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts ) +{ + next = 0; + used = 0; + owner = 0; + pts = trimpts; + npts = (int) count; + + /* copy user data into internal trimming data structures */ + switch( _type ) { + case N_P2D: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0]; + v->param[1] = (REAL) array[1]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + case N_P2DR: { + TrimVertex *v = pts; + for( TrimVertex *lastv = v + count; v != lastv; v++ ) { + v->param[0] = (REAL) array[0] / (REAL) array[2]; + v->param[1] = (REAL) array[1] / (REAL) array[2]; + array = (INREAL *) (((char *) array) + byte_stride); + } + break; + } + } +} +#endif + + + + + diff --git a/project/jni/glu/src/libnurbs/internals/reader.h b/project/jni/glu/src/libnurbs/internals/reader.h new file mode 100644 index 000000000..8a8dcebb5 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/reader.h @@ -0,0 +1,132 @@ +/* + * 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. + */ + +/* + * reader.h + * + */ + +#ifndef __glureader_h_ +#define __glureader_h_ + +#include "bufpool.h" +#include "types.h" + +enum Curvetype { ct_nurbscurve, ct_pwlcurve, ct_none }; + +struct Property; +struct O_surface; +struct O_nurbssurface; +struct O_trim; +class O_pwlcurve; +struct O_nurbscurve; +struct O_curve; +class Quilt; +class TrimVertex; + + +struct O_curve : public PooledObj { + union { + O_nurbscurve *o_nurbscurve; + O_pwlcurve *o_pwlcurve; + } curve; + Curvetype curvetype; /* arc type: pwl or nurbs */ + O_curve * next; /* next arc in loop */ + O_surface * owner; /* owning surface */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + long nuid; + O_curve() { next = 0; used = 0; owner = 0; + curve.o_pwlcurve = 0; } + }; + +struct O_nurbscurve : public PooledObj { + Quilt *bezier_curves; /* array of bezier curves */ + long type; /* range descriptor */ + REAL tesselation; /* tesselation tolerance */ + int method; /* tesselation method */ + O_nurbscurve * next; /* next curve in list */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + O_curve * owner; /* owning curve */ + O_nurbscurve( long _type ) + { type = _type; owner = 0; next = 0; used = 0; } + }; + +class O_pwlcurve : public PooledObj { +public: + TrimVertex *pts; /* array of trim vertices */ + int npts; /* number of trim vertices */ + O_pwlcurve * next; /* next curve in list */ + int used; /* curve called in cur surf */ + int save; /* 1 if in display list */ + O_curve * owner; /* owning curve */ + O_pwlcurve( long, long, INREAL *, long, TrimVertex * ); + }; + +struct O_trim : public PooledObj { + O_curve *o_curve; /* closed trim loop */ + O_trim * next; /* next loop along trim */ + int save; /* 1 if in display list */ + O_trim() { next = 0; o_curve = 0; } + }; + +struct O_nurbssurface : public PooledObj { + Quilt * bezier_patches;/* array of bezier patches */ + long type; /* range descriptor */ + O_surface * owner; /* owning surface */ + O_nurbssurface * next; /* next surface in chain */ + int save; /* 1 if in display list */ + int used; /* 1 if prev called in block */ + O_nurbssurface( long _type ) + { type = _type; owner = 0; next = 0; used = 0; } + }; + +struct O_surface : public PooledObj { + O_nurbssurface * o_nurbssurface; /* linked list of surfaces */ + O_trim * o_trim; /* list of trim loops */ + int save; /* 1 if in display list */ + long nuid; + O_surface() { o_trim = 0; o_nurbssurface = 0; } + }; + +struct Property : public PooledObj { + long type; + long tag; + REAL value; + int save; /* 1 if in display list */ + Property( long _type, long _tag, INREAL _value ) + { type = _type; tag = _tag; value = (REAL) _value; } + Property( long _tag, INREAL _value ) + { type = 0; tag = _tag; value = (REAL) _value; } + }; + +class NurbsTessellator; +#endif /* __glureader_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/renderhints.cc b/project/jni/glu/src/libnurbs/internals/renderhints.cc new file mode 100644 index 000000000..8b56cf8dc --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/renderhints.cc @@ -0,0 +1,132 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "mystdio.h" +#include "renderhints.h" +#include "defines.h" +#include "nurbsconsts.h" + + +/*-------------------------------------------------------------------------- + * Renderhints::Renderhints - set all window specific options + *-------------------------------------------------------------------------- + */ +Renderhints::Renderhints() +{ + display_method=N_FILL; + errorchecking=N_MSG; + subdivisions=6.0f; + tmp1=0.0f; +} + +void +Renderhints::init( void ) +{ + maxsubdivisions = (int) subdivisions; + if( maxsubdivisions < 0 ) maxsubdivisions = 0; + + + if( display_method == N_FILL ) { + wiretris = 0; + wirequads = 0; + } else if( display_method == N_OUTLINE_TRI ) { + wiretris = 1; + wirequads = 0; + } else if( display_method == N_OUTLINE_QUAD ) { + wiretris = 0; + wirequads = 1; + } else { + wiretris = 1; + wirequads = 1; + } +} + +int +Renderhints::isProperty( long property ) +{ + switch ( property ) { + case N_DISPLAY: + case N_ERRORCHECKING: + case N_SUBDIVISIONS: + case N_TMP1: + return 1; + default: + return 0; + } +} + +REAL +Renderhints::getProperty( long property ) +{ + switch ( property ) { + case N_DISPLAY: + return display_method; + case N_ERRORCHECKING: + return errorchecking; + case N_SUBDIVISIONS: + return subdivisions; + case N_TMP1: + return tmp1; + default: + abort(); + return -1; // not necessary, needed to shut up compiler + } +} + +void +Renderhints::setProperty( long property, REAL value ) +{ + switch ( property ) { + case N_DISPLAY: + display_method = value; + break; + case N_ERRORCHECKING: + errorchecking = value; + break; + case N_SUBDIVISIONS: + subdivisions = value; + break; + case N_TMP1: /* unused */ + tmp1 = value; + break; + default: + abort(); + break; + } +} diff --git a/project/jni/glu/src/libnurbs/internals/renderhints.h b/project/jni/glu/src/libnurbs/internals/renderhints.h new file mode 100644 index 000000000..5d527d0a1 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/renderhints.h @@ -0,0 +1,59 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glurenderhints_h_ +#define __glurenderhints_h_ + +#include "types.h" + +class Renderhints { +public: + Renderhints( void ); + void init( void ); + int isProperty( long ); + REAL getProperty( long ); + void setProperty( long, REAL ); + + REAL display_method; /* display mode */ + REAL errorchecking; /* activate error checking */ + REAL subdivisions; /* maximum number of subdivisions per patch */ + REAL tmp1; /* unused */ + + int displaydomain; + int maxsubdivisions; + int wiretris; + int wirequads; +}; + +#endif /* __glurenderhints_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/simplemath.h b/project/jni/glu/src/libnurbs/internals/simplemath.h new file mode 100644 index 000000000..75633157e --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/simplemath.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +/* + * simplemath.h + * + */ + +#ifndef __glusimplemath_h_ +#define __glusimplemath_h_ + +/* simple inline routines */ + +inline int max(int x, int y) { return (xy) ? y : x; } + +inline REAL glu_abs(REAL x) { return (x<0.0) ? -x : x; } + +#endif /* __glusimplemath_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/slicer.cc b/project/jni/glu/src/libnurbs/internals/slicer.cc new file mode 100644 index 000000000..8e8dea1ce --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/slicer.cc @@ -0,0 +1,1450 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * slicer.c++ + * + */ + +#include +#include +#include +#include "glimports.h" +#include "mystdio.h" +#include "myassert.h" +#include "bufpool.h" +#include "slicer.h" +#include "backend.h" +#include "arc.h" +#include "gridtrimvertex.h" +#include "simplemath.h" +#include "trimvertex.h" +#include "varray.h" +#include "displaymode.h" + +#include "polyUtil.h" // for area() + +#include "gles_evaluator.h" +#include "glues.h" + +#define max(a,b) ((a>b)? a:b) +#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/ +#define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle + +/******triangulate a monotone polygon**************/ +#include "monoTriangulation.h" + +inline int compInY(REAL a[2], REAL b[2]) +{ + if(a[1] < b[1]) + return -1; + else if (a[1] > b[1]) + return 1; + else if(a[0] > b[0]) + return 1; + else return -1; +} + +void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream) +{ + int i; + //find the top, bottom, increasing and decreasing chain + //then call monoTrianulation + Arc_ptr jarc, temp; + Arc_ptr top; + Arc_ptr bot; + top = bot = loop; + if(compInY(loop->tail(), loop->prev->tail()) < 0) + { + //first find bot + for(temp = loop->next; temp != loop; temp = temp->next) + { + if(compInY(temp->tail(), temp->prev->tail()) > 0) + break; + } + bot = temp->prev; + //then find top + for(temp=loop->prev; temp != loop; temp = temp->prev) + { + if(compInY(temp->tail(), temp->prev->tail()) > 0) + break; + } + top = temp; + } + else //loop > loop->prev + { + for(temp=loop->next; temp != loop; temp = temp->next) + { + if(compInY(temp->tail(), temp->prev->tail()) < 0) + break; + } + top = temp->prev; + for(temp=loop->prev; temp != loop; temp = temp->prev) + { + if(compInY(temp->tail(), temp->prev->tail()) < 0) + break; + } + bot = temp; + } + //creat increase and decrease chains + vertexArray inc_chain(50); //this is a dynamci array + for(i=1; i<=top->pwlArc->npts-2; i++) + { + //the first vertex is the top which doesn't below to inc_chain + inc_chain.appendVertex(top->pwlArc->pts[i].param); + } + for(jarc=top->next; jarc != bot; jarc = jarc->next) + { + for(i=0; i<=jarc->pwlArc->npts-2; i++) + { + inc_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + + } + vertexArray dec_chain(50); + for(jarc = top->prev; jarc != bot; jarc = jarc->prev) + { + for(i=jarc->pwlArc->npts-2; i>=0; i--) + { + dec_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + } + for(i=bot->pwlArc->npts-2; i>=1; i--) + { + dec_chain.appendVertex(jarc->pwlArc->pts[i].param); + } + + monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0, + &dec_chain, 0, &backend); + +} + +/********tesselate a rectanlge (OPTIMIZATION**************/ +static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend); + +static Int is_rect(Arc_ptr loop) +{ + Int nlines =1; + for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next) + { + nlines++; + if(nlines == 5) + break; + } + if(nlines != 4) + return 0; + + if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) && + (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) && + (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) && + (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO) + ) + return 1; + else if + ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) && + (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) && + (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) && + (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO) + ) + return 1; + else + return 0; +} + +int primitive_type; +int primitive_count; +int max_primitives; +REAL* enormals; +REAL* evertices; +REAL startvtx[3]; +REAL startnrm[3]; +REAL prevvtx[3]; +REAL prevnrm[3]; + +#define PRIMITIVES_INCREMENT 256 + +void OPT_START(GLuint type) +{ + primitive_type=type; + primitive_count=0; + max_primitives=PRIMITIVES_INCREMENT; + + enormals=(REAL*)malloc(sizeof(REAL)*3*max_primitives); + assert(enormals); + evertices=(REAL*)malloc(sizeof(REAL)*3*max_primitives); + assert(evertices); +} + +void OPT_OUTVERT(TrimVertex& vv, Backend& backend, REAL* retPoint, REAL* retNormal) +{ + /* increase vertex and normal buffers size */ + if (primitive_count+3>=max_primitives) + { + max_primitives+=PRIMITIVES_INCREMENT; + enormals=(REAL*)realloc(enormals, sizeof(REAL)*3*max_primitives); + assert(enormals); + evertices=(REAL*)realloc(evertices, sizeof(REAL)*3*max_primitives); + assert(evertices); + } + + backend.tmeshvert(&vv, retPoint, retNormal); + switch (primitive_type) + { + case GL_TRIANGLE_FAN: + switch (backend.get_output_style()) + { + case N_MESHFILL: + evertices[primitive_count*3+0]=retPoint[0]; + evertices[primitive_count*3+1]=retPoint[1]; + evertices[primitive_count*3+2]=retPoint[2]; + enormals[primitive_count*3+0]=retNormal[0]; + enormals[primitive_count*3+1]=retNormal[1]; + enormals[primitive_count*3+2]=retNormal[2]; + primitive_count++; + break; + case N_MESHLINE: + if (primitive_count==0) + { + /* Store start vertex, centre of triangle fan */ + startvtx[0]=retPoint[0]; + startvtx[1]=retPoint[1]; + startvtx[2]=retPoint[2]; + startnrm[0]=retNormal[0]; + startnrm[1]=retNormal[1]; + startnrm[2]=retNormal[2]; + } + + if (primitive_count%3==0) + { + /* Insert new triangle vertices */ + evertices[primitive_count*3+0]=startvtx[0]; + evertices[primitive_count*3+1]=startvtx[1]; + evertices[primitive_count*3+2]=startvtx[2]; + enormals[primitive_count*3+0]=startnrm[0]; + enormals[primitive_count*3+1]=startnrm[1]; + enormals[primitive_count*3+2]=startnrm[2]; + primitive_count++; + + evertices[primitive_count*3+0]=prevvtx[0]; + evertices[primitive_count*3+1]=prevvtx[1]; + evertices[primitive_count*3+2]=prevvtx[2]; + enormals[primitive_count*3+0]=prevnrm[0]; + enormals[primitive_count*3+1]=prevnrm[1]; + enormals[primitive_count*3+2]=prevnrm[2]; + primitive_count++; + } + + /* Store current vertex */ + evertices[primitive_count*3+0]=retPoint[0]; + evertices[primitive_count*3+1]=retPoint[1]; + evertices[primitive_count*3+2]=retPoint[2]; + enormals[primitive_count*3+0]=retNormal[0]; + enormals[primitive_count*3+1]=retNormal[1]; + enormals[primitive_count*3+2]=retNormal[2]; + primitive_count++; + + /* Store current vertex as previous */ + prevvtx[0]=retPoint[0]; + prevvtx[1]=retPoint[1]; + prevvtx[2]=retPoint[2]; + prevnrm[0]=retNormal[0]; + prevnrm[1]=retNormal[1]; + prevnrm[2]=retNormal[2]; + break; + } + break; + case GL_TRIANGLE_STRIP: + switch (backend.get_output_style()) + { + case N_MESHFILL: + evertices[primitive_count*3+0]=retPoint[0]; + evertices[primitive_count*3+1]=retPoint[1]; + evertices[primitive_count*3+2]=retPoint[2]; + enormals[primitive_count*3+0]=retNormal[0]; + enormals[primitive_count*3+1]=retNormal[1]; + enormals[primitive_count*3+2]=retNormal[2]; + primitive_count++; + break; + case N_MESHLINE: + switch (primitive_count%4) + { + case 0: + case 1: + evertices[primitive_count*3+0]=retPoint[0]; + evertices[primitive_count*3+1]=retPoint[1]; + evertices[primitive_count*3+2]=retPoint[2]; + enormals[primitive_count*3+0]=retNormal[0]; + enormals[primitive_count*3+1]=retNormal[1]; + enormals[primitive_count*3+2]=retNormal[2]; + primitive_count++; + break; + case 2: + evertices[(primitive_count+1)*3+0]=retPoint[0]; + evertices[(primitive_count+1)*3+1]=retPoint[1]; + evertices[(primitive_count+1)*3+2]=retPoint[2]; + enormals[(primitive_count+1)*3+0]=retNormal[0]; + enormals[(primitive_count+1)*3+1]=retNormal[1]; + enormals[(primitive_count+1)*3+2]=retNormal[2]; + primitive_count++; + break; + case 3: + evertices[(primitive_count-1)*3+0]=retPoint[0]; + evertices[(primitive_count-1)*3+1]=retPoint[1]; + evertices[(primitive_count-1)*3+2]=retPoint[2]; + enormals[(primitive_count-1)*3+0]=retNormal[0]; + enormals[(primitive_count-1)*3+1]=retNormal[1]; + enormals[(primitive_count-1)*3+2]=retNormal[2]; + primitive_count++; + break; + } + break; + } + break; + } +} + +void OPT_END(Backend& backend) +{ + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, evertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, enormals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + switch (primitive_type) + { + case GL_TRIANGLE_FAN: + switch (backend.get_output_style()) + { + case N_MESHFILL: + glDrawArrays(GL_TRIANGLE_FAN, 0, primitive_count); + break; + case N_MESHLINE: + { + int jt; + + for (jt=0; jttail()[1] == loop->head()[1]) + { + if(loop->tail()[1] > loop->prev->prev->tail()[1]) + { + top = loop; + } + else + { + top = loop->prev->prev; + } + } + else + { + if(loop->tail()[0] > loop->prev->prev->tail()[0]) + { + //loop is the right arc + top = loop->next; + } + else + { + top = loop->prev; + } + } + left=top->next; + bot=left->next; + right=bot->next; + + // if u, v are both nonlinear, then if the + // boundary is tessellated dense, we also + // sample the inside to get a better tesslletant. + if ((!ulinear) && (!vlinear)) + { + int nu = top->pwlArc->npts; + if(nu < bot->pwlArc->npts) + nu = bot->pwlArc->npts; + int nv = left->pwlArc->npts; + if(nv < right->pwlArc->npts) + nv = right->pwlArc->npts; + } + + if(TB_or_LR == 1) + triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); + else if(TB_or_LR == -1) + triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); + else + { + Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts; + Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts; + + if(maxPointsTB < maxPointsLR) + triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend); + else + triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend); + } +} + +static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend) +{ + Int d, topd_left, topd_right, botd_left, botd_right, i, j; + d=left->npts/2; + REAL retPoint[4]; + REAL retNormal[3]; + + if (top->npts==2) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(top->pts[0], backend, retPoint, retNormal); // the root + for(i=0; inpts; i++) + { + OPT_OUTVERT(left->pts[i], backend, retPoint, retNormal); + } + for(i=1; i<= bot->npts-2; i++) + { + OPT_OUTVERT(bot->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[bot->npts-2], backend, retPoint, retNormal); + for(i=0; inpts; i++) + { + OPT_OUTVERT(right->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + else + { + if(bot->npts==2) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[0], backend, retPoint, retNormal); // the root + for(i=0; inpts; i++) + { + OPT_OUTVERT(right->pts[i], backend, retPoint, retNormal); + } + for(i=1; i<= top->npts-2; i++) + { + OPT_OUTVERT(top->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(top->pts[top->npts-2], backend, retPoint, retNormal); + for(i=0; inpts; i++) + { + OPT_OUTVERT(left->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + else // both top and bot have >=3 points + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + + OPT_OUTVERT(top->pts[top->npts-2], backend, retPoint, retNormal); + + for(i=0; i<=d; i++) + { + OPT_OUTVERT(left->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[1], backend, retPoint, retNormal); + OPT_OUTVERT(top->pts[top->npts-2], backend, retPoint, retNormal); + for(i=d; i< left->npts; i++) + { + OPT_OUTVERT(left->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + + d = right->npts/2; + // output only when dnpts-1 and + if (dnpts-1) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(top->pts[1], backend, retPoint, retNormal); + for(i=d; i< right->npts; i++) + { + OPT_OUTVERT(right->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[bot->npts-2], backend, retPoint, retNormal); + for(i=0; i<=d; i++) + { + OPT_OUTVERT(right->pts[i], backend, retPoint, retNormal); + } + + OPT_OUTVERT(top->pts[1], backend, retPoint, retNormal); + + backend.endtfan(); OPT_END(backend); + + + topd_left=top->npts-2; + topd_right=1; // topd_left>= topd_right + + botd_left=1; + botd_right=bot->npts-2; // botd_left<=bot_dright + + if (top->nptsnpts) + { + int delta=bot->npts-top->npts; + int u=delta/2; + botd_left=1+u; + botd_right=bot->npts-2-(delta-u); + + if (botd_left>1) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(top->pts[top->npts-2], backend, retPoint, retNormal); + for(i=1; i<=botd_left; i++) + { + OPT_OUTVERT(bot->pts[i] , backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + if (botd_right < bot->npts-2) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(top->pts[1], backend, retPoint, retNormal); + for(i=botd_right; i<=bot->npts-2; i++) + { + OPT_OUTVERT(bot->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + } + else + { + if(top->npts> bot->npts) + { + int delta=top->npts-bot->npts; + int u=delta/2; + + topd_left=top->npts-2 - u; + topd_right=1+delta-u; + + if (topd_leftnpts-2) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[1], backend, retPoint, retNormal); + for(i=topd_left; i<=top->npts-2; i++) + { + OPT_OUTVERT(top->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + if (topd_right>1) + { + backend.bgntfan(); OPT_START(GL_TRIANGLE_FAN); + OPT_OUTVERT(bot->pts[bot->npts-2], backend, retPoint, retNormal); + for(i=1; i<=topd_right; i++) + { + OPT_OUTVERT(top->pts[i], backend, retPoint, retNormal); + } + backend.endtfan(); OPT_END(backend); + } + } + } + + if (topd_left<=topd_right) + { + return; + } + + backend.bgnqstrip(); OPT_START(GL_TRIANGLE_STRIP); + for(j=botd_left, i=topd_left; i>=topd_right; i--, j++) + { + OPT_OUTVERT(top->pts[i], backend, retPoint, retNormal); + OPT_OUTVERT(bot->pts[j], backend, retPoint, retNormal); + } + backend.endqstrip(); OPT_END(backend); + } + } +} + +static void triangulateRectCenter(int n_ulines, REAL* u_val, int n_vlines, REAL* v_val, + Backend& backend) +{ + // XXX this code was patched by Diego Santa Cruz + // to fix a problem in which glMapGrid2f() was called with bad parameters. + // This has beens submitted to SGI but not integrated as of May 1, 2001. + if (n_ulines>1 && n_vlines>1) + { + backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1, v_val[n_vlines-1], v_val[0], n_vlines-1); + backend.surfmesh(0, 0, n_ulines-1, n_vlines-1); + } + + return; +} + +//it works for top, bot, left ad right, you need ot select correct arguments +static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend) +{ + + if(is_u) + { + int i,k; + REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); + assert(upper_val); + if(dir) + { + for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) + { + upper_val[k] = arc->pwlArc->pts[i].param[0]; + } + backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], + upper_val, + n_ulines, v, u_val); + } + else + { + for(k=0,i=0; ipwlArc->npts; i++,k++) + { + upper_val[k] = arc->pwlArc->pts[i].param[0]; + + } + + backend.evalUStrip( + n_ulines, v, u_val, + arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val + ); + } + + free(upper_val); + return; + } + else //is_v + { + int i,k; + REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts); + assert(left_val); + if(dir) + { + for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++) + { + left_val[k] = arc->pwlArc->pts[i].param[1]; + } + backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], + left_val, + n_ulines, v, u_val); + } + else + { + for(k=0,i=0; ipwlArc->npts; i++,k++) + { + left_val[k] = arc->pwlArc->pts[i].param[1]; + } + backend.evalVStrip( + n_ulines, v, u_val, + arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val + ); + } + free(left_val); + return; + } +} + +//n_ulines is the number of ulines inside, and n_vlines is the number of vlines +//inside, different from meanings elsewhere!!! +static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend) +{ + + int i; + //we know the loop is a rectangle, but not sure which is top + Arc_ptr top, bot, left, right; + + if(equalRect(loop->tail()[1] , loop->head()[1])) + { + + if(loop->tail()[1] > loop->prev->prev->tail()[1]) + { + + top = loop; + } + else{ + + top = loop->prev->prev; + } + } + else + { + if(loop->tail()[0] > loop->prev->prev->tail()[0]) + { + //loop is the right arc + + top = loop->next; + } + else + { + + top = loop->prev; + } + } + + left = top->next; + bot = left->next; + right= bot->next; + +/* + backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1, + top->tail()[1], bot->tail()[1], n_vlines+1); +// if(n_ulines>1 && n_vlines>1) + backend.surfmesh(0,0,n_ulines+1,n_vlines+1); +return; +*/ + REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines); + assert(u_val); + REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines); + assert(v_val); + REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1); + REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1); + Real temp=left->tail()[0]+u_stepsize; + for(i=0; itail()[1] + v_stepsize; + for(i=0; ipwlArc->npts); + for(i=0; ipwlArc->npts; i++) + { + vert[0] = arc->pwlArc->pts[i].param[0]; + vert[1] = arc->pwlArc->pts[i].param[1]; + sline->setPoint(i, vert); + } + ret = new directedLine(INCREASING, sline); + return ret; +} + +/*an pwlArc may not be a straight line*/ +directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc) +{ + directedLine* ret = original; + int is_linear = 0; + if(arc->pwlArc->npts == 2 ) + is_linear = 1; + else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0) + is_linear = 1; + + if(is_linear) + { + directedLine *dline = arcToDLine(arc); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + return ret; + } + else /*not linear*/ + { + for(Int i=0; ipwlArc->npts-1; i++) + { + Real vert[2][2]; + vert[0][0] = arc->pwlArc->pts[i].param[0]; + vert[0][1] = arc->pwlArc->pts[i].param[1]; + vert[1][0] = arc->pwlArc->pts[i+1].param[0]; + vert[1][1] = arc->pwlArc->pts[i+1].param[1]; + + sampledLine *sline = new sampledLine(2, vert); + directedLine *dline = new directedLine(INCREASING, sline); + if(ret == NULL) + ret = dline; + else + ret->insert(dline); + } + return ret; + } +} + +directedLine* arcLoopToDLineLoop(Arc_ptr loop) +{ + directedLine* ret; + + if (loop==NULL) + { + return NULL; + } + + ret=arcToMultDLines(NULL, loop); + + for (Arc_ptr temp=loop->next; temp!=loop; temp=temp->next) + { + ret=arcToMultDLines(ret, temp); + } + + return ret; +} + +void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid) +{ + Int i,j,k; + + Int n_vlines=grid->get_n_vlines(); + //the reason to switch the position of v_max and v_min is because of the + //the orientation problem. glEvalMesh generates quad_strip clockwise, but + //we need counter-clockwise. + backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1, + grid->get_v_max(), grid->get_v_min(), n_vlines-1); + + + for(j=0; jget_n_elements(); j++) + { + rectBlock* block = rbArray->get_element(j); + Int low = block->get_lowGridLineIndex(); + Int high = block->get_upGridLineIndex(); + + for(k=0, i=high; i>low; i--, k++) + { + backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1); + } + } +} + +#define DEFAULT_EVAL_STREAM_ALLOCS 512 + +void Slicer::evalStream(primStream* pStream) +{ + Int i, j, k; + + k=0; + TrimVertex* trimVert=(TrimVertex*)malloc(sizeof(TrimVertex)); + trimVert->nuid=0; + Real* tvertices=pStream->get_vertices(); // for efficiency + REAL retPoint[4]; + REAL retNormal[3]; + + REAL* normals=(REAL*)malloc(sizeof(REAL)*3*DEFAULT_EVAL_STREAM_ALLOCS); + assert(normals); + REAL* vertices=(REAL*)malloc(sizeof(REAL)*3*DEFAULT_EVAL_STREAM_ALLOCS); + assert(vertices); + int alloc_size=DEFAULT_EVAL_STREAM_ALLOCS; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + for (i=0; iget_n_prims(); i++) + { + // ith primitive has #tvertices = lengths[i], type=types[i] + switch(pStream->get_type(i)) + { + case PRIMITIVE_STREAM_FAN: + backend.bgntfan(); + + if (backend.get_output_style()==N_MESHLINE) + { + int startk=k; + int it=0; + int jt; + + if (pStream->get_length(i)>(alloc_size/(3))) + { + normals=(REAL*)realloc(normals, sizeof(REAL)*pStream->get_length(i)*3*(3)); + assert(normals); + vertices=(REAL*)realloc(vertices, sizeof(REAL)*pStream->get_length(i)*3*(3)); + assert(vertices); + alloc_size=pStream->get_length(i)*(3); + + glVertexPointer(3, GL_FLOAT, 0, vertices); + glNormalPointer(GL_FLOAT, 0, normals); + } + + /* Fill up the first vertex */ + trimVert->param[0]=tvertices[startk]; + trimVert->param[1]=tvertices[startk+1]; + backend.tmeshvert(trimVert, retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + k+=2; + + for (j=1; jget_length(i); j++) + { + if (it%3==0) + { + /* Fill up the first vertex again */ + trimVert->param[0]=tvertices[startk]; + trimVert->param[1]=tvertices[startk+1]; + backend.tmeshvert(trimVert, retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + + /* Fill up the previous vertex */ + trimVert->param[0]=tvertices[k-2]; + trimVert->param[1]=tvertices[k-1]; + backend.tmeshvert(trimVert, retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + + /* Fill up the current vertex */ + trimVert->param[0]=tvertices[k]; + trimVert->param[1]=tvertices[k+1]; + backend.tmeshvert(trimVert, retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + k+=2; + } + + for (jt=0; jtget_length(i)>(alloc_size)) + { + normals=(REAL*)realloc(normals, sizeof(REAL)*3*pStream->get_length(i)); + assert(normals); + vertices=(REAL*)realloc(vertices, sizeof(REAL)*3*pStream->get_length(i)); + assert(vertices); + alloc_size=pStream->get_length(i); + + glVertexPointer(3, GL_FLOAT, 0, vertices); + glNormalPointer(GL_FLOAT, 0, normals); + } + + for(j=0; jget_length(i); j++) + { + trimVert->param[0]=tvertices[k]; + trimVert->param[1]=tvertices[k+1]; + backend.tmeshvert(trimVert, retPoint, retNormal); + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + k+=2; + } + + glDrawArrays(GL_TRIANGLE_FAN, 0, it); + } + + backend.endtfan(); + + break; + default: + fprintf(stderr, "evalStream: not implemented yet\n"); + exit(1); + } + } + + /* 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); + } + + free(normals); + free(vertices); + free(trimVert); +} + +void Slicer::slice_new(Arc_ptr loop) +{ + Int num_ulines; + Int num_vlines; + Real uMin, uMax, vMin, vMax; + Real mydu, mydv; + + uMin=uMax=loop->tail()[0]; + vMin=vMax=loop->tail()[1]; + mydu=(du>0)?du:-du; + mydv=(dv>0)?dv:-dv; + + for(Arc_ptr jarc=loop->next; jarc!=loop; jarc=jarc->next) + { + if (jarc->tail()[0]tail()[0]; + } + if(jarc->tail()[0] > uMax) + uMax = jarc->tail()[0]; + if(jarc->tail()[1] < vMin) + vMin = jarc->tail()[1]; + if(jarc->tail()[1] > vMax) + vMax = jarc->tail()[1]; + } + + if (uMax == uMin) + return; // prevent divide-by-zero. Jon Perry. 17 June 2002 + + if(mydu > uMax - uMin) + num_ulines = 2; + else + { + num_ulines = 3 + (Int) ((uMax-uMin)/mydu); + } + if(mydv>=vMax-vMin) + num_vlines = 2; + else + { + num_vlines = 2+(Int)((vMax-vMin)/mydv); + } + + Int isRect = is_rect(loop); + + if(isRect && (num_ulines<=2 || num_vlines<=2)) + { + if(vlinear) + triangulateRect(loop, backend, 1, ulinear, vlinear); + else if(ulinear) + triangulateRect(loop, backend, -1, ulinear, vlinear); + else + triangulateRect(loop, backend, 0, ulinear, vlinear); + } + + else if(isRect) + { + triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend); + } + else if( (num_ulines<=2 || num_vlines <=2) && ulinear) + { + monoTriangulationFunBackend(loop, compV2InY, &backend); + } + else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2)) + { + monoTriangulationFunBackend(loop, compV2InY, &backend); + } + else + { + directedLine* poly = arcLoopToDLineLoop(loop); + + gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax); + primStream pStream(20, 20); + rectBlockArray rbArray(20); + + sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray); + + evalStream(&pStream); + + evalRBArray(&rbArray, &grid); + + poly->deleteSinglePolygonWithSline(); + } +} + +void Slicer::slice(Arc_ptr loop) +{ + slice_new(loop); +} + +Slicer::Slicer(Backend& b): CoveAndTiler(b), Mesher(b), backend(b) +{ + ulinear=0; + vlinear=0; +} + +Slicer::~Slicer() +{ +} + +void Slicer::setisolines(int x) +{ + isolines=x; +} + +void Slicer::setstriptessellation(REAL x, REAL y) +{ + assert(x>0 && y>0); + du=x; + dv=y; + setDu(du); +} + +void +Slicer::slice_old( Arc_ptr loop ) +{ + loop->markverts(); + + Arc_ptr extrema[4]; + loop->getextrema( extrema ); + + unsigned int npts = loop->numpts(); + TrimRegion::init( npts, extrema[0] ); + + Mesher::init( npts ); + + long ulines = uarray.init( du, extrema[1], extrema[3] ); + Varray varray; + long vlines = varray.init( dv, extrema[0], extrema[2] ); + long botv = 0; + long topv; + TrimRegion::init( varray.varray[botv] ); + getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] ); + + for( long quad=0; quadmarkverts(); + + if (jarc->pwlArc->npts>=2) + { + REAL* vertices=(REAL*)malloc(sizeof(REAL)*3*jarc->pwlArc->npts); + assert(vertices); + REAL* normals=(REAL*)malloc(sizeof(REAL)*3*jarc->pwlArc->npts); + assert(normals); + int it=0; + + GLboolean texcoord_enabled; + GLboolean normal_enabled; + GLboolean vertex_enabled; + GLboolean color_enabled; + + /* 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 needed and disable unneeded arrays */ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vertices); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, normals); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + backend.bgnoutline(); + for(int j=jarc->pwlArc->npts-1; j>=0; j--) + { + backend.linevert(&(jarc->pwlArc->pts[j]), retPoint, retNormal); + + vertices[it*3+0]=retPoint[0]; + vertices[it*3+1]=retPoint[1]; + vertices[it*3+2]=retPoint[2]; + normals[it*3+0]=retNormal[0]; + normals[it*3+1]=retNormal[1]; + normals[it*3+2]=retNormal[2]; + it++; + } + backend.endoutline(); + + glDrawArrays(GL_LINE_STRIP, 0, it); + + /* 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); + } + + /* cleanup */ + free(normals); + free(vertices); + } +} diff --git a/project/jni/glu/src/libnurbs/internals/slicer.h b/project/jni/glu/src/libnurbs/internals/slicer.h new file mode 100644 index 000000000..749461390 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/slicer.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +/* + * slicer.h + * + */ + +#ifndef __gluslicer_h_ +#define __gluslicer_h_ + +#include "trimregion.h" +#include "mesher.h" +#include "coveandtiler.h" +#include "primitiveStream.h" +#include "rectBlock.h" + +class Backend; +class Arc; +class TrimVertex; + +class Slicer: public CoveAndTiler, public Mesher +{ + public: + Slicer(Backend&); + ~Slicer(void); + void slice(Arc_ptr); + void slice_old(Arc_ptr); + void slice_new(Arc_ptr); + void evalStream(primStream*); + void evalRBArray(rectBlockArray* rbArray, gridWrap* grid); + + void outline(Arc_ptr); + void setstriptessellation(REAL, REAL); + void setisolines(int); + + void set_ulinear(int ulinear_flag) + { + ulinear=ulinear_flag; + } + + void set_vlinear(int vlinear_flag) + { + vlinear=vlinear_flag; + } + + private: + Backend& backend; + REAL oneOverDu; + REAL du, dv; + int isolines; + + void outline( void ); + void initGridlines( void ); + void advanceGridlines( long ); + + int ulinear; //indicate whether uorder is 2 or not + int vlinear; //indicate whether vorder is 2 or not +}; +#endif /* __gluslicer_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/sorter.cc b/project/jni/glu/src/libnurbs/internals/sorter.cc new file mode 100644 index 000000000..98ba0c872 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/sorter.cc @@ -0,0 +1,144 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * sorter.c++ + * + */ + +#include "glimports.h" +#include "sorter.h" +#include "mystdio.h" + +Sorter::Sorter(int _es) +{ + es=_es; +} + +void Sorter::qsort(void* a, int n) +{ + qs1((char*)a, ((char*)a)+n*es); +} + +int Sorter::qscmp(char*, char*) +{ + return 0; +} + +void Sorter::qsexc(char*, char*) +{ +} + +void Sorter::qstexc(char*, char*, char*) +{ +} + +void Sorter::qs1(char* a, char* l) +{ + char* i; + char* j; + char* lp; + char* hp; + int c; + unsigned int n; + +start: + if ((n=(int)(l-a))<=(unsigned int)es) + { + return; + } + n=es*(n/(2*es)); + hp=lp=a+n; + i=a; + j=l-es; + + while(1) + { + if (ihp) + { + if ((c=qscmp(hp, j))==0) + { + qsexc(hp+=es, j); + goto loop; + } + if (c>0) + { + if (i==lp) + { + qstexc(i, hp+=es, j); + i=lp+=es; + goto loop; + } + qsexc(i, j); + j-=es; + i+=es; + continue; + } + j-=es; + goto loop; + } + + if (i==lp) + { + if (lp-a>=l-hp) + { + qs1(hp+es, l); + l=lp; + } + else + { + qs1(a, lp); + a=hp+es; + } + goto start; + } + + qstexc(j, lp-=es, i); + j=hp-=es; + } +} diff --git a/project/jni/glu/src/libnurbs/internals/sorter.h b/project/jni/glu/src/libnurbs/internals/sorter.h new file mode 100644 index 000000000..bbaf0a08a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/sorter.h @@ -0,0 +1,53 @@ +/* + * 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. + */ +/* +*/ + +#ifndef __glusorter_h_ +#define __glusorter_h_ + +class Sorter +{ + public: + Sorter(int es); + virtual ~Sorter() {/* silence warning*/} + void qsort(void *a, int n); + + protected: + virtual int qscmp(char*, char*); + virtual void qsexc(char* i, char* j); // i<-j, j<-i + virtual void qstexc(char* i, char* j, char* k); // i<-k, k<-j, j<-i + + private: + void qs1(char*, char*); + int es; +}; + +#endif /* __glusorter_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/splitarcs.cc b/project/jni/glu/src/libnurbs/internals/splitarcs.cc new file mode 100644 index 000000000..a948cd41c --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/splitarcs.cc @@ -0,0 +1,276 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * splitarcs.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mysetjmp.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arcsorter.h" +#include "arc.h" +#include "bin.h" + +/* local preprocessor definitions */ +#define MAXARCS 10 + +/*---------------------------------------------------------------------------- + * Subdivider::split - split trim regions in source bin by line (param == value). + *---------------------------------------------------------------------------- + */ + +void +Subdivider::split( Bin& bin, Bin& left, Bin& right, int param, REAL value ) +{ + Bin intersections, unknown; + + partition( bin, left, intersections, right, unknown, param, value ); + + int count = intersections.numarcs(); + if( count % 2 ) { + ::mylongjmp( jumpbuffer, 29 ); + } + + Arc_ptr arclist[MAXARCS], *list; + if( count >= MAXARCS ) { + list = new Arc_ptr[count]; + } else { + list = arclist; + } + + Arc_ptr jarc, *last, *lptr; + for( last = list; (jarc=intersections.removearc()) != NULL; last++ ) + *last = jarc; + + if( param == 0 ) { /* sort into increasing t order */ + ArcSdirSorter sorter(*this); + sorter.qsort( list, count ); + + //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_s); + for( lptr=list; lptrhead()[0] <= value) && ((*lptr)->tail()[0] <= value) ) + left.addarc( *lptr ); + else + right.addarc( *lptr ); + } + } else { /* sort into decreasing s order */ + ArcTdirSorter sorter(*this); + sorter.qsort( list, count ); + //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_t); + for( lptr=list; lptrhead()[1] <= value) && ((*lptr)->tail()[1] <= value) ) + left.addarc( *lptr ); + else + right.addarc( *lptr ); + } + } + + if( list != arclist ) delete[] list; + unknown.adopt(); +} + + +void +Subdivider::check_s( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + /* XXX - if these assertions fail, it is due to user error or + undersampling */ + if( ! ( jarc1->tail()[0] < (jarc1)->head()[0] ) ) { + ::mylongjmp( jumpbuffer, 28 ); + } + + if( ! ( jarc2->tail()[0] > (jarc2)->head()[0] ) ) { + ::mylongjmp( jumpbuffer, 28 ); + } +} + +inline void +Subdivider::link( Arc_ptr jarc1, Arc_ptr jarc2, Arc_ptr up, Arc_ptr down ) +{ + up->nuid = down->nuid = 0; // XXX + + up->next = jarc2; + down->next = jarc1; + up->prev = jarc1->prev; + down->prev = jarc2->prev; + + down->next->prev = down; + up->next->prev = up; + down->prev->next = down; + up->prev->next = up; +} + +inline void +Subdivider::simple_link( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + Arc_ptr tmp = jarc2->prev; + jarc2->prev = jarc1->prev; + jarc1->prev = tmp; + jarc2->prev->next = jarc2; + jarc1->prev->next = jarc1; +} + + +/*---------------------------------------------------------------------------- + * join - add a pair of oppositely directed jordan arcs between two arcs + *---------------------------------------------------------------------------- + */ + +void +Subdivider::join_s( Bin& left, Bin& right, Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0); + assert( jarc2->check( ) != 0); + assert( jarc1 != jarc2 ); + + if( ! jarc1->getitail() ) + jarc1 = jarc1->next; + + if( ! jarc2->getitail() ) + jarc2 = jarc2->next; + + REAL s = jarc1->tail()[0]; + REAL t1 = jarc1->tail()[1]; + REAL t2 = jarc2->tail()[1]; + + if( t1 == t2 ) { + simple_link( jarc1, jarc2 ); + } else { + Arc_ptr newright = new(arcpool) Arc( arc_right, 0 ); + Arc_ptr newleft = new(arcpool) Arc( arc_left, 0 ); + assert( t1 < t2 ); + if( isBezierArcType() ) { + arctessellator.bezier( newright, s, s, t1, t2 ); + arctessellator.bezier( newleft, s, s, t2, t1 ); + } else { + arctessellator.pwl_right( newright, s, t1, t2, stepsizes[0] ); + arctessellator.pwl_left( newleft, s, t2, t1, stepsizes[2] ); + } + link( jarc1, jarc2, newright, newleft ); + left.addarc( newright ); + right.addarc( newleft ); + } + + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0); + assert( jarc2->next->check( ) != 0); +} + +void +Subdivider::check_t( Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + /* XXX - if these assertions fail, it is due to user error or + undersampling */ + if( ! ( jarc1->tail()[1] < (jarc1)->head()[1] ) ) { + ::mylongjmp( jumpbuffer, 28 ); + } + + if( ! ( jarc2->tail()[1] > (jarc2)->head()[1] ) ) { + ::mylongjmp( jumpbuffer, 28 ); + } +} + +/*---------------------------------------------------------------------------- + * join_t - add a pair of oppositely directed jordan arcs between two arcs + *---------------------------------------------------------------------------- + */ + +void +Subdivider::join_t( Bin& bottom, Bin& top, Arc_ptr jarc1, Arc_ptr jarc2 ) +{ + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); + assert( jarc1 != jarc2 ); + + if( ! jarc1->getitail() ) + jarc1 = jarc1->next; + + if( ! jarc2->getitail() ) + jarc2 = jarc2->next; + + REAL s1 = jarc1->tail()[0]; + REAL s2 = jarc2->tail()[0]; + REAL t = jarc1->tail()[1]; + + if( s1 == s2 ) { + simple_link( jarc1, jarc2 ); + } else { + Arc_ptr newtop = new(arcpool) Arc( arc_top, 0 ); + Arc_ptr newbot = new(arcpool) Arc( arc_bottom, 0 ); + assert( s1 > s2 ); + if( isBezierArcType() ) { + arctessellator.bezier( newtop, s1, s2, t, t ); + arctessellator.bezier( newbot, s2, s1, t, t ); + } else { + arctessellator.pwl_top( newtop, t, s1, s2, stepsizes[1] ); + arctessellator.pwl_bottom( newbot, t, s2, s1, stepsizes[3] ); + } + link( jarc1, jarc2, newtop, newbot ); + bottom.addarc( newtop ); + top.addarc( newbot ); + } + + assert( jarc1->check( ) != 0 ); + assert( jarc2->check( ) != 0 ); + assert( jarc1->next->check( ) != 0 ); + assert( jarc2->next->check( ) != 0 ); +} + diff --git a/project/jni/glu/src/libnurbs/internals/subdivider.cc b/project/jni/glu/src/libnurbs/internals/subdivider.cc new file mode 100644 index 000000000..939482a02 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/subdivider.cc @@ -0,0 +1,877 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* +* subdivider.cxx +* +*/ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "subdivider.h" +#include "arc.h" +#include "bezierarc.h" +#include "bin.h" +#include "renderhints.h" +#include "backend.h" +#include "mapdesc.h" +#include "quilt.h" +#include "patchlist.h" +#include "patch.h" +#include "nurbsconsts.h" +#include "trimvertpool.h" +#include "simplemath.h" + +#include "polyUtil.h" //for function area() + +Bin* Subdivider::makePatchBoundary(const REAL* from, const REAL* to) +{ + Bin* ret=new Bin(); + REAL smin=from[0]; + REAL smax=to[0]; + REAL tmin=from[1]; + REAL tmax=to[1]; + + pjarc=0; + + Arc_ptr jarc=new(arcpool) Arc(arc_bottom, 0); + arctessellator.bezier(jarc, smin, smax, tmin, tmin); + ret->addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_right, 0); + arctessellator.bezier(jarc, smax, smax, tmin, tmax); + ret->addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_top, 0); + arctessellator.bezier(jarc, smax, smin, tmax, tmax); + ret->addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_left, 0); + arctessellator.bezier(jarc, smin, smin, tmax, tmin); + ret->addarc(jarc); + jarc->append(pjarc); + + assert(jarc->check()!=0); + + return ret; +} + +/*--------------------------------------------------------------------------- +* Subdivider - construct a subdivider +*--------------------------------------------------------------------------- +*/ + +Subdivider::Subdivider(Renderhints& r, Backend& b): slicer(b), + arctessellator(trimvertexpool, pwlarcpool), + arcpool(sizeof(Arc), 1, "arcpool"), + bezierarcpool(sizeof(BezierArc), 1, "Bezarcpool"), + pwlarcpool(sizeof(PwlArc), 1, "Pwlarcpool"), + renderhints(r), + backend(b) +{ +} + +void Subdivider::setJumpbuffer(JumpBuffer* j) +{ + jumpbuffer=j; +} + +/*--------------------------------------------------------------------------- +* clear - reset all state after possible error condition +*--------------------------------------------------------------------------- +*/ + +void Subdivider::clear(void) +{ + trimvertexpool.clear(); + arcpool.clear(); + pwlarcpool.clear(); + bezierarcpool.clear(); +} + +/*--------------------------------------------------------------------------- +* ~Subdivider - destroy a subdivider +*--------------------------------------------------------------------------- +*/ + +Subdivider::~Subdivider(void) +{ +} + +/*--------------------------------------------------------------------------- +* addArc - add a bezier arc to a trim loop and to a bin +*--------------------------------------------------------------------------- +*/ +void Subdivider::addArc(REAL* cpts, Quilt* quilt, long _nuid) +{ + BezierArc* bezierArc=new(bezierarcpool) BezierArc; + Arc* jarc=new(arcpool) Arc(arc_none, _nuid); + jarc->pwlArc=0; + jarc->bezierArc=bezierArc; + bezierArc->order=quilt->qspec->order; + bezierArc->stride=quilt->qspec->stride; + bezierArc->mapdesc=quilt->mapdesc; + bezierArc->cpts=cpts; + initialbin.addarc(jarc); + pjarc=jarc->append(pjarc); +} + +/*--------------------------------------------------------------------------- +* addArc - add a pwl arc to a trim loop and to a bin +*--------------------------------------------------------------------------- +*/ + +void Subdivider::addArc(int npts, TrimVertex* pts, long _nuid) +{ + Arc* jarc=new(arcpool) Arc(arc_none, _nuid); + jarc->pwlArc=new(pwlarcpool) PwlArc(npts, pts); + initialbin.addarc(jarc); + pjarc=jarc->append(pjarc); +} + +void Subdivider::beginQuilts(void) +{ + qlist=0; +} + +void Subdivider::addQuilt(Quilt* quilt) +{ + quilt->next=qlist; + qlist=quilt; +} + +/*--------------------------------------------------------------------------- +* drawSurfaces - main entry point for surface tessellation +*--------------------------------------------------------------------------- +*/ + +void Subdivider::drawSurfaces(long nuid) +{ + renderhints.init(); + + if (qlist==NULL) + { + //initialbin could be nonempty due to some errors + freejarcs(initialbin); + return; + } + + for (Quilt* q=qlist; q; q=q->next) + { + if (q->isCulled()==CULL_TRIVIAL_REJECT) + { + freejarcs(initialbin); + return; + } + } + + REAL from[2], to[2]; + qlist->getRange(from, to, spbrkpts, tpbrkpts); + + // perform optimization only when the samplng method is + // DOMAIN_DISTANCE and the display methdo is either + // fill or outline_polygon. + int optimize=(is_domain_distance_sampling && (renderhints.display_method!=N_OUTLINE_PATCH)); + + if (!initialbin.isnonempty()) + { + if (!optimize) + { + makeBorderTrim(from, to); + } + } + else + { + REAL rate[2]; + qlist->findRates(spbrkpts, tpbrkpts, rate); + + if (decompose(initialbin, min(rate[0], rate[1]))) + { + mylongjmp(jumpbuffer, 31); + } + } + + backend.bgnsurf(renderhints.wiretris, renderhints.wirequads, nuid); + + if ((!initialbin.isnonempty()) && optimize) + { + int i, j; + int num_u_steps; + int num_v_steps; + for (i=spbrkpts.start; idownloadAll(pta, ptb, backend); + + num_u_steps=(int)(domain_distance_u_rate*(ptb[0]-pta[0])); + num_v_steps=(int)(domain_distance_v_rate*(ptb[1]-pta[1])); + + if (num_u_steps<=0) + { + num_u_steps=1; + } + if (num_v_steps<=0) + { + num_v_steps=1; + } + + backend.surfgrid(pta[0], ptb[0], num_u_steps, + ptb[1], pta[1], num_v_steps); + backend.surfmesh(0, 0, num_u_steps,num_v_steps); + + continue; + } + } + } + else + { + subdivideInS(initialbin); + } + + backend.endsurf(); +} + +void Subdivider::subdivideInS(Bin& source) +{ + if (renderhints.display_method==N_OUTLINE_PARAM) + { + outline(source); + freejarcs(source); + } + else + { + setArcTypeBezier(); + setNonDegenerate(); + splitInS(source, spbrkpts.start, spbrkpts.end); + } +} + +/*--------------------------------------------------------------------------- +* splitInS - split a patch and a bin by an isoparametric line +*--------------------------------------------------------------------------- +*/ + +void Subdivider::splitInS(Bin& source, int start, int end) +{ + if (source.isnonempty()) + { + if (start!=end) + { + int i=start+(end-start)/2; + Bin left, right; + split(source, left, right, 0, spbrkpts.pts[i]); + splitInS(left, start, i); + splitInS(right, i+1, end); + } + else + { + if (start==spbrkpts.start || start==spbrkpts.end) + { + freejarcs(source); + } + else + { + if (renderhints.display_method==N_OUTLINE_PARAM_S) + { + outline(source); + freejarcs(source); + } + else + { + setArcTypeBezier(); + setNonDegenerate(); + s_index=start; + splitInT(source, tpbrkpts.start, tpbrkpts.end); + } + } + } + } +} + +/*--------------------------------------------------------------------------- +* splitInT - split a patch and a bin by an isoparametric line +*--------------------------------------------------------------------------- +*/ + +void Subdivider::splitInT(Bin& source, int start, int end) +{ + if (source.isnonempty()) + { + if (start!=end) + { + int i=start+(end-start)/2; + Bin left, right; + split(source, left, right, 1, tpbrkpts.pts[i]); + splitInT(left, start, i); + splitInT(right, i+1, end); + } + else + { + if (start==tpbrkpts.start || start==tpbrkpts.end) + { + freejarcs(source); + } + else + { + if (renderhints.display_method==N_OUTLINE_PARAM_ST) + { + outline(source); + freejarcs(source); + } + else + { + t_index=start; + setArcTypeBezier(); + setDegenerate(); + + REAL pta[2], ptb[2]; + pta[0]=spbrkpts.pts[s_index-1]; + pta[1]=tpbrkpts.pts[t_index-1]; + + ptb[0]=spbrkpts.pts[s_index]; + ptb[1]=tpbrkpts.pts[t_index]; + qlist->downloadAll(pta, ptb, backend); + + Patchlist patchlist(qlist, pta, ptb); + samplingSplit(source, patchlist, renderhints.maxsubdivisions, 0); + setNonDegenerate(); + setArcTypeBezier(); + } + } + } + } +} + +/*-------------------------------------------------------------------------- +* samplingSplit - recursively subdivide patch, cull check each subpatch +*-------------------------------------------------------------------------- +*/ + +void Subdivider::samplingSplit(Bin& source, Patchlist& patchlist, int subdivisions, int param) +{ + if (!source.isnonempty()) + { + return; + } + + if (patchlist.cullCheck()==CULL_TRIVIAL_REJECT) + { + freejarcs(source); + return; + } + + patchlist.getstepsize(); + + if (renderhints.display_method==N_OUTLINE_PATCH) + { + tessellation(source, patchlist); + outline(source); + freejarcs(source); + return; + } + + tessellation(source, patchlist); + + if (patchlist.needsSamplingSubdivision() && (subdivisions>0)) + { + if (!patchlist.needsSubdivision(0)) + { + param=1; + } + else + { + if (! patchlist.needsSubdivision(1)) + { + param=0; + } + else + { + param=1-param; + } + } + + Bin left, right; + REAL mid=(patchlist.pspec[param].range[0]+patchlist.pspec[param].range[1])*0.5f; + split(source, left, right, param, mid); + Patchlist subpatchlist(patchlist, param, mid); + samplingSplit(left, subpatchlist, subdivisions-1, param); + samplingSplit(right, patchlist, subdivisions-1, param); + } + else + { + setArcTypePwl(); + setDegenerate(); + nonSamplingSplit(source, patchlist, subdivisions, param); + setDegenerate(); + setArcTypeBezier(); + } +} + +void Subdivider::nonSamplingSplit(Bin& source, Patchlist& patchlist, + int subdivisions, int param) +{ + if (patchlist.needsNonSamplingSubdivision() && (subdivisions>0)) + { + param=1-param; + + Bin left, right; + REAL mid=(patchlist.pspec[param].range[0]+patchlist.pspec[param].range[1])*0.5f; + split(source, left, right, param, mid); + Patchlist subpatchlist(patchlist, param, mid); + if (left.isnonempty()) + { + if (subpatchlist.cullCheck()==CULL_TRIVIAL_REJECT) + { + freejarcs(left); + } + else + { + nonSamplingSplit(left, subpatchlist, subdivisions-1, param); + } + } + if (right.isnonempty()) + { + if (patchlist.cullCheck()==CULL_TRIVIAL_REJECT) + { + freejarcs(right); + } + else + { + nonSamplingSplit(right, patchlist, subdivisions-1, param); + } + } + } + else + { + // make bbox calls + patchlist.bbox(); + backend.patch(patchlist.pspec[0].range[0], patchlist.pspec[0].range[1], + patchlist.pspec[1].range[0], patchlist.pspec[1].range[1]); + + if (renderhints.display_method==N_OUTLINE_SUBDIV) + { + outline(source); + freejarcs(source); + } + else + { + setArcTypePwl(); + setDegenerate(); + findIrregularS(source); + monosplitInS(source, smbrkpts.start, smbrkpts.end); + } + } +} + +/*-------------------------------------------------------------------------- +* tessellation - set tessellation of interior and boundary of patch +*-------------------------------------------------------------------------- +*/ + +void Subdivider::tessellation(Bin& bin, Patchlist &patchlist) +{ + // tessellate unsampled trim curves + tessellate(bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1], + patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0]); + + // set interior sampling rates + slicer.setstriptessellation(patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize); + + //added by zl: set the order which will be used in slicer.c++ + slicer.set_ulinear((patchlist.get_uorder()==2)); + slicer.set_vlinear((patchlist.get_vorder()==2)); + + // set boundary sampling rates + stepsizes[0]=patchlist.pspec[1].stepsize; + stepsizes[1]=patchlist.pspec[0].stepsize; + stepsizes[2]=patchlist.pspec[1].stepsize; + stepsizes[3]=patchlist.pspec[0].stepsize; +} + +/*--------------------------------------------------------------------------- +* monosplitInS - split a patch and a bin by an isoparametric line +*--------------------------------------------------------------------------- +*/ + +void Subdivider::monosplitInS(Bin& source, int start, int end) +{ + if (source.isnonempty()) + { + if (start!=end) + { + int i=start+(end-start)/2; + Bin left, right; + split(source, left, right, 0, smbrkpts.pts[i]); + monosplitInS(left, start, i); + monosplitInS(right, i+1, end); + } + else + { + if (renderhints.display_method==N_OUTLINE_SUBDIV_S) + { + outline(source); + freejarcs(source); + } + else + { + setArcTypePwl(); + setDegenerate(); + findIrregularT(source); + monosplitInT(source, tmbrkpts.start, tmbrkpts.end); + } + } + } +} + +/*--------------------------------------------------------------------------- +* monosplitInT - split a patch and a bin by an isoparametric line +*--------------------------------------------------------------------------- +*/ + +void Subdivider::monosplitInT(Bin& source, int start, int end) +{ + if (source.isnonempty()) + { + if (start!=end) + { + int i=start+(end-start)/2; + Bin left, right; + split(source, left, right, 1, tmbrkpts.pts[i]); + monosplitInT(left, start, i); + monosplitInT(right, i+1, end); + } + else + { + if (renderhints.display_method==N_OUTLINE_SUBDIV_ST) + { + outline(source); + freejarcs(source); + } + else + { + render(source); + freejarcs(source); + } + } + } +} + +/*---------------------------------------------------------------------------- +* findIrregularS - determine points of non-monotonicity is s direction +*---------------------------------------------------------------------------- +*/ + +void Subdivider::findIrregularS(Bin& bin) +{ + assert(bin.firstarc()->check()!=0); + + smbrkpts.grow(bin.numarcs()); + + for (Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()) + { + REAL* a=jarc->prev->tail(); + REAL* b=jarc->tail(); + REAL* c=jarc->head(); + + if (b[1]==a[1] && b[1]==c[1]) + { + continue; + } + + // corrected code + if ((b[1]<=a[1] && b[1]<=c[1]) || (b[1]>=a[1] && b[1]>=c[1])) + { + //each arc (jarc, jarc->prev, jarc->next) is a + //monotone arc consisting of multiple line segements. + //it may happen that jarc->prev and jarc->next are the same, + //that is, jarc->prev and jarc form a closed loop. + //In such case, a and c will be the same. + if (a[0]==c[0] && a[1]==c[1]) + { + if (jarc->pwlArc->npts>2) + { + c=jarc->pwlArc->pts[jarc->pwlArc->npts-2].param; + } + else + { + assert(jarc->prev->pwlArc->npts>2); + a=jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param; + } + } + if (area(a, b, c)<0) + { + smbrkpts.add(b[0]); + } + } + } + + smbrkpts.filter(); +} + +/*---------------------------------------------------------------------------- +* findIrregularT - determine points of non-monotonicity in t direction +* where one arc is parallel to the s axis. +*---------------------------------------------------------------------------- +*/ + +void Subdivider::findIrregularT(Bin& bin) +{ + assert(bin.firstarc()->check()!=0); + + tmbrkpts.grow(bin.numarcs()); + + for (Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()) + { + REAL* a=jarc->prev->tail(); + REAL* b=jarc->tail(); + REAL* c=jarc->head(); + + if (b[0]==a[0] && b[0]==c[0]) + { + continue; + } + + if (b[0]<=a[0] && b[0]<=c[0]) + { + if (a[1]!=b[1] && b[1]!=c[1]) + { + continue; + } + if (!ccwTurn_sr(jarc->prev, jarc)) + { + tmbrkpts.add(b[1]); + } + } + else + { + if (b[0]>=a[0] && b[0]>=c[0]) + { + if (a[1]!=b[1] && b[1]!=c[1]) + { + continue; + } + if (!ccwTurn_sl(jarc->prev, jarc)) + { + tmbrkpts.add(b[1]); + } + } + } + } + tmbrkpts.filter(); +} + +/*----------------------------------------------------------------------------- +* makeBorderTrim - if no user input trimming data then create +* a trimming curve around the boundaries of the Quilt. The curve consists of +* four Jordan arcs, one for each side of the Quilt, connected, of course, +* head to tail. +*----------------------------------------------------------------------------- +*/ + +void Subdivider::makeBorderTrim(const REAL* from, const REAL* to) +{ + REAL smin=from[0]; + REAL smax=to[0]; + REAL tmin=from[1]; + REAL tmax=to[1]; + + pjarc=0; + + Arc_ptr jarc=new(arcpool) Arc(arc_bottom, 0); + arctessellator.bezier(jarc, smin, smax, tmin, tmin); + initialbin.addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_right, 0); + arctessellator.bezier(jarc, smax, smax, tmin, tmax); + initialbin.addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_top, 0); + arctessellator.bezier(jarc, smax, smin, tmax, tmax); + initialbin.addarc(jarc); + pjarc=jarc->append(pjarc); + + jarc=new(arcpool) Arc(arc_left, 0); + arctessellator.bezier(jarc, smin, smin, tmax, tmin); + initialbin.addarc(jarc); + jarc->append(pjarc); + + assert(jarc->check()!=0); +} + +/*---------------------------------------------------------------------------- +* render - renders all monotone regions in a bin and frees the bin +*---------------------------------------------------------------------------- +*/ + +void Subdivider::render(Bin& bin) +{ + bin.markall(); + +#ifdef N_ISOLINE_S + slicer.setisolines((renderhints.display_method==N_ISOLINE_S) ? 1 : 0); +#else + slicer.setisolines(0); +#endif + + for (Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()) + { + if (jarc->ismarked()) + { + assert(jarc->check()!=0); + Arc_ptr jarchead=jarc; + do { + jarc->clearmark(); + jarc=jarc->next; + } while (jarc!=jarchead); + slicer.slice(jarc); + } + } +} + +/*--------------------------------------------------------------------------- +* outline - render the trimmed patch by outlining the boundary +*--------------------------------------------------------------------------- +*/ + +void Subdivider::outline(Bin& bin) +{ + bin.markall(); + for (Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()) + { + if (jarc->ismarked()) + { + assert(jarc->check()!=0); + Arc_ptr jarchead=jarc; + do { + slicer.outline(jarc); + jarc->clearmark(); + jarc=jarc->prev; + } while (jarc!=jarchead); + } + } +} + +/*--------------------------------------------------------------------------- +* freejarcs - free all arcs in a bin +*--------------------------------------------------------------------------- +*/ + +void +Subdivider::freejarcs(Bin& bin) +{ + bin.adopt(); /* XXX - should not be necessary*/ + + Arc_ptr jarc; + while((jarc=bin.removearc())!=NULL) + { + if (jarc->pwlArc) + { + jarc->pwlArc->deleteMe(pwlarcpool); jarc->pwlArc=0; + } + if (jarc->bezierArc) + { + jarc->bezierArc->deleteMe(bezierarcpool); jarc->bezierArc=0; + } + jarc->deleteMe(arcpool); + } +} + +/*---------------------------------------------------------------------------- +* tessellate - tessellate all Bezier arcs in a bin +* 1) only accepts linear Bezier arcs as input +* 2) the Bezier arcs are stored in the pwlArc structure +* 3) only vertical or horizontal lines work +* -- should +* 1) represent Bezier arcs in BezierArc structure +* (this requires a multitude of changes to the code) +* 2) accept high degree Bezier arcs (hard) +* 3) map the curve onto the surface to determine tessellation +* 4) work for curves of arbitrary geometry +*---------------------------------------------------------------------------- +*/ + +void Subdivider::tessellate(Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate) +{ + for (Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()) + { + if (jarc->isbezier()) + { + assert(jarc->pwlArc->npts==2); + TrimVertex* pts=jarc->pwlArc->pts; + REAL s1=pts[0].param[0]; + REAL t1=pts[0].param[1]; + REAL s2=pts[1].param[0]; + REAL t2=pts[1].param[1]; + + jarc->pwlArc->deleteMe(pwlarcpool); jarc->pwlArc=0; + + switch(jarc->getside()) + { + case arc_left: + assert(s1==s2); + arctessellator.pwl_left(jarc, s1, t1, t2, lrate); + break; + case arc_right: + assert(s1==s2); + arctessellator.pwl_right(jarc, s1, t1, t2, rrate); + break; + case arc_top: + assert(t1==t2); + arctessellator.pwl_top(jarc, t1, s1, s2, trate); + break; + case arc_bottom: + assert(t1==t2); + arctessellator.pwl_bottom(jarc, t1, s1, s2, brate); + break; + case arc_none: + (void)abort(); + break; + } + assert(! jarc->isbezier()); + assert(jarc->check()!=0); + } + } +} diff --git a/project/jni/glu/src/libnurbs/internals/subdivider.h b/project/jni/glu/src/libnurbs/internals/subdivider.h new file mode 100644 index 000000000..17e52fdd3 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/subdivider.h @@ -0,0 +1,198 @@ +/* + * 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. + */ + +/* + * subdivider.h + * + */ + +#ifndef __glusubdivider_h_ +#define __glusubdivider_h_ + +#include "mysetjmp.h" +#include "bin.h" +#include "flist.h" +#include "slicer.h" +#include "arctess.h" +#include "trimvertex.h" +#include "trimvertpool.h" + +class Arc; +class Pool; +class Renderhints; +class Quilt; +class Patchlist; +class Curvelist; +struct JumpBuffer; + +class Subdivider +{ + public: + Subdivider(Renderhints&, Backend&); + ~Subdivider(void); + void clear(void); + + void beginTrims(void) {} + void beginLoop(void); + void addArc(REAL*, Quilt*, long); + void addArc(int, TrimVertex*, long); + void endLoop(void) {} + void endTrims(void) {} + + void beginQuilts(void); + void addQuilt(Quilt*); + void endQuilts(void) {} + + void drawCurves(void); + void drawSurfaces(long); + + int ccwTurn_sl(Arc_ptr, Arc_ptr); + int ccwTurn_sr(Arc_ptr, Arc_ptr); + int ccwTurn_tl(Arc_ptr, Arc_ptr); + int ccwTurn_tr(Arc_ptr, Arc_ptr); + + void setJumpbuffer(JumpBuffer*); + + void set_domain_distance_u_rate(REAL u_rate) + { + domain_distance_u_rate=u_rate; + } + void set_domain_distance_v_rate(REAL v_rate) + { + domain_distance_v_rate=v_rate; + } + void set_is_domain_distance_sampling(int flag) + { + is_domain_distance_sampling=flag; + } + + private: + void classify_headonleft_s(Bin&, Bin&, Bin&, REAL); + void classify_tailonleft_s(Bin&, Bin&, Bin&, REAL); + void classify_headonright_s(Bin&, Bin&, Bin&, REAL); + void classify_tailonright_s(Bin&, Bin&, Bin&, REAL); + void classify_headonleft_t(Bin&, Bin&, Bin&, REAL); + void classify_tailonleft_t(Bin&, Bin&, Bin&, REAL); + void classify_headonright_t(Bin&, Bin&, Bin&, REAL); + void classify_tailonright_t(Bin&, Bin&, Bin&, REAL); + + enum dir { down, same, up, none }; + void tessellate(Arc_ptr, REAL); + void monotonize(Arc_ptr, Bin&); + int isMonotone(Arc_ptr); + int decompose(Bin&, REAL); + + Slicer slicer; + ArcTessellator arctessellator; + Pool arcpool; + Pool bezierarcpool; + Pool pwlarcpool; + TrimVertexPool trimvertexpool; + + JumpBuffer* jumpbuffer; + Renderhints& renderhints; + Backend& backend; + + Bin initialbin; + Arc_ptr pjarc; + int s_index; + int t_index; + Quilt* qlist; + Flist spbrkpts; + Flist tpbrkpts; + Flist smbrkpts; + Flist tmbrkpts; + REAL stepsizes[4]; + int showDegenerate; + int isArcTypeBezier; + + void samplingSplit(Curvelist&, int); + + void subdivideInS(Bin&); + void splitInS(Bin&, int, int); + void splitInT(Bin&, int, int); + void samplingSplit(Bin&, Patchlist&, int, int); + void nonSamplingSplit(Bin&, Patchlist&, int, int); + void tessellation(Bin&, Patchlist&); + void monosplitInS(Bin&, int, int); + void monosplitInT(Bin&, int, int); + + void outline(Bin&); + void freejarcs(Bin&); + void render(Bin&); + void split(Bin&, Bin&, Bin&, int, REAL); + void tessellate(Bin&, REAL, REAL, REAL, REAL); + + inline void setDegenerate(void) { showDegenerate=1; } + inline void setNonDegenerate(void) { showDegenerate=0; } + inline int showingDegenerate(void) { return showDegenerate; } + inline void setArcTypeBezier(void) { isArcTypeBezier=1; } + inline void setArcTypePwl(void) { isArcTypeBezier=0; } + inline int isBezierArcType(void) { return isArcTypeBezier; } + + void makeBorderTrim(const REAL*, const REAL*); + void split(Bin&, int, const REAL*, int, int); + void partition(Bin&, Bin&, Bin&, Bin&, Bin&, int, REAL); + void findIrregularS(Bin&); + void findIrregularT(Bin&); + + + inline int bbox(TrimVertex*, TrimVertex*, TrimVertex*, int); + static int bbox(REAL, REAL, REAL, REAL, REAL, REAL); + static int ccw(TrimVertex*, TrimVertex*, TrimVertex*); + void join_s(Bin&, Bin&, Arc_ptr, Arc_ptr); + void join_t(Bin&, Bin&, Arc_ptr, Arc_ptr); + int arc_split(Arc_ptr, int, REAL, int); + void check_s(Arc_ptr, Arc_ptr); + void check_t(Arc_ptr, Arc_ptr); + inline void link(Arc_ptr, Arc_ptr, Arc_ptr, Arc_ptr); + inline void simple_link(Arc_ptr, Arc_ptr); + + Bin* makePatchBoundary(const REAL* from, const REAL* to); + + /*in domain distance method, the tessellation is controled by two numbers: + *GLU_U_STEP: number of u-segments per unit u length of domain + *GLU_V_STEP: number of v-segments per unit v length of domain + *These two numbers are normally stored in mapdesc->maxs(t)rate. + *I (ZL) put these two numbers here so that I can optimize the untrimmed + *case in the case of domain distance sampling. + *These two numbers are set by set_domain_distance_u_rate() and ..._v_..(). + */ + REAL domain_distance_u_rate; + REAL domain_distance_v_rate; + int is_domain_distance_sampling; +}; + +inline void Subdivider::beginLoop(void) +{ + pjarc=0; +} + +#endif /* __glusubdivider_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/tobezier.cc b/project/jni/glu/src/libnurbs/internals/tobezier.cc new file mode 100644 index 000000000..6c74cdb05 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/tobezier.cc @@ -0,0 +1,668 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * tobezier.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mystring.h" +#include "quilt.h" +#include "knotvector.h" + +/* local type definitions */ +struct Breakpt { /* breakpoints */ + Knot value; /* value */ + int multi; /* multiplicity */ + int def; /* deficit */ +}; + +struct Knotspec { /* knotvector format */ + long order; /* order of spline */ + Knot_ptr inkbegin; /* input knot sequence */ + Knot_ptr inkend; /* location after last knot */ + Knot_ptr outkbegin; /* in-process knot subsequence */ + Knot_ptr outkend; /* location after last knot */ + Knot_ptr kleft; /* */ + Knot_ptr kright; /* */ + Knot_ptr kfirst; /* */ + Knot_ptr klast; /* */ + Knot_ptr sbegin; /* conversion factor values */ + Breakpt * bbegin; /* in-process breakpoints */ + Breakpt * bend; /* last breakpoint */ + int ncoords; /* coordinates per control point */ + int prestride; /* stride between input points */ + int poststride; /* stride between output points */ + int preoffset; /* scaled point offset */ + int postoffset; /* scaled point offset */ + int prewidth; /* width of dimension */ + int postwidth; /* width of dimension */ + int istransformed; /* was dimension transformed */ + Knotspec * next; /* next knotspec */ + Knotspec * kspectotrans; /* knotspec in transformation direction */ + + Knotspec( void ); + ~Knotspec( void ); + void factors( void ); + void insert( REAL * ); + void preselect(); + void select( void ); + void copy( INREAL *, REAL * ); + void breakpoints( void ); + void knots( void ); + void transform( REAL * ); + + void pt_io_copy( REAL *, INREAL * ); + void pt_oo_copy( REAL *, REAL * ); + void pt_oo_sum( REAL*, REAL*, REAL*, Knot, Knot ); +}; + +struct Splinespec { /* a non-uniform tensor element */ + Splinespec( int ); + ~Splinespec(void); + Knotspec *kspec; /* format of each param. dir. */ + int dim; /* domain dimension */ + REAL * outcpts; /* Bezier control points */ + + void kspecinit( Knotvector & ); + void kspecinit( Knotvector &, Knotvector & ); + void select( void ); + void layout( long ); + void setupquilt( Quilt_ptr ); + void copy( INREAL * ); + void transform( void ); +}; + +/*----------------------------------------------------------------------------- + * Quilt::toBezier - convert from NURBS to rational Bezier + *----------------------------------------------------------------------------- + */ + +void +Quilt::toBezier( + Knotvector& knotvector, /* a knot vector */ + INREAL *ctlpts, /* input contol points */ + long ncoords ) /* number of coordinates per control point */ +{ + Splinespec spline( 1 ); + spline.kspecinit( knotvector ); + spline.select(); + spline.layout( ncoords ); + spline.setupquilt( this ); + spline.copy( ctlpts ); + spline.transform(); +} + +void +Quilt::toBezier( + Knotvector& sknotvector, /* a knot vector */ + Knotvector& tknotvector, /* a knot vector */ + INREAL *ctlpts, /* input contol points */ + long ncoords ) /* number of coordinates per control point */ +{ + Splinespec spline( 2 ); + spline.kspecinit( sknotvector, tknotvector ); + spline.select(); + spline.layout( ncoords ); + spline.setupquilt( this ); + spline.copy( ctlpts ); + spline.transform(); +} +Splinespec::Splinespec( int dimen ) +{ + dim = dimen; +} + +Splinespec::~Splinespec( void ) +{ + /* Note: do NOT delete 'outcpts' here since its address (not contents) + * is copied in 'cpts' in this file in function Splinespec::setupquilt(). + * This block of memory will eventually be deleted in file quilt.c++ in + * function Quilt::deleteMe() through 'cpts' so do NOT delete it here! + */ + Knotspec *ktrav= kspec; //start at beginning of list + while (ktrav != 0) { //any items to delete? + Knotspec *deleteThis= ktrav; //remember to delete this + ktrav= ktrav->next; //go to next item if any + delete deleteThis; //delete it + } +} /* ~Splinespec() */ + +/*----------------------------------------------------------------------------- + * Splinespec::kspecinit - initialize Splinespec structure + * + * Client: Quilt::toBezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::kspecinit( Knotvector& knotvector ) +{ + kspec = new Knotspec; + kspec->inkbegin = knotvector.knotlist; + kspec->inkend = knotvector.knotlist + knotvector.knotcount; + kspec->prestride = (int) knotvector.stride; + kspec->order = knotvector.order; + kspec->next = NULL; +} + +void +Splinespec::kspecinit( Knotvector& sknotvector, Knotvector& tknotvector ) +{ + kspec = new Knotspec; + Knotspec *tkspec = new Knotspec; + + kspec->inkbegin = sknotvector.knotlist; + kspec->inkend = sknotvector.knotlist + sknotvector.knotcount; + kspec->prestride = (int) sknotvector.stride; + kspec->order = sknotvector.order; + kspec->next = tkspec; + + tkspec->inkbegin = tknotvector.knotlist; + tkspec->inkend = tknotvector.knotlist + tknotvector.knotcount; + tkspec->prestride = (int) tknotvector.stride; + tkspec->order = tknotvector.order; + tkspec->next = NULL; +} + + +/*----------------------------------------------------------------------------- + * Splinespec::select - select the subsegments to copy + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::select( ) +{ + for( Knotspec *knotspec = kspec; knotspec; knotspec = knotspec->next ) { + knotspec->preselect(); + knotspec->select(); + } +} + +/*----------------------------------------------------------------------------- + * Splinespec::layout - + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::layout( long ncoords ) +{ + + long stride = ncoords; + for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next ) { + knotspec->poststride = (int) stride; + stride *= ((long)(knotspec->bend-knotspec->bbegin)*knotspec->order + knotspec->postoffset); + knotspec->preoffset *= knotspec->prestride; + knotspec->prewidth *= knotspec->poststride; + knotspec->postwidth *= knotspec->poststride; + knotspec->postoffset *= knotspec->poststride; + knotspec->ncoords = (int) ncoords; + } + outcpts = new REAL[stride]; + assert( outcpts != 0 ); +} + +/*----------------------------------------------------------------------------- + * Splinespec::copy - copy the control points of current subobject + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::copy( INREAL *incpts ) +{ + kspec->copy( incpts, outcpts ); +} + +/*----------------------------------------------------------------------------- + * Splinespec::setupquilt - assign all quilt variables from knotspec + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::setupquilt( Quilt_ptr quilt ) +{ + Quiltspec_ptr qspec = quilt->qspec; + quilt->eqspec = qspec + dim; + for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next, qspec++ ) { + qspec->stride = knotspec->poststride; + qspec->width = (int)(knotspec->bend - knotspec->bbegin); + qspec->order = (int)knotspec->order; + qspec->offset = knotspec->postoffset; + qspec->index = 0; + qspec->bdry[0] = (knotspec->kleft == knotspec->kfirst) ? 1 : 0; + qspec->bdry[1] = (knotspec->kright == knotspec->klast) ? 1 : 0; + qspec->breakpoints = new Knot[qspec->width+1]; + Knot_ptr k = qspec->breakpoints; + for( Breakpt *bk = knotspec->bbegin; bk <= knotspec->bend; bk++ ) + *(k++) = bk->value; + } + quilt->cpts = outcpts; + quilt->next = 0; +} + +/*----------------------------------------------------------------------------- + * Splinespec::transform - convert a spline to Bezier format + * + * Client: gl_quilt_to_bezier + *----------------------------------------------------------------------------- + */ + +void +Splinespec::transform( void ) +{ + Knotspec *knotspec; + for( knotspec = kspec; knotspec; knotspec=knotspec->next ) + knotspec->istransformed = 0; + + for( knotspec = kspec; knotspec; knotspec=knotspec->next ) { + for( Knotspec *kspec2 = kspec; kspec2; kspec2=kspec2->next ) + kspec2->kspectotrans = knotspec; + kspec->transform( outcpts ); + knotspec->istransformed = 1; + } +} + + +/*----------------------------------------------------------------------------- + * Knotspec::Knotspec - constuct a knot spec + *----------------------------------------------------------------------------- + */ + +Knotspec::Knotspec( void ) +{ + bbegin = 0; + sbegin = 0; + outkbegin = 0; +} + +/*----------------------------------------------------------------------------- + * Knotspec::copy - copy the control points along minor direction + * + * Client: Splinespec::copy + *----------------------------------------------------------------------------- + */ + +void +Knotspec::copy( INREAL *inpt, REAL *outpt ) +{ + inpt = (INREAL *) (((char *) inpt) + preoffset); + + if( next ) { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { + next->copy( inpt, outpt ); + inpt = (INREAL *) (((char *) inpt) + prestride); + } + } else { + for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) { + pt_io_copy( outpt, inpt ); + inpt = (INREAL *) (((char *) inpt) + prestride); + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::factors - precompute scale factors + * - overwrites knot vector, actual new knot vector is NOT produced + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::factors( void ) +{ + Knot *mid = (outkend - 1) - order + bend->multi; + Knot_ptr fptr = sbegin; + + for( Breakpt *bpt = bend; bpt >= bbegin; bpt-- ) { + mid -= bpt->multi; // last knot less than knot to insert + int def = bpt->def - 1; // number of knots to insert + if( def <= 0 ) continue; + Knot kv = bpt->value; // knot to insert + + Knot *kf = (mid-def) + (order-1); + for( Knot *kl = kf + def; kl != kf; kl-- ) { + Knot *kh, *kt; + for( kt=kl, kh=mid; kt != kf; kh--, kt-- ) + *(fptr++) = (kv - *kh) / (*kt - *kh); + *kl = kv; + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::insert - convert subobject in direction of kspec into Bezier + * + * Client: Knotspec::transform + *----------------------------------------------------------------------------- + */ + +void +Knotspec::insert( REAL *p ) +{ + Knot_ptr fptr = sbegin; + REAL *srcpt = p + prewidth - poststride; + REAL *dstpt = p + postwidth + postoffset - poststride; + Breakpt *bpt = bend; + + for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride ) { + REAL *p1 = srcpt; + for( REAL *p2 = srcpt-poststride; p2 != pend; p1 = p2, p2 -= poststride ) { + pt_oo_sum( p1, p1, p2, *fptr, 1.0f-*fptr ); + fptr++; + } + } + + for( --bpt; bpt >= bbegin; bpt-- ) { + + for( int multi = bpt->multi; multi > 0; multi-- ) { + pt_oo_copy( dstpt, srcpt ); + dstpt -= poststride; + srcpt -= poststride; + } + + for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride, dstpt-=poststride ) { + pt_oo_copy( dstpt, srcpt ); + REAL *p1 = srcpt; + + for( REAL *p2 = srcpt-poststride; p2 != pend; p1=p2, p2 -= poststride ) { + pt_oo_sum( p1, p1, p2, *fptr, 1.0f-*fptr ); + fptr++; + } + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::preselect - initialize kspec for processing + * + * Client: Splinespec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::preselect( void ) +{ + Knot kval; + + /* position klast after last knot of "last" breakpoint */ + for( klast = inkend - order, kval = *klast; klast != inkend; klast++ ) + if( ! identical( *klast, kval ) ) break; + + /* position kfirst after last knot of "first" breakpoint */ + for( kfirst = inkbegin+order-1, kval= *kfirst; kfirst != inkend; kfirst++ ) + if( ! identical( *kfirst, kval ) ) break; + + /* compute multiplicity of first breakpoint */ + Knot_ptr k; + for( k = kfirst - 1; k >= inkbegin; k-- ) + if( ! identical( kval, *k ) ) break; + k++; + + /* allocate space for breakpoints - + use worst case estimate on number of breakpoints */ + + bbegin = new Breakpt[(klast - kfirst)+1]; + /* record multiplicity and value of first breakpoint */ + bbegin->multi = (int)(kfirst - k); + bbegin->value = kval; + bend = bbegin; + + kleft = kright = kfirst; +} + + +/*----------------------------------------------------------------------------- + * Knotspec::select - Knotspec::select segments and precompute scale factors + * + * Client: Splinespec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::select( void ) +{ + breakpoints(); + knots(); + factors(); + + preoffset = (int)(kleft - (inkbegin + order)); + postwidth = (int)((bend - bbegin) * order); + prewidth = (int)((outkend - outkbegin) - order); + postoffset = (bbegin->def > 1) ? (bbegin->def-1) : 0; +} + +/*----------------------------------------------------------------------------- + * Knotspec::breakpoints - compute breakpoints for knotspec + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::breakpoints( void ) +{ + Breakpt *ubpt = bbegin; + Breakpt *ubend = bend; + long nfactors = 0; + + ubpt->value = ubend->value; + ubpt->multi = ubend->multi; + + kleft = kright; + + for( ; kright != klast; kright++ ) { + if ( identical(*kright,ubpt->value) ) { + (ubpt->multi)++; + } else { + ubpt->def = (int) (order - ubpt->multi); + nfactors += (ubpt->def * (ubpt->def - 1)) / 2; + (++ubpt)->value = *kright; + ubpt->multi = 1; + } + } + ubpt->def = (int) (order - ubpt->multi); + nfactors += (ubpt->def * (ubpt->def - 1)) / 2; + + bend = ubpt; + + if( nfactors ) { + sbegin = new Knot[nfactors]; + } else { + sbegin = NULL; + } +} + + +/*----------------------------------------------------------------------------- + * Knotspec::knots - copy relevant subsequence of knots into temporary area + * + * Client: Knotspec::select + *----------------------------------------------------------------------------- + */ + +void +Knotspec::knots( void ) +{ + Knot_ptr inkpt = kleft - order; + Knot_ptr inkend = kright + bend->def; + + /* allocate space for knots and factors */ + outkbegin = new Knot[inkend-inkpt]; + Knot_ptr outkpt; + for( outkpt = outkbegin; inkpt != inkend; inkpt++, outkpt++ ) + *outkpt = *inkpt; + + outkend = outkpt; +} + + +/*----------------------------------------------------------------------------- + * Knotspec::transform - convert a spline along a given direction + * + * Client: Splienspec::transform + *----------------------------------------------------------------------------- + */ + +void +Knotspec::transform( REAL *p ) +{ + if( next ) { + if( this == kspectotrans ) { + next->transform( p ); + } else { + if( istransformed ) { + p += postoffset; + for( REAL *pend = p + postwidth; p != pend; p += poststride ) + next->transform( p ); + } else { + REAL *pend = p + prewidth; + for( ; p != pend; p += poststride ) + next->transform( p ); + } + } + } else { + if( this == kspectotrans ) { + insert( p ); + } else { + if( istransformed ) { + p += postoffset; + for( REAL *pend = p + postwidth; p != pend; p += poststride ) + kspectotrans->insert( p ); + } else { + REAL *pend = p + prewidth; + for( ; p != pend; p += poststride ) + kspectotrans->insert( p ); + } + } + } +} + +/*----------------------------------------------------------------------------- + * Knotspec::~Knotspec - free space alocated for knotspec + *----------------------------------------------------------------------------- + */ + +Knotspec::~Knotspec( void ) +{ + if( bbegin ) delete[] bbegin; + if( sbegin ) delete[] sbegin; + if( outkbegin ) delete[] outkbegin; +} + + +/*----------------------------------------------------------------------------- + * pt_io_copy - make internal copy of input cntrl pt. of x coords + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_io_copy( REAL *topt, INREAL *frompt ) +{ + switch( ncoords ) { + case 4: + topt[3] = (REAL) frompt[3]; + case 3: + topt[2] = (REAL) frompt[2]; + case 2: + topt[1] = (REAL) frompt[1]; + case 1: + topt[0] = (REAL) frompt[0]; + break; + default: { + for( int i = 0; i < ncoords; i++ ) + *topt++ = (REAL) *frompt++; + } + } +} + +/*----------------------------------------------------------------------------- + * pt_oo_copy - make internal copy of internal cntrl pt. of x coords + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_oo_copy( REAL *topt, REAL *frompt ) +{ + switch( ncoords ) { + case 4: + topt[3] = frompt[3]; + case 3: + topt[2] = frompt[2]; + case 2: + topt[1] = frompt[1]; + case 1: + topt[0] = frompt[0]; + break; + default: + memcpy( topt, frompt, ncoords * sizeof( REAL ) ); + } +} + +/*----------------------------------------------------------------------------- + * pt_oo_sum - compute affine combination of internal cntrl pts + *----------------------------------------------------------------------------- + */ + +void +Knotspec::pt_oo_sum( REAL *x, REAL *y, REAL *z, Knot a, Knot b ) +{ + switch( ncoords ) { + case 4: + x[3] = a * y[3] + b * z[3]; + case 3: + x[2] = a * y[2] + b * z[2]; + case 2: + x[1] = a * y[1] + b * z[1]; + case 1: + x[0] = a * y[0] + b * z[0]; + break; + default: { + for( int i = 0; i < ncoords; i++ ) + *x++ = a * *y++ + b * *z++; + } + } +} diff --git a/project/jni/glu/src/libnurbs/internals/trimline.cc b/project/jni/glu/src/libnurbs/internals/trimline.cc new file mode 100644 index 000000000..99fea9d8e --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimline.cc @@ -0,0 +1,216 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * trimline.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "trimline.h" +#include "backend.h" + +Trimline::Trimline() +{ + size = 0; pts = 0; numverts = 0; + tinterp = &t; binterp = &b; +} + +Trimline::~Trimline() +{ + if( pts ) delete[] pts; +} + +void +Trimline::init( TrimVertex *v ) +{ + reset(); + grow(1); + append(v); +} + +inline void +Trimline::grow( long npts ) +{ + if( size < npts ) { + size = 2 * npts; + if( pts ) delete[] pts; + pts = new TrimVertex_p[size]; + } +} + +inline void +Trimline::append( TrimVertex *v ) +{ + assert( numverts != size ); + pts[numverts++] = v; +} + +void +Trimline::init( long npts, Arc_ptr jarc, long last ) +{ + jarcl.init( jarc, 0, last ); + grow( npts + 2 ); +} + +inline void +Trimline::swap() +{ + TrimVertex *tmp=tinterp; + tinterp=binterp; + binterp=tmp; +} + +void +Trimline::getNextPt() +{ + *binterp = *jarcl.getnextpt(); +} + +void +Trimline::getPrevPt() +{ + *binterp = *jarcl.getprevpt(); +} + +/*---------------------------------------------------------------------- + * getNextPts - make arrays of pointers to trim points on left and right + * hulls of trim strip. + *---------------------------------------------------------------------- + */ +void +Trimline::getNextPts( REAL vval, Backend& backend ) +{ + reset(); swap(); append( tinterp ); + assert( tinterp->param[1] >= vval ); + + register TrimVertex *p; + for( p=jarcl.getnextpt() ; p->param[1] >= vval; p=jarcl.getnextpt() ) { + append( p ); + } + + /* compute and copy pointer to final point on left hull */ + if( interpvert( last(), p, binterp, vval ) ) { + binterp->nuid = p->nuid; + backend.triangle( p, binterp, last() ); + append( binterp ); + } + jarcl.reverse(); + (void) jarcl.getprevpt(); /* reset jarcl to proper position */ + jarcl.reverse(); +} + +void +Trimline::getPrevPts( REAL vval, Backend& backend ) +{ + reset(); swap(); append( tinterp ); + assert( tinterp->param[1] >= vval ); + + register TrimVertex *q; + for( q=jarcl.getprevpt(); q->param[1] >= vval; q=jarcl.getprevpt() ) { + append( q ); + } + + /* compute and copy pointer to final point on right hull */ + if( interpvert( q, last(), binterp, vval ) ) { + binterp->nuid = q->nuid; + backend.triangle( last(), binterp, q ); + append( binterp ); + } + jarcl.reverse(); + (void) jarcl.getnextpt(); /* reset jarcl to proper position */ + jarcl.reverse(); +} + +void +Trimline::getNextPts( Arc_ptr botarc ) +{ + reset(); swap(); append( tinterp ); + + TrimVertex *lastpt2 = botarc->pwlArc->pts; + register TrimVertex *p = jarcl.getnextpt(); + for( append( p ); p != lastpt2; append( p ) ) { + assert( p != lastpt1 ); + p = jarcl.getnextpt(); + } +} + +void +Trimline::getPrevPts( Arc_ptr botarc ) +{ + reset(); swap(); append( tinterp ); + + PwlArc *lastpwl = botarc->prev->pwlArc; + TrimVertex *lastpt1 = &lastpwl->pts[lastpwl->npts-1]; + + register TrimVertex *q = jarcl.getprevpt(); + for( append( q ); q != lastpt1; append( q ) ) { + assert( q != lastpt2 ); + q = jarcl.getprevpt(); + } +} + + +long +Trimline::interpvert( TrimVertex *a, TrimVertex *b, TrimVertex *c, REAL vval ) +{ + REAL denom = a->param[1] - b->param[1]; + + if(denom != 0) { + if( vval == a->param[1] ) { + c->param[0] = a->param[0]; + c->param[1] = a->param[1]; + c->nuid = a->nuid; + return 0; + } else if( vval == b->param[1] ) { + c->param[0] = b->param[0]; + c->param[1] = b->param[1]; + c->nuid = b->nuid; + return 0; + } else { + REAL r = (a->param[1] - vval)/denom; + c->param[0] = a->param[0] - r * (a->param[0] - b->param[0]); + c->param[1] = vval; + return 1; + } + } else { + c->param[0] = a->param[0]; + c->param[1] = a->param[1]; + c->nuid = a->nuid; + return 0; + } +} + diff --git a/project/jni/glu/src/libnurbs/internals/trimline.h b/project/jni/glu/src/libnurbs/internals/trimline.h new file mode 100644 index 000000000..711191e1a --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimline.h @@ -0,0 +1,101 @@ +/* + * 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. + */ + +/* + * trimline.h + * + */ + +#ifndef __glutrimline_h_ +#define __glutrimline_h_ + +class Arc; +class Backend; + +#include "trimvertex.h" +#include "jarcloc.h" + + +class Trimline { +private: + TrimVertex** pts; + long numverts; + long i; + long size; + Jarcloc jarcl; + TrimVertex t, b; + TrimVertex *tinterp, *binterp; + void reset( void ) { numverts = 0; } + inline void grow( long ); + inline void swap( void ); + inline void append( TrimVertex * ); + static long interpvert( TrimVertex *, TrimVertex *, TrimVertex *, REAL ); + +public: + Trimline(); + ~Trimline(); + void init( TrimVertex * ); + void init( long, Arc_ptr, long ); + void getNextPt( void ); + void getPrevPt( void ); + void getNextPts( REAL, Backend & ); + void getPrevPts( REAL, Backend & ); + void getNextPts( Arc_ptr ); + void getPrevPts( Arc_ptr ); + inline TrimVertex * next( void ); + inline TrimVertex * prev( void ); + inline TrimVertex * first( void ); + inline TrimVertex * last( void ); +}; + +inline TrimVertex * +Trimline::next( void ) +{ + if( i < numverts) return pts[i++]; else return 0; +} + +inline TrimVertex * +Trimline::prev( void ) +{ + if( i >= 0 ) return pts[i--]; else return 0; +} + +inline TrimVertex * +Trimline::first( void ) +{ + i = 0; return pts[i]; +} + +inline TrimVertex * +Trimline::last( void ) +{ + i = numverts; return pts[--i]; +} +#endif /* __glutrimline_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/trimregion.cc b/project/jni/glu/src/libnurbs/internals/trimregion.cc new file mode 100644 index 000000000..7400bd654 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimregion.cc @@ -0,0 +1,112 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ + +/* + * trimregion.c++ + * + */ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "trimregion.h" +#include "backend.h" + +TrimRegion::TrimRegion(void) +{ +} + +void TrimRegion::setDu(REAL du) +{ + oneOverDu=1.0f/du; +} + +void TrimRegion::init(long npts, Arc_ptr extrema) +{ + left.init(npts, extrema, extrema->pwlArc->npts-1); + left.getNextPt(); + + right.init(npts, extrema, 0); + right.getPrevPt(); +} + +void TrimRegion::getPts(Arc_ptr extrema) +{ + left.getNextPts(extrema); + right.getPrevPts(extrema); +} + +void TrimRegion::getPts(Backend& backend) +{ + left.getNextPts(bot.vval, backend); + right.getPrevPts(bot.vval, backend); +} + +void TrimRegion::getGridExtent(void) +{ + getGridExtent(left.last(), right.last()); +} + +void TrimRegion::getGridExtent(TrimVertex* l, TrimVertex* r) +{ + bot.ustart=(long)((l->param[0]-uarray.uarray[0])*oneOverDu); + + if (l->param[0]>=uarray.uarray[bot.ustart]) + { + bot.ustart++; + } + assert(l->param[0]<=uarray.uarray[bot.ustart]); + assert(l->param[0]>=uarray.uarray[bot.ustart-1]); + + bot.uend=(long)((r->param[0]-uarray.uarray[0])*oneOverDu); + if (uarray.uarray[bot.uend]>=r->param[0]) + { + bot.uend--; + } + assert(r->param[0]>=uarray.uarray[bot.uend]); + assert(r->param[0]<=uarray.uarray[bot.uend+1]); +} + +int TrimRegion::canTile(void) +{ + TrimVertex* lf=left.first(); + TrimVertex* ll=left.last(); + TrimVertex* l=(ll->param[0]>lf->param[0]) ? ll : lf; + + TrimVertex* rf=right.first(); + TrimVertex* rl=right.last(); + TrimVertex* r=(rl->param[0]param[0]) ? rl : rf; + + return (l->param[0]<=r->param[0]) ? 1 : 0; +} diff --git a/project/jni/glu/src/libnurbs/internals/trimregion.h b/project/jni/glu/src/libnurbs/internals/trimregion.h new file mode 100644 index 000000000..ee581871f --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimregion.h @@ -0,0 +1,84 @@ +/* + * 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. + */ + +/* + * trimregion.h + * + */ + +#ifndef __glutrimregion_h_ +#define __glutrimregion_h_ + +#include "trimline.h" +#include "gridline.h" +#include "uarray.h" + +class Arc; +class Backend; + +class TrimRegion +{ + public: + TrimRegion(); + Trimline left; + Trimline right; + Gridline top; + Gridline bot; + Uarray uarray; + + void init(REAL); + void advance(REAL, REAL, REAL); + void setDu(REAL); + void init(long, Arc_ptr); + void getPts(Arc_ptr); + void getPts(Backend&); + void getGridExtent(TrimVertex*, TrimVertex*); + void getGridExtent(void); + int canTile(void); + private: + REAL oneOverDu; +}; + +inline void TrimRegion::init(REAL vval) +{ + bot.vval=vval; +} + +inline void TrimRegion::advance(REAL topVindex, REAL botVindex, REAL botVval) +{ + top.vindex=(long)topVindex; + bot.vindex=(long)botVindex; + top.vval=bot.vval; + bot.vval=botVval; + top.ustart=bot.ustart; + top.uend=bot.uend; +} + +#endif /* __glutrimregion_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/trimvertex.h b/project/jni/glu/src/libnurbs/internals/trimvertex.h new file mode 100644 index 000000000..7a0e272ef --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimvertex.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * trimvertex.h + * + */ + +#ifndef __glutrimvertex_h_ +#define __glutrimvertex_h_ + +#include "types.h" + +/* a vertex on a trim curve */ +class TrimVertex +{ + public: + REAL param[2]; /* parametric space coords */ + long nuid; +}; + +typedef class TrimVertex* TrimVertex_p; + +inline REAL det3(TrimVertex* a, TrimVertex* b, TrimVertex* c) +{ + return a->param[0]*(b->param[1]-c->param[1])+ + b->param[0]*(c->param[1]-a->param[1])+ + c->param[0]*(a->param[1]-b->param[1]); +} + +#endif /* __glutrimvertex_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/trimvertpool.cc b/project/jni/glu/src/libnurbs/internals/trimvertpool.cc new file mode 100644 index 000000000..693b7b4dd --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimvertpool.cc @@ -0,0 +1,133 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "mystring.h" +#include "trimvertex.h" +#include "trimvertpool.h" +#include "bufpool.h" + +#include + +/*---------------------------------------------------------------------------- + * TrimVertexPool::TrimVertexPool + *---------------------------------------------------------------------------- + */ +TrimVertexPool::TrimVertexPool(void): pool(sizeof(TrimVertex)*3, 32, "Threevertspool") +{ + // initialize array of pointers to vertex lists + nextvlistslot=0; + vlistsize=INIT_VERTLISTSIZE; + vlist=new TrimVertex_p[vlistsize]; +} + +/*---------------------------------------------------------------------------- + * TrimVertexPool::~TrimVertexPool + *---------------------------------------------------------------------------- + */ +TrimVertexPool::~TrimVertexPool(void) +{ + // free all arrays of TrimVertices vertices + while (nextvlistslot) + { + delete[] vlist[--nextvlistslot]; + } + + // reallocate space for array of pointers to vertex lists + if (vlist) + { + delete[] vlist; + } +} + +/*---------------------------------------------------------------------------- + * TrimVertexPool::clear + *---------------------------------------------------------------------------- + */ +void TrimVertexPool::clear(void) +{ + // reinitialize pool of 3 vertex arrays + pool.clear(); + + // free all arrays of TrimVertices vertices + while (nextvlistslot) + { + delete[] vlist[--nextvlistslot]; + vlist[nextvlistslot]=0; + } + + // reallocate space for array of pointers to vertex lists + if (vlist) + { + delete[] vlist; + } + vlist=new TrimVertex_p[vlistsize]; +} + +/*---------------------------------------------------------------------------- + * TrimVertexPool::get - allocate a vertex list + *---------------------------------------------------------------------------- + */ +TrimVertex* TrimVertexPool::get(int n) +{ + TrimVertex* v; + + if (n==3) + { + v=(TrimVertex*)pool.new_buffer(); + } + else + { + if (nextvlistslot==vlistsize) + { + vlistsize*=2; + TrimVertex_p* nvlist=new TrimVertex_p[vlistsize]; + memcpy(nvlist, vlist, nextvlistslot*sizeof(TrimVertex_p)); + if (vlist) + { + delete[] vlist; + } + vlist=nvlist; + } + v=vlist[nextvlistslot++]=new TrimVertex[n]; + } + + return v; +} diff --git a/project/jni/glu/src/libnurbs/internals/trimvertpool.h b/project/jni/glu/src/libnurbs/internals/trimvertpool.h new file mode 100644 index 000000000..c8c128818 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/trimvertpool.h @@ -0,0 +1,58 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glutrimvertpool_h_ +#define __glutrimvertpool_h_ + +#include "bufpool.h" + +class TrimVertex; + +#define INIT_VERTLISTSIZE 200 + +class TrimVertexPool +{ + public: + TrimVertexPool(void); + ~TrimVertexPool(void); + void clear(void); + TrimVertex* get(int); + private: + Pool pool; + TrimVertex** vlist; + int nextvlistslot; + int vlistsize; +}; + +#endif /* __glutrimvertpool_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/types.h b/project/jni/glu/src/libnurbs/internals/types.h new file mode 100644 index 000000000..49e6071a1 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/types.h @@ -0,0 +1,45 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __glutypes_h_ +#define __glutypes_h_ + +#define INREAL float +typedef float REAL; +typedef void (*Pfvv)(void); +typedef void (*Pfvf)(float*); +typedef int (*cmpfunc)(const void*, const void*); +typedef REAL Knot, *Knot_ptr; /* knot values */ + +#endif /* __glutypes_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/uarray.cc b/project/jni/glu/src/libnurbs/internals/uarray.cc new file mode 100644 index 000000000..d77313863 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/uarray.cc @@ -0,0 +1,82 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "uarray.h" +#include "arc.h" + +Uarray::Uarray(void) +{ + uarray=0; + size=0; +} + +Uarray::~Uarray(void) +{ + if (uarray) + { + delete[] uarray; + } +} + +long Uarray::init(REAL delta, Arc_ptr lo, Arc_ptr hi) +{ + ulines=(long)((hi->tail()[0]-lo->tail()[0])/delta)+3; + + if (sizetail()[0]-delta/2.0f; + + for (long i=1; i!=ulines; i++) + { + uarray[i]=uarray[0]+i*delta; + } + + return ulines; +} diff --git a/project/jni/glu/src/libnurbs/internals/uarray.h b/project/jni/glu/src/libnurbs/internals/uarray.h new file mode 100644 index 000000000..e7add743c --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/uarray.h @@ -0,0 +1,55 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __gluuarray_h_ +#define __gluuarray_h_ + +#include "types.h" + +class Arc; +typedef class Arc* Arc_ptr; + +class Uarray +{ + private: + long size; + long ulines; + public: + Uarray(); + ~Uarray(); + long init(REAL, Arc_ptr, Arc_ptr); + REAL* uarray; +}; + +#endif /* __gluuarray_h_ */ diff --git a/project/jni/glu/src/libnurbs/internals/varray.cc b/project/jni/glu/src/libnurbs/internals/varray.cc new file mode 100644 index 000000000..d69876fb5 --- /dev/null +++ b/project/jni/glu/src/libnurbs/internals/varray.cc @@ -0,0 +1,163 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glimports.h" +#include "myassert.h" +#include "mystdio.h" +#include "varray.h" +#include "arc.h" +#include "simplemath.h" // glu_abs() + +#define TINY 0.0001f +inline long sgn(REAL x) +{ + return (x<-TINY) ? -1 : ((x>TINY) ? 1 : 0); +} + +Varray::Varray(void) +{ + varray=0; + size=0; +} + +Varray::~Varray(void) +{ + if (varray) + { + delete[] varray; + } +} + +inline void Varray::update(Arc_ptr arc, long dir[2], REAL val) +{ + register long ds=sgn(arc->tail()[0]-arc->prev->tail()[0]); + register long dt=sgn(arc->tail()[1]-arc->prev->tail()[1]); + + if (dir[0]!=ds || dir[1]!=dt) + { + dir[0]=ds; + dir[1]=dt; + append(val); + } +} + +void Varray::grow(long guess) +{ + if (sizenext; + Arc_ptr right=toparc; + long ldir[2], rdir[2]; + + ldir[0]=sgn(left->tail()[0]-left->prev->tail()[0]); + ldir[1]=sgn(left->tail()[1]-left->prev->tail()[1]); + rdir[0]=sgn(right->tail()[0]-right->prev->tail()[0]); + rdir[1]=sgn(right->tail()[1]-right->prev->tail()[1]); + + vval[0]=toparc->tail()[1]; + numquads=0; + + while (1) + { + switch (sgn(left->tail()[1]-right->prev->tail()[1])) + { + case 1: + left=left->next; + update(left, ldir, left->prev->tail()[1]); + break; + case -1: + right=right->prev; + update(right, rdir, right->tail()[1]); + break; + case 0: + if (glu_abs(left->tail()[1]-botarc->tail()[1])tail()[0]-right->prev->tail()[0])tail()[1]-right->prev->tail()[1])next; + break; + } + } +end: + append(botarc->tail()[1]); + + grow(((long)((vval[0]-vval[numquads])/delta))+numquads+2); + + long i, index=0; + + for (i=0; idelta) + { + long steps=((long)(dist/delta))+1; + float deltav=-dist/(REAL)steps; + + for (long j=1; j +*/ + +#ifndef __gluvarray_h_ +#define __gluvarray_h_ + +#include "types.h" + +class Arc; + +class Varray +{ + public: + Varray(); + ~Varray(); + long init(REAL, Arc*, Arc*); + REAL* varray; + REAL vval[1000]; + long voffset[1000]; + long numquads; + + private: + long size; + inline void update(Arc*, long[2], REAL); + void grow(long); + inline void append(REAL); +}; + +inline void Varray::append(REAL v) +{ + if (v!=vval[numquads]) + { + vval[++numquads]=v; + } +} + +#endif /* __gluvarray_h_ */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/definitions.h b/project/jni/glu/src/libnurbs/nurbtess/definitions.h new file mode 100644 index 000000000..a3ba5533b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/definitions.h @@ -0,0 +1,42 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _DEFINITIONS_H +#define _DEFINITIONS_H + +typedef float Real; +typedef int Int; +typedef Real Real2[2]; + +#endif /* _DEFINITIONS_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/directedLine.cc b/project/jni/glu/src/libnurbs/nurbtess/directedLine.cc new file mode 100644 index 000000000..e99c4841b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/directedLine.cc @@ -0,0 +1,716 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include +#include "glimports.h" +#include "zlassert.h" + +#include "quicksort.h" +#include "directedLine.h" +#include "polyDBG.h" + +#ifdef __WATCOMC__ +#pragma warning 726 10 +#endif + +//we must return the newLine +directedLine* directedLine::deleteChain(directedLine* begin, directedLine* end) +{ + if(begin->head()[0] == end->tail()[0] && + begin->head()[1] == end->tail()[1] + ) + { + directedLine *ret = begin->prev; + begin->prev->next = end->next; + end->next->prev = begin->prev; + delete begin->sline; + delete end->sline; + delete begin; + delete end; + + return ret; + } + + directedLine* newLine; + sampledLine* sline = new sampledLine(begin->head(), end->tail()); + newLine = new directedLine(INCREASING, sline); + directedLine *p = begin->prev; + directedLine *n = end->next; + p->next = newLine; + n->prev = newLine; + newLine->prev = p; + newLine->next = n; + + delete begin->sline; + delete end->sline; + delete begin; + delete end; + return newLine; +} + + +void directedLine::deleteSingleLine(directedLine* dline) +{ + //make sure that dline->prev->tail is the same as + //dline->next->head. This is for numerical erros. + //for example, if we delete a line which is almost degeneate + //within (epsilon), then we want to make that the polygon after deletion + //is still a valid polygon + + dline->next->head()[0] = dline->prev->tail()[0]; + dline->next->head()[1] = dline->prev->tail()[1]; + + dline->prev->next = dline->next; + dline->next->prev = dline->prev; + + delete dline; + +} + +static Int myequal(Real a[2], Real b[2]) +{ + /* + if(a[0]==b[0] && a[1] == b[1]) + return 1; + else + return 0; + */ + + + if(fabs(a[0]-b[0]) < 0.00001 && + fabs(a[1]-b[1]) < 0.00001) + return 1; + else + return 0; + +} + +directedLine* directedLine::deleteDegenerateLines() +{ + //if there is only one edge or two edges, don't do anything + if(this->next == this) + return this; + if(this->next == this->prev) + return this; + + //find a nondegenerate line + directedLine* temp; + directedLine* first = NULL; + if(! myequal(head(), tail())) + /* + if(head()[0] != tail()[0] || + head()[1] != tail()[1]) + */ + first = this; + else + { + for(temp = this->next; temp != this; temp = temp->next) + { + /* + if(temp->head()[0] != temp->tail()[0] || + temp->head()[1] != temp->tail()[1]) + */ + if(! myequal(temp->head(), temp->tail())) + { + first = temp; + break; + } + + } + } + + //if there are no non-degenerate lines, then we simply return NULL. + if(first == NULL) + { + deleteSinglePolygonWithSline(); + return NULL; + } + + directedLine* tempNext = NULL; + for(temp =first->next; temp != first; temp = tempNext) + { + tempNext = temp->getNext(); +/* + if(temp->head()[0] == temp->tail()[0] && + temp->head()[1] == temp->tail()[1]) +*/ + + if(myequal(temp->head(), temp->tail())) + deleteSingleLine(temp); + } + return first; +} + +directedLine* directedLine::deleteDegenerateLinesAllPolygons() +{ + directedLine* temp; + directedLine *tempNext = NULL; + directedLine* ret= NULL; + directedLine* retEnd = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->nextPolygon; + temp->nextPolygon = NULL; + if(ret == NULL) + { + ret = retEnd = temp->deleteDegenerateLines(); + + } + else + { + directedLine *newPolygon = temp->deleteDegenerateLines(); + if(newPolygon != NULL) + { + retEnd->nextPolygon = temp->deleteDegenerateLines(); + retEnd = retEnd->nextPolygon; + } + } + } + return ret; +} + +directedLine* directedLine::cutIntersectionAllPoly(int &cutOccur) +{ + directedLine* temp; + directedLine *tempNext = NULL; + directedLine* ret= NULL; + directedLine* retEnd = NULL; + cutOccur = 0; + for(temp=this; temp != NULL; temp = tempNext) + { + int eachCutOccur=0; + tempNext = temp->nextPolygon; + temp->nextPolygon = NULL; + if(ret == NULL) + { + + ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur); + if(eachCutOccur) + cutOccur = 1; + } + else + { + + retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur); + retEnd = retEnd->nextPolygon; + if(eachCutOccur) + cutOccur = 1; + } + } + return ret; +} + + +void directedLine::deleteSinglePolygonWithSline() +{ + directedLine *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp->sline; + delete temp; + } +} + +void directedLine::deletePolygonListWithSline() +{ + directedLine *temp, *tempNext; + for(temp=this; temp != NULL; temp=tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteSinglePolygonWithSline(); + } +} + +void directedLine::deleteSinglePolygon() +{ + directedLine *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + +void directedLine::deletePolygonList() +{ + directedLine *temp, *tempNext; + for(temp=this; temp != NULL; temp=tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteSinglePolygon(); + } +} + + +/*a loop by itself*/ +directedLine::directedLine(int dir, sampledLine* sl) +{ + direction = dir; + sline = sl; + next = this; + prev = this; + nextPolygon = NULL; +// prevPolygon = NULL; + rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ + + rootLink = NULL; + +} + +void directedLine::init(int dir, sampledLine* sl) +{ + direction = dir; + sline = sl; +} + +directedLine::directedLine() +{ + next = this; + prev = this; + nextPolygon = NULL; + rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ + rootLink = NULL; +} + +directedLine::~directedLine() +{ +} + +Real* directedLine::head() +{ + + return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; +} + +/*inline*/ Real* directedLine::getVertex(Int i) +{ + return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i]; +} + +Real* directedLine::tail() +{ + return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; +} + + /*insert a new line between prev and this*/ +void directedLine::insert(directedLine* nl) +{ + nl->next = this; + nl->prev = prev; + prev->next = nl; + prev = nl; + nl->rootLink = this; /*assuming that 'this' is the root!!!*/ +} + +Int directedLine::numEdges() +{ + Int ret=0; + directedLine* temp; + if(next == this) return 1; + + ret = 1; + for(temp = next; temp != this; temp = temp->next) + ret++; + return ret; +} + +Int directedLine::numEdgesAllPolygons() +{ + Int ret=0; + directedLine* temp; + for(temp=this; temp!= NULL; temp=temp->nextPolygon) + { + ret += temp->numEdges(); + } + return ret; +} + +/*return 1 if the double linked list forms a polygon. + */ +int directedLine::isPolygon() +{ + directedLine* temp; + + /*a polygon contains at least 3 edges*/ + if(numEdges() <=2) return 0; + + /*check this edge*/ + if(! isConnected()) return 0; + + /*check all other edges*/ + for(temp=next; temp != this; temp = temp->next){ + if(!isConnected()) return 0; + } + return 1; +} + +/*check if the head of this edge is connected to + *the tail of the prev + */ +int directedLine::isConnected() +{ + if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1])) + return 1; + else + return 0; +} + +Int compV2InY(Real A[2], Real B[2]) +{ + if(A[1] < B[1]) return -1; + if(A[1] == B[1] && A[0] < B[0]) return -1; + if(A[1] == B[1] && A[0] == B[0]) return 0; + return 1; +} + +Int compV2InX(Real A[2], Real B[2]) +{ + if(A[0] < B[0]) return -1; + if(A[0] == B[0] && A[1] < B[1]) return -1; + if(A[0] == B[0] && A[1] == B[1]) return 0; + return 1; +} + +/*compare two vertices NOT lines! + *A vertex is the head of a directed line. + *(x_1, y_1) <= (x_2, y_2) if + *either y_1 < y_2 + *or y_1 == y_2 && x_1 < x_2. + *return -1 if this->head() <= nl->head(), + *return 1 otherwise + */ +Int directedLine::compInY(directedLine* nl) +{ + if(head()[1] < nl->head()[1]) return -1; + if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1; + return 1; +} + +/*compare two vertices NOT lines! + *A vertex is the head of a directed line. + *(x_1, y_1) <= (x_2, y_2) if + *either x_1 < x_2 + *or x_1 == x_2 && y_1 < y_2. + *return -1 if this->head() <= nl->head(), + *return 1 otherwise + */ +Int directedLine::compInX(directedLine* nl) +{ + if(head()[0] < nl->head()[0]) return -1; + if(head()[0] == nl->head()[0] && head()[1] < nl->head()[1]) return -1; + return 1; +} + +/*used by sort precedures + */ +static Int compInY2(directedLine* v1, directedLine* v2) +{ + return v1->compInY(v2); +} + +/*sort all the vertices NOT the lines! + *a vertex is the head of a directed line + */ +directedLine** directedLine::sortAllPolygons() +{ + Int total_num_edges = 0; + directedLine** array = toArrayAllPolygons(total_num_edges); + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void *, void *)) compInY2); + + return array; +} + +/*insert this polygon into the head of the old polygon List*/ +directedLine* directedLine::insertPolygon(directedLine* oldList) +{ + /*this polygon is a root*/ + setRootBit(); + if(oldList == NULL) return this; + nextPolygon = oldList; + return this; +} + +/*cutoff means delete. but we don't deallocate any space, + *so we use cutoff instead of delete + */ +directedLine* directedLine::cutoffPolygon(directedLine *p) +{ + directedLine* temp; + directedLine* prev_polygon = NULL; + if (p==NULL) + { + return this; + } + + for (temp=this; temp!=p; temp=temp->nextPolygon) + { + if (temp==NULL) + { + fprintf(stderr, "in cutoffPolygon, not found\n"); + exit(1); + } + prev_polygon=temp; + } + + p->resetRootBit(); + if (prev_polygon==NULL) /* this is the one to cutoff */ + { + return nextPolygon; + } + else + { + prev_polygon->nextPolygon=p->nextPolygon; + return this; + } +} + +Int directedLine::numPolygons() +{ + if (nextPolygon==NULL) + { + return 1; + } + else + { + return 1+nextPolygon->numPolygons(); + } +} + +/*let array[index ...] denote + *all the edges in this polygon + *return the next available index of array. + */ +Int directedLine::toArraySinglePolygon(directedLine** array, Int index) +{ + directedLine *temp; + array[index++] = this; + for(temp = next; temp != this; temp = temp->next) + { + array[index++] = temp; + } + return index; +} + +/*the space is allocated. The caller is responsible for + *deallocate the space. + *total_num_edges is set to be the total number of edges of all polygons + */ +directedLine** directedLine::toArrayAllPolygons(Int& total_num_edges) +{ + total_num_edges=numEdgesAllPolygons(); + directedLine** ret = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); + assert(ret); + + directedLine *temp; + Int index = 0; + for(temp=this; temp != NULL; temp=temp->nextPolygon) { + index = temp->toArraySinglePolygon(ret, index); + } + return ret; +} + +/*assume the polygon is a simple polygon, return + *the area enclosed by it. + *if thee order is counterclock wise, the area is positive. + */ +Real directedLine::polyArea() +{ + directedLine* temp; + Real ret=0.0; + Real x1,y1,x2,y2; + x1 = this->head()[0]; + y1 = this->head()[1]; + x2 = this->next->head()[0]; + y2 = this->next->head()[1]; + ret = -(x2*y1-x1*y2); + for(temp=this->next; temp!=this; temp = temp->next) + { + x1 = temp->head()[0]; + y1 = temp->head()[1]; + x2 = temp->next->head()[0]; + y2 = temp->next->head()[1]; + ret += -( x2*y1-x1*y2); + } + return Real(0.5)*ret; +} + +/*******************split or combine polygons begin********************/ +/*conect a diagonal of a single simple polygon or two simple polygons. + *If the two vertices v1 (head) and v2 (head) are in the same simple polygon, + *then we actually split the simple polygon into two polygons. + *If instead two vertices velong to two difference polygons, + *then we combine the two polygons into one polygon. + *It is upto the caller to decide whether this is a split or a + *combination. + * + *Case Split: + *split a single simple polygon into two simple polygons by + *connecting a diagonal (two vertices). + *v1, v2: the two vertices are the head() of the two directedLines. + * this routine generates one new sampledLine which is returned in + *generatedLine, + *and it generates two directedLines returned in ret_p1 and ret_p2. + *ret_p1 and ret_p2 are used as the entry to the two new polygons. + *Notice the caller should not deallocate the space of v2 and v2 after + *calling this function, since all of the edges are connected to + *ret_p1 or ret_p2. + * + *combine: + *combine two simpolygons into one by connecting one diagonal. + *the returned polygon is returned in ret_p1. + */ +/*ARGSUSED*/ +void directedLine::connectDiagonal(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + sampledLine** generatedLine, + directedLine* polygonList ) +{ + sampledLine *nsline = new sampledLine(2); + + + + nsline->setPoint(0, v1->head()); + nsline->setPoint(1, v2->head()); + + + + /*the increasing line is from v1 head to v2 head*/ + directedLine* newLineInc = new directedLine(INCREASING, nsline); + + + + directedLine* newLineDec = new directedLine(DECREASING, nsline); + + + directedLine* v1Prev = v1->prev; + directedLine* v2Prev = v2->prev; + + v1 ->prev = newLineDec; + v2Prev ->next = newLineDec; + newLineDec->next = v1; + newLineDec->prev = v2Prev; + + v2 ->prev = newLineInc; + v1Prev ->next = newLineInc; + newLineInc->next = v2; + newLineInc->prev = v1Prev; + + *ret_p1 = newLineDec; + *ret_p2 = newLineInc; + *generatedLine = nsline; +} + +//see the function connectDiangle +/*ARGSUSED*/ +void directedLine::connectDiagonal_2slines(directedLine* v1, directedLine* v2, + directedLine** ret_p1, + directedLine** ret_p2, + directedLine* polygonList ) +{ + sampledLine *nsline = new sampledLine(2); + sampledLine *nsline2 = new sampledLine(2); + + nsline->setPoint(0, v1->head()); + nsline->setPoint(1, v2->head()); + nsline2->setPoint(0, v1->head()); + nsline2->setPoint(1, v2->head()); + + /*the increasing line is from v1 head to v2 head*/ + directedLine* newLineInc = new directedLine(INCREASING, nsline); + + directedLine* newLineDec = new directedLine(DECREASING, nsline2); + + directedLine* v1Prev = v1->prev; + directedLine* v2Prev = v2->prev; + + v1 ->prev = newLineDec; + v2Prev ->next = newLineDec; + newLineDec->next = v1; + newLineDec->prev = v2Prev; + + v2 ->prev = newLineInc; + v1Prev ->next = newLineInc; + newLineInc->next = v2; + newLineInc->prev = v1Prev; + + *ret_p1 = newLineDec; + *ret_p2 = newLineInc; + +} + +Int directedLine::samePolygon(directedLine* v1, directedLine* v2) +{ + if(v1 == v2) return 1; + directedLine *temp; + for(temp = v1->next; temp != v1; temp = temp->next) + { + if(temp == v2) return 1; + } + return 0; +} + +directedLine* directedLine::findRoot() +{ + if(rootBit) return this; + directedLine* temp; + for(temp = next; temp != this; temp = temp->next) + if(temp -> rootBit ) return temp; + return NULL; /*should not happen*/ +} + +directedLine* directedLine::rootLinkFindRoot() +{ + directedLine* tempRoot; + directedLine* tempLink; + tempRoot = this; + tempLink = rootLink; + while(tempLink != NULL){ + tempRoot = tempLink; + tempLink = tempRoot->rootLink; + } + return tempRoot; +} + +/*******************split or combine polygons end********************/ diff --git a/project/jni/glu/src/libnurbs/nurbtess/directedLine.h b/project/jni/glu/src/libnurbs/nurbtess/directedLine.h new file mode 100644 index 000000000..9f65277b9 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/directedLine.h @@ -0,0 +1,163 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _DIRECTEDLINE_H +#define _DIRECTEDLINE_H + +#include "definitions.h" +#include "sampledLine.h" + +enum {INCREASING, DECREASING}; + +class directedLine +{ + int direction; /* INCREASING or DECREASING */ + sampledLine* sline; + directedLine* next; /* double linked list */ + directedLine* prev; /* double linked list */ + + /* in case we need a list of polygons each + * consisting of a double linked list + */ + directedLine* nextPolygon; + + /* optimization make cutoff polygon faster */ + /* directedLine* prevPolygon; */ + + Int rootBit; /*1 if this is a root of the polygon, set by setRootBit*/ + /*and reset by resetRootBit()*/ + + directedLine* rootLink; /*fast root-finding*/ + + + + public: + directedLine(int dir, sampledLine* sl); + directedLine(); + ~directedLine(); + + void init(int dir, sampledLine* sl); + + Real* head(); /* points[0] if INCREASING, points[n-1] otherwise */ + Real* tail(); /* points[n-1] if INCREASING, points[0] otherwise */ + Real* getVertex(Int i); /* points[i] if INCREASING, points[n-1-i] otherwise */ + Int get_npoints() {return sline->get_npoints();} + directedLine* getPrev() {return prev;} + directedLine* getNext() {return next;} + directedLine* getNextPolygon() {return nextPolygon;} + sampledLine* getSampledLine() {return sline;} + + int getDirection(){return direction;} + void putDirection(int dir) {direction = dir;} + void putPrev(directedLine* p) {prev = p;} + void putNext(directedLine* p) {next = p;} + + /*insert a new line between prev and this*/ + void insert(directedLine* nl); + + /* delete all the polygons following the link: nextPolygon. + * notice that sampledLine is not deleted. The caller is + * responsible for that + */ + void deletePolygonList(); + void deleteSinglePolygon(); + + void deleteSinglePolygonWithSline(); // also delete sanmpled line + void deletePolygonListWithSline(); // also delete sanmpled line + + void deleteSingleLine(directedLine* dline); + directedLine* deleteDegenerateLines(); + directedLine* deleteDegenerateLinesAllPolygons(); + directedLine* cutIntersectionAllPoly(int& cutOccur); + + /*check to see if the list forms a closed polygon + *return 1 if yes + */ + int isPolygon(); + + Int compInY(directedLine* nl); + Int compInX(directedLine* nl); + + /* return an array of pointers. + * the + */ + directedLine** sortAllPolygons(); + + Int numEdges(); + Int numEdgesAllPolygons(); + Int numPolygons(); + + /* check if the head of this edge is connected to + * the tail of the prev + */ + int isConnected(); + + Real polyArea(); + + /* insert a polygon: using nextPolygon */ + directedLine* insertPolygon(directedLine* newpolygon); + directedLine* cutoffPolygon(directedLine* p); + + Int toArraySinglePolygon(directedLine** array, Int index); + directedLine** toArrayAllPolygons(Int& total_num_edges); + + void connectDiagonal(directedLine* v1, directedLine* v2, + directedLine** ret_p1, directedLine** ret_p2, + sampledLine** generatedLine, directedLine* list); + + /* generate two slines + */ + void connectDiagonal_2slines(directedLine* v1, directedLine* v2, + directedLine** ret_p1, directedLine** ret_p2, + directedLine* list); + + Int samePolygon(directedLine* v1, directedLine* v2); + void setRootBit() {rootBit = 1;} + void resetRootBit() {rootBit = 0;} + directedLine* findRoot(); + + void rootLinkSet(directedLine* r) {rootLink = r;} + directedLine* rootLinkFindRoot(); + + // the chain from begin to end is deleted (the space is deallocated) + // and a new edge(which connectes the head of begin and the tail of end) + // is inserted. The new polygon is returned. + // notice that "this" is arbitrary + directedLine* deleteChain(directedLine* begin, directedLine* end); +}; + +extern Int compV2InY(Real A[2], Real B[2]); +extern Int compV2InX(Real A[2], Real B[2]); + +#endif /* _DIRECTEDLINE_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/glimports.h b/project/jni/glu/src/libnurbs/nurbtess/glimports.h new file mode 100644 index 000000000..e469566f6 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/glimports.h @@ -0,0 +1,41 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#ifndef __gluimports_h_ +#define __gluimports_h_ + +#include "mystdlib.h" +#include "mystdio.h" + +#endif /* __gluimports_h_ */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/gridWrap.cc b/project/jni/glu/src/libnurbs/nurbtess/gridWrap.cc new file mode 100644 index 000000000..303ef4dc5 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/gridWrap.cc @@ -0,0 +1,260 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include +#include "zlassert.h" +#include "gridWrap.h" + +/*******************grid structure****************************/ +gridWrap::gridWrap(Int nUlines, Real* uvals, Int nVlines, Real* vvals) +{ + Int i; + + assert(nUlines>=2); + assert(nVlines>=2); + + is_uniform=0; + n_ulines=nUlines; + n_vlines=nVlines; + u_min=uvals[0]; + u_max=uvals[nUlines-1]; + v_min=vvals[0]; + v_max=vvals[nVlines-1]; + u_values=(Real*)malloc(sizeof(Real)*n_ulines); + assert(u_values); + v_values=(Real*)malloc(sizeof(Real)*n_vlines); + assert(v_values); + + for (i=0; i=2); + assert(nVlines>=2); + Real du = (uMax-uMin)/(nUlines-1); + Real dv = (vMax-vMin)/(nVlines-1); + + float tempu=uMin; + u_values[0] = tempu; + for(i=1; i=uright) + { + return; // no triangles to output. + } + + pStream->begin(); + pStream->insert(vert); + + assert(vert[1] != v_values[v]); // don't output degenerate triangles + + if(vert[1] > v_values[v]) // vertex is above this grid line: notice the orientation + { + for(i=uleft; i<=uright; i++) + { + pStream->insert(u_values[i], v_values[v]); + } + } + else // vertex is below the grid line + { + for(i=uright; i>= uleft; i--) + { + pStream->insert(u_values[i], v_values[v]); + } + } + + pStream->end(PRIMITIVE_STREAM_FAN); +} + +/* each chain stores a number of consecutive + * V-lines within a grid. + * There is one grid vertex on each V-line. + * The total number of V-lines is: + * nVlines. + * with respect to the grid, the index of the first V-line is + * firstVlineIndex. + * So with respect to the grid, the index of the ith V-line is + * firstVlineIndex-i. + * the grid-index of the uline at the ith vline (recall that each vline has one grid point) + * is ulineIndices[i]. The u_value is cached in ulineValues[i], that is, + * ulineValues[i] = grid->get_u_value(ulineIndices[i]) + */ +gridBoundaryChain::gridBoundaryChain( + gridWrap* gr, + Int first_vline_index, + Int n_vlines, + Int* uline_indices, + Int* inner_indices + ) +: grid(gr), firstVlineIndex(first_vline_index), nVlines(n_vlines) +{ + ulineIndices = (Int*) malloc(sizeof(Int) * n_vlines); + assert(ulineIndices); + + innerIndices = (Int*) malloc(sizeof(Int) * n_vlines); + assert(innerIndices); + + vertices = (Real2*) malloc(sizeof(Real2) * n_vlines); + assert(vertices); + + + + Int i; + for(i=0; iget_u_value(ulineIndices[i]); + vertices[i][1] = gr->get_v_value(first_vline_index-i); + } +} + +Int gridBoundaryChain::lookfor(Real v, Int i1, Int i2) +{ + Int mid; + while(i1 < i2-1) + { + mid = (i1+i2)/2; + if(v > vertices[mid][1]) + { + i2 = mid; + } + else + i1 = mid; + } + return i1; +} + +/*output the fan of the right end between grid line i-1 and grid line i*/ +void gridBoundaryChain::rightEndFan(Int i, primStream* pStream) +{ + Int j; + if(getUlineIndex(i) > getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i-1)); + for(j=getUlineIndex(i-1); j<= getUlineIndex(i); j++) + pStream->insert(grid->get_u_value(j), get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(getUlineIndex(i) < getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i)); + for(j=getUlineIndex(i-1); j>= getUlineIndex(i); j--) + pStream->insert(grid->get_u_value(j), get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + //otherside, the two are equal, so there is no fan to output +} + +/*output the fan of the left end between grid line i-1 and grid line i*/ +void gridBoundaryChain::leftEndFan(Int i, primStream* pStream) +{ + Int j; + if(getUlineIndex(i) < getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i-1)); + for(j=getUlineIndex(i); j<= getUlineIndex(i-1); j++) + pStream->insert(grid->get_u_value(j), get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(getUlineIndex(i) > getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(get_vertex(i)); + for(j=getUlineIndex(i); j>= getUlineIndex(i-1); j--) + pStream->insert(grid->get_u_value(j), get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/gridWrap.h b/project/jni/glu/src/libnurbs/nurbtess/gridWrap.h new file mode 100644 index 000000000..6979a788c --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/gridWrap.h @@ -0,0 +1,129 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _GRIDWRAP_H +#define _GRIDWRAP_H + +#include +#include "definitions.h" + +#include "primitiveStream.h" +#include "zlassert.h" + +class gridWrap +{ + Int n_ulines; + Int n_vlines; + Real u_min, u_max; + Real v_min, v_max; + + /*cache the coordinate values for efficiency. + *these are redundant information when + *the grid is uniform. + */ + Real* u_values; /*size is n_ulines*/ + Real* v_values; /*size is n_vlines*/ + + Int is_uniform; + + public: + //uniform grid constructor + gridWrap(Int nUlines, Int nVlines, Real uMin, Real uMax, Real vMin, Real vMax); + + //nonuniform grid constructor. + gridWrap(Int nUlines, Real* uvals, Int nVlines, Real* vvlas); + ~gridWrap(); + + Int get_n_ulines() {return n_ulines;} + Int get_n_vlines() {return n_vlines;} + Real get_u_min() {return u_min;} + Real get_u_max() {return u_max;} + Real get_v_min() {return v_min;} + Real get_v_max() {return v_max;} + + Real get_u_value(Int i) + { + assert(iget_u_value(innerIndices[i]);} + + Real* get_vertex(Int i) {return vertices[i];} + gridWrap* getGrid() {return grid;} + void leftEndFan(Int i, primStream* pStream); + void rightEndFan(Int i, primStream* pStream); + + Int lookfor(Real v, Int i1, Int i2); //find i in [i1,i2] so that vertices[i][1]>= v > vertices[i+1][1] +}; + +#endif /* _GRIDWRAP_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoChain.cc b/project/jni/glu/src/libnurbs/nurbtess/monoChain.cc new file mode 100644 index 000000000..bdd8e2be8 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoChain.cc @@ -0,0 +1,813 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include + +#include "glimports.h" +#include "zlassert.h" + +#include "monoChain.h" +#include "quicksort.h" +#include "searchTree.h" +#include "polyUtil.h" + +#ifndef max +#define max(a,b) ((a>b)? a:b) +#endif +#ifndef min +#define min(a,b) ((a>b)? b:a) +#endif + +extern Int isCusp(directedLine *v); +extern Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices); + +/*given (x_1, y_1) and (x_2, y_2), and y + *return x such that (x,y) is on the line + */ +inline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) +{ + return ((y2==y1) ? (x1+x2)*0.5f : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); +} + +//compare the heads of the two chains +static int compChainHeadInY(monoChain* mc1, monoChain* mc2) +{ + return compV2InY(mc1->getHead()->head(), mc2->getHead()->head()); +} + +monoChain::monoChain(directedLine* cHead, directedLine* cTail) +{ + chainHead = cHead; + chainTail = cTail; + next = this; + prev = this; + + nextPolygon = NULL; + + //compute bounding box + directedLine* temp; + minX = maxX = chainTail->head()[0]; + minY = maxY = chainTail->head()[1]; + + for(temp=chainHead; temp!=cTail; temp = temp->getNext()) + { + if(temp->head()[0] < minX) + minX = temp->head()[0]; + if(temp->head()[0] > maxX) + maxX = temp->head()[0]; + + if(temp->head()[1] < minY) + minY = temp->head()[1]; + if(temp->head()[1] > maxY) + maxY = temp->head()[1]; + } + + //check whether the chain is increasing or decreasing + if(chainHead->compInY(chainTail) <0) + isIncrease = 1; + else + isIncrease = 0; + + //initilize currrent, this is used for accelerating search + if(isIncrease) + current = chainHead; + else + current = chainTail; + + isKey = 0; +} + +//insert a new line between prev and this +void monoChain::insert(monoChain* nc) +{ + nc->next = this; + nc->prev = prev; + prev->next = nc; + prev = nc; +} + +void monoChain::deleteLoop() +{ + monoChain *temp, *tempNext; + prev->next = NULL; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + +void monoChain::deleteLoopList() +{ + monoChain *temp, *tempNext; + for(temp=this; temp != NULL; temp = tempNext) + { + tempNext = temp->nextPolygon; + temp->deleteLoop(); + } +} + +Int monoChain::toArraySingleLoop(monoChain** array, Int index) +{ + monoChain *temp; + array[index++] = this; + for(temp = next; temp != this; temp = temp->next) + { + array[index++] = temp; + } + return index; +} + +monoChain** monoChain::toArrayAllLoops(Int& num_chains) +{ + num_chains = numChainsAllLoops(); + monoChain **ret = (monoChain**) malloc(sizeof(monoChain*) * num_chains); + assert(ret); + monoChain *temp; + Int index = 0; + for(temp = this; temp != NULL; temp=temp->nextPolygon){ + index = temp->toArraySingleLoop(ret, index); + } + return ret; +} + +Int monoChain::numChainsSingleLoop() +{ + Int ret=0; + monoChain* temp; + if(next == this) return 1; + ret = 1; + for(temp=next; temp != this; temp = temp->next) + ret++; + return ret; +} + +Int monoChain::numChainsAllLoops() +{ + Int ret=0; + monoChain *temp; + for(temp =this; temp != NULL; temp = temp->nextPolygon) + ret += temp->numChainsSingleLoop(); + return ret; +} + +//update 'current' +Real monoChain::chainIntersectHoriz(Real y) +{ + directedLine* temp; + if(isIncrease) + { + for(temp= current; temp != chainTail; temp = temp->getNext()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getPrev(); + } + else + { + for(temp = current; temp != chainHead; temp = temp->getPrev()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getNext(); + } + return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y); +} + +monoChain* directedLineLoopToMonoChainLoop(directedLine* loop) +{ + directedLine *temp; + monoChain *ret=NULL; + + //find the first cusp + directedLine *prevCusp=NULL; + directedLine *firstCusp; + + if(isCusp(loop)) + prevCusp = loop; + else + { + for(temp = loop->getNext(); temp != loop; temp = temp->getNext()) + if(isCusp(temp)) + break; + prevCusp = temp; + } + firstCusp = prevCusp; + + for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext()) + { + if(isCusp(temp)) + { + if(ret == NULL) + { + ret = new monoChain(prevCusp, temp); + } + else + ret->insert(new monoChain(prevCusp, temp)); + prevCusp = temp; + } + } + ret->insert(new monoChain(prevCusp, firstCusp)); + + return ret; +} + +monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list) +{ + directedLine* temp; + monoChain* mc; + monoChain* mcEnd; + mc = directedLineLoopToMonoChainLoop(list); + mcEnd = mc; + for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) + { + monoChain *newLoop = directedLineLoopToMonoChainLoop(temp); + mcEnd->setNextPolygon(newLoop); + mcEnd = newLoop; + } + return mc; +} + +/*compare two edges of a polygon. + *edge A < edge B if there is a horizontal line so that the intersection + *with A is to the left of the intersection with B. + *This function is used in sweepY for the dynamic search tree insertion to + *order the edges. + * Implementation: (x_1,y_1) and (x_2, y_2) + */ +static Int compEdges(directedLine *e1, directedLine *e2) +{ + Real* head1 = e1->head(); + Real* tail1 = e1->tail(); + Real* head2 = e2->head(); + Real* tail2 = e2->tail(); +/* + Real h10 = head1[0]; + Real h11 = head1[1]; + Real t10 = tail1[0]; + Real t11 = tail1[1]; + Real h20 = head2[0]; + Real h21 = head2[1]; + Real t20 = tail2[0]; + Real t21 = tail2[1]; +*/ + Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; +/* + if(h11>t11) { + e1_Ymax= h11; + e1_Ymin= t11; + } + else{ + e1_Ymax = t11; + e1_Ymin = h11; + } + + if(h21>t21) { + e2_Ymax= h21; + e2_Ymin= t21; + } + else{ + e2_Ymax = t21; + e2_Ymin = h21; + } +*/ + + if(head1[1]>tail1[1]) { + e1_Ymax= head1[1]; + e1_Ymin= tail1[1]; + } + else{ + e1_Ymax = tail1[1]; + e1_Ymin = head1[1]; + } + + if(head2[1]>tail2[1]) { + e2_Ymax= head2[1]; + e2_Ymin= tail2[1]; + } + else{ + e2_Ymax = tail2[1]; + e2_Ymin = head2[1]; + } + + Real Ymax = min(e1_Ymax, e2_Ymax); + Real Ymin = max(e1_Ymin, e2_Ymin); + + Real y = 0.5f*(Ymax + Ymin); + + Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); + Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); + + if(x1<= x2) return -1; + else return 1; +} + +Int compChains(monoChain* mc1, monoChain* mc2) +{ + Real y; + assert(mc1->isKey || mc2->isKey); + if(mc1->isKey) + y = mc1->keyY; + else + y = mc2->keyY; + directedLine *d1 = mc1->find(y); + directedLine *d2 = mc2->find(y); + mc2->find(y); +// Real x1 = mc1->chainIntersectHoriz(y); +// Real x2 = mc2->chainIntersectHoriz(y); + return compEdges(d1, d2); +} + +//this function modifies current for efficiency +directedLine* monoChain::find(Real y) +{ + directedLine *ret; + directedLine *temp; + assert(current->head()[1] <= y); + if(isIncrease) + { + assert(chainTail->head()[1] >=y); + for(temp=current; temp!=chainTail; temp = temp->getNext()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getPrev(); + ret = current; + } + else + { + for(temp=current; temp != chainHead; temp = temp->getPrev()) + { + if(temp->head()[1] > y) + break; + } + current = temp->getNext(); + ret = temp; + } + return ret; +} + +// return 1 if error occures +Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges) +{ + Int i; + Real keyY; + Int errOccur=0; + /*for each vertex in the sorted list, update the binary search tree. + *and store the range information for each vertex. + */ + treeNode* searchTree = NULL; + for(i=0; igetHead()->head()[1]; //the sweep line + directedLine *dline = vert->getHead(); + directedLine *dlinePrev = dline->getPrev(); + if(isBelow(dline, dline) && isBelow(dline, dlinePrev)) + { + //thisisKey = 1; + vert->keyY = keyY; + treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (void *, void *))compChains); + vert->isKey = 0; + + vert->getPrev()->isKey = 1; + vert->getPrev()->keyY = keyY; + treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (void *, void *))compChains); + vert->getPrev()->isKey = 0; + + if(cuspType(dline) == 1)//interior cusp + { + + treeNode* leftEdge = TreeNodePredecessor(prevNode); + treeNode* rightEdge = TreeNodeSuccessor(thisNode); + if(leftEdge == NULL || rightEdge == NULL) + { + errOccur = 1; + goto JUMP_HERE; + } + + directedLine* leftEdgeDline = ((monoChain* ) leftEdge->key)->find(keyY); + + + + directedLine* rightEdgeDline = ((monoChain* ) rightEdge->key)->find(keyY); + + ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1); + } + else /*exterior cusp*/ + { + ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1); + } + + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + + } + else if(isAbove(dline, dline) && isAbove(dline, dlinePrev)) + { + //insert both edges + treeNode* thisNode = TreeNodeMake(vert); + treeNode* prevNode = TreeNodeMake(vert->getPrev()); + + vert->isKey = 1; + vert->keyY = keyY; + searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (void *, void *))compChains); + vert->isKey = 0; + + vert->getPrev()->isKey = 1; + vert->getPrev()->keyY = keyY; + searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (void *, void *))compChains); + vert->getPrev()->isKey = 0; + + if(cuspType(dline) == 1) //interior cusp + { + treeNode* leftEdge = TreeNodePredecessor(thisNode); + treeNode* rightEdge = TreeNodeSuccessor(prevNode); + if(leftEdge == NULL || rightEdge == NULL) + { + errOccur = 1; + goto JUMP_HERE; + } + directedLine* leftEdgeDline = ((monoChain*) leftEdge->key)->find(keyY); + directedLine* rightEdgeDline = ((monoChain*) rightEdge->key)->find(keyY); + ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1); + } + else //exterior cusp + { + ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1); + } + } + else + { + errOccur = 1; + goto JUMP_HERE; + + fprintf(stderr, "error in MC_sweepY\n"); + exit(1); + } + } + + JUMP_HERE: + //finally clean up space: delete the search tree + TreeNodeDeleteWholeTree(searchTree); + return errOccur; +} + +void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices, + sweepRange** ranges, Int& num_diagonals, + directedLine** diagonal_vertices) +{ + Int i,j,k; + k=0; + //reset 'current' of all the monoChains + for(i=0; iresetCurrent(); + + for(i=0; igetHead(); + directedLine* thisEdge = vert; + directedLine* prevEdge = vert->getPrev(); + if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) + { + //this is an upward interior cusp + diagonal_vertices[k++] = vert; + + directedLine* leftEdge = ranges[i]->left; + directedLine* rightEdge = ranges[i]->right; + + directedLine* leftVert = leftEdge; + directedLine* rightVert = rightEdge->getNext(); + assert(leftVert->head()[1] >= vert->head()[1]); + assert(rightVert->head()[1] >= vert->head()[1]); + directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert; + Int found = 0; + for(j=i+1; jgetHead()->head()[1] > minVert->head()[1]) + break; + + if(sweepRangeEqual(ranges[i], ranges[j])) + { + found = 1; + break; + } + } + + if(found) + diagonal_vertices[k++] = sortedVertices[j]->getHead(); + else + diagonal_vertices[k++] = minVert; + } + else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0) + { + //downward interior cusp + diagonal_vertices[k++] = vert; + directedLine* leftEdge = ranges[i]->left; + directedLine* rightEdge = ranges[i]->right; + directedLine* leftVert = leftEdge->getNext(); + directedLine* rightVert = rightEdge; + assert(leftVert->head()[1] <= vert->head()[1]); + assert(rightVert->head()[1] <= vert->head()[1]); + directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert; + Int found=0; + for(j=i-1; j>=0; j--) + { + if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1]) + break; + if(sweepRangeEqual(ranges[i], ranges[j])) + { + found = 1; + break; + } + } + if(found) + diagonal_vertices[k++] = sortedVertices[j]->getHead(); + else + diagonal_vertices[k++] = maxVert; + } + } + num_diagonals = k/2; +} + + + + +directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines) +{ + Int total_num_chains = 0; + monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons); + monoChain** array = loopList->toArrayAllLoops(total_num_chains); + + if(total_num_chains<=2) //there is just one single monotone polygon + { + loopList->deleteLoopList(); + free(array); + *retSampledLines = NULL; + return polygons; + } + + quicksort( (void**)array, 0, total_num_chains-1, (Int (*)(void*, void*))compChainHeadInY); + + sweepRange** ranges = (sweepRange**)malloc(sizeof(sweepRange*) * (total_num_chains)); + assert(ranges); + + if(MC_sweepY(total_num_chains, array, ranges)) + { + loopList->deleteLoopList(); + free(array); + *retSampledLines = NULL; + return NULL; + } + + Int num_diagonals; + /*number diagonals is < total_num_edges*total_num_edges*/ + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_chains*2/*total_num_edges*/); + assert(diagonal_vertices); + + MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices); + + directedLine* ret_polygons = polygons; + sampledLine* newSampledLines = NULL; + Int i,k; + + num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + + Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); + for(i=0; irootLinkFindRoot(); +directedLine* root2 = v2->rootLinkFindRoot(); + + if(root1 != root2) + { + + removedDiagonals[i] = 1; + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + + + + newSampledLines = generatedLine->insert(newSampledLines); +/* + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_polygons->cutoffPolygon(root2); + ret_polygons = ret_p1->insertPolygon(ret_polygons); +root1->rootLinkSet(ret_p1); +root2->rootLinkSet(ret_p1); +ret_p1->rootLinkSet(NULL); +ret_p2->rootLinkSet(ret_p1); +*/ + ret_polygons = ret_polygons->cutoffPolygon(root2); + + + +root2->rootLinkSet(root1); +ret_p1->rootLinkSet(root1); +ret_p2->rootLinkSet(root1); + + /*now that we have connected the diagonal v1 and v2, + *we have to check those unprocessed diagonals which + *have v1 or v2 as an end point. Notice that the head of v1 + *has the same coodinates as the head of v2->prev, and the head of + *v2 has the same coordinate as the head of v1->prev. + *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid + *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be + *replaced by (v2->prev, x), that is, x is on the left of + * v2->prev->prev->head, v2->prev->head, v2->prev->tail. + */ + Int ii, kk; + for(ii=0, kk=0; iiprev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v2->getPrev(); + } + } + if(d1 == v2) { + /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v1->getPrev(); + } + } + /*check d2 and replace diagonal_vertices[k+1] if necessary*/ + if(d2 == v1) { + /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v2->getPrev(); + } + } + if(d2 == v2) { + /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v1->getPrev(); + } + } + } +}/*end if (root1 not equal to root 2)*/ +} + + /*second pass, now all diagoals should belong to the same polygon*/ + + for(i=0,k=0; ifindRoot(); + sampledLine* generatedLine; + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + newSampledLines = generatedLine->insert(newSampledLines); + + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_p1->insertPolygon(ret_polygons); + + ret_polygons = ret_p2->insertPolygon(ret_polygons); + + + + for(Int j=i+1; jsamePolygon(temp1, temp2)) + { + /*if temp1 and temp2 are in different polygons, + *then one of them must be v1 or v2. + */ + assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); + if(temp1==v1) + { + diagonal_vertices[2*j] = v2->getPrev(); + } + if(temp2==v1) + { + diagonal_vertices[2*j+1] = v2->getPrev(); + } + if(temp1==v2) + { + diagonal_vertices[2*j] = v1->getPrev(); + } + if(temp2==v2) + { + diagonal_vertices[2*j+1] = v1->getPrev(); + } + } + } + } + } + + //clean up + loopList->deleteLoopList(); + free(array); + free(ranges); + free(diagonal_vertices); + free(removedDiagonals); + + *retSampledLines = newSampledLines; + return ret_polygons; +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoChain.h b/project/jni/glu/src/libnurbs/nurbtess/monoChain.h new file mode 100644 index 000000000..b74e1c482 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoChain.h @@ -0,0 +1,100 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _MONO_CHAIN_H +#define _MONO_CHAIN_H + +#include "directedLine.h" +#include "partitionY.h" + +class monoChain; + +class monoChain +{ + directedLine* chainHead; + directedLine* chainTail; + monoChain* next; + monoChain* prev; + monoChain* nextPolygon; // a list of polygons + + // cached informatin + // bounding box + Real minX, maxX, minY, maxY; + Int isIncrease; + + // for efficiently comparing two chains + directedLine* current; + + public: + monoChain(directedLine* cHead, directedLine* cTail); + ~monoChain() {} + + inline void setNext(monoChain* n) {next = n;} + inline void setPrev(monoChain* p) {prev = p;} + inline void setNextPolygon(monoChain* np) {nextPolygon = np;} + inline monoChain* getNext() {return next;} + inline monoChain* getPrev() {return prev;} + inline directedLine* getHead() {return chainHead;} + inline directedLine* getTail() {return chainTail;} + + inline void resetCurrent() { current=((isIncrease==1)?chainHead:chainTail);} + + void deleteLoop(); + void deleteLoopList(); + + // insert a new chain between prev and this + void insert(monoChain* nc); + + Int numChainsSingleLoop(); + Int numChainsAllLoops(); + monoChain** toArrayAllLoops(Int& num_chains); + Int toArraySingleLoop(monoChain** array, Int index); + + Int isKey; + Real keyY; // the current horizotal line + Real chainIntersectHoriz(Real y); // updates current incrementally for efficiency + directedLine* find(Real y); // find dline so that y intersects dline. +}; + +monoChain* directedLineLoopToMonoChainLoop(directedLine* loop); +monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list); +Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges); + +void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices, + sweepRange** ranges, Int& num_diagonals, + directedLine** diagonal_vertices); + +directedLine* MC_partitionY(directedLine* polygons, sampledLine** retSampledLines); + +#endif /* _MONO_CHAIN_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.cc b/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.cc new file mode 100644 index 000000000..64342f420 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.cc @@ -0,0 +1,301 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak + */ + +/* + *monoPolyPart.C + * + *To partition a v-monotone polygon into some uv-monotone polygons. + *The algorithm is different from the general monotone partition algorithm. + *while the general monotone partition algorithm works for this special case, + *but it is more expensive (O(nlogn)). The algorithm implemented here takes + *advantage of the fact that the input is a v-monotone polygon and it is + *conceptually simpler and computationally cheaper (a linear time algorithm). + *The algorithm is described in Zicheng Liu's paper + * "Quality-Oriented Linear Time Tessellation". + */ + +#include +#include +#include "directedLine.h" +#include "monoPolyPart.h" + +/*a vertex is u_maximal if both of its two neightbors are to the left of this + *vertex + */ +static Int is_u_maximal(directedLine* v) +{ + if (compV2InX(v->getPrev()->head(), v->head()) == -1 && + compV2InX(v->getNext()->head(), v->head()) == -1) + return 1; + else + return 0; +} + +/*a vertex is u_minimal if both of its two neightbors are to the right of this + *vertex + */ +static Int is_u_minimal(directedLine* v) +{ + if (compV2InX(v->getPrev()->head(), v->head()) == 1 && + compV2InX(v->getNext()->head(), v->head()) == 1) + return 1; + else + return 0; +} + +/*poly: a v-monotone polygon + *return: a linked list of uv-monotone polygons. + */ +directedLine* monoPolyPart(directedLine* polygon) +{ + //handle special cases: + if(polygon == NULL) + return NULL; + if(polygon->getPrev() == polygon) + return polygon; + if(polygon->getPrev() == polygon->getNext()) + return polygon; + if(polygon->getPrev()->getPrev() == polygon->getNext()) + return polygon; + + //find the top and bottom vertexes + directedLine *tempV, *topV, *botV; + topV = botV = polygon; + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + + //initilization + directedLine *A, *B, *C, *D, *G, *H; + //find A:the first u_maximal vertex on the left chain + //and C: the left most vertex between top and A + A = NULL; + C = topV; + for(tempV=topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + if(tempV->head()[0] < C->head()[0]) + C = tempV; + + if(is_u_maximal(tempV)) + { + A = tempV; + break; + } + } + if(A == NULL) + { + A = botV; + if(A->head()[0] < C->head()[0]) + C = A; + } + + //find B: the first u_minimal vertex on the right chain + //and D: the right most vertex between top and B + B = NULL; + D = topV; + for(tempV=topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + if(tempV->head()[0] > D->head()[0]) + D = tempV; + if(is_u_minimal(tempV)) + { + B = tempV; + break; + } + } + if(B == NULL) + { + B = botV; + if(B->head()[0] > D->head()[0]) + D = B; + } + + //error checking XXX + if(C->head()[0] >= D->head()[0]) + return polygon; + + //find G on the left chain that is right above B + for(tempV=topV; compV2InY(tempV->head(), B->head()) == 1; tempV=tempV->getNext()); + G = tempV->getPrev(); + //find H on the right chain that is right above A + for(tempV=topV; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev()); + H = tempV->getNext(); + + //Main Loop + directedLine* ret = NULL; + directedLine* currentPolygon = polygon; + while(1) + { + //if both B and D are equal to botV, then this polygon is already + //u-monotone + if(A == botV && B == botV) + { + ret = currentPolygon->insertPolygon(ret); + return ret; + } + else //not u-monotone + { + directedLine *ret_p1, *ret_p2; + if(compV2InY(A->head(),B->head()) == 1) //A is above B + { + directedLine* E = NULL; + for(tempV = C; tempV != D; tempV = tempV->getPrev()) + { + if(tempV->head()[0] >= A->head()[0]) + { + E = tempV; + break; + } + } + + if(E == NULL) + E = D; + if(E->head()[0]> H->head()[0]) + E = H; + //connect AE and output polygon ECA + polygon->connectDiagonal_2slines(A, E, + &ret_p1, + &ret_p2, + NULL); + ret = ret_p2->insertPolygon(ret); + currentPolygon = ret_p1; + + if(E == D) + D = ret_p1; + if(E == H) + H = ret_p1; + if(G->head()[1] >= A->head()[1]) + G = A; + //update A to be the next u-maxiaml vertex on left chain + //and C the leftmost vertex between the old A and the new A + C = A; + for(tempV = A->getNext(); tempV != botV; tempV = tempV->getNext()) + { + + if(tempV->head()[0] < C->head()[0]) + C = tempV; + if(is_u_maximal(tempV)) + { + A = tempV; + break; + } + } + + if(tempV == botV) + { + A = botV; + if(botV->head()[0] < C->head()[0]) + C = botV; + } + //update H + + if(A == botV) + H = botV; + else + { + for(tempV = H; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev()); + H = tempV->getNext(); + } + + } + else //A is below B + { + + directedLine* F = NULL; + for(tempV = D; tempV != C; tempV = tempV->getNext()) + { + if(tempV->head()[0] <= B->head()[0]) + { + F = tempV; + break; + } + } + if(F == NULL) + F = C; + if(F->head()[0] < G->head()[0]) + F = G; + + //connect FB + polygon->connectDiagonal_2slines(F, B, + &ret_p1, + &ret_p2, + NULL); + ret = ret_p2->insertPolygon(ret); + currentPolygon = ret_p1; + B = ret_p1; + if(H ->head()[1] >= B->head()[1]) + H = ret_p1; + + //update B to be the next u-minimal vertex on right chain + //and D the rightmost vertex between the old B and the new B + D = B; + for(tempV = B->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + if(tempV->head()[0] > D->head()[0]) + D = tempV; + if(is_u_minimal(tempV)) + { + B = tempV; + break; + } + } + if(tempV == botV) + { + B = botV; + if(botV->head()[0] > D->head()[0]) + D = botV; + } + //update G + if(B == botV) + G = botV; + else + { + for(tempV = G; compV2InY(tempV->head(), B->head()) == 1; tempV = tempV->getNext()); + G = tempV->getPrev(); + } + } //end of A is below B + } //end not u-monotone + } //end of main loop +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.h b/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.h new file mode 100644 index 000000000..71db8d73c --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoPolyPart.h @@ -0,0 +1,42 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#ifndef _MONO_POLY_PART_H +#define _MONO_POLY_PART_H + +class directedLine; + +directedLine* monoPolyPart(directedLine* polygon); + +#endif /* _MONO_POLY_PART_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.cc b/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.cc new file mode 100644 index 000000000..0f11b81d2 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.cc @@ -0,0 +1,1467 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include "glimports.h" +#include "zlassert.h" + +#include "monoTriangulation.h" +#include "polyUtil.h" /* for area */ +#include "partitionX.h" +#include "monoPolyPart.h" + +extern directedLine* polygonConvert(directedLine* polygon); + +/*poly is NOT deleted + */ +void monoTriangulationOpt(directedLine* poly, primStream* pStream) +{ + Int n_cusps; + Int n_edges = poly->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges); + assert(cusps); + findInteriorCuspsX(poly, n_cusps, cusps); + if(n_cusps ==0) //u monotine + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else if(n_cusps == 1) // one interior cusp + { + directedLine* new_polygon = polygonConvert(cusps[0]); + directedLine* other = findDiagonal_singleCuspX(new_polygon); + // should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + //we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else + { + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + } + } + else + { + //we need a general partitionX funtion (supposed to be in partitionX.C, + //not implemented yet. XXX + monoTriangulationFun(poly, compV2InY, pStream); + } + + free(cusps); +} + +void monoTriangulationRecOpt(Real* topVertex, Real* botVertex, + vertexArray* left_chain, Int left_current, + vertexArray* right_chain, Int right_current, + primStream* pStream) +{ + Int i,j; + Int n_left = left_chain->getNumElements(); + Int n_right = right_chain->getNumElements(); + if(left_current>= n_left-1 || + right_current>= n_right-1) + { + monoTriangulationRec(topVertex, botVertex, left_chain, left_current, + right_chain, right_current, pStream); + return; + } + //now both left and right have at least two vertices each. + Real left_v = left_chain->getVertex(left_current)[1]; + Real right_v = right_chain->getVertex(right_current)[1]; + + if(left_v <= right_v) //first left vertex is below right + { + //find the last vertex of right which is above or equal to left + for(j=right_current; j<=n_right-1; j++) + { + if(right_chain->getVertex(j)[1] < left_v) + break; + } + monoTriangulationRecGen(topVertex, left_chain->getVertex(left_current), + left_chain, left_current, left_current, + right_chain, right_current, j-1, + pStream); + monoTriangulationRecOpt(right_chain->getVertex(j-1), + botVertex, + left_chain, left_current, + right_chain, j, + pStream); + } + else //first right vertex is strictly below left + { + //find the last vertex of left which is strictly above right + for(i=left_current; i<=n_left-1; i++) + { + if(left_chain->getVertex(i)[1] <= right_v) + break; + } + monoTriangulationRecGen(topVertex, right_chain->getVertex(right_current), + left_chain, left_current, i-1, + right_chain, right_current, right_current, + pStream); + monoTriangulationRecOpt(left_chain->getVertex(i-1), + botVertex, + left_chain, i, + right_chain, right_current, + pStream); + } +} + + +void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + pStream->triangle(topVertex, inc_chain->getVertex(inc_current), dec_chain->getVertex(dec_current)); + + triangulateXYMonoTB(inc_end-inc_current+1, inc_chain->getArray()+inc_current, dec_end-dec_current+1, dec_chain->getArray()+dec_current, pStream); + + pStream->triangle(botVertex, dec_chain->getVertex(dec_end), inc_chain->getVertex(inc_end)); +} + + +/*n_left>=1 + *n_right>=1 + *the strip is going top to bottom. compared to the funtion + * triangulateXYmono() + */ +void triangulateXYMonoTB(Int n_left, Real** leftVerts, + Int n_right, Real** rightVerts, + primStream* pStream) +{ + + + Int i,j,k,l; + Real* topMostV; + + assert(n_left>=1 && n_right>=1); + if(leftVerts[0][1] >= rightVerts[0][1]) + { + i=1; + j=0; + topMostV = leftVerts[0]; + } + else + { + i=0; + j=1; + topMostV = rightVerts[0]; + } + + while(1) + { + if(i >= n_left) /*case1: no more in left*/ + { + + if(jbegin(); + pStream->insert(topMostV); + for(k=n_right-1; k>=j; k--) + pStream->insert(rightVerts[j]); + + pStream->end(PRIMITIVE_STREAM_FAN); + + } + + break; + } + else if(j>= n_right) /*case2: no more in right*/ + { + + if(ibegin(); + pStream->insert(topMostV); + + for(k=i; kinsert(leftVerts[k]); + + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else /* case3: neither is empty, plus the topMostV, there is at least one triangle to output*/ + { + + if(leftVerts[i][1] >= rightVerts[j][1]) + { + pStream->begin(); + pStream->insert(rightVerts[j]); /*the origin of this fan*/ + + pStream->insert(topMostV); + + /*find the last k>=i such that + *leftverts[k][1] >= rightverts[j][1] + */ + k=i; + while(kinsert(leftVerts[l]); + } + + pStream->end(PRIMITIVE_STREAM_FAN); + //update i for next loop + i = k+1; + topMostV = leftVerts[k]; + + } + else /*leftVerts[i][1] < rightVerts[j][1]*/ + { + pStream->begin(); + pStream->insert(leftVerts[i]);/*the origion of this fan*/ + + /*find the last k>=j such that + *rightverts[k][1] > leftverts[i][1]*/ + k=j; + while(k< n_right) + { + if(rightVerts[k][1] <= leftVerts[i][1]) + break; + k++; + } + k--; + + for(l=k; l>= j; l--) + pStream->insert(rightVerts[l]); + + pStream->insert(topMostV); + pStream->end(PRIMITIVE_STREAM_FAN); + j=k+1; + topMostV = rightVerts[j-1]; + } + } + } +} + +static int chainConvex(vertexArray* inc_chain, Int inc_current, Int inc_end) +{ + Int i; + //if there are no more than 2 vertices, return 1 + if(inc_current >= inc_end-1) return 1; + for(i=inc_current; i<= inc_end-2; i++) + { + if(area(inc_chain->getVertex(i), inc_chain->getVertex(i+1), inc_chain->getVertex(i+2)) <0) + return 0; + } + return 1; +} + +static int chainConcave(vertexArray* dec_chain, Int dec_current, Int dec_end) +{ + Int i; + //if there are no more than 2 vertices, return 1 + if(dec_current >= dec_end -1) return 1; + for(i=dec_current; i<=dec_end-2; i++) + { + if(area(dec_chain->getVertex(i), dec_chain->getVertex(i+1), dec_chain->getVertex(i+2)) >0) + return 0; + } + return 1; +} + +void monoTriangulationRecGenInU(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + +} + +void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + Int i; + //copy this to a polygon: directedLine Lioop + sampledLine* sline; + directedLine* dline; + directedLine* poly; + + if(inc_current <= inc_end) //at least one vertex in inc_chain + { + sline = new sampledLine(topVertex, inc_chain->getVertex(inc_current)); + poly = new directedLine(INCREASING, sline); + for(i=inc_current; i<=inc_end-1; i++) + { + sline = new sampledLine(inc_chain->getVertex(i), inc_chain->getVertex(i+1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + sline = new sampledLine(inc_chain->getVertex(inc_end), botVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + else //inc_chian is empty + { + sline = new sampledLine(topVertex, botVertex); + dline = new directedLine(INCREASING, sline); + poly = dline; + } + + assert(poly != NULL); + + if(dec_current <= dec_end) //at least on vertex in dec_Chain + { + sline = new sampledLine(botVertex, dec_chain->getVertex(dec_end)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + for(i=dec_end; i>dec_current; i--) + { + sline = new sampledLine(dec_chain->getVertex(i), dec_chain->getVertex(i-1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + sline = new sampledLine(dec_chain->getVertex(dec_current), topVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + else //dec_chain is empty + { + sline = new sampledLine(botVertex, topVertex); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + { + Int n_cusps; + Int n_edges = poly->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges); + assert(cusps); + findInteriorCuspsX(poly, n_cusps, cusps); + + if(n_cusps ==0) //u monotine + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else if(n_cusps == 1) // one interior cusp + { + directedLine* new_polygon = polygonConvert(cusps[0]); + directedLine* other = findDiagonal_singleCuspX(new_polygon); + // should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + //we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(poly, compV2InX, pStream); + } + else + { + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + } + } + else + { + //we need a general partitionX funtion (supposed to be in partitionX.C, + //not implemented yet. XXX + //monoTriangulationFun(poly, compV2InY, pStream); + + directedLine* new_polygon = polygonConvert(poly); + directedLine* list = monoPolyPart(new_polygon); + for(directedLine* temp = list; temp != NULL; temp = temp->getNextPolygon()) + { + monoTriangulationFun(temp, compV2InX, pStream); + } + //clean up + list->deletePolygonListWithSline(); + + } + + free(cusps); + /* + if(numInteriorCuspsX(poly) == 0) //is u monotone + monoTriangulationFun(poly, compV2InX, pStream); + else //it is not u motone + monoTriangulationFun(poly, compV2InY, pStream); + */ + //clean up space + poly->deleteSinglePolygonWithSline(); + return; + } + + //apparently the following code is not reachable, + //it is for test purpose + if(inc_current > inc_end || dec_current>dec_end) + { + monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + return; + } + + + if( + area(dec_chain->getVertex(dec_current), + topVertex, + inc_chain->getVertex(inc_current)) >=0 + && chainConvex(inc_chain, inc_current, inc_end) + && chainConcave(dec_chain, dec_current, dec_end) + && area(inc_chain->getVertex(inc_end), botVertex, dec_chain->getVertex(dec_end)) >=0 + ) + { + monoTriangulationRecFunGen(topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + compV2InX, pStream); + } + else + { + monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + } +} + +/*if inc_current>inc_end, then inc_chain has no points to be considered + *same for dec_chain + */ +void monoTriangulationRecGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + Real** inc_array ; + Real** dec_array ; + Int i; + + if(inc_current > inc_end && dec_current>dec_end) + return; + else if(inc_current>inc_end) /*no more vertices on inc_chain*/ + { + dec_array = dec_chain->getArray(); + reflexChain rChain(100,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<=dec_end; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else if(dec_current> dec_end) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + + reflexChain rChain(100,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<=inc_end; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(100, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<=dec_end; i++) + { + if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRecGen(dec_array[i-1], botVertex, + inc_chain, inc_current, inc_end, + dec_chain, i, dec_end, + pStream); + } + else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(100, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<=inc_end; i++) + { + if(compV2InY(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecGen(inc_array[i-1], botVertex, + inc_chain, i, inc_end, + dec_chain, dec_current,dec_end, + pStream); + } + }/*end case neither is empty*/ +} + +void monoTriangulationFun(directedLine* monoPolygon, Int (*compFun)(Real*, Real*), primStream* pStream) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = monoPolygon; + for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext()) + { + if(compFun(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compFun(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + inc_chain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + + if (!(0 == inc_chain.getNumElements() && 0 == dec_chain.getNumElements())) { + monoTriangulationRecFun(topV->head(), botV->head(), &inc_chain, 0, + &dec_chain, 0, compFun, pStream); + } +} + +void monoTriangulation(directedLine* monoPolygon, primStream* pStream) +{ + Int i; + /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain, + *then call monoTriangulationRec + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = monoPolygon; + for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } + /*creat increase and decrease chains*/ + vertexArray inc_chain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + inc_chain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + inc_chain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray dec_chain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + dec_chain.appendVertex(tempV->getVertex(i)); + } + + monoTriangulationRec(topV->head(), botV->head(), &inc_chain, 0, &dec_chain, 0, pStream); + +} + +/*the chain could be increasing or decreasing, although we use the + * name inc_chain. + *the argument is_increase_chain indicates whether this chain + *is increasing (left chain in V-monotone case) or decreaing (right chain + *in V-monotone case). + */ +void monoTriangulation2(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_smallIndex, + Int inc_largeIndex, + Int is_increase_chain, + primStream* pStream) +{ + assert( inc_chain != NULL); + Real** inc_array ; + + if(inc_smallIndex > inc_largeIndex) + return; //no triangles + if(inc_smallIndex == inc_largeIndex) + { + if(is_increase_chain) + pStream->triangle(inc_chain->getVertex(inc_smallIndex), botVertex, topVertex); + else + pStream->triangle(inc_chain->getVertex(inc_smallIndex), topVertex, botVertex); + return; + } + Int i; + + if(is_increase_chain && botVertex[1] == inc_chain->getVertex(inc_largeIndex)[1]) + { + pStream->triangle(botVertex, inc_chain->getVertex(inc_largeIndex-1), + inc_chain->getVertex(inc_largeIndex)); + monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex, + inc_largeIndex-1, + is_increase_chain, + pStream); + return; + } + else if( (!is_increase_chain) && topVertex[1] == inc_chain->getVertex(inc_smallIndex)[1]) + { + pStream->triangle(topVertex, inc_chain->getVertex(inc_smallIndex+1), + inc_chain->getVertex(inc_smallIndex)); + monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex+1, + inc_largeIndex, is_increase_chain, pStream); + return ; + } + + inc_array = inc_chain->getArray(); + + reflexChain rChain(20,is_increase_chain); /*1 means the chain is increasing*/ + + rChain.processNewVertex(topVertex, pStream); + + for(i=inc_smallIndex; i<=inc_largeIndex; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + rChain.processNewVertex(botVertex, pStream); + +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + Int (*compFun)(Real*, Real*), + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current> inc_end && + dec_current> dec_end)); + /* + Int inc_nVertices; + Int dec_nVertices; + */ + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current> inc_end) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i<=dec_end; i++){ + rChain.processNewVertex(dec_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + + } + else if(dec_current> dec_end) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i<=inc_end; i++){ + rChain.processNewVertex(inc_array[i], pStream); + } + /*process the bottom vertex*/ + rChain.processNewVertex(botVertex, pStream); + } + else /*neither chain is empty*/ + { + inc_array = inc_chain -> getArray(); + dec_array = dec_chain -> getArray(); + + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i<=dec_end; i++) + { + if(compFun(inc_array[inc_current], dec_array[i]) <= 0) + rChain.processNewVertex(dec_array[i], pStream); + else + break; + } + rChain.outputFan(inc_array[inc_current], pStream); + monoTriangulationRecFunGen(dec_array[i-1], botVertex, + inc_chain, inc_current, inc_end, + dec_chain, i, dec_end, + compFun, + pStream); + } + else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i<=inc_end; i++) + { + if(compFun(inc_array[i], dec_array[dec_current]) >0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecFunGen(inc_array[i-1], botVertex, + inc_chain, i,inc_end, + dec_chain, dec_current,dec_end, + compFun, + pStream); + } + }/*end case neither is empty*/ +} + +/*if compFun == compV2InY, top to bottom: V-monotone + *if compFun == compV2InX, right to left: U-monotone + */ +void monoTriangulationRecFun(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRecFun(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + compFun, + pStream); + } + }/*end case neither is empty*/ +} + + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + primStream* pStream) +{ + assert( inc_chain != NULL && dec_chain != NULL); + assert( ! (inc_current>=inc_chain->getNumElements() && + dec_current>=dec_chain->getNumElements())); + Int inc_nVertices; + Int dec_nVertices; + Real** inc_array ; + Real** dec_array ; + Int i; + assert( ! ( (inc_chain==NULL) && (dec_chain==NULL))); + + if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/ + { + + dec_array = dec_chain->getArray(); + dec_nVertices = dec_chain->getNumElements(); + reflexChain rChain(20,0); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the dec_chain*/ + for(i=dec_current; i= dec_chain->getNumElements()) /*no more vertices on dec_chain*/ + { + inc_array = inc_chain->getArray(); + inc_nVertices= inc_chain->getNumElements(); + reflexChain rChain(20,1); + /*put the top vertex into the reflex chain*/ + rChain.processNewVertex(topVertex, pStream); + /*process all the vertices on the inc_chain*/ + for(i=inc_current; i getArray(); + dec_array = dec_chain -> getArray(); + inc_nVertices= inc_chain->getNumElements(); + dec_nVertices= dec_chain->getNumElements(); + /*if top of inc_chain is 'lower' than top of dec_chain, process all the + *vertices on the dec_chain which are higher than top of inc_chain + */ + if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0) + { + + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex, pStream); + for(i=dec_current; i 0*/ + { + + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex, pStream); + for(i=inc_current; i0) + rChain.processNewVertex(inc_array[i], pStream); + else + break; + } + rChain.outputFan(dec_array[dec_current], pStream); + monoTriangulationRec(inc_array[i-1], botVertex, + inc_chain, i, + dec_chain, dec_current, + pStream); + } + }/*end case neither is empty*/ +} + + + +/* the name here assumes that the polygon is Y-monotone, but + *this function also works for X-monotone polygons. + * a monotne polygon consists of two extrem verteices: topVertex and botVertex, and + *two monotone chains: inc_chain, and dec_chain. The edges of the increasing chain (inc_chain) + *is ordered by following pointer: next, while the edges of the decreasing chain (dec_chain) + *is ordered by following pointer: prev + * inc_index index the vertex which is the toppest of the inc_chain which we are handling currently. + * dec_index index the vertex which is the toppest of the dec_chain which we are handling currently. + */ +void monoTriangulationRec(directedLine* inc_chain, Int inc_index, + directedLine* dec_chain, Int dec_index, + directedLine* topVertex, Int top_index, + directedLine* botVertex, + primStream* pStream) +{ + Int i; + directedLine *temp, *oldtemp = NULL; + Int tempIndex, oldtempIndex = 0; + + assert(inc_chain != NULL && dec_chain != NULL); + + if(inc_chain == botVertex) { + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex->getVertex(top_index), pStream); + for(i=dec_index; i< dec_chain->get_npoints(); i++){ + rChain.processNewVertex(dec_chain->getVertex(i), pStream); + } + for(temp = dec_chain->getPrev(); temp != botVertex; temp = temp->getPrev()) + { + for(i=0; iget_npoints(); i++){ + rChain.processNewVertex(temp->getVertex(i), pStream); + } + } + } + else if(dec_chain==botVertex) { + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex->getVertex(top_index), pStream); + for(i=inc_index; i< inc_chain->get_npoints(); i++){ + rChain.processNewVertex(inc_chain->getVertex(i), pStream); + } + for(temp = inc_chain->getPrev(); temp != botVertex; temp = temp->getNext()) + { + for(i=0; iget_npoints(); i++){ + rChain.processNewVertex(temp->getVertex(i), pStream); + } + } + } + else /*neither reached the bottom*/{ + if(compV2InY(inc_chain->getVertex(inc_index), dec_chain->getVertex(dec_index)) <=0) { + reflexChain rChain(20, 0); + rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); + temp = dec_chain; + tempIndex = dec_index; + while( compV2InY(inc_chain->getVertex(inc_index), temp->getVertex(tempIndex))<=0) { + oldtemp = temp; + oldtempIndex = tempIndex; + rChain.processNewVertex(temp->getVertex(tempIndex), pStream); + + if(tempIndex == temp->get_npoints()-1){ + tempIndex = 0; + temp = temp->getPrev(); + } + else{ + tempIndex++; + } + } + rChain.outputFan(inc_chain->getVertex(inc_index), pStream); + monoTriangulationRec(inc_chain, inc_index, temp, tempIndex, oldtemp, oldtempIndex, botVertex, pStream); + } + else /* >0*/ { + reflexChain rChain(20, 1); + rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); + temp = inc_chain; + tempIndex = inc_index; + while( compV2InY(temp->getVertex(tempIndex), dec_chain->getVertex(dec_index))>0){ + oldtemp = temp; + oldtempIndex = tempIndex; + rChain.processNewVertex(temp->getVertex(tempIndex), pStream); + + if(tempIndex == temp->get_npoints()-1){ + tempIndex = 0; + temp = temp->getNext(); + } + else{ + tempIndex++; + } + } + rChain.outputFan(dec_chain->getVertex(dec_index), pStream); + monoTriangulationRec(temp, tempIndex, dec_chain, dec_index, oldtemp, oldtempIndex, botVertex, pStream); + } + } /*end case neither reached the bottom*/ +} + +/***************************vertexArray begin here**********************************/ +vertexArray::vertexArray(Real2* vertices, Int nVertices) +{ + Int i; + size = index = nVertices; + array = (Real**) malloc(sizeof(Real*) * nVertices); + assert(array); + for(i=0; i= size){ + Real** temp = (Real**) malloc(sizeof(Real*) * (2*size +1)); + assert(temp); + for(i=0; i= v + * and array[i+1][1] v + *if sartIndex>endIndex, then return endIndex+1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex endIndex) + return endIndex+1; + else if(array[endIndex][1] > v) + return endIndex+1; + else //now array[endIndex][1] <= v + { + for(i=endIndex-1; i>=startIndex; i--) + { + if(array[i][1] > v) + break; + } + return i+1; + } +} + +/*find the first i<=endIndex such that array[i-1][1] >= v + * and array[i][1] < v + *if sartIndex>endIndex, then return endIndex+1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex endIndex) + return endIndex+1; + else if(array[endIndex][1] >= v) + return endIndex+1; + else //now array[endIndex][1] < v + { + for(i=endIndex-1; i>=startIndex; i--) + { + if(array[i][1] >= v) + break; + } + return i+1; + } +} + +/*find the first i>startIndex such that array[i-1][1] > v + * and array[i][1] >=v + *if sartIndex>endIndex, then return startIndex-1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex endIndex) + return startIndex-1; + else if(array[startIndex][1] < v) + return startIndex-1; + else //now array[startIndex][1] >= v + { + + for(i=startIndex; i<=endIndex; i++) + { + if(array[i][1] <= v) + break; + } + if(i>endIndex) // v is strictly below all + return endIndex; + else if(array[i][1] == v) + return i; + else + return i-1; + } + +} + + +/*find the first i>=startIndex such that array[i][1] >= v + * and array[i+1][1] endIndex, then return startIndex-1. + *otherwise, startIndex<=endIndex, it is assumed that + * 0<=startIndex<=endIndex endIndex) + return startIndex-1; + else if(array[startIndex][1] < v) + return startIndex-1; + else //now array[startIndex][1] >= v + { + for(i=startIndex+1; i<=endIndex; i++) + { + if(array[i][1] < v) + break; + } + return i-1; + } +} + +Int vertexArray::findDecreaseChainFromEnd(Int begin, Int end) +{ + Int i = end; + Real prevU = array[i][0]; + Real thisU; + for(i=end-1; i>=begin; i--){ + thisU = array[i][0]; + if(thisU < prevU) + prevU = thisU; + else + break; + } + return i; +} + +//if(V(start) == v, return start, other wise return the +//last i so that V(i)==v +Int vertexArray::skipEqualityFromStart(Real v, Int start, Int end) +{ + Int i; + if(array[start][1] != v) + return start; + //now array[start][1] == v + for(i=start+1; i<= end; i++) + if(array[i][1] != v) + break; + return i-1; +} + + +/***************************vertexArray end****************************************/ + + + +/***************************relfex chain stuff begin here*****************************/ + +reflexChain::reflexChain(Int size, Int is_increasing) +{ + queue = (Real2*) malloc(sizeof(Real2) * size); + assert(queue); + index_queue = 0; + size_queue = size; + isIncreasing = is_increasing; +} + +reflexChain::~reflexChain() +{ + free(queue); +} + +/*put (u,v) at the end of the queue + *pay attention to space + */ +void reflexChain::insert(Real u, Real v) +{ + Int i; + if(index_queue >= size_queue) { + Real2 *temp = (Real2*) malloc(sizeof(Real2) * (2*size_queue+1)); + assert(temp); + + /*copy*/ + for(i=0; ibegin(); + pStream->insert(v); + + if (isIncreasing) + { + for(i=0; iinsert(queue[i]); + } + } + else + { + for(i=index_queue-1; i>=0; i--) + { + pStream->insert(queue[i]); + } + } + pStream->end(PRIMITIVE_STREAM_FAN); +} + +void reflexChain::processNewVertex(Real v[2], primStream* pStream) +{ + Int i,j,k; + Int isReflex; + /*if there are at most one vertex in the queue, then simply insert + */ + if(index_queue <=1){ + insert(v); + return; + } + + /*there are at least two vertices in the queue*/ + j=index_queue-1; + + for(i=j; i>=1; i--) { + if(isIncreasing) { + isReflex = (area(queue[i-1], queue[i], v) <= 0.0); + } + else /*decreasing*/{ + isReflex = (area(v, queue[i], queue[i-1]) <= 0.0); + } + if(isReflex) { + break; + } + } + + /* + *if ibegin(); + pStream->insert(v); + if(isIncreasing) { + for(k=i; k<=j; k++) + pStream->insert(queue[k]); + } + else { + for(k=j; k>=i; k--) + pStream->insert(queue[k]); + } + pStream->end(PRIMITIVE_STREAM_FAN); + } + + /*delete vertices i+1--j from the queue*/ + index_queue = i+1; + /*finally insert v at the end of the queue*/ + insert(v); + +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.h b/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.h new file mode 100644 index 000000000..a83903807 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/monoTriangulation.h @@ -0,0 +1,177 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _MONO_TRIANGULATION_H +#define _MONO_TRIANGULATION_H + +#include "definitions.h" +#include "primitiveStream.h" +#include "directedLine.h" +#include "arc.h" + +class Backend; + +class reflexChain{ + Real2 *queue; + /*the order of the polygon vertices: either q[0],q[1].., or + * q[n-1], q[n-2], ..., q[0] + *this order determines the interior of the polygon, so it + *also used to determines whether a chain is reflex or convex + */ + Int isIncreasing; + Int index_queue; + Int size_queue; /*allocated size*/ + +public: + reflexChain(Int size, Int isIncreasing); + ~reflexChain(); + + void insert(Real u, Real v); + void insert(Real v[2]); + + void processNewVertex(Real v[2], primStream* pStream); + void outputFan(Real v[2], primStream* pStream); + + void processNewVertex(Real v[2], Backend* backend); + void outputFan(Real v[2], Backend* backend); +}; + +/*dynamic array of pointers to reals. + *Intended to store an array of (u,v). + *Notice that it doesn't allocate or dealocate the space + *for the (u,v) themselfs. So it assums that someone else + *is taking care of them, while this class only plays with + *the pointers. + */ +class vertexArray{ + Real** array; + Int index; + Int size; +public: + vertexArray(Int s); + vertexArray(Real vertices[][2], Int nVertices); + ~vertexArray(); + void appendVertex(Real* ptr); /*the content (pointed by ptr is NOT copied*/ + Real* getVertex(Int i) {return array[i];} + Real** getArray() {return array;} + Int getNumElements() {return index;} + Int findIndexAbove(Real v); + Int findIndexAboveGen(Real v, Int startIndex, Int EndIndex); + Int findIndexBelowGen(Real v, Int startIndex, Int EndIndex); + Int findIndexStrictBelowGen(Real v, Int startIndex, Int EndIndex); + Int findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex); + Int skipEqualityFromStart(Real v, Int start, Int end); + //return i such that fron [i+1, end] is strictly U-monotone (left to right + Int findDecreaseChainFromEnd(Int begin, Int end); +}; + +void monoTriangulation(directedLine* monoPolygon, primStream* pStream); + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + primStream* pStream); + +void monoTriangulationRec(directedLine* inc_chain, Int inc_index, + directedLine* dec_chain, Int dec_index, + directedLine* topVertex, Int top_index, + directedLine* botVertex, + primStream* pStream); + +/*the chain could be increasing or decreasing, although we use the + * name inc_chain. + *the argument is_increase_chain indicates whether this chain + *is increasing (left chain in V-monotone case) or decreaing (right chain + *in V-monotone case). + */ +void monoTriangulation2(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_smallIndex, + Int inc_largeIndex, + Int is_increase_chain, + primStream* pStream); +void monoTriangulationRecGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void triangulateXYMonoTB(Int n_left, Real** leftVerts, + Int n_right, Real** rightVerts, + primStream* pStream); + +void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream); + +void monoTriangulationRecOpt(Real* topVertex, Real* botVertex, + vertexArray* left_chain, Int left_current, + vertexArray* right_chain, Int right_current, + primStream* pStream); + +void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + Int (*compFun)(Real*, Real*), + primStream* pStream); + +void monoTriangulationRecFun(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + primStream* pStream); +void monoTriangulationFun(directedLine* monoPolygon, + Int (*compFun)(Real*, Real*), primStream* pStream); + + +void monoTriangulationRec(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Backend* backend); + +void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend); + +void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, + vertexArray* dec_chain, Int dec_current, + Int (*compFun)(Real*, Real*), + Backend* backend); + +void monoTriangulationOpt(directedLine* poly, primStream* pStream); + +#endif /* _MONO_TRIANGULATION_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/mystdio.h b/project/jni/glu/src/libnurbs/nurbtess/mystdio.h new file mode 100644 index 000000000..65a305506 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/mystdio.h @@ -0,0 +1,55 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#ifndef __glumystdio_h_ +#define __glumystdio_h_ + +#ifdef LIBRARYBUILD + #ifndef NDEBUG + #include + #define _glu_dprintf printf + #else + inline void _glu_dprintf(char *, ...) { } + #endif /* NDEBUG */ +#endif /* LIBRARYBUILD */ + +#ifdef GLBUILD + inline void _glu_dprintf(char *, ...) { } +#endif + +#ifndef NULL + #define NULL 0 +#endif + +#endif /* __glumystdio_h_ */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/mystdlib.h b/project/jni/glu/src/libnurbs/nurbtess/mystdlib.h new file mode 100644 index 000000000..c1a9ecaab --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/mystdlib.h @@ -0,0 +1,49 @@ +/* + * 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 GLU by Mike Gorchak + */ + +#ifndef __glumystdlib_h_ +#define __glumystdlib_h_ + +#ifdef LIBRARYBUILD + #include +#endif + +#ifdef GLBUILD + typedef unsigned int size_t; + extern "C" void abort(void); + extern "C" void* malloc(size_t); + extern "C" void free(void*); +#endif + +#endif /* __glumystdlib_h_ */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/partitionX.cc b/project/jni/glu/src/libnurbs/nurbtess/partitionX.cc new file mode 100644 index 000000000..4c1479e90 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/partitionX.cc @@ -0,0 +1,158 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include + +#include "partitionX.h" + +#define CONCAVITY_ZERO 1.0e-6 //this number is used to test whether a vertex is concave (refelx) + //or not. The test needs to compute the area of the three adjacent + //vertices to see if the are is positive or negative. + +Int isCuspX(directedLine *v) +{ + //if v->prev <= v && v->next <= v + //|| v->prev >= v && v->next >= v + Real* T = v->head(); + Real* P = v->getPrev()->head(); + Real* N = v->getNext()->head(); + if( + (compV2InX(T,P) != -1 && + compV2InX(T,N) != -1 + ) || + (compV2InX(T,P) != 1 && + compV2InX(T,N) != 1 + ) + ) + return 1; + else + return 0; +} + +Int isReflexX(directedLine* v) +{ + Real* A = v->getPrev()->head(); + Real* B = v->head(); + Real* C = v->tail(); + Real Bx,By, Cx, Cy; + //scale them in case they are too small + Bx = 10*(B[0] - A[0]); + By = 10*(B[1] - A[1]); + Cx = 10*(C[0] - A[0]); + Cy = 10*(C[1] - A[1]); + + if(Bx*Cy - Cx*By < -CONCAVITY_ZERO) return 1; + else return 0; +} + + +/*return + *0: not-cusp + *1: interior cusp + *2: exterior cusp + */ +Int cuspTypeX(directedLine *v) +{ + if(! isCuspX(v)) return 0; + else + { + if(isReflexX(v)) + { + return 1; + } + else + { + return 2; + } + } +} + +Int numInteriorCuspsX(directedLine *polygon) +{ + directedLine *temp; + int ret = 0; + if(cuspTypeX(polygon) == 1) + ret++; + for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + if(cuspTypeX(temp) == 1) + ret++; + return ret; +} + + +void findInteriorCuspsX(directedLine *polygon, Int& ret_n_interior_cusps, + directedLine** ret_interior_cusps) +{ + directedLine *temp; + ret_n_interior_cusps = 0; + if(cuspTypeX(polygon) == 1) + { + ret_interior_cusps[ret_n_interior_cusps++] = polygon; + } + for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + if(cuspTypeX(temp) == 1) + { + ret_interior_cusps[ret_n_interior_cusps++] = temp; + } +} + +directedLine* findDiagonal_singleCuspX(directedLine* cusp) +{ + directedLine* temp; + Int is_minimal = ((compV2InX(cusp->head(), cusp->tail()) == -1)? 1:0); + + if(is_minimal) + for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext()) + { + if(compV2InX(cusp->head(), temp->head()) == 1) + { + return temp; + } + } + else //is maxmal + for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext()) + { + if(compV2InX(cusp->head(), temp->head()) == -1) + { + return temp; + } + } + return NULL; +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/partitionX.h b/project/jni/glu/src/libnurbs/nurbtess/partitionX.h new file mode 100644 index 000000000..88b699f1b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/partitionX.h @@ -0,0 +1,55 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _PARTITIONX_H +#define _PARTITIONX_H + +#include "directedLine.h" + +Int isCuspX(directedLine *v); +Int isReflexX(directedLine *v); +Int cuspTypeX(directedLine *v); + +//assuming the array of ret_interior_cusps has been allocated +void findInteriorCuspsX(directedLine* polygon, Int& ret_n_interior_cusps, + directedLine** ret_interior_cusps); + +Int numInteriorCuspsX(directedLine* polygon); + +/*a single polygon with a single cusp + *return the diagonal vertex corresponding to this cusp + */ +directedLine* findDiagonal_singleCuspX(directedLine* cusp); + +#endif /* _PARTITIONX_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/partitionY.cc b/project/jni/glu/src/libnurbs/nurbtess/partitionY.cc new file mode 100644 index 000000000..edbdb8050 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/partitionY.cc @@ -0,0 +1,817 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include + +#include "zlassert.h" +#include "partitionY.h" +#include "searchTree.h" +#include "quicksort.h" +#include "polyUtil.h" + + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + + +/* return + * -1: if A < B (YaB + */ +static Int compVertInY(Real A[2], Real B[2]) +{ + if( (A[1] < B[1]) || (A[1]==B[1] && A[0]head(); + if( compVertInY(e->head(), vert) != 1 + && compVertInY(e->tail(), vert) != 1 + ) + return 1; + else + return 0; +} + +/*v is a vertex: the head of en edge, + *e is an edge, + *return 1 if e is below v: assume v1 and v2 are the two endpoints of e: + * v1>= v, v2>=v. + */ +Int isAbove(directedLine *v, directedLine *e) +{ + Real* vert = v->head(); + if( compVertInY(e->head(), vert) != -1 + && compVertInY(e->tail(), vert) != -1 + ) + return 1; + else + return 0; +} + +Int isCusp(directedLine *v) +{ + Real *A=v->getPrev()->head(); + Real *B=v->head(); + Real *C=v->tail(); + if(A[1] < B[1] && B[1] < C[1]) + return 0; + else if(A[1] > B[1] && B[1] > C[1]) + return 0; + else if(A[1] < B[1] && C[1] < B[1]) + return 1; + else if(A[1] > B[1] && C[1] > B[1]) + return 1; + + if((isAbove(v, v) && isAbove(v, v->getPrev())) || + (isBelow(v, v) && isBelow(v, v->getPrev()))) + return 1; + else + return 0; +} + +/*crossproduct is strictly less than 0*/ +Int isReflex(directedLine *v) +{ + Real* A = v->getPrev()->head(); + Real* B = v->head(); + Real* C = v->tail(); + Real Bx,By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + + if(Bx*Cy - Cx*By < 0) return 1; + else return 0; +} + + /*return + *0: not-cusp + *1: interior cusp + *2: exterior cusp + */ +Int cuspType(directedLine *v) +{ + if(! isCusp(v)) return 0; + else if(isReflex(v)) return 1; + else + return 2; +} + +sweepRange* sweepRangeMake(directedLine* left, Int leftType, + directedLine* right, Int rightType) +{ + sweepRange* ret = (sweepRange*)malloc(sizeof(sweepRange)); + assert(ret); + ret->left = left; + ret->leftType = leftType; + ret->right = right; + ret->rightType = rightType; + return ret; +} + +void sweepRangeDelete(sweepRange* range) +{ + free(range); +} + +Int sweepRangeEqual(sweepRange* src1, sweepRange* src2) +{ + Int leftEqual; + Int rightEqual; + + + /*The case when both are vertices should not happen*/ + assert(! (src1->leftType == 0 && src2->leftType == 0)); + if(src1->leftType == 0 && src2->leftType == 1){ + if(src1->left == src2->left || + src1->left->getPrev() == src2->left + ) + leftEqual = 1; + else + leftEqual = 0; + } + else if(src1->leftType == 1 && src2->leftType == 1){ + if(src1->left == src2->left) + leftEqual = 1; + else + leftEqual = 0; + } + else /*src1->leftType == 1 && src2->leftType == 0*/{ + if(src1->left == src2->left || + src1->left == src2->left->getPrev() + ) + leftEqual = 1; + else + leftEqual = 0; + } + + /*the same thing for right*/ + /*The case when both are vertices should not happen*/ + assert(! (src1->rightType == 0 && src2->rightType == 0)); + if(src1->rightType == 0 && src2->rightType == 1){ + if(src1->right == src2->right || + src1->right->getPrev() == src2->right + ) + rightEqual = 1; + else + rightEqual = 0; + } + else if(src1->rightType == 1 && src2->rightType == 1){ + if(src1->right == src2->right) + rightEqual = 1; + else + rightEqual = 0; + } + else /*src1->rightType == 1 && src2->rightType == 0*/{ + if(src1->right == src2->right || + src1->right == src2->right->getPrev() + ) + rightEqual = 1; + else + rightEqual = 0; + } + + return (leftEqual == 1 || rightEqual == 1); +} + +/*given (x_1, y_1) and (x_2, y_2), and y + *return x such that (x,y) is on the line + */ +inline/*static*/ Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) +{ + return ((y2==y1)? (x1+x2)*Real(0.5) : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); +/* + if(y2 == y1) return (x1+x2)*0.5; + else return x1 + ((y-y1)/(y2-y1)) * (x2-x1); +*/ +} + +/*compare two edges of a polygon. + *edge A < edge B if there is a horizontal line so that the intersection + *with A is to the left of the intersection with B. + *This function is used in sweepY for the dynamic search tree insertion to + *order the edges. + * Implementation: (x_1,y_1) and (x_2, y_2) + */ +static Int compEdges(directedLine *e1, directedLine *e2) +{ + Real* head1 = e1->head(); + Real* tail1 = e1->tail(); + Real* head2 = e2->head(); + Real* tail2 = e2->tail(); +/* + Real h10 = head1[0]; + Real h11 = head1[1]; + Real t10 = tail1[0]; + Real t11 = tail1[1]; + Real h20 = head2[0]; + Real h21 = head2[1]; + Real t20 = tail2[0]; + Real t21 = tail2[1]; +*/ + Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; +/* + if(h11>t11) { + e1_Ymax= h11; + e1_Ymin= t11; + } + else{ + e1_Ymax = t11; + e1_Ymin = h11; + } + + if(h21>t21) { + e2_Ymax= h21; + e2_Ymin= t21; + } + else{ + e2_Ymax = t21; + e2_Ymin = h21; + } +*/ + + if(head1[1]>tail1[1]) { + e1_Ymax= head1[1]; + e1_Ymin= tail1[1]; + } + else{ + e1_Ymax = tail1[1]; + e1_Ymin = head1[1]; + } + + if(head2[1]>tail2[1]) { + e2_Ymax= head2[1]; + e2_Ymin= tail2[1]; + } + else{ + e2_Ymax = tail2[1]; + e2_Ymin = head2[1]; + } + + + /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/ + /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/ + /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/ + /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/ + + Real Ymax = min(e1_Ymax, e2_Ymax); + Real Ymin = max(e1_Ymin, e2_Ymin); + Real y = Real(0.5)*(Ymax + Ymin); + +/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y); + Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y); +*/ +/* + Real x1 = intersectHoriz(h10, h11, t10, t11, y); + Real x2 = intersectHoriz(h20, h21, t20, t21, y); +*/ + Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); + Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); + + if(x1<= x2) return -1; + else return 1; +} + +/*used by sort precedures + */ +static Int compInY(directedLine* v1, directedLine* v2) +{ + return v1->compInY(v2); +} + +void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices) +{ + Int i,j,k; + + k=0; + + for(i=0; igetPrev(); + + if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) + { + /*this is an upward interior cusp*/ + diagonal_vertices[k++] = vert; + + for(j=i+1; j0) + { + /*this is an downward interior cusp*/ + diagonal_vertices[k++] = vert; + for(j=i-1; j>=0; j--) + if(sweepRangeEqual(ranges[i], ranges[j])) + { + diagonal_vertices[k++] = sortedVertices[j]; + break; + } + assert(j>=0); + } + } + num_diagonals = k/2; +} + +/*get rid of repeated diagonlas so that each diagonal appears only once in the array + */ +Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices) +{ + Int i,k; + Int j,l; + Int index; + index=0; + for(i=0,k=0; itoArrayAllPolygons(total_num_edges); + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); + sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * total_num_edges); + assert(ranges); + + sweepY(total_num_edges, array, ranges); + + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); + assert(diagonal_vertices); + findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); + + num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + return diagonal_vertices; + +} + + +/*partition into Y-monotone polygons*/ +directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines) +{ + Int total_num_edges = 0; + directedLine** array = polygons->toArrayAllPolygons(total_num_edges); + + quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); + + sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * (total_num_edges)); + assert(ranges); + + + + sweepY(total_num_edges, array, ranges); + + + + /*the diagonal vertices are stored as: + *v0-v1: 1st diagonal + *v2-v3: 2nd diagonal + *v5-v5: 3rd diagonal + *... + */ + + + Int num_diagonals; + /*number diagonals is < total_num_edges*total_num_edges*/ + directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges*2/*total_num_edges*/); + assert(diagonal_vertices); + + + + findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); + + + + directedLine* ret_polygons = polygons; + sampledLine* newSampledLines = NULL; + Int i,k; + +num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); + + + + Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); + for(i=0; ifindRoot(); + directedLine *root2 = v2->findRoot(); + assert(root1); + assert(root2); +*/ + +directedLine* root1 = v1->rootLinkFindRoot(); +directedLine* root2 = v2->rootLinkFindRoot(); + + if(root1 != root2) + { + + removedDiagonals[i] = 1; + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + + + + newSampledLines = generatedLine->insert(newSampledLines); +/* + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_polygons->cutoffPolygon(root2); + ret_polygons = ret_p1->insertPolygon(ret_polygons); +root1->rootLinkSet(ret_p1); +root2->rootLinkSet(ret_p1); +ret_p1->rootLinkSet(NULL); +ret_p2->rootLinkSet(ret_p1); +*/ + ret_polygons = ret_polygons->cutoffPolygon(root2); + + + +root2->rootLinkSet(root1); +ret_p1->rootLinkSet(root1); +ret_p2->rootLinkSet(root1); + + /*now that we have connected the diagonal v1 and v2, + *we have to check those unprocessed diagonals which + *have v1 or v2 as an end point. Notice that the head of v1 + *has the same coodinates as the head of v2->prev, and the head of + *v2 has the same coordinate as the head of v1->prev. + *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid + *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be + *replaced by (v2->prev, x), that is, x is on the left of + * v2->prev->prev->head, v2->prev->head, v2->prev->tail. + */ + Int ii, kk; + for(ii=0, kk=0; iiprev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v2->getPrev(); + } + } + if(d1 == v2) { + /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d2->head())) + { +/* + assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d2->head())); +*/ + diagonal_vertices[kk] = v1->getPrev(); + } + } + /*check d2 and replace diagonal_vertices[k+1] if necessary*/ + if(d2 == v1) { + /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ + if(! pointLeft2Lines(v1->getPrev()->head(), + v1->head(), v1->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), + v2->getPrev()->head(), + v2->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v2->getPrev(); + } + } + if(d2 == v2) { + /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ + if(! pointLeft2Lines(v2->getPrev()->head(), + v2->head(), v2->tail(), d1->head())) + { +/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), + v1->getPrev()->head(), + v1->getPrev()->tail(), d1->head())); +*/ + diagonal_vertices[kk+1] = v1->getPrev(); + } + } + } +}/*end if (root1 not equal to root 2)*/ +} + + /*second pass, now all diagoals should belong to the same polygon*/ + + + + for(i=0,k=0; ifindRoot(); +/* + directedLine *root2 = v2->findRoot(); + + + + assert(root1); + assert(root2); + assert(root1 == root2); + */ + sampledLine* generatedLine; + + + + v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); + newSampledLines = generatedLine->insert(newSampledLines); + + ret_polygons = ret_polygons->cutoffPolygon(root1); + + ret_polygons = ret_p1->insertPolygon(ret_polygons); + + ret_polygons = ret_p2->insertPolygon(ret_polygons); + + + + for(Int j=i+1; jsamePolygon(temp1, temp2)) + { + /*if temp1 and temp2 are in different polygons, + *then one of them must be v1 or v2. + */ + + + + assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); + if(temp1==v1) + { + diagonal_vertices[2*j] = v2->getPrev(); + } + if(temp2==v1) + { + diagonal_vertices[2*j+1] = v2->getPrev(); + } + if(temp1==v2) + { + diagonal_vertices[2*j] = v1->getPrev(); + } + if(temp2==v2) + { + diagonal_vertices[2*j+1] = v1->getPrev(); + } + } + } + } + + } + + /*clean up spaces*/ + free(array); + free(ranges); + free(diagonal_vertices); + free(removedDiagonals); + + *retSampledLines = newSampledLines; + return ret_polygons; +} + +/*given a set of simple polygons where the interior + *is decided by left-hand principle, + *return a range (sight) for each vertex. This is called + *Trapezoidalization. + */ +void sweepY(Int nVertices, directedLine** sortedVertices, sweepRange** ret_ranges) +{ + Int i; + /*for each vertex in the sorted list, update the binary search tree. + *and store the range information for each vertex. + */ + treeNode* searchTree = NULL; + for(i=0; igetPrev(); + + if(isBelow(vert, thisEdge) && isAbove(vert, prevEdge)) + { + + /*case 1: this < v < prev + *the polygon is going down at v, the interior is to + *the right hand side. + * find the edge to the right of thisEdge for right range. + * delete thisEdge + * insert prevEdge + */ + treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); + assert(thisNode); + + treeNode* succ = TreeNodeSuccessor(thisNode); + assert(succ); + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeInsert(searchTree, TreeNodeMake(prevEdge), ( Int (*) (void *, void *))compEdges); + + + ret_ranges[i] = sweepRangeMake(vert, 0, (directedLine*) (succ->key), 1); + + } + else if(isAbove(vert, thisEdge) && isBelow(vert, prevEdge)) + { + + /*case 2: this > v > prev + *the polygon is going up at v, the interior is to + *the left hand side. + * find the edge to the left of thisEdge for left range. + * delete prevEdge + * insert thisEdge + */ + treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); + assert(prevNode); + treeNode* pred = TreeNodePredecessor(prevNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + searchTree = TreeNodeInsert(searchTree, TreeNodeMake(thisEdge), ( Int (*) (void *, void *))compEdges); + ret_ranges[i] = sweepRangeMake((directedLine*)(pred->key), 1, vert, 0); + } + else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge)) + { + + /*case 3: insert both edges*/ + treeNode* thisNode = TreeNodeMake(thisEdge); + treeNode* prevNode = TreeNodeMake(prevEdge); + searchTree = TreeNodeInsert(searchTree, thisNode, ( Int (*) (void *, void *))compEdges); + searchTree = TreeNodeInsert(searchTree, prevNode, ( Int (*) (void *, void *))compEdges); + if(compEdges(thisEdge, prevEdge)<0) /*interior cusp*/ + { + + treeNode* leftEdge = TreeNodePredecessor(thisNode); + treeNode* rightEdge = TreeNodeSuccessor(prevNode); + ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, + (directedLine*) rightEdge->key, 1 + ); + } + else /*exterior cusp*/ + { + + ret_ranges[i] = sweepRangeMake( prevEdge, 1, thisEdge, 1); + } + } + else if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge)) + { + + /*case 4: delete both edges*/ + treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); + treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); + if(compEdges(thisEdge, prevEdge)>0) /*interior cusp*/ + { + treeNode* leftEdge = TreeNodePredecessor(prevNode); + treeNode* rightEdge = TreeNodeSuccessor(thisNode); + ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, + (directedLine*) rightEdge->key, 1 + ); + } + else /*exterior cusp*/ + { + ret_ranges[i] = sweepRangeMake( thisEdge, 1, prevEdge, 1); + } + searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); + searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); + } + } + + /*finaly clean up space: delete the search tree*/ + TreeNodeDeleteWholeTree(searchTree); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/partitionY.h b/project/jni/glu/src/libnurbs/nurbtess/partitionY.h new file mode 100644 index 000000000..77598fc3d --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/partitionY.h @@ -0,0 +1,102 @@ +/* + * 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 GLU by Mike Gorchak + */ + +/* + *partitionY.h: + *partition a polygon into a Y-monotone polygon: + * A polygon is Y-monotone if the boundary can be split into two polygon chains + *A and B such that each chain is Y-monotonic that is the intersection of any + *horizontal line intersects each chain has at most one connected componenets + * (empty, single point or a single line). + * + * A vertex is a cusp if both its ajacent vertices are either at or above v, + *or both at or below v. In addition, at least one of the ajacent verteces is + *strictly below or above v. + * A vertex is a relex vertex if the internals angle is strictly greater than + *180. In other words, if the the signed area is negative: + *(x1, y1), (x2, y2), (x3, y3) are the three vertices along a polygon, the + *order is such that left hand side is inside the polygon. Then (x2,y2) is + *reflex if: + * (x2-x1, y2-y1) cross (x3-x1, y3-y1) <0. + *A vertex is an interior cusp if it is a cusp and a reflex. + *A vertex is an exterior cusp if it is a cusp but not a reflex. + * + */ + +#ifndef _PARTITIONY_H +#define _PARTITIONY_H + +#include "directedLine.h" + +/*whether an edge is below a vertex*/ +Int isBelow(directedLine *v, directedLine *e); + +/*whether an edge is above a vertex*/ +Int isAbove(directedLine *v, directedLine *e); + +/*not-cusp, + *inerior cusp + *exterior cusp + */ +Int cuspType(directedLine *v); + +/*used in trapezoidalization*/ +typedef struct sweepRange{ + directedLine *left; + Int leftType; /*either a vertex (leftType=0) or an edge (leftType =1) */ + directedLine *right; + Int rightType; /*either a vertex (rightType=0) or an edge (rightType =1) */ +} sweepRange; + +sweepRange* sweepRangeMake(directedLine* left, Int leftType, + directedLine* right, Int rightType); + +void sweepRangeDelete(sweepRange* range); +Int sweepRangeEqual(sweepRange* sr1, sweepRange* sr2); + +/*given a set of simple polygons where the interior + *is decided by left-hand principle, + *return a range (sight) for each vertex. This is called + *Trapezoidalization. + */ +void sweepY(Int nVertices, directedLine **sortedVerteces, sweepRange** ret_ranges); + + +directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines); + +void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices); + +directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals); + +#endif /* _PARTITIONY_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/polyDBG.cc b/project/jni/glu/src/libnurbs/nurbtess/polyDBG.cc new file mode 100644 index 000000000..ae75ed030 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/polyDBG.cc @@ -0,0 +1,651 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include +#include "zlassert.h" +#include "polyDBG.h" + +#ifdef __WATCOMC__ +#pragma warning 14 10 +#pragma warning 391 10 +#pragma warning 726 10 +#endif + +static Real area(Real A[2], Real B[2], Real C[2]) +{ + Real Bx, By, Cx, Cy; + Bx = B[0] - A[0]; + By = B[1] - A[1]; + Cx = C[0] - A[0]; + Cy = C[1] - A[1]; + return Bx*Cy - Cx*By; +} + +Int DBG_isConvex(directedLine *poly) +{ + directedLine* temp; + if(area(poly->head(), poly->tail(), poly->getNext()->tail()) < 0.00000) + return 0; + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + if(area(temp->head(), temp->tail(), temp->getNext()->tail()) < 0.00000) + return 0; + } + return 1; +} + +Int DBG_is_U_monotone(directedLine* poly) +{ + Int n_changes = 0; + Int prev_sign; + Int cur_sign; + directedLine* temp; + cur_sign = compV2InX(poly->tail(), poly->head()); + + n_changes = (compV2InX(poly->getPrev()->tail(), poly->getPrev()->head()) + != cur_sign); + + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + prev_sign = cur_sign; + cur_sign = compV2InX(temp->tail(), temp->head()); + + if(cur_sign != prev_sign) + n_changes++; + } + + if(n_changes ==2) return 1; + else return 0; +} + +/*if u-monotone, and there is a long horizontal edge*/ +Int DBG_is_U_direction(directedLine* poly) +{ +/* + if(! DBG_is_U_monotone(poly)) + return 0; +*/ + Int V_count = 0; + Int U_count = 0; + directedLine* temp; + if( fabs(poly->head()[0] - poly->tail()[0]) <= fabs(poly->head()[1]-poly->tail()[1])) + V_count += poly->get_npoints(); + else + U_count += poly->get_npoints(); + /* + else if(poly->head()[1] == poly->tail()[1]) + U_count += poly->get_npoints(); + */ + for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) + { + if( fabs(temp->head()[0] - temp->tail()[0]) <= fabs(temp->head()[1]-temp->tail()[1])) + V_count += temp->get_npoints(); + else + U_count += temp->get_npoints(); + /* + if(temp->head()[0] == temp->tail()[0]) + V_count += temp->get_npoints(); + else if(temp->head()[1] == temp->tail()[1]) + U_count += temp->get_npoints(); + */ + } + + if(U_count > V_count) return 1; + else return 0; +} + +/*given two line segments, determine whether + *they intersect each other or not. + *return 1 if they do, + *return 0 otherwise + */ +Int DBG_edgesIntersect(directedLine* l1, directedLine* l2) +{ + if(l1->getNext() == l2) + { + if(area(l1->head(), l1->tail(), l2->tail()) == 0) //colinear + { + if( (l1->tail()[0] - l1->head()[0])*(l2->tail()[0]-l2->head()[0]) + + (l1->tail()[1] - l1->head()[1])*(l2->tail()[1]-l2->head()[1]) >=0) + return 0; //not intersect + else + return 1; + } + //else we use the normal code + } + else if(l1->getPrev() == l2) + { + if(area(l2->head(), l2->tail(), l1->tail()) == 0) //colinear + { + if( (l2->tail()[0] - l2->head()[0])*(l1->tail()[0]-l1->head()[0]) + + (l2->tail()[1] - l2->head()[1])*(l1->tail()[1]-l1->head()[1]) >=0) + return 0; //not intersect + else + return 1; + } + //else we use the normal code + } + else //the two edges are not connected + { + if((l1->head()[0] == l2->head()[0] && + l1->head()[1] == l2->head()[1]) || + (l1->tail()[0] == l2->tail()[0] && + l1->tail()[1] == l2->tail()[1])) + return 1; + + } + + + if( + ( + area(l1->head(), l1->tail(), l2->head()) + * + area(l1->head(), l1->tail(), l2->tail()) + < 0 + ) + && + ( + area(l2->head(), l2->tail(), l1->head()) + *area(l2->head(), l2->tail(), l1->tail()) + < 0 + ) + ) + return 1; + else + return 0; +} + +/*whether AB and CD intersect + *return 1 if they do + *retur 0 otheriwse + */ +Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]) +{ + if( + ( + area(A, B, C) * area(A,B,D) <0 + ) + && + ( + area(C,D,A) * area(C,D,B) < 0 + ) + ) + return 1; + else + return 0; +} + +/*determien whether (A,B) interesect chain[start] to [end] + */ +Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]) +{ + Int i; + for(i=start; i<=end-2; i++) + if(DBG_edgesIntersectGen(chain->getVertex(i), chain->getVertex(i+1), A, B)) + return 1; + + return 0; +} + +/*determine whether a polygon intersect itself or not + *return 1 is it does, + * 0 otherwise + */ +Int DBG_polygonSelfIntersect(directedLine* poly) +{ + directedLine* temp1; + directedLine* temp2; + temp1=poly; + for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) + { + if(DBG_edgesIntersect(temp1, temp2)) + { + return 1; + } + + } + + for(temp1=poly->getNext(); temp1 != poly; temp1 = temp1->getNext()) + for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) + { + if(DBG_edgesIntersect(temp1, temp2)) + { + return 1; + } + } + return 0; +} + +/*check whether a line segment intersects a polygon + */ +Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly) +{ + directedLine* temp; + if(DBG_edgesIntersect(edge, poly)) + return 1; + for(temp=poly->getNext(); temp != poly; temp=temp->getNext()) + if(DBG_edgesIntersect(edge, temp)) + return 1; + return 0; +} + +/*check whether two polygons intersect + */ +Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2) +{ + directedLine* temp; + if(DBG_edgeIntersectPoly(p1, p2)) + return 1; + for(temp=p1->getNext(); temp!= p1; temp = temp->getNext()) + if(DBG_edgeIntersectPoly(temp, p2)) + return 1; + return 0; +} + +/*check whether there are polygons intersecting each other in + *a list of polygons + */ +Int DBG_polygonListIntersect(directedLine* pList) +{ + directedLine *temp; + for(temp=pList; temp != NULL; temp = temp->getNextPolygon()) + if(DBG_polygonSelfIntersect(temp)) + return 1; + directedLine* temp2; + for(temp=pList; temp!=NULL; temp=temp->getNextPolygon()) + { + for(temp2=temp->getNextPolygon(); temp2 != NULL; temp2=temp2->getNextPolygon()) + if(DBG_polygonsIntersect(temp, temp2)) + return 1; + } + + return 0; +} + + +Int DBG_isCounterclockwise(directedLine* poly) +{ + return (poly->polyArea() > 0); +} + +/*ray: v0 with direction (dx,dy). + *edge: v1-v2. + * the extra point v10[2] is given for the information at + *v1. Basically this edge is connectd to edge + * v10-v1. If v1 is on the ray, + * then we need v10 to determine whether this ray intersects + * the edge or not (that is, return 1 or return 0). + * If v1 is on the ray, then if v2 and v10 are on the same side of the ray, + * we return 0, otherwise return 1. + *For v2, if v2 is on the ray, we always return 0. + *Notice that v1 and v2 are not symmetric. So the edge is directed!!! + * The purpose for this convention is such that: a point is inside a polygon + * if and only if it intersets with odd number of edges. + */ +Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]) +{ + Real denom = (v2[0]-v1[0])*(-dy) - (v2[1]-v1[1]) * (-dx); + Real nomRay = (v2[0]-v1[0]) * (v0[1] - v1[1]) - (v2[1]-v1[1])*(v0[0]-v1[0]); + Real nomEdge = (v0[0]-v1[0]) * (-dy) - (v0[1]-v1[1])*(-dx); + + /*if the ray is parallel to the edge, return 0: not intersect*/ + if(denom == 0.0) + return 0; + + /*if v0 is on the edge, return 0: not intersect*/ + if(nomRay == 0.0) + return 0; + + /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray + *return 1: intersect + */ + if(nomEdge == 0) + { /*v1 is on the positive or negative ray*/ + + if(dx*(v1[0]-v0[0])>=0 && dy*(v1[1]-v0[1])>=0) /*v1 on positive ray*/ + { + if(area(v0, v1, v10) * area(v0, v1, v2) >0) + return 0; + else + return 1; + } + else /*v1 on negative ray*/ + return 0; + } + + /*if v2 is on the ray, always return 0: not intersect*/ + if(nomEdge == denom) { + return 0; + } + + /*finally */ + if(denom*nomRay>0 && denom*nomEdge>0 && nomEdge/denom <=1.0) + return 1; + return 0; +} + + +/*return the number of intersections*/ +Int DBG_rayIntersectPoly(Real v0[2], Real dx, Real dy, directedLine* poly) +{ + directedLine* temp; + Int count=0; + if(DBG_rayIntersectEdge(v0, dx, dy, poly->getPrev()->head(), poly->head(), poly->tail())) + count++; + + for(temp=poly->getNext(); temp != poly; temp = temp->getNext()) + if(DBG_rayIntersectEdge(v0, dx, dy, temp->getPrev()->head(), temp->head(), temp->tail())) + count++; + + return count; +} + +Int DBG_pointInsidePoly(Real v[2], directedLine* poly) +{ + /*for debug purpose*/ + assert( (DBG_rayIntersectPoly(v,1,0,poly) % 2 ) + == (DBG_rayIntersectPoly(v,1,Real(0.1234), poly) % 2 ) + ); + if(DBG_rayIntersectPoly(v, 1, 0, poly) % 2 == 1) + return 1; + else + return 0; +} + +/*return the number of polygons which contain thie polygon + * as a subset + */ +Int DBG_enclosingPolygons(directedLine* poly, directedLine* list) +{ + directedLine* temp; + Int count=0; + + for(temp = list; temp != NULL; temp = temp->getNextPolygon()) + { + if(poly != temp) + if(DBG_pointInsidePoly(poly->head(), temp)) + count++; + } + return count; +} + +void DBG_reverse(directedLine* poly) +{ + if(poly->getDirection() == INCREASING) + poly->putDirection(DECREASING); + else + poly->putDirection(INCREASING); + + directedLine* oldNext = poly->getNext(); + poly->putNext(poly->getPrev()); + poly->putPrev(oldNext); + + directedLine* temp; + for(temp=oldNext; temp!=poly; temp = oldNext) + { + if(temp->getDirection() == INCREASING) + temp->putDirection(DECREASING); + else + temp->putDirection(INCREASING); + + oldNext = temp->getNext(); + temp->putNext(temp->getPrev()); + temp->putPrev(oldNext); + } + printf("reverse done\n"); +} + +Int DBG_checkConnectivity(directedLine *polygon) +{ + if(polygon == NULL) return 1; + directedLine* temp; + if(polygon->head()[0] != polygon->getPrev()->tail()[0] || + polygon->head()[1] != polygon->getPrev()->tail()[1]) + return 0; + for(temp=polygon->getNext(); temp != polygon; temp=temp->getNext()) + { + if(temp->head()[0] != temp->getPrev()->tail()[0] || + temp->head()[1] != temp->getPrev()->tail()[1]) + return 0; + } + return 1; +} + +/*print out error message. + *If it cannot modify the polygon list to make it satify the + *requirements, return 1. + *otherwise modify the polygon list, and return 0 + */ +Int DBG_check(directedLine *polyList) +{ + directedLine* temp; + if(polyList == NULL) return 0; + + /*if there are intersections, print out error message + */ + if(DBG_polygonListIntersect(polyList)) + { + fprintf(stderr, "DBG_check: there are self intersections, don't know to modify the polygons\n"); + return 1; + } + + /*check the connectivity of each polygon*/ + for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) + { + if(! DBG_checkConnectivity(temp)) + { + fprintf(stderr, "DBG_check, polygon not connected\n"); + return 1; + } + } + + /*check the orientation of each polygon*/ + for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) + { + + + Int correctDir; + + if( DBG_enclosingPolygons(temp, polyList) % 2 == 0) + correctDir = 1; /*counterclockwise*/ + else + correctDir = 0; /*clockwise*/ + + Int actualDir = DBG_isCounterclockwise(temp); + + if(correctDir != actualDir) + { + fprintf(stderr, "DBG_check: polygon with incorrect orientations. reversed\n"); + + DBG_reverse(temp); + } + + } + return 0; +} + +/**************handle self intersections*****************/ +//determine whether e interects [begin, end] or not +static directedLine* DBG_edgeIntersectChainD(directedLine *e, + directedLine *begin, directedLine *end) +{ + directedLine *temp; + for(temp=begin; temp != end; temp = temp->getNext()) + { + if(DBG_edgesIntersect(e, temp)) + return temp; + } + if(DBG_edgesIntersect(e, end)) + return end; + return NULL; +} + +//given a polygon, cut the edges off and finally obtain a +//a polygon without intersections. The cut-off edges are +//dealloated. The new polygon is returned. +directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur) +{ + directedLine *begin, *end, *next; + begin = polygon; + end = polygon; + cutOccur = 0; + while( (next = end->getNext()) != begin) + { + directedLine *interc = NULL; + if( (interc = DBG_edgeIntersectChainD(next, begin, end))) + { + int fixed = 0; + if(DBG_edgesIntersect(next, interc->getNext())) + { + //trying to fix it + Real buf[2]; + int i; + Int n=5; + buf[0] = interc->tail()[0]; + buf[1] = interc->tail()[1]; + + for(i=1; ihead()[0] + r * interc->tail()[0]; + Real v = (1-r) * interc->head()[1] + r * interc->tail()[1]; + interc->tail()[0] = interc->getNext()->head()[0] = u; + interc->tail()[1] = interc->getNext()->head()[1] = v; + if( (! DBG_edgesIntersect(next, interc)) && + (! DBG_edgesIntersect(next, interc->getNext()))) + break; //we fixed it + } + if(i==n) // we didn't fix it + { + fixed = 0; + //back to original + interc->tail()[0] = interc->getNext()->head()[0] = buf[0]; + interc->tail()[1] = interc->getNext()->head()[1] = buf[1]; + } + else + { + fixed = 1; + } + } + if(fixed == 0) + { + cutOccur = 1; + begin->deleteSingleLine(next); + + if(begin != end) + { + if(DBG_polygonSelfIntersect(begin)) + { + directedLine* newEnd = end->getPrev(); + begin->deleteSingleLine(end); + end = newEnd; + } + } + } + else + { + end = end->getNext(); + } + } + else + { + end = end->getNext(); + } + } + return begin; +} + +directedLine* DBG_cutIntersectionAllPoly(directedLine* list) +{ + directedLine* temp; + directedLine* tempNext=NULL; + directedLine* ret = NULL; + int cutOccur=0; + for(temp=list; temp != NULL; temp = tempNext) + { + directedLine *left; + tempNext = temp->getNextPolygon(); + + left = DBG_cutIntersectionPoly(temp, cutOccur); + if(left != NULL) + ret=left->insertPolygon(ret); + } + return ret; +} + +sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList) +{ + directedLine *temp; + sampledLine* tempHead = NULL; + sampledLine* tempTail = NULL; + sampledLine* cHead = NULL; + sampledLine* cTail = NULL; + + if(polygonList == NULL) + return NULL; + + DBG_collectSampledLinesPoly(polygonList, cHead, cTail); + + assert(cHead); + assert(cTail); + for(temp = polygonList->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) + { + DBG_collectSampledLinesPoly(temp, tempHead, tempTail); + cTail->insert(tempHead); + cTail = tempTail; + } + return cHead; +} + +void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail) +{ + directedLine *temp; + retHead = NULL; + retTail = NULL; + if(polygon == NULL) + return; + + retHead = retTail = polygon->getSampledLine(); + for(temp = polygon->getNext(); temp != polygon; temp=temp->getNext()) + { + retHead = temp->getSampledLine()->insert(retHead); + } +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/polyDBG.h b/project/jni/glu/src/libnurbs/nurbtess/polyDBG.h new file mode 100644 index 000000000..b68cd76a5 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/polyDBG.h @@ -0,0 +1,69 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _POLYDBG_H +#define _POLYDBG_H + +#include "definitions.h" +#include "directedLine.h" +#include "monoTriangulation.h" + +Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]); +Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]); + +Int DBG_edgesIntersect(directedLine* l1, directedLine* l2); +Int DBG_polygonSelfIntersect(directedLine* poly); +Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly); +Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2); +Int DBG_polygonListIntersect(directedLine* pList); + +Int DBG_isCounterclockwise(directedLine* poly); +Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]); +Int DBG_pointInsidePoly(Real v[2], directedLine* poly); +Int DBG_enclosingPolygons(directedLine* poly, directedLine* list); +void DBG_reverse(directedLine* poly); +Int DBG_check(directedLine *polyList); + +Int DBG_isConvex(directedLine *poly); +Int DBG_is_U_direction(directedLine *poly); +Int DBG_is_U_monotone(directedLine* poly); + +directedLine* DBG_cutIntersectionAllPoly(directedLine* list); +directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur); + +sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList); + +void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail); + +#endif /* _POLYDBG_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/polyUtil.cc b/project/jni/glu/src/libnurbs/nurbtess/polyUtil.cc new file mode 100644 index 000000000..65cf87301 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/polyUtil.cc @@ -0,0 +1,100 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include + +#include "polyUtil.h" + +Real area(Real A[2], Real B[2], Real C[2]) +{ + Real Bx, By, Cx, Cy; + Bx=B[0]-A[0]; + By=B[1]-A[1]; + Cx=C[0]-A[0]; + Cy=C[1]-A[1]; + + return Bx*Cy-Cx*By; +} + +/*given a directed line A->B, and a point P, + *determine whether P is to the left of AB. + *the line A->B (imagine it has beedn extended both + *end to the infinity) divides the plan into two + *half planes. When we walk from A to B, one + *half is to the left and the other half is to the right. + *return 1 if P is to the left. + *if P is on AB, 0 is returned. + */ + +Int pointLeftLine(Real A[2], Real B[2], Real P[2]) +{ + if (area(A, B, P)>0) + { + return 1; + } + else + { + return 0; + } +} + +/*given two directed line: A -> B -> C, and another point P. + *determine whether P is to the left hand side of A->B->C. + *Think of BA and BC extended as two rays. So that the plane is + * divided into two parts. One part is to the left we walk from A + *to B and to C, the other part is to the right. + * In order for P to be the left, P must be either to the left + *of + */ +Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2]) +{ + Int C_left_AB=(area(A, B, C)>0); + Int P_left_AB=(area(A, B, P)>0); + Int P_left_BC=(area(B, C, P)>0); + + if (C_left_AB) + { + return (P_left_AB && P_left_BC); + } + else + { + return (P_left_AB || P_left_BC); + } +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/polyUtil.h b/project/jni/glu/src/libnurbs/nurbtess/polyUtil.h new file mode 100644 index 000000000..5f1c6a108 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/polyUtil.h @@ -0,0 +1,53 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _POLYUTIL_H +#define _POLYUTIL_H + +#include "definitions.h" + +#ifdef __cplusplus +extern "C" { +#endif + +Real area(Real A[2], Real B[2], Real C[2]); + +Int pointLeftLine(Real A[2], Real B[2], Real P[2]); +Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2]); + +#ifdef __cplusplus +} +#endif + +#endif /* _POLYUTIL_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/primitiveStream.cc b/project/jni/glu/src/libnurbs/nurbtess/primitiveStream.cc new file mode 100644 index 000000000..2be7d72b4 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/primitiveStream.cc @@ -0,0 +1,147 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" + +#include +#include +#include + +#include "primitiveStream.h" + +Int primStream::num_triangles() +{ + Int i; + Int ret=0; + + for(i=0; i= size_vertices) { + Real* temp = (Real*) malloc (sizeof(Real) * (2*size_vertices + 2)); + assert(temp); + + /*copy*/ + for(Int i=0; i= size_lengths){ + Int* temp = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2)); + assert(temp); + Int* tempTypes = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2)); + assert(tempTypes); + + /*copy*/ + for(i=0; i +*/ + +/* we do not use the constans GL_... so that this file is independent of + * + */ + +#ifndef _PRIMITIVE_STREAM_H +#define _PRIMITIVE_STREAM_H + +enum {PRIMITIVE_STREAM_FAN, PRIMITIVE_STREAM_STRIP}; + +#include "definitions.h" + +class primStream +{ + Int* lengths; /* length[i]=number of vertices of ith primitive */ + Int* types; /* each primive has a type: FAN or STREAM */ + Real* vertices; /* the size >= 2 * num_vertices, each vertex (u,v) */ + + /*the following size information are used for dynamic arrays*/ + Int index_lengths; /* the current available entry*/ + Int size_lengths; /* the allocated size of the array: lengths*/ + Int index_vertices; + Int size_vertices; + + /*the vertex is inserted one by one. counter is used to + *count the number of vertices which have been inserted so far in + *the current primitive + */ + Int counter; + + public: + primStream(Int sizeLengths, Int sizeVertices); + ~primStream(); + + Int get_n_prims() // num of primitives + { + return index_lengths; + } + Int get_type(Int i) // the type of ith primitive + { + return types[i]; + } + Int get_length(Int i) // the length of the ith primitive + { + return lengths[i]; + } + Real* get_vertices() {return vertices;} + + /* the begining of inserting a new primitive. + * reset counter to be 0. + */ + void begin(); + void insert(Real u, Real v); + void insert(Real v[2]) {insert(v[0], v[1]);} + void end(Int type); + + Int num_triangles(); + + void triangle(Real A[2], Real B[2], Real C[2]) + { + begin(); + insert(A); + insert(B); + insert(C); + end(PRIMITIVE_STREAM_FAN); + } +}; + +#endif /* _PRIMITIVE_STREAM_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/quicksort.cc b/project/jni/glu/src/libnurbs/nurbtess/quicksort.cc new file mode 100644 index 000000000..6a8ae4a8a --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/quicksort.cc @@ -0,0 +1,78 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include + +static void swap(void *v[], int i, int j) +{ + void *temp; + temp = v[i]; + v[i] = v[j]; + v[j] = temp; +} + +/*as an example to use this function to + *sort integers, you need to supply the function + *int comp(int *i1, int *i2) + *{ + * if( *i1 < * i2) return -1; + * else return 1; + *} + *and an array of pointers to integers: + * int *v[100] (allocate space for where each v[i] points to). + *then you can call: + * quicksort( (void**)v, left, right, (int (*)(void *, void *))comp) + */ +void quicksort(void *v[], int left, int right, + int (*comp) (void *, void *)) +{ + int i, last; + if(left >= right) /*do nothing if array contains */ + return; /*fewer than two elements*/ + + swap(v, left, (left+right)/2); + last = left; + for(i=left+1; i<=right; i++) + if((*comp)(v[i], v[left])<0) + swap(v, ++last, i); + swap(v, left, last); + quicksort(v, left, last-1, comp); + quicksort(v, last+1, right, comp); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/quicksort.h b/project/jni/glu/src/libnurbs/nurbtess/quicksort.h new file mode 100644 index 000000000..cb9d53e76 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/quicksort.h @@ -0,0 +1,44 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _QUICKSORT_H +#define _QUICKSORT_H + +#include +#include + +void quicksort(void *v[], int left, int right, + int (*comp) (void *, void *)); + +#endif /* _QUICKSORT_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/rectBlock.cc b/project/jni/glu/src/libnurbs/nurbtess/rectBlock.cc new file mode 100644 index 000000000..663fa7a14 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/rectBlock.cc @@ -0,0 +1,140 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include "glues.h" +#include +#include +#include "glimports.h" +#include "zlassert.h" + +#include "rectBlock.h" + +rectBlock::rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline) +{ + Int i; + + + upGridLineIndex = left->getVlineIndex(beginVline); + + lowGridLineIndex = left->getVlineIndex(endVline); + + Int n = upGridLineIndex-lowGridLineIndex+1; //number of grid lines + leftIndices = (Int*) malloc(sizeof(Int) * n); + assert(leftIndices); + rightIndices = (Int*) malloc(sizeof(Int) * n); + assert(rightIndices); + for(i=0; igetInnerIndex(i+beginVline); + rightIndices[i] = right->getInnerIndex(i+beginVline); + } +} + + +rectBlock::~rectBlock() +{ + free(leftIndices); + free(rightIndices); +} + +Int rectBlock::num_quads() +{ + Int ret=0; + Int k,i; + for(k=0, i=upGridLineIndex; i>lowGridLineIndex; i--, k++) + { + ret += (rightIndices[k+1]-leftIndices[k+1]); + } + return ret; +} + +Int rectBlockArray::num_quads() +{ + Int ret=0; + for(Int i=0; inum_quads(); + return ret; +} + +rectBlockArray::rectBlockArray(Int s) +{ + Int i; + n_elements = 0; + size = s; + array = (rectBlock**) malloc(sizeof(rectBlock*) * s); + assert(array); +//initialization + for(i=0; i +*/ + +#ifndef _RECTBLOCK_H +#define _RECTBLOCK_H + +#include "definitions.h" +#include "gridWrap.h" + +class rectBlock +{ + Int upGridLineIndex; + Int lowGridLineIndex; + Int* leftIndices; // up to bottome + Int* rightIndices; // up to bottom + + public: + // the arrays are copies. + rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline); + ~rectBlock(); // free the two arrays + + Int get_upGridLineIndex() {return upGridLineIndex;} + Int get_lowGridLineIndex() {return lowGridLineIndex;} + Int* get_leftIndices() {return leftIndices;} + Int* get_rightIndices() {return rightIndices;} + + Int num_quads(); +}; + +class rectBlockArray +{ + rectBlock** array; + Int n_elements; + Int size; + + public: + rectBlockArray(Int s); + ~rectBlockArray(); // delete avarything including the blocks + + Int get_n_elements() {return n_elements;} + rectBlock* get_element(Int i) {return array[i];} + void insert(rectBlock* newBlock); // only take the pointer, not ther cotent + + Int num_quads(); +}; + +#endif /* _RECTBLOCK_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleComp.cc b/project/jni/glu/src/libnurbs/nurbtess/sampleComp.cc new file mode 100644 index 000000000..bccc110fe --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleComp.cc @@ -0,0 +1,358 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include "glimports.h" +#include "sampleComp.h" +#include "sampleCompTop.h" +#include "sampleCompBot.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + +void sampleConnectedComp(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream, + rectBlockArray* rbArray + ) +{ + + sampleCompLeft(topVertex, botVertex, + leftChain, + leftStartIndex, leftEndIndex, + rightChain, + rightStartIndex, rightEndIndex, + leftGridChain, + gridIndex1, + gridIndex2, + up_leftCornerWhere, + up_leftCornerIndex, + down_leftCornerWhere, + down_leftCornerIndex, + pStream); + + + sampleCompRight(topVertex, botVertex, + leftChain, + leftStartIndex, leftEndIndex, + rightChain, + rightStartIndex, + rightEndIndex, + rightGridChain, + gridIndex1, gridIndex2, + up_rightCornerWhere, + up_rightCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + + sampleCompTop(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + + sampleCompBot(botVertex, + leftChain, + leftEndIndex, + rightChain, + rightEndIndex, + leftGridChain, + rightGridChain, + gridIndex2, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + + //the center + + rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2)); + + +} + +/*notice that we need rightChain because the + *corners could be on the rightChain. + *here comp means component. + */ +void sampleCompLeft(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream) +{ + /*find out whether there is a trim vertex which is + *inbetween the top and bot grid lines or not. + */ + Int midIndex1; + Int midIndex2; + Int gridMidIndex1 = 0, gridMidIndex2 = 0; + //midIndex1: array[i] <= v, array[i-1] > v + //midIndex2: array[i] >= v, array[i+1] < v + // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1) + // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ?? + midIndex1 = leftChain->findIndexBelowGen( + leftGridChain->get_v_value(gridIndex1), + leftStartIndex, + leftEndIndex); + + midIndex2 = -1; /*initilization*/ + if(midIndex1<= leftEndIndex && gridIndex1getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2)) + { + midIndex2 = leftChain->findIndexAboveGen( + leftGridChain->get_v_value(gridIndex2), + midIndex1, //midIndex1 <= midIndex2. + leftEndIndex); + gridMidIndex1 = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1], + gridIndex1, gridIndex2); + gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1], + gridMidIndex1, gridIndex2); + } + + + /*to interprete the corner information*/ + Real* cornerTop; + Real* cornerBot; + Int cornerLeftStart; + Int cornerLeftEnd; + Int cornerRightUpEnd; + Int cornerRightDownStart; + if(up_leftCornerWhere == 0) /*left corner is on left chain*/ + { + cornerTop = leftChain->getVertex(up_leftCornerIndex); + cornerLeftStart = up_leftCornerIndex+1; + cornerRightUpEnd = -1; /*no right*/ + } + else if(up_leftCornerWhere == 1) /*left corner is on top*/ + { + cornerTop = topVertex; + cornerLeftStart = leftStartIndex; + cornerRightUpEnd = -1; /*no right*/ + } + else /*left corner is on right chain*/ + { + cornerTop = topVertex; + cornerLeftStart = leftStartIndex; + cornerRightUpEnd = up_leftCornerIndex; + } + + if(down_leftCornerWhere == 0) /*left corner is on left chain*/ + { + cornerBot = leftChain->getVertex(down_leftCornerIndex); + cornerLeftEnd = down_leftCornerIndex-1; + cornerRightDownStart = rightEndIndex+1; /*no right*/ + } + else if(down_leftCornerWhere == 1) /*left corner is on bot*/ + { + cornerBot = botVertex; + cornerLeftEnd = leftEndIndex; + cornerRightDownStart = rightEndIndex+1; /*no right*/ + } + else /*left corner is on the right chian*/ + { + cornerBot = botVertex; + cornerLeftEnd = leftEndIndex; + cornerRightDownStart = down_leftCornerIndex; + } + + /*sample*/ + if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/ + { + + sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1), + leftChain, + cornerLeftStart, + midIndex1-1, + leftGridChain, + gridIndex1, + gridMidIndex1, + rightChain, + rightStartIndex, + cornerRightUpEnd, + 0, //no right down section + -1, + pStream); + + sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2), + cornerBot, + leftChain, + midIndex2+1, + cornerLeftEnd, + leftGridChain, + gridMidIndex2, + gridIndex2, + rightChain, + 0, //no right up section + -1, + cornerRightDownStart, + rightEndIndex, + pStream); + + + sampleLeftStripRecF(leftChain, + midIndex1, + midIndex2, + leftGridChain, + gridMidIndex1, + gridMidIndex2, + pStream); + } + else + { + sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot, + leftChain, + cornerLeftStart, + cornerLeftEnd, + leftGridChain, + gridIndex1, + gridIndex2, + rightChain, + rightStartIndex, + cornerRightUpEnd, + cornerRightDownStart, + rightEndIndex, + pStream); + } +} + +void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridBoundaryChain* gridChain, + Int gridBeginIndex, + Int gridEndIndex, + vertexArray* rightChain, + Int rightUpBegin, + Int rightUpEnd, + Int rightDownBegin, + Int rightDownEnd, + primStream* pStream) +{ + Int i,j,k; + + /*creat an array to store all the up and down secments of the right chain, + *and the left end grid points + * + *although vertex array is a dynamic array, but to gain efficiency, + *it is better to initiliza the exact array size + */ + vertexArray vArray(gridEndIndex-gridBeginIndex+1 + + max(0,rightUpEnd - rightUpBegin+1)+ + max(0,rightDownEnd - rightDownBegin+1)); + + /*append the vertices on the up section of thr right chain*/ + for(i=rightUpBegin; i<= rightUpEnd; i++) + vArray.appendVertex(rightChain->getVertex(i)); + + /*append the vertices of the left extremal grid points, + *and at the same time, perform triangulation for the stair cases + */ + vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); + + for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + /*output the fan of the grid points of the (i)th and (i-1)th grid line. + */ + if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i-1)); + for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i)); + for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ + } + + /*then append all the vertices on the down section of the right chain*/ + for(i=rightDownBegin; i<= rightDownEnd; i++) + vArray.appendVertex(rightChain->getVertex(i)); + + monoTriangulationRecGen(topVert, botVert, + leftChain, leftStart, leftEnd, + &vArray, 0, vArray.getNumElements()-1, + pStream); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleComp.h b/project/jni/glu/src/libnurbs/nurbtess/sampleComp.h new file mode 100644 index 000000000..9c371776b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleComp.h @@ -0,0 +1,88 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLECOMP_H +#define _SAMPLECOMP_H + +#include "sampleMonoPoly.h" +#include "rectBlock.h" + +void sampleConnectedComp(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int botLeftIndex, + vertexArray* rightChain, + Int rightStartIndex, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream, + rectBlockArray* rbArray + ); + +void sampleCompLeft(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* leftGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream); + +void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridBoundaryChain* gridChain, + Int gridBegindex, + Int gridEndIndex, + vertexArray* rightChain, + Int rightUpBegin, + Int rightUpEnd, + Int rightDownBegin, + Int rightDownEnd, + primStream* pStream); + +#endif /* _SAMPLECOMP_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.cc b/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.cc new file mode 100644 index 000000000..3c0657e10 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.cc @@ -0,0 +1,653 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include "zlassert.h" +#include "sampleCompBot.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) + +//return: index_mono, index_pass +//from [pass, mono] is strictly U-monotone +//from [corner, pass] is = u +//if everybost is getVertex(i)[0] >= u) + break; + ret_index_pass = i; + if(ret_index_pass <= leftEnd) + { + for(i=ret_index_pass; i< leftEnd; i++) + { + if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0]) + break; + } + ret_index_mono = i; + } + +} + +void findBotRightSegment(vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass) +{ + Int i; + assert(rightCorner <= rightEnd); + for(i=rightCorner; i<= rightEnd; i++) + if(rightChain->getVertex(i)[0] <= u) + break; + + + + ret_index_pass = i; + + if(ret_index_pass <= rightEnd) + { + for(i=ret_index_pass; i< rightEnd; i++) + { + if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0]) + break; + } + ret_index_mono = i; + } +} + + +void sampleBotRightWithGridLinePost(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int segIndexMono, + Int segIndexPass, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the right of rightU + if(segIndexPass > rightCorner) //from corner to pass-1 is > u. + { + Real *tempBot; + if(segIndexPass <= rightEnd) //there is a point to the left of u + tempBot = rightChain->getVertex(segIndexPass); + else //nothing is to the left of u. + tempBot = botVertex; + Real tempTop[2]; + tempTop[0] = grid->get_u_value(rightU); + tempTop[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, tempBot, + rightChain, + rightCorner, + segIndexPass-1, + 0, // a decrease chain + pStream); + } + + //the possible section which is strictly Umonotone + if(segIndexPass <= rightEnd) //segIndex pass and mono exist + { + //if there are grid points which are to the left of botVertex + //then we should use botVertex to form a fan with these points to + //optimize the triangulation + int do_optimize = 1; + if(botVertex[0] <= grid->get_u_value(leftU)) + do_optimize = 0; + else + { + //we also have to make sure that botVertex is the left most vertex on the chain + int i; + for(i=segIndexMono; i<=rightEnd; i++) + if(rightChain->getVertex(i)[0] <= botVertex[0]) + { + do_optimize = 0; + break; + } + } + + if(do_optimize) + { + //find midU so that grid->get_u_value(midU) <= botVertex[0] + //and grid->get_u_value(midU) > botVertex[0] + int midU = leftU; + while(grid->get_u_value(midU) <= botVertex[0]) + { + midU++; + if(midU > rightU) + break; + } + midU--; + + grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream); + stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(midU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream); + } + else //not optimize + { + stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(leftU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream); + } + } + else //the botVertex forms a fan witht eh grid points + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); +} + +void sampleBotRightWithGridLine(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //if right chaain is empty, then there is only one bot vertex with + //one grid line + if(rightEndoutputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + return; + } + + Int segIndexMono=0, segIndexPass=0; + + findBotRightSegment(rightChain, + rightEnd, + rightCorner, + grid->get_u_value(rightU), + segIndexMono, + segIndexPass); + + sampleBotRightWithGridLinePost(botVertex, + rightChain, + rightEnd, + segIndexMono, + segIndexPass, + rightCorner, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +void sampleBotLeftWithGridLinePost(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int segIndexMono, + Int segIndexPass, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + + //the possible section which is to the left of leftU + if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU + { + Real *tempBot; + if(segIndexPass <= leftEnd) //from corner to pass-1 is getVertex(segIndexPass); + else //nothing is to the rigth of u + tempBot = botVertex; + Real tempTop[2]; + tempTop[0] = grid->get_u_value(leftU); + tempTop[1] = grid->get_v_value(gridV); + monoTriangulation2(tempTop, tempBot, leftChain, leftCorner, segIndexPass-1, + 1, //a increase chain, + pStream); + } + //the possible section which is strictly Umonotone + if(segIndexPass <= leftEnd) //segIndexpass and mono exist + { + stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1); + Real tempTop[2]; + tempTop[0] = grid->get_u_value(rightU); + tempTop[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd, + 1, //increase chain + pStream); + } + else //the botVertex forms a fan with the grid points + { + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + } + +} + +void sampleBotLeftWithGridLine(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + + //if leftChain is empty, then there is only one botVertex with one grid line + if(leftEnd< leftCorner){ + grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream); + return; + } + + Int segIndexPass=0, segIndexMono=0; + findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass); + + sampleBotLeftWithGridLinePost(botVertex, + leftChain, + leftEnd, + segIndexMono, + segIndexPass, + leftCorner, + grid, + gridV, + leftU, rightU, pStream); +} + +//return 1 if separator exists, 0 otherwise +Int findBotSeparator(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Int& ret_sep_left, + Int& ret_sep_right) +{ + Int oldLeftI, oldRightI, newLeftI, newRightI; + Int i,j,k; + Real leftMax /*= leftChain->getVertex(leftCorner)[0]*/; + Real rightMin /*= rightChain->getVertex(rightCorner)[0]*/; + if(leftChain->getVertex(leftCorner)[1] < rightChain->getVertex(rightCorner)[1])//leftlower + { + oldLeftI = leftCorner-1; + oldRightI = rightCorner; + leftMax = leftChain->getVertex(leftCorner)[0] - Real(1.0) ; //initilize to be left of leftCorner + rightMin = rightChain->getVertex(rightCorner)[0]; + } + else //rightlower + { + oldLeftI = leftCorner; + oldRightI = rightCorner-1; + leftMax = leftChain->getVertex(leftCorner)[0]; + rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0); + } + + //i: the current working leftChain Index + //j: the curent working right chian index + //if(left(i) is lower than right(j), then the two chains above right(j) are separated. + //else the two chains below left(i) are separated. + i = leftCorner; + j = rightCorner; + while(1) + { + newLeftI = oldLeftI; + newRightI = oldRightI; + if(i> leftEnd) //left chain is doen , go through remaining right chain + { + for(k=j+1; k<= rightEnd; k++) + { + if(rightChain->getVertex(k)[0] > leftMax) //no conflict + { + //update oldRightI if necessary + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + oldRightI = k; + } + } + else //there is a conflict + break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI + } + break; //the while loop + } + else if(j > rightEnd) //right Chain is doen + { + for(k=i+1; k<= leftEnd; k++) + { + if(leftChain->getVertex(k)[0] < rightMin) //no conflict + { + //update oldLeftI if necessary + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + oldLeftI = k; + } + } + else //there is a conflict + break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI + } + break; //the while loop + } + else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower + { + + if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI + { + leftMax = leftChain->getVertex(i)[0]; + newLeftI = i; + } + for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI; + { + if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower + break; + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + newRightI = k; + } + } + j = k; //next working j, since j will he lower than i in next loop + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + + } + } + else //right lower + { + if(rightChain->getVertex(j)[0] < rightMin) + { + rightMin = rightChain->getVertex(j)[0]; + newRightI = j; + } + for(k=i+1; k<= leftEnd; k++) + { + if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1]) + break; + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + newLeftI = k; + } + } + i=k; //nexct working i, since i will be lower than j next loop + if(leftMax >= rightMin) //there is conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + }//end of while loop + //now oldLeftI and oldRight I are the desired separator index notice that they are not + //necessarily valid + if(oldLeftI < leftCorner || oldRightI < rightCorner) + return 0; //no separator + else + { + ret_sep_left = oldLeftI; + ret_sep_right = oldRightI; + return 1; + } +} + +void sampleCompBot(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + + if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points + { + + leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + botVertex, + pStream); + return; + } + else if(down_leftCornerWhere != 0) + { + + Real* tempBot; + Int tempRightEnd; + if(down_leftCornerWhere == 1){ + tempRightEnd = rightEnd; + tempBot = botVertex; + } + else + { + tempRightEnd = down_leftCornerIndex-1; + tempBot = rightChain->getVertex(down_leftCornerIndex); + } + + sampleBotRightWithGridLine(tempBot, + rightChain, + tempRightEnd, + down_rightCornerIndex, + rightGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream); + } + else if(down_rightCornerWhere != 2) + { + + Real* tempBot; + Int tempLeftEnd; + if(down_rightCornerWhere == 1){ + tempLeftEnd = leftEnd; + tempBot = botVertex; + } + else //right corner is on left chain + { + tempLeftEnd = down_rightCornerIndex-1; + tempBot = leftChain->getVertex(down_rightCornerIndex); + } + + + sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex), + leftGridChain->getUlineIndex(gridIndex), + rightGridChain->getUlineIndex(gridIndex), + pStream); + + } + else //down_leftCornereWhere == 0, down_rightCornerwhere == 2 + { + sampleCompBotSimple(botVertex, + leftChain, + leftEnd, + rightChain, + rightEnd, + leftGridChain, + rightGridChain, + gridIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream); + + return; + }//end id 0 2 +}//end if the functin + +void sampleCompBotSimple(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + //the plan is to use monotriangulation algorithm. + Int i,k; + Real* ActualTop; + Real* ActualBot; + Int ActualLeftStart, ActualLeftEnd; + Int ActualRightStart, ActualRightEnd; + + //creat an array to store the points on the grid line + gridWrap* grid = leftGridChain->getGrid(); + Int gridV = leftGridChain->getVlineIndex(gridIndex); + Int gridLeftU = leftGridChain->getUlineIndex(gridIndex); + Int gridRightU = rightGridChain->getUlineIndex(gridIndex); + Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1)); + assert(gridPoints); + + for(k=0, i=gridRightU; i>= gridLeftU; i--, k++) + { + gridPoints[k][0] = grid->get_u_value(i); + gridPoints[k][1] = grid->get_v_value(gridV); + } + + if(down_rightCornerWhere != 0) //rightCorner is not on lef + ActualLeftEnd = leftEnd; + else + ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot + + if(down_leftCornerWhere != 0) //left corner is not on let chian + ActualLeftStart = leftEnd+1; //meaning that there is no actual left section + else + ActualLeftStart = down_leftCornerIndex; + + vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1); + + for(i=0; igetVertex(i)); + + //determine ActualRightStart + if(down_rightCornerWhere != 2) //right is not on right + ActualRightStart = rightEnd +1; //meaning no section on right + else + ActualRightStart = down_rightCornerIndex; + + //determine actualrightEnd + if(down_leftCornerWhere != 2) //left is not on right + { + + ActualRightEnd = rightEnd; + } + else //left corner is on right + { + ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot + + } + + //actual bot + if(down_rightCornerWhere == 2) + { + if(down_leftCornerWhere == 2) + ActualBot = rightChain->getVertex(down_leftCornerIndex); + else + ActualBot = botVertex; + } + else if(down_rightCornerWhere == 1) //right corner bot + ActualBot = botVertex; + else //down_rightCornerWhere == 0 + ActualBot = leftChain->getVertex(down_rightCornerIndex); + + ActualTop = gridPoints[0]; + if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1]) + monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart), + ActualBot, + &ActualLeftChain, + 0, + ActualLeftChain.getNumElements()-1, + rightChain, + ActualRightStart+1, + ActualRightEnd, + pStream); + else + monoTriangulationRecGenOpt(ActualTop, ActualBot, + &ActualLeftChain, + 1, //the first one is the top vertex + ActualLeftChain.getNumElements()-1, + rightChain, + ActualRightStart, + ActualRightEnd, + pStream); + free(gridPoints); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.h b/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.h new file mode 100644 index 000000000..814fb8194 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompBot.h @@ -0,0 +1,140 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLECOMPBOT_H +#define _SAMPLECOMPBOT_H + +#include "sampleMonoPoly.h" + +void findBotLeftSegment(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass); + +void findBotRightSegment(vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Real u, + Int& ret_index_mono, + Int& ret_index_pass); + + +void sampleBotRightWithGridLinePost(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int segIndexMono, + Int segIndexPass, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotRightWithGridLine(Real* botVertex, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotLeftWithGridLinePost(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int segIndexMono, + Int segIndexPass, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +void sampleBotLeftWithGridLine(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream); + + +Int findBotSeparator(vertexArray* leftChain, + Int leftEnd, + Int leftCorner, + vertexArray* rightChain, + Int rightEnd, + Int rightCorner, + Int& ret_sep_left, + Int& ret_sep_right); + +void sampleCompBot(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream); + +void sampleCompBotSimple(Real* botVertex, + vertexArray* leftChain, + Int leftEnd, + vertexArray* rightChain, + Int rightEnd, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream); + +#endif /* _SAMPLECOMPBOT_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.cc b/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.cc new file mode 100644 index 000000000..66625f06b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.cc @@ -0,0 +1,633 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include + +#include "glues.h" +#include "glimports.h" +#include "zlassert.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) +#define min(a,b) ((a>b)? b:a) + + + +#ifdef NOT_TAKEOUT + +/*notice that we need leftChain because the + *corners could be on the leftChain. + */ +void sampleCompRight(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + Int down_rightCornerWhere, + Int down_rightCornerIndex, + primStream* pStream) +{ + /*find out whether there is a trim vertex which is + *inbetween the top and bot grid lines or not. + */ + Int midIndex1; + Int midIndex2; + Int gridMidIndex1 = 0, gridMidIndex2 = 0; + //midIndex1: array[i] <= v, array[i+1] > v + //midIndex2: array[i] >= v, array[i+1] < v + midIndex1 = rightChain->findIndexBelowGen(rightGridChain->get_v_value(gridIndex1), + rightStartIndex, + rightEndIndex); + midIndex2 = -1; //initilization + if(midIndex1 <= rightEndIndex && gridIndex1 < gridIndex2) + if(rightChain->getVertex(midIndex1)[1] >= rightGridChain->get_v_value(gridIndex2)) + { + //midIndex2 must exist: + midIndex2 = rightChain->findIndexAboveGen(rightGridChain->get_v_value(gridIndex2), + midIndex1, //midIndex1<=midIndex2 + rightEndIndex); + //find gridMidIndex1 so that either it=gridIndex1 when the gridline is + // at the same height as trim vertex midIndex1, or it is the last one + //which is strictly above midIndex1. + { + Real temp = rightChain->getVertex(midIndex1)[1]; + if(rightGridChain->get_v_value(gridIndex1) == temp) + gridMidIndex1 = gridIndex1; + else + { + gridMidIndex1 = gridIndex1; + while(rightGridChain->get_v_value(gridMidIndex1) > temp) + gridMidIndex1++; + gridMidIndex1--; + } + }//end of find gridMindIndex1 + //find gridMidIndex2 so that it is the (first one below or equal + //midIndex) last one above or equal midIndex2 + { + Real temp = rightChain->getVertex(midIndex2)[1]; + for(gridMidIndex2 = gridMidIndex1+1; gridMidIndex2 <= gridIndex2; gridMidIndex2++) + if(rightGridChain->get_v_value(gridMidIndex2) <= temp) + break; + + assert(gridMidIndex2 <= gridIndex2); + }//end of find gridMidIndex2 + } + + //to interprete the corner information + Real* cornerTop; + Real* cornerBot; + Int cornerRightStart; + Int cornerRightEnd; + Int cornerLeftUpEnd; + Int cornerLeftDownStart; + if(up_rightCornerWhere == 2) //right corner is on right chain + { + cornerTop = rightChain->getVertex(up_rightCornerIndex); + cornerRightStart = up_rightCornerIndex+1; + cornerLeftUpEnd = -1; //no left + } + else if(up_rightCornerWhere == 1) //right corner is on top + { + cornerTop = topVertex; + cornerRightStart = rightStartIndex; + cornerLeftUpEnd = -1; //no left + } + else //right corner is on left chain + { + cornerTop = topVertex; + cornerRightStart = rightStartIndex; + cornerLeftUpEnd = up_rightCornerIndex; + } + + if(down_rightCornerWhere == 2) //right corner is on right chan + { + cornerBot = rightChain->getVertex(down_rightCornerIndex); + cornerRightEnd = down_rightCornerIndex-1; + cornerLeftDownStart = leftEndIndex+1; //no left + } + else if (down_rightCornerWhere == 1) //right corner is at bot + { + cornerBot = botVertex; + cornerRightEnd = rightEndIndex; + cornerLeftDownStart = leftEndIndex+1; //no left + } + else //right corner is on the left chain + { + cornerBot = botVertex; + cornerRightEnd = rightEndIndex; + cornerLeftDownStart = down_rightCornerIndex; + } + + //sample + if(midIndex2 >= 0) //there is a trm point between grid lines + { + + sampleRightSingleTrimEdgeRegionGen(cornerTop, rightChain->getVertex(midIndex1), + rightChain, + cornerRightStart, + midIndex1-1, + rightGridChain, + gridIndex1, + gridMidIndex1, + leftChain, + leftStartIndex, + cornerLeftUpEnd, + 0, //no left down section, + -1, + pStream); + + sampleRightSingleTrimEdgeRegionGen(rightChain->getVertex(midIndex2), + cornerBot, + rightChain, + midIndex2+1, + cornerRightEnd, + rightGridChain, + gridMidIndex2, + gridIndex2, + leftChain, + 0, //no left up section + -1, + cornerLeftDownStart, + leftEndIndex, + pStream); + + sampleRightStripRecF(rightChain, + midIndex1, + midIndex2, + rightGridChain, + gridMidIndex1, + gridMidIndex2, + pStream); + + } + else + { + sampleRightSingleTrimEdgeRegionGen(cornerTop, cornerBot, + rightChain, + cornerRightStart, + cornerRightEnd, + rightGridChain, + gridIndex1, + gridIndex2, + leftChain, + leftStartIndex, + cornerLeftUpEnd, + cornerLeftDownStart, + leftEndIndex, + pStream); + } +} + +void sampleRightSingleTrimEdgeRegionGen(Real topVertex[2], Real botVertex[2], + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridBoundaryChain* gridChain, + Int gridBeginIndex, + Int gridEndIndex, + vertexArray* leftChain, + Int leftUpBegin, + Int leftUpEnd, + Int leftDownBegin, + Int leftDownEnd, + primStream* pStream) +{ + Int i,k; + /*creat an array to store all the up and down secments of the left chain, + *and the right end grid points + * + *although vertex array is a dynamic array, but to gain efficiency, + *it is better to initiliza the exact array size + */ + vertexArray vArray(gridEndIndex-gridBeginIndex+1 + + max(0,leftUpEnd - leftUpBegin+1)+ + max(0,leftDownEnd - leftDownBegin+1)); + //append the vertices on the up section of the left chain + for(i=leftUpBegin; i<= leftUpEnd; i++) + vArray.appendVertex(leftChain->getVertex(i)); + + //append the vertices of the right extremal grid points, + //and at the same time, perform triangulation for the stair cases + vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); + + for(k=1, i=gridBeginIndex+1; i<= gridEndIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + //output the fan of the grid points of the (i)th and (i-1)th grid line. + gridChain->rightEndFan(i, pStream); + } + + //append all the vertices on the down section of the left chain + for(i=leftDownBegin; i<= leftDownEnd; i++) + vArray.appendVertex(leftChain->getVertex(i)); + monoTriangulationRecGen(topVertex, botVertex, + &vArray, 0, vArray.getNumElements()-1, + rightChain, rightStart, rightEnd, + pStream); +} + +void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream) +{ + Int i,k; + vertexArray vArray(endIndex-beginIndex+1); + vArray.appendVertex(gridChain->get_vertex(beginIndex)); + for(k=1, i=beginIndex+1; i<= endIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + //output the fan of the grid points of the (i)_th and i-1th gridLine + gridChain->rightEndFan(i, pStream); + } + monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, + 1, //increase chain (to the left) + pStream); +} + + +/*the gridlines from rightGridChainStartIndex to + *rightGridChainEndIndex are assumed to form a + *connected componenet + *the trm vertex of topRightIndex is assumed to be below + *or equal the first gridLine, and the trm vertex of + *botRightIndex is assumed to be above or equal the last gridline + **there could be multipe trm vertices equal to the last gridline, but + **only one could be equal to top gridline. shape: ____| (recall that + **for left chain recF, we allow shape: |---- + *if botRightIndex= topRightIndex, there is at least one triangles to + *output + */ +void sampleRightStripRecF(vertexArray* rightChain, + Int topRightIndex, + Int botRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + Int rightGridChainEndIndex, + primStream* pStream + ) +{ + + //sstop conditionL: if topRightIndex > botRightIndex, then stop + if(topRightIndex > botRightIndex) + return; + + //if there is only one grid line, return + if(rightGridChainStartIndex >= rightGridChainEndIndex) + return; + + + assert(rightChain->getVertex(topRightIndex)[1] <= rightGridChain->get_v_value(rightGridChainStartIndex) && + rightChain->getVertex(botRightIndex)[1] >= rightGridChain->get_v_value(rightGridChainEndIndex)); + + //firstfind the first trim vertex which is strictly below the second top + //grid line: index1. + Real secondGridChainV = rightGridChain->get_v_value(rightGridChainStartIndex+1); + Int index1 = topRightIndex; + while(rightChain->getVertex(index1)[1] >= secondGridChainV){ + index1++; + if(index1 > botRightIndex) + break; + } + //now rightChain->getVertex(index1-1)[1] >= secondGridChainV and + //rightChain->getVertex(index1)[1] < secondGridChainV and + //we should include index1-1 to perform a gridStep + index1--; + + //now we have rightChain->getVertex(index1)[1] >= secondGridChainV, and + //rightChain->getVertex(index1+1)[1] < secondGridChainV + sampleRightOneGridStep(rightChain, topRightIndex, index1, rightGridChain, rightGridChainStartIndex, pStream); + + //if rightChain->getVertex(index1)[1] ==secondGridChainV then we can + //recurvesively to the rest + if(rightChain->getVertex(index1)[1] == secondGridChainV) + { + sampleRightStripRecF(rightChain, index1, botRightIndex, rightGridChain, rightGridChainStartIndex+1, rightGridChainEndIndex, pStream); + } + else if(index1 < botRightIndex) + { + //otherwise, we have rightChain->getVertex(index1)[1] > secondV + //let the next trim vertex be nextTrimVertex, (which should be strictly + //below the second grid line). Find the last grid line index2 which is STRICTLY ABOVE + //nextTrimVertex. + //sample one trm edge region. + Real *uppervert, *lowervert; + uppervert = rightChain->getVertex(index1); + lowervert = rightChain->getVertex(index1+1); //okay since index1get_v_value(index2) > lowervert[1]) + { + index2++; + if(index2 > rightGridChainEndIndex) + break; + } + index2--; + + sampleRightSingleTrimEdgeRegion(uppervert, lowervert, rightGridChain, rightGridChainStartIndex+1, index2, pStream); + + //recursion + sampleRightStripRecF(rightChain, index1+1, botRightIndex, rightGridChain, index2, rightGridChainEndIndex, pStream); + } +} + +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream) +{ + /*since there is no middle, there is at most one point which is on the + *second grid line, there could be multiple points on the first (top) + *grid line. + */ + rightGridChain->rightEndFan(rightGridChainStartIndex+1, pStream); + monoTriangulation2(rightGridChain->get_vertex(rightGridChainStartIndex), + rightGridChain->get_vertex(rightGridChainStartIndex+1), + rightChain, + beginRightIndex, + endRightIndex, + 0, //decrease chain + pStream); +} + +//sampling the right area in between two grid lines +//shape: _________| +void sampleRightOneGridStep(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream) +{ + if(checkMiddle(rightChain, beginRightIndex, endRightIndex, + rightGridChain->get_v_value(rightGridChainStartIndex), + rightGridChain->get_v_value(rightGridChainStartIndex+1))<0) + { + sampleRightOneGridStepNoMiddle(rightChain, beginRightIndex, endRightIndex, rightGridChain, rightGridChainStartIndex, pStream); + return; + } + + //copy into a polygn + { + directedLine* poly = NULL; + sampledLine* sline; + directedLine* dline; + gridWrap* grid = rightGridChain->getGrid(); + float vert1[2]; + float vert2[2]; + Int i; + + Int innerInd = rightGridChain->getInnerIndex(rightGridChainStartIndex+1); + Int upperInd = rightGridChain->getUlineIndex(rightGridChainStartIndex); + Int lowerInd = rightGridChain->getUlineIndex(rightGridChainStartIndex+1); + Real upperV = rightGridChain->get_v_value(rightGridChainStartIndex); + Real lowerV = rightGridChain->get_v_value(rightGridChainStartIndex+1); + + //the upper gridline + vert1[1]=vert2[1]=upperV; + for(i=upperInd; + i>innerInd; + i--) + { + vert1[0]=grid->get_u_value(i); + vert2[0]=grid->get_u_value(i-1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + } + + //the vertical grid line segment + vert1[0]=vert2[0] = grid->get_u_value(innerInd); + vert1[1]=upperV; + vert2[1]=lowerV; + sline=new sampledLine(vert1, vert2); + dline=new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + + //the lower grid line + vert1[1]=vert2[1]=lowerV; + for(i=innerInd; iget_u_value(i); + vert2[0] = grid->get_u_value(i+1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting lower grid to right chain + vert1[0]=grid->get_u_value(lowerInd); + sline = new sampledLine(vert1, rightChain->getVertex(endRightIndex)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + + //the right Chain + for(i=endRightIndex; i>beginRightIndex; i--) + { + sline = new sampledLine(rightChain->getVertex(i), rightChain->getVertex(i-1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting right chain with upper grid + vert2[1]=upperV; + vert2[0]=grid->get_u_value(upperInd); + sline = new sampledLine(rightChain->getVertex(beginRightIndex), vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + monoTriangulationOpt(poly, pStream); + //clean up + poly->deleteSinglePolygonWithSline(); + + return; + } + + //this following code cannot be reached, but leave it for debuggig purpose. + Int i; + //find the maximal U-monotone chain of beginRightIndex, beginRightIndex+1,... + i=beginRightIndex; + Real prevU = rightChain->getVertex(i)[0]; + for(i=beginRightIndex+1; i<= endRightIndex; i++){ + Real thisU = rightChain->getVertex(i)[0]; + if(thisU < prevU) + prevU = thisU; + else + break; + } + //from beginRightIndex to i-1 is strictly U-monotne + //if(i-1==beginRightIndex and the vertex of rightchain is on the first + //gridline, then we should use 2 vertices on the right chain. Of we only + //use one (begin), we would output degenrate triangles. + if(i-1 == beginRightIndex && rightChain->getVertex(beginRightIndex)[1] == rightGridChain->get_v_value(rightGridChainStartIndex)) + i++; + + Int j = endRightIndex -1; + if(rightGridChain->getInnerIndex(rightGridChainStartIndex+1) < rightGridChain->getUlineIndex(rightGridChainStartIndex+1)) + { + j = rightChain->findDecreaseChainFromEnd(i-1/*beginRightIndex*/, endRightIndex); + Int temp = endRightIndex; + //now from j+1 to end is strictly U-monotone. + //if j+1 is on the last grid line, then we wat to skip to the vertex + //whcih is strictly above the second grid line. This vertex must exist + //since there is a middle vertex + if(j+1 == endRightIndex) + { + while(rightChain->getVertex(j+1)[1] == rightGridChain->get_v_value(rightGridChainStartIndex+1)) + j--; + + monoTriangulation2(rightChain->getVertex(j+1), + rightGridChain->get_vertex(rightGridChainStartIndex+1), + rightChain, + j+2, + endRightIndex, + 0, //a decrease chain + pStream); + + temp = j+1; + } + + stripOfFanRight(rightChain, temp, j+1, rightGridChain->getGrid(), + rightGridChain->getVlineIndex(rightGridChainStartIndex+1), + rightGridChain->getInnerIndex(rightGridChainStartIndex+1), + rightGridChain->getUlineIndex(rightGridChainStartIndex+1), + pStream, + 0 //the grid line is below the trim line + ); + + } + + + stripOfFanRight(rightChain, i-1, beginRightIndex, rightGridChain->getGrid(), + rightGridChain->getVlineIndex(rightGridChainStartIndex), + rightGridChain->getInnerIndex(rightGridChainStartIndex+1), + rightGridChain->getUlineIndex(rightGridChainStartIndex), + pStream, + 1 //the grid line is above the trm lines + ); + + //monotone triangulate the remaining rightchain together with the + //two vertices on the two grid v-lines + Real vert[2][2]; + vert[0][0] = vert[1][0] = rightGridChain->getInner_u_value(rightGridChainStartIndex+1); + vert[0][1] = rightGridChain->get_v_value(rightGridChainStartIndex); + vert[1][1] = rightGridChain->get_v_value(rightGridChainStartIndex+1); + + monoTriangulation2(&vert[0][0], + &vert[1][0], + rightChain, + i-1, + j+1, + 0, ///a decreae chain + pStream); +} + +#endif + +void stripOfFanRight(vertexArray* rightChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if the grid line is above the trim lines*/ + ) +{ + assert(largeIndex >= smallIndex); + + Real grid_v_value; + grid_v_value = grid->get_v_value(vlineIndex); + + Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); + assert(trimVerts); + + + Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); + assert(gridVerts); + + Int k,i; + if(! gridLineUp) /*trim line is above grid line, so trim vertices are going right when index increases*/ + for(k=0, i=smallIndex; i<=largeIndex; i++, k++) + { + trimVerts[k][0] = rightChain->getVertex(i)[0]; + trimVerts[k][1] = rightChain->getVertex(i)[1]; + } + else + for(k=0, i=largeIndex; i>=smallIndex; i--, k++) + { + trimVerts[k][0] = rightChain->getVertex(i)[0]; + trimVerts[k][1] = rightChain->getVertex(i)[1]; + } + + for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) + { + gridVerts[k][0] = grid->get_u_value(i); + gridVerts[k][1] = grid_v_value; + } + + if(gridLineUp) + triangulateXYMono( + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + largeIndex-smallIndex+1, trimVerts, + pStream); + else + triangulateXYMono(largeIndex-smallIndex+1, trimVerts, + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + pStream); + free(trimVerts); + free(gridVerts); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.h b/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.h new file mode 100644 index 000000000..ad9af071c --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompRight.h @@ -0,0 +1,117 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLECOMPRIGHT_H +#define _SAMPLECOMPRIGHT_H + +#define NOT_TAKEOUT + +#include "sampleMonoPoly.h" +void stripOfFanRight(vertexArray* rightChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if grid line is above the trim lines */ + ); + +#ifdef NOT_TAKEOUT +void sampleRightStripRecF(vertexArray* rightChain, + Int topRightIndex, + Int botRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + Int rightGridChainEndIndex, + primStream* pStream + ); +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); +//sampling the right area in between two grid lines +//shape: _________| +void sampleRightOneGridStep(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); +void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream); +//the degenerate case of sampleRightOneGridStep +void sampleRightOneGridStepNoMiddle(vertexArray* rightChain, + Int beginRightIndex, + Int endRightIndex, + gridBoundaryChain* rightGridChain, + Int rightGridChainStartIndex, + primStream* pStream); + +void sampleCompRight(Real* topVertex, Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, Int rightEndIndex, + gridBoundaryChain* rightGridChain, + Int gridIndex1, Int gridIndex2, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int down_leftCornerWhere, + Int down_leftCornerIndex, + primStream* pStream); + +void sampleRightSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridBoundaryChain* gridChain, + Int gridBegindex, + Int gridEndIndex, + vertexArray* leftChain, + Int leftUpBegin, + Int leftUpEnd, + Int leftDownBegin, + Int leftDownEnd, + primStream* pStream); +#endif + +#endif /* _SAMPLECOMPRIGHT_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.cc b/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.cc new file mode 100644 index 000000000..d49cdbff7 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.cc @@ -0,0 +1,802 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include +#include "zlassert.h" +#include "sampleCompTop.h" +#include "sampleCompRight.h" + +#define max(a,b) ((a>b)? a:b) + +//return : index_small, and index_large, +//from [small, large] is strictly U-monotne, +//from [large+1, end] is = u +//if eveybody is = leftStart; i--) + { + if(leftChain->getVertex(i)[0] >= u) + break; + } + ret_index_large = i; + if(ret_index_large >= leftStart) + { + for(i=ret_index_large; i>leftStart; i--) + { + if(leftChain->getVertex(i-1)[0] <= leftChain->getVertex(i)[0]) + break; + } + ret_index_small = i; + } +} + +void findTopRightSegment(vertexArray* rightChain, + Int rightStart, + Int rightEnd, + Real u, + Int& ret_index_small, + Int& ret_index_large) +{ + Int i; + assert(rightStart<=rightEnd); + for(i=rightEnd; i>=rightStart; i--) + { + if(rightChain->getVertex(i)[0] <= u) + break; + } + ret_index_large = i; + if(ret_index_large >= rightStart) + { + for(i=ret_index_large; i>rightStart;i--) + { + if(rightChain->getVertex(i-1)[0] >= rightChain->getVertex(i)[0]) + break; + } + ret_index_small = i; + } +} + + +void sampleTopRightWithGridLinePost(Real* topVertex, + vertexArray* rightChain, + Int rightStart, + Int segIndexSmall, + Int segIndexLarge, + Int rightEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the right of rightU + if(segIndexLarge < rightEnd) + { + Real *tempTop; + if(segIndexLarge >= rightStart) + tempTop = rightChain->getVertex(segIndexLarge); + else + tempTop = topVertex; + Real tempBot[2]; + tempBot[0] = grid->get_u_value(rightU); + tempBot[1] = grid->get_v_value(gridV); +monoTriangulationRecGenOpt(tempTop, tempBot, + NULL, 1,0, + rightChain, segIndexLarge+1, rightEnd, + pStream); +/* + monoTriangulation2(tempTop, tempBot, + rightChain, + segIndexLarge+1, + rightEnd, + 0, //a decrease chian + pStream); +*/ + + } + + //the possible section which is strictly Umonotone + if(segIndexLarge >= rightStart) + { + stripOfFanRight(rightChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(leftU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, rightChain, rightStart, segIndexSmall, 0, pStream); + } + else //the topVertex forms a fan with the grid points + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); +} + +void sampleTopRightWithGridLine(Real* topVertex, + vertexArray* rightChain, + Int rightStart, + Int rightEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream + ) +{ + //if right chian is empty, then there is only one topVertex with one grid line + if(rightEnd < rightStart){ + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); + return; + } + + Int segIndexSmall=0, segIndexLarge=0; + findTopRightSegment(rightChain, + rightStart, + rightEnd, + grid->get_u_value(rightU), + segIndexSmall, + segIndexLarge + ); + sampleTopRightWithGridLinePost(topVertex, rightChain, + rightStart, + segIndexSmall, + segIndexLarge, + rightEnd, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +void sampleTopLeftWithGridLinePost(Real* topVertex, + vertexArray* leftChain, + Int leftStart, + Int segIndexSmall, + Int segIndexLarge, + Int leftEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream) +{ + //the possible section which is to the left of leftU + + if(segIndexLarge < leftEnd) + { + Real *tempTop; + if(segIndexLarge >= leftStart) + tempTop = leftChain->getVertex(segIndexLarge); + else + tempTop = topVertex; + Real tempBot[2]; + tempBot[0] = grid->get_u_value(leftU); + tempBot[1] = grid->get_v_value(gridV); + + monoTriangulation2(tempTop, tempBot, + leftChain, + segIndexLarge+1, + leftEnd, + 1, //a increase chian + pStream); + } + + //the possible section which is strictly Umonotone + if(segIndexLarge >= leftStart) + { + //if there are grid points which are to the right of topV, + //then we should use topVertex to form a fan with these points to + //optimize the triangualtion + int do_optimize=1; + if(topVertex[0] >= grid->get_u_value(rightU)) + do_optimize = 0; + else + { + //we also have to make sure that topVertex are the right most vertex + //on the chain. + int i; + for(i=leftStart; i<=segIndexSmall; i++) + if(leftChain->getVertex(i)[0] >= topVertex[0]) + { + do_optimize = 0; + break; + } + } + + if(do_optimize) + { + //find midU so that grid->get_u_value(midU) >= topVertex[0] + //and grid->get_u_value(midU-1) < topVertex[0] + int midU=rightU; + while(grid->get_u_value(midU) >= topVertex[0]) + { + midU--; + if(midU < leftU) + break; + } + midU++; + + grid->outputFanWithPoint(gridV, midU, rightU, topVertex, pStream); + stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, midU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(midU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); + } + else //not optimize + { + + stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0); + Real tempBot[2]; + tempBot[0] = grid->get_u_value(rightU); + tempBot[1] = grid->get_v_value(gridV); + monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream); + } + } + else //the topVertex forms a fan with the grid points + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); +} + +void sampleTopLeftWithGridLine(Real* topVertex, + vertexArray* leftChain, + Int leftStart, + Int leftEnd, + gridWrap* grid, + Int gridV, + Int leftU, + Int rightU, + primStream* pStream + ) +{ + Int segIndexSmall=0, segIndexLarge=0; + //if left chain is empty, then there is only one top vertex with one grid + // line + if(leftEnd < leftStart) { + grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream); + return; + } + findTopLeftSegment(leftChain, + leftStart, + leftEnd, + grid->get_u_value(leftU), + segIndexSmall, + segIndexLarge + ); + sampleTopLeftWithGridLinePost(topVertex, + leftChain, + leftStart, + segIndexSmall, + segIndexLarge, + leftEnd, + grid, + gridV, + leftU, + rightU, + pStream); +} + + +//return 1 if saprator exits, 0 otherwise +Int findTopSeparator(vertexArray* leftChain, + Int leftStartIndex, + Int leftEndIndex, + vertexArray* rightChain, + Int rightStartIndex, + Int rightEndIndex, + Int& ret_sep_left, + Int& ret_sep_right) +{ + Int oldLeftI, oldRightI, newLeftI, newRightI; + Int i,j,k; + Real leftMax /*= leftChain->getVertex(leftEndIndex)[0]*/; + Real rightMin /*= rightChain->getVertex(rightEndIndex)[0]*/; + if(leftChain->getVertex(leftEndIndex)[1] > rightChain->getVertex(rightEndIndex)[1]) //left higher + { + oldLeftI = leftEndIndex+1; + oldRightI = rightEndIndex; + leftMax = leftChain->getVertex(leftEndIndex)[0] - Real(1.0); //initilza to left of leftU + rightMin = rightChain->getVertex(rightEndIndex)[0]; + } + else + { + oldLeftI = leftEndIndex; + oldRightI = rightEndIndex+1; + leftMax = leftChain->getVertex(leftEndIndex)[0]; + rightMin = rightChain->getVertex(rightEndIndex)[0] + Real(1.0); + } + + //i: the current working leftChain index, + //j: the current working rightChain index, + //if left(i) is higher than right(j), then the two chains beloew right(j) are separated. + //else the two chains below left(i) are separeated. + i=leftEndIndex; + j=rightEndIndex; + while(1) + { + newLeftI = oldLeftI; + newRightI = oldRightI; + + if(i= rightStartIndex; k--) + { + if(rightChain->getVertex(k)[0] > leftMax) //no conflict + { + //update oldRightI if necessary + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + oldRightI = k; + } + } + else //there is a conflict + break; //the for-loop. below right(k-1) is seperated: oldLeftI, oldRightI. + } + break; //the while loop + } + else if(j= leftStartIndex; k--) + { + if(leftChain->getVertex(k)[0] < rightMin) //no conflict + { + //update oldLeftI if necessary + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + oldLeftI = k; + } + } + else //there is a conflict + break; //the for loop + } + break; //the while loop + } + else if(leftChain->getVertex(i)[1] > rightChain->getVertex(j)[1]) //left hgiher + { + if(leftChain->getVertex(i)[0] > leftMax) //update leftMax and newLeftI. + { + leftMax = leftChain->getVertex(i)[0]; + newLeftI = i; + } + for(k=j-1; k>= rightStartIndex; k--) //update rightMin and newRightI. + { + if(rightChain->getVertex(k)[1] > leftChain->getVertex(i)[1]) + break; + if(rightChain->getVertex(k)[0] < rightMin) + { + rightMin = rightChain->getVertex(k)[0]; + newRightI = k; + } + } + j = k; //next working j, since j will be higher than i in next loop + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + else //right higher + { + if(rightChain->getVertex(j)[0] < rightMin) + { + rightMin = rightChain->getVertex(j)[0]; + newRightI = j; + } + for(k=i-1; k>= leftStartIndex; k--) + { + if(leftChain->getVertex(k)[1] > rightChain->getVertex(j)[1]) + break; + if(leftChain->getVertex(k)[0] > leftMax) + { + leftMax = leftChain->getVertex(k)[0]; + newLeftI = k; + } + } + i = k; //next working i, since i will be higher than j next loop + + if(leftMax >= rightMin) //there is a conflict + break; + else //still no conflict + { + oldLeftI = newLeftI; + oldRightI = newRightI; + } + } + }//end of while loop + //now oldLeftI and oldRightI are the desired separeator index, notice that there are not necessarily valid + if(oldLeftI > leftEndIndex || oldRightI > rightEndIndex) + return 0; + else + { + ret_sep_left = oldLeftI; + ret_sep_right = oldRightI; + return 1; + } +} + + +void sampleCompTop(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream) +{ + if(up_leftCornerWhere == 1 && up_rightCornerWhere == 1) //the top is topVertex with possible grid points + { + leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + topVertex, + pStream); + return; + } + + else if(up_leftCornerWhere != 0) + { + Real* tempTop; + Int tempRightStart; + if(up_leftCornerWhere == 1){ + tempRightStart = rightStartIndex; + tempTop = topVertex; + } + else + { + tempRightStart = up_leftCornerIndex+1; + tempTop = rightChain->getVertex(up_leftCornerIndex); + } + sampleTopRightWithGridLine(tempTop, rightChain, tempRightStart, up_rightCornerIndex, + rightGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream); + } + else if(up_rightCornerWhere != 2) + { + Real* tempTop; + Int tempLeftStart; + if(up_rightCornerWhere == 1) + { + tempLeftStart = leftStartIndex; + tempTop = topVertex; + } + else //0 + { + tempLeftStart = up_rightCornerIndex+1; + tempTop = leftChain->getVertex(up_rightCornerIndex); + } +/* + sampleTopLeftWithGridLine(tempTop, leftChain, tempLeftStart, up_leftCornerIndex, + leftGridChain->getGrid(), + leftGridChain->getVlineIndex(gridIndex1), + leftGridChain->getUlineIndex(gridIndex1), + rightGridChain->getUlineIndex(gridIndex1), + pStream); +*/ + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + } + else //up_leftCornerWhere == 0, up_rightCornerWhere == 2. + { + sampleCompTopSimple(topVertex, + leftChain, + leftStartIndex, + rightChain, + rightStartIndex, + leftGridChain, + rightGridChain, + gridIndex1, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + pStream); + return; + }//end if 0,2 +}//end if the function + + +static void sampleCompTopSimpleOpt(gridWrap* grid, + Int gridV, + Real* topVertex, Real* botVertex, + vertexArray* inc_chain, Int inc_current, Int inc_end, + vertexArray* dec_chain, Int dec_current, Int dec_end, + primStream* pStream) +{ + if(gridV <= 0 || dec_endget_v_value(gridV+1) >= topVertex[1]) + { + monoTriangulationRecGenOpt(topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + return; + } + Int i,j,k; + Real currentV = grid->get_v_value(gridV+1); + if(inc_chain->getVertex(inc_end)[1] <= currentV && + dec_chain->getVertex(dec_end)[1] < currentV) + { + //find i bottom up so that inc_chain[i]<= curentV and inc_chain[i-1] > currentV, + //find j botom up so that dec_chain[j] < currentV and dec_chain[j-1] >= currentV + for(i=inc_end; i >= inc_current; i--) + { + if(inc_chain->getVertex(i)[1] > currentV) + break; + } + i++; + for(j=dec_end; j >= dec_current; j--) + { + if(dec_chain->getVertex(j)[1] >= currentV) + break; + } + j++; + if(inc_chain->getVertex(i)[1] <= dec_chain->getVertex(j)[1]) + { + //find the k so that dec_chain[k][1] < inc_chain[i][1] + for(k=j; k<=dec_end; k++) + { + if(dec_chain->getVertex(k)[1] < inc_chain->getVertex(i)[1]) + break; + } + //we know that dec_chain[j][1] >= inc_chian[i][1] + //we know that dec_chain[k-1][1]>=inc_chain[i][1] + //we know that dec_chian[k][1] < inc_chain[i][1] + //find l in [j, k-1] so that dec_chain[l][0] 0 is closest to + // inc_chain[i] + int l; + Real tempI = Real(j); + Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); + for(l=j+1; l<= k-1; l++) + { + if(fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]) + <= tempMin) + { + tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]); + tempI = (Real)l; + } + } + //inc_chain[i] and dec_chain[tempI] are connected. + monoTriangulationRecGenOpt(dec_chain->getVertex((int)tempI), + botVertex, + inc_chain, i, inc_end, + dec_chain, (int)(tempI+1), dec_end, + pStream); + //recursively do the rest + sampleCompTopSimpleOpt(grid, + gridV+1, + topVertex, inc_chain->getVertex(i), + inc_chain, inc_current, i-1, + dec_chain, dec_current, (int)tempI, + pStream); + } + else + { + //find the k so that inc_chain[k][1] <= dec_chain[j][1] + for(k=i; k<=inc_end; k++) + { + if(inc_chain->getVertex(k)[1] <= dec_chain->getVertex(j)[1]) + break; + } + //we know that inc_chain[i] > dec_chain[j] + //we know that inc_chain[k-1][1] > dec_chain[j][1] + //we know that inc_chain[k][1] <= dec_chain[j][1] + //so we find l between [i,k-1] so that + //inc_chain[l][0] is the closet to dec_chain[j][0] + int tempI = i; + int l; + Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]); + for(l=i+1; l<=k-1; l++) + { + if(fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]) <= tempMin) + { + tempMin = (Real)fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]); + tempI = l; + } + } + + //inc_chain[tempI] and dec_chain[j] are connected + + monoTriangulationRecGenOpt(inc_chain->getVertex(tempI), + botVertex, + inc_chain, tempI+1, inc_end, + dec_chain, j, dec_end, + pStream); + + //recurvesily do the rest + sampleCompTopSimpleOpt(grid, gridV+1, + topVertex, dec_chain->getVertex(j), + inc_chain, inc_current, tempI, + dec_chain, dec_current, j-1, + pStream); + } + } + else //go to the next higher gridV + { + sampleCompTopSimpleOpt(grid, + gridV+1, + topVertex, botVertex, + inc_chain, inc_current, inc_end, + dec_chain, dec_current, dec_end, + pStream); + } +} + +void sampleCompTopSimple(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream) +{ + //the plan is to use monotriangulation algortihm. + Int i,k; + Real* ActualTop; + Real* ActualBot; + Int ActualLeftStart, ActualLeftEnd; + Int ActualRightStart, ActualRightEnd; + + //creat an array to store the points on the grid line + gridWrap* grid = leftGridChain->getGrid(); + Int gridV = leftGridChain->getVlineIndex(gridIndex1); + Int gridLeftU = leftGridChain->getUlineIndex(gridIndex1); + Int gridRightU = rightGridChain->getUlineIndex(gridIndex1); + + Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1)); + assert(gridPoints); + + for(k=0, i=gridRightU; i>= gridLeftU; i--, k++) + { + gridPoints[k][0] = grid->get_u_value(i); + gridPoints[k][1] = grid->get_v_value(gridV); + } + + if(up_leftCornerWhere != 2) + ActualRightStart = rightStartIndex; + else + ActualRightStart = up_leftCornerIndex+1; //up_leftCornerIndex will be the ActualTop + + if(up_rightCornerWhere != 2) //right corner is not on right chain + ActualRightEnd = rightStartIndex-1; //meaning that there is no actual rigth section + else + ActualRightEnd = up_rightCornerIndex; + + vertexArray ActualRightChain(max(0, ActualRightEnd-ActualRightStart+1) + gridRightU-gridLeftU+1); + + for(i=ActualRightStart; i<= ActualRightEnd; i++) + ActualRightChain.appendVertex(rightChain->getVertex(i)); + for(i=0; igetVertex(up_rightCornerIndex); + else + ActualTop = topVertex; + } + else if(up_leftCornerWhere == 1) + ActualTop = topVertex; + else // up_leftCornerWhere == 2 + ActualTop = rightChain->getVertex(up_leftCornerIndex); + + ActualBot = gridPoints[gridRightU - gridLeftU]; + + if(leftChain->getVertex(ActualLeftEnd)[1] == ActualBot[1]) + { + sampleCompTopSimpleOpt(grid, gridV, + ActualTop, leftChain->getVertex(ActualLeftEnd), + leftChain, + ActualLeftStart, ActualLeftEnd-1, + &ActualRightChain, + 0, + ActualRightChain.getNumElements()-1, + pStream); + + } + else + { + sampleCompTopSimpleOpt(grid, gridV, + ActualTop, ActualBot, leftChain, + ActualLeftStart, ActualLeftEnd, + &ActualRightChain, + 0, ActualRightChain.getNumElements()-2, //the last is the bot. + pStream); + } + + free(gridPoints); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.h b/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.h new file mode 100644 index 000000000..d594e4482 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleCompTop.h @@ -0,0 +1,69 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLECOMPTOP_H +#define _SAMPLECOMPTOP_H + +#include "sampleMonoPoly.h" + +void sampleCompTop(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream); + +void sampleCompTopSimple(Real* topVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridIndex1, + Int up_leftCornerWhere, + Int up_leftCornerIndex, + Int up_rightCornerWhere, + Int up_rightCornerIndex, + primStream* pStream); + +#endif /* _SAMPLECOMPTOP_H */ + diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.cc b/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.cc new file mode 100644 index 000000000..f75d7ca62 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.cc @@ -0,0 +1,2230 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include + +#ifndef max +#define max(a,b) ((a>b)? a:b) +#endif +#ifndef min +#define min(a,b) ((a>b)? b:a) +#endif + +#include "glues.h" + +#include "glimports.h" +#include "zlassert.h" +#include "sampleMonoPoly.h" +#include "sampleComp.h" +#include "polyDBG.h" +#include "partitionX.h" + +#define ZERO 0.00001 + +//#define SHORTEN_GRID_LINE +//see work/newtess/internal/test/problems + + +/*split a polygon so that each vertex correcpond to one edge + *the head of the first edge of the returned plygon must be the head of the first + *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function + */ + directedLine* polygonConvert(directedLine* polygon) +{ + int i; + directedLine* ret; + sampledLine* sline; + sline = new sampledLine(2); + sline->setPoint(0, polygon->getVertex(0)); + sline->setPoint(1, polygon->getVertex(1)); + ret=new directedLine(INCREASING, sline); + for(i=1; i<= polygon->get_npoints()-2; i++) + { + sline = new sampledLine(2); + sline->setPoint(0, polygon->getVertex(i)); + sline->setPoint(1, polygon->getVertex(i+1)); + ret->insert(new directedLine(INCREASING, sline)); + } + + for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext()) + { + for(i=0; i<= temp->get_npoints()-2; i++) + { + sline = new sampledLine(2); + sline->setPoint(0, temp->getVertex(i)); + sline->setPoint(1, temp->getVertex(i+1)); + ret->insert(new directedLine(INCREASING, sline)); + } + } + return ret; +} + +void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream) +{ + Int i,j; + Int n_leftVerts; + Int n_rightVerts; + Real** leftVerts; + Real** rightVerts; + directedLine* tempV; + n_leftVerts = 0; + for(tempV = topV; tempV != botV; tempV = tempV->getNext()) + { + n_leftVerts += tempV->get_npoints(); + } + n_rightVerts=0; + for(tempV = botV; tempV != topV; tempV = tempV->getNext()) + { + n_rightVerts += tempV->get_npoints(); + } + + Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts); + assert(temp_leftVerts); + Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts); + assert(temp_rightVerts); + + leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts); + assert(leftVerts); + rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts); + assert(rightVerts); + for(i=0; igetNext()) + { + for(j=1; jget_npoints(); j++) + { + leftVerts[i][0] = tempV->getVertex(j)[0]; + leftVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + n_leftVerts = i; + i=0; + for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev()) + { + for(j=tempV->get_npoints()-1; j>=1; j--) + { + rightVerts[i][0] = tempV->getVertex(j)[0]; + rightVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + n_rightVerts = i; + triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream); + free(leftVerts); + free(rightVerts); + free(temp_leftVerts); + free(temp_rightVerts); +} + +void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream) +{ + Int i,j; + Int n_lowerVerts; + Int n_upperVerts; + Real2 *lowerVerts; + Real2 *upperVerts; + directedLine* tempV; + n_lowerVerts=0; + for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) + { + n_lowerVerts += tempV->get_npoints(); + } + n_upperVerts=0; + for(tempV = rightV; tempV != leftV; tempV = tempV->getNext()) + { + n_upperVerts += tempV->get_npoints(); + } + lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts); + assert(n_lowerVerts); + upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts); + assert(n_upperVerts); + i=0; + for(tempV = leftV; tempV != rightV; tempV = tempV->getNext()) + { + for(j=0; jget_npoints(); j++) + { + lowerVerts[i][0] = tempV->getVertex(j)[0]; + lowerVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + i=0; + for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev()) + { + for(j=tempV->get_npoints()-1; j>=0; j--) + { + upperVerts[i][0] = tempV->getVertex(j)[0]; + upperVerts[i][1] = tempV->getVertex(j)[1]; + i++; + } + } + triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream); + free(lowerVerts); + free(upperVerts); +} +void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream) +{ + /*find left, right, top , bot + */ + directedLine* tempV; + directedLine* topV; + directedLine* botV; + directedLine* leftV; + directedLine* rightV; + topV = botV = polygon; + + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + + botV = tempV; + } + } + //find leftV + for(tempV = topV; tempV != botV; tempV = tempV->getNext()) + { + if(tempV->tail()[0] >= tempV->head()[0]) + break; + } + leftV = tempV; + //find rightV + for(tempV = botV; tempV != topV; tempV = tempV->getNext()) + { + if(tempV->tail()[0] <= tempV->head()[0]) + break; + } + rightV = tempV; + if(vlinear) + { + triangulateConvexPolyHoriz( leftV, rightV, pStream); + } + else if(ulinear) + { + triangulateConvexPolyVertical(topV, botV, pStream); + } + else + { + if(DBG_is_U_direction(polygon)) + { + triangulateConvexPolyHoriz( leftV, rightV, pStream); + } + else + triangulateConvexPolyVertical(topV, botV, pStream); + } +} + +void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain) +{ + Int i; + directedLine* tempV; + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + leftChain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + leftChain.appendVertex(tempV->getVertex(i)); + } + } + + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } +} + + +void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV) +{ + assert(polygon); + directedLine* tempV; + topV = botV = polygon; + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + botV = tempV; + } + } +} + +void findGridChains(directedLine* topV, directedLine* botV, + gridWrap* grid, + gridBoundaryChain*& leftGridChain, + gridBoundaryChain*& rightGridChain) +{ + /*find the first(top) and the last (bottom) grid line which intersect the + *this polygon + */ + Int firstGridIndex; /*the index in the grid*/ + Int lastGridIndex; + + firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); + + if(botV->head()[1] < grid->get_v_min()) + lastGridIndex = 0; + else + lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; + + /*find the interval inside the polygon for each gridline*/ + Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridIndices); + Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridIndices); + Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridInnerIndices); + Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridInnerIndices); + + findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); + + findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); + + leftGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); + + rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); + + free(leftGridIndices); + free(rightGridIndices); + free(leftGridInnerIndices); + free(rightGridInnerIndices); +} + +void findDownCorners(Real *botVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ + Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ + ) +{ + assert(v > botVertex[1]); + Real leftGridPoint[2]; + leftGridPoint[0] = uleft; + leftGridPoint[1] = v; + Real rightGridPoint[2]; + rightGridPoint[0] = uright; + rightGridPoint[1] = v; + + Int i; + Int index1, index2; + + index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex); + index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex); + + if(index2 <= rightChainEndIndex) //index2 was found above + index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); + + if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/ + { + + /*the botVertex is the only vertex below v*/ + ret_leftCornerWhere = 1; + ret_rightCornerWhere = 1; + } + else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/ + { + + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + + + Real tempMin = rightChain->getVertex(index2)[0]; + Int tempI = index2; + for(i=index2+1; i<= rightChainEndIndex; i++) + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + + + //we consider whether we can use botVertex as left corner. First check + //if (leftGirdPoint, botVertex) interesects right chian or not. + if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex, + leftGridPoint, botVertex)) + { + ret_leftCornerWhere = 2;//right + ret_leftCornerIndex = index2; //should use tempI??? + } + else if(botVertex[0] < tempMin) + ret_leftCornerWhere = 1; //bot + else + { + ret_leftCornerWhere = 2; //right + ret_leftCornerIndex = tempI; + } + } + else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/ + { + ret_leftCornerWhere = 0; /*left chain*/ + ret_leftCornerIndex = index1; + + /*find the vertex on the left chain with the maximum u, + *either this vertex or the botvertex can be used as the right corner + */ + + Int tempI; + //skip those points which are equal to v. (avoid degeneratcy) + for(tempI = index1; tempI <= leftChainEndIndex; tempI++) + if(leftChain->getVertex(tempI)[1] < v) + break; + if(tempI > leftChainEndIndex) + ret_rightCornerWhere = 1; + else + { + Real tempMax = leftChain->getVertex(tempI)[0]; + for(i=tempI; i<= leftChainEndIndex; i++) + if(leftChain->getVertex(i)[0] > tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + + + + //we consider whether we can use botVertex as a corner. So first we check + //whether (rightGridPoint, botVertex) interescts the left chain or not. + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, + rightGridPoint, botVertex)) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; //should use tempI??? + } + else if(botVertex[0] > tempMax) + { + + ret_rightCornerWhere = 1; + } + else + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = tempI; + } + } + + } + else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/ + { + if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/ + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + + Real tempMax; + Int tempI; + + tempI = index1; + tempMax = leftChain->getVertex(index1)[0]; + + /*find the maximum u for all the points on the left above the right point index2*/ + for(i=index1+1; i<= leftChainEndIndex; i++) + { + if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1]) + break; + + if(leftChain->getVertex(i)[0]>tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + } + //we consider if we can use rightChain(index2) as right corner + //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not. + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; //should use tempI??? + } + else if(tempMax >= rightChain->getVertex(index2)[0] || + tempMax >= uright + ) + { + + ret_rightCornerWhere = 0; /*on left Chain*/ + ret_rightCornerIndex = tempI; + } + else + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + } + } + else /*left below right*/ + { + ret_rightCornerWhere = 2; /*on the right*/ + ret_rightCornerIndex = index2; + + Real tempMin; + Int tempI; + + tempI = index2; + tempMin = rightChain->getVertex(index2)[0]; + + /*find the minimum u for all the points on the right above the left poitn index1*/ + for(i=index2+1; i<= rightChainEndIndex; i++) + { + if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1]) + break; + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + } + + //we consider if we can use leftchain(index1) as left corner. + //we check if (leftChain(index1) intersects right chian or not + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1))) + { + ret_leftCornerWhere = 2; + ret_leftCornerIndex = index2; //should use tempI??? + } + else if(tempMin <= leftChain->getVertex(index1)[0] || + tempMin <= uleft) + { + ret_leftCornerWhere = 2; /* on right chain*/ + ret_leftCornerIndex = tempI; + } + else + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + } + } + } + +} + + +void findUpCorners(Real *topVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/ + Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/ + Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/ + ) +{ + assert(v < topVertex[1]); + Real leftGridPoint[2]; + leftGridPoint[0] = uleft; + leftGridPoint[1] = v; + Real rightGridPoint[2]; + rightGridPoint[0] = uright; + rightGridPoint[1] = v; + + Int i; + Int index1, index2; + + index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex); + + + index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex); + + if(index2>= leftChainStartIndex) //index2 was found above + index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex); + + if(index1= rightChainStartIndex*/ + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + + //find the minimum u on right top, either that, or top, or right[index2] is the left corner + Real tempMin = rightChain->getVertex(index2)[0]; + Int tempI = index2; + for(i=index2-1; i>=rightChainStartIndex; i--) + if(rightChain->getVertex(i)[0] < tempMin) + { + tempMin = rightChain->getVertex(i)[0]; + tempI = i; + } + //chech whether (leftGridPoint, top) intersects rightchai, + //if yes, use right corner as left corner + //if not, use top or right[tempI] as left corner + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, + leftGridPoint, topVertex)) + { + ret_leftCornerWhere = 2; //rightChain + ret_leftCornerIndex = index2; + } + else if(topVertex[0] < tempMin) + ret_leftCornerWhere = 1; /*topvertex*/ + else + { + ret_leftCornerWhere = 2; //right chain + ret_leftCornerIndex = tempI; + } + + } + else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/ + { + ret_leftCornerWhere = 0; /*left chain*/ + ret_leftCornerIndex = index1; + + //find the maximum u on the left top section. either that or topvertex, or left[index1] is the right corner + Real tempMax = leftChain->getVertex(index1)[0]; + Int tempI = index1; + + for(i=index1-1; i>=leftChainStartIndex; i--){ + + if(leftChain->getVertex(i)[0] > tempMax) + { + + tempMax = leftChain->getVertex(i)[0]; + tempI = i; + } + } + //check whether (rightGridPoint, top) intersects leftChain or not + //if yes, we use leftCorner as the right corner + //if not, we use either top or left[tempI] as the right corner + if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, + rightGridPoint, topVertex)) + { + ret_rightCornerWhere = 0; //left chan + ret_rightCornerIndex = index1; + } + else if(topVertex[0] > tempMax) + ret_rightCornerWhere = 1;//topVertex + else + { + ret_rightCornerWhere = 0;//left chain + ret_rightCornerIndex = tempI; + } + } + else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/ + { + if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/ + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + + Real tempMax; + Int tempI; + + tempI = index1; + tempMax = leftChain->getVertex(index1)[0]; + + /*find the maximum u for all the points on the left below the right point index2*/ + for(i=index1-1; i>= leftChainStartIndex; i--) + { + if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1]) + break; + + if(leftChain->getVertex(i)[0]>tempMax) + { + tempI = i; + tempMax = leftChain->getVertex(i)[0]; + } + } + //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not + if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2))) + { + ret_rightCornerWhere = 0; + ret_rightCornerIndex = index1; + } + else if(tempMax >= rightChain->getVertex(index2)[0] || + tempMax >= uright) + { + ret_rightCornerWhere = 0; /*on left Chain*/ + ret_rightCornerIndex = tempI; + } + else + { + ret_rightCornerWhere = 2; /*on right chain*/ + ret_rightCornerIndex = index2; + } + } + else /*left above right*/ + { + ret_rightCornerWhere = 2; /*on the right*/ + ret_rightCornerIndex = index2; + + Real tempMin; + Int tempI; + + tempI = index2; + tempMin = rightChain->getVertex(index2)[0]; + + /*find the minimum u for all the points on the right below the left poitn index1*/ + for(i=index2-1; i>= rightChainStartIndex; i--) + { + if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1]) + break; + if(rightChain->getVertex(i)[0] < tempMin) + { + tempI = i; + tempMin = rightChain->getVertex(i)[0]; + } + } + //check whether (leftGRidPoint,left(index1)) interesect right chain + if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, + leftGridPoint, leftChain->getVertex(index1))) + { + ret_leftCornerWhere = 2; //right + ret_leftCornerIndex = index2; + } + else if(tempMin <= leftChain->getVertex(index1)[0] || + tempMin <= uleft) + { + ret_leftCornerWhere = 2; /* on right chain*/ + ret_leftCornerIndex = tempI; + } + else + { + ret_leftCornerWhere = 0; /*on left chain*/ + ret_leftCornerIndex = index1; + } + } + } +} + +//return 1 if neck exists, 0 othewise +Int findNeckF(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + Int& neckLeft, + Int& neckRight) +{ + + Int lowerGridIndex; //the grid below leftChain and rightChian vertices + Int i; + Int n_vlines = leftGridChain->get_nVlines(); + Real v; + if(botLeftIndex >= leftChain->getNumElements() || + botRightIndex >= rightChain->getNumElements()) + return 0; //no neck exists + + v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]); + + for(i=gridStartIndex; iget_v_value(i) <= v && + leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i)) + break; + + lowerGridIndex = i; + + if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines + return 0; + else + { + Int botLeft2, botRight2; + + botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ; + + botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1; + if(botRight2 < botRightIndex) botRight2=botRightIndex; + + if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex; + + assert(botLeft2 >= botLeftIndex); + assert(botRight2 >= botRightIndex); + //find nectLeft so that it is th erightmost vertex on letChain + + Int tempI = botLeftIndex; + Real temp = leftChain->getVertex(tempI)[0]; + for(i=botLeftIndex+1; i<= botLeft2; i++) + if(leftChain->getVertex(i)[0] > temp) + { + temp = leftChain->getVertex(i)[0]; + tempI = i; + } + neckLeft = tempI; + + tempI = botRightIndex; + temp = rightChain->getVertex(tempI)[0]; + for(i=botRightIndex+1; i<= botRight2; i++) + if(rightChain->getVertex(i)[0] < temp) + { + temp = rightChain->getVertex(i)[0]; + tempI = i; + } + neckRight = tempI; + return 1; + } +} + + + +/*find i>=botLeftIndex,j>=botRightIndex so that + *(leftChain[i], rightChain[j]) is a neck. + */ +void findNeck(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + Int& leftLastIndex, /*left point of the neck*/ + Int& rightLastIndex /*right point of the neck*/ + ) +{ + assert(botLeftIndex < leftChain->getNumElements() && + botRightIndex < rightChain->getNumElements()); + + /*now the neck exists for sure*/ + + if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right + { + + leftLastIndex = botLeftIndex; + + /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1< + */ + rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1); + } + else //left above right + { + + rightLastIndex = botRightIndex; + + leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1], + botLeftIndex+1, + leftChain->getNumElements()-1); + } +} + + + +void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) +{ + + Int i,k,isHoriz = 0; + Int n_ulines = grid->get_n_ulines(); + Real uMin = grid->get_u_min(); + Real uMax = grid->get_u_max(); + /* + Real vMin = grid->get_v_min(); + Real vMax = grid->get_v_max(); + */ + Real slop = 0.0, uinterc; + +#ifdef SHORTEN_GRID_LINE + //uintercBuf stores all the interction u value for each grid line + //notice that lastGridIndex<= firstGridIndex + Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); + assert(uintercBuf); +#endif + + /*initialization to make vtail bigger than grid->...*/ + directedLine* dLine = topEdge; + Real vtail = grid->get_v_value(firstGridIndex) + 1.0f; + Real tempMaxU = grid->get_u_min(); + + + /*for each grid line*/ + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + + Real grid_v_value = grid->get_v_value(i); + + /*check whether this grid line is below the current trim edge.*/ + if(vtail > grid_v_value) + { + /*since the grid line is below the trim edge, we + *find the trim edge which will contain the trim line + */ + while( (vtail=dLine->tail()[1]) > grid_v_value){ + + tempMaxU = max(tempMaxU, dLine->tail()[0]); + dLine = dLine -> getNext(); + } + + if( fabs(dLine->head()[1] - vtail) < ZERO) + isHoriz = 1; + else + { + isHoriz = 0; + slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail); + } + } + + if(isHoriz) + { + uinterc = max(dLine->head()[0], dLine->tail()[0]); + } + else + { + uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0]; + } + + tempMaxU = max(tempMaxU, uinterc); + + if(uinterc < uMin && uinterc >= uMin - ZERO) + uinterc = uMin; + if(uinterc > uMax && uinterc <= uMax + ZERO) + uinterc = uMax; + +#ifdef SHORTEN_GRID_LINE + uintercBuf[k] = uinterc; +#endif + + assert(uinterc >= uMin && uinterc <= uMax); + if(uinterc == uMax) + ret_indices[k] = n_ulines-1; + else + ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; + if(ret_indices[k] >= n_ulines) + ret_indices[k] = n_ulines-1; + + + ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1; + + /*reinitialize tempMaxU for next grdiLine*/ + tempMaxU = uinterc; + } +#ifdef SHORTEN_GRID_LINE + //for each grid line, compare the left grid point with the + //intersection point. If the two points are too close, then + //we should move the grid point one grid to the right + //and accordingly we should update the inner index. + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + //check gridLine i + //check ret_indices[k] + Real a = grid->get_u_value(ret_indices[k]-1); + Real b = grid->get_u_value(ret_indices[k]); + assert(uintercBuf[k] >= a && uintercBuf < b); + if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b + { + ret_indices[k]++; + } + + //check ret_innerIndices[k] + if(k>0) + { + if(ret_innerIndices[k] < ret_indices[k-1]) + ret_innerIndices[k] = ret_indices[k-1]; + if(ret_innerIndices[k] < ret_indices[k]) + ret_innerIndices[k] = ret_indices[k]; + } + } + //clean up + free(uintercBuf); +#endif +} + +void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices) +{ + + Int i,k; + Int n_ulines = grid->get_n_ulines(); + Real uMin = grid->get_u_min(); + Real uMax = grid->get_u_max(); + /* + Real vMin = grid->get_v_min(); + Real vMax = grid->get_v_max(); + */ + Real slop = 0.0, uinterc; + +#ifdef SHORTEN_GRID_LINE + //uintercBuf stores all the interction u value for each grid line + //notice that firstGridIndex >= lastGridIndex + Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1)); + assert(uintercBuf); +#endif + + /*initialization to make vhead bigger than grid->v_value...*/ + directedLine* dLine = topEdge->getPrev(); + Real vhead = dLine->tail()[1]; + Real tempMinU = grid->get_u_max(); + + /*for each grid line*/ + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + + Real grid_v_value = grid->get_v_value(i); + + + /*check whether this grid line is below the current trim edge.*/ + if(vhead >= grid_v_value) + { + /*since the grid line is below the tail of the trim edge, we + *find the trim edge which will contain the trim line + */ + while( (vhead=dLine->head()[1]) > grid_v_value){ + tempMinU = min(tempMinU, dLine->head()[0]); + dLine = dLine -> getPrev(); + } + + /*skip the equality in the case of degenerat case: horizontal */ + while(dLine->head()[1] == grid_v_value) + dLine = dLine->getPrev(); + + assert( dLine->tail()[1] != dLine->head()[1]); + slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]); + /* + if(dLine->tail()[1] == vhead) + isHoriz = 1; + else + { + isHoriz = 0; + slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead); + } + */ + } + uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0]; + + //in case unterc is outside of the grid due to floating point + if(uinterc < uMin) + uinterc = uMin; + else if(uinterc > uMax) + uinterc = uMax; + +#ifdef SHORTEN_GRID_LINE + uintercBuf[k] = uinterc; +#endif + + tempMinU = min(tempMinU, uinterc); + + assert(uinterc >= uMin && uinterc <= uMax); + + if(uinterc == uMin) + ret_indices[k] = 0; + else + ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; + + ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1; + + tempMinU = uinterc; + } +#ifdef SHORTEN_GRID_LINE + //for each grid line, compare the left grid point with the + //intersection point. If the two points are too close, then + //we should move the grid point one grid to the right + //and accordingly we should update the inner index. + for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++) + { + //check gridLine i + //check ret_indices[k] + Real a = grid->get_u_value(ret_indices[k]); + Real b = grid->get_u_value(ret_indices[k]+1); + assert(uintercBuf[k] > a && uintercBuf <= b); + if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a + { + ret_indices[k]--; + } + + //check ret_innerIndices[k] + if(k>0) + { + if(ret_innerIndices[k] > ret_indices[k-1]) + ret_innerIndices[k] = ret_indices[k-1]; + if(ret_innerIndices[k] > ret_indices[k]) + ret_innerIndices[k] = ret_indices[k]; + } + } + //clean up + free(uintercBuf); +#endif +} + + +void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray) +{ +if(grid->get_n_ulines() == 2 || + grid->get_n_vlines() == 2) +{ + if(ulinear && grid->get_n_ulines() == 2) + { + monoTriangulationFun(polygon, compV2InY, pStream); + return; + } + else if(DBG_isConvex(polygon) && polygon->numEdges() >=4) + { + triangulateConvexPoly(polygon, ulinear, vlinear, pStream); + return; + } + else if(vlinear || DBG_is_U_direction(polygon)) + { + Int n_cusps;//num interior cusps + Int n_edges = polygon->numEdges(); + directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges); + assert(cusps); + findInteriorCuspsX(polygon, n_cusps, cusps); + + if(n_cusps == 0) //u_monotone + { + + monoTriangulationFun(polygon, compV2InX, pStream); + + free(cusps); + return; + } + else if(n_cusps == 1) //one interior cusp + { + + directedLine* new_polygon = polygonConvert(cusps[0]); + + directedLine* other = findDiagonal_singleCuspX( new_polygon); + + + + // should NOT be null unless there are self-intersecting + //trim curves. In that case, we don't want to core dump, instead, + // we triangulate anyway, and print out error message. + if(other == NULL) + { + monoTriangulationFun(polygon, compV2InX, pStream); + free(cusps); + return; + } + + directedLine* ret_p1; + directedLine* ret_p2; + + new_polygon->connectDiagonal_2slines(new_polygon, other, + &ret_p1, + &ret_p2, + new_polygon); + + monoTriangulationFun(ret_p1, compV2InX, pStream); + monoTriangulationFun(ret_p2, compV2InX, pStream); + + ret_p1->deleteSinglePolygonWithSline(); + ret_p2->deleteSinglePolygonWithSline(); + + free(cusps); + return; + } + free(cusps); + } +} + + /*find the top and bottom of the polygon. It is supposed to be + *a V-monotone polygon + */ + + directedLine* tempV; + directedLine* topV; + directedLine* botV; + topV = botV = polygon; + + for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext()) + { + if(compV2InY(topV->head(), tempV->head())<0) { + + topV = tempV; + } + if(compV2InY(botV->head(), tempV->head())>0) { + + botV = tempV; + } + } + + /*find the first(top) and the last (bottom) grid line which intersect the + *this polygon + */ + Int firstGridIndex; /*the index in the grid*/ + Int lastGridIndex; + firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)); + lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1; + + + /*find the interval inside the polygon for each gridline*/ + Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridIndices); + Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridIndices); + Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(leftGridInnerIndices); + Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1)); + assert(rightGridInnerIndices); + + findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices); + + findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices); + + gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices); + + gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices); + + + +// leftGridChain.draw(); +// leftGridChain.drawInner(); +// rightGridChain.draw(); +// rightGridChain.drawInner(); + /*(1) determine the grid boundaries (left and right). + *(2) process polygon into two monotone chaines: use vertexArray + *(3) call sampleMonoPolyRec + */ + + /*copy the two chains into vertexArray datastructure*/ + Int i; + vertexArray leftChain(20); /*this is a dynamic array*/ + for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/ + leftChain.appendVertex(topV->getVertex(i)); + } + for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext()) + { + for(i=0; i<=tempV->get_npoints()-2; i++){ + leftChain.appendVertex(tempV->getVertex(i)); + } + } + + vertexArray rightChain(20); + for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev()) + { + for(i=tempV->get_npoints()-2; i>=0; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + } + for(i=botV->get_npoints()-2; i>=1; i--){ + rightChain.appendVertex(tempV->getVertex(i)); + } + + sampleMonoPolyRec(topV->head(), + botV->head(), + &leftChain, + 0, + &rightChain, + 0, + &leftGridChain, + &rightGridChain, + 0, + pStream, + rbArray); + + + /*cleanup space*/ + free(leftGridIndices); + free(rightGridIndices); + free(leftGridInnerIndices); + free(rightGridInnerIndices); +} + +void sampleMonoPolyRec( + Real* topVertex, + Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + primStream* pStream, + rectBlockArray* rbArray) +{ + + /*find the first connected component, and the four corners. + */ + Int index1, index2; /*the first and last grid line of the first connected component*/ + + if(topVertex[1] <= botVertex[1]) + return; + + /*find i so that the grid line is below the top vertex*/ + Int i=gridStartIndex; + while (i < leftGridChain->get_nVlines()) + { + if(leftGridChain->get_v_value(i) < topVertex[1]) + break; + i++; + } + + /*find the first connected component starting with i*/ + /*find index1 so that left_uline_index <= right_uline_index, that is, this + *grid line contains at least one inner grid point + */ + index1=i; + int num_skipped_grid_lines=0; + while(index1 < leftGridChain->get_nVlines()) + { + if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1)) + break; + num_skipped_grid_lines++; + index1++; + } + + + + if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/ + { + /*stop recursion, ...*/ + /*monotone triangulate it...*/ +if(num_skipped_grid_lines <2) + { + monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex, + leftChain->getNumElements()-1, + rightChain, rightStartIndex, + rightChain->getNumElements()-1, + pStream); + } +else + { + //the optimum way to triangulate is top-down since this polygon + //is narrow-long. + monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, + rightChain, rightStartIndex, pStream); + } + +/* + monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex, + rightChain, rightStartIndex, pStream); +*/ + +/* monoTriangulationRecGenTBOpt(topVertex, botVertex, + leftChain, leftStartIndex, leftChain->getNumElements()-1, + rightChain, rightStartIndex, rightChain->getNumElements()-1, + pStream);*/ + + + + } + else + { + + /*find index2 so that left_inner_index <= right_inner_index holds until index2*/ + index2=index1+1; + if(index2 < leftGridChain->get_nVlines()) + while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2)) + { + index2++; + if(index2 >= leftGridChain->get_nVlines()) + break; + } + + index2--; + + + + /*the neck*/ + Int neckLeftIndex; + Int neckRightIndex; + + /*the four corners*/ + Int up_leftCornerWhere; + Int up_leftCornerIndex; + Int up_rightCornerWhere; + Int up_rightCornerIndex; + Int down_leftCornerWhere; + Int down_leftCornerIndex; + Int down_rightCornerWhere; + Int down_rightCornerIndex; + + Real* tempBotVertex; /*the bottom vertex for this component*/ + Real* nextTopVertex=NULL; /*for the recursion*/ + Int nextLeftStartIndex=0; + Int nextRightStartIndex=0; + + /*find the points below the grid line index2 on both chains*/ + Int botLeftIndex = leftChain->findIndexStrictBelowGen( + leftGridChain->get_v_value(index2), + leftStartIndex, + leftChain->getNumElements()-1); + Int botRightIndex = rightChain->findIndexStrictBelowGen( + rightGridChain->get_v_value(index2), + rightStartIndex, + rightChain->getNumElements()-1); + /*if either botLeftIndex>= numelements, + * or botRightIndex >= numelemnet, + *then there is no neck exists. the bottom vertex is botVertex, + */ + if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex, + leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex)) + /* + if(botLeftIndex == leftChain->getNumElements() || + botRightIndex == rightChain->getNumElements()) + */ + { + + tempBotVertex = botVertex; + nextTopVertex = botVertex; + botLeftIndex = leftChain->getNumElements()-1; + botRightIndex = rightChain->getNumElements()-1; + } + else /*neck exists*/ + { + if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1]) + { + tempBotVertex = leftChain->getVertex(neckLeftIndex); + botLeftIndex = neckLeftIndex-1; + botRightIndex = neckRightIndex; + nextTopVertex = rightChain->getVertex(neckRightIndex); + nextLeftStartIndex = neckLeftIndex; + nextRightStartIndex = neckRightIndex+1; + } + else + { + tempBotVertex = rightChain->getVertex(neckRightIndex); + botLeftIndex = neckLeftIndex; + botRightIndex = neckRightIndex-1; + nextTopVertex = leftChain->getVertex(neckLeftIndex); + nextLeftStartIndex = neckLeftIndex+1; + nextRightStartIndex = neckRightIndex; + } + } + + findUpCorners(topVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain->get_v_value(index1), + leftGridChain->get_u_value(index1), + rightGridChain->get_u_value(index1), + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex); + + findDownCorners(tempBotVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain->get_v_value(index2), + leftGridChain->get_u_value(index2), + rightGridChain->get_u_value(index2), + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex); + + sampleConnectedComp(topVertex, tempBotVertex, + leftChain, + leftStartIndex, botLeftIndex, + rightChain, + rightStartIndex, botRightIndex, + leftGridChain, + rightGridChain, + index1, index2, + up_leftCornerWhere, + up_leftCornerIndex, + up_rightCornerWhere, + up_rightCornerIndex, + down_leftCornerWhere, + down_leftCornerIndex, + down_rightCornerWhere, + down_rightCornerIndex, + pStream, + rbArray + ); + + /*recursion*/ + + sampleMonoPolyRec( + nextTopVertex, + botVertex, + leftChain, + nextLeftStartIndex, + rightChain, + nextRightStartIndex, + leftGridChain, + rightGridChain, + index2+1, + pStream, rbArray); + + + } + +} + +void sampleLeftStrip(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex)); + assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex)); + assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex)); + assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex)); + + /* + *(1)find the last grid line which doesn'; pass below + * this first edge, sample this region: one trim edge and + * possily multiple grid lines. + */ + Real *upperVert, *lowerVert; /*the end points of the first trim edge*/ + upperVert = leftChain->getVertex(topLeftIndex); + lowerVert = leftChain->getVertex(topLeftIndex+1); + + Int index = leftGridChainStartIndex; + while(leftGridChain->get_v_value(index) >= lowerVert[1]){ + index++; + if(index > leftGridChainEndIndex) + break; + } + index--; + + sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert, + leftGridChain, + leftGridChainStartIndex, + index, + pStream); + sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex, + leftGridChain, index, leftGridChainEndIndex, + pStream); + +} + +void sampleLeftStripRec(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + /*now top left trim vertex is below the top grid line. + */ + /*stop condition: if topLeftIndex >= botLeftIndex, then stop. + */ + if(topLeftIndex >= botLeftIndex) + return; + + /*find the last trim vertex which is above the second top grid line: + * index1. + *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain, + * leftGridChainStartIndex). + * index1 could be equal to topLeftIndex. + */ + Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + assert(leftGridChainStartIndex < leftGridChainEndIndex); + Int index1 = topLeftIndex; + while(leftChain->getVertex(index1)[1] > secondGridChainV) + index1++; + index1--; + + sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); + + + /* + * Let the next trim vertex be nextTrimVertIndex (which should be + * below the second grid line). + * Find the last grid line index2 which is above nextTrimVert. + * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], + * leftGridChain, leftGridChainStartIndex+1, index2). + */ + Real *uppervert, *lowervert; + uppervert = leftChain->getVertex(index1); + lowervert = leftChain->getVertex(index1+1); + Int index2 = leftGridChainStartIndex+1; + + while(leftGridChain->get_v_value(index2) >= lowervert[1]) + { + index2++; + if(index2 > leftGridChainEndIndex) + break; + } + index2--; + sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); + + /* sampleLeftStripRec(leftChain, + nextTrimVertIndex, + botLeftIndex, + leftGridChain, + index2, + leftGridChainEndIndex + ) + * + */ + sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); + +} + + +/***************begin RecF***********************/ +/* the gridlines from leftGridChainStartIndex to + * leftGridChainEndIndex are assumed to form a + * connected component. + * the trim vertex of topLeftIndex is assumed to + * be below the first gridline, and the tim vertex + * of botLeftIndex is assumed to be above the last + * grid line. + * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without + * outputing any triangles. + * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output. + */ +void sampleLeftStripRecF(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ) +{ + /*now top left trim vertex is below the top grid line. + */ + /*stop condition: if topLeftIndex > botLeftIndex, then stop. + */ + if(topLeftIndex > botLeftIndex) + return; + + /*if there is only one grid Line, return.*/ + + if(leftGridChainStartIndex>=leftGridChainEndIndex) + return; + + + assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) && + leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex)); + + /*firs find the first trim vertex which is below or equal to the second top grid line: + * index1. + */ + Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + + Int index1 = topLeftIndex; + + while(leftChain->getVertex(index1)[1] > secondGridChainV){ + index1++; + if(index1>botLeftIndex) + break; + } + + /*now leftChain->getVertex(index-1)[1] > secondGridChainV and + * leftChain->getVertex(index)[1] <= secondGridChainV + *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to + *perform sampleOneGridStep. + */ + if(index1>botLeftIndex) + index1--; + else if(leftChain->getVertex(index1)[1] < secondGridChainV) + index1--; + + /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and + * leftChain->getVertex(index1+1)[1] <= secondGridChainV + */ + + + sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream); + + + /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest. + */ + if(leftChain->getVertex(index1)[1] == secondGridChainV) + { + + sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream); + } + else if(index1 < botLeftIndex) + { + + /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV, + * let the next trim vertex be nextTrimVertIndex (which should be strictly + * below the second grid line). + * Find the last grid line index2 which is above nextTrimVert. + * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2], + * leftGridChain, leftGridChainStartIndex+1, index2). + */ + Real *uppervert, *lowervert; + uppervert = leftChain->getVertex(index1); + lowervert = leftChain->getVertex(index1+1); //okay since index1get_v_value(index2) >= lowervert[1]) + { + index2++; + if(index2 > leftGridChainEndIndex) + break; + } + index2--; + + + sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream); + + /*recursion*/ + + sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream); + } + +} + +/***************End RecF***********************/ + +/*sample the left area in between one trim edge and multiple grid lines. + * all the grid lines should be in between the two end poins of the + *trim edge. + */ +void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream) +{ + Int i,j,k; + + vertexArray vArray(endIndex-beginIndex+1); + vArray.appendVertex(gridChain->get_vertex(beginIndex)); + + for(k=1, i=beginIndex+1; i<=endIndex; i++, k++) + { + vArray.appendVertex(gridChain->get_vertex(i)); + + /*output the fan of the grid points of the (i)th and (i-1)th grid line. + */ + if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i-1)); + for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1)) + { + pStream->begin(); + pStream->insert(gridChain->get_vertex(i)); + for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--) + pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1)); + pStream->end(PRIMITIVE_STREAM_FAN); + } + /*otherwisem, the two are equal, so there is no fan to outout*/ + } + + monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex, + 0, /*decreasing chain*/ + pStream); +} + +/*return i, such that from begin to i-1 the chain is strictly u-monotone. + */ +Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end) +{ + Int i=begin; + Real prevU = chain->getVertex(i)[0]; + Real thisU; + for(i=begin+1; i<=end; i++){ + thisU = chain->getVertex(i)[0]; + + if(prevU < thisU){ + prevU = thisU; + } + else + break; + } + return i; +} + +/*check whether there is a vertex whose v value is strictly + *inbetween vup vbelow + *if no middle exists return -1, else return the idnex. + */ +Int checkMiddle(vertexArray* chain, Int begin, Int end, + Real vup, Real vbelow) +{ + Int i; + for(i=begin; i<=end; i++) + { + if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow) + return i; + } + return -1; +} + +/*the degenerat case of sampleLeftOneGridStep*/ +void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream) +{ + /*since there is no middle, there is at most one point which is on the + *second grid line, there could be multiple points on the first (top) + *grid line. + */ + + leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream); + + monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex), + leftGridChain->get_vertex(leftGridChainStartIndex+1), + leftChain, + beginLeftIndex, + endLeftIndex, + 1, //is increase chain. + pStream); +} + + + +/*sampling the left area in between two grid lines. + */ +void sampleLeftOneGridStep(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream + ) +{ + if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex, + leftGridChain->get_v_value(leftGridChainStartIndex), + leftGridChain->get_v_value(leftGridChainStartIndex+1))<0) + + { + + sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream); + return; + } + + //copy into a polygon + { + directedLine* poly = NULL; + sampledLine* sline; + directedLine* dline; + gridWrap* grid = leftGridChain->getGrid(); + Real vert1[2]; + Real vert2[2]; + Int i; + + Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1); + Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex); + Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1); + Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex); + Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + //the upper gridline + vert1[1] = vert2[1] = upperV; + for(i=innerInd; i>upperInd; i--) + { + vert1[0]=grid->get_u_value(i); + vert2[0]=grid->get_u_value(i-1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + } + + //the edge connecting upper grid with left chain + vert1[0] = grid->get_u_value(upperInd); + vert1[1] = upperV; + sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex)); + dline = new directedLine(INCREASING, sline); + if(poly == NULL) + poly = dline; + else + poly->insert(dline); + + //the left chain + for(i=beginLeftIndex; igetVertex(i), leftChain->getVertex(i+1)); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the edge connecting left chain with lower gridline + vert2[0] = grid->get_u_value(lowerInd); + vert2[1] = lowerV; + sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + + //the lower grid line + vert1[1] = vert2[1] = lowerV; + for(i=lowerInd; iget_u_value(i); + vert2[0] = grid->get_u_value(i+1); + sline = new sampledLine(vert1, vert2); + dline = new directedLine(INCREASING, sline); + poly->insert(dline); + } + + //the vertical grid line segement + vert1[0]=vert2[0] = grid->get_u_value(innerInd); + vert2[1]=upperV; + vert1[1]=lowerV; + sline=new sampledLine(vert1, vert2); + dline=new directedLine(INCREASING, sline); + poly->insert(dline); + monoTriangulationOpt(poly, pStream); + //cleanup + poly->deleteSinglePolygonWithSline(); + return; + } + + + + + + Int i; + if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >= + leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/ + ) /*the second grid line is beyond the first one to the left*/ + { + /*find the maximal U-monotone chain + * of endLeftIndex, endLeftIndex-1, ..., + */ + i=endLeftIndex; + Real prevU = leftChain->getVertex(i)[0]; + for(i=endLeftIndex-1; i>=beginLeftIndex; i--){ + Real thisU = leftChain->getVertex(i)[0]; + if( prevU < thisU){ + prevU = thisU; + } + else + break; + } + /*from endLeftIndex to i+1 is strictly U- monotone */ + /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then + *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we + *we would output degenerate triangles + */ + if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex)) + i--; + + Int j = beginLeftIndex/*endLeftIndex*/+1; + + + if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex)) + { + j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/); + + Int temp = beginLeftIndex; + /*now from begin to j-1 is strictly u-monotone*/ + /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly + *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines + */ + if(j-1 == beginLeftIndex) + { + while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex)) + j++; + + Real vert[2]; + vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex); + vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex); + + monoTriangulation2( + vert/*leftChain->getVertex(beginLeftIndex)*/, + leftChain->getVertex(j-1), + leftChain, + beginLeftIndex, + j-2, + 1, + pStream //increase chain + ); + + temp = j-1; + } + + stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex), + leftGridChain->getInnerIndex(leftGridChainStartIndex+1), + pStream, + 1 /*the grid line is above the trim line*/ + ); + } + + stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex+1), + leftGridChain->getUlineIndex(leftGridChainStartIndex+1), + leftGridChain->getInnerIndex(leftGridChainStartIndex+1), + pStream, + 0 /*the grid line is below the trim lines*/ + ); + + /*monotone triangulate the remaining left chain togther with the + *two vertices on the two grid v-lines. + */ + Real vert[2][2]; + vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1); + vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); + vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); + +// vertexArray right(vert, 2); + + monoTriangulation2( + &vert[0][0], /*top vertex */ + &vert[1][0], /*bottom vertex*/ + leftChain, + /*beginLeftIndex*/j-1, + i+1, + 1, /*an increasing chain*/ + pStream); + } + else /*the second one is shorter than the first one to the left*/ + { + /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,..., + */ + i=beginLeftIndex; + Real prevU = leftChain->getVertex(i)[0]; + for(i=beginLeftIndex+1; i<=endLeftIndex; i++){ + Real thisU = leftChain->getVertex(i)[0]; + + if(prevU < thisU){ + prevU = thisU; + } + else + break; + } + /*from beginLeftIndex to i-1 is strictly U-monotone*/ + + + stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(), + leftGridChain->getVlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex), + leftGridChain->getUlineIndex(leftGridChainStartIndex+1), + pStream, + 1 /*the grid line is above the trim lines*/ + ); + /*monotone triangulate the remaining left chain together with the + *two vertices on the two grid v-lines. + */ + Real vert[2][2]; + vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1); + vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex); + vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1); + + vertexArray right(vert, 2); + + monoTriangulation2( + &vert[0][0], //top vertex + &vert[1][0], //bottom vertex + leftChain, + i-1, + endLeftIndex, + 1, /*an increase chain*/ + pStream); + + } +} + +/*n_upper>=1 + *n_lower>=1 + */ +void triangulateXYMono(Int n_upper, Real upperVerts[][2], + Int n_lower, Real lowerVerts[][2], + primStream* pStream) +{ + Int i,j,k,l; + Real* leftMostV; + + assert(n_upper>=1 && n_lower>=1); + if(upperVerts[0][0] <= lowerVerts[0][0]) + { + i=1; + j=0; + leftMostV = upperVerts[0]; + } + else + { + i=0; + j=1; + leftMostV = lowerVerts[0]; + } + + while(1) + { + if(i >= n_upper) /*case1: no more in upper*/ + { + + if(jbegin(); + pStream->insert(leftMostV); + while(jinsert(lowerVerts[j]); + j++; + } + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else if(j>= n_lower) /*case2: no more in lower*/ + { + + if(ibegin(); + pStream->insert(leftMostV); + + for(k=n_upper-1; k>=i; k--) + pStream->insert(upperVerts[k]); + + pStream->end(PRIMITIVE_STREAM_FAN); + } + + break; + } + else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/ + { + + if(upperVerts[i][0] <= lowerVerts[j][0]) + { + pStream->begin(); + pStream->insert(lowerVerts[j]); /*the origin of this fan*/ + + /*find the last k>=i such that + *upperverts[k][0] <= lowerverts[j][0] + */ + k=i; + while(k lowerVerts[j][0]) + break; + k++; + } + k--; + for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/ + { + pStream->insert(upperVerts[l]); + } + pStream->insert(leftMostV); + + pStream->end(PRIMITIVE_STREAM_FAN); + //update i for next loop + i = k+1; + leftMostV = upperVerts[k]; + + } + else /*upperVerts[i][0] > lowerVerts[j][0]*/ + { + pStream->begin(); + pStream->insert(upperVerts[i]);/*the origion of this fan*/ + pStream->insert(leftMostV); + /*find the last k>=j such that + *lowerverts[k][0] < upperverts[i][0]*/ + k=j; + while(k< n_lower) + { + if(lowerVerts[k][0] >= upperVerts[i][0]) + break; + pStream->insert(lowerVerts[k]); + k++; + } + pStream->end(PRIMITIVE_STREAM_FAN); + j=k; + leftMostV = lowerVerts[j-1]; + } + } + } +} + + +void stripOfFanLeft(vertexArray* leftChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp /*1 if the grid line is above the trim lines*/ + ) +{ + assert(largeIndex >= smallIndex); + + Real grid_v_value; + grid_v_value = grid->get_v_value(vlineIndex); + + Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1)); + assert(trimVerts); + + + Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1)); + assert(gridVerts); + + Int k,i; + if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/ + for(k=0, i=smallIndex; i<=largeIndex; i++, k++) + { + trimVerts[k][0] = leftChain->getVertex(i)[0]; + trimVerts[k][1] = leftChain->getVertex(i)[1]; + } + else + for(k=0, i=largeIndex; i>=smallIndex; i--, k++) + { + trimVerts[k][0] = leftChain->getVertex(i)[0]; + trimVerts[k][1] = leftChain->getVertex(i)[1]; + } + + for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++) + { + gridVerts[k][0] = grid->get_u_value(i); + gridVerts[k][1] = grid_v_value; + } + + if(gridLineUp) + triangulateXYMono( + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + largeIndex-smallIndex+1, trimVerts, + pStream); + else + triangulateXYMono(largeIndex-smallIndex+1, trimVerts, + ulineLargeIndex-ulineSmallIndex+1, gridVerts, + pStream); + free(trimVerts); + free(gridVerts); +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.h b/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.h new file mode 100644 index 000000000..1ab23db81 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampleMonoPoly.h @@ -0,0 +1,168 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLEMONOPOLY_H +#define _SAMPLEMONOPOLY_H + +#include "monoTriangulation.h" +#include "gridWrap.h" +#include "rectBlock.h" + + +void triangulateXYMono(Int n_upper, Real upperVerts[][2], + Int n_lower, Real lowerVerts[][2], + primStream* pStream); + +void stripOfFanLeft(vertexArray* leftChain, + Int largeIndex, + Int smallIndex, + gridWrap* grid, + Int vlineIndex, + Int ulineSmallIndex, + Int ulineLargeIndex, + primStream* pStream, + Int gridLineUp + ); +void sampleLeftOneGridStep(vertexArray* leftChain, + Int beginLeftIndex, + Int endLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + primStream* pStream + ); + +void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2], + gridBoundaryChain* gridChain, + Int beginIndex, + Int endIndex, + primStream* pStream); + +void sampleLeftStripRec(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void sampleLeftStrip(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner); + +void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner); + +void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream *pStream, rectBlockArray* rbArray); + +void sampleMonoPolyRec( + Real* topVertex, + Real* botVertex, + vertexArray* leftChain, + Int leftStartIndex, + vertexArray* rightChain, + Int rightStartIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + primStream* pStream, + rectBlockArray* rbArray + ); + +void sampleLeftStripRecF(vertexArray* leftChain, + Int topLeftIndex, + Int botLeftIndex, + gridBoundaryChain* leftGridChain, + Int leftGridChainStartIndex, + Int leftGridChainEndIndex, + primStream* pStream + ); + +void findUpCorners(Real *topVertex, + vertexArray *leftChain, + Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, + Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, + Int& ret_leftCornerIndex, + Int& ret_rightCornerWhere, + Int& ret_rightCornerIndex + ); +void findDownCorners(Real *botVertex, + vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex, + vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex, + Real v, + Real uleft, + Real uright, + Int& ret_leftCornerWhere, + Int& ret_leftCornerIndex, + Int& ret_rightCornerWhere, + Int& ret_rightCornerIndex + ); +void findNeck(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + Int& leftLastIndex, /*left point of the neck*/ + Int& rightLastIndex /*right point of the neck*/ + ); + +Int findNeckF(vertexArray *leftChain, Int botLeftIndex, + vertexArray *rightChain, Int botRightIndex, + gridBoundaryChain* leftGridChain, + gridBoundaryChain* rightGridChain, + Int gridStartIndex, + Int& neckLeft, + Int& neckRight); + +void findTopAndBot(directedLine* polygon, + directedLine*& topV, + directedLine*& botV); +void findGridChains(directedLine* top, directedLine* bot, + gridWrap* grid, + gridBoundaryChain*& leftGridChain, + gridBoundaryChain*& rightGridChain); +void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain); + +Int checkMiddle(vertexArray* chain, Int begin, Int end, + Real vup, Real vbelow); + +#endif /* _SAMPLEMONOPOLY_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampledLine.cc b/project/jni/glu/src/libnurbs/nurbtess/sampledLine.cc new file mode 100644 index 000000000..e489e01d3 --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampledLine.cc @@ -0,0 +1,170 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include //for fabs() +#include "glimports.h" +#include "zlassert.h" +#include "sampledLine.h" + +void sampledLine::setPoint(Int i, Real p[2]) +{ + points[i][0]=p[0]; + points[i][1]=p[1]; +} + + +/*insert this single line in front of the oldList*/ +sampledLine* sampledLine::insert(sampledLine *oldList) +{ + next = oldList; + return this; +} + +void sampledLine::deleteList() +{ + sampledLine *temp, *tempNext; + for(temp = this; temp != NULL; temp = tempNext) + { + tempNext = temp->next; + delete temp; + } +} + + +/*space of points[][2] is allocated*/ +sampledLine::sampledLine(Int n_points) +{ + npoints = n_points; + points = (Real2*) malloc(sizeof(Real2) * n_points); + assert(points); + next = NULL; +} + +/*space of points[][2] is allocated and + *points are copied + */ +sampledLine::sampledLine(Int n_points, Real2 pts[]) +{ + int i; + npoints = n_points; + points = (Real2*) malloc(sizeof(Real2) * n_points); + assert(points); + for(i=0; i nv) n = nu; + else + n = nv; + if(n<1) + n = 1; + //du dv could be negative + Real du = (points[npoints-1][0] - points[0][0])/n; + Real dv = (points[npoints-1][1] - points[0][1])/n; + Real2 *temp = (Real2*) malloc(sizeof(Real2) * (n+1)); + assert(temp); + + Real u,v; + for(i=0, u=points[0][0], v=points[0][1]; inext) + { + temp->tessellate(u_reso, v_reso); + } +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/sampledLine.h b/project/jni/glu/src/libnurbs/nurbtess/sampledLine.h new file mode 100644 index 000000000..eb7f1818c --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/sampledLine.h @@ -0,0 +1,69 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SAMPLEDLINE_H +#define _SAMPLEDLINE_H + +#include "definitions.h" + +class sampledLine +{ + Int npoints; + Real2* points; + + public: + sampledLine(Int n_points); + sampledLine(Int n_points, Real pts[][2]); + sampledLine(Real pt1[2], Real pt2[2]); + sampledLine(); // special, careful about memory + ~sampledLine(); + + void init(Int n_points, Real2* pts); // special, careful about memory + + void setPoint(Int i, Real p[2]); + + sampledLine* insert(sampledLine* nline); + void deleteList(); + + Int get_npoints() {return npoints;} + Real2* get_points() {return points;} + + // u_reso is number of segments (may not be integer) per unit u + void tessellate(Real u_reso, Real v_reso); // n segments + void tessellateAll(Real u_reso, Real v_reso); + + sampledLine* next; +}; + +#endif /* _SAMPLEDLINE_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/searchTree.cc b/project/jni/glu/src/libnurbs/nurbtess/searchTree.cc new file mode 100644 index 000000000..885c5112d --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/searchTree.cc @@ -0,0 +1,327 @@ +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ +/* + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +*/ + +#include +#include +#include "zlassert.h" + +#include "searchTree.h" + +#define max(a,b) ((a>b)? a:b) + +treeNode* TreeNodeMake(void* key) +{ + treeNode* ret=(treeNode*)malloc(sizeof(treeNode)); + + assert(ret); + + ret->key=key; + ret->parent=NULL; + ret->left=NULL; + ret->right=NULL; + + return ret; +} + +void TreeNodeDeleteSingleNode(treeNode* node) +{ + free(node); +} + +void TreeNodeDeleteWholeTree(treeNode* node) +{ + if (node==NULL) + { + return; + } + TreeNodeDeleteWholeTree(node->left); + TreeNodeDeleteWholeTree(node->right); + TreeNodeDeleteSingleNode(node); +} + +void TreeNodePrint(treeNode* node, void (*keyPrint)(void*)) +{ + if (node==NULL) + { + return; + } + + TreeNodePrint(node->left, keyPrint); + keyPrint(node->key); + TreeNodePrint(node->right, keyPrint); +} + +int TreeNodeDepth(treeNode* root) +{ + if (root==NULL) + { + return 0; + } + else + { + int leftdepth = TreeNodeDepth(root->left); + int rightdepth = TreeNodeDepth(root->right); + + return 1 + max(leftdepth, rightdepth); + } +} + +/*return the node with the key. + *NULL is returned if not found + */ +treeNode* TreeNodeFind(treeNode* tree, void* key, + int (*compkey) (void*, void*)) +{ + if (tree==NULL) + { + return NULL; + } + if (key==tree->key) + { + return tree; + } + else + { + if (compkey(key, tree->key)<0) + { + return TreeNodeFind(tree->left, key, compkey); + } + else + { + return TreeNodeFind(tree->right, key, compkey); + } + } +} + +treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode, + int (*compkey) (void *, void *)) +{ + treeNode *y = NULL; + treeNode *x = root; + /* going down the tree from the root. + * x traces the path, y is the parent of x. + */ + while (x!=NULL) + { + y=x; + if (compkey(newnode->key, x->key)<0) + { + x=x->left; + } + else + { + x=x->right; + } + } + + /* now y has the property that + * if newnode < y, then y->left is NULL + * if newnode > y, then y->right is NULL. + * So we want to isnert newnode to be the child of y + */ + newnode->parent=y; + if (y==NULL) + { + return newnode; + } + else + { + if (compkey(newnode->key, y->key)<0) + { + y->left=newnode; + } + else + { + y->right=newnode; + } + } + + return root; +} + +treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node) +{ + treeNode* y; + treeNode* x; + treeNode* ret; + + if (node==NULL) + { + return tree; + } + + if (node->left==NULL || node->right==NULL) + { + y = node; + if (y->left!=NULL) + { + x=y->left; + } + else + { + x=y->right; + } + + if (x!=NULL) + { + x->parent=y->parent; + } + + if(y->parent == NULL) /*y is the root which has at most one child x*/ + ret = x; + else /*y is not the root*/ + { + if(y == y->parent->left) + y->parent->left = x; + else + y->parent->right = x; + ret = tree; + } + } + else { /*node has two children*/ + + y = TreeNodeSuccessor(node); + assert(y->left == NULL); + + if(y == node->right) /*y is the right child if node*/ + { + y->parent = node->parent; + y->left = node->left; + node->left->parent = y; + + } + else /*y != node->right*/ + { + x = y->right; + if(x!= NULL) + x->parent = y->parent; + + assert(y->parent != NULL); + if(y == y->parent->left) + y->parent->left = x; + else + y->parent->right = x; + /*move y to the position of node*/ + y->parent = node->parent; + y->left = node->left; + y->right = node->right; + node->left->parent = y; + node->right->parent = y; + } + if(node->parent != NULL) { + if(node->parent->left == node) + node->parent->left = y; + else + node->parent->right = y; + ret = tree; /*the root if the tree doesn't change*/ + } + else /*node->parent is NULL: node is the root*/ + ret = y; + } + + /*finally free the node, and return the new root*/ + TreeNodeDeleteSingleNode(node); + return ret; +} + +/*the minimum node in the tree rooted by node + */ +treeNode* TreeNodeMinimum(treeNode* node) +{ + treeNode* temp = node; + if(temp == NULL) return NULL; + while(temp->left != NULL) { + temp = temp->left; + } + return temp; +} + +/*the maximum node in the tree rooted by node + */ +treeNode* TreeNodeMaximum(treeNode* node) +{ + treeNode* temp = node; + if(temp == NULL) return NULL; + while(temp->right != NULL) { + temp = temp->right; + } + return temp; +} + +/*return the first node (in sorted order) which is to the right of this node + */ +treeNode* TreeNodeSuccessor(treeNode* node) +{ + if(node == NULL) return NULL; + if(node->right != NULL) + return TreeNodeMinimum(node->right); + else{ /*node->right is NULL*/ + + /*find the first right-ancestor*/ + treeNode *y = node->parent; + treeNode* x = node; + while(y != NULL && x == y->right) /*if y is a left parent of x*/ + { + + x = y; + y = y->parent; + } + return y; + } +} + +/*return the first node (in sorted order) which is to the left of this node + */ +treeNode* TreeNodePredecessor(treeNode* node) +{ + if(node == NULL) return NULL; + if(node->left != NULL) + return TreeNodeMaximum(node->left); + else{ /*node->left is NULL*/ + /*find the first left-ancestor*/ + treeNode *y = node->parent; + treeNode *x = node; + while(y != NULL && x == y->left) /*if y is a right parent of x*/ + { + x = y; + y = y->parent; + } + return y; + } +} diff --git a/project/jni/glu/src/libnurbs/nurbtess/searchTree.h b/project/jni/glu/src/libnurbs/nurbtess/searchTree.h new file mode 100644 index 000000000..99fd5046b --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/searchTree.h @@ -0,0 +1,62 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef _SEARCHTREE_H +#define _SEARCHTREE_H + +typedef struct treeNode +{ + void* key; + struct treeNode* parent; + struct treeNode* left; /* children */ + struct treeNode* right; +} treeNode; + +treeNode* TreeNodeMake(void* key); +void TreeNodeDeleteSingleNode(treeNode* node); +void TreeNodeDeleteWholeTree(treeNode* node); +void TreeNodePrint(treeNode* node, void (*keyPrint)(void*)); +int TreeNodeDepth(treeNode* root); +treeNode* TreeNodeMinimum(treeNode* node); +treeNode* TreeNodeMaximum(treeNode* node); +treeNode* TreeNodePredecessor(treeNode* node); +treeNode* TreeNodeSuccessor(treeNode* node); +treeNode* TreeNodeFind(treeNode* tree, void* key, + int (*compkey) (void*, void*)); + +treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode, + int (*comp) (void *, void *)); +treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node); + +#endif /* _SEARCHTREE_H */ diff --git a/project/jni/glu/src/libnurbs/nurbtess/zlassert.h b/project/jni/glu/src/libnurbs/nurbtess/zlassert.h new file mode 100644 index 000000000..315a9aeaf --- /dev/null +++ b/project/jni/glu/src/libnurbs/nurbtess/zlassert.h @@ -0,0 +1,40 @@ +/* + * 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 GLU by Mike Gorchak +*/ + +#ifndef __zlassert_h_ +#define __zlassert_h_ + +#define assert(EX) ((void)0) + +#endif /* __zlassert_h_ */ diff --git a/project/jni/glu/src/libtess/README b/project/jni/glu/src/libtess/README new file mode 100644 index 000000000..60e1cb32d --- /dev/null +++ b/project/jni/glu/src/libtess/README @@ -0,0 +1,446 @@ +/* +*/ + +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/project/jni/glu/src/libtess/alg-outline b/project/jni/glu/src/libtess/alg-outline new file mode 100644 index 000000000..e714a6c75 --- /dev/null +++ b/project/jni/glu/src/libtess/alg-outline @@ -0,0 +1,228 @@ +/* +*/ + +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/project/jni/glu/src/libtess/dict-list.h b/project/jni/glu/src/libtess/dict-list.h new file mode 100644 index 000000000..3dfdc32b3 --- /dev/null +++ b/project/jni/glu/src/libtess/dict-list.h @@ -0,0 +1,99 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/dict.c b/project/jni/glu/src/libtess/dict.c new file mode 100644 index 000000000..95a523845 --- /dev/null +++ b/project/jni/glu/src/libtess/dict.c @@ -0,0 +1,121 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/dict.h b/project/jni/glu/src/libtess/dict.h new file mode 100644 index 000000000..93e60caec --- /dev/null +++ b/project/jni/glu/src/libtess/dict.h @@ -0,0 +1,98 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/geom.c b/project/jni/glu/src/libtess/geom.c new file mode 100644 index 000000000..9399102e4 --- /dev/null +++ b/project/jni/glu/src/libtess/geom.c @@ -0,0 +1,327 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/geom.h b/project/jni/glu/src/libtess/geom.h new file mode 100644 index 000000000..861e75d95 --- /dev/null +++ b/project/jni/glu/src/libtess/geom.h @@ -0,0 +1,86 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/memalloc.c b/project/jni/glu/src/libtess/memalloc.c new file mode 100644 index 000000000..bbfeee44a --- /dev/null +++ b/project/jni/glu/src/libtess/memalloc.c @@ -0,0 +1,57 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/memalloc.h b/project/jni/glu/src/libtess/memalloc.h new file mode 100644 index 000000000..d391ea7c4 --- /dev/null +++ b/project/jni/glu/src/libtess/memalloc.h @@ -0,0 +1,55 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/mesh.c b/project/jni/glu/src/libtess/mesh.c new file mode 100644 index 000000000..a12a0f83c --- /dev/null +++ b/project/jni/glu/src/libtess/mesh.c @@ -0,0 +1,877 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/mesh.h b/project/jni/glu/src/libtess/mesh.h new file mode 100644 index 000000000..511122015 --- /dev/null +++ b/project/jni/glu/src/libtess/mesh.h @@ -0,0 +1,271 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/normal.c b/project/jni/glu/src/libtess/normal.c new file mode 100644 index 000000000..36b8434e8 --- /dev/null +++ b/project/jni/glu/src/libtess/normal.c @@ -0,0 +1,281 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/normal.h b/project/jni/glu/src/libtess/normal.h new file mode 100644 index 000000000..e847266aa --- /dev/null +++ b/project/jni/glu/src/libtess/normal.h @@ -0,0 +1,47 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/priorityq-heap.h b/project/jni/glu/src/libtess/priorityq-heap.h new file mode 100644 index 000000000..4ee1dc28b --- /dev/null +++ b/project/jni/glu/src/libtess/priorityq-heap.h @@ -0,0 +1,118 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/priorityq-heap.i b/project/jni/glu/src/libtess/priorityq-heap.i new file mode 100644 index 000000000..28ca9d94d --- /dev/null +++ b/project/jni/glu/src/libtess/priorityq-heap.i @@ -0,0 +1,278 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/priorityq-sort.h b/project/jni/glu/src/libtess/priorityq-sort.h new file mode 100644 index 000000000..9b6b1783d --- /dev/null +++ b/project/jni/glu/src/libtess/priorityq-sort.h @@ -0,0 +1,120 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/priorityq.c b/project/jni/glu/src/libtess/priorityq.c new file mode 100644 index 000000000..07f836629 --- /dev/null +++ b/project/jni/glu/src/libtess/priorityq.c @@ -0,0 +1,318 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/priorityq.h b/project/jni/glu/src/libtess/priorityq.h new file mode 100644 index 000000000..9388dacf0 --- /dev/null +++ b/project/jni/glu/src/libtess/priorityq.h @@ -0,0 +1,120 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/render.c b/project/jni/glu/src/libtess/render.c new file mode 100644 index 000000000..19a48653e --- /dev/null +++ b/project/jni/glu/src/libtess/render.c @@ -0,0 +1,586 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/render.h b/project/jni/glu/src/libtess/render.h new file mode 100644 index 000000000..228d4bceb --- /dev/null +++ b/project/jni/glu/src/libtess/render.h @@ -0,0 +1,54 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/sweep.c b/project/jni/glu/src/libtess/sweep.c new file mode 100644 index 000000000..58751acf8 --- /dev/null +++ b/project/jni/glu/src/libtess/sweep.c @@ -0,0 +1,1703 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/sweep.h b/project/jni/glu/src/libtess/sweep.h new file mode 100644 index 000000000..6ba2591e1 --- /dev/null +++ b/project/jni/glu/src/libtess/sweep.h @@ -0,0 +1,79 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/tess.c b/project/jni/glu/src/libtess/tess.c new file mode 100644 index 000000000..8a4288f1f --- /dev/null +++ b/project/jni/glu/src/libtess/tess.c @@ -0,0 +1,642 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/tess.h b/project/jni/glu/src/libtess/tess.h new file mode 100644 index 000000000..1dbad7476 --- /dev/null +++ b/project/jni/glu/src/libtess/tess.h @@ -0,0 +1,162 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/tessmono.c b/project/jni/glu/src/libtess/tessmono.c new file mode 100644 index 000000000..2b20c5470 --- /dev/null +++ b/project/jni/glu/src/libtess/tessmono.c @@ -0,0 +1,232 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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/project/jni/glu/src/libtess/tessmono.h b/project/jni/glu/src/libtess/tessmono.h new file mode 100644 index 000000000..753a7809f --- /dev/null +++ b/project/jni/glu/src/libtess/tessmono.h @@ -0,0 +1,72 @@ +/* + * 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. + * + * OpenGL ES 1.0 CM port of GLU by Mike Gorchak +** +*/ + +#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_ */