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