Annotation of quake1/gl_mesh.c, revision 1.1.1.1

1.1       root        1: // gl_mesh.c: triangle model functions
                      2: 
                      3: #include "quakedef.h"
                      4: 
                      5: /*
                      6: =================================================================
                      7: 
                      8: ALIAS MODEL DISPLAY LIST GENERATION
                      9: 
                     10: =================================================================
                     11: */
                     12: 
                     13: model_t                *aliasmodel;
                     14: aliashdr_t     *paliashdr;
                     15: 
                     16: qboolean       used[8192];
                     17: 
                     18: // the command list holds counts and s/t values that are valid for
                     19: // every frame
                     20: int            commands[8192];
                     21: int            numcommands;
                     22: 
                     23: // all frames will have their vertexes rearranged and expanded
                     24: // so they are in the order expected by the command list
                     25: int            vertexorder[8192];
                     26: int            numorder;
                     27: 
                     28: int            allverts, alltris;
                     29: 
                     30: int            stripverts[128];
                     31: int            striptris[128];
                     32: int            stripcount;
                     33: 
                     34: /*
                     35: ================
                     36: StripLength
                     37: ================
                     38: */
                     39: int    StripLength (int starttri, int startv)
                     40: {
                     41:        int                     m1, m2;
                     42:        int                     j;
                     43:        mtriangle_t     *last, *check;
                     44:        int                     k;
                     45: 
                     46:        used[starttri] = 2;
                     47: 
                     48:        last = &triangles[starttri];
                     49: 
                     50:        stripverts[0] = last->vertindex[(startv)%3];
                     51:        stripverts[1] = last->vertindex[(startv+1)%3];
                     52:        stripverts[2] = last->vertindex[(startv+2)%3];
                     53: 
                     54:        striptris[0] = starttri;
                     55:        stripcount = 1;
                     56: 
                     57:        m1 = last->vertindex[(startv+2)%3];
                     58:        m2 = last->vertindex[(startv+1)%3];
                     59: 
                     60:        // look for a matching triangle
                     61: nexttri:
                     62:        for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++)
                     63:        {
                     64:                if (check->facesfront != last->facesfront)
                     65:                        continue;
                     66:                for (k=0 ; k<3 ; k++)
                     67:                {
                     68:                        if (check->vertindex[k] != m1)
                     69:                                continue;
                     70:                        if (check->vertindex[ (k+1)%3 ] != m2)
                     71:                                continue;
                     72: 
                     73:                        // this is the next part of the fan
                     74: 
                     75:                        // if we can't use this triangle, this tristrip is done
                     76:                        if (used[j])
                     77:                                goto done;
                     78: 
                     79:                        // the new edge
                     80:                        if (stripcount & 1)
                     81:                                m2 = check->vertindex[ (k+2)%3 ];
                     82:                        else
                     83:                                m1 = check->vertindex[ (k+2)%3 ];
                     84: 
                     85:                        stripverts[stripcount+2] = check->vertindex[ (k+2)%3 ];
                     86:                        striptris[stripcount] = j;
                     87:                        stripcount++;
                     88: 
                     89:                        used[j] = 2;
                     90:                        goto nexttri;
                     91:                }
                     92:        }
                     93: done:
                     94: 
                     95:        // clear the temp used flags
                     96:        for (j=starttri+1 ; j<pheader->numtris ; j++)
                     97:                if (used[j] == 2)
                     98:                        used[j] = 0;
                     99: 
                    100:        return stripcount;
                    101: }
                    102: 
                    103: /*
                    104: ===========
                    105: FanLength
                    106: ===========
                    107: */
                    108: int    FanLength (int starttri, int startv)
                    109: {
                    110:        int             m1, m2;
                    111:        int             j;
                    112:        mtriangle_t     *last, *check;
                    113:        int             k;
                    114: 
                    115:        used[starttri] = 2;
                    116: 
                    117:        last = &triangles[starttri];
                    118: 
                    119:        stripverts[0] = last->vertindex[(startv)%3];
                    120:        stripverts[1] = last->vertindex[(startv+1)%3];
                    121:        stripverts[2] = last->vertindex[(startv+2)%3];
                    122: 
                    123:        striptris[0] = starttri;
                    124:        stripcount = 1;
                    125: 
                    126:        m1 = last->vertindex[(startv+0)%3];
                    127:        m2 = last->vertindex[(startv+2)%3];
                    128: 
                    129: 
                    130:        // look for a matching triangle
                    131: nexttri:
                    132:        for (j=starttri+1, check=&triangles[starttri+1] ; j<pheader->numtris ; j++, check++)
                    133:        {
                    134:                if (check->facesfront != last->facesfront)
                    135:                        continue;
                    136:                for (k=0 ; k<3 ; k++)
                    137:                {
                    138:                        if (check->vertindex[k] != m1)
                    139:                                continue;
                    140:                        if (check->vertindex[ (k+1)%3 ] != m2)
                    141:                                continue;
                    142: 
                    143:                        // this is the next part of the fan
                    144: 
                    145:                        // if we can't use this triangle, this tristrip is done
                    146:                        if (used[j])
                    147:                                goto done;
                    148: 
                    149:                        // the new edge
                    150:                        m2 = check->vertindex[ (k+2)%3 ];
                    151: 
                    152:                        stripverts[stripcount+2] = m2;
                    153:                        striptris[stripcount] = j;
                    154:                        stripcount++;
                    155: 
                    156:                        used[j] = 2;
                    157:                        goto nexttri;
                    158:                }
                    159:        }
                    160: done:
                    161: 
                    162:        // clear the temp used flags
                    163:        for (j=starttri+1 ; j<pheader->numtris ; j++)
                    164:                if (used[j] == 2)
                    165:                        used[j] = 0;
                    166: 
                    167:        return stripcount;
                    168: }
                    169: 
                    170: 
                    171: /*
                    172: ================
                    173: BuildTris
                    174: 
                    175: Generate a list of trifans or strips
                    176: for the model, which holds for all frames
                    177: ================
                    178: */
                    179: void BuildTris (void)
                    180: {
                    181:        int             i, j, k;
                    182:        int             startv;
                    183:        mtriangle_t     *last, *check;
                    184:        int             m1, m2;
                    185:        int             striplength;
                    186:        trivertx_t      *v;
                    187:        mtriangle_t *tv;
                    188:        float   s, t;
                    189:        int             index;
                    190:        int             len, bestlen, besttype;
                    191:        int             bestverts[1024];
                    192:        int             besttris[1024];
                    193:        int             type;
                    194: 
                    195:        //
                    196:        // build tristrips
                    197:        //
                    198:        numorder = 0;
                    199:        numcommands = 0;
                    200:        memset (used, 0, sizeof(used));
                    201:        for (i=0 ; i<pheader->numtris ; i++)
                    202:        {
                    203:                // pick an unused triangle and start the trifan
                    204:                if (used[i])
                    205:                        continue;
                    206: 
                    207:                bestlen = 0;
                    208:                for (type = 0 ; type < 2 ; type++)
                    209: //     type = 1;
                    210:                {
                    211:                        for (startv =0 ; startv < 3 ; startv++)
                    212:                        {
                    213:                                if (type == 1)
                    214:                                        len = StripLength (i, startv);
                    215:                                else
                    216:                                        len = FanLength (i, startv);
                    217:                                if (len > bestlen)
                    218:                                {
                    219:                                        besttype = type;
                    220:                                        bestlen = len;
                    221:                                        for (j=0 ; j<bestlen+2 ; j++)
                    222:                                                bestverts[j] = stripverts[j];
                    223:                                        for (j=0 ; j<bestlen ; j++)
                    224:                                                besttris[j] = striptris[j];
                    225:                                }
                    226:                        }
                    227:                }
                    228: 
                    229:                // mark the tris on the best strip as used
                    230:                for (j=0 ; j<bestlen ; j++)
                    231:                        used[besttris[j]] = 1;
                    232: 
                    233:                if (besttype == 1)
                    234:                        commands[numcommands++] = (bestlen+2);
                    235:                else
                    236:                        commands[numcommands++] = -(bestlen+2);
                    237: 
                    238:                for (j=0 ; j<bestlen+2 ; j++)
                    239:                {
                    240:                        // emit a vertex into the reorder buffer
                    241:                        k = bestverts[j];
                    242:                        vertexorder[numorder++] = k;
                    243: 
                    244:                        // emit s/t coords into the commands stream
                    245:                        s = stverts[k].s;
                    246:                        t = stverts[k].t;
                    247:                        if (!triangles[besttris[0]].facesfront && stverts[k].onseam)
                    248:                                s += pheader->skinwidth / 2;    // on back side
                    249:                        s = (s + 0.5) / pheader->skinwidth;
                    250:                        t = (t + 0.5) / pheader->skinheight;
                    251: 
                    252:                        *(float *)&commands[numcommands++] = s;
                    253:                        *(float *)&commands[numcommands++] = t;
                    254:                }
                    255:        }
                    256: 
                    257:        commands[numcommands++] = 0;            // end of list marker
                    258: 
                    259:        Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands);
                    260: 
                    261:        allverts += numorder;
                    262:        alltris += pheader->numtris;
                    263: }
                    264: 
                    265: 
                    266: /*
                    267: ================
                    268: GL_MakeAliasModelDisplayLists
                    269: ================
                    270: */
                    271: void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr)
                    272: {
                    273:        int             i, j;
                    274:        maliasgroup_t   *paliasgroup;
                    275:        int                     *cmds;
                    276:        trivertx_t      *verts;
                    277:        char    cache[MAX_QPATH], fullpath[MAX_OSPATH], *c;
                    278:        FILE    *f;
                    279:        int             len;
                    280:        byte    *data;
                    281: 
                    282:        aliasmodel = m;
                    283:        paliashdr = hdr;        // (aliashdr_t *)Mod_Extradata (m);
                    284: 
                    285:        //
                    286:        // look for a cached version
                    287:        //
                    288:        strcpy (cache, "glquake/");
                    289:        COM_StripExtension (m->name+strlen("progs/"), cache+strlen("glquake/"));
                    290:        strcat (cache, ".ms2");
                    291: 
                    292:        COM_FOpenFile (cache, &f);      
                    293:        if (f)
                    294:        {
                    295:                fread (&numcommands, 4, 1, f);
                    296:                fread (&numorder, 4, 1, f);
                    297:                fread (&commands, numcommands * sizeof(commands[0]), 1, f);
                    298:                fread (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
                    299:                fclose (f);
                    300:        }
                    301:        else
                    302:        {
                    303:                //
                    304:                // build it from scratch
                    305:                //
                    306:                Con_Printf ("meshing %s...\n",m->name);
                    307: 
                    308:                BuildTris ();           // trifans or lists
                    309: 
                    310:                //
                    311:                // save out the cached version
                    312:                //
                    313:                sprintf (fullpath, "%s/%s", com_gamedir, cache);
                    314:                f = fopen (fullpath, "wb");
                    315:                if (f)
                    316:                {
                    317:                        fwrite (&numcommands, 4, 1, f);
                    318:                        fwrite (&numorder, 4, 1, f);
                    319:                        fwrite (&commands, numcommands * sizeof(commands[0]), 1, f);
                    320:                        fwrite (&vertexorder, numorder * sizeof(vertexorder[0]), 1, f);
                    321:                        fclose (f);
                    322:                }
                    323:        }
                    324: 
                    325: 
                    326:        // save the data out
                    327: 
                    328:        paliashdr->poseverts = numorder;
                    329: 
                    330:        cmds = Hunk_Alloc (numcommands * 4);
                    331:        paliashdr->commands = (byte *)cmds - (byte *)paliashdr;
                    332:        memcpy (cmds, commands, numcommands * 4);
                    333: 
                    334:        verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts 
                    335:                * sizeof(trivertx_t) );
                    336:        paliashdr->posedata = (byte *)verts - (byte *)paliashdr;
                    337:        for (i=0 ; i<paliashdr->numposes ; i++)
                    338:                for (j=0 ; j<numorder ; j++)
                    339:                        *verts++ = poseverts[i][vertexorder[j]];
                    340: }
                    341: 

unix.superglobalmegacorp.com

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