Annotation of quake1/gl_mesh.c, revision 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.