Annotation of quake1/r_alias.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.