1 /*
2 Copyright (C) 2001-2002 Charles Hollemeersch
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 PENTA: the whole file is freakin penta...
20 
21   Md3 support
22 */
23 
24 #include "quakedef.h"
25 
26 #define MD3_VERSION			15
27 #define	MD3_XYZ_SCALE		(1.0/64)
28 
29 //#define MD3DEBUG
30 
31 typedef struct md3Frame_s {
32 	vec3_t		bounds[2];
33 	vec3_t		localOrigin;
34 	float		radius;
35 	char		name[16];
36 } md3Frame_t;
37 
38 typedef struct {
39 	char			name[MAX_QPATH];
40 	int				shaderIndex;
41 } md3Shader_t;
42 
43 typedef struct {
44 	int		ident;				//
45 
46 	char	name[MAX_QPATH];	// polyset name
47 
48 	int		flags;
49 	int		numFrames;			// all surfaces in a model should have the same
50 
51 	int		numShaders;			// all surfaces in a model should have the same
52 	int		numVerts;
53 
54 	int		numTriangles;
55 	int		ofsTriangles;
56 
57 	int		ofsShaders;			// offset from start of md3Surface_t
58 	int		ofsSt;				// texture coords are common for all frames
59 	int		ofsXyzNormals;		// numVerts * numFrames
60 
61 	int		ofsEnd;				// next surface follows
62 } md3Surface_t;
63 
64 typedef struct {
65 	int			ident;
66 	int			version;
67 
68 	char		name[MAX_QPATH];
69 
70 	int			flags;
71 
72 	int			numFrames;
73 	int			numTags;
74 	int			numSurfaces;
75 
76 	int			numSkins;
77 
78 	int			ofsFrames;
79 	int			ofsTags;
80 	int			ofsSurfaces;
81 	int			ofsEnd;
82 } md3Header_t;
83 
84 typedef struct {
85 	short		xyz[3];
86 	unsigned short normal;
87 } md3XyzNormal_t;
88 
89 typedef struct {
90 	int			indexes[3];
91 } md3Triangle_t;
92 
93 typedef struct {
94 	float		s;
95 	float		t;
96 } md3St_t;
97 
98 
99 typedef struct md3tag_s
100 {
101      char		name[MAX_QPATH];	// supported names : weapon
102      vec3_t		origin;			// pretty much self explanatory
103      vec3_t		axis[3];		// no ?
104 
105 } md3tag_t;
106 
107 
findneighbourmd3_old(int index,int edgei,int numtris,mtriangle_t * triangles)108 int findneighbourmd3_old(int index, int edgei, int numtris, mtriangle_t *triangles) {
109 	int i, j;
110 	mtriangle_t *current = &triangles[index];
111 
112 	for (i=0; i<numtris; i++) {
113 		if (i == index) continue;
114 		for (j=0; j<3; j++) {
115 			if (((current->vertindex[edgei] == triangles[i].vertindex[j])
116 			    && (current->vertindex[(edgei+1)%3] == triangles[i].vertindex[(j+1)%3]))
117 				||
118 			   ((current->vertindex[edgei] == triangles[i].vertindex[(j+1)%3])
119 			    && (current->vertindex[(edgei+1)%3] == triangles[i].vertindex[j])))
120 			{
121 				triangles[i].neighbours[j] = index;
122 				return i;
123 			}
124 
125 		}
126 	}
127 	return -1;
128 }
129 /*
130 Yet another hack.  Some models seem to have edges shared between three triangles, this is obviously
131 a strange thing to have, we resolve it simply by throwing away that shared egde and giving all
132 triangles a "-1" neighbour for that edge.  This will give some unneeded fins for some edges of some models
133 but this number is generally verry low (< 3 edges per model) and only on a few models.
134 */
findneighbourmd3(int index,int edgei,int numtris,mtriangle_t * triangles)135 int findneighbourmd3(int index, int edgei, int numtris, mtriangle_t *triangles) {
136 	int i, j, v1, v0, found,foundj = 0;
137 	mtriangle_t *current = &triangles[index];
138 	mtriangle_t *t;
139 	qboolean	dup;
140 
141 	v0 = current->vertindex[edgei];
142 	v1 = current->vertindex[(edgei+1)%3];
143 
144 	//XYZ
145 	found = -1;
146 	dup = false;
147 	for (i=0; i<numtris; i++) {
148 		if (i == index) continue;
149 		t = &triangles[i];
150 
151 		for (j=0; j<3; j++) {
152 			if (((current->vertindex[edgei] == triangles[i].vertindex[j])
153 			    && (current->vertindex[(edgei+1)%3] == triangles[i].vertindex[(j+1)%3]))
154 				||
155 			   ((current->vertindex[edgei] == triangles[i].vertindex[(j+1)%3])
156 			    && (current->vertindex[(edgei+1)%3] == triangles[i].vertindex[j])))
157 			{
158 				//no edge for this model found yet?
159 				if (found == -1) {
160 					found = i;
161 					foundj = j;
162 				}
163 				//the three edges story
164 				else
165 					dup = true;
166 			}
167 
168 		}
169 	}
170 
171 	//normal edge, setup neighbour pointers
172 	if (!dup) {
173 		if (found != -1)
174 			triangles[found].neighbours[foundj] = index;
175 		return found;
176 	}
177 	//naughty egde let no-one have the neighbour
178 	//Con_Printf("%s: warning: open edge added\n",loadname);
179 	return -1;
180 }
181 
TangentForTrimd3(int * index,ftrivertx_t * vertices,fstvert_t * texcos,vec3_t Tangent,vec3_t Binormal)182 void TangentForTrimd3(int *index, ftrivertx_t *vertices, fstvert_t *texcos, vec3_t Tangent, vec3_t Binormal) {
183 //see:
184 //http://members.rogers.com/deseric/tangentspace.htm
185 	vec3_t stvecs [3];
186 	float *v0, *v1, *v2;
187 	float *st0, *st1, *st2;
188 	vec3_t vec1, vec2;
189 	vec3_t planes[3];
190 	int i;
191 
192 	v0 = &vertices[index[0]].v[0];
193 	v1 = &vertices[index[1]].v[0];
194 	v2 = &vertices[index[2]].v[0];
195 	st0 = &texcos[index[0]].s;
196 	st1 = &texcos[index[1]].s;
197 	st2 = &texcos[index[2]].s;
198 
199 	for (i=0; i<3; i++) {
200 		vec1[0] = v1[i]-v0[i];
201 		vec1[1] = st1[0]-st0[0];
202 		vec1[2] = st1[1]-st0[1];
203 		vec2[0] = v2[i]-v0[i];
204 		vec2[1] = st2[0]-st0[0];
205 		vec2[2] = st2[1]-st0[1];
206 		VectorNormalize(vec1);
207 		VectorNormalize(vec2);
208 		CrossProduct(vec1,vec2,planes[i]);
209 	}
210 
211 	//Tangent = (-planes[B][x]/plane[A][x], -planes[B][y]/planes[A][y], - planes[B][z]/planes[A][z] )
212 	//Binormal = (-planes[C][x]/planes[A][x], -planes[C][y]/planes[A][y], -planes[C][z]/planes[A][z] )
213 	Tangent[0] = -planes[0][1]/planes[0][0];
214 	Tangent[1] = -planes[1][1]/planes[1][0];
215 	Tangent[2] = -planes[2][1]/planes[2][0];
216 	Binormal[0] = -planes[0][2]/planes[0][0];
217 	Binormal[1] = -planes[1][2]/planes[1][0];
218 	Binormal[2] = -planes[2][2]/planes[2][0];
219 	VectorNormalize(Tangent); //is this needed?
220 	VectorNormalize(Binormal);
221 }
222 
ClosestPointOnLine(vec3_t a,vec3_t b,vec3_t p,vec3_t res)223 void ClosestPointOnLine(vec3_t a, vec3_t b, vec3_t p, vec3_t res)
224 {
225 	vec3_t c,V;
226 	float d,t ;
227 
228 	// a-b is the line, p the point in question
229 	VectorSubtract(p, a, c);
230 	VectorSubtract(b, a, V);
231 	d = Length(V);
232 	VectorNormalize(V); // normalize V
233 	t = DotProduct(V,c);
234 
235 	// Check to see if t is beyond the extents of the line segment
236 	if (t < 0.0f)
237 	{
238 		VectorCopy(a, res);
239 	}
240 	if (t > d)
241 	{
242 		VectorCopy(b, res);
243 	}
244 	// Return the point between a and b
245 	VectorScale(V, t, V); //set length of V to t.
246 	VectorAdd(a, V, res);
247 }
248 
Orthogonalize(vec3_t v1,vec3_t v2,vec3_t res)249 void Orthogonalize(vec3_t v1, vec3_t v2, vec3_t res)
250 {
251 	vec3_t v2ProjV1;
252 	vec3_t iV1;
253 	VectorScale(v1, -1.0f, iV1);
254 	ClosestPointOnLine(v1, iV1, v2, v2ProjV1);
255 	VectorSubtract(v2, v2ProjV1, res);
256 	VectorNormalize(res);
257 }
258 
DecodeNormal(int quant,vec3_t norm)259 void DecodeNormal(int quant, vec3_t norm) {
260 
261 	float lat = ( quant >> 8 ) & 0xff;
262 	float lng = ( quant & 0xff );
263 	lat *= M_PI/128;
264 	lng *= M_PI/128;
265 
266 	norm[0] = cos(lat) * sin(lng);
267 	norm[1] = sin(lat) * sin(lng);
268 	norm[2] = cos(lng);
269 }
270 
271 /*
272 =================
273 Mod_LoadMd3Model
274 
275 PENTA: Very similar to LoadAliasModel
276 DC: added multiple surface -> alias3data_t
277 =================
278 */
279 
280 #define	LL(x) x=LittleLong(x)
281 
Mod_LoadMd3Model(model_t * mod,void * buffer)282 void Mod_LoadMd3Model (model_t *mod, void *buffer)
283 {
284 	int					i, j, k, l;
285 	md3Header_t			*pinmodel;
286 	int					size;
287 	int					start, end, total;
288 	md3Surface_t		*surf;
289 	md3tag_t			*tag;
290 	vec3_t				md3scale = {MD3_XYZ_SCALE, 	MD3_XYZ_SCALE, 	MD3_XYZ_SCALE};
291 	vec3_t				md3origin = {0.0f, 0.0f, 0.0f};
292 	ftrivertx_t			*verts, *v;
293 	md3XyzNormal_t		*xyz;
294 	mtriangle_t			*tris;
295 	md3Triangle_t		*tri;
296 	md3St_t				*st;
297 	fstvert_t			*texcoords;
298 	md3Frame_t			*frame;
299 	plane_t				*norms;
300 	int					*indecies;
301 	vec3_t				v1, v2, normal;
302 	vec3_t				triangle[3];
303 	vec3_t				*tangents, *binormals;
304 	md3Shader_t			*shader;
305 	byte				fake[16];
306 	char				shadername[MAX_QPATH];
307     alias3data_t			*palias3;
308     int				surfcount;
309 
310 	start = Hunk_LowMark ();
311 
312 	//Con_Printf("Loading md3 from %s\n",mod->name);
313 	pinmodel = (md3Header_t *)buffer;
314 
315 //
316 // endian-adjust and copy the data, starting with the md3 header
317 //
318 
319 
320 	LL(pinmodel->version);
321 	if (pinmodel->version != MD3_VERSION)
322 		Sys_Error ("%s has wrong version number (%i should be %i)",
323 				 mod->name, pinmodel->version, MD3_VERSION);
324 
325 	//swap header
326 	LL(pinmodel->numFrames);
327 	LL(pinmodel->numTags);
328 	LL(pinmodel->numSurfaces);
329 
330 	LL(pinmodel->numSkins);
331 
332 	LL(pinmodel->ofsFrames);
333 	LL(pinmodel->ofsTags);
334 	LL(pinmodel->ofsSurfaces);
335 	LL(pinmodel->ofsEnd);
336 
337 #ifdef MD3DEBUG
338 	Con_Printf("Statistics for model %s\n",loadname);
339 	Con_Printf("NumFrames: %i\n",pinmodel->numFrames);
340 	Con_Printf("NumSurfaces: %i\n",pinmodel->numSurfaces);
341 	Con_Printf("NumSkins: %i\n",pinmodel->numSkins);
342         Con_Printf("NumTags: %i\n",surf->numTags);
343 #endif
344 
345 	if ( pinmodel->numFrames < 1 ) {
346 		Con_Printf( "LoadMd3Model: %s has no frames\n", mod->name );
347 		return;
348 	}
349 
350 	if ( pinmodel->numFrames > MAXALIASFRAMES) {
351 		Sys_Error ("LoadMd3Model: %s has too many frames",mod->name);
352 	}
353 
354 	// swap all the frames
355     frame = (md3Frame_t *) ( (byte *)pinmodel + pinmodel->ofsFrames );
356     for ( i = 0 ; i < pinmodel->numFrames ; i++, frame++) {
357     	frame->radius = LittleFloat( frame->radius );
358         for ( j = 0 ; j < 3 ; j++ ) {
359             frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
360             frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
361 	    	frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
362         }
363 	}
364 
365 	// swap all the surfaces
366 	surf = (md3Surface_t *) ( (byte *)pinmodel + pinmodel->ofsSurfaces );
367 
368 	if (pinmodel->numSurfaces > 1) {
369 		Con_Printf("%s: warning: Model with multiple surfaces\n",mod->name);
370 	}
371 
372 	for ( i = 0 ; i < pinmodel->numSurfaces ; i++) {
373 
374         LL(surf->ident);
375         LL(surf->flags);
376         LL(surf->numFrames);
377         LL(surf->numShaders);
378         LL(surf->numTriangles);
379         LL(surf->ofsTriangles);
380         LL(surf->numVerts);
381         LL(surf->ofsShaders);
382         LL(surf->ofsSt);
383         LL(surf->ofsXyzNormals);
384         LL(surf->ofsEnd);
385 
386 #ifdef MD3DEBUG
387 		Con_Printf("->surface %i\n",i);
388 		Con_Printf("  NumTriangles: %i\n",surf->numTriangles);
389 		Con_Printf("  NumVertices: %i\n",surf->numVerts);
390 		Con_Printf("  NumFrames: %i\n",surf->numFrames);
391 		Con_Printf("  NumShaders: %i\n",surf->numShaders);
392 #endif
393 		if ( surf->numVerts > MAXALIASVERTS)
394 			Sys_Error ("LoadMd3Model: %s has too many vertices (%i)%i",mod->name,surf->numVerts,surf->numTriangles);
395 
396 		if (surf->numTriangles <= 0)
397 			Sys_Error ("LoadMd3Model: %s has no triangles", mod->name);
398 
399 		if (surf->numTriangles > MAXALIASTRIS)
400 			Sys_Error ("LoadMd3Model: %s has too many triangles",mod->name);
401 
402 		// swap all the triangles
403 		tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
404 		for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
405 			LL(tri->indexes[0]);
406 			LL(tri->indexes[1]);
407 			LL(tri->indexes[2]);
408 		}
409 
410 		// swap all the ST
411         st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
412         for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
413             st->s = LittleFloat( st->s);
414             st->t = LittleFloat( st->t);
415         }
416 
417 		// swap all the XyzNormals
418         xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
419         for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ )
420 		{
421             xyz->xyz[0] = LittleShort( xyz->xyz[0] );
422             xyz->xyz[1] = LittleShort( xyz->xyz[1] );
423             xyz->xyz[2] = LittleShort( xyz->xyz[2] );
424 
425             xyz->normal = LittleShort( xyz->normal );
426         }
427 
428 
429 		// find the next surface
430 		surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
431 	}
432 
433 	//point to first surface again
434 	surf = (md3Surface_t *) ( (byte *)pinmodel + pinmodel->ofsSurfaces );
435 
436 //
437 // We have now a working version of the md3 in the "*buffer" now convert that to an "alias" model
438 // this conversion is not to bad sice the I changed the way alias models work to make them more
439 // quake3 friendly, the only thing that remains is that we only use the first surface of the  model.
440 // - DC -
441 // added multiple surfaces.
442 // multiples surfaces : the cached data (alias3data_t) hold an aliashdr_t for each surface
443 //
444 
445         size = sizeof (alias3data_t);
446         palias3 = Hunk_AllocName (size, mod->name);
447         palias3->numSurfaces = pinmodel->numSurfaces;
448 
449         // allocate header offset array
450         size = sizeof (aliashdr_t *) * (pinmodel->numSurfaces - 1);
451         if (size)
452              Hunk_Alloc (size);
453 
454      mod->flags = 0;
455      mod->type = mod_alias;
456      mod->numframes = pinmodel->numFrames;
457      mod->synctype = ST_SYNC;
458 
459      mod->mins[0] = mod->mins[1] = mod->mins[2] =  99999.0;
460      mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = -99999.0;
461 
462 for (surfcount = 0; surfcount < pinmodel->numSurfaces; ++surfcount) {
463 
464 	//Alocate hunk mem for the header and the frame info (not the actual frame vertices)
465 	size = 	sizeof (aliashdr_t) + (pinmodel->numFrames-1) * sizeof (maliasframedesc_t);
466 	pheader = Hunk_Alloc (size);
467 	// store alias offset
468 	palias3->ofsSurfaces[surfcount] = (int)((char*)pheader - (char*)palias3);
469 	Q_memset(pheader,0,sizeof(aliashdr_t));
470 
471 	//Convert the header to the old header
472 	pheader->ident = pinmodel->ident;
473 	pheader->version = pinmodel->version;
474 	VectorCopy(md3scale,pheader->scale);
475 	VectorCopy(md3origin,pheader->scale_origin);
476 	pheader->boundingradius = 100; //This seems not used anymore by quake
477 	VectorCopy(md3origin,pheader->eyeposition);//This seems not used anymore by quake
478 	pheader->numskins = 1; //Hacked value
479 	pheader->skinwidth = 4;//Hacked value
480 	pheader->skinheight = 4;//Hacked value
481 	pheader->numverts = surf->numVerts;
482 	pheader->numtris = surf->numTriangles;
483           pheader->numframes = surf->numFrames;
484           pheader->synctype = mod->synctype;
485 	pheader->flags = 0;//Hacked value
486 	pheader->size = 1;//All right, the unofficial specs say the average size of triangles, so we just put something there
487           pheader->numposes = surf->numFrames;
488 	pheader->poseverts = surf->numVerts;
489 
490 	//Allocate the vertices
491 	verts = Hunk_Alloc (pheader->numposes * pheader->poseverts * sizeof(ftrivertx_t) );
492 	pheader->posedata = (byte *)verts - (byte *)pheader;
493 	xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
494 
495 	//Convert the frames
496 	frame = (md3Frame_t *) ( (byte *)pinmodel + pinmodel->ofsFrames );
497 	for (i=0; i<pheader->numframes; i++, frame++) {
498 		strcpy (pheader->frames[i].name, frame->name);
499 		pheader->frames[i].firstpose = i;
500 		pheader->frames[i].numposes = 1;
501 		pheader->frames[i].frame = i;
502 		pheader->frames[i].interval = 0.1f;
503 		pheader->mins[0] = pheader->mins[1] = pheader->mins[2] =  99999.0;
504 		pheader->maxs[0] = pheader->maxs[1] = pheader->maxs[2] = -99999.0;
505 		//Convert the vertices
506 		for (j=0; j<pheader->poseverts; j++) {
507 			k = i*pheader->poseverts+j;
508 			verts[k].v[0] = xyz[k].xyz[0]*MD3_XYZ_SCALE;
509 			verts[k].v[1] = xyz[k].xyz[1]*MD3_XYZ_SCALE;
510 			verts[k].v[2] = xyz[k].xyz[2]*MD3_XYZ_SCALE;
511 			verts[k].lightnormalindex = xyz[k].normal;
512 			//setup correct surface bounding box
513 			for (l=0; l<3; l++) {
514 				pheader->mins[l] = min(pheader->mins[l],verts[k].v[l]);
515 				pheader->maxs[l] = max(pheader->maxs[l],verts[k].v[l]);
516 			}
517 		}
518 		//setup correct model bounding box
519 		for (j=0; j<3; j++) {
520 			mod->mins[j] = min(mod->mins[j],pheader->mins[j]);
521 			mod->maxs[j] = max(mod->maxs[j],pheader->maxs[j]);
522 		}
523 
524 	}
525 	//Con_Printf("%s: %f,%f,%f %f,%f,%f\n",loadname,mod->mins[0],mod->mins[1],mod->mins[2],mod->maxs[0],mod->maxs[1],mod->maxs[2]);
526 
527 	//Convert the triangles
528 	tris = Hunk_Alloc (pheader->numtris * sizeof(mtriangle_t));
529 	pheader->triangles = (byte *)tris - (byte *)pheader;
530 	tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
531 	for (i=0; i<pheader->numtris; i++) {
532 		for (j=0; j<3; j++) {
533 			tris[i].vertindex[j] = tri[i].indexes[j];
534 			tris[i].neighbours[j] = -1;
535 		}
536 		tris[i].facesfront = true; //doesn't matter
537 	}
538 
539 	//Setup connectivity
540 	for (i=0; i<pheader->numtris; i++)
541 		for (j=0 ; j<3 ; j++) {
542 			//none found yet
543 			if (tris[i].neighbours[j] == -1) {
544 				tris[i].neighbours[j] = findneighbourmd3(i, j, pheader->numtris, tris);
545 			}
546 		}
547 
548 	//Calculate plane equations
549 	norms = Hunk_Alloc (pheader->numtris * pheader->numposes * sizeof(plane_t));
550 	pheader->planes = (byte *)norms - (byte *)pheader;
551 	for (i=0; i<pheader->numposes; i++) {
552 		for (j=0; j<pheader->numtris ; j++) {
553 
554 			//make 3 vec3_t's of this triangle's vertices
555 			for (k=0; k<3; k++) {
556 				v = &verts[i*pheader->poseverts + tris[j].vertindex[k]];
557 				for (l=0; l<3; l++)
558 					triangle[k][l] = v->v[l];
559 			}
560 
561 			//calculate their normal
562 			VectorSubtract(triangle[0], triangle[1], v1);
563 			VectorSubtract(triangle[2], triangle[1], v2);
564 			CrossProduct(v2,v1, normal);
565 			VectorScale(normal, 1/Length(normal), norms[i*pheader->numtris+j].normal);
566 
567 			//distance of plane eq
568 			norms[i*pheader->numtris+j].dist = DotProduct(triangle[0],norms[i*pheader->numtris+j].normal);
569 		}
570 	}
571 
572 	//Convert texcoords for triangles
573 	texcoords = Hunk_Alloc (pheader->poseverts * sizeof(fstvert_t));
574 	pheader->texcoords = (byte *)texcoords - (byte *)pheader;
575 	st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
576 	for (i=0; i<pheader->poseverts ; i++) {
577 		texcoords[i].s = st[i].s;
578 		texcoords[i].t = st[i].t;
579 	}
580 
581 	//Create index lists
582 	indecies = Hunk_Alloc (pheader->numtris * sizeof(int) * 3);
583 	pheader->indecies = (byte *)indecies - (byte *)pheader;
584 	for (i=0 ; i<pheader->numtris ; i++) {
585 		for (j=0 ; j<3 ; j++) {
586 			//Throw vertex index into our index array
587 			(*indecies) = tris[i].vertindex[j];
588 			indecies++;
589 		}
590 	}
591 	indecies = (int *)((byte *)pheader+pheader->indecies);
592 
593 	//Calculate tangents for vertices
594 	tangents = Hunk_Alloc (pheader->poseverts * pheader->numposes * sizeof(vec3_t));
595 	pheader->tangents = (byte *)tangents - (byte *)pheader;
596 
597 	binormals = Hunk_Alloc (pheader->poseverts * pheader->numposes * sizeof(vec3_t));
598 	pheader->binormals = (byte *)binormals - (byte *)pheader;
599 	//for all frames
600 	for (i=0; i<pheader->numposes; i++) {
601 
602 		//set temp to zero
603 		for (j=0; j<pheader->poseverts; j++) {
604 			tangents[i*pheader->poseverts+j][0] = 0;
605 			tangents[i*pheader->poseverts+j][1] = 0;
606 			tangents[i*pheader->poseverts+j][2] = 0;
607 			binormals[i*pheader->poseverts+j][0] = 0;
608 			binormals[i*pheader->poseverts+j][1] = 0;
609 			binormals[i*pheader->poseverts+j][2] = 0;
610 			numNormals[j] = 0;
611 		}
612 
613 		//for all tris
614 		for (j=0; j<pheader->numtris; j++) {
615 			vec3_t tangent;
616 			vec3_t binormal;
617 			vec3_t normal;
618 			TangentForTrimd3(&indecies[j*3],&verts[i*pheader->poseverts],texcoords,tangent,binormal);
619 			//for all vertices in the tri
620 			for (k=0; k<3; k++) {
621 				l = indecies[j*3+k];
622 
623 				VectorAdd(tangents[i*pheader->poseverts+l],tangent,
624 							tangents[i*pheader->poseverts+l]);
625 				VectorAdd(binormals[i*pheader->poseverts+l],binormal,
626 							binormals[i*pheader->poseverts+l]);
627 				numNormals[l]++;
628 			}
629 		}
630 
631 		//calculate average
632 		for (j=0; j<pheader->poseverts; j++) {
633 			vec3_t normal;
634 			if (!numNormals[j]) continue;
635 			tangents[i*pheader->poseverts+j][0] = tangents[i*pheader->poseverts+j][0]/numNormals[j];
636 			tangents[i*pheader->poseverts+j][1] = tangents[i*pheader->poseverts+j][1]/numNormals[j];
637 			tangents[i*pheader->poseverts+j][2] = tangents[i*pheader->poseverts+j][2]/numNormals[j];
638 
639 			binormals[i*pheader->poseverts+j][0] = binormals[i*pheader->poseverts+j][0]/numNormals[j];
640 			binormals[i*pheader->poseverts+j][1] = binormals[i*pheader->poseverts+j][1]/numNormals[j];
641 			binormals[i*pheader->poseverts+j][2] = binormals[i*pheader->poseverts+j][2]/numNormals[j];
642 
643 			VectorNormalize(tangents[i*pheader->poseverts+j]);
644 			VectorNormalize(binormals[i*pheader->poseverts+j]);
645 
646 			DecodeNormal(verts[i*pheader->poseverts+j].lightnormalindex, normal);
647 
648 			Orthogonalize(normal, tangents[i*pheader->poseverts+j], tangents[i*pheader->poseverts+j]);
649 			Orthogonalize(normal, binormals[i*pheader->poseverts+j], binormals[i*pheader->poseverts+j]);
650 		}
651 	}
652 
653 
654 	//Load skins
655 	for (i=0; i<16; i++)
656 		fake[i] = 254;
657 
658 	shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
659 
660 	if (!shader->name[0]) {
661 		Q_strcpy(shader->name,"unnamed");
662 	}
663 
664 	COM_FileBase (shader->name, shadername);
665 	pheader->gl_texturenum[0][0] =
666 	pheader->gl_texturenum[0][1] =
667 	pheader->gl_texturenum[0][2] =
668 	pheader->gl_texturenum[0][3] = GL_LoadTexture (shadername, 4, 4, &fake[0], true, false, true);
669 
670 	pheader->gl_lumatex[0][0] =
671 	pheader->gl_lumatex[0][1] =
672 	pheader->gl_lumatex[0][2] =
673 	pheader->gl_lumatex[0][3] = GL_LoadLuma(shadername, true);
674 #ifdef MD3DEBUG
675 	Con_Printf("Load shader %s\n",shadername);
676 #endif
677 	// next surface
678 	surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
679 } /* for numsurf */
680 
681      //calculate radius
682      mod->radius = RadiusFromBounds (mod->mins, mod->maxs);
683 
684 
685         /* monster or player models only ? */
686         /* tags */
687      /*
688         tag = (md3tag_t *)( (byte *)pinmodel + pinmodel->ofsTags );
689 
690         for (i = 0; i< pinmodel->numTags; ++i){
691 
692              Con_Printf("Tag %s\n",tag[i].name);
693 
694              // swap everything first
695              for ( j = 0 ; j < 3 ; j++ ) {
696                   tag[i].origin[j] = LittleFloat( tag[i].origin[j] );
697                   tag[i].axis[0][j] = LittleFloat( tag[i].axis[0][j] );
698                   tag[i].axis[1][j] = LittleFloat( tag[i].axis[1][j] );
699                   tag[i].axis[2][j] = LittleFloat( tag[i].axis[2][j] );
700              }
701              // then look for supported tags
702              // weapon tag ?
703              if (!strcmp(tag[i].name,"tag_weapon")){
704                   // for weapon, we only need origin, as the weapon
705                   // follows the player look
706                   VectorCopy(palias3->weaponTag.origin,tag[i].origin);
707              }
708         }
709      */
710 
711 	if (!strcmp (mod->name, "progs/g_shot.mdl") || //Hack to give .md3 files renamed to .mdl rotate effects - Eradicator
712  		!strcmp (mod->name, "progs/g_nail.mdl") ||
713  		!strcmp (mod->name, "progs/g_nail2.mdl") ||
714  		!strcmp (mod->name, "progs/g_rock.mdl") ||
715  		!strcmp (mod->name, "progs/g_rock2.mdl") ||
716  		!strcmp (mod->name, "progs/g_light.mdl") ||
717 		!strcmp (mod->name, "progs/armor.mdl") ||
718 		!strcmp (mod->name, "progs/backpack.mdl") ||
719  		!strcmp (mod->name, "progs/w_g_key.mdl") ||
720  		!strcmp (mod->name, "progs/w_s_key.mdl") ||
721  		!strcmp (mod->name, "progs/m_g_key.mdl") ||
722  		!strcmp (mod->name, "progs/m_s_key.mdl") ||
723  		!strcmp (mod->name, "progs/b_g_key.mdl") ||
724  		!strcmp (mod->name, "progs/b_s_key.mdl") ||
725  		!strcmp (mod->name, "progs/quaddama.mdl") ||
726  		!strcmp (mod->name, "progs/invisibl.mdl") ||
727  		!strcmp (mod->name, "progs/invulner.mdl") ||
728  		!strcmp (mod->name, "progs/jetpack.mdl") ||
729  		!strcmp (mod->name, "progs/cube.mdl") ||
730  		!strcmp (mod->name, "progs/suit.mdl") ||
731  		!strcmp (mod->name, "progs/boots.mdl") ||
732  		!strcmp (mod->name, "progs/end1.mdl") ||
733  		!strcmp (mod->name, "progs/end2.mdl") ||
734  		!strcmp (mod->name, "progs/end3.mdl") ||
735 		!strcmp (mod->name, "progs/end4.mdl")) {
736 		mod->flags |= EF_ROTATE;
737 	}
738 	else if (!strcmp (mod->name, "progs/missile.mdl")) {
739 		mod->flags |= EF_ROCKET;
740 	}
741 	else if (!strcmp (mod->name, "progs/gib1.mdl") || //EF_GIB
742  			!strcmp (mod->name, "progs/gib2.mdl") ||
743  			!strcmp (mod->name, "progs/gib3.mdl") ||
744  			!strcmp (mod->name, "progs/h_player.mdl") ||
745  			!strcmp (mod->name, "progs/h_dog.mdl") ||
746  			!strcmp (mod->name, "progs/h_mega.mdl") ||
747  			!strcmp (mod->name, "progs/h_guard.mdl") ||
748  			!strcmp (mod->name, "progs/h_wizard.mdl") ||
749  			!strcmp (mod->name, "progs/h_knight.mdl") ||
750  			!strcmp (mod->name, "progs/h_hellkn.mdl") ||
751  			!strcmp (mod->name, "progs/h_zombie.mdl") ||
752  			!strcmp (mod->name, "progs/h_shams.mdl") ||
753  			!strcmp (mod->name, "progs/h_shal.mdl") ||
754  			!strcmp (mod->name, "progs/h_ogre.mdl") ||
755  			!strcmp (mod->name, "progs/armor.mdl") ||
756 			!strcmp (mod->name, "progs/h_demon.mdl")) {
757 		mod->flags |= EF_GIB;
758 	}
759 	else if (!strcmp (mod->name, "progs/grenade.mdl")) {
760 		mod->flags |= EF_GRENADE;
761 	}
762 	else if (!strcmp (mod->name, "progs/w_spike.mdl")) //EF_TRACER
763 	{
764 		mod->flags |= EF_TRACER;
765 	}
766 	else if (!strcmp (mod->name, "progs/k_spike.mdl")) //EF_TRACER2
767 	{
768 		mod->flags |= EF_TRACER2;
769 	}
770 	else if (!strcmp (mod->name, "progs/v_spike.mdl")) //EF_TRACER3
771 	{
772 		mod->flags |= EF_TRACER3;
773 	}
774  	else if (!strcmp (mod->name, "progs/zom_gib.mdl")) //EF_ZOMGIB
775  	{
776  		mod->flags |= EF_ZOMGIB;
777 	}
778 
779 	if (!strcmp (mod->name, "progs/flame2.mdl")
780 		|| !strcmp (mod->name, "progs/flame.mdl")
781 		|| !strcmp (mod->name, "progs/lavaball.mdl")
782 		|| !strcmp (mod->name, "progs/laser.mdl")
783                 || !strcmp (mod->name, "progs/k_spike.mdl")
784 		|| !strcmp (mod->name, "progs/bolt.mdl")
785 		|| !strcmp (mod->name, "progs/bolt2.mdl")
786 		|| !strcmp (mod->name, "progs/bolt3.mdl"))
787 	{
788 		mod->flags |= EF_FULLBRIGHT;
789 	}
790 
791 //
792 // move the complete, relocatable alias model to the cache
793 //
794 	end = Hunk_LowMark ();
795 	total = end - start;
796 
797 	Cache_Alloc (&mod->cache, total, loadname);
798 	if (!mod->cache.data)
799 		return;
800 	memcpy (mod->cache.data, palias3, total);
801 
802 
803 
804 	Hunk_FreeToLowMark (start);
805 
806 }
807