public static int BOX_ON_PLANE_SIDE(double[] emins, double[] emaxs, model.mplane_t p) { return ((p.type < 3) ? ( (p.dist <= emins[p.type]) ? 1 : ( (p.dist >= emaxs[p.type]) ? 2 : 3 ) ) : BoxOnPlaneSide(emins, emaxs, p)); }
static render() { int kk; int i, j; for (kk = 0; kk < 4; kk++) { screenedge[kk] = new model.mplane_t(); } for (kk = 0; kk < 4; kk++) { view_clipplanes[kk] = new render.clipplane_t(); } for (kk = 0; kk < 16; kk++) { world_clipplanes[kk] = new render.clipplane_t(); } for (i = 0; i < 2; i++) { for (j = 0; j < MAXWORKINGVERTS; j++) { clip_verts[i][j] = new double[5]; } } for (i = 0; i < 2; i++) { for (j = 0; j < 8; j++) { fva[i][j] = new draw.finalvert_t(); } } for (kk = 0; kk < 8; kk++) { av[kk] = new auxvert_t(); } r_alias_init(); }
/* ================== BoxOnPlaneSide Returns 1, 2, or 1 + 2 ================== */ static int BoxOnPlaneSide (double[] emins, double[] emaxs, model.mplane_t p) { double dist1, dist2; int sides; /* // this is done by the BOX_ON_PLANE_SIDE macro before calling this // function // fast axial cases if (p.type < 3) { if (p.dist <= emins[p.type]) return 1; if (p.dist >= emaxs[p.type]) return 2; return 3; } */ // general case switch (p.signbits) { case 0: dist1 = p.normal[0]*emaxs[0] + p.normal[1]*emaxs[1] + p.normal[2]*emaxs[2]; dist2 = p.normal[0]*emins[0] + p.normal[1]*emins[1] + p.normal[2]*emins[2]; break; case 1: dist1 = p.normal[0]*emins[0] + p.normal[1]*emaxs[1] + p.normal[2]*emaxs[2]; dist2 = p.normal[0]*emaxs[0] + p.normal[1]*emins[1] + p.normal[2]*emins[2]; break; case 2: dist1 = p.normal[0]*emaxs[0] + p.normal[1]*emins[1] + p.normal[2]*emaxs[2]; dist2 = p.normal[0]*emins[0] + p.normal[1]*emaxs[1] + p.normal[2]*emins[2]; break; case 3: dist1 = p.normal[0]*emins[0] + p.normal[1]*emins[1] + p.normal[2]*emaxs[2]; dist2 = p.normal[0]*emaxs[0] + p.normal[1]*emaxs[1] + p.normal[2]*emins[2]; break; case 4: dist1 = p.normal[0]*emaxs[0] + p.normal[1]*emaxs[1] + p.normal[2]*emins[2]; dist2 = p.normal[0]*emins[0] + p.normal[1]*emins[1] + p.normal[2]*emaxs[2]; break; case 5: dist1 = p.normal[0]*emins[0] + p.normal[1]*emaxs[1] + p.normal[2]*emins[2]; dist2 = p.normal[0]*emaxs[0] + p.normal[1]*emins[1] + p.normal[2]*emaxs[2]; break; case 6: dist1 = p.normal[0]*emaxs[0] + p.normal[1]*emins[1] + p.normal[2]*emins[2]; dist2 = p.normal[0]*emins[0] + p.normal[1]*emaxs[1] + p.normal[2]*emaxs[2]; break; case 7: dist1 = p.normal[0]*emins[0] + p.normal[1]*emins[1] + p.normal[2]*emins[2]; dist2 = p.normal[0]*emaxs[0] + p.normal[1]*emaxs[1] + p.normal[2]*emaxs[2]; break; default: dist1 = dist2 = 0; // shut up compiler BOPS_Error (); break; } sides = 0; if (dist1 >= p.dist) sides = 1; if (dist2 < p.dist) sides |= 2; return sides; }
/* * ================ * R_RecursiveClipBPoly * ================ */ static void R_RecursiveClipBPoly(bedge_t pedges, model.mnode_t pnode, model.msurface_t psurf) { bedge_t[] psideedges = new bedge_t[2]; bedge_t pnextedge, ptedge; int i, side, lastside; double dist, frac, lastdist; model.mplane_t splitplane, tplane = new model.mplane_t(); model.mvertex_t pvert, plastvert, ptvert; model.node_or_leaf_t pn; psideedges[0] = psideedges[1] = null; makeclippededge = false; // transform the BSP plane into model space // FIXME: cache these? splitplane = pnode.plane; tplane.dist = splitplane.dist - mathlib.DotProduct(r_entorigin, splitplane.normal); tplane.normal[0] = mathlib.DotProduct(entity_rotation[0], splitplane.normal); tplane.normal[1] = mathlib.DotProduct(entity_rotation[1], splitplane.normal); tplane.normal[2] = mathlib.DotProduct(entity_rotation[2], splitplane.normal); // clip edges to BSP plane for ( ; pedges != null; pedges = pnextedge) { pnextedge = pedges.pnext; // set the status for the last point as the previous point // FIXME: cache this stuff somehow? plastvert = pedges.v[0]; lastdist = mathlib.DotProduct(plastvert.position, tplane.normal) - tplane.dist; if (lastdist > 0) { lastside = 0; } else { lastside = 1; } pvert = pedges.v[1]; dist = mathlib.DotProduct(pvert.position, tplane.normal) - tplane.dist; if (dist > 0) { side = 0; } else { side = 1; } if (side != lastside) { // clipped if (numbverts >= MAX_BMODEL_VERTS) { return; } // generate the clipped vertex frac = lastdist / (lastdist - dist); ptvert = pbverts[numbverts++]; ptvert.position[0] = plastvert.position[0] + frac * (pvert.position[0] - plastvert.position[0]); ptvert.position[1] = plastvert.position[1] + frac * (pvert.position[1] - plastvert.position[1]); ptvert.position[2] = plastvert.position[2] + frac * (pvert.position[2] - plastvert.position[2]); // split into two edges, one on each side, and remember entering // and exiting points // FIXME: share the clip edge by having a winding direction flag? if (numbedges >= (MAX_BMODEL_EDGES - 1)) { console.Con_Printf("Out of edges for bmodel\n"); return; } ptedge = pbedges[numbedges]; ptedge.pnext = psideedges[lastside]; psideedges[lastside] = ptedge; ptedge.v[0] = plastvert; ptedge.v[1] = ptvert; ptedge = pbedges[numbedges + 1]; ptedge.pnext = psideedges[side]; psideedges[side] = ptedge; ptedge.v[0] = ptvert; ptedge.v[1] = pvert; numbedges += 2; if (side == 0) { // entering for front, exiting for back pfrontenter = ptvert; makeclippededge = true; } else { pfrontexit = ptvert; makeclippededge = true; } } else { // add the edge to the appropriate side pedges.pnext = psideedges[side]; psideedges[side] = pedges; } } // if anything was clipped, reconstitute and add the edges along the clip // plane to both sides (but in opposite directions) if (makeclippededge) { if (numbedges >= (MAX_BMODEL_EDGES - 2)) { console.Con_Printf("Out of edges for bmodel\n"); return; } ptedge = pbedges[numbedges]; ptedge.pnext = psideedges[0]; psideedges[0] = ptedge; ptedge.v[0] = pfrontexit; ptedge.v[1] = pfrontenter; ptedge = pbedges[numbedges + 1]; ptedge.pnext = psideedges[1]; psideedges[1] = ptedge; ptedge.v[0] = pfrontenter; ptedge.v[1] = pfrontexit; numbedges += 2; } // draw or recurse further for (i = 0; i < 2; i++) { if (psideedges[i] != null) { // draw if we've reached a non-solid leaf, done if all that's left is a // solid leaf, and continue down the tree if it's not a leaf pn = pnode.children[i]; // we're done with this branch if the node or leaf isn't in the PVS if (pn.visframe == r_visframecount) { if (pn.contents < 0) { if (pn.contents != bspfile.CONTENTS_SOLID) { r_currentbkey = ((model.mleaf_t)pn).key; R_RenderBmodelFace(psideedges[i], psurf); } } else { R_RecursiveClipBPoly(psideedges[i], (model.mnode_t)pnode.children[i], psurf); } } } } }
/* * ================ * R_TransformPlane * ================ */ void R_TransformPlane(model.mplane_t p, ref double normal, ref double dist) { }