00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "r_local.h"
00027
00028
00029
00030
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
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
00064 memcpy((char *) pheader + pheader->ofs_names, (char *) pintag + pheader->ofs_names, pheader->num_tags * MD2_MAX_SKINNAME);
00065
00066
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00434 if (R_ModLoadMDX(mod)) {
00435 R_ModLoadAliasMD2MeshIndexed(mod, md2, bufSize);
00436 } else {
00437
00438 R_ModLoadAliasMD2MeshUnindexed(mod, md2, bufSize, qtrue);
00439 }
00440 } else {
00441
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
00469 bufSize = FS_LoadFile(fileName, &buf);
00470 if (!buf)
00471 return;
00472
00473
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
00493 md2 = (dMD2Model_t *) buffer;
00494
00495
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
00501 mod->type = mod_alias_md2;
00502
00503 ClearBounds(mod->mins, mod->maxs);
00504
00505 R_ModLoadAliasMD2Mesh(mod, md2, bufSize, loadNormals);
00506
00507
00508 Q_strncpyz(mod->alias.tagname, mod->name, sizeof(mod->alias.tagname));
00509
00510 l = strlen(mod->alias.tagname) - 4;
00511 strcpy(&(mod->alias.tagname[l]), ".tag");
00512
00513
00514 if (FS_CheckFile("%s", mod->alias.tagname) != -1) {
00515
00516 const int size = FS_LoadFile(mod->alias.tagname, &tagbuf);
00517 R_ModLoadTags(mod, tagbuf, size);
00518 FS_FreeFile(tagbuf);
00519 }
00520
00521
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
00527 if (FS_CheckFile("%s", mod->alias.animname) != -1) {
00528
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 }