/* ================ R_AliasDrawModel ================ */ static void R_AliasDrawModel(alight_t plighting) { r_amodels_drawn++; // cache align pfinalverts = (draw.finalvert_t[])finalverts; pauxverts = auxverts; paliashdr = (model.aliashdr_t)model.Mod_Extradata (currententity.model); pmdl = (model.mdl_t)paliashdr.model; R_AliasSetupSkin (); R_AliasSetUpTransform (currententity.trivial_accept); R_AliasSetupLighting (plighting); R_AliasSetupFrame (); if (currententity.colormap == null) sys_linux.Sys_Error ("R_AliasDrawModel: !currententity.colormap"); r_affinetridesc.drawtype = (currententity.trivial_accept == 3) && r_recursiveaffinetriangles; if (r_affinetridesc.drawtype) { draw.D_PolysetUpdateTables (); // FIXME: precalc... } else { } acolormap = currententity.colormap; if (currententity != client.cl.viewent) ziscale = (double)0x8000 * (double)0x10000; else ziscale = (double)0x8000 * (double)0x10000 * 3.0; if (currententity.trivial_accept != 0) R_AliasPrepareUnclippedPoints (); else R_AliasPreparePoints (); }
/* ================ R_AliasCheckBBox ================ */ static bool R_AliasCheckBBox() { int i, flags, frame, numv; model.aliashdr_t pahdr; double zi, v0, v1, frac; double[][] basepts = new double[8][]; draw.finalvert_t pv0, pv1; draw.finalvert_t[] viewpts = new draw.finalvert_t[16]; auxvert_t pa0, pa1; auxvert_t[] viewaux = new auxvert_t[16]; model.maliasframedesc_t pframedesc; bool zclipped, zfullyclipped; uint anyclip, allclip; int minz; int kk; for (kk = 0; kk < 16; kk++) viewpts[kk] = new draw.finalvert_t(); for (kk = 0; kk < 16; kk++) viewaux[kk] = new auxvert_t(); for (kk = 0; kk < 8; kk++) basepts[kk] = new double[3] {0, 0, 0}; // expand, rotate, and translate points into worldspace currententity.trivial_accept = 0; pmodel = currententity.model; pahdr = (model.aliashdr_t)model.Mod_Extradata (pmodel); pmdl = (model.mdl_t)pahdr.model; R_AliasSetUpTransform (0); // construct the base bounding box for this frame frame = currententity.frame; // TODO: don't repeat this check when drawing? if ((frame >= pmdl.numframes) || (frame < 0)) { console.Con_DPrintf ("No such frame " + frame + " " + pmodel.name + "\n"); frame = 0; } pframedesc = pahdr.frames[frame]; // x worldspace coordinates basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = (double)pframedesc.bboxmin.v[0]; basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = (double)pframedesc.bboxmax.v[0]; // y worldspace coordinates basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = (double)pframedesc.bboxmin.v[1]; basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = (double)pframedesc.bboxmax.v[1]; // z worldspace coordinates basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = (double)pframedesc.bboxmin.v[2]; basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = (double)pframedesc.bboxmax.v[2]; zclipped = false; zfullyclipped = true; minz = 9999; for (i=0; i<8 ; i++) { R_AliasTransformVector (basepts[i], viewaux[i].fv); if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) { // we must clip points that are closer than the near clip plane viewpts[i].flags = ALIAS_Z_CLIP; zclipped = true; } else { if (viewaux[i].fv[2] < minz) minz = (int)viewaux[i].fv[2]; viewpts[i].flags = 0; zfullyclipped = false; } } if (zfullyclipped) { return false; // everything was near-z-clipped } numv = 8; if (zclipped) { // organize points by edges, use edges to get new points (possible trivial // reject) for (i=0 ; i<12 ; i++) { // edge endpoints pv0 = viewpts[aedges[i].index0]; pv1 = viewpts[aedges[i].index1]; pa0 = viewaux[aedges[i].index0]; pa1 = viewaux[aedges[i].index1]; // if one end is clipped and the other isn't, make a new point if ((pv0.flags ^ pv1.flags) != 0) { frac = (ALIAS_Z_CLIP_PLANE - pa0.fv[2]) / (pa1.fv[2] - pa0.fv[2]); viewaux[numv].fv[0] = pa0.fv[0] + (pa1.fv[0] - pa0.fv[0]) * frac; viewaux[numv].fv[1] = pa0.fv[1] + (pa1.fv[1] - pa0.fv[1]) * frac; viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE; viewpts[numv].flags = 0; numv++; } } } // project the vertices that remain after clipping anyclip = 0; allclip = ALIAS_XY_CLIP_MASK; // TODO: probably should do this loop in ASM, especially if we use floats for (i=0 ; i<numv ; i++) { // we don't need to bother with vertices that were z-clipped if ((viewpts[i].flags & ALIAS_Z_CLIP) != 0) continue; zi = 1.0 / viewaux[i].fv[2]; // FIXME: do with chop mode in ASM, or convert to float v0 = (viewaux[i].fv[0] * xscale * zi) + xcenter; v1 = (viewaux[i].fv[1] * yscale * zi) + ycenter; flags = 0; if (v0 < r_refdef.fvrectx) flags |= ALIAS_LEFT_CLIP; if (v1 < r_refdef.fvrecty) flags |= ALIAS_TOP_CLIP; if (v0 > r_refdef.fvrectright) flags |= ALIAS_RIGHT_CLIP; if (v1 > r_refdef.fvrectbottom) flags |= ALIAS_BOTTOM_CLIP; anyclip |= (uint)flags; allclip &= (uint)flags; } if (allclip != 0) return false; // trivial reject off one side currententity.trivial_accept = ((anyclip == 0) && !zclipped) ? 1 : 0; if (currententity.trivial_accept != 0) { if (minz > (r_aliastransition + (pmdl.size * r_resfudge))) { currententity.trivial_accept |= 2; } } return true; }