X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fpolyclip.c;h=35e6cd62a0fedf07263adcfc8fadae41b14ec1d7;hp=67e1c8344554da17d75ab66c5e9c8eb5c5f98606;hb=d956a9d9273eebfacfda58cb3bafff017269d5dc;hpb=a5c65ceb155188c8acee31a475f8db9f5b58f4b6 diff --git a/src/polyclip.c b/src/polyclip.c index 67e1c83..35e6cd6 100644 --- a/src/polyclip.c +++ b/src/polyclip.c @@ -11,6 +11,8 @@ struct ray { static int clip_edge(struct g3d_vertex *poly, int *vnumptr, const struct g3d_vertex *v0, const struct g3d_vertex *v1, const struct cplane *plane); +static int check_clip_edge(const struct g3d_vertex *v0, + const struct g3d_vertex *v1, const struct cplane *plane); static int clip_edge_frustum(struct g3d_vertex *poly, int *vnumptr, const struct g3d_vertex *v0, const struct g3d_vertex *v1, int fplane); static float distance_signed(float *pos, const struct cplane *plane); @@ -23,54 +25,69 @@ int clip_poly(struct g3d_vertex *vout, int *voutnum, { int i, nextidx, res; int edges_clipped = 0; - int out_vnum = 0; + + *voutnum = 0; for(i=0; i= vnum) nextidx = 0; - res = clip_edge(vout, &out_vnum, vin + i, vin + nextidx, plane); + res = clip_edge(vout, voutnum, vin + i, vin + nextidx, plane); if(res == 0) { ++edges_clipped; } } - if(out_vnum <= 0) { + if(*voutnum <= 0) { assert(edges_clipped == 0); return -1; } - *voutnum = out_vnum; return edges_clipped > 0 ? 0 : 1; } +int check_clip_poly(const struct g3d_vertex *v, int vnum, struct cplane *plane) +{ + int i, nextidx, res; + int edges_clipped = 0; + + for(i=0; i= vnum) nextidx = 0; + res = check_clip_edge(v + i, v + nextidx, plane); + if(res == 0) { + ++edges_clipped; + } + } + return edges_clipped ? 0 : res; +} int clip_frustum(struct g3d_vertex *vout, int *voutnum, const struct g3d_vertex *vin, int vnum, int fplane) { int i, nextidx, res; int edges_clipped = 0; - int out_vnum = 0; if(vnum == 1) { /* special case: point clipping */ return inside_frustum_plane(vin, fplane) ? 1 : -1; } + *voutnum = 0; + for(i=0; i= vnum) nextidx = 0; - res = clip_edge_frustum(vout, &out_vnum, vin + i, vin + nextidx, fplane); + res = clip_edge_frustum(vout, voutnum, vin + i, vin + nextidx, fplane); if(res == 0) { ++edges_clipped; } } - if(out_vnum <= 0) { + if(*voutnum <= 0) { assert(edges_clipped == 0); return -1; } - *voutnum = out_vnum; return edges_clipped > 0 ? 0 : 1; } @@ -163,6 +180,27 @@ static int clip_edge(struct g3d_vertex *poly, int *vnumptr, return 0; } +/* same as above, but only checks for clipping and classifies the edge */ +static int check_clip_edge(const struct g3d_vertex *v0, + const struct g3d_vertex *v1, const struct cplane *plane) +{ + float pos0[3], pos1[3]; + float d0, d1; + + pos0[0] = v0->x; pos0[1] = v0->y; pos0[2] = v0->z; + pos1[0] = v1->x; pos1[1] = v1->y; pos1[2] = v1->z; + + d0 = distance_signed(pos0, plane); + d1 = distance_signed(pos1, plane); + + if(d0 > 0.0f && d1 > 0.0f) { + return 1; + } + if(d0 < 0.0f && d1 < 0.0f) { + return -1; + } + return 0; +} static float distance_signed(float *pos, const struct cplane *plane) {