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