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