1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4
5 This file is part of Quake III Arena source code.
6
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
21 */
22 // tr_models.c -- model loading and caching
23
24 #include "tr_local.h"
25
26 #define LL(x) x=LittleLong(x)
27
28 static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *name );
29 static qboolean R_LoadMD4 (model_t *mod, void *buffer, const char *name );
30 #ifdef RAVENMD4
31 static qboolean R_LoadMDR (model_t *mod, void *buffer, int filesize, const char *name );
32 #endif
33
34 model_t *loadmodel;
35
36 /*
37 ** R_GetModelByHandle
38 */
R_GetModelByHandle(qhandle_t index)39 model_t *R_GetModelByHandle( qhandle_t index ) {
40 model_t *mod;
41
42 // out of range gets the defualt model
43 if ( index < 1 || index >= tr.numModels ) {
44 return tr.models[0];
45 }
46
47 mod = tr.models[index];
48
49 return mod;
50 }
51
52 //===============================================================================
53
54 /*
55 ** R_AllocModel
56 */
R_AllocModel(void)57 model_t *R_AllocModel( void ) {
58 model_t *mod;
59
60 if ( tr.numModels == MAX_MOD_KNOWN ) {
61 return NULL;
62 }
63
64 mod = ri.Hunk_Alloc( sizeof( *tr.models[tr.numModels] ), h_low );
65 mod->index = tr.numModels;
66 tr.models[tr.numModels] = mod;
67 tr.numModels++;
68
69 return mod;
70 }
71
72 /*
73 ====================
74 RE_RegisterModel
75
76 Loads in a model for the given name
77
78 Zero will be returned if the model fails to load.
79 An entry will be retained for failed models as an
80 optimization to prevent disk rescanning if they are
81 asked for again.
82 ====================
83 */
RE_RegisterModel(const char * name)84 qhandle_t RE_RegisterModel( const char *name ) {
85 model_t *mod;
86 union {
87 unsigned *u;
88 void *v;
89 } buf;
90 int lod;
91 int ident;
92 qboolean loaded = qfalse;
93 qhandle_t hModel;
94 int numLoaded;
95 char *fext, defex[] = "md3", filename[MAX_QPATH], namebuf[MAX_QPATH+20];
96
97 if ( !name || !name[0] ) {
98 ri.Printf( PRINT_ALL, "RE_RegisterModel: NULL name\n" );
99 return 0;
100 }
101
102 if ( strlen( name ) >= MAX_QPATH ) {
103 Com_Printf( "Model name exceeds MAX_QPATH\n" );
104 return 0;
105 }
106
107 //
108 // search the currently loaded models
109 //
110 for ( hModel = 1 ; hModel < tr.numModels; hModel++ ) {
111 mod = tr.models[hModel];
112 if ( !strcmp( mod->name, name ) ) {
113 if( mod->type == MOD_BAD ) {
114 return 0;
115 }
116 return hModel;
117 }
118 }
119
120 // allocate a new model_t
121
122 if ( ( mod = R_AllocModel() ) == NULL ) {
123 ri.Printf( PRINT_WARNING, "RE_RegisterModel: R_AllocModel() failed for '%s'\n", name);
124 return 0;
125 }
126
127 // only set the name after the model has been successfully loaded
128 Q_strncpyz( mod->name, name, sizeof( mod->name ) );
129
130
131 // make sure the render thread is stopped
132 R_SyncRenderThread();
133
134 mod->numLods = 0;
135
136 //
137 // load the files
138 //
139 numLoaded = 0;
140
141 strcpy(filename, name);
142
143 fext = strchr(filename, '.');
144 if(!fext)
145 fext = defex;
146 else
147 {
148 *fext = '\0';
149 fext++;
150 }
151
152 #ifdef RAVENMD4
153 if(!Q_stricmp(fext, "mdr"))
154 {
155 int filesize;
156
157 filesize = ri.FS_ReadFile(name, (void **) &buf.v);
158 if(!buf.u)
159 {
160 ri.Printf (PRINT_WARNING,"RE_RegisterModel: couldn't load %s\n", name);
161 mod->type = MOD_BAD;
162 return 0;
163 }
164
165 ident = LittleLong(*(unsigned *)buf.u);
166 if(ident == MDR_IDENT)
167 loaded = R_LoadMDR(mod, buf.u, filesize, name);
168
169 ri.FS_FreeFile (buf.v);
170
171 if(!loaded)
172 {
173 ri.Printf(PRINT_WARNING,"RE_RegisterModel: couldn't load mdr file %s\n", name);
174 mod->type = MOD_BAD;
175 return 0;
176 }
177
178 return mod->index;
179 }
180 #endif
181
182 fext = defex;
183
184 for ( lod = MD3_MAX_LODS - 1 ; lod >= 0 ; lod-- ) {
185 if ( lod )
186 Com_sprintf(namebuf, sizeof(namebuf), "%s_%d.%s", filename, lod, fext);
187 else
188 Com_sprintf(namebuf, sizeof(namebuf), "%s.%s", filename, fext);
189
190 ri.FS_ReadFile( namebuf, &buf.v );
191 if ( !buf.u ) {
192 continue;
193 }
194
195 loadmodel = mod;
196
197 ident = LittleLong(*(unsigned *)buf.u);
198 if ( ident == MD4_IDENT ) {
199 loaded = R_LoadMD4( mod, buf.u, name );
200
201 } else {
202 if ( ident != MD3_IDENT ) {
203 ri.Printf (PRINT_WARNING,"RE_RegisterModel: unknown fileid for %s\n", name);
204 goto fail;
205 }
206
207 loaded = R_LoadMD3( mod, lod, buf.u, name );
208 }
209
210 ri.FS_FreeFile (buf.v);
211
212 if ( !loaded ) {
213 if ( lod == 0 ) {
214 goto fail;
215 } else {
216 break;
217 }
218 } else {
219 mod->numLods++;
220 numLoaded++;
221 // if we have a valid model and are biased
222 // so that we won't see any higher detail ones,
223 // stop loading them
224 // if ( lod <= r_lodbias->integer ) {
225 // break;
226 // }
227 }
228 }
229
230 if ( numLoaded ) {
231 // duplicate into higher lod spots that weren't
232 // loaded, in case the user changes r_lodbias on the fly
233 for ( lod-- ; lod >= 0 ; lod-- ) {
234 mod->numLods++;
235 mod->md3[lod] = mod->md3[lod+1];
236 }
237
238 return mod->index;
239 }
240 #ifdef _DEBUG
241 else {
242 ri.Printf (PRINT_WARNING,"RE_RegisterModel: couldn't load %s\n", name);
243 }
244 #endif
245
246 fail:
247 // we still keep the model_t around, so if the model name is asked for
248 // again, we won't bother scanning the filesystem
249 mod->type = MOD_BAD;
250 return 0;
251 }
252
253
254 /*
255 =================
256 R_LoadMD3
257 =================
258 */
R_LoadMD3(model_t * mod,int lod,void * buffer,const char * mod_name)259 static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *mod_name ) {
260 int i, j;
261 md3Header_t *pinmodel;
262 md3Frame_t *frame;
263 md3Surface_t *surf;
264 md3Shader_t *shader;
265 md3Triangle_t *tri;
266 md3St_t *st;
267 md3XyzNormal_t *xyz;
268 md3Tag_t *tag;
269 int version;
270 int size;
271
272 pinmodel = (md3Header_t *)buffer;
273
274 version = LittleLong (pinmodel->version);
275 if (version != MD3_VERSION) {
276 ri.Printf( PRINT_WARNING, "R_LoadMD3: %s has wrong version (%i should be %i)\n",
277 mod_name, version, MD3_VERSION);
278 return qfalse;
279 }
280
281 mod->type = MOD_MESH;
282 size = LittleLong(pinmodel->ofsEnd);
283 mod->dataSize += size;
284 mod->md3[lod] = ri.Hunk_Alloc( size, h_low );
285
286 Com_Memcpy (mod->md3[lod], buffer, LittleLong(pinmodel->ofsEnd) );
287
288 LL(mod->md3[lod]->ident);
289 LL(mod->md3[lod]->version);
290 LL(mod->md3[lod]->numFrames);
291 LL(mod->md3[lod]->numTags);
292 LL(mod->md3[lod]->numSurfaces);
293 LL(mod->md3[lod]->ofsFrames);
294 LL(mod->md3[lod]->ofsTags);
295 LL(mod->md3[lod]->ofsSurfaces);
296 LL(mod->md3[lod]->ofsEnd);
297
298 if ( mod->md3[lod]->numFrames < 1 ) {
299 ri.Printf( PRINT_WARNING, "R_LoadMD3: %s has no frames\n", mod_name );
300 return qfalse;
301 }
302
303 // swap all the frames
304 frame = (md3Frame_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsFrames );
305 for ( i = 0 ; i < mod->md3[lod]->numFrames ; i++, frame++) {
306 frame->radius = LittleFloat( frame->radius );
307 for ( j = 0 ; j < 3 ; j++ ) {
308 frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
309 frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
310 frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
311 }
312 }
313
314 // swap all the tags
315 tag = (md3Tag_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsTags );
316 for ( i = 0 ; i < mod->md3[lod]->numTags * mod->md3[lod]->numFrames ; i++, tag++) {
317 for ( j = 0 ; j < 3 ; j++ ) {
318 tag->origin[j] = LittleFloat( tag->origin[j] );
319 tag->axis[0][j] = LittleFloat( tag->axis[0][j] );
320 tag->axis[1][j] = LittleFloat( tag->axis[1][j] );
321 tag->axis[2][j] = LittleFloat( tag->axis[2][j] );
322 }
323 }
324
325 // swap all the surfaces
326 surf = (md3Surface_t *) ( (byte *)mod->md3[lod] + mod->md3[lod]->ofsSurfaces );
327 for ( i = 0 ; i < mod->md3[lod]->numSurfaces ; i++) {
328
329 LL(surf->ident);
330 LL(surf->flags);
331 LL(surf->numFrames);
332 LL(surf->numShaders);
333 LL(surf->numTriangles);
334 LL(surf->ofsTriangles);
335 LL(surf->numVerts);
336 LL(surf->ofsShaders);
337 LL(surf->ofsSt);
338 LL(surf->ofsXyzNormals);
339 LL(surf->ofsEnd);
340
341 if ( surf->numVerts > SHADER_MAX_VERTEXES ) {
342 ri.Error (ERR_DROP, "R_LoadMD3: %s has more than %i verts on a surface (%i)",
343 mod_name, SHADER_MAX_VERTEXES, surf->numVerts );
344 }
345 if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) {
346 ri.Error (ERR_DROP, "R_LoadMD3: %s has more than %i triangles on a surface (%i)",
347 mod_name, SHADER_MAX_INDEXES / 3, surf->numTriangles );
348 }
349
350 // change to surface identifier
351 surf->ident = SF_MD3;
352
353 // lowercase the surface name so skin compares are faster
354 Q_strlwr( surf->name );
355
356 // strip off a trailing _1 or _2
357 // this is a crutch for q3data being a mess
358 j = strlen( surf->name );
359 if ( j > 2 && surf->name[j-2] == '_' ) {
360 surf->name[j-2] = 0;
361 }
362
363 // register the shaders
364 shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
365 for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
366 shader_t *sh;
367
368 sh = R_FindShader( shader->name, LIGHTMAP_NONE, qtrue );
369 if ( sh->defaultShader ) {
370 shader->shaderIndex = 0;
371 } else {
372 shader->shaderIndex = sh->index;
373 }
374 }
375
376 // swap all the triangles
377 tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
378 for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
379 LL(tri->indexes[0]);
380 LL(tri->indexes[1]);
381 LL(tri->indexes[2]);
382 }
383
384 // swap all the ST
385 st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
386 for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
387 st->st[0] = LittleFloat( st->st[0] );
388 st->st[1] = LittleFloat( st->st[1] );
389 }
390
391 // swap all the XyzNormals
392 xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
393 for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ )
394 {
395 xyz->xyz[0] = LittleShort( xyz->xyz[0] );
396 xyz->xyz[1] = LittleShort( xyz->xyz[1] );
397 xyz->xyz[2] = LittleShort( xyz->xyz[2] );
398
399 xyz->normal = LittleShort( xyz->normal );
400 }
401
402
403 // find the next surface
404 surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
405 }
406
407 return qtrue;
408 }
409
410
411 #ifdef RAVENMD4
412
413 /*
414 =================
415 R_LoadMDR
416 =================
417 */
R_LoadMDR(model_t * mod,void * buffer,int filesize,const char * mod_name)418 static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char *mod_name )
419 {
420 int i, j, k, l;
421 mdrHeader_t *pinmodel, *mdr;
422 mdrFrame_t *frame;
423 mdrLOD_t *lod, *curlod;
424 mdrSurface_t *surf, *cursurf;
425 mdrTriangle_t *tri, *curtri;
426 mdrVertex_t *v, *curv;
427 mdrWeight_t *weight, *curweight;
428 mdrTag_t *tag, *curtag;
429 int size;
430 shader_t *sh;
431
432 pinmodel = (mdrHeader_t *)buffer;
433
434 pinmodel->version = LittleLong(pinmodel->version);
435 if (pinmodel->version != MDR_VERSION)
436 {
437 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has wrong version (%i should be %i)\n", mod_name, pinmodel->version, MDR_VERSION);
438 return qfalse;
439 }
440
441 size = LittleLong(pinmodel->ofsEnd);
442
443 if(size > filesize)
444 {
445 ri.Printf(PRINT_WARNING, "R_LoadMDR: Header of %s is broken. Wrong filesize declared!\n", mod_name);
446 return qfalse;
447 }
448
449 mod->type = MOD_MDR;
450
451 LL(pinmodel->numFrames);
452 LL(pinmodel->numBones);
453 LL(pinmodel->ofsFrames);
454
455 // This is a model that uses some type of compressed Bones. We don't want to uncompress every bone for each rendered frame
456 // over and over again, we'll uncompress it in this function already, so we must adjust the size of the target md4.
457 if(pinmodel->ofsFrames < 0)
458 {
459 // mdrFrame_t is larger than mdrCompFrame_t:
460 size += pinmodel->numFrames * sizeof(frame->name);
461 // now add enough space for the uncompressed bones.
462 size += pinmodel->numFrames * pinmodel->numBones * ((sizeof(mdrBone_t) - sizeof(mdrCompBone_t)));
463 }
464
465 // simple bounds check
466 if(pinmodel->numBones < 0 ||
467 sizeof(*mdr) + pinmodel->numFrames * (sizeof(*frame) + (pinmodel->numBones - 1) * sizeof(*frame->bones)) > size)
468 {
469 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
470 return qfalse;
471 }
472
473 mod->dataSize += size;
474 mod->md4 = mdr = ri.Hunk_Alloc( size, h_low );
475
476 // Copy all the values over from the file and fix endian issues in the process, if necessary.
477
478 mdr->ident = LittleLong(pinmodel->ident);
479 mdr->version = pinmodel->version; // Don't need to swap byte order on this one, we already did above.
480 Q_strncpyz(mdr->name, pinmodel->name, sizeof(mdr->name));
481 mdr->numFrames = pinmodel->numFrames;
482 mdr->numBones = pinmodel->numBones;
483 mdr->numLODs = LittleLong(pinmodel->numLODs);
484 mdr->numTags = LittleLong(pinmodel->numTags);
485 // We don't care about the other offset values, we'll generate them ourselves while loading.
486
487 mod->numLods = mdr->numLODs;
488
489 if ( mdr->numFrames < 1 )
490 {
491 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has no frames\n", mod_name);
492 return qfalse;
493 }
494
495 /* The first frame will be put into the first free space after the header */
496 frame = (mdrFrame_t *)(mdr + 1);
497 mdr->ofsFrames = (int)((byte *) frame - (byte *) mdr);
498
499 if (pinmodel->ofsFrames < 0)
500 {
501 mdrCompFrame_t *cframe;
502
503 // compressed model...
504 cframe = (mdrCompFrame_t *)((byte *) pinmodel - pinmodel->ofsFrames);
505
506 for(i = 0; i < mdr->numFrames; i++)
507 {
508 for(j = 0; j < 3; j++)
509 {
510 frame->bounds[0][j] = LittleFloat(cframe->bounds[0][j]);
511 frame->bounds[1][j] = LittleFloat(cframe->bounds[1][j]);
512 frame->localOrigin[j] = LittleFloat(cframe->localOrigin[j]);
513 }
514
515 frame->radius = LittleFloat(cframe->radius);
516 frame->name[0] = '\0'; // No name supplied in the compressed version.
517
518 for(j = 0; j < mdr->numBones; j++)
519 {
520 for(k = 0; k < (sizeof(cframe->bones[j].Comp) / 2); k++)
521 {
522 // Do swapping for the uncompressing functions. They seem to use shorts
523 // values only, so I assume this will work. Never tested it on other
524 // platforms, though.
525
526 ((unsigned short *)(cframe->bones[j].Comp))[k] =
527 LittleShort( ((unsigned short *)(cframe->bones[j].Comp))[k] );
528 }
529
530 /* Now do the actual uncompressing */
531 MC_UnCompress(frame->bones[j].matrix, cframe->bones[j].Comp);
532 }
533
534 // Next Frame...
535 cframe = (mdrCompFrame_t *) &cframe->bones[j];
536 frame = (mdrFrame_t *) &frame->bones[j];
537 }
538 }
539 else
540 {
541 mdrFrame_t *curframe;
542
543 // uncompressed model...
544 //
545
546 curframe = (mdrFrame_t *)((byte *) pinmodel + pinmodel->ofsFrames);
547
548 // swap all the frames
549 for ( i = 0 ; i < mdr->numFrames ; i++)
550 {
551 for(j = 0; j < 3; j++)
552 {
553 frame->bounds[0][j] = LittleFloat(curframe->bounds[0][j]);
554 frame->bounds[1][j] = LittleFloat(curframe->bounds[1][j]);
555 frame->localOrigin[j] = LittleFloat(curframe->localOrigin[j]);
556 }
557
558 frame->radius = LittleFloat(curframe->radius);
559 Q_strncpyz(frame->name, curframe->name, sizeof(frame->name));
560
561 for (j = 0; j < (int) (mdr->numBones * sizeof(mdrBone_t) / 4); j++)
562 {
563 ((float *)frame->bones)[j] = LittleFloat( ((float *)curframe->bones)[j] );
564 }
565
566 curframe = (mdrFrame_t *) &curframe->bones[mdr->numBones];
567 frame = (mdrFrame_t *) &frame->bones[mdr->numBones];
568 }
569 }
570
571 // frame should now point to the first free address after all frames.
572 lod = (mdrLOD_t *) frame;
573 mdr->ofsLODs = (int) ((byte *) lod - (byte *)mdr);
574
575 curlod = (mdrLOD_t *)((byte *) pinmodel + LittleLong(pinmodel->ofsLODs));
576
577 // swap all the LOD's
578 for ( l = 0 ; l < mdr->numLODs ; l++)
579 {
580 // simple bounds check
581 if((byte *) (lod + 1) > (byte *) mdr + size)
582 {
583 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
584 return qfalse;
585 }
586
587 lod->numSurfaces = LittleLong(curlod->numSurfaces);
588
589 // swap all the surfaces
590 surf = (mdrSurface_t *) (lod + 1);
591 lod->ofsSurfaces = (int)((byte *) surf - (byte *) lod);
592 cursurf = (mdrSurface_t *) ((byte *)curlod + LittleLong(curlod->ofsSurfaces));
593
594 for ( i = 0 ; i < lod->numSurfaces ; i++)
595 {
596 // simple bounds check
597 if((byte *) (surf + 1) > (byte *) mdr + size)
598 {
599 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
600 return qfalse;
601 }
602
603 // first do some copying stuff
604
605 surf->ident = SF_MDR;
606 Q_strncpyz(surf->name, cursurf->name, sizeof(surf->name));
607 Q_strncpyz(surf->shader, cursurf->shader, sizeof(surf->shader));
608
609 surf->ofsHeader = (byte *) mdr - (byte *) surf;
610
611 surf->numVerts = LittleLong(cursurf->numVerts);
612 surf->numTriangles = LittleLong(cursurf->numTriangles);
613 // numBoneReferences and BoneReferences generally seem to be unused
614
615 // now do the checks that may fail.
616 if ( surf->numVerts > SHADER_MAX_VERTEXES )
617 {
618 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has more than %i verts on a surface (%i)",
619 mod_name, SHADER_MAX_VERTEXES, surf->numVerts );
620 return qfalse;
621 }
622 if ( surf->numTriangles*3 > SHADER_MAX_INDEXES )
623 {
624 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has more than %i triangles on a surface (%i)",
625 mod_name, SHADER_MAX_INDEXES / 3, surf->numTriangles );
626 return qfalse;
627 }
628 // lowercase the surface name so skin compares are faster
629 Q_strlwr( surf->name );
630
631 // register the shaders
632 sh = R_FindShader(surf->shader, LIGHTMAP_NONE, qtrue);
633 if ( sh->defaultShader ) {
634 surf->shaderIndex = 0;
635 } else {
636 surf->shaderIndex = sh->index;
637 }
638
639 // now copy the vertexes.
640 v = (mdrVertex_t *) (surf + 1);
641 surf->ofsVerts = (int)((byte *) v - (byte *) surf);
642 curv = (mdrVertex_t *) ((byte *)cursurf + LittleLong(cursurf->ofsVerts));
643
644 for(j = 0; j < surf->numVerts; j++)
645 {
646 LL(curv->numWeights);
647
648 // simple bounds check
649 if(curv->numWeights < 0 || (byte *) (v + 1) + (curv->numWeights - 1) * sizeof(*weight) > (byte *) mdr + size)
650 {
651 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
652 return qfalse;
653 }
654
655 v->normal[0] = LittleFloat(curv->normal[0]);
656 v->normal[1] = LittleFloat(curv->normal[1]);
657 v->normal[2] = LittleFloat(curv->normal[2]);
658
659 v->texCoords[0] = LittleFloat(curv->texCoords[0]);
660 v->texCoords[1] = LittleFloat(curv->texCoords[1]);
661
662 v->numWeights = curv->numWeights;
663 weight = &v->weights[0];
664 curweight = &curv->weights[0];
665
666 // Now copy all the weights
667 for(k = 0; k < v->numWeights; k++)
668 {
669 weight->boneIndex = LittleLong(curweight->boneIndex);
670 weight->boneWeight = LittleFloat(curweight->boneWeight);
671
672 weight->offset[0] = LittleFloat(curweight->offset[0]);
673 weight->offset[1] = LittleFloat(curweight->offset[1]);
674 weight->offset[2] = LittleFloat(curweight->offset[2]);
675
676 weight++;
677 curweight++;
678 }
679
680 v = (mdrVertex_t *) weight;
681 curv = (mdrVertex_t *) curweight;
682 }
683
684 // we know the offset to the triangles now:
685 tri = (mdrTriangle_t *) v;
686 surf->ofsTriangles = (int)((byte *) tri - (byte *) surf);
687 curtri = (mdrTriangle_t *)((byte *) cursurf + LittleLong(cursurf->ofsTriangles));
688
689 // simple bounds check
690 if(surf->numTriangles < 0 || (byte *) (tri + surf->numTriangles) > (byte *) mdr + size)
691 {
692 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
693 return qfalse;
694 }
695
696 for(j = 0; j < surf->numTriangles; j++)
697 {
698 tri->indexes[0] = LittleLong(curtri->indexes[0]);
699 tri->indexes[1] = LittleLong(curtri->indexes[1]);
700 tri->indexes[2] = LittleLong(curtri->indexes[2]);
701
702 tri++;
703 curtri++;
704 }
705
706 // tri now points to the end of the surface.
707 surf->ofsEnd = (byte *) tri - (byte *) surf;
708 surf = (mdrSurface_t *) tri;
709
710 // find the next surface.
711 cursurf = (mdrSurface_t *) ((byte *) cursurf + LittleLong(cursurf->ofsEnd));
712 }
713
714 // surf points to the next lod now.
715 lod->ofsEnd = (int)((byte *) surf - (byte *) lod);
716 lod = (mdrLOD_t *) surf;
717
718 // find the next LOD.
719 curlod = (mdrLOD_t *)((byte *) curlod + LittleLong(curlod->ofsEnd));
720 }
721
722 // lod points to the first tag now, so update the offset too.
723 tag = (mdrTag_t *) lod;
724 mdr->ofsTags = (int)((byte *) tag - (byte *) mdr);
725 curtag = (mdrTag_t *) ((byte *)pinmodel + LittleLong(pinmodel->ofsTags));
726
727 // simple bounds check
728 if(mdr->numTags < 0 || (byte *) (tag + mdr->numTags) > (byte *) mdr + size)
729 {
730 ri.Printf(PRINT_WARNING, "R_LoadMDR: %s has broken structure.\n", mod_name);
731 return qfalse;
732 }
733
734 for (i = 0 ; i < mdr->numTags ; i++)
735 {
736 tag->boneIndex = LittleLong(curtag->boneIndex);
737 Q_strncpyz(tag->name, curtag->name, sizeof(tag->name));
738
739 tag++;
740 curtag++;
741 }
742
743 // And finally we know the real offset to the end.
744 mdr->ofsEnd = (int)((byte *) tag - (byte *) mdr);
745
746 // phew! we're done.
747
748 return qtrue;
749 }
750 #endif
751
752 /*
753 =================
754 R_LoadMD4
755 =================
756 */
757
R_LoadMD4(model_t * mod,void * buffer,const char * mod_name)758 static qboolean R_LoadMD4( model_t *mod, void *buffer, const char *mod_name ) {
759 int i, j, k, lodindex;
760 md4Header_t *pinmodel, *md4;
761 md4Frame_t *frame;
762 md4LOD_t *lod;
763 md4Surface_t *surf;
764 md4Triangle_t *tri;
765 md4Vertex_t *v;
766 int version;
767 int size;
768 shader_t *sh;
769 int frameSize;
770
771 pinmodel = (md4Header_t *)buffer;
772
773 version = LittleLong (pinmodel->version);
774 if (version != MD4_VERSION) {
775 ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has wrong version (%i should be %i)\n",
776 mod_name, version, MD4_VERSION);
777 return qfalse;
778 }
779
780 mod->type = MOD_MD4;
781 size = LittleLong(pinmodel->ofsEnd);
782 mod->dataSize += size;
783 md4 = mod->md4 = ri.Hunk_Alloc( size, h_low );
784
785 Com_Memcpy(md4, buffer, size);
786
787 LL(md4->ident);
788 LL(md4->version);
789 LL(md4->numFrames);
790 LL(md4->numBones);
791 LL(md4->numLODs);
792 LL(md4->ofsFrames);
793 LL(md4->ofsLODs);
794 md4->ofsEnd = size;
795
796 if ( md4->numFrames < 1 ) {
797 ri.Printf( PRINT_WARNING, "R_LoadMD4: %s has no frames\n", mod_name );
798 return qfalse;
799 }
800
801 // we don't need to swap tags in the renderer, they aren't used
802
803 // swap all the frames
804 frameSize = (size_t)( &((md4Frame_t *)0)->bones[ md4->numBones ] );
805 for ( i = 0 ; i < md4->numFrames ; i++, frame++) {
806 frame = (md4Frame_t *) ( (byte *)md4 + md4->ofsFrames + i * frameSize );
807 frame->radius = LittleFloat( frame->radius );
808 for ( j = 0 ; j < 3 ; j++ ) {
809 frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
810 frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
811 frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
812 }
813 for ( j = 0 ; j < md4->numBones * sizeof( md4Bone_t ) / 4 ; j++ ) {
814 ((float *)frame->bones)[j] = LittleFloat( ((float *)frame->bones)[j] );
815 }
816 }
817
818 // swap all the LOD's
819 lod = (md4LOD_t *) ( (byte *)md4 + md4->ofsLODs );
820 for ( lodindex = 0 ; lodindex < md4->numLODs ; lodindex++ ) {
821
822 // swap all the surfaces
823 surf = (md4Surface_t *) ( (byte *)lod + lod->ofsSurfaces );
824 for ( i = 0 ; i < lod->numSurfaces ; i++) {
825 LL(surf->ident);
826 LL(surf->numTriangles);
827 LL(surf->ofsTriangles);
828 LL(surf->numVerts);
829 LL(surf->ofsVerts);
830 LL(surf->ofsEnd);
831
832 if ( surf->numVerts > SHADER_MAX_VERTEXES ) {
833 ri.Error (ERR_DROP, "R_LoadMD3: %s has more than %i verts on a surface (%i)",
834 mod_name, SHADER_MAX_VERTEXES, surf->numVerts );
835 }
836 if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) {
837 ri.Error (ERR_DROP, "R_LoadMD3: %s has more than %i triangles on a surface (%i)",
838 mod_name, SHADER_MAX_INDEXES / 3, surf->numTriangles );
839 }
840
841 // change to surface identifier
842 surf->ident = SF_MD4;
843
844 // lowercase the surface name so skin compares are faster
845 Q_strlwr( surf->name );
846
847 // register the shaders
848 sh = R_FindShader( surf->shader, LIGHTMAP_NONE, qtrue );
849 if ( sh->defaultShader ) {
850 surf->shaderIndex = 0;
851 } else {
852 surf->shaderIndex = sh->index;
853 }
854
855 // swap all the triangles
856 tri = (md4Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
857 for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
858 LL(tri->indexes[0]);
859 LL(tri->indexes[1]);
860 LL(tri->indexes[2]);
861 }
862
863 // swap all the vertexes
864 // FIXME
865 // This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
866 // in for reference.
867 //v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts + 12);
868 v = (md4Vertex_t *) ( (byte *)surf + surf->ofsVerts);
869 for ( j = 0 ; j < surf->numVerts ; j++ ) {
870 v->normal[0] = LittleFloat( v->normal[0] );
871 v->normal[1] = LittleFloat( v->normal[1] );
872 v->normal[2] = LittleFloat( v->normal[2] );
873
874 v->texCoords[0] = LittleFloat( v->texCoords[0] );
875 v->texCoords[1] = LittleFloat( v->texCoords[1] );
876
877 v->numWeights = LittleLong( v->numWeights );
878
879 for ( k = 0 ; k < v->numWeights ; k++ ) {
880 v->weights[k].boneIndex = LittleLong( v->weights[k].boneIndex );
881 v->weights[k].boneWeight = LittleFloat( v->weights[k].boneWeight );
882 v->weights[k].offset[0] = LittleFloat( v->weights[k].offset[0] );
883 v->weights[k].offset[1] = LittleFloat( v->weights[k].offset[1] );
884 v->weights[k].offset[2] = LittleFloat( v->weights[k].offset[2] );
885 }
886 // FIXME
887 // This makes TFC's skeletons work. Shouldn't be necessary anymore, but left
888 // in for reference.
889 //v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights] + 12 );
890 v = (md4Vertex_t *)( ( byte * )&v->weights[v->numWeights]);
891 }
892
893 // find the next surface
894 surf = (md4Surface_t *)( (byte *)surf + surf->ofsEnd );
895 }
896
897 // find the next LOD
898 lod = (md4LOD_t *)( (byte *)lod + lod->ofsEnd );
899 }
900
901 return qtrue;
902 }
903
904
905
906 //=============================================================================
907
908 /*
909 ** RE_BeginRegistration
910 */
RE_BeginRegistration(glconfig_t * glconfigOut)911 void RE_BeginRegistration( glconfig_t *glconfigOut ) {
912
913 R_Init();
914
915 *glconfigOut = glConfig;
916
917 R_SyncRenderThread();
918
919 tr.viewCluster = -1; // force markleafs to regenerate
920 R_ClearFlares();
921 RE_ClearScene();
922
923 tr.registered = qtrue;
924
925 // NOTE: this sucks, for some reason the first stretch pic is never drawn
926 // without this we'd see a white flash on a level load because the very
927 // first time the level shot would not be drawn
928 // RE_StretchPic(0, 0, 0, 0, 0, 0, 1, 1, 0);
929 }
930
931 //=============================================================================
932
933 /*
934 ===============
935 R_ModelInit
936 ===============
937 */
R_ModelInit(void)938 void R_ModelInit( void ) {
939 model_t *mod;
940
941 // leave a space for NULL model
942 tr.numModels = 0;
943
944 mod = R_AllocModel();
945 mod->type = MOD_BAD;
946 }
947
948
949 /*
950 ================
951 R_Modellist_f
952 ================
953 */
R_Modellist_f(void)954 void R_Modellist_f( void ) {
955 int i, j;
956 model_t *mod;
957 int total;
958 int lods;
959
960 total = 0;
961 for ( i = 1 ; i < tr.numModels; i++ ) {
962 mod = tr.models[i];
963 lods = 1;
964 for ( j = 1 ; j < MD3_MAX_LODS ; j++ ) {
965 if ( mod->md3[j] && mod->md3[j] != mod->md3[j-1] ) {
966 lods++;
967 }
968 }
969 ri.Printf( PRINT_ALL, "%8i : (%i) %s\n",mod->dataSize, lods, mod->name );
970 total += mod->dataSize;
971 }
972 ri.Printf( PRINT_ALL, "%8i : Total models\n", total );
973
974 #if 0 // not working right with new hunk
975 if ( tr.world ) {
976 ri.Printf( PRINT_ALL, "\n%8i : %s\n", tr.world->dataSize, tr.world->name );
977 }
978 #endif
979 }
980
981
982 //=============================================================================
983
984
985 /*
986 ================
987 R_GetTag
988 ================
989 */
R_GetTag(md3Header_t * mod,int frame,const char * tagName)990 static md3Tag_t *R_GetTag( md3Header_t *mod, int frame, const char *tagName ) {
991 md3Tag_t *tag;
992 int i;
993
994 if ( frame >= mod->numFrames ) {
995 // it is possible to have a bad frame while changing models, so don't error
996 frame = mod->numFrames - 1;
997 }
998
999 tag = (md3Tag_t *)((byte *)mod + mod->ofsTags) + frame * mod->numTags;
1000 for ( i = 0 ; i < mod->numTags ; i++, tag++ ) {
1001 if ( !strcmp( tag->name, tagName ) ) {
1002 return tag; // found it
1003 }
1004 }
1005
1006 return NULL;
1007 }
1008
1009 #ifdef RAVENMD4
R_GetAnimTag(mdrHeader_t * mod,int framenum,const char * tagName,md3Tag_t * dest)1010 void R_GetAnimTag( mdrHeader_t *mod, int framenum, const char *tagName, md3Tag_t * dest)
1011 {
1012 int i, j, k;
1013 int frameSize;
1014 mdrFrame_t *frame;
1015 mdrTag_t *tag;
1016
1017 if ( framenum >= mod->numFrames )
1018 {
1019 // it is possible to have a bad frame while changing models, so don't error
1020 framenum = mod->numFrames - 1;
1021 }
1022
1023 tag = (mdrTag_t *)((byte *)mod + mod->ofsTags);
1024 for ( i = 0 ; i < mod->numTags ; i++, tag++ )
1025 {
1026 if ( !strcmp( tag->name, tagName ) )
1027 {
1028 Q_strncpyz(dest->name, tag->name, sizeof(dest->name));
1029
1030 // uncompressed model...
1031 //
1032 frameSize = (long)( &((mdrFrame_t *)0)->bones[ mod->numBones ] );
1033 frame = (mdrFrame_t *)((byte *)mod + mod->ofsFrames + framenum * frameSize );
1034
1035 for (j = 0; j < 3; j++)
1036 {
1037 for (k = 0; k < 3; k++)
1038 dest->axis[j][k]=frame->bones[tag->boneIndex].matrix[k][j];
1039 }
1040
1041 dest->origin[0]=frame->bones[tag->boneIndex].matrix[0][3];
1042 dest->origin[1]=frame->bones[tag->boneIndex].matrix[1][3];
1043 dest->origin[2]=frame->bones[tag->boneIndex].matrix[2][3];
1044
1045 return;
1046 }
1047 }
1048
1049 AxisClear( dest->axis );
1050 VectorClear( dest->origin );
1051 strcpy(dest->name,"");
1052 }
1053 #endif
1054
1055 /*
1056 ================
1057 R_LerpTag
1058 ================
1059 */
R_LerpTag(orientation_t * tag,qhandle_t handle,int startFrame,int endFrame,float frac,const char * tagName)1060 int R_LerpTag( orientation_t *tag, qhandle_t handle, int startFrame, int endFrame,
1061 float frac, const char *tagName ) {
1062 md3Tag_t *start, *end;
1063 #ifdef RAVENMD4
1064 md3Tag_t start_space, end_space;
1065 #endif
1066 int i;
1067 float frontLerp, backLerp;
1068 model_t *model;
1069
1070 model = R_GetModelByHandle( handle );
1071 if ( !model->md3[0] )
1072 {
1073 #ifdef RAVENMD4
1074 if(model->md4)
1075 {
1076 start = &start_space;
1077 end = &end_space;
1078 R_GetAnimTag((mdrHeader_t *) model->md4, startFrame, tagName, start);
1079 R_GetAnimTag((mdrHeader_t *) model->md4, endFrame, tagName, end);
1080 }
1081 else
1082 #endif
1083 {
1084
1085 AxisClear( tag->axis );
1086 VectorClear( tag->origin );
1087 return qfalse;
1088
1089 }
1090 }
1091 else
1092 {
1093 start = R_GetTag( model->md3[0], startFrame, tagName );
1094 end = R_GetTag( model->md3[0], endFrame, tagName );
1095 if ( !start || !end ) {
1096 AxisClear( tag->axis );
1097 VectorClear( tag->origin );
1098 return qfalse;
1099 }
1100 }
1101
1102 frontLerp = frac;
1103 backLerp = 1.0f - frac;
1104
1105 for ( i = 0 ; i < 3 ; i++ ) {
1106 tag->origin[i] = start->origin[i] * backLerp + end->origin[i] * frontLerp;
1107 tag->axis[0][i] = start->axis[0][i] * backLerp + end->axis[0][i] * frontLerp;
1108 tag->axis[1][i] = start->axis[1][i] * backLerp + end->axis[1][i] * frontLerp;
1109 tag->axis[2][i] = start->axis[2][i] * backLerp + end->axis[2][i] * frontLerp;
1110 }
1111 VectorNormalize( tag->axis[0] );
1112 VectorNormalize( tag->axis[1] );
1113 VectorNormalize( tag->axis[2] );
1114 return qtrue;
1115 }
1116
1117
1118 /*
1119 ====================
1120 R_ModelBounds
1121 ====================
1122 */
R_ModelBounds(qhandle_t handle,vec3_t mins,vec3_t maxs)1123 void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
1124 model_t *model;
1125 md3Header_t *header;
1126 md3Frame_t *frame;
1127
1128 model = R_GetModelByHandle( handle );
1129
1130 if ( model->bmodel ) {
1131 VectorCopy( model->bmodel->bounds[0], mins );
1132 VectorCopy( model->bmodel->bounds[1], maxs );
1133 return;
1134 }
1135
1136 if ( !model->md3[0] ) {
1137 VectorClear( mins );
1138 VectorClear( maxs );
1139 return;
1140 }
1141
1142 header = model->md3[0];
1143
1144 frame = (md3Frame_t *)( (byte *)header + header->ofsFrames );
1145
1146 VectorCopy( frame->bounds[0], mins );
1147 VectorCopy( frame->bounds[1], maxs );
1148 }
1149
1150