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 #include "../../shared/parse.h"
00028 #include "r_state.h"
00029
00030
00031
00032
00033
00034
00035
00036 void R_ModLoadAnims (mAliasModel_t *mod, void *buffer)
00037 {
00038 const char *text, *token;
00039 mAliasAnim_t *anim;
00040 int n;
00041
00042 for (n = 0, text = buffer; text; n++)
00043 Com_Parse(&text);
00044 n /= 4;
00045 if (n > MAX_ANIMS)
00046 n = MAX_ANIMS;
00047
00048 mod->animdata = (mAliasAnim_t *) Mem_PoolAlloc(n * sizeof(*mod->animdata), vid_modelPool, 0);
00049 anim = mod->animdata;
00050 text = buffer;
00051 mod->num_anims = 0;
00052
00053 do {
00054
00055 token = Com_Parse(&text);
00056 if (!text)
00057 break;
00058 Q_strncpyz(anim->name, token, sizeof(anim->name));
00059
00060
00061 token = Com_Parse(&text);
00062 if (!text)
00063 break;
00064 anim->from = atoi(token);
00065 if (anim->from < 0)
00066 Com_Error(ERR_FATAL, "R_ModLoadAnims: negative start frame for %s", mod->animname);
00067 else if (anim->from > mod->num_frames)
00068 Com_Error(ERR_FATAL, "R_ModLoadAnims: start frame is higher than models frame count (%i) (model: %s)",
00069 mod->num_frames, mod->animname);
00070
00071
00072 token = Com_Parse(&text);
00073 if (!text)
00074 break;
00075 anim->to = atoi(token);
00076 if (anim->to < 0)
00077 Com_Error(ERR_FATAL, "R_ModLoadAnims: negative start frame for %s", mod->animname);
00078 else if (anim->to > mod->num_frames)
00079 Com_Error(ERR_FATAL, "R_ModLoadAnims: end frame is higher than models frame count (%i) (model: %s)",
00080 mod->num_frames, mod->animname);
00081
00082
00083 token = Com_Parse(&text);
00084 if (!text)
00085 break;
00086 anim->time = (atof(token) > 0.01) ? (1000.0 / atof(token)) : (1000.0 / 0.01);
00087
00088
00089 mod->num_anims++;
00090 anim++;
00091 } while (mod->num_anims < MAX_ANIMS);
00092 }
00093
00094
00103 static void R_ModCalcNormalsAndTangents (mAliasMesh_t *mesh, int framenum, const vec3_t translate, qboolean backlerp)
00104 {
00105 int i, j;
00106 mAliasVertex_t *vertexes = &mesh->vertexes[framenum * mesh->num_verts];
00107 mAliasCoord_t *stcoords = mesh->stcoords;
00108 const int numIndexes = mesh->num_tris * 3;
00109 const int32_t *indexArray = mesh->indexes;
00110 vec3_t triangleNormals[MAX_ALIAS_TRIS];
00111 vec3_t triangleTangents[MAX_ALIAS_TRIS];
00112 vec3_t triangleBitangents[MAX_ALIAS_TRIS];
00113 float *texcoords, *verts, *normals, *tangents;
00114
00115
00116 texcoords = mesh->texcoords;
00117 if (backlerp) {
00118 verts = mesh->verts;
00119 normals = mesh->normals;
00120 tangents = mesh->tangents;
00121 } else {
00122 verts = mesh->next_verts;
00123 normals = mesh->next_normals;
00124 tangents = mesh->next_tangents;
00125 }
00126
00127
00128 for (i = 0, j = 0; i < numIndexes; i += 3, j++) {
00129 vec3_t dir1, dir2;
00130 vec2_t dir1uv, dir2uv;
00131
00132
00133 VectorSubtract(vertexes[indexArray[i + 0]].point, vertexes[indexArray[i + 1]].point, dir1);
00134 VectorSubtract(vertexes[indexArray[i + 2]].point, vertexes[indexArray[i + 1]].point, dir2);
00135 Vector2Subtract(stcoords[indexArray[i + 0]], stcoords[indexArray[i + 1]], dir1uv);
00136 Vector2Subtract(stcoords[indexArray[i + 2]], stcoords[indexArray[i + 1]], dir2uv);
00137
00138
00139
00140 CrossProduct(dir1, dir2, triangleNormals[j]);
00141
00142 VectorNormalize(triangleNormals[j]);
00143
00144
00145 if ((dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]) != 0.0) {
00146 const float frac = 1.0 / (dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]);
00147 vec3_t tmp1, tmp2;
00148
00149
00150 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
00151 VectorMul(dir1uv[1] * frac, dir2, tmp2);
00152 VectorAdd(tmp1, tmp2, triangleTangents[j]);
00153
00154
00155 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
00156 VectorMul(dir1uv[0] * frac, dir2, tmp2);
00157 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
00158
00159
00160 VectorNormalize(triangleTangents[j]);
00161 VectorNormalize(triangleBitangents[j]);
00162 } else {
00163 VectorClear(triangleTangents[j]);
00164 VectorClear(triangleBitangents[j]);
00165 }
00166 }
00167
00168
00169 for (i = 0; i < mesh->num_verts; i++) {
00170 vec3_t n, b, v;
00171 vec4_t t;
00172 const int len = mesh->revIndexes[i].length;
00173 const int32_t *list = mesh->revIndexes[i].list;
00174
00175 VectorClear(n);
00176 VectorClear(t);
00177 VectorClear(b);
00178
00179
00180 for (j = 0; j < len; j++) {
00181 const int32_t idx = list[j] / 3;
00182 VectorAdd(n, triangleNormals[idx], n);
00183 VectorAdd(t, triangleTangents[idx], t);
00184 VectorAdd(b, triangleBitangents[idx], b);
00185 }
00186
00187
00188 VectorNormalize(n);
00189 VectorNormalize(t);
00190 VectorNormalize(b);
00191
00192
00193 Orthogonalize(t, n);
00194
00195
00196 CrossProduct(n, t, v);
00197 t[3] = (DotProduct(v, b) < 0.0) ? -1.0 : 1.0;
00198
00199
00200 for (j = 0; j < len; j++) {
00201 const int32_t idx = list[j];
00202 const int meshIndex = mesh->indexes[list[j]];
00203 Vector2Copy(stcoords[meshIndex], (texcoords + (2 * idx)));
00204 VectorAdd(vertexes[meshIndex].point, translate, (verts + (3 * idx)));
00205 VectorCopy(n, (normals + (3 * idx)));
00206 Vector4Copy(t, (tangents + (4 * idx)));
00207 }
00208 }
00209 }
00210
00217 qboolean R_ModLoadMDX (model_t *mod)
00218 {
00219 int i;
00220 for (i = 0; i < mod->alias.num_meshes; i++) {
00221 mAliasMesh_t *mesh = &mod->alias.meshes[i];
00222 char mdxFileName[MAX_QPATH];
00223 byte *buffer = NULL, *buf;
00224 const int32_t *intbuf;
00225 int32_t numIndexes;
00226 uint32_t version;
00227 int sharedTris[MAX_ALIAS_VERTS];
00228
00229 Com_StripExtension(mod->name, mdxFileName, sizeof(mdxFileName));
00230 Com_DefaultExtension(mdxFileName, sizeof(mdxFileName), ".mdx");
00231
00232 if (FS_LoadFile(mdxFileName, &buffer) == -1)
00233 return qfalse;
00234
00235 buf = buffer;
00236 if (strncmp((const char *) buf, IDMDXHEADER, strlen(IDMDXHEADER)))
00237 Com_Error(ERR_DROP, "No mdx file buffer given");
00238 buffer += strlen(IDMDXHEADER) * sizeof(char);
00239 version = LittleLong(*(uint32_t*) buffer);
00240 if (version != MDX_VERSION)
00241 Com_Error(ERR_DROP, "Invalid version of the mdx file, expected %i, found %i",
00242 MDX_VERSION, version);
00243 buffer += sizeof(uint32_t);
00244
00245 intbuf = (const int32_t *) buffer;
00246
00247 mesh->num_verts = LittleLong(*intbuf);
00248 if (mesh->num_verts <= 0 || mesh->num_verts > MAX_ALIAS_VERTS)
00249 Com_Error(ERR_DROP, "mdx file for %s has to many (or no) vertices: %i", mod->name, mesh->num_verts);
00250 intbuf++;
00251 numIndexes = LittleLong(*intbuf);
00252 intbuf++;
00253
00254 mesh->indexes = Mem_PoolAlloc(sizeof(int32_t) * numIndexes, vid_modelPool, 0);
00255 mesh->revIndexes = Mem_PoolAlloc(sizeof(mIndexList_t) * mesh->num_verts, vid_modelPool, 0);
00256 mesh->vertexes = Mem_PoolAlloc(sizeof(mAliasVertex_t) * mod->alias.num_frames * mesh->num_verts, vid_modelPool, 0);
00257
00258
00259 for (i = 0; i < numIndexes; i++) {
00260 mesh->indexes[i] = LittleLong(*intbuf);
00261 intbuf++;
00262 }
00263
00264 for (i = 0; i < mesh->num_verts; i++)
00265 sharedTris[i] = 0;
00266
00267
00268 for (i = 0; i < numIndexes; i++)
00269 sharedTris[mesh->indexes[i]]++;
00270
00271 for (i = 0; i < mesh->num_verts; i++) {
00272 mesh->revIndexes[i].length = 0;
00273 mesh->revIndexes[i].list = Mem_PoolAlloc(sizeof(int32_t) * sharedTris[i], vid_modelPool, 0);
00274 }
00275
00276 for (i = 0; i < numIndexes; i++)
00277 mesh->revIndexes[mesh->indexes[i]].list[mesh->revIndexes[mesh->indexes[i]].length++] = i;
00278
00279 FS_FreeFile(buf);
00280 }
00281
00282 return qtrue;
00283 }
00284
00292 void R_ModCalcUniqueNormalsAndTangents (mAliasMesh_t *mesh, int nFrames, float smoothness)
00293 {
00294 int i, j;
00295 vec3_t triangleNormals[MAX_ALIAS_TRIS];
00296 vec3_t triangleTangents[MAX_ALIAS_TRIS];
00297 vec3_t triangleBitangents[MAX_ALIAS_TRIS];
00298 const mAliasVertex_t *vertexes = mesh->vertexes;
00299 mAliasCoord_t *stcoords = mesh->stcoords;
00300 mAliasVertex_t *newVertexes;
00301 mAliasComplexVertex_t tmpVertexes[MAX_ALIAS_VERTS];
00302 vec3_t tmpBitangents[MAX_ALIAS_VERTS];
00303 mAliasCoord_t *newStcoords;
00304 const int numIndexes = mesh->num_tris * 3;
00305 const int32_t *indexArray = mesh->indexes;
00306 int32_t *newIndexArray;
00307 int indRemap[MAX_ALIAS_VERTS];
00308 int sharedTris[MAX_ALIAS_VERTS];
00309 int numVerts = 0;
00310
00311 newIndexArray = Mem_PoolAlloc(sizeof(int32_t) * numIndexes, vid_modelPool, 0);
00312
00313
00314 for (i = 0, j = 0; i < numIndexes; i += 3, j++) {
00315 vec3_t dir1, dir2;
00316 vec2_t dir1uv, dir2uv;
00317
00318
00319 VectorSubtract(vertexes[indexArray[i + 0]].point, vertexes[indexArray[i + 1]].point, dir1);
00320 VectorSubtract(vertexes[indexArray[i + 2]].point, vertexes[indexArray[i + 1]].point, dir2);
00321 Vector2Subtract(stcoords[indexArray[i + 0]], stcoords[indexArray[i + 1]], dir1uv);
00322 Vector2Subtract(stcoords[indexArray[i + 2]], stcoords[indexArray[i + 1]], dir2uv);
00323
00324
00325
00326 CrossProduct(dir1, dir2, triangleNormals[j]);
00327
00328
00329 if ((dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]) != 0.0) {
00330 const float frac = 1.0 / (dir1uv[1] * dir2uv[0] - dir1uv[0] * dir2uv[1]);
00331 vec3_t tmp1, tmp2;
00332
00333
00334 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
00335 VectorMul(dir1uv[1] * frac, dir2, tmp2);
00336 VectorAdd(tmp1, tmp2, triangleTangents[j]);
00337
00338
00339 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
00340 VectorMul(dir1uv[0] * frac, dir2, tmp2);
00341 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
00342 } else {
00343 const float frac = 1.0 / (0.00001);
00344 vec3_t tmp1, tmp2;
00345
00346
00347 VectorMul(-1.0 * dir2uv[1] * frac, dir1, tmp1);
00348 VectorMul(dir1uv[1] * frac, dir2, tmp2);
00349 VectorAdd(tmp1, tmp2, triangleTangents[j]);
00350
00351
00352 VectorMul(-1.0 * dir2uv[0] * frac, dir1, tmp1);
00353 VectorMul(dir1uv[0] * frac, dir2, tmp2);
00354 VectorAdd(tmp1, tmp2, triangleBitangents[j]);
00355 }
00356
00357
00358 VectorNormalize(triangleNormals[j]);
00359 VectorNormalize(triangleTangents[j]);
00360 VectorNormalize(triangleBitangents[j]);
00361
00362 Orthogonalize(triangleTangents[j], triangleBitangents[j]);
00363 }
00364
00365
00366 for (i = 0; i < numIndexes; i++) {
00367 const int idx = (i - i % 3) / 3;
00368 VectorCopy(triangleNormals[idx], tmpVertexes[i].normal);
00369 VectorCopy(triangleTangents[idx], tmpVertexes[i].tangent);
00370 VectorCopy(triangleBitangents[idx], tmpBitangents[i]);
00371
00372 for (j = 0; j < numIndexes; j++) {
00373 const int idx2 = (j - j % 3) / 3;
00374
00375 if (j == i)
00376 continue;
00377
00378
00379
00380 if (VectorEqual(vertexes[indexArray[i]].point, vertexes[indexArray[j]].point)
00381 && DotProduct(triangleNormals[idx], triangleNormals[idx2]) > smoothness) {
00382
00383 VectorAdd(tmpVertexes[i].normal, triangleNormals[idx2], tmpVertexes[i].normal);
00384
00385
00386
00387
00388
00389
00390
00391 if (Vector2Equal(stcoords[indexArray[i]], stcoords[indexArray[j]])
00392 && DotProduct(triangleTangents[idx], triangleTangents[idx2]) > smoothness
00393 && DotProduct(triangleBitangents[idx], triangleBitangents[idx2]) > smoothness) {
00394
00395 VectorAdd(tmpVertexes[i].tangent, triangleTangents[idx2], tmpVertexes[i].tangent);
00396 VectorAdd(tmpBitangents[i], triangleBitangents[idx2], tmpBitangents[i]);
00397 }
00398 }
00399 }
00400
00401 VectorNormalize(tmpVertexes[i].normal);
00402 VectorNormalize(tmpVertexes[i].tangent);
00403 VectorNormalize(tmpBitangents[i]);
00404 }
00405
00406
00407 for (i = 0; i < numIndexes; i++)
00408 indRemap[i] = -1;
00409
00410
00411 for (i = 0; i < numIndexes; i++) {
00412 vec3_t n, b, t, v;
00413 if (indRemap[i] != -1)
00414 continue;
00415
00416 for (j = i + 1; j < numIndexes; j++) {
00417 if (Vector2Equal(stcoords[indexArray[i]], stcoords[indexArray[j]])
00418 && VectorEqual(vertexes[indexArray[i]].point, vertexes[indexArray[j]].point)
00419 && (DotProduct(tmpVertexes[i].normal, tmpVertexes[j].normal) > smoothness)
00420 && (DotProduct(tmpVertexes[i].tangent, tmpVertexes[j].tangent) > smoothness)) {
00421 indRemap[j] = i;
00422 newIndexArray[j] = numVerts;
00423 }
00424 }
00425
00426 VectorCopy(tmpVertexes[i].normal, n);
00427 VectorCopy(tmpVertexes[i].tangent, t);
00428 VectorCopy(tmpBitangents[i], b);
00429
00430
00431 VectorNormalize(n);
00432 VectorNormalize(t);
00433 VectorNormalize(b);
00434
00435
00436 VectorMul(DotProduct(t, n), n, v);
00437 VectorSubtract(t, v, t);
00438 VectorNormalize(t);
00439
00440
00441 CrossProduct(n, t, v);
00442 tmpVertexes[i].tangent[3] = (DotProduct(v, b) < 0.0) ? -1.0 : 1.0;
00443 VectorCopy(n, tmpVertexes[i].normal);
00444 VectorCopy(t, tmpVertexes[i].tangent);
00445
00446 newIndexArray[i] = numVerts++;
00447 indRemap[i] = i;
00448 }
00449
00450 for (i = 0; i < numVerts; i++)
00451 sharedTris[i] = 0;
00452
00453 for (i = 0; i < numIndexes; i++)
00454 sharedTris[newIndexArray[i]]++;
00455
00456
00457 mesh->revIndexes = Mem_PoolAlloc(sizeof(mIndexList_t) * numVerts, vid_modelPool, 0);
00458 for (i = 0; i < numVerts; i++) {
00459 mesh->revIndexes[i].length = 0;
00460 mesh->revIndexes[i].list = Mem_PoolAlloc(sizeof(int32_t) * sharedTris[i], vid_modelPool, 0);
00461 }
00462
00463
00464 newVertexes = Mem_PoolAlloc(sizeof(mAliasVertex_t) * numVerts * nFrames, vid_modelPool, 0);
00465 newStcoords = Mem_PoolAlloc(sizeof(mAliasCoord_t) * numVerts, vid_modelPool, 0);
00466 for (i = 0; i < numIndexes; i++) {
00467 const int idx = indexArray[indRemap[i]];
00468 const int idx2 = newIndexArray[i];
00469
00470
00471 VectorCopy(vertexes[idx].point, newVertexes[idx2].point);
00472 Vector2Copy(stcoords[idx], newStcoords[idx2]);
00473 mesh->revIndexes[idx2].list[mesh->revIndexes[idx2].length++] = i;
00474 }
00475
00476
00477 for (i = 1; i < nFrames; i++) {
00478 for (j = 0; j < numIndexes; j++) {
00479 const int idx = indexArray[indRemap[j]] + (mesh->num_verts * i);
00480 const int idx2 = newIndexArray[j] + (numVerts * i);
00481
00482 VectorCopy(vertexes[idx].point, newVertexes[idx2].point);
00483 }
00484 }
00485
00486
00487 Mem_Free(mesh->stcoords);
00488 Mem_Free(mesh->indexes);
00489 Mem_Free(mesh->vertexes);
00490
00491 mesh->num_verts = numVerts;
00492 mesh->vertexes = newVertexes;
00493 mesh->stcoords = newStcoords;
00494 mesh->indexes = newIndexArray;
00495 }
00496
00497
00498 image_t* R_AliasModelGetSkin (const char *modelFileName, const char *skin)
00499 {
00500 if (skin[0] != '.')
00501 return R_FindImage(skin, it_skin);
00502 else {
00503 char path[MAX_QPATH];
00504 Com_ReplaceFilename(modelFileName, skin, path, sizeof(path));
00505 return R_FindImage(path, it_skin);
00506 }
00507 }
00508
00509 image_t* R_AliasModelState (const model_t *mod, int *mesh, int *frame, int *oldFrame, int *skin)
00510 {
00511
00512 if ((*frame >= mod->alias.num_frames) || *frame < 0) {
00513 Com_Printf("R_AliasModelState %s: no such frame %d (# %i)\n", mod->name, *frame, mod->alias.num_frames);
00514 *frame = 0;
00515 }
00516 if ((*oldFrame >= mod->alias.num_frames) || *oldFrame < 0) {
00517 Com_Printf("R_AliasModelState %s: no such oldframe %d (# %i)\n", mod->name, *oldFrame, mod->alias.num_frames);
00518 *oldFrame = 0;
00519 }
00520
00521 if (*mesh < 0 || *mesh >= mod->alias.num_meshes)
00522 *mesh = 0;
00523
00524 if (!mod->alias.meshes)
00525 return NULL;
00526
00527
00528 if (*skin < 0 || *skin >= mod->alias.meshes[*mesh].num_skins)
00529 *skin = 0;
00530
00531 if (!mod->alias.meshes[*mesh].num_skins)
00532 Com_Error(ERR_DROP, "Model with no skins");
00533
00534 if (mod->alias.meshes[*mesh].skins[*skin].skin->texnum <= 0)
00535 Com_Error(ERR_DROP, "Texture is already freed and no longer uploaded, texnum is invalid for model %s",
00536 mod->name);
00537
00538 return mod->alias.meshes[*mesh].skins[*skin].skin;
00539 }
00540
00554 void R_FillArrayData (mAliasModel_t* mod, mAliasMesh_t *mesh, float backlerp, int framenum, int oldframenum, qboolean prerender)
00555 {
00556 const mAliasFrame_t *frame, *oldframe;
00557 vec3_t move;
00558 const float frontlerp = 1.0 - backlerp;
00559 vec3_t r_mesh_verts[MAX_ALIAS_VERTS];
00560 vec_t *texcoord_array, *vertex_array_3d;
00561
00562 frame = mod->frames + framenum;
00563 oldframe = mod->frames + oldframenum;
00564
00565
00566 if (r_state.lighting_enabled) {
00567
00568 if (mod->curFrame != framenum) {
00569
00570
00571
00572 if (mod->curFrame == oldframenum) {
00573 vec_t *tmp1 = mesh->verts;
00574 vec_t *tmp2 = mesh->normals;
00575 vec_t *tmp3 = mesh->tangents;
00576
00577 mesh->verts = mesh->next_verts;
00578 mesh->next_verts = tmp1;
00579
00580 mesh->normals = mesh->next_normals;
00581 mesh->next_normals = tmp2;
00582
00583 mesh->tangents = mesh->next_tangents;
00584 mesh->next_tangents = tmp3;
00585
00586
00587
00588 if (mod->oldFrame != framenum)
00589 R_ModCalcNormalsAndTangents(mesh, framenum, frame->translate, qfalse);
00590 } else {
00591
00592
00593 R_ModCalcNormalsAndTangents(mesh, oldframenum, oldframe->translate, qtrue);
00594 R_ModCalcNormalsAndTangents(mesh, framenum, frame->translate, qfalse);
00595 }
00596
00597 mod->oldFrame = oldframenum;
00598 mod->curFrame = framenum;
00599 }
00600 } else {
00601 const mAliasVertex_t *v, *ov;
00602 int i;
00603 assert(mesh->num_verts < lengthof(r_mesh_verts));
00604 v = &mesh->vertexes[framenum * mesh->num_verts];
00605 ov = &mesh->vertexes[oldframenum * mesh->num_verts];
00606
00607 if (prerender)
00608 R_ModCalcNormalsAndTangents(mesh, 0, oldframe->translate, qtrue);
00609
00610 for (i = 0; i < 3; i++)
00611 move[i] = backlerp * oldframe->translate[i] + frontlerp * frame->translate[i];
00612
00613 for (i = 0; i < mesh->num_verts; i++, v++, ov++) {
00614 VectorSet(r_mesh_verts[i],
00615 move[0] + ov->point[0] * backlerp + v->point[0] * frontlerp,
00616 move[1] + ov->point[1] * backlerp + v->point[1] * frontlerp,
00617 move[2] + ov->point[2] * backlerp + v->point[2] * frontlerp);
00618 }
00619
00620 texcoord_array = texunit_diffuse.texcoord_array;
00621 vertex_array_3d = r_state.vertex_array_3d;
00622
00624 for (i = 0; i < mesh->num_tris; i++) {
00625 int j;
00626 for (j = 0; j < 3; j++) {
00627 const int arrayIndex = 3 * i + j;
00628 const int meshIndex = mesh->indexes[arrayIndex];
00629 Vector2Copy(mesh->stcoords[meshIndex], texcoord_array);
00630 VectorCopy(r_mesh_verts[meshIndex], vertex_array_3d);
00631
00632 texcoord_array += 2;
00633 vertex_array_3d += 3;
00634 }
00635 }
00636 }
00637 }
00638
00642 void R_ModLoadArrayData (mAliasModel_t *mod, mAliasMesh_t *mesh, qboolean loadNormals)
00643 {
00644 const int v = mesh->num_tris * 3 * 3;
00645 const int t = mesh->num_tris * 3 * 4;
00646 const int st = mesh->num_tris * 3 * 2;
00647
00648 assert(mesh->verts == NULL);
00649 assert(mesh->texcoords == NULL);
00650 assert(mesh->normals == NULL);
00651 assert(mesh->tangents == NULL);
00652 assert(mesh->next_verts == NULL);
00653 assert(mesh->next_normals == NULL);
00654 assert(mesh->next_tangents == NULL);
00655
00656 mesh->verts = (float *)Mem_PoolAlloc(sizeof(float) * v, vid_modelPool, 0);
00657 mesh->normals = (float *)Mem_PoolAlloc(sizeof(float) * v, vid_modelPool, 0);
00658 mesh->tangents = (float *)Mem_PoolAlloc(sizeof(float) * t, vid_modelPool, 0);
00659 mesh->texcoords = (float *)Mem_PoolAlloc(sizeof(float) * st, vid_modelPool, 0);
00660 if (mod->num_frames == 1) {
00661 R_FillArrayData(mod, mesh, 0.0, 0, 0, loadNormals);
00662 } else {
00663 mesh->next_verts = (float *)Mem_PoolAlloc(sizeof(float) * v, vid_modelPool, 0);
00664 mesh->next_normals = (float *)Mem_PoolAlloc(sizeof(float) * v, vid_modelPool, 0);
00665 mesh->next_tangents = (float *)Mem_PoolAlloc(sizeof(float) * t, vid_modelPool, 0);
00666
00667 mod->curFrame = -1;
00668 mod->oldFrame = -1;
00669 }
00670 }