/* ================ R_RenderFace ================ */ static void R_RenderFace(model.msurface_t fa, int clipflags) { int i, lindex; uint mask; model.mplane_t pplane; double distinv; double[] p_normal = new double[3] {0, 0, 0}; model.medge_t[] pedges; model.medge_t tedge = new model.medge_t(); clipplane_t pclip; // skip out if no more surfs if ((surface_p) >= surf_max) { r_outofsurfaces++; return; } // ditto if not enough edges left, or switch to auxedges if possible if ((edge_p + fa.numedges + 4) >= edge_max) { r_outofedges += fa.numedges; return; } c_faceclip++; // set up clip planes pclip = null; for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) { if ((clipflags & mask) != 0) { view_clipplanes[i].next = pclip; pclip = view_clipplanes[i]; } } // push the edges through r_emitted = 0; r_nearzi = 0; r_nearzionly = false; makeleftedge = makerightedge = false; pedges = currententity.model.edges; r_lastvertvalid = false; for (i=0 ; i<fa.numedges ; i++) { lindex = currententity.model.surfedges[fa.firstedge + i]; if (lindex > 0) { r_pedge = pedges[lindex]; // if the edge is cached, we can just reuse the edge if (!insubmodel) { if ((r_pedge.cachededgeoffset & FULLY_CLIPPED_CACHED) != 0) { if ((r_pedge.cachededgeoffset & FRAMECOUNT_MASK) == r_framecount) { r_lastvertvalid = false; continue; } } else { if ((edge_p > r_pedge.cachededgeoffset) && (r_edges[r_pedge.cachededgeoffset].owner == r_pedge)) { R_EmitCachedEdge (); r_lastvertvalid = false; continue; } } } // assume it's cacheable cacheoffset = (uint)edge_p; r_leftclipped = r_rightclipped = false; R_ClipEdge (r_pcurrentvertbase[r_pedge.v[0]], r_pcurrentvertbase[r_pedge.v[1]], pclip); r_pedge.cachededgeoffset = cacheoffset; if (r_leftclipped) makeleftedge = true; if (r_rightclipped) makerightedge = true; r_lastvertvalid = true; } else { lindex = -lindex; r_pedge = pedges[lindex]; // if the edge is cached, we can just reuse the edge if (!insubmodel) { if ((r_pedge.cachededgeoffset & FULLY_CLIPPED_CACHED) != 0) { if ((r_pedge.cachededgeoffset & FRAMECOUNT_MASK) == r_framecount) { r_lastvertvalid = false; continue; } } else { // it's cached if the cached edge is valid and is owned // by this medge_t if ((edge_p > r_pedge.cachededgeoffset) && (r_edges[r_pedge.cachededgeoffset].owner == r_pedge)) { R_EmitCachedEdge (); r_lastvertvalid = false; continue; } } } // assume it's cacheable cacheoffset = (uint)edge_p; r_leftclipped = r_rightclipped = false; R_ClipEdge (r_pcurrentvertbase[r_pedge.v[1]], r_pcurrentvertbase[r_pedge.v[0]], pclip); r_pedge.cachededgeoffset = cacheoffset; if (r_leftclipped) makeleftedge = true; if (r_rightclipped) makerightedge = true; r_lastvertvalid = true; } } // if there was a clip off the left edge, add that edge too // FIXME: faster to do in screen space? // FIXME: share clipped edges? if (makeleftedge) { r_pedge = tedge; r_lastvertvalid = false; R_ClipEdge (r_leftexit, r_leftenter, pclip.next); } // if there was a clip off the right edge, get the right r_nearzi if (makerightedge) { r_pedge = tedge; r_lastvertvalid = false; r_nearzionly = true; R_ClipEdge (r_rightexit, r_rightenter, view_clipplanes[1].next); } // if no edges made it out, return without posting the surface if (r_emitted == 0) return; r_polycount++; surfaces[surface_p].data = fa; surfaces[surface_p].nearzi = r_nearzi; surfaces[surface_p].flags = fa.flags; surfaces[surface_p].insubmodel = insubmodel; surfaces[surface_p].spanstate = 0; surfaces[surface_p].entity = currententity; surfaces[surface_p].key = r_currentkey++; surfaces[surface_p].spans = null; pplane = fa.plane; // FIXME: cache this? TransformVector(pplane.normal, p_normal); // FIXME: cache this? distinv = 1.0 / (pplane.dist - mathlib.DotProduct(modelorg, pplane.normal)); surfaces[surface_p].d_zistepu = p_normal[0] * xscaleinv * distinv; surfaces[surface_p].d_zistepv = -p_normal[1] * yscaleinv * distinv; surfaces[surface_p].d_ziorigin = p_normal[2] * distinv - xcenter * surfaces[surface_p].d_zistepu - ycenter * surfaces[surface_p].d_zistepv; //JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); surface_p++; }
/* ================ R_RenderBmodelFace ================ */ static void R_RenderBmodelFace(bedge_t pedges, model.msurface_t psurf) { int i; uint mask; model.mplane_t pplane; double distinv; double[] p_normal = new double[3] {0, 0, 0}; model.medge_t tedge = new model.medge_t(); clipplane_t pclip; // skip out if no more surfs if (surface_p >= surf_max) { r_outofsurfaces++; return; } // ditto if not enough edges left, or switch to auxedges if possible if ((edge_p + psurf.numedges + 4) >= edge_max) { r_outofedges += psurf.numedges; return; } c_faceclip++; // this is a dummy to give the caching mechanism someplace to write to r_pedge = tedge; // set up clip planes pclip = null; for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) { if ((r_clipflags & mask) != 0) { view_clipplanes[i].next = pclip; pclip = view_clipplanes[i]; } } // push the edges through r_emitted = 0; r_nearzi = 0; r_nearzionly = false; makeleftedge = makerightedge = false; // FIXME: keep clipped bmodel edges in clockwise order so last vertex caching // can be used? r_lastvertvalid = false; for ( ; pedges != null ; pedges = pedges.pnext) { r_leftclipped = r_rightclipped = false; R_ClipEdge (pedges.v[0], pedges.v[1], pclip); if (r_leftclipped) makeleftedge = true; if (r_rightclipped) makerightedge = true; } // if there was a clip off the left edge, add that edge too // FIXME: faster to do in screen space? // FIXME: share clipped edges? if (makeleftedge) { r_pedge = tedge; R_ClipEdge (r_leftexit, r_leftenter, pclip.next); } // if there was a clip off the right edge, get the right r_nearzi if (makerightedge) { r_pedge = tedge; r_nearzionly = true; R_ClipEdge (r_rightexit, r_rightenter, view_clipplanes[1].next); } // if no edges made it out, return without posting the surface if (r_emitted == 0) return; r_polycount++; surfaces[surface_p].data = psurf; surfaces[surface_p].nearzi = r_nearzi; surfaces[surface_p].flags = psurf.flags; surfaces[surface_p].insubmodel = true; surfaces[surface_p].spanstate = 0; surfaces[surface_p].entity = currententity; surfaces[surface_p].key = r_currentbkey; surfaces[surface_p].spans = null; pplane = psurf.plane; // FIXME: cache this? TransformVector (pplane.normal, p_normal); // FIXME: cache this? distinv = 1.0 / (pplane.dist - mathlib.DotProduct (modelorg, pplane.normal)); surfaces[surface_p].d_zistepu = p_normal[0] * xscaleinv * distinv; surfaces[surface_p].d_zistepv = -p_normal[1] * yscaleinv * distinv; surfaces[surface_p].d_ziorigin = p_normal[2] * distinv - xcenter * surfaces[surface_p].d_zistepu - ycenter * surfaces[surface_p].d_zistepv; //JDC VectorCopy (r_worldmodelorg, surface_p.modelorg); surface_p++; }