~agrip-hackers/sns/trunk

« back to all changes in this revision

Viewing changes to zq-repo/zquake/source/r_alias.c

  • Committer: Matthew Tylee Atkinson
  • Date: 2008-03-07 20:15:20 UTC
  • Revision ID: mta@agrip.org.uk-20080307201520-uj9sa2jrytx91b2t
Remove non-SNS components.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
*/
89
 
qbool 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
 
        qbool                           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
 
                Com_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
 
*/
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
 
*/
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
 
*/
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
 
        VectorNegate (vup, viewmatrix[1]);
381
 
        VectorCopy (vpn, viewmatrix[2]);
382
 
 
383
 
//      viewmatrix[0][3] = 0;
384
 
//      viewmatrix[1][3] = 0;
385
 
//      viewmatrix[2][3] = 0;
386
 
 
387
 
        R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform);
388
 
 
389
 
// do the scaling up of x and y to screen coordinates as part of the transform
390
 
// for the unclipped case (it would mess up clipping in the clipped case).
391
 
// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y
392
 
// correspondingly so the projected x and y come out right
393
 
// FIXME: make this work for clipped case too?
394
 
        if (trivial_accept)
395
 
        {
396
 
                for (i=0 ; i<4 ; i++)
397
 
                {
398
 
                        aliastransform[0][i] *= aliasxscale *
399
 
                                        (1.0 / ((float)0x8000 * 0x10000));
400
 
                        aliastransform[1][i] *= aliasyscale *
401
 
                                        (1.0 / ((float)0x8000 * 0x10000));
402
 
                        aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000);
403
 
 
404
 
                }
405
 
        }
406
 
}
407
 
 
408
 
 
409
 
/*
410
 
================
411
 
R_AliasTransformFinalVert
412
 
================
413
 
*/
414
 
void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av,
415
 
        trivertx_t *pverts, stvert_t *pstverts)
416
 
{
417
 
        int             temp;
418
 
        float   lightcos, *plightnormal;
419
 
 
420
 
        av->fv[0] = DotProduct(pverts->v, aliastransform[0]) +
421
 
                        aliastransform[0][3];
422
 
        av->fv[1] = DotProduct(pverts->v, aliastransform[1]) +
423
 
                        aliastransform[1][3];
424
 
        av->fv[2] = DotProduct(pverts->v, aliastransform[2]) +
425
 
                        aliastransform[2][3];
426
 
 
427
 
        fv->v[2] = pstverts->s;
428
 
        fv->v[3] = pstverts->t;
429
 
 
430
 
        fv->flags = pstverts->onseam;
431
 
 
432
 
// lighting
433
 
        plightnormal = r_avertexnormals[pverts->lightnormalindex];
434
 
        lightcos = DotProduct (plightnormal, r_plightvec);
435
 
        temp = r_ambientlight;
436
 
 
437
 
        if (lightcos < 0)
438
 
        {
439
 
                temp += (int)(r_shadelight * lightcos);
440
 
 
441
 
        // clamp; because we limited the minimum ambient and shading light, we
442
 
        // don't have to clamp low light, just bright
443
 
                if (temp < 0)
444
 
                        temp = 0;
445
 
        }
446
 
 
447
 
        fv->v[4] = temp;
448
 
}
449
 
 
450
 
 
451
 
#if     !id386
452
 
 
453
 
/*
454
 
================
455
 
R_AliasTransformAndProjectFinalVerts
456
 
================
457
 
*/
458
 
void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts)
459
 
{
460
 
        int                     i, temp;
461
 
        float           lightcos, *plightnormal, zi;
462
 
        trivertx_t      *pverts;
463
 
 
464
 
        pverts = r_apverts;
465
 
 
466
 
        for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
467
 
        {
468
 
        // transform and project
469
 
                zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
470
 
                                aliastransform[2][3]);
471
 
 
472
 
        // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
473
 
        // scaled up by 1/2**31, and the scaling cancels out for x and y in the
474
 
        // projection
475
 
                fv->v[5] = zi;
476
 
 
477
 
                fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
478
 
                                aliastransform[0][3]) * zi) + aliasxcenter;
479
 
                fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
480
 
                                aliastransform[1][3]) * zi) + aliasycenter;
481
 
 
482
 
                fv->v[2] = pstverts->s;
483
 
                fv->v[3] = pstverts->t;
484
 
                fv->flags = pstverts->onseam;
485
 
 
486
 
        // lighting
487
 
                plightnormal = r_avertexnormals[pverts->lightnormalindex];
488
 
                lightcos = DotProduct (plightnormal, r_plightvec);
489
 
                temp = r_ambientlight;
490
 
 
491
 
                if (lightcos < 0)
492
 
                {
493
 
                        temp += (int)(r_shadelight * lightcos);
494
 
 
495
 
                // clamp; because we limited the minimum ambient and shading light, we
496
 
                // don't have to clamp low light, just bright
497
 
                        if (temp < 0)
498
 
                                temp = 0;
499
 
                }
500
 
 
501
 
                fv->v[4] = temp;
502
 
        }
503
 
}
504
 
 
505
 
#endif
506
 
 
507
 
 
508
 
/*
509
 
================
510
 
R_AliasProjectFinalVert
511
 
================
512
 
*/
513
 
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av)
514
 
{
515
 
        float   zi;
516
 
 
517
 
// project points
518
 
        zi = 1.0 / av->fv[2];
519
 
 
520
 
        fv->v[5] = zi * ziscale;
521
 
 
522
 
        fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter;
523
 
        fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter;
524
 
}
525
 
 
526
 
 
527
 
/*
528
 
================
529
 
R_AliasPrepareUnclippedPoints
530
 
================
531
 
*/
532
 
void R_AliasPrepareUnclippedPoints (void)
533
 
{
534
 
        stvert_t        *pstverts;
535
 
        finalvert_t     *fv;
536
 
 
537
 
        pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts);
538
 
        r_anumverts = pmdl->numverts;
539
 
// FIXME: just use pfinalverts directly?
540
 
        fv = pfinalverts;
541
 
 
542
 
        R_AliasTransformAndProjectFinalVerts (fv, pstverts);
543
 
 
544
 
        if (r_affinetridesc.drawtype)
545
 
                D_PolysetDrawFinalVerts (fv, r_anumverts);
546
 
 
547
 
        r_affinetridesc.pfinalverts = pfinalverts;
548
 
        r_affinetridesc.ptriangles = (mtriangle_t *)
549
 
                        ((byte *)paliashdr + paliashdr->triangles);
550
 
        r_affinetridesc.numtriangles = pmdl->numtris;
551
 
 
552
 
        D_PolysetDraw ();
553
 
}
554
 
 
555
 
/*
556
 
===============
557
 
R_AliasSetupSkin
558
 
===============
559
 
*/
560
 
void R_AliasSetupSkin (void)
561
 
{
562
 
        int                                     skinnum;
563
 
        int                                     i, numskins;
564
 
        maliasskingroup_t       *paliasskingroup;
565
 
        float                           *pskinintervals, fullskininterval;
566
 
        float                           skintargettime, skintime;
567
 
 
568
 
        skinnum = currententity->skinnum;
569
 
        if ((skinnum >= pmdl->numskins) || (skinnum < 0))
570
 
        {
571
 
                Com_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum);
572
 
                skinnum = 0;
573
 
        }
574
 
 
575
 
        pskindesc = ((maliasskindesc_t *)
576
 
                        ((byte *)paliashdr + paliashdr->skindesc)) + skinnum;
577
 
        a_skinwidth = pmdl->skinwidth;
578
 
 
579
 
        if (pskindesc->type == ALIAS_SKIN_GROUP)
580
 
        {
581
 
                paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr +
582
 
                                pskindesc->skin);
583
 
                pskinintervals = (float *)
584
 
                                ((byte *)paliashdr + paliasskingroup->intervals);
585
 
                numskins = paliasskingroup->numskins;
586
 
                fullskininterval = pskinintervals[numskins-1];
587
 
        
588
 
                skintime = r_refdef2.time;
589
 
        
590
 
        // when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval
591
 
        // values are positive, so we don't have to worry about division by 0
592
 
                skintargettime = skintime -
593
 
                                ((int)(skintime / fullskininterval)) * fullskininterval;
594
 
        
595
 
                for (i=0 ; i<(numskins-1) ; i++)
596
 
                {
597
 
                        if (pskinintervals[i] > skintargettime)
598
 
                                break;
599
 
                }
600
 
        
601
 
                pskindesc = &paliasskingroup->skindescs[i];
602
 
        }
603
 
 
604
 
        r_affinetridesc.pskindesc = pskindesc;
605
 
        r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin);
606
 
        r_affinetridesc.skinwidth = a_skinwidth;
607
 
        r_affinetridesc.seamfixupX16 =  (a_skinwidth >> 1) << 16;
608
 
        r_affinetridesc.skinheight = pmdl->skinheight;
609
 
 
610
 
        if (currententity->scoreboard)
611
 
        {
612
 
                byte    *base;
613
 
 
614
 
                if (!currententity->scoreboard->skin)
615
 
                        Skin_Find (currententity->scoreboard);
616
 
                base = Skin_Cache (currententity->scoreboard->skin);
617
 
                if (base)
618
 
                {
619
 
                        r_affinetridesc.pskin = base;
620
 
                        r_affinetridesc.skinwidth = 320;
621
 
                        r_affinetridesc.skinheight = 200;
622
 
                }
623
 
        }
624
 
}
625
 
 
626
 
/*
627
 
================
628
 
R_AliasSetupLighting
629
 
================
630
 
*/
631
 
void R_AliasSetupLighting (void)
632
 
{
633
 
        int                     j, lnum;
634
 
// FIXME: remove and do real lighting
635
 
        float           lightvec[3] = {-1, 0, 0};
636
 
        vec3_t          dist;
637
 
        float           add;
638
 
 
639
 
        j = R_LightPoint (currententity->origin);
640
 
 
641
 
        r_ambientlight = j;
642
 
        r_shadelight = j;
643
 
 
644
 
        for (lnum=0 ; lnum<r_refdef2.numDlights ; lnum++)
645
 
        {
646
 
                VectorSubtract (currententity->origin, r_refdef2.dlights[lnum].origin, dist);
647
 
                add = r_refdef2.dlights[lnum].radius - VectorLength(dist);
648
 
                if (add > 0)
649
 
                        r_ambientlight += add;
650
 
        }
651
 
 
652
 
// clamp lighting so it doesn't overbright as much
653
 
        if (r_ambientlight > 128)
654
 
                r_ambientlight = 128;
655
 
        if (r_ambientlight + r_shadelight > 192)
656
 
                r_shadelight = 192 - r_ambientlight;
657
 
 
658
 
// always give the gun some light
659
 
        if ((currententity->renderfx & RF_WEAPONMODEL) && r_ambientlight < 24)
660
 
                r_shadelight = r_ambientlight = 24;             // always give some light on gun
661
 
 
662
 
// never allow players to go totally black
663
 
        if ((currententity->model->modhint == MOD_PLAYER || currententity->renderfx & RF_PLAYERMODEL)
664
 
                && r_ambientlight < 8) {
665
 
                        r_ambientlight = r_shadelight = 8;
666
 
        }
667
 
 
668
 
        if ((currententity->model->modhint == MOD_PLAYER || currententity->renderfx & RF_PLAYERMODEL)
669
 
                && r_fullbrightSkins.value && r_refdef2.allow_fbskins) {
670
 
                        r_ambientlight = max (r_ambientlight, 100);
671
 
                        r_shadelight = max (r_shadelight, 100);
672
 
        }
673
 
 
674
 
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
675
 
// to clamp off the bottom
676
 
        if (r_ambientlight < LIGHT_MIN)
677
 
                r_ambientlight = LIGHT_MIN;
678
 
 
679
 
        r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
680
 
        if (r_ambientlight < LIGHT_MIN)
681
 
                r_ambientlight = LIGHT_MIN;
682
 
 
683
 
        if (r_shadelight < 0)
684
 
                r_shadelight = 0;
685
 
        else
686
 
                r_shadelight *= VID_GRADES;
687
 
 
688
 
// rotate the lighting vector into the model's frame of reference
689
 
        r_plightvec[0] = DotProduct (lightvec, alias_forward);
690
 
        r_plightvec[1] = -DotProduct (lightvec, alias_right);
691
 
        r_plightvec[2] = DotProduct (lightvec, alias_up);
692
 
}
693
 
 
694
 
/*
695
 
=================
696
 
R_AliasSetupFrame
697
 
 
698
 
set r_apverts
699
 
=================
700
 
*/
701
 
void R_AliasSetupFrame (void)
702
 
{
703
 
        int                             frame;
704
 
        int                             i, numframes;
705
 
        maliasgroup_t   *paliasgroup;
706
 
        float                   *pintervals, fullinterval, targettime, time;
707
 
 
708
 
        frame = currententity->frame;
709
 
        if ((frame >= pmdl->numframes) || (frame < 0))
710
 
        {
711
 
                Com_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
712
 
                frame = 0;
713
 
        }
714
 
 
715
 
        if (paliashdr->frames[frame].type == ALIAS_SINGLE)
716
 
        {
717
 
                r_apverts = (trivertx_t *)
718
 
                                ((byte *)paliashdr + paliashdr->frames[frame].frame);
719
 
                return;
720
 
        }
721
 
        
722
 
        paliasgroup = (maliasgroup_t *)
723
 
                                ((byte *)paliashdr + paliashdr->frames[frame].frame);
724
 
        pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals);
725
 
        numframes = paliasgroup->numframes;
726
 
        fullinterval = pintervals[numframes-1];
727
 
 
728
 
        time = r_refdef2.time;
729
 
 
730
 
//
731
 
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
732
 
// are positive, so we don't have to worry about division by 0
733
 
//
734
 
        targettime = time - ((int)(time / fullinterval)) * fullinterval;
735
 
 
736
 
        for (i=0 ; i<(numframes-1) ; i++)
737
 
        {
738
 
                if (pintervals[i] > targettime)
739
 
                        break;
740
 
        }
741
 
 
742
 
        r_apverts = (trivertx_t *)
743
 
                                ((byte *)paliashdr + paliasgroup->frames[i].frame);
744
 
}
745
 
 
746
 
 
747
 
/*
748
 
================
749
 
R_AliasDrawModel
750
 
================
751
 
*/
752
 
void R_AliasDrawModel (void)
753
 
{
754
 
        finalvert_t             finalverts[MAXALIASVERTS +
755
 
                                                ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1];
756
 
        auxvert_t               auxverts[MAXALIASVERTS];
757
 
 
758
 
// see if the bounding box lets us trivially reject, also sets
759
 
// trivial accept status
760
 
        if (!R_AliasCheckBBox ())
761
 
                return;
762
 
 
763
 
        r_amodels_drawn++;
764
 
 
765
 
// cache align
766
 
        pfinalverts = (finalvert_t *)
767
 
                        (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
768
 
        pauxverts = &auxverts[0];
769
 
 
770
 
        paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
771
 
        pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model);
772
 
 
773
 
        R_AliasSetupSkin ();
774
 
        R_AliasSetUpTransform (currententity->trivial_accept);
775
 
        R_AliasSetupLighting ();
776
 
        R_AliasSetupFrame ();
777
 
 
778
 
        if (!currententity->colormap)
779
 
                Sys_Error ("R_AliasDrawModel: !currententity->colormap");
780
 
 
781
 
        r_affinetridesc.drawtype = (currententity->trivial_accept == 3);
782
 
 
783
 
        if (r_affinetridesc.drawtype)
784
 
        {
785
 
                D_PolysetUpdateTables ();               // FIXME: precalc...
786
 
        }
787
 
        else
788
 
        {
789
 
#if id386
790
 
                D_Aff8Patch (currententity->colormap);
791
 
#endif
792
 
        }
793
 
 
794
 
        acolormap = currententity->colormap;
795
 
 
796
 
        ziscale = (float)0x8000 * (float)0x10000;
797
 
        if (currententity->renderfx & RF_WEAPONMODEL)
798
 
                ziscale *= 3.0;         // hack depth range to prevent model from poking into walls
799
 
 
800
 
        if (currententity->trivial_accept)
801
 
                R_AliasPrepareUnclippedPoints ();
802
 
        else
803
 
                R_AliasPreparePoints ();
804
 
}
805