1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 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
30 mtriangle_t *ptriangles;
31 affinetridesc_t r_affinetridesc;
32
33 void * acolormap; // FIXME: should go away
34
35 trivertx_t *r_apverts;
36
37 // TODO: these probably will go away with optimized rasterization
38 mdl_t *pmdl;
39 vec3_t r_plightvec;
40 int r_ambientlight;
41 float r_shadelight;
42 aliashdr_t *paliashdr;
43 finalvert_t *pfinalverts;
44 auxvert_t *pauxverts;
45 static float ziscale;
46 static model_t *pmodel;
47
48 static vec3_t alias_forward, alias_right, alias_up;
49
50 static maliasskindesc_t *pskindesc;
51
52 int r_amodels_drawn;
53 int a_skinwidth;
54 int r_anumverts;
55
56 float aliastransform[3][4];
57
58 typedef struct {
59 int index0;
60 int index1;
61 } aedge_t;
62
63 static 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
71 float r_avertexnormals[NUMVERTEXNORMALS][3] = {
72 #include "anorms.h"
73 };
74
75 void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv,
76 stvert_t *pstverts);
77 void R_AliasSetUpTransform (int trivial_accept);
78 void R_AliasTransformVector (vec3_t in, vec3_t out);
79 void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av,
80 trivertx_t *pverts, stvert_t *pstverts);
81 void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
82
83
84 /*
85 ================
86 R_AliasCheckBBox
87 ================
88 */
R_AliasCheckBBox(void)89 qboolean 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 ================
250 R_AliasTransformVector
251 ================
252 */
R_AliasTransformVector(vec3_t in,vec3_t out)253 void 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 ================
263 R_AliasPreparePoints
264
265 General clipped case
266 ================
267 */
R_AliasPreparePoints(void)268 void 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 ================
334 R_AliasSetUpTransform
335 ================
336 */
R_AliasSetUpTransform(int trivial_accept)337 void 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 ================
412 R_AliasTransformFinalVert
413 ================
414 */
R_AliasTransformFinalVert(finalvert_t * fv,auxvert_t * av,trivertx_t * pverts,stvert_t * pstverts)415 void 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 ================
456 R_AliasTransformAndProjectFinalVerts
457 ================
458 */
R_AliasTransformAndProjectFinalVerts(finalvert_t * fv,stvert_t * pstverts)459 void 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 ================
511 R_AliasProjectFinalVert
512 ================
513 */
R_AliasProjectFinalVert(finalvert_t * fv,auxvert_t * av)514 void 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 ================
530 R_AliasPrepareUnclippedPoints
531 ================
532 */
R_AliasPrepareUnclippedPoints(void)533 void 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 ===============
558 R_AliasSetupSkin
559 ===============
560 */
R_AliasSetupSkin(void)561 void 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
612 /*
613 ================
614 R_AliasSetupLighting
615 ================
616 */
R_AliasSetupLighting(alight_t * plighting)617 void R_AliasSetupLighting (alight_t *plighting)
618 {
619
620 // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
621 // to clamp off the bottom
622 r_ambientlight = plighting->ambientlight;
623
624 if (r_ambientlight < LIGHT_MIN)
625 r_ambientlight = LIGHT_MIN;
626
627 r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
628
629 if (r_ambientlight < LIGHT_MIN)
630 r_ambientlight = LIGHT_MIN;
631
632 r_shadelight = plighting->shadelight;
633
634 if (r_shadelight < 0)
635 r_shadelight = 0;
636
637 r_shadelight *= VID_GRADES;
638
639 // rotate the lighting vector into the model's frame of reference
640 r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward);
641 r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right);
642 r_plightvec[2] = DotProduct (plighting->plightvec, alias_up);
643 }
644
645 /*
646 =================
647 R_AliasSetupFrame
648
649 set r_apverts
650 =================
651 */
R_AliasSetupFrame(void)652 void R_AliasSetupFrame (void)
653 {
654 int frame;
655 int i, numframes;
656 maliasgroup_t *paliasgroup;
657 float *pintervals, fullinterval, targettime, time;
658
659 frame = currententity->frame;
660 if ((frame >= pmdl->numframes) || (frame < 0))
661 {
662 Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
663 frame = 0;
664 }
665
666 if (paliashdr->frames[frame].type == ALIAS_SINGLE)
667 {
668 r_apverts = (trivertx_t *)
669 ((byte *)paliashdr + paliashdr->frames[frame].frame);
670 return;
671 }
672
673 paliasgroup = (maliasgroup_t *)
674 ((byte *)paliashdr + paliashdr->frames[frame].frame);
675 pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals);
676 numframes = paliasgroup->numframes;
677 fullinterval = pintervals[numframes-1];
678
679 time = cl.time + currententity->syncbase;
680
681 //
682 // when loading in Mod_LoadAliasGroup, we guaranteed all interval values
683 // are positive, so we don't have to worry about division by 0
684 //
685 targettime = time - ((int)(time / fullinterval)) * fullinterval;
686
687 for (i=0 ; i<(numframes-1) ; i++)
688 {
689 if (pintervals[i] > targettime)
690 break;
691 }
692
693 r_apverts = (trivertx_t *)
694 ((byte *)paliashdr + paliasgroup->frames[i].frame);
695 }
696
697
698 /*
699 ================
700 R_AliasDrawModel
701 ================
702 */
R_AliasDrawModel(alight_t * plighting)703 void R_AliasDrawModel (alight_t *plighting)
704 {
705 finalvert_t finalverts[MAXALIASVERTS +
706 ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1];
707 auxvert_t auxverts[MAXALIASVERTS];
708
709 r_amodels_drawn++;
710
711 // cache align
712 pfinalverts = (finalvert_t *)
713 (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
714 pauxverts = &auxverts[0];
715
716 paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
717 pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model);
718
719 R_AliasSetupSkin ();
720 R_AliasSetUpTransform (currententity->trivial_accept);
721 R_AliasSetupLighting (plighting);
722 R_AliasSetupFrame ();
723
724 if (!currententity->colormap)
725 Sys_Error ("R_AliasDrawModel: !currententity->colormap");
726
727 r_affinetridesc.drawtype = (currententity->trivial_accept == 3) &&
728 r_recursiveaffinetriangles;
729
730 if (r_affinetridesc.drawtype)
731 {
732 D_PolysetUpdateTables (); // FIXME: precalc...
733 }
734 else
735 {
736 #if id386
737 D_Aff8Patch (currententity->colormap);
738 #endif
739 }
740
741 acolormap = currententity->colormap;
742
743 if (currententity != &cl.viewent)
744 ziscale = (float)0x8000 * (float)0x10000;
745 else
746 ziscale = (float)0x8000 * (float)0x10000 * 3.0;
747
748 if (currententity->trivial_accept)
749 R_AliasPrepareUnclippedPoints ();
750 else
751 R_AliasPreparePoints ();
752 }
753
754