static void ClipSkyPolygon(int nump, vec3 *vecs, int stage) { bool front, back; float d, e; float dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; vec3 newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if (nump > MAX_CLIP_VERTS-2) interface::Error("ClipSkyPolygon: MAX_CLIP_VERTS"); if (stage == 6) { // fully clipped, so draw it AddSkyPolygon (nump, vecs); return; } front = back = false; for (i=0; i<nump ; i++) { d = vec3::dotProduct(vecs[i], sky_clip[stage]); if (d > ON_EPSILON) { front = true; sides[i] = SIDE_FRONT; } else if (d < -ON_EPSILON) { back = true; sides[i] = SIDE_BACK; } else sides[i] = SIDE_ON; dists[i] = d; } if (!front || !back) { // not clipped ClipSkyPolygon (nump, vecs, stage+1); return; } // clip it sides[i] = sides[0]; dists[i] = dists[0]; vecs[i] = vecs[0]; newc[0] = newc[1] = 0; for (i=0; i<nump ; i++) { const vec3 &v = vecs[i]; switch (sides[i]) { case SIDE_FRONT: newv[0][newc[0]] = v; newc[0]++; break; case SIDE_BACK: newv[1][newc[1]] = v; newc[1]++; break; case SIDE_ON: newv[0][newc[0]] = v; newc[0]++; newv[1][newc[1]] = v; newc[1]++; break; } if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; d = dists[i] / (dists[i] - dists[i+1]); for (j=0 ; j<3 ; j++) { e = v[j] + d*(vecs[i + 1][j] - v[j]); newv[0][newc[0]][j] = e; newv[1][newc[1]][j] = e; } newc[0]++; newc[1]++; } // continue ClipSkyPolygon(newc[0], &newv[0][0], stage+1); ClipSkyPolygon(newc[1], &newv[1][0], stage+1); }
/* ================ ClipSkyPolygon ================ */ static void ClipSkyPolygon (int nump, bvec3_t vecs, int stage) { bfixed *norm; bfixed *v; qboolean front, back; bfixed d, e; bfixed dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; bvec3_t newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if (nump > MAX_CLIP_VERTS-2) ri.Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS"); if (stage == 6) { // fully clipped, so draw it AddSkyPolygon (nump, vecs); return; } front = back = qfalse; norm = sky_clip[stage]; for (i=0, v = vecs ; i<nump ; i++, v+=3) { d = FIXED_VEC3DOT (v, norm); if (d > ON_EPSILON) { front = qtrue; sides[i] = SIDE_FRONT; } else if (d < -ON_EPSILON) { back = qtrue; sides[i] = SIDE_BACK; } else sides[i] = SIDE_ON; dists[i] = d; } if (!front || !back) { // not clipped ClipSkyPolygon (nump, vecs, stage+1); return; } // clip it sides[i] = sides[0]; dists[i] = dists[0]; VectorCopy (vecs, (vecs+(i*3)) ); newc[0] = newc[1] = 0; for (i=0, v = vecs ; i<nump ; i++, v+=3) { switch (sides[i]) { case SIDE_FRONT: VectorCopy (v, newv[0][newc[0]]); newc[0]++; break; case SIDE_BACK: VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; case SIDE_ON: VectorCopy (v, newv[0][newc[0]]); newc[0]++; VectorCopy (v, newv[1][newc[1]]); newc[1]++; break; } if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; d = dists[i] / (dists[i] - dists[i+1]); for (j=0 ; j<3 ; j++) { e = v[j] + d*(v[j+3] - v[j]); newv[0][newc[0]][j] = e; newv[1][newc[1]][j] = e; } newc[0]++; newc[1]++; } // continue ClipSkyPolygon (newc[0], newv[0][0], stage+1); ClipSkyPolygon (newc[1], newv[1][0], stage+1); }
/* * ClipSkyPolygon */ static void ClipSkyPolygon(int nump, Vec3 vecs, int stage) { float *norm; float *v; qbool front, back; float d, e; float dists[MAX_CLIP_VERTS]; int sides[MAX_CLIP_VERTS]; Vec3 newv[2][MAX_CLIP_VERTS]; int newc[2]; int i, j; if(nump > MAX_CLIP_VERTS-2) ri.Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS"); if(stage == 6){ /* fully clipped, so draw it */ AddSkyPolygon (nump, vecs); return; } front = back = qfalse; norm = sky_clip[stage]; for(i=0, v = vecs; i<nump; i++, v+=3){ d = dotv3 (v, norm); if(d > ON_EPSILON){ front = qtrue; sides[i] = SIDE_FRONT; }else if(d < -ON_EPSILON){ back = qtrue; sides[i] = SIDE_BACK; }else sides[i] = SIDE_ON; dists[i] = d; } if(!front || !back){ /* not clipped */ ClipSkyPolygon (nump, vecs, stage+1); return; } /* clip it */ sides[i] = sides[0]; dists[i] = dists[0]; copyv3 (vecs, (vecs+(i*3))); newc[0] = newc[1] = 0; for(i=0, v = vecs; i<nump; i++, v+=3){ switch(sides[i]){ case SIDE_FRONT: copyv3 (v, newv[0][newc[0]]); newc[0]++; break; case SIDE_BACK: copyv3 (v, newv[1][newc[1]]); newc[1]++; break; case SIDE_ON: copyv3 (v, newv[0][newc[0]]); newc[0]++; copyv3 (v, newv[1][newc[1]]); newc[1]++; break; } if(sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) continue; d = dists[i] / (dists[i] - dists[i+1]); for(j=0; j<3; j++){ e = v[j] + d*(v[j+3] - v[j]); newv[0][newc[0]][j] = e; newv[1][newc[1]][j] = e; } newc[0]++; newc[1]++; } /* continue */ ClipSkyPolygon (newc[0], newv[0][0], stage+1); ClipSkyPolygon (newc[1], newv[1][0], stage+1); }