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;
}