home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / r_alias.c.orig < prev    next >
Text File  |  2000-06-17  |  19KB  |  754 lines

  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. 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. */
  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.   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. */
  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. */
  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. */
  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. */
  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. */
  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. */
  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. */
  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. */
  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.