home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include "mytypes.h"
- #include "poly.h"
- #include "bezpt.h"
- #include "revolve.h"
- #include "readilbm.h"
- #include "mapstuff.h"
- #include "menuexp.h"
-
- #define FarRight 1e6
- #define FarLeft -1e6
- #define FarTop 0x7fff
- #define FarBottom -0x7fff
-
- /*
- #ifndef MANX
- #include "libraries/mathffp.h"
- #define ceil SPCeil
- #define floor SPFloor
- #define fabs SPAbs
- #endif
- */
-
- typedef struct { float left, right; } Hedge;
-
- static float *BezMapping = null,
- *RevMapping = null;
- static float revmin, revdiff,
- bezmin, bezdiff;
-
-
- /*
- * given the ptlist of a polygon, find its vertical range
- */
- static void FindVRange(scrnlist, top, bottom)
- register ScrnPair *scrnlist;
- short *top, *bottom;
- {
- short i;
- short localtop, localbot;
-
- localtop = FarBottom;
- localbot = FarTop;
-
- for( i = 4; i--; scrnlist++ ) {
- if( localtop < scrnlist->y ) localtop = scrnlist->y;
- if( localbot > scrnlist->y ) localbot = scrnlist->y;
- }
- *top = localtop;
- *bottom = localbot;
- }
- /*
- * allocate table to store a quick and dirty representation of the
- * quadrilateral segments
- */
- static Hedge *InitVRange( depth, tabptr, olddepth )
- short depth, *olddepth;
- Hedge *tabptr;
- {
- Hedge *edgel, *tab;
- if( *olddepth < depth || !tabptr ) {
- if( tabptr ) free( tabptr);
- tab = (Hedge *) malloc(sizeof(Hedge)*depth);
- *olddepth = depth;
- }
- else {
- tab = tabptr;
- }
- if( !tab ) return( null);
-
- for( edgel = tab; depth--; edgel++) {
- edgel->left = FarRight;
- edgel->right = FarLeft;
- }
- return( tab );
- }
-
-
- /*
- * add line to quadrilateral descriptions
- */
- static void AddVLine( tab, x1, y1, x2, y2 )
- Hedge *tab;
- short x1, y1, x2, y2;
- {
- short dy;
- float curx, slope;
- /*
- * want y1 to have smaller value, ie, y1 below y2
- */
- if( y1 > y2 ) {
- short temp;
- temp = y1; y1 = y2; y2 = temp;
- temp = x1; x1 = x2; x2 = temp;
- }
- dy = y2 - y1;
- tab += y1;
-
- if( !dy ) {
- if ( x1 < x2 ) {
- short tempx;
- tempx = x1; x1 = x2; x2 = tempx;
- }
- if( x2 < tab->left ) tab->left = x2;
- if( x1 > tab->right ) tab->right = x1;
- return;
- }
- slope = (float)(x2 - x1)/dy;
-
- curx = x1;
- #define ZipIt(xxx) { if( xxx < tab->left) tab->left = xxx; \
- if( xxx > tab->right ) tab->right = xxx; }
- ZipIt(curx);
- while( dy--) {
- curx += slope;
- tab++;
- ZipIt(curx);
- }
- }
-
-
- static void AdjMapXY( inx, iny, outpair)
- float inx, iny;
- ScrnPair *outpair;
- {
- float outx, outy;
- MapXYRatio( inx, iny, &outx, &outy);
-
- outpair->y = MapImageH * (bezmin + bezdiff * outy);
- outpair->x = MapImageV * (revmin + revdiff * outx);
-
- /*
- if( RevAxis == RevX ) {
- outpair->y = MapImageH * (bezmin + bezdiff * outy);
- outpair->x = MapImageV * (revmin + revdiff * outx);
- } else {
- outpair->x = MapImageH * (bezmin + bezdiff * outy);
- outpair->y = MapImageV * (revmin + revdiff * outx);
- }
- */
- }
-
- static void ScanCnvQuad( tab, pt)
- Hedge *tab;
- ScrnPair pt[];
- {
- register int i;
- ScrnPair *listb, *liste;
-
- liste = pt;
- listb = liste + 3;
- for ( i = 4; i--;) {
- AddVLine( tab, listb->x, listb->y, liste->x, liste->y);
- listb = liste++;
- }
- }
-
- static float AverageShade(pts)
- ScrnPair pts[];
- {
- register Hedge *tab;
- static Hedge *tabfree = null;
- static short olddepth = 0;
- short top, bot;
- long shade = 0,
- pixcnt = 0;
-
- FindVRange( pts, &top, &bot);
- tabfree = tab = InitVRange( top - bot + 1, tabfree, &olddepth);
- if(!tabfree) return(0.0);
-
- ScanCnvQuad( tab-bot, pts );
- #if DEBUG
- if( DebugOn ) {
- printf("AverageShade top is %d, bot = %d\n", top, bot );
- }
- #endif DEBUG
-
- while( bot <= top ) {
- register int hori;
- int right, left;
- #if DEBUG
- if( DebugOn ) {
- printf("....row %d \t%d -> %d\n", bot, left, right );
- }
- #endif DEBUG
-
- left = (int) ceil(tab->left - SingleTinyVal);
- right = (int)floor(tab->right+ SingleTinyVal);
-
- for( hori= left; hori <= right; hori++ ) {
- shade += GetImgPix( bot, hori);
- pixcnt++;
- }
-
- /*
- if( RevAxis == RevX ) {
- for( hori= left; hori <= right; hori++ ) {
- shade += GetImgPix( bot, hori);
- pixcnt++;
- }
- }
- else {
- for( hori= left; hori <= right; hori++ ) {
- shade += GetImgPix( hori, bot);
- pixcnt++;
- }
- }
- */
- tab++;
- bot++;
- }
- return( (float)shade / (pixcnt *(15 *16)) );
- }
-
- /*
- * mess with the number so truncation doesn't
- * do nasty things to a float containing an int
- */
- static int NearestInt( afloat )
- float afloat;
- {
- afloat += ( afloat > 0 )? 1e-2 : -1e-2;
- return( (int)afloat );
- }
-
-
- static void ShadeQuad(tab, top, bot, intensity)
- register Hedge *tab;
- short top, bot;
- float intensity;
- {
- short vert;
- float rowminl, rowminr,
- rowmaxl, rowmaxr;
- Hedge *oldtab, *nexttab;
-
- for ( vert = bot;
- nexttab = tab+1, vert <= top;
- vert++, oldtab = tab, tab++ ) {
- float hori;
- float colmin, colmax;
- float leftmost, rightmost;
- int ihori, ileftmost, irightmost;
- ScrnPair MpPnts[4];
-
- #define lefttop MpPnts[0]
- #define leftbot MpPnts[3]
- #define righttop MpPnts[1]
- #define rightbot MpPnts[2]
-
-
- rowminl = (float)vert;
- rowmaxr = rowmaxl = rowminr = rowminl;
-
- if( vert > bot && oldtab->left < tab->left ) {
- rowminl -= 0.5;
- }
- if( vert > bot && oldtab->right > tab->right ) {
- rowminr -= 0.5;
- }
- if( vert < top && nexttab->left < tab->left ) {
- rowmaxl += 0.5;
- }
- if( vert < top && nexttab->right > tab->right ) {
- rowmaxr += 0.5;
- }
-
- irightmost = NearestInt( tab->right );
- rightmost = irightmost;
- ileftmost = NearestInt( tab->left );
- leftmost = ileftmost;
- if( irightmost < ileftmost ) {
- irightmost = ileftmost;
- }
- for( ihori = leftmost, hori = leftmost;
- ihori <= irightmost;
- ihori += 1, hori += 1.0 ) {
-
-
- if( AbortDraw ) { return; }
-
- colmin = hori - 0.5;
- colmax = hori + 0.5;
-
- colmin =(colmin > leftmost)?colmin: tab->left;
- colmax =(colmax < rightmost)?colmax: tab->right;
-
- AdjMapXY( colmin, rowmaxl, &lefttop, MP_XMIN| MP_YMAX);
- AdjMapXY( colmax, rowmaxr, &righttop, MP_XMAX| MP_YMAX);
- AdjMapXY( colmin, rowminl, &leftbot, MP_XMIN| MP_YMIN);
- AdjMapXY( colmax, rowminr, &rightbot, MP_XMAX| MP_YMIN);
-
- PaintPoint(ihori, vert, AverageShade(MpPnts) *intensity);
- }
- }
- #undef lefttop
- #undef righttop
- #undef rightbot
- #undef leftbot
- }
-
-
- void DrawRhomMap(mpr)
- MapRhomboid *mpr;
- {
- short top, bottom;
- short vrange, hrange;
- static Hedge *tab = null;
- static short olddepth = 0;
-
- CalcMapConsts( mpr->rhom.pt );
- FindVRange( mpr->rhom.pt, &top, &bottom );
- tab = InitVRange( top - bottom + 1, tab, &olddepth );
- if(!tab) return;
- ScanCnvQuad( tab -bottom, mpr->rhom.pt );
-
- bezmin = BezMapping[mpr->bezindex];/* make it global */
- bezdiff = BezMapping[mpr->bezindex+1] - bezmin;
- revmin = RevMapping[mpr->revindex];
- revdiff = RevMapping[mpr->revindex+1] - revmin;
- #if DEBUG
- if( DebugOn ) {
- DBMAP(mpr->rhom.pt, mpr->bezindex, mpr->revindex);
- }
- #endif DEBUG
- ShadeQuad(tab, top, bottom, mpr->rhom.intensity);
- }
-
- #ifdef DEBUG
- DBMAP(ptlist, bindex, rindex)
- ScrnPair ptlist[];
- short bindex, rindex;
- {
- int i;
-
- printf("...................................\n");
- for( i = 0; i < 4; i++ ) {
- printf("%10d", ptlist[i].x);
- };
- printf("\n");
- for( i = 0; i < 4; i++ ) {
- printf("%10d", ptlist[i].y);
- };
- printf("\n");
- printf(" bezmin %f bezdiff %f index = %d \n", bezmin, bezdiff, bindex );
- printf(" revmin %f revdiff %f index = %d \n", revmin, revdiff, rindex );
- }
- #endif DEBUG
-
-
- /*
- * return true if image mappings could not be performed
- * false if successful
- */
- bool InitMapping() {
- float *vfmptr;
- float totallen = 0,
- scaling;
- short numvslices;
-
- if( BezMapping ) free( BezMapping );
- if( RevMapping ) free( RevMapping );
-
- /*
- * compute width of each bezier segment
- */
- numvslices = BezMesh*GetNumSegs() +1;
- vfmptr = BezMapping = (float *) malloc(sizeof(float) * numvslices);
- if( !BezMapping ) return(true);
-
- *vfmptr++ = totallen = 0.0;
- ResetActSeg();
- do {
- float t, ffromx, ftox, ffromy, ftoy;
- int i;
- InitCalcBez();
- for( i = 1, ffromx = StartPtX(ActSeg), ffromy = StartPtY(ActSeg);
- i <= BezMesh; i++, ffromx = ftox, ffromy = ftoy ) {
- float diffx, diffy;
-
- t = (float)i/BezMesh;
-
- CalcBezPt( t, &ftox, &ftoy );
- diffx = ftox - ffromx;
- diffy = ftoy - ffromy;
- totallen += sqrt( diffx * diffx + diffy * diffy );
- *vfmptr++ = totallen;
- }
- NextSeg();
- } while( ActSeg);
- /*
- * convert scale floating point values to integer pixel positions
- */
- scaling = 1.0 / totallen;
- for( vfmptr = BezMapping; numvslices; numvslices--, vfmptr++ ) {
- *vfmptr *= scaling;
- }
- /*
- * compute height of each revolution segment
- */
- RevMapping = (float *) malloc( sizeof(float) * (RevMesh + 1));
- if( !RevMapping ) return( true );
- {
- short i;
- for( i = 0; i <= RevMesh; i++ ) {
- RevMapping[i] = ((float) i)/RevMesh;
- }
- }
-
- return(false);
- }
-