|
|
1.1 ! root 1: // r_alias.c: routines for setting up to draw alias models ! 2: ! 3: #include "quakedef.h" ! 4: #include "r_local.h" ! 5: #include "d_local.h" // FIXME: shouldn't be needed (is needed for patch ! 6: // right now, but that should move) ! 7: ! 8: #define LIGHT_MIN 5 // lowest light value we'll allow, to avoid the ! 9: // need for inner-loop light clamping ! 10: ! 11: mtriangle_t *ptriangles; ! 12: affinetridesc_t r_affinetridesc; ! 13: ! 14: void * acolormap; // FIXME: should go away ! 15: ! 16: trivertx_t *r_apverts; ! 17: ! 18: // TODO: these probably will go away with optimized rasterization ! 19: mdl_t *pmdl; ! 20: vec3_t r_plightvec; ! 21: int r_ambientlight; ! 22: float r_shadelight; ! 23: aliashdr_t *paliashdr; ! 24: finalvert_t *pfinalverts; ! 25: auxvert_t *pauxverts; ! 26: static float ziscale; ! 27: static model_t *pmodel; ! 28: ! 29: static vec3_t alias_forward, alias_right, alias_up; ! 30: ! 31: static maliasskindesc_t *pskindesc; ! 32: ! 33: int r_amodels_drawn; ! 34: int a_skinwidth; ! 35: int r_anumverts; ! 36: ! 37: float aliastransform[3][4]; ! 38: ! 39: typedef struct { ! 40: int index0; ! 41: int index1; ! 42: } aedge_t; ! 43: ! 44: static aedge_t aedges[12] = { ! 45: {0, 1}, {1, 2}, {2, 3}, {3, 0}, ! 46: {4, 5}, {5, 6}, {6, 7}, {7, 4}, ! 47: {0, 5}, {1, 4}, {2, 7}, {3, 6} ! 48: }; ! 49: ! 50: #define NUMVERTEXNORMALS 162 ! 51: ! 52: float r_avertexnormals[NUMVERTEXNORMALS][3] = { ! 53: #include "anorms.h" ! 54: }; ! 55: ! 56: void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, ! 57: stvert_t *pstverts); ! 58: void R_AliasSetUpTransform (int trivial_accept); ! 59: void R_AliasTransformVector (vec3_t in, vec3_t out); ! 60: void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av, ! 61: trivertx_t *pverts, stvert_t *pstverts); ! 62: void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av); ! 63: ! 64: ! 65: /* ! 66: ================ ! 67: R_AliasCheckBBox ! 68: ================ ! 69: */ ! 70: qboolean R_AliasCheckBBox (void) ! 71: { ! 72: int i, flags, frame, numv; ! 73: aliashdr_t *pahdr; ! 74: float zi, basepts[8][3], v0, v1, frac; ! 75: finalvert_t *pv0, *pv1, viewpts[16]; ! 76: auxvert_t *pa0, *pa1, viewaux[16]; ! 77: maliasframedesc_t *pframedesc; ! 78: qboolean zclipped, zfullyclipped; ! 79: unsigned anyclip, allclip; ! 80: int minz; ! 81: ! 82: // expand, rotate, and translate points into worldspace ! 83: ! 84: currententity->trivial_accept = 0; ! 85: pmodel = currententity->model; ! 86: pahdr = Mod_Extradata (pmodel); ! 87: pmdl = (mdl_t *)((byte *)pahdr + pahdr->model); ! 88: ! 89: R_AliasSetUpTransform (0); ! 90: ! 91: // construct the base bounding box for this frame ! 92: frame = currententity->frame; ! 93: // TODO: don't repeat this check when drawing? ! 94: if ((frame >= pmdl->numframes) || (frame < 0)) ! 95: { ! 96: Con_DPrintf ("No such frame %d %s\n", frame, ! 97: pmodel->name); ! 98: frame = 0; ! 99: } ! 100: ! 101: pframedesc = &pahdr->frames[frame]; ! 102: ! 103: // x worldspace coordinates ! 104: basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = ! 105: (float)pframedesc->bboxmin.v[0]; ! 106: basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = ! 107: (float)pframedesc->bboxmax.v[0]; ! 108: ! 109: // y worldspace coordinates ! 110: basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = ! 111: (float)pframedesc->bboxmin.v[1]; ! 112: basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = ! 113: (float)pframedesc->bboxmax.v[1]; ! 114: ! 115: // z worldspace coordinates ! 116: basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = ! 117: (float)pframedesc->bboxmin.v[2]; ! 118: basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = ! 119: (float)pframedesc->bboxmax.v[2]; ! 120: ! 121: zclipped = false; ! 122: zfullyclipped = true; ! 123: ! 124: minz = 9999; ! 125: for (i=0; i<8 ; i++) ! 126: { ! 127: R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]); ! 128: ! 129: if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) ! 130: { ! 131: // we must clip points that are closer than the near clip plane ! 132: viewpts[i].flags = ALIAS_Z_CLIP; ! 133: zclipped = true; ! 134: } ! 135: else ! 136: { ! 137: if (viewaux[i].fv[2] < minz) ! 138: minz = viewaux[i].fv[2]; ! 139: viewpts[i].flags = 0; ! 140: zfullyclipped = false; ! 141: } ! 142: } ! 143: ! 144: ! 145: if (zfullyclipped) ! 146: { ! 147: return false; // everything was near-z-clipped ! 148: } ! 149: ! 150: numv = 8; ! 151: ! 152: if (zclipped) ! 153: { ! 154: // organize points by edges, use edges to get new points (possible trivial ! 155: // reject) ! 156: for (i=0 ; i<12 ; i++) ! 157: { ! 158: // edge endpoints ! 159: pv0 = &viewpts[aedges[i].index0]; ! 160: pv1 = &viewpts[aedges[i].index1]; ! 161: pa0 = &viewaux[aedges[i].index0]; ! 162: pa1 = &viewaux[aedges[i].index1]; ! 163: ! 164: // if one end is clipped and the other isn't, make a new point ! 165: if (pv0->flags ^ pv1->flags) ! 166: { ! 167: frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) / ! 168: (pa1->fv[2] - pa0->fv[2]); ! 169: viewaux[numv].fv[0] = pa0->fv[0] + ! 170: (pa1->fv[0] - pa0->fv[0]) * frac; ! 171: viewaux[numv].fv[1] = pa0->fv[1] + ! 172: (pa1->fv[1] - pa0->fv[1]) * frac; ! 173: viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE; ! 174: viewpts[numv].flags = 0; ! 175: numv++; ! 176: } ! 177: } ! 178: } ! 179: ! 180: // project the vertices that remain after clipping ! 181: anyclip = 0; ! 182: allclip = ALIAS_XY_CLIP_MASK; ! 183: ! 184: // TODO: probably should do this loop in ASM, especially if we use floats ! 185: for (i=0 ; i<numv ; i++) ! 186: { ! 187: // we don't need to bother with vertices that were z-clipped ! 188: if (viewpts[i].flags & ALIAS_Z_CLIP) ! 189: continue; ! 190: ! 191: zi = 1.0 / viewaux[i].fv[2]; ! 192: ! 193: // FIXME: do with chop mode in ASM, or convert to float ! 194: v0 = (viewaux[i].fv[0] * xscale * zi) + xcenter; ! 195: v1 = (viewaux[i].fv[1] * yscale * zi) + ycenter; ! 196: ! 197: flags = 0; ! 198: ! 199: if (v0 < r_refdef.fvrectx) ! 200: flags |= ALIAS_LEFT_CLIP; ! 201: if (v1 < r_refdef.fvrecty) ! 202: flags |= ALIAS_TOP_CLIP; ! 203: if (v0 > r_refdef.fvrectright) ! 204: flags |= ALIAS_RIGHT_CLIP; ! 205: if (v1 > r_refdef.fvrectbottom) ! 206: flags |= ALIAS_BOTTOM_CLIP; ! 207: ! 208: anyclip |= flags; ! 209: allclip &= flags; ! 210: } ! 211: ! 212: if (allclip) ! 213: return false; // trivial reject off one side ! 214: ! 215: currententity->trivial_accept = !anyclip & !zclipped; ! 216: ! 217: if (currententity->trivial_accept) ! 218: { ! 219: if (minz > (r_aliastransition + (pmdl->size * r_resfudge))) ! 220: { ! 221: currententity->trivial_accept |= 2; ! 222: } ! 223: } ! 224: ! 225: return true; ! 226: } ! 227: ! 228: ! 229: /* ! 230: ================ ! 231: R_AliasTransformVector ! 232: ================ ! 233: */ ! 234: void R_AliasTransformVector (vec3_t in, vec3_t out) ! 235: { ! 236: out[0] = DotProduct(in, aliastransform[0]) + aliastransform[0][3]; ! 237: out[1] = DotProduct(in, aliastransform[1]) + aliastransform[1][3]; ! 238: out[2] = DotProduct(in, aliastransform[2]) + aliastransform[2][3]; ! 239: } ! 240: ! 241: ! 242: /* ! 243: ================ ! 244: R_AliasPreparePoints ! 245: ! 246: General clipped case ! 247: ================ ! 248: */ ! 249: void R_AliasPreparePoints (void) ! 250: { ! 251: int i; ! 252: stvert_t *pstverts; ! 253: finalvert_t *fv; ! 254: auxvert_t *av; ! 255: mtriangle_t *ptri; ! 256: finalvert_t *pfv[3]; ! 257: ! 258: pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); ! 259: r_anumverts = pmdl->numverts; ! 260: fv = pfinalverts; ! 261: av = pauxverts; ! 262: ! 263: for (i=0 ; i<r_anumverts ; i++, fv++, av++, r_apverts++, pstverts++) ! 264: { ! 265: R_AliasTransformFinalVert (fv, av, r_apverts, pstverts); ! 266: if (av->fv[2] < ALIAS_Z_CLIP_PLANE) ! 267: fv->flags |= ALIAS_Z_CLIP; ! 268: else ! 269: { ! 270: R_AliasProjectFinalVert (fv, av); ! 271: ! 272: if (fv->v[0] < r_refdef.aliasvrect.x) ! 273: fv->flags |= ALIAS_LEFT_CLIP; ! 274: if (fv->v[1] < r_refdef.aliasvrect.y) ! 275: fv->flags |= ALIAS_TOP_CLIP; ! 276: if (fv->v[0] > r_refdef.aliasvrectright) ! 277: fv->flags |= ALIAS_RIGHT_CLIP; ! 278: if (fv->v[1] > r_refdef.aliasvrectbottom) ! 279: fv->flags |= ALIAS_BOTTOM_CLIP; ! 280: } ! 281: } ! 282: ! 283: // ! 284: // clip and draw all triangles ! 285: // ! 286: r_affinetridesc.numtriangles = 1; ! 287: ! 288: ptri = (mtriangle_t *)((byte *)paliashdr + paliashdr->triangles); ! 289: for (i=0 ; i<pmdl->numtris ; i++, ptri++) ! 290: { ! 291: pfv[0] = &pfinalverts[ptri->vertindex[0]]; ! 292: pfv[1] = &pfinalverts[ptri->vertindex[1]]; ! 293: pfv[2] = &pfinalverts[ptri->vertindex[2]]; ! 294: ! 295: if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) ! 296: continue; // completely clipped ! 297: ! 298: if ( ! ( (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) & ! 299: (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) ) ! 300: { // totally unclipped ! 301: r_affinetridesc.pfinalverts = pfinalverts; ! 302: r_affinetridesc.ptriangles = ptri; ! 303: D_PolysetDraw (); ! 304: } ! 305: else ! 306: { // partially clipped ! 307: R_AliasClipTriangle (ptri); ! 308: } ! 309: } ! 310: } ! 311: ! 312: ! 313: /* ! 314: ================ ! 315: R_AliasSetUpTransform ! 316: ================ ! 317: */ ! 318: void R_AliasSetUpTransform (int trivial_accept) ! 319: { ! 320: int i; ! 321: float rotationmatrix[3][4], t2matrix[3][4]; ! 322: static float tmatrix[3][4]; ! 323: static float viewmatrix[3][4]; ! 324: vec3_t angles; ! 325: ! 326: // TODO: should really be stored with the entity instead of being reconstructed ! 327: // TODO: should use a look-up table ! 328: // TODO: could cache lazily, stored in the entity ! 329: ! 330: angles[ROLL] = currententity->angles[ROLL]; ! 331: angles[PITCH] = -currententity->angles[PITCH]; ! 332: angles[YAW] = currententity->angles[YAW]; ! 333: AngleVectors (angles, alias_forward, alias_right, alias_up); ! 334: ! 335: tmatrix[0][0] = pmdl->scale[0]; ! 336: tmatrix[1][1] = pmdl->scale[1]; ! 337: tmatrix[2][2] = pmdl->scale[2]; ! 338: ! 339: tmatrix[0][3] = pmdl->scale_origin[0]; ! 340: tmatrix[1][3] = pmdl->scale_origin[1]; ! 341: tmatrix[2][3] = pmdl->scale_origin[2]; ! 342: ! 343: // TODO: can do this with simple matrix rearrangement ! 344: ! 345: for (i=0 ; i<3 ; i++) ! 346: { ! 347: t2matrix[i][0] = alias_forward[i]; ! 348: t2matrix[i][1] = -alias_right[i]; ! 349: t2matrix[i][2] = alias_up[i]; ! 350: } ! 351: ! 352: t2matrix[0][3] = -modelorg[0]; ! 353: t2matrix[1][3] = -modelorg[1]; ! 354: t2matrix[2][3] = -modelorg[2]; ! 355: ! 356: // FIXME: can do more efficiently than full concatenation ! 357: R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); ! 358: ! 359: // TODO: should be global, set when vright, etc., set ! 360: VectorCopy (vright, viewmatrix[0]); ! 361: VectorCopy (vup, viewmatrix[1]); ! 362: VectorInverse (viewmatrix[1]); ! 363: VectorCopy (vpn, viewmatrix[2]); ! 364: ! 365: // viewmatrix[0][3] = 0; ! 366: // viewmatrix[1][3] = 0; ! 367: // viewmatrix[2][3] = 0; ! 368: ! 369: R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform); ! 370: ! 371: // do the scaling up of x and y to screen coordinates as part of the transform ! 372: // for the unclipped case (it would mess up clipping in the clipped case). ! 373: // Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y ! 374: // correspondingly so the projected x and y come out right ! 375: // FIXME: make this work for clipped case too? ! 376: if (trivial_accept) ! 377: { ! 378: for (i=0 ; i<4 ; i++) ! 379: { ! 380: aliastransform[0][i] *= aliasxscale * ! 381: (1.0 / ((float)0x8000 * 0x10000)); ! 382: aliastransform[1][i] *= aliasyscale * ! 383: (1.0 / ((float)0x8000 * 0x10000)); ! 384: aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000); ! 385: ! 386: } ! 387: } ! 388: } ! 389: ! 390: ! 391: /* ! 392: ================ ! 393: R_AliasTransformFinalVert ! 394: ================ ! 395: */ ! 396: void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av, ! 397: trivertx_t *pverts, stvert_t *pstverts) ! 398: { ! 399: int temp; ! 400: float lightcos, *plightnormal; ! 401: ! 402: av->fv[0] = DotProduct(pverts->v, aliastransform[0]) + ! 403: aliastransform[0][3]; ! 404: av->fv[1] = DotProduct(pverts->v, aliastransform[1]) + ! 405: aliastransform[1][3]; ! 406: av->fv[2] = DotProduct(pverts->v, aliastransform[2]) + ! 407: aliastransform[2][3]; ! 408: ! 409: fv->v[2] = pstverts->s; ! 410: fv->v[3] = pstverts->t; ! 411: ! 412: fv->flags = pstverts->onseam; ! 413: ! 414: // lighting ! 415: plightnormal = r_avertexnormals[pverts->lightnormalindex]; ! 416: lightcos = DotProduct (plightnormal, r_plightvec); ! 417: temp = r_ambientlight; ! 418: ! 419: if (lightcos < 0) ! 420: { ! 421: temp += (int)(r_shadelight * lightcos); ! 422: ! 423: // clamp; because we limited the minimum ambient and shading light, we ! 424: // don't have to clamp low light, just bright ! 425: if (temp < 0) ! 426: temp = 0; ! 427: } ! 428: ! 429: fv->v[4] = temp; ! 430: } ! 431: ! 432: ! 433: #if !id386 ! 434: ! 435: /* ! 436: ================ ! 437: R_AliasTransformAndProjectFinalVerts ! 438: ================ ! 439: */ ! 440: void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts) ! 441: { ! 442: int i, temp; ! 443: float lightcos, *plightnormal, zi; ! 444: trivertx_t *pverts; ! 445: ! 446: pverts = r_apverts; ! 447: ! 448: for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++) ! 449: { ! 450: // transform and project ! 451: zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) + ! 452: aliastransform[2][3]); ! 453: ! 454: // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is ! 455: // scaled up by 1/2**31, and the scaling cancels out for x and y in the ! 456: // projection ! 457: fv->v[5] = zi; ! 458: ! 459: fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) + ! 460: aliastransform[0][3]) * zi) + aliasxcenter; ! 461: fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) + ! 462: aliastransform[1][3]) * zi) + aliasycenter; ! 463: ! 464: fv->v[2] = pstverts->s; ! 465: fv->v[3] = pstverts->t; ! 466: fv->flags = pstverts->onseam; ! 467: ! 468: // lighting ! 469: plightnormal = r_avertexnormals[pverts->lightnormalindex]; ! 470: lightcos = DotProduct (plightnormal, r_plightvec); ! 471: temp = r_ambientlight; ! 472: ! 473: if (lightcos < 0) ! 474: { ! 475: temp += (int)(r_shadelight * lightcos); ! 476: ! 477: // clamp; because we limited the minimum ambient and shading light, we ! 478: // don't have to clamp low light, just bright ! 479: if (temp < 0) ! 480: temp = 0; ! 481: } ! 482: ! 483: fv->v[4] = temp; ! 484: } ! 485: } ! 486: ! 487: #endif ! 488: ! 489: ! 490: /* ! 491: ================ ! 492: R_AliasProjectFinalVert ! 493: ================ ! 494: */ ! 495: void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av) ! 496: { ! 497: float zi; ! 498: ! 499: // project points ! 500: zi = 1.0 / av->fv[2]; ! 501: ! 502: fv->v[5] = zi * ziscale; ! 503: ! 504: fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter; ! 505: fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter; ! 506: } ! 507: ! 508: ! 509: /* ! 510: ================ ! 511: R_AliasPrepareUnclippedPoints ! 512: ================ ! 513: */ ! 514: void R_AliasPrepareUnclippedPoints (void) ! 515: { ! 516: stvert_t *pstverts; ! 517: finalvert_t *fv; ! 518: ! 519: pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); ! 520: r_anumverts = pmdl->numverts; ! 521: // FIXME: just use pfinalverts directly? ! 522: fv = pfinalverts; ! 523: ! 524: R_AliasTransformAndProjectFinalVerts (fv, pstverts); ! 525: ! 526: if (r_affinetridesc.drawtype) ! 527: D_PolysetDrawFinalVerts (fv, r_anumverts); ! 528: ! 529: r_affinetridesc.pfinalverts = pfinalverts; ! 530: r_affinetridesc.ptriangles = (mtriangle_t *) ! 531: ((byte *)paliashdr + paliashdr->triangles); ! 532: r_affinetridesc.numtriangles = pmdl->numtris; ! 533: ! 534: D_PolysetDraw (); ! 535: } ! 536: ! 537: /* ! 538: =============== ! 539: R_AliasSetupSkin ! 540: =============== ! 541: */ ! 542: void R_AliasSetupSkin (void) ! 543: { ! 544: int skinnum; ! 545: int i, numskins; ! 546: maliasskingroup_t *paliasskingroup; ! 547: float *pskinintervals, fullskininterval; ! 548: float skintargettime, skintime; ! 549: ! 550: skinnum = currententity->skinnum; ! 551: if ((skinnum >= pmdl->numskins) || (skinnum < 0)) ! 552: { ! 553: Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum); ! 554: skinnum = 0; ! 555: } ! 556: ! 557: pskindesc = ((maliasskindesc_t *) ! 558: ((byte *)paliashdr + paliashdr->skindesc)) + skinnum; ! 559: a_skinwidth = pmdl->skinwidth; ! 560: ! 561: if (pskindesc->type == ALIAS_SKIN_GROUP) ! 562: { ! 563: paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr + ! 564: pskindesc->skin); ! 565: pskinintervals = (float *) ! 566: ((byte *)paliashdr + paliasskingroup->intervals); ! 567: numskins = paliasskingroup->numskins; ! 568: fullskininterval = pskinintervals[numskins-1]; ! 569: ! 570: skintime = cl.time + currententity->syncbase; ! 571: ! 572: // when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval ! 573: // values are positive, so we don't have to worry about division by 0 ! 574: skintargettime = skintime - ! 575: ((int)(skintime / fullskininterval)) * fullskininterval; ! 576: ! 577: for (i=0 ; i<(numskins-1) ; i++) ! 578: { ! 579: if (pskinintervals[i] > skintargettime) ! 580: break; ! 581: } ! 582: ! 583: pskindesc = &paliasskingroup->skindescs[i]; ! 584: } ! 585: ! 586: r_affinetridesc.pskindesc = pskindesc; ! 587: r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin); ! 588: r_affinetridesc.skinwidth = a_skinwidth; ! 589: r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16; ! 590: r_affinetridesc.skinheight = pmdl->skinheight; ! 591: } ! 592: ! 593: /* ! 594: ================ ! 595: R_AliasSetupLighting ! 596: ================ ! 597: */ ! 598: void R_AliasSetupLighting (alight_t *plighting) ! 599: { ! 600: ! 601: // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have ! 602: // to clamp off the bottom ! 603: r_ambientlight = plighting->ambientlight; ! 604: ! 605: if (r_ambientlight < LIGHT_MIN) ! 606: r_ambientlight = LIGHT_MIN; ! 607: ! 608: r_ambientlight = (255 - r_ambientlight) << VID_CBITS; ! 609: ! 610: if (r_ambientlight < LIGHT_MIN) ! 611: r_ambientlight = LIGHT_MIN; ! 612: ! 613: r_shadelight = plighting->shadelight; ! 614: ! 615: if (r_shadelight < 0) ! 616: r_shadelight = 0; ! 617: ! 618: r_shadelight *= VID_GRADES; ! 619: ! 620: // rotate the lighting vector into the model's frame of reference ! 621: r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward); ! 622: r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right); ! 623: r_plightvec[2] = DotProduct (plighting->plightvec, alias_up); ! 624: } ! 625: ! 626: /* ! 627: ================= ! 628: R_AliasSetupFrame ! 629: ! 630: set r_apverts ! 631: ================= ! 632: */ ! 633: void R_AliasSetupFrame (void) ! 634: { ! 635: int frame; ! 636: int i, numframes; ! 637: maliasgroup_t *paliasgroup; ! 638: float *pintervals, fullinterval, targettime, time; ! 639: ! 640: frame = currententity->frame; ! 641: if ((frame >= pmdl->numframes) || (frame < 0)) ! 642: { ! 643: Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); ! 644: frame = 0; ! 645: } ! 646: ! 647: if (paliashdr->frames[frame].type == ALIAS_SINGLE) ! 648: { ! 649: r_apverts = (trivertx_t *) ! 650: ((byte *)paliashdr + paliashdr->frames[frame].frame); ! 651: return; ! 652: } ! 653: ! 654: paliasgroup = (maliasgroup_t *) ! 655: ((byte *)paliashdr + paliashdr->frames[frame].frame); ! 656: pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals); ! 657: numframes = paliasgroup->numframes; ! 658: fullinterval = pintervals[numframes-1]; ! 659: ! 660: time = cl.time + currententity->syncbase; ! 661: ! 662: // ! 663: // when loading in Mod_LoadAliasGroup, we guaranteed all interval values ! 664: // are positive, so we don't have to worry about division by 0 ! 665: // ! 666: targettime = time - ((int)(time / fullinterval)) * fullinterval; ! 667: ! 668: for (i=0 ; i<(numframes-1) ; i++) ! 669: { ! 670: if (pintervals[i] > targettime) ! 671: break; ! 672: } ! 673: ! 674: r_apverts = (trivertx_t *) ! 675: ((byte *)paliashdr + paliasgroup->frames[i].frame); ! 676: } ! 677: ! 678: ! 679: /* ! 680: ================ ! 681: R_AliasDrawModel ! 682: ================ ! 683: */ ! 684: void R_AliasDrawModel (alight_t *plighting) ! 685: { ! 686: finalvert_t finalverts[MAXALIASVERTS + ! 687: ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1]; ! 688: auxvert_t auxverts[MAXALIASVERTS]; ! 689: ! 690: r_amodels_drawn++; ! 691: ! 692: // cache align ! 693: pfinalverts = (finalvert_t *) ! 694: (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); ! 695: pauxverts = &auxverts[0]; ! 696: ! 697: paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); ! 698: pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model); ! 699: ! 700: R_AliasSetupSkin (); ! 701: R_AliasSetUpTransform (currententity->trivial_accept); ! 702: R_AliasSetupLighting (plighting); ! 703: R_AliasSetupFrame (); ! 704: ! 705: if (!currententity->colormap) ! 706: Sys_Error ("R_AliasDrawModel: !currententity->colormap"); ! 707: ! 708: r_affinetridesc.drawtype = (currententity->trivial_accept == 3) && ! 709: r_recursiveaffinetriangles; ! 710: ! 711: if (r_affinetridesc.drawtype) ! 712: { ! 713: D_PolysetUpdateTables (); // FIXME: precalc... ! 714: } ! 715: else ! 716: { ! 717: #if id386 ! 718: D_Aff8Patch (currententity->colormap); ! 719: #endif ! 720: } ! 721: ! 722: acolormap = currententity->colormap; ! 723: ! 724: if (currententity != &cl.viewent) ! 725: ziscale = (float)0x8000 * (float)0x10000; ! 726: else ! 727: ziscale = (float)0x8000 * (float)0x10000 * 3.0; ! 728: ! 729: if (currententity->trivial_accept) ! 730: R_AliasPrepareUnclippedPoints (); ! 731: else ! 732: R_AliasPreparePoints (); ! 733: } ! 734:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.