/* ============= R_ClipSpriteFace Clips the winding at clip_verts[clip_current] and changes clip_current Throws out the back side ============== */ static int R_ClipSpriteFace(int nump, clipplane_t pclipplane) { int i, outcount; double[] dists = new double[MAXWORKINGVERTS+1]; double frac, clipdist; double[] pclipnormal; double[][] @in; double[][] @out; double[] instep, vert2; int outstep; clipdist = pclipplane.dist; pclipnormal = pclipplane.normal; // calc dists if (clip_current != 0) { @in = clip_verts[1]; @out = clip_verts[0]; clip_current = 0; } else { @in = clip_verts[0]; @out = clip_verts[1]; clip_current = 1; } for (i=0 ; i<nump ; i++) { instep = @in[i]; dists[i] = mathlib.DotProduct(instep, pclipnormal) - clipdist; } // handle wraparound case dists[nump] = dists[0]; for(int kk = 0; kk < 5; kk++) @in[nump][kk] = @in[0][kk]; // clip the winding outstep = 0; outcount = 0; for (i=0 ; i<nump ; i++) { instep = @in[i]; if (dists[i] >= 0) { for (int kk = 0; kk < 5; kk++) @out[outstep][kk] = instep[kk]; outstep += 1; outcount++; } if (dists[i] == 0 || dists[i+1] == 0) continue; if ( (dists[i] > 0) == (dists[i+1] > 0) ) continue; // split it into a new vertex frac = dists[i] / (dists[i] - dists[i+1]); vert2 = @in[i + 1]; @out[outstep][0] = instep[0] + frac * (vert2[0] - instep[0]); @out[outstep][1] = instep[1] + frac * (vert2[1] - instep[1]); @out[outstep][2] = instep[2] + frac * (vert2[2] - instep[2]); @out[outstep][3] = instep[3] + frac * (vert2[3] - instep[3]); @out[outstep][4] = instep[4] + frac * (vert2[4] - instep[4]); outstep += 1; outcount++; } return outcount; }
/* * ================ * R_ClipEdge * ================ */ static void R_ClipEdge(model.mvertex_t pv0, model.mvertex_t pv1, clipplane_t clip) { double d0, d1, f; model.mvertex_t clipvert = new model.mvertex_t(); if (clip != null) { do { d0 = mathlib.DotProduct(pv0.position, clip.normal) - clip.dist; d1 = mathlib.DotProduct(pv1.position, clip.normal) - clip.dist; if (d0 >= 0) { // point 0 is unclipped if (d1 >= 0) { // both points are unclipped continue; } // only point 1 is clipped // we don't cache clipped edges cacheoffset = 0x7FFFFFFF; f = d0 / (d0 - d1); clipvert.position[0] = pv0.position[0] + f * (pv1.position[0] - pv0.position[0]); clipvert.position[1] = pv0.position[1] + f * (pv1.position[1] - pv0.position[1]); clipvert.position[2] = pv0.position[2] + f * (pv1.position[2] - pv0.position[2]); if (clip.leftedge) { r_leftclipped = true; r_leftexit = clipvert; } else if (clip.rightedge) { r_rightclipped = true; r_rightexit = clipvert; } R_ClipEdge(pv0, clipvert, clip.next); return; } else { // point 0 is clipped if (d1 < 0) { // both points are clipped // we do cache fully clipped edges if (!r_leftclipped) { cacheoffset = (uint)(FULLY_CLIPPED_CACHED | (r_framecount & FRAMECOUNT_MASK)); } return; } // only point 0 is clipped r_lastvertvalid = false; // we don't cache partially clipped edges cacheoffset = 0x7FFFFFFF; f = d0 / (d0 - d1); clipvert.position[0] = pv0.position[0] + f * (pv1.position[0] - pv0.position[0]); clipvert.position[1] = pv0.position[1] + f * (pv1.position[1] - pv0.position[1]); clipvert.position[2] = pv0.position[2] + f * (pv1.position[2] - pv0.position[2]); if (clip.leftedge) { r_leftclipped = true; r_leftenter = clipvert; } else if (clip.rightedge) { r_rightclipped = true; r_rightenter = clipvert; } R_ClipEdge(clipvert, pv1, clip.next); return; } } while ((clip = clip.next) != null); } // add the edge R_EmitEdge(pv0, pv1); }
/* * ============= * R_ClipSpriteFace * * Clips the winding at clip_verts[clip_current] and changes clip_current * Throws out the back side * ============== */ static int R_ClipSpriteFace(int nump, clipplane_t pclipplane) { int i, outcount; double[] dists = new double[MAXWORKINGVERTS + 1]; double frac, clipdist; double[] pclipnormal; double[][] @in; double[][] @out; double[] instep, vert2; int outstep; clipdist = pclipplane.dist; pclipnormal = pclipplane.normal; // calc dists if (clip_current != 0) { @in = clip_verts[1]; @out = clip_verts[0]; clip_current = 0; } else { @in = clip_verts[0]; @out = clip_verts[1]; clip_current = 1; } for (i = 0; i < nump; i++) { instep = @in[i]; dists[i] = mathlib.DotProduct(instep, pclipnormal) - clipdist; } // handle wraparound case dists[nump] = dists[0]; for (int kk = 0; kk < 5; kk++) { @in[nump][kk] = @in[0][kk]; } // clip the winding outstep = 0; outcount = 0; for (i = 0; i < nump; i++) { instep = @in[i]; if (dists[i] >= 0) { for (int kk = 0; kk < 5; kk++) { @out[outstep][kk] = instep[kk]; } outstep += 1; outcount++; } if (dists[i] == 0 || dists[i + 1] == 0) { continue; } if ((dists[i] > 0) == (dists[i + 1] > 0)) { continue; } // split it into a new vertex frac = dists[i] / (dists[i] - dists[i + 1]); vert2 = @in[i + 1]; @out[outstep][0] = instep[0] + frac * (vert2[0] - instep[0]); @out[outstep][1] = instep[1] + frac * (vert2[1] - instep[1]); @out[outstep][2] = instep[2] + frac * (vert2[2] - instep[2]); @out[outstep][3] = instep[3] + frac * (vert2[3] - instep[3]); @out[outstep][4] = instep[4] + frac * (vert2[4] - instep[4]); outstep += 1; outcount++; } return(outcount); }
/* ================ R_ClipEdge ================ */ static void R_ClipEdge(model.mvertex_t pv0, model.mvertex_t pv1, clipplane_t clip) { double d0, d1, f; model.mvertex_t clipvert = new model.mvertex_t(); if (clip != null) { do { d0 = mathlib.DotProduct(pv0.position, clip.normal) - clip.dist; d1 = mathlib.DotProduct(pv1.position, clip.normal) - clip.dist; if (d0 >= 0) { // point 0 is unclipped if (d1 >= 0) { // both points are unclipped continue; } // only point 1 is clipped // we don't cache clipped edges cacheoffset = 0x7FFFFFFF; f = d0 / (d0 - d1); clipvert.position[0] = pv0.position[0] + f * (pv1.position[0] - pv0.position[0]); clipvert.position[1] = pv0.position[1] + f * (pv1.position[1] - pv0.position[1]); clipvert.position[2] = pv0.position[2] + f * (pv1.position[2] - pv0.position[2]); if (clip.leftedge) { r_leftclipped = true; r_leftexit = clipvert; } else if (clip.rightedge) { r_rightclipped = true; r_rightexit = clipvert; } R_ClipEdge(pv0, clipvert, clip.next); return; } else { // point 0 is clipped if (d1 < 0) { // both points are clipped // we do cache fully clipped edges if (!r_leftclipped) cacheoffset = (uint)(FULLY_CLIPPED_CACHED | (r_framecount & FRAMECOUNT_MASK)); return; } // only point 0 is clipped r_lastvertvalid = false; // we don't cache partially clipped edges cacheoffset = 0x7FFFFFFF; f = d0 / (d0 - d1); clipvert.position[0] = pv0.position[0] + f * (pv1.position[0] - pv0.position[0]); clipvert.position[1] = pv0.position[1] + f * (pv1.position[1] - pv0.position[1]); clipvert.position[2] = pv0.position[2] + f * (pv1.position[2] - pv0.position[2]); if (clip.leftedge) { r_leftclipped = true; r_leftenter = clipvert; } else if (clip.rightedge) { r_rightclipped = true; r_rightenter = clipvert; } R_ClipEdge(clipvert, pv1, clip.next); return; } } while ((clip = clip.next) != null); } // add the edge R_EmitEdge(pv0, pv1); }