www.pudn.com > fatmap2.zip > CLIP.CPP


 
/* 
 *      2D clipping of a triangle into a polygon using the clipping 
 *      boundarys LeftClip, RightClip, TopClip and BotClip. 
 * 
 *      The code is based on Sutherland-Hodgman algorithm where we 
 *      clip the polygon against each clipping boundary in turn. 
 * 
 *      Note! This code is far from optimal but it does what it is 
 *            supposed to do. 
 * 
 *      This source is part of the fatmap2.txt document by 
 *      Mats Byggmastar, mri@penti.sit.fi 
 *      17.4.1997 Jakobstad, Finland 
 * 
 *      Companies with self respect are encouraged to contact me if 
 *      any of this code is to be used as part of a commercial product. 
 */ 
 
 
#include "misc.h" 
 
float LeftClip  =   0.0; 
float RightClip = 320.0; 
float TopClip   =   0.0; 
float BotClip   = 200.0; 
 
 
inline int cliptestx(vertexclip * v) 
{ 
    int bits = 0; 
    if(v->y < LeftClip)     bits |= LEFT; 
    if(v->y > RightClip)    bits |= RIGHT; 
    return bits; 
} 
 
inline int cliptesty(vertexclip * v) 
{ 
    int bits = 0; 
    if(v->y < TopClip)      bits |= TOP; 
    if(v->y > BotClip)      bits |= BOT; 
    return bits; 
} 
 
/* 
 *      vbp is a pointer to a vertex array. The first 3 vertices in that 
 *      array is our source vertices. The rest of the array will be used 
 *      to hold new vertices created during clipping. 
 * 
 *      you can then access the new vertices using the *final variable 
 * 
 *      function returns the number of vertices in the resulting polygon 
 */ 
 
int ClipUV(vertexclip *** final, vertexclip * vbp) 
{ 
    int max, n, dsti; 
    static vertexclip * vp1[12], * vp2[12];     // vertex ptr buffers 
    vertexclip ** src = vp1; 
    vertexclip ** dst = vp2; 
    vertexclip ** tmp; 
 
    vp1[0] = vbp + 0; 
    vp1[1] = vbp + 1; 
    vp1[2] = vbp + 2; 
    vp1[3] = vbp + 0; 
 
    vbp += 3;       // Next free vertex 
 
    dsti = 0; 
    max = 3; 
 
    // left clip 
 
    for(n=0; nvisible & LEFT) == VISIBLE) { 
            dst[dsti++] = src1;                 // add visible vertex to list 
            if((src2->visible & LEFT) == VISIBLE) 
                continue; 
        } else 
            if((src2->visible & LEFT) != VISIBLE) 
                continue; 
        float a = (LeftClip - src1->x) / (src2->x - src1->x); 
        float ima = 1.0-a; 
        dst[dsti] = vbp++;                      // create new vertex 
        dst[dsti]->y = src1->y*ima + src2->y*a; 
        dst[dsti]->x = LeftClip; 
        dst[dsti]->u = src1->u*ima + src2->u*a; 
        dst[dsti]->v = src1->v*ima + src2->v*a; 
        dst[dsti]->visible = cliptesty(dst[dsti]); 
        dsti++; 
    } 
    dst[dsti] = dst[0]; 
    tmp = src; src = dst; dst = tmp;            // Swap src - dst buffers 
    max = dsti; 
    dsti = 0; 
 
    // right clip 
 
    for(n=0; nvisible & RIGHT) == VISIBLE) { 
            dst[dsti++] = src1;                 // add visible vertex to list 
            if((src2->visible & RIGHT) == VISIBLE) 
                continue; 
        } else 
            if((src2->visible & RIGHT) != VISIBLE) 
                continue; 
        float a = (RightClip - src1->x) / (src2->x - src1->x); 
        float ima = 1.0-a; 
        dst[dsti] = vbp++;                      // create new vertex 
        dst[dsti]->y = src1->y*ima + src2->y*a; 
        dst[dsti]->x = RightClip; 
        dst[dsti]->u = src1->u*ima + src2->u*a; 
        dst[dsti]->v = src1->v*ima + src2->v*a; 
        dst[dsti]->visible = cliptesty(dst[dsti]); 
        dsti++; 
    } 
    dst[dsti] = dst[0]; 
    tmp = src; src = dst; dst = tmp;            // swap src - dst buffers 
    max = dsti; 
    dsti = 0; 
 
    // top clip 
 
    for(n=0; nvisible & TOP) == VISIBLE) { 
            dst[dsti++] = src1;                 // add visible vertex to list 
            if((src2->visible & TOP) == VISIBLE) 
                continue; 
        } else 
            if((src2->visible & TOP) != VISIBLE) 
                continue; 
        float a = (TopClip - src1->y) / (src2->y - src1->y); 
        float ima = 1.0-a; 
        dst[dsti] = vbp++;                      // create new vertex 
        dst[dsti]->x = src1->x*ima + src2->x*a; 
        dst[dsti]->y = TopClip; 
        dst[dsti]->u = src1->u*ima + src2->u*a; 
        dst[dsti]->v = src1->v*ima + src2->v*a; 
        dst[dsti]->visible = cliptestx(dst[dsti]); 
        dsti++; 
    } 
    dst[dsti] = dst[0]; 
    tmp = src; src = dst; dst = tmp;            // swap src - dst buffers 
    max = dsti; 
    dsti = 0; 
 
    // bot clip 
 
    for(n=0; nvisible & BOT) == VISIBLE) { 
            dst[dsti++] = src1;                 // add visible vertex to list 
            if((src2->visible & BOT) == VISIBLE) 
                continue; 
        } else 
            if((src2->visible & BOT) != VISIBLE) 
                continue; 
        float a = (BotClip - src1->y) / (src2->y - src1->y); 
        float ima = 1.0-a; 
        dst[dsti] = vbp++;                      // create new vertex 
        dst[dsti]->x = src1->x*ima + src2->x*a; 
        dst[dsti]->y = BotClip; 
        dst[dsti]->u = src1->u*ima + src2->u*a; 
        dst[dsti]->v = src1->v*ima + src2->v*a; 
        dsti++; 
    } 
 
    *final = dst; 
     
    return dsti; 
}