1f220fa62Smrg/* 2f220fa62Smrg** License Applicability. Except to the extent portions of this file are 3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free 4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this 5f220fa62Smrg** file are subject only to the provisions of the License. You may not use 6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy 7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9f220fa62Smrg** 10f220fa62Smrg** http://oss.sgi.com/projects/FreeB 11f220fa62Smrg** 12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an 13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17f220fa62Smrg** 18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation, 19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 21f220fa62Smrg** Copyright in any portions created by third parties is as indicated 22f220fa62Smrg** elsewhere herein. All Rights Reserved. 23f220fa62Smrg** 24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces 25f220fa62Smrg** established by SGI in conjunction with the Original Code are The 26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software 30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation 31f220fa62Smrg** published by SGI, but has not been independently verified as being 32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification. 33f220fa62Smrg*/ 34f220fa62Smrg 35f220fa62Smrg/* 36f220fa62Smrg * ccw.c++ 37f220fa62Smrg * 38f220fa62Smrg */ 39f220fa62Smrg 40f220fa62Smrg#include "glimports.h" 41f220fa62Smrg#include "mystdio.h" 42f220fa62Smrg#include "myassert.h" 43f220fa62Smrg#include "subdivider.h" 44f220fa62Smrg#include "types.h" 45f220fa62Smrg#include "arc.h" 46f220fa62Smrg#include "trimvertex.h" 47f220fa62Smrg#include "simplemath.h" 48f220fa62Smrg 49f220fa62Smrginline int 50f220fa62SmrgSubdivider::bbox( TrimVertex *a, TrimVertex *b, TrimVertex *c, int p ) 51f220fa62Smrg{ 52f220fa62Smrg return bbox( a->param[p], b->param[p], c->param[p], 53f220fa62Smrg a->param[1-p], b->param[1-p], c->param[1-p] ); 54f220fa62Smrg} 55f220fa62Smrg 56f220fa62Smrgint 57f220fa62SmrgSubdivider::ccwTurn_sr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1 58f220fa62Smrg{ 59e7980a23Smrg TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; 60e7980a23Smrg TrimVertex *v1last = &j1->pwlArc->pts[0]; 61e7980a23Smrg TrimVertex *v2 = &j2->pwlArc->pts[0]; 62e7980a23Smrg TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; 63e7980a23Smrg TrimVertex *v1next = v1-1; 64e7980a23Smrg TrimVertex *v2next = v2+1; 65f220fa62Smrg int sgn; 66f220fa62Smrg 67f220fa62Smrg assert( v1 != v1last ); 68f220fa62Smrg assert( v2 != v2last ); 69f220fa62Smrg 70f220fa62Smrg#ifndef NDEBUG 71f220fa62Smrg _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 ); 72f220fa62Smrg#endif 73f220fa62Smrg 74f220fa62Smrg // the arcs lie on the line (0 == v1->param[0]) 75f220fa62Smrg if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] ) 76f220fa62Smrg return 0; 77f220fa62Smrg 78f220fa62Smrg if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] ) 79f220fa62Smrg ::mylongjmp( jumpbuffer, 28 ); 80f220fa62Smrg 81f220fa62Smrg if( v1->param[1] < v2->param[1] ) 82f220fa62Smrg return 0; 83f220fa62Smrg else if( v1->param[1] > v2->param[1] ) 84f220fa62Smrg return 1; 85f220fa62Smrg 86f220fa62Smrg while( 1 ) { 87f220fa62Smrg if( v1next->param[0] < v2next->param[0] ) { 88f220fa62Smrg#ifndef NDEBUG 89f220fa62Smrg _glu_dprintf( "case a\n" ); 90f220fa62Smrg#endif 91f220fa62Smrg assert( v1->param[0] <= v1next->param[0] ); 92f220fa62Smrg assert( v2->param[0] <= v1next->param[0] ); 93f220fa62Smrg switch( bbox( v2, v2next, v1next, 1 ) ) { 94f220fa62Smrg case -1: 95f220fa62Smrg return 0; 96f220fa62Smrg case 0: 97f220fa62Smrg sgn = ccw( v1next, v2, v2next ); 98f220fa62Smrg if( sgn != -1 ) { 99f220fa62Smrg return sgn; 100f220fa62Smrg } else { 101f220fa62Smrg#ifdef DEBUG 102f220fa62Smrg _glu_dprintf( "decr\n" ); 103f220fa62Smrg#endif 104f220fa62Smrg v1 = v1next--; 105f220fa62Smrg if( v1 == v1last ) { 106f220fa62Smrg#ifdef DEBUG 107f220fa62Smrg _glu_dprintf( "no good results\n" ); 108f220fa62Smrg#endif 109f220fa62Smrg return 0; // ill-conditioned, guess answer 110f220fa62Smrg } 111f220fa62Smrg } 112f220fa62Smrg break; 113f220fa62Smrg case 1: 114f220fa62Smrg return 1; 115f220fa62Smrg } 116f220fa62Smrg } else if( v1next->param[0] > v2next->param[0] ) { 117f220fa62Smrg#ifndef NDEBUG 118f220fa62Smrg _glu_dprintf( "case b\n" ); 119f220fa62Smrg#endif 120f220fa62Smrg assert( v1->param[0] <= v2next->param[0] ); 121f220fa62Smrg assert( v2->param[0] <= v2next->param[0] ); 122f220fa62Smrg switch( bbox( v1, v1next, v2next, 1 ) ) { 123f220fa62Smrg case -1: 124f220fa62Smrg return 1; 125f220fa62Smrg case 0: 126f220fa62Smrg sgn = ccw( v1next, v1, v2next ); 127f220fa62Smrg if( sgn != -1 ) { 128f220fa62Smrg return sgn; 129f220fa62Smrg } else { 130f220fa62Smrg#ifdef DEBUG 131f220fa62Smrg _glu_dprintf( "incr\n" ); 132f220fa62Smrg#endif 133f220fa62Smrg v2 = v2next++; 134f220fa62Smrg if( v2 == v2last ) { 135f220fa62Smrg#ifdef DEBUG 136f220fa62Smrg _glu_dprintf( "no good results\n" ); 137f220fa62Smrg#endif 138f220fa62Smrg return 0; // ill-conditioned, guess answer 139f220fa62Smrg } 140f220fa62Smrg } 141f220fa62Smrg break; 142f220fa62Smrg case 1: 143f220fa62Smrg return 0; 144f220fa62Smrg } 145f220fa62Smrg } else { 146f220fa62Smrg#ifndef NDEBUG 147f220fa62Smrg _glu_dprintf( "case ab\n" ); 148f220fa62Smrg#endif 149f220fa62Smrg if( v1next->param[1] < v2next->param[1] ) 150f220fa62Smrg return 0; 151f220fa62Smrg else if( v1next->param[1] > v2next->param[1] ) 152f220fa62Smrg return 1; 153f220fa62Smrg else { 154f220fa62Smrg#ifdef DEBUG 155f220fa62Smrg _glu_dprintf( "incr\n" ); 156f220fa62Smrg#endif 157f220fa62Smrg v2 = v2next++; 158f220fa62Smrg if( v2 == v2last ) { 159f220fa62Smrg#ifdef DEBUG 160f220fa62Smrg _glu_dprintf( "no good results\n" ); 161f220fa62Smrg#endif 162f220fa62Smrg return 0; // ill-conditioned, guess answer 163f220fa62Smrg } 164f220fa62Smrg } 165f220fa62Smrg } 166f220fa62Smrg } 167f220fa62Smrg} 168f220fa62Smrg 169f220fa62Smrgint 170f220fa62SmrgSubdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0 171f220fa62Smrg{ 172e7980a23Smrg TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; 173e7980a23Smrg TrimVertex *v1last = &j1->pwlArc->pts[0]; 174e7980a23Smrg TrimVertex *v2 = &j2->pwlArc->pts[0]; 175e7980a23Smrg TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; 176e7980a23Smrg TrimVertex *v1next = v1-1; 177e7980a23Smrg TrimVertex *v2next = v2+1; 178f220fa62Smrg int sgn; 179f220fa62Smrg 180f220fa62Smrg assert( v1 != v1last ); 181f220fa62Smrg assert( v2 != v2last ); 182f220fa62Smrg 183f220fa62Smrg#ifndef NDEBUG 184f220fa62Smrg _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 ); 185f220fa62Smrg#endif 186f220fa62Smrg 187f220fa62Smrg // the arcs lie on the line (0 == v1->param[0]) 188f220fa62Smrg if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] ) 189f220fa62Smrg return 0; 190f220fa62Smrg 191f220fa62Smrg if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] ) 192f220fa62Smrg ::mylongjmp( jumpbuffer, 28 ); 193f220fa62Smrg 194f220fa62Smrg if( v1->param[1] < v2->param[1] ) 195f220fa62Smrg return 1; 196f220fa62Smrg else if( v1->param[1] > v2->param[1] ) 197f220fa62Smrg return 0; 198f220fa62Smrg 199f220fa62Smrg while( 1 ) { 200f220fa62Smrg if( v1next->param[0] > v2next->param[0] ) { 201f220fa62Smrg#ifndef NDEBUG 202f220fa62Smrg _glu_dprintf( "case c\n" ); 203f220fa62Smrg#endif 204f220fa62Smrg assert( v1->param[0] >= v1next->param[0] ); 205f220fa62Smrg assert( v2->param[0] >= v1next->param[0] ); 206f220fa62Smrg switch( bbox( v2next, v2, v1next, 1 ) ) { 207f220fa62Smrg case -1: 208f220fa62Smrg return 1; 209f220fa62Smrg case 0: 210f220fa62Smrg sgn = ccw( v1next, v2, v2next ); 211f220fa62Smrg if( sgn != -1 ) 212f220fa62Smrg return sgn; 213f220fa62Smrg else { 214f220fa62Smrg v1 = v1next--; 215f220fa62Smrg#ifdef DEBUG 216f220fa62Smrg _glu_dprintf( "decr\n" ); 217f220fa62Smrg#endif 218f220fa62Smrg if( v1 == v1last ) { 219f220fa62Smrg#ifdef DEBUG 220f220fa62Smrg _glu_dprintf( "no good results\n" ); 221f220fa62Smrg#endif 222f220fa62Smrg return 0; // ill-conditioned, guess answer 223f220fa62Smrg } 224f220fa62Smrg } 225f220fa62Smrg break; 226f220fa62Smrg case 1: 227f220fa62Smrg return 0; 228f220fa62Smrg } 229f220fa62Smrg } else if( v1next->param[0] < v2next->param[0] ) { 230f220fa62Smrg#ifndef NDEBUG 231f220fa62Smrg _glu_dprintf( "case d\n" ); 232f220fa62Smrg#endif 233f220fa62Smrg assert( v1->param[0] >= v2next->param[0] ); 234f220fa62Smrg assert( v2->param[0] >= v2next->param[0] ); 235f220fa62Smrg switch( bbox( v1next, v1, v2next, 1 ) ) { 236f220fa62Smrg case -1: 237f220fa62Smrg return 0; 238f220fa62Smrg case 0: 239f220fa62Smrg sgn = ccw( v1next, v1, v2next ); 240f220fa62Smrg if( sgn != -1 ) 241f220fa62Smrg return sgn; 242f220fa62Smrg else { 243f220fa62Smrg v2 = v2next++; 244f220fa62Smrg#ifdef DEBUG 245f220fa62Smrg _glu_dprintf( "incr\n" ); 246f220fa62Smrg#endif 247f220fa62Smrg if( v2 == v2last ) { 248f220fa62Smrg#ifdef DEBUG 249f220fa62Smrg _glu_dprintf( "no good results\n" ); 250f220fa62Smrg#endif 251f220fa62Smrg return 0; // ill-conditioned, guess answer 252f220fa62Smrg } 253f220fa62Smrg } 254f220fa62Smrg break; 255f220fa62Smrg case 1: 256f220fa62Smrg return 1; 257f220fa62Smrg } 258f220fa62Smrg } else { 259f220fa62Smrg#ifdef DEBUG 260f220fa62Smrg _glu_dprintf( "case cd\n" ); 261f220fa62Smrg#endif 262f220fa62Smrg if( v1next->param[1] < v2next->param[1] ) 263f220fa62Smrg return 1; 264f220fa62Smrg else if( v1next->param[1] > v2next->param[1] ) 265f220fa62Smrg return 0; 266f220fa62Smrg else { 267f220fa62Smrg v2 = v2next++; 268f220fa62Smrg#ifdef DEBUG 269f220fa62Smrg _glu_dprintf( "incr\n" ); 270f220fa62Smrg#endif 271f220fa62Smrg if( v2 == v2last ) { 272f220fa62Smrg#ifdef DEBUG 273f220fa62Smrg _glu_dprintf( "no good results\n" ); 274f220fa62Smrg#endif 275f220fa62Smrg return 0; // ill-conditioned, guess answer 276f220fa62Smrg } 277f220fa62Smrg } 278f220fa62Smrg } 279f220fa62Smrg } 280f220fa62Smrg} 281f220fa62Smrg 282f220fa62Smrgint 283f220fa62SmrgSubdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1 284f220fa62Smrg{ 285e7980a23Smrg TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; 286e7980a23Smrg TrimVertex *v1last = &j1->pwlArc->pts[0]; 287e7980a23Smrg TrimVertex *v2 = &j2->pwlArc->pts[0]; 288e7980a23Smrg TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; 289e7980a23Smrg TrimVertex *v1next = v1-1; 290e7980a23Smrg TrimVertex *v2next = v2+1; 291f220fa62Smrg int sgn; 292f220fa62Smrg 293f220fa62Smrg assert( v1 != v1last ); 294f220fa62Smrg assert( v2 != v2last ); 295f220fa62Smrg 296f220fa62Smrg#ifndef NDEBUG 297f220fa62Smrg _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 ); 298f220fa62Smrg#endif 299f220fa62Smrg 300f220fa62Smrg // the arcs lie on the line (1 == v1->param[1]) 301f220fa62Smrg if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) 302f220fa62Smrg return 0; 303f220fa62Smrg 304f220fa62Smrg if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] ) 305f220fa62Smrg ::mylongjmp( jumpbuffer, 28 ); 306f220fa62Smrg 307f220fa62Smrg if( v1->param[0] < v2->param[0] ) 308f220fa62Smrg return 1; 309f220fa62Smrg else if( v1->param[0] > v2->param[0] ) 310f220fa62Smrg return 0; 311f220fa62Smrg 312f220fa62Smrg while( 1 ) { 313f220fa62Smrg if( v1next->param[1] < v2next->param[1] ) { 314f220fa62Smrg#ifndef NDEBUG 315f220fa62Smrg _glu_dprintf( "case a\n" ); 316f220fa62Smrg#endif 317f220fa62Smrg assert( v1->param[1] <= v1next->param[1] ); 318f220fa62Smrg assert( v2->param[1] <= v1next->param[1] ); 319f220fa62Smrg switch( bbox( v2, v2next, v1next, 0 ) ) { 320f220fa62Smrg case -1: 321f220fa62Smrg return 1; 322f220fa62Smrg case 0: 323f220fa62Smrg sgn = ccw( v1next, v2, v2next ); 324f220fa62Smrg if( sgn != -1 ) { 325f220fa62Smrg return sgn; 326f220fa62Smrg } else { 327f220fa62Smrg#ifdef DEBUG 328f220fa62Smrg _glu_dprintf( "decr\n" ); 329f220fa62Smrg#endif 330f220fa62Smrg v1 = v1next--; 331f220fa62Smrg if( v1 == v1last ) { 332f220fa62Smrg#ifdef DEBUG 333f220fa62Smrg _glu_dprintf( "no good results\n" ); 334f220fa62Smrg#endif 335f220fa62Smrg return 0; // ill-conditioned, guess answer 336f220fa62Smrg } 337f220fa62Smrg } 338f220fa62Smrg break; 339f220fa62Smrg case 1: 340f220fa62Smrg return 0; 341f220fa62Smrg } 342f220fa62Smrg } else if( v1next->param[1] > v2next->param[1] ) { 343f220fa62Smrg#ifndef NDEBUG 344f220fa62Smrg _glu_dprintf( "case b\n" ); 345f220fa62Smrg#endif 346f220fa62Smrg assert( v1->param[1] <= v2next->param[1] ); 347f220fa62Smrg assert( v2->param[1] <= v2next->param[1] ); 348f220fa62Smrg switch( bbox( v1, v1next, v2next, 0 ) ) { 349f220fa62Smrg case -1: 350f220fa62Smrg return 0; 351f220fa62Smrg case 0: 352f220fa62Smrg sgn = ccw( v1next, v1, v2next ); 353f220fa62Smrg if( sgn != -1 ) { 354f220fa62Smrg return sgn; 355f220fa62Smrg } else { 356f220fa62Smrg#ifdef DEBUG 357f220fa62Smrg _glu_dprintf( "incr\n" ); 358f220fa62Smrg#endif 359f220fa62Smrg v2 = v2next++; 360f220fa62Smrg if( v2 == v2last ) { 361f220fa62Smrg#ifdef DEBUG 362f220fa62Smrg _glu_dprintf( "no good results\n" ); 363f220fa62Smrg#endif 364f220fa62Smrg return 0; // ill-conditioned, guess answer 365f220fa62Smrg } 366f220fa62Smrg } 367f220fa62Smrg break; 368f220fa62Smrg case 1: 369f220fa62Smrg return 1; 370f220fa62Smrg } 371f220fa62Smrg } else { 372f220fa62Smrg#ifdef DEBUG 373f220fa62Smrg _glu_dprintf( "case ab\n" ); 374f220fa62Smrg#endif 375f220fa62Smrg if( v1next->param[0] < v2next->param[0] ) 376f220fa62Smrg return 1; 377f220fa62Smrg else if( v1next->param[0] > v2next->param[0] ) 378f220fa62Smrg return 0; 379f220fa62Smrg else { 380f220fa62Smrg#ifdef DEBUG 381f220fa62Smrg _glu_dprintf( "incr\n" ); 382f220fa62Smrg#endif 383f220fa62Smrg v2 = v2next++; 384f220fa62Smrg if( v2 == v2last ) { 385f220fa62Smrg#ifdef DEBUG 386f220fa62Smrg _glu_dprintf( "no good results\n" ); 387f220fa62Smrg#endif 388f220fa62Smrg return 0; // ill-conditioned, guess answer 389f220fa62Smrg } 390f220fa62Smrg } 391f220fa62Smrg } 392f220fa62Smrg } 393f220fa62Smrg} 394f220fa62Smrg 395f220fa62Smrgint 396f220fa62SmrgSubdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 ) 397f220fa62Smrg{ 398e7980a23Smrg TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1]; 399e7980a23Smrg TrimVertex *v1last = &j1->pwlArc->pts[0]; 400e7980a23Smrg TrimVertex *v2 = &j2->pwlArc->pts[0]; 401e7980a23Smrg TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1]; 402e7980a23Smrg TrimVertex *v1next = v1-1; 403e7980a23Smrg TrimVertex *v2next = v2+1; 404f220fa62Smrg int sgn; 405f220fa62Smrg 406f220fa62Smrg assert( v1 != v1last ); 407f220fa62Smrg assert( v2 != v2last ); 408f220fa62Smrg 409f220fa62Smrg#ifndef NDEBUG 410f220fa62Smrg _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 ); 411f220fa62Smrg#endif 412f220fa62Smrg 413f220fa62Smrg // the arcs lie on the line (1 == v1->param[1]) 414f220fa62Smrg if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] ) 415f220fa62Smrg return 0; 416f220fa62Smrg 417f220fa62Smrg if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] ) 418f220fa62Smrg ::mylongjmp( jumpbuffer, 28 ); 419f220fa62Smrg 420f220fa62Smrg if( v1->param[0] < v2->param[0] ) 421f220fa62Smrg return 0; 422f220fa62Smrg else if( v1->param[0] > v2->param[0] ) 423f220fa62Smrg return 1; 424f220fa62Smrg 425f220fa62Smrg while( 1 ) { 426f220fa62Smrg if( v1next->param[1] > v2next->param[1] ) { 427f220fa62Smrg#ifndef NDEBUG 428f220fa62Smrg _glu_dprintf( "case c\n" ); 429f220fa62Smrg#endif 430f220fa62Smrg assert( v1->param[1] >= v1next->param[1] ); 431f220fa62Smrg assert( v2->param[1] >= v1next->param[1] ); 432f220fa62Smrg switch( bbox( v2next, v2, v1next, 0 ) ) { 433f220fa62Smrg case -1: 434f220fa62Smrg return 0; 435f220fa62Smrg case 0: 436f220fa62Smrg sgn = ccw( v1next, v2, v2next ); 437f220fa62Smrg if( sgn != -1 ) 438f220fa62Smrg return sgn; 439f220fa62Smrg else { 440f220fa62Smrg v1 = v1next--; 441f220fa62Smrg#ifdef DEBUG 442f220fa62Smrg _glu_dprintf( "decr\n" ); 443f220fa62Smrg#endif 444f220fa62Smrg if( v1 == v1last ) { 445f220fa62Smrg#ifdef DEBUG 446f220fa62Smrg _glu_dprintf( "no good results\n" ); 447f220fa62Smrg#endif 448f220fa62Smrg return 0; // ill-conditioned, guess answer 449f220fa62Smrg } 450f220fa62Smrg } 451f220fa62Smrg break; 452f220fa62Smrg case 1: 453f220fa62Smrg return 1; 454f220fa62Smrg } 455f220fa62Smrg } else if( v1next->param[1] < v2next->param[1] ) { 456f220fa62Smrg#ifndef NDEBUG 457f220fa62Smrg _glu_dprintf( "case d\n" ); 458f220fa62Smrg assert( v1->param[1] >= v2next->param[1] ); 459f220fa62Smrg assert( v2->param[1] >= v2next->param[1] ); 460f220fa62Smrg#endif 461f220fa62Smrg switch( bbox( v1next, v1, v2next, 0 ) ) { 462f220fa62Smrg case -1: 463f220fa62Smrg return 1; 464f220fa62Smrg case 0: 465f220fa62Smrg sgn = ccw( v1next, v1, v2next ); 466f220fa62Smrg if( sgn != -1 ) 467f220fa62Smrg return sgn; 468f220fa62Smrg else { 469f220fa62Smrg v2 = v2next++; 470f220fa62Smrg#ifdef DEBUG 471f220fa62Smrg _glu_dprintf( "incr\n" ); 472f220fa62Smrg#endif 473f220fa62Smrg if( v2 == v2last ) { 474f220fa62Smrg#ifdef DEBUG 475f220fa62Smrg _glu_dprintf( "no good results\n" ); 476f220fa62Smrg#endif 477f220fa62Smrg return 0; // ill-conditioned, guess answer 478f220fa62Smrg } 479f220fa62Smrg } 480f220fa62Smrg break; 481f220fa62Smrg case 1: 482f220fa62Smrg return 0; 483f220fa62Smrg } 484f220fa62Smrg } else { 485f220fa62Smrg#ifdef DEBUG 486f220fa62Smrg _glu_dprintf( "case cd\n" ); 487f220fa62Smrg#endif 488f220fa62Smrg if( v1next->param[0] < v2next->param[0] ) 489f220fa62Smrg return 0; 490f220fa62Smrg else if( v1next->param[0] > v2next->param[0] ) 491f220fa62Smrg return 1; 492f220fa62Smrg else { 493f220fa62Smrg v2 = v2next++; 494f220fa62Smrg#ifdef DEBUG 495f220fa62Smrg _glu_dprintf( "incr\n" ); 496f220fa62Smrg#endif 497f220fa62Smrg if( v2 == v2last ) { 498f220fa62Smrg#ifdef DEBUG 499f220fa62Smrg _glu_dprintf( "no good results\n" ); 500f220fa62Smrg#endif 501f220fa62Smrg return 0; // ill-conditioned, guess answer 502f220fa62Smrg } 503f220fa62Smrg } 504f220fa62Smrg } 505f220fa62Smrg } 506f220fa62Smrg} 507f220fa62Smrg 508f220fa62Smrg 509f220fa62Smrg#ifndef NDEBUG 510f220fa62Smrgint 511e7980a23SmrgSubdivider::bbox( REAL sa, REAL sb, REAL sc, REAL ta, REAL tb, REAL tc ) 512f220fa62Smrg#else 513f220fa62Smrgint 514e7980a23SmrgSubdivider::bbox( REAL sa, REAL sb, REAL sc, REAL , REAL , REAL ) 515f220fa62Smrg#endif 516f220fa62Smrg{ 517f220fa62Smrg#ifndef NDEBUG 518f220fa62Smrg assert( tc >= ta ); 519f220fa62Smrg assert( tc <= tb ); 520f220fa62Smrg#endif 521f220fa62Smrg 522f220fa62Smrg if( sa < sb ) { 523f220fa62Smrg if( sc <= sa ) { 524f220fa62Smrg return -1; 525f220fa62Smrg } else if( sb <= sc ) { 526f220fa62Smrg return 1; 527f220fa62Smrg } else { 528f220fa62Smrg return 0; 529f220fa62Smrg } 530f220fa62Smrg } else if( sa > sb ) { 531f220fa62Smrg if( sc >= sa ) { 532f220fa62Smrg return 1; 533f220fa62Smrg } else if( sb >= sc ) { 534f220fa62Smrg return -1; 535f220fa62Smrg } else { 536f220fa62Smrg return 0; 537f220fa62Smrg } 538f220fa62Smrg } else { 539f220fa62Smrg if( sc > sa ) { 540f220fa62Smrg return 1; 541f220fa62Smrg } else if( sb > sc ) { 542f220fa62Smrg return -1; 543f220fa62Smrg } else { 544f220fa62Smrg return 0; 545f220fa62Smrg } 546f220fa62Smrg } 547f220fa62Smrg} 548f220fa62Smrg 549f220fa62Smrg/*---------------------------------------------------------------------------- 550f220fa62Smrg * ccw - determine how three points are oriented by computing their 551f220fa62Smrg * determinant. 552f220fa62Smrg * Return 1 if the vertices are ccw oriented, 553f220fa62Smrg * 0 if they are cw oriented, or 554f220fa62Smrg * -1 if the computation is ill-conditioned. 555f220fa62Smrg *---------------------------------------------------------------------------- 556f220fa62Smrg */ 557f220fa62Smrgint 558f220fa62SmrgSubdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c ) 559f220fa62Smrg{ 560f220fa62Smrg REAL d = det3( a, b, c ); 561f220fa62Smrg if( glu_abs(d) < 0.0001 ) return -1; 562f220fa62Smrg return (d < 0.0) ? 0 : 1; 563f220fa62Smrg} 564