varray.cc revision f220fa62
1/* 2** License Applicability. Except to the extent portions of this file are 3** made subject to an alternative license as permitted in the SGI Free 4** Software License B, Version 1.1 (the "License"), the contents of this 5** file are subject only to the provisions of the License. You may not use 6** this file except in compliance with the License. You may obtain a copy 7** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9** 10** http://oss.sgi.com/projects/FreeB 11** 12** Note that, as provided in the License, the Software is distributed on an 13** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17** 18** Original Code. The Original Code is: OpenGL Sample Implementation, 19** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 20** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 21** Copyright in any portions created by third parties is as indicated 22** elsewhere herein. All Rights Reserved. 23** 24** Additional Notice Provisions: The application programming interfaces 25** established by SGI in conjunction with the Original Code are The 26** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 27** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 28** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 29** Window System(R) (Version 1.3), released October 19, 1998. This software 30** was created using the OpenGL(R) version 1.2.1 Sample Implementation 31** published by SGI, but has not been independently verified as being 32** compliant with the OpenGL(R) version 1.2.1 Specification. 33*/ 34 35/* 36 * varray.c++ 37 * 38 */ 39 40#include "glimports.h" 41#include "myassert.h" 42#include "mystdio.h" 43#include "varray.h" 44#include "arc.h" 45#include "simplemath.h" // glu_abs() 46 47#define TINY 0.0001 48inline long sgn( REAL x ) 49{ 50 return (x < -TINY) ? -1 : ((x > TINY) ? 1 : 0 ); 51} 52 53 54Varray::Varray( void ) 55{ 56 int i; 57 58 varray = 0; 59 size = 0; 60 numquads = 0; 61 62 for (i = 0; i < 1000; i++) { 63 vval[i] = 0; 64 voffset[i] = 0; 65 } 66} 67 68Varray::~Varray( void ) 69{ 70 if( varray ) delete[] varray; 71} 72 73inline void 74Varray::update( Arc_ptr arc, long dir[2], REAL val ) 75{ 76 register long ds = sgn(arc->tail()[0] - arc->prev->tail()[0]); 77 register long dt = sgn(arc->tail()[1] - arc->prev->tail()[1]); 78 79 if( dir[0] != ds || dir[1] != dt ) { 80 dir[0] = ds; 81 dir[1] = dt; 82 append( val ); 83 } 84} 85 86void 87Varray::grow( long guess ) 88{ 89 if( size < guess ) { 90 size = guess * 2; 91 if( varray ) delete[] varray; 92 varray = new REAL[size]; 93 assert( varray != 0 ); 94 } 95} 96 97long 98Varray::init( REAL delta, Arc_ptr toparc, Arc_ptr botarc ) 99{ 100 Arc_ptr left = toparc->next; 101 Arc_ptr right = toparc; 102 long ldir[2], rdir[2]; 103 104 ldir[0] = sgn( left->tail()[0] - left->prev->tail()[0] ); 105 ldir[1] = sgn( left->tail()[1] - left->prev->tail()[1] ); 106 rdir[0] = sgn( right->tail()[0] - right->prev->tail()[0] ); 107 rdir[1] = sgn( right->tail()[1] - right->prev->tail()[1] ); 108 109 vval[0] = toparc->tail()[1]; 110 numquads = 0; 111 112 while( 1 ) { 113 switch( sgn( left->tail()[1] - right->prev->tail()[1] ) ) { 114 case 1: 115 left = left->next; 116 update( left, ldir, left->prev->tail()[1] ); 117 break; 118 case -1: 119 right = right->prev; 120 update( right, rdir, right->tail()[1] ); 121 break; 122 case 0: 123 if( glu_abs(left->tail()[1] - botarc->tail()[1]) < TINY) goto end; 124 if( glu_abs(left->tail()[0]-right->prev->tail()[0]) < TINY && 125 glu_abs(left->tail()[1]-right->prev->tail()[1]) < TINY) goto end; 126 left = left->next; 127 break; 128 } 129 } 130 131end: 132 append( botarc->tail()[1] ); 133 134 grow( ((long) ((vval[0] - vval[numquads])/delta)) + numquads + 2 ); 135 136 long i, index = 0; 137 for( i=0; i<numquads; i++ ) { 138 voffset[i] = index; 139 varray[index++] = vval[i]; 140 REAL dist = vval[i] - vval[i+1]; 141 if( dist > delta ) { 142 long steps = ((long) (dist/delta)) +1; 143 float deltav = - dist / (REAL) steps; 144 for( long j=1; j<steps; j++ ) 145 varray[index++] = vval[i] + j * deltav; 146 } 147 } 148 voffset[i] = index; 149 varray[index] = vval[i]; 150 return index; 151} 152 153