r_model_md2.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 1997-2001 Id Software, Inc.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 #include "r_local.h"
00027 
00028 /*
00029 ==============================================================================
00030 MD2 ALIAS MODELS
00031 ==============================================================================
00032 */
00033 
00034 static void R_ModLoadTags (model_t * mod, void *buffer, int bufSize)
00035 {
00036     dMD2tag_t *pintag, *pheader;
00037     int version;
00038     int i, j, size;
00039     float *inmat, *outmat;
00040     int read;
00041 
00042     pintag = (dMD2tag_t *) buffer;
00043 
00044     version = LittleLong(pintag->version);
00045     if (version != TAG_VERSION)
00046         Com_Error(ERR_FATAL, "R_ModLoadTags: %s has wrong version number (%i should be %i)",
00047                 mod->alias.tagname, version, TAG_VERSION);
00048 
00049     size = LittleLong(pintag->ofs_extractend);
00050     mod->alias.tagdata = Mem_PoolAlloc(size, vid_modelPool, 0);
00051     pheader = mod->alias.tagdata;
00052 
00053     /* byte swap the header fields and sanity check */
00054     for (i = 0; i < (int)sizeof(dMD2tag_t) / 4; i++)
00055         ((int *) pheader)[i] = LittleLong(((int *) buffer)[i]);
00056 
00057     if (pheader->num_tags <= 0)
00058         Com_Error(ERR_FATAL, "R_ModLoadTags: tag file %s has no tags", mod->alias.tagname);
00059 
00060     if (pheader->num_frames <= 0)
00061         Com_Error(ERR_FATAL, "R_ModLoadTags: tag file %s has no frames", mod->alias.tagname);
00062 
00063     /* load tag names */
00064     memcpy((char *) pheader + pheader->ofs_names, (char *) pintag + pheader->ofs_names, pheader->num_tags * MD2_MAX_SKINNAME);
00065 
00066     /* load tag matrices */
00067     inmat = (float *) ((byte *) pintag + pheader->ofs_tags);
00068     outmat = (float *) ((byte *) pheader + pheader->ofs_tags);
00069 
00070     if (bufSize != pheader->ofs_end)
00071         Com_Error(ERR_FATAL, "R_ModLoadTags: tagfile %s is broken - expected: %i, offsets tell us to read: %i",
00072             mod->alias.tagname, bufSize, pheader->ofs_end);
00073 
00074     if (pheader->num_frames != mod->alias.num_frames)
00075         Com_Printf("R_ModLoadTags: found %i frames in %s but model has %i frames\n",
00076             pheader->num_frames, mod->alias.tagname, mod->alias.num_frames);
00077 
00078     if (pheader->ofs_names != 32)
00079         Com_Error(ERR_FATAL, "R_ModLoadTags: invalid ofs_name for tagfile %s", mod->alias.tagname);
00080     if (pheader->ofs_tags != pheader->ofs_names + (pheader->num_tags * 64))
00081         Com_Error(ERR_FATAL, "R_ModLoadTags: invalid ofs_tags for tagfile %s", mod->alias.tagname);
00082     /* (4 * 3) * 4 bytes (int) */
00083     if (pheader->ofs_end != pheader->ofs_tags + (pheader->num_tags * pheader->num_frames * 48))
00084         Com_Error(ERR_FATAL, "R_ModLoadTags: invalid ofs_end for tagfile %s", mod->alias.tagname);
00085     /* (4 * 4) * 4 bytes (int) */
00086     if (pheader->ofs_extractend != pheader->ofs_tags + (pheader->num_tags * pheader->num_frames * 64))
00087         Com_Error(ERR_FATAL, "R_ModLoadTags: invalid ofs_extractend for tagfile %s", mod->alias.tagname);
00088 
00089     for (i = 0; i < pheader->num_tags * pheader->num_frames; i++) {
00090         for (j = 0; j < 4; j++) {
00091             *outmat++ = LittleFloat(*inmat++);
00092             *outmat++ = LittleFloat(*inmat++);
00093             *outmat++ = LittleFloat(*inmat++);
00094             *outmat++ = 0.0;
00095         }
00096         outmat--;
00097         *outmat++ = 1.0;
00098     }
00099 
00100     read = (byte *)outmat - (byte *)pheader;
00101     if (read != size)
00102         Com_Error(ERR_FATAL, "R_ModLoadTags: read: %i expected: %i - tags: %i, frames: %i (should be %i)",
00103             read, size, pheader->num_tags, pheader->num_frames, mod->alias.num_frames);
00104 }
00105 
00109 static void R_ModLoadAliasMD2MeshUnindexed (model_t *mod, const dMD2Model_t *md2, int bufSize, qboolean loadNormals)
00110 {
00111     int i, j;
00112     const dMD2Triangle_t *pintri;
00113     const dMD2Coord_t *pincoord;
00114     mAliasMesh_t *outMesh;
00115     mAliasFrame_t *outFrame, *outFrameTmp;
00116     mAliasVertex_t *outVertex;
00117     mAliasCoord_t *outCoord;
00118     int32_t tempIndex[MD2_MAX_TRIANGLES * 3];
00119     int32_t tempSTIndex[MD2_MAX_TRIANGLES * 3];
00120     int indRemap[MD2_MAX_TRIANGLES * 3];
00121     int32_t *outIndex;
00122     int frameSize, numIndexes, numVerts;
00123     double isw;
00124     const char *md2Path;
00125     int md2Verts;
00126 
00127     outMesh = &mod->alias.meshes[mod->alias.num_meshes - 1];
00128 
00129     Q_strncpyz(outMesh->name, mod->name, sizeof(outMesh->name));
00130     md2Verts = LittleLong(md2->num_verts);
00131     if (md2Verts <= 0 || md2Verts >= MD2_MAX_VERTS)
00132         Com_Error(ERR_DROP, "model %s has too many (or no) vertices (%i/%i)",
00133             mod->name, md2Verts, MD2_MAX_VERTS);
00134     outMesh->num_tris = LittleLong(md2->num_tris);
00135     if (outMesh->num_tris <= 0 || outMesh->num_tris >= MD2_MAX_TRIANGLES)
00136         Com_Error(ERR_DROP, "model %s has too many (or no) triangles (%i/%i)",
00137             mod->name, outMesh->num_tris, MD2_MAX_TRIANGLES);
00138     frameSize = LittleLong(md2->framesize);
00139     outMesh->num_verts = md2Verts;
00140 
00141     if (mod->alias.num_meshes == 1) {
00142         /* load the skins */
00143         outMesh->num_skins = LittleLong(md2->num_skins);
00144         if (outMesh->num_skins < 0 || outMesh->num_skins >= MD2_MAX_SKINS)
00145             Com_Error(ERR_DROP, "Could not load model '%s' - invalid num_skins value: %i", mod->name, outMesh->num_skins);
00146 
00147         outMesh->skins = Mem_PoolAlloc(sizeof(mAliasSkin_t) * outMesh->num_skins, vid_modelPool, 0);
00148         md2Path = (const char *) md2 + LittleLong(md2->ofs_skins);
00149         for (i = 0; i < outMesh->num_skins; i++) {
00150             outMesh->skins[i].skin = R_AliasModelGetSkin(mod->name, md2Path + i * MD2_MAX_SKINNAME);
00151             Q_strncpyz(outMesh->skins[i].name, outMesh->skins[i].skin->name, sizeof(outMesh->skins[i].name));
00152         }
00153 
00154         outMesh->skinWidth = LittleLong(md2->skinwidth);
00155         outMesh->skinHeight = LittleLong(md2->skinheight);
00156 
00157         if (outMesh->skinHeight <= 0 || outMesh->skinWidth <= 0)
00158             Com_Error(ERR_DROP, "model %s has invalid skin dimensions '%d x %d'",
00159                     mod->name, outMesh->skinHeight, outMesh->skinWidth);
00160     } else {
00161         /* skin data must be the same for the lod meshes */
00162         outMesh->num_skins = mod->alias.meshes[0].num_skins;
00163         outMesh->skins = mod->alias.meshes[0].skins;
00164         outMesh->skinWidth = mod->alias.meshes[0].skinWidth;
00165         outMesh->skinHeight = mod->alias.meshes[0].skinHeight;
00166     }
00167 
00168     isw = 1.0 / (double)outMesh->skinWidth;
00169 
00170     /* load triangle lists */
00171     pintri = (const dMD2Triangle_t *) ((const byte *) md2 + LittleLong(md2->ofs_tris));
00172     pincoord = (const dMD2Coord_t *) ((const byte *) md2 + LittleLong(md2->ofs_st));
00173 
00174     for (i = 0; i < outMesh->num_tris; i++) {
00175         for (j = 0; j < 3; j++) {
00176             tempIndex[i * 3 + j] = (int32_t)LittleShort(pintri[i].index_verts[j]);
00177             tempSTIndex[i * 3 + j] = (int32_t)LittleShort(pintri[i].index_st[j]);
00178         }
00179     }
00180 
00181     /* build list of unique vertices */
00182     numIndexes = outMesh->num_tris * 3;
00183     numVerts = 0;
00184     outMesh->indexes = outIndex = Mem_PoolAlloc(sizeof(int32_t) * numIndexes, vid_modelPool, 0);
00185 
00186     for (i = 0; i < numIndexes; i++)
00187         indRemap[i] = -1;
00188 
00189     for (i = 0; i < numIndexes; i++) {
00190         if (indRemap[i] != -1)
00191             continue;
00192 
00193         /* remap duplicates */
00194         for (j = i + 1; j < numIndexes; j++) {
00195             if (tempIndex[j] != tempIndex[i])
00196                 continue;
00197             if (pincoord[tempSTIndex[j]].s != pincoord[tempSTIndex[i]].s
00198              || pincoord[tempSTIndex[j]].t != pincoord[tempSTIndex[i]].t)
00199                 continue;
00200 
00201             indRemap[j] = i;
00202             outIndex[j] = numVerts;
00203         }
00204 
00205         /* add unique vertex */
00206         indRemap[i] = i;
00207         outIndex[i] = numVerts++;
00208     }
00209 
00210     if (numVerts >= 4096)
00211         Com_Printf("model %s has more than 4096 verts (original verts: %i and tris: %i)\n",
00212                 mod->name, outMesh->num_verts, outMesh->num_tris);
00213 
00214     outMesh->num_verts = numVerts;
00215     if (outMesh->num_verts <= 0 || outMesh->num_verts >= MAX_ALIAS_VERTS)
00216         Com_Error(ERR_DROP, "R_ModLoadAliasMD2Mesh: invalid amount of verts for model '%s' (verts: %i, tris: %i)\n",
00217             mod->name, outMesh->num_verts, outMesh->num_tris);
00218 
00219     for (i = 0; i < numIndexes; i++) {
00220         if (indRemap[i] == i)
00221             continue;
00222 
00223         outIndex[i] = outIndex[indRemap[i]];
00224     }
00225 
00226     outMesh->stcoords = outCoord = Mem_PoolAlloc(sizeof(mAliasCoord_t) * outMesh->num_verts, vid_modelPool, 0);
00227     for (j = 0; j < numIndexes; j++) {
00228         outCoord[outIndex[j]][0] = (float)(((double)LittleShort(pincoord[tempSTIndex[indRemap[j]]].s) + 0.5) * isw);
00229         outCoord[outIndex[j]][1] = (float)(((double)LittleShort(pincoord[tempSTIndex[indRemap[j]]].t) + 0.5) * isw);
00230     }
00231 
00232     /* load the frames */
00233     outFrameTmp = outFrame = Mem_PoolAlloc(sizeof(mAliasFrame_t) * mod->alias.num_frames, vid_modelPool, 0);
00234     outMesh->vertexes = outVertex = Mem_PoolAlloc(sizeof(mAliasVertex_t) * mod->alias.num_frames * outMesh->num_verts, vid_modelPool, 0);
00235     if (mod->alias.num_meshes == 1)
00236         mod->alias.frames = outFrame;
00237     else if (mod->alias.num_frames != LittleLong(md2->num_frames))
00238         Com_Error(ERR_DROP, "R_ModLoadAliasMD2Mesh: invalid amount of frames for lod model for '%s'\n", mod->name);
00239 
00240     for (i = 0; i < mod->alias.num_frames; i++, outFrame++, outVertex += numVerts) {
00241         const dMD2Frame_t *pinframe = (const dMD2Frame_t *) ((const byte *) md2 + LittleLong(md2->ofs_frames) + i * frameSize);
00242 
00243         for (j = 0; j < 3; j++)
00244             outFrame->scale[j] = LittleFloat(pinframe->scale[j]);
00245 
00246         if (mod->alias.num_meshes == 1) {
00247             for (j = 0; j < 3; j++)
00248                 outFrame->translate[j] = LittleFloat(pinframe->translate[j]);
00249 
00250             VectorCopy(outFrame->translate, outFrame->mins);
00251             VectorMA(outFrame->translate, 255, outFrame->scale, outFrame->maxs);
00252 
00253             AddPointToBounds(outFrame->mins, mod->mins, mod->maxs);
00254             AddPointToBounds(outFrame->maxs, mod->mins, mod->maxs);
00255         }
00256 
00257         for (j = 0; j < numIndexes; j++) {
00258             const int index = tempIndex[indRemap[j]];
00259             const dMD2TriangleVertex_t *v = &pinframe->verts[index];
00260             float* ov = outVertex[outIndex[j]].point;
00261             ov[0] = (int16_t)v->v[0] * outFrame->scale[0];
00262             ov[1] = (int16_t)v->v[1] * outFrame->scale[1];
00263             ov[2] = (int16_t)v->v[2] * outFrame->scale[2];
00264         }
00265     }
00266 
00267     /* Calculate normals and tangents */
00268     if (loadNormals)
00269         R_ModCalcUniqueNormalsAndTangents(outMesh, mod->alias.num_frames, 0.5);
00270 
00271     if (mod->alias.num_meshes > 1)
00272         Mem_Free(outFrameTmp);
00273 }
00274 
00278 static void R_ModLoadAliasMD2MeshIndexed (model_t *mod, const dMD2Model_t *md2, int bufSize)
00279 {
00280     int i, j;
00281     const dMD2Triangle_t *pintri;
00282     const dMD2Coord_t *pincoord;
00283     mAliasMesh_t *outMesh;
00284     mAliasFrame_t *outFrame, *outFrameTmp;
00285     mAliasVertex_t *outVertex;
00286     mAliasCoord_t *outCoord;
00287     int32_t tempIndex[MD2_MAX_TRIANGLES * 3];
00288     int32_t tempSTIndex[MD2_MAX_TRIANGLES * 3];
00289     int32_t *outIndex;
00290     int frameSize, numIndexes, numVerts;
00291     double isw;
00292     const char *md2Path;
00293     int md2Verts;
00294 
00295     outMesh = &mod->alias.meshes[mod->alias.num_meshes - 1];
00296 
00297     Q_strncpyz(outMesh->name, mod->name, sizeof(outMesh->name));
00298     md2Verts = LittleLong(md2->num_verts);
00299     if (md2Verts <= 0 || md2Verts >= MD2_MAX_VERTS)
00300         Com_Error(ERR_DROP, "model %s has too many (or no) vertices (%i/%i)",
00301             mod->name, md2Verts, MD2_MAX_VERTS);
00302     outMesh->num_tris = LittleLong(md2->num_tris);
00303     if (outMesh->num_tris <= 0 || outMesh->num_tris >= MD2_MAX_TRIANGLES)
00304         Com_Error(ERR_DROP, "model %s has too many (or no) triangles (%i/%i)",
00305             mod->name, outMesh->num_tris, MD2_MAX_TRIANGLES);
00306     frameSize = LittleLong(md2->framesize);
00307 
00308     if (outMesh->num_verts >= 4096)
00309         Com_Printf("model %s has more than 4096 verts\n", mod->name);
00310 
00311     if (outMesh->num_verts <= 0 || outMesh->num_verts >= MAX_ALIAS_VERTS)
00312         Com_Error(ERR_DROP, "R_ModLoadAliasMD2Mesh: invalid amount of verts for model '%s' (verts: %i, tris: %i)",
00313             mod->name, outMesh->num_verts, outMesh->num_tris);
00314 
00315     if (mod->alias.num_meshes == 1) {
00316         /* load the skins */
00317         outMesh->num_skins = LittleLong(md2->num_skins);
00318         if (outMesh->num_skins < 0 || outMesh->num_skins >= MD2_MAX_SKINS)
00319             Com_Error(ERR_DROP, "Could not load model '%s' - invalid num_skins value: %i\n", mod->name, outMesh->num_skins);
00320 
00321         outMesh->skins = Mem_PoolAlloc(sizeof(mAliasSkin_t) * outMesh->num_skins, vid_modelPool, 0);
00322         md2Path = (const char *) md2 + LittleLong(md2->ofs_skins);
00323         for (i = 0; i < outMesh->num_skins; i++) {
00324             outMesh->skins[i].skin = R_AliasModelGetSkin(mod->name, md2Path + i * MD2_MAX_SKINNAME);
00325             Q_strncpyz(outMesh->skins[i].name, outMesh->skins[i].skin->name, sizeof(outMesh->skins[i].name));
00326         }
00327 
00328         outMesh->skinWidth = LittleLong(md2->skinwidth);
00329         outMesh->skinHeight = LittleLong(md2->skinheight);
00330 
00331         if (outMesh->skinHeight <= 0 || outMesh->skinWidth <= 0)
00332             Com_Error(ERR_DROP, "model %s has invalid skin dimensions '%d x %d'",
00333                     mod->name, outMesh->skinHeight, outMesh->skinWidth);
00334     } else {
00335         /* skin data must be the same for the lod meshes */
00336         outMesh->num_skins = mod->alias.meshes[0].num_skins;
00337         outMesh->skins = mod->alias.meshes[0].skins;
00338         outMesh->skinWidth = mod->alias.meshes[0].skinWidth;
00339         outMesh->skinHeight = mod->alias.meshes[0].skinHeight;
00340     }
00341 
00342     isw = 1.0 / (double)outMesh->skinWidth;
00343 
00344     /* load triangle lists */
00345     pintri = (const dMD2Triangle_t *) ((const byte *) md2 + LittleLong(md2->ofs_tris));
00346     pincoord = (const dMD2Coord_t *) ((const byte *) md2 + LittleLong(md2->ofs_st));
00347 
00348     for (i = 0; i < outMesh->num_tris; i++) {
00349         for (j = 0; j < 3; j++) {
00350             tempIndex[i * 3 + j] = (int32_t)LittleShort(pintri[i].index_verts[j]);
00351             tempSTIndex[i * 3 + j] = (int32_t)LittleShort(pintri[i].index_st[j]);
00352         }
00353     }
00354 
00355     /* build list of unique vertices */
00356     numIndexes = outMesh->num_tris * 3;
00357     numVerts = outMesh->num_verts;
00358 
00359     outMesh->stcoords = outCoord = Mem_PoolAlloc(sizeof(mAliasCoord_t) * outMesh->num_verts, vid_modelPool, 0);
00360     outIndex = outMesh->indexes;
00361     for (j = 0; j < numIndexes; j++) {
00362         outCoord[outIndex[j]][0] = (float)(((double)LittleShort(pincoord[tempSTIndex[j]].s) + 0.5) * isw);
00363         outCoord[outIndex[j]][1] = (float)(((double)LittleShort(pincoord[tempSTIndex[j]].t) + 0.5) * isw);
00364     }
00365 
00366     /* load the frames */
00367     outFrameTmp = outFrame = Mem_PoolAlloc(sizeof(mAliasFrame_t) * mod->alias.num_frames, vid_modelPool, 0);
00368     outVertex = outMesh->vertexes;
00369     if (mod->alias.num_meshes == 1)
00370         mod->alias.frames = outFrame;
00371     else if (mod->alias.num_frames != LittleLong(md2->num_frames))
00372         Com_Error(ERR_DROP, "R_ModLoadAliasMD2Mesh: invalid amount of frames for lod model for '%s'\n", mod->name);
00373 
00374     for (i = 0; i < mod->alias.num_frames; i++, outFrame++, outVertex += numVerts) {
00375         const dMD2Frame_t *pinframe = (const dMD2Frame_t *) ((const byte *) md2 + LittleLong(md2->ofs_frames) + i * frameSize);
00376 
00377         for (j = 0; j < 3; j++)
00378             outFrame->scale[j] = LittleFloat(pinframe->scale[j]);
00379 
00380         if (mod->alias.num_meshes == 1) {
00381             for (j = 0; j < 3; j++)
00382                 outFrame->translate[j] = LittleFloat(pinframe->translate[j]);
00383 
00384             VectorCopy(outFrame->translate, outFrame->mins);
00385             VectorMA(outFrame->translate, 255, outFrame->scale, outFrame->maxs);
00386 
00387             AddPointToBounds(outFrame->mins, mod->mins, mod->maxs);
00388             AddPointToBounds(outFrame->maxs, mod->mins, mod->maxs);
00389         }
00390 
00391         for (j = 0; j < numIndexes; j++) {
00392             const int index = tempIndex[j];
00393             const dMD2TriangleVertex_t *v = &pinframe->verts[index];
00394             float* ov = outVertex[outIndex[j]].point;
00395             ov[0] = (int16_t)v->v[0] * outFrame->scale[0];
00396             ov[1] = (int16_t)v->v[1] * outFrame->scale[1];
00397             ov[2] = (int16_t)v->v[2] * outFrame->scale[2];
00398         }
00399     }
00400 
00401     if (mod->alias.num_meshes > 1)
00402         Mem_Free(outFrameTmp);
00403 }
00404 
00408 static void R_ModLoadAliasMD2Mesh (model_t *mod, const dMD2Model_t *md2, int bufSize, qboolean loadNormals)
00409 {
00410     mAliasMesh_t *outMesh;
00411     int version;
00412     size_t size;
00413 
00414     /* sanity checks */
00415     version = LittleLong(md2->version);
00416     if (version != MD2_ALIAS_VERSION)
00417         Com_Error(ERR_DROP, "%s has wrong version number (%i should be %i)", mod->name, version, MD2_ALIAS_VERSION);
00418 
00419     if (bufSize != LittleLong(md2->ofs_end))
00420         Com_Error(ERR_DROP, "model %s broken offset values (%i, %i)", mod->name, bufSize, LittleLong(md2->ofs_end));
00421 
00422     mod->alias.num_meshes++;
00423     size = sizeof(mAliasMesh_t) * mod->alias.num_meshes;
00424 
00425     if (mod->alias.meshes == NULL)
00426         mod->alias.meshes = outMesh = Mem_PoolAlloc(size, vid_modelPool, 0);
00427     else {
00428         mod->alias.meshes = Mem_ReAlloc(mod->alias.meshes, size);
00429         outMesh = &mod->alias.meshes[mod->alias.num_meshes - 1];
00430     }
00431 
00432     if (loadNormals) {
00433         /* try to load normals and tangents */
00434         if (R_ModLoadMDX(mod)) {
00435             R_ModLoadAliasMD2MeshIndexed(mod, md2, bufSize);
00436         } else {
00437             /* compute normals and tangents */
00438             R_ModLoadAliasMD2MeshUnindexed(mod, md2, bufSize, qtrue);
00439         }
00440     } else {
00441         /* don't load normals and tangents */
00442         R_ModLoadAliasMD2MeshUnindexed(mod, md2, bufSize, qfalse);
00443     }
00444 }
00445 
00451 static void R_ModLoadLevelOfDetailData (model_t* mod, qboolean loadNormals)
00452 {
00453     char base[MAX_QPATH];
00454     int i;
00455 
00456     Com_StripExtension(mod->name, base, sizeof(base));
00457 
00458     for (i = 1; i <= 3; i++) {
00459         if (FS_CheckFile("%s-lod%02i.md2", base, i) != -1) {
00460             byte *buf;
00461             int bufSize;
00462             char fileName[MAX_QPATH];
00463             const dMD2Model_t *md2;
00464 
00465             Com_Printf("found lod model for %s\n", mod->name);
00466 
00467             Com_sprintf(fileName, sizeof(fileName), "%s-lod%02i.md2", base, i);
00468             /* load the file */
00469             bufSize = FS_LoadFile(fileName, &buf);
00470             if (!buf)
00471                 return;
00472 
00473             /* get the disk data */
00474             md2 = (const dMD2Model_t *) buf;
00475 
00476             R_ModLoadAliasMD2Mesh(mod, md2, bufSize, loadNormals);
00477 
00478             FS_FreeFile(buf);
00479         }
00480     }
00481 }
00482 
00486 void R_ModLoadAliasMD2Model (model_t *mod, byte *buffer, int bufSize, qboolean loadNormals)
00487 {
00488     dMD2Model_t *md2;
00489     byte *tagbuf = NULL, *animbuf = NULL;
00490     size_t l;
00491 
00492     /* get the disk data */
00493     md2 = (dMD2Model_t *) buffer;
00494 
00495     /* only one mesh for md2 models */
00496     mod->alias.num_frames = LittleLong(md2->num_frames);
00497     if (mod->alias.num_frames <= 0 || mod->alias.num_frames >= MD2_MAX_FRAMES)
00498         Com_Error(ERR_DROP, "model %s has too many (or no) frames", mod->name);
00499 
00500     /* fixed values */
00501     mod->type = mod_alias_md2;
00502 
00503     ClearBounds(mod->mins, mod->maxs);
00504 
00505     R_ModLoadAliasMD2Mesh(mod, md2, bufSize, loadNormals);
00506 
00507     /* load the tags */
00508     Q_strncpyz(mod->alias.tagname, mod->name, sizeof(mod->alias.tagname));
00509     /* strip model extension and set the extension to tag */
00510     l = strlen(mod->alias.tagname) - 4;
00511     strcpy(&(mod->alias.tagname[l]), ".tag");
00512 
00513     /* try to load the tag file */
00514     if (FS_CheckFile("%s", mod->alias.tagname) != -1) {
00515         /* load the tags */
00516         const int size = FS_LoadFile(mod->alias.tagname, &tagbuf);
00517         R_ModLoadTags(mod, tagbuf, size);
00518         FS_FreeFile(tagbuf);
00519     }
00520 
00521     /* load the animations */
00522     Q_strncpyz(mod->alias.animname, mod->name, sizeof(mod->alias.animname));
00523     l = strlen(mod->alias.animname) - 4;
00524     strcpy(&(mod->alias.animname[l]), ".anm");
00525 
00526     /* try to load the animation file */
00527     if (FS_CheckFile("%s", mod->alias.animname) != -1) {
00528         /* load the tags */
00529         FS_LoadFile(mod->alias.animname, &animbuf);
00530         R_ModLoadAnims(&mod->alias, animbuf);
00531         FS_FreeFile(animbuf);
00532     }
00533 
00534     R_ModLoadLevelOfDetailData(mod, loadNormals);
00535 
00536     R_ModLoadArrayData(&mod->alias, mod->alias.meshes, loadNormals);
00537 }

Generated by  doxygen 1.6.2