1 /*
2  * File:         fmt_md2.c
3  *
4  * Description:  loads Quake2 model files (.md2)
5  *
6  *
7  * This source code is part of kludge3d, and is released under the
8  * GNU General Public License.
9  *
10  *
11  */
12 
13 /*
14 This code is based on Mete Cerrigan's .md2 loading code.
15 
16 Note - This code probably won't work on non-Intel systems,
17 as the model data is loaded by simply reading in raw
18 structs in binary form.  (No effort is made to get the bytes into
19 whatever order the local machine uses.)
20 
21 Damn Intel.  I've been told that the reason for storing
22 multi-byte variables (ints, floats etc) in a backwards manner
23 is that it provides a slight performance gain.  In my opinion,
24 that's not a good enough reason.
25 */
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <math.h>
31 #include <gtk/gtk.h>
32 
33 #include "gui.h"
34 #include "mesh.h"
35 #include "model.h"
36 #include "group.h"
37 #include "polygon.h"
38 #include "vertex.h"
39 #include "texture.h"
40 #include "bottombar.h"
41 #include "model_load_save.h"
42 #include "vector.h"
43 #include "tools.h"
44 
45 
46 #ifdef MEMWATCH
47 #include "memwatch.h"
48 #endif
49 
50 
51 #include "fmt_md2.h"
52 
53 /* PROTOTYPES **************************************************************/
54 
55 gint md2_load_doc( struct fu_file *file, Model *model );
56 
57 void md2_set_current_frame( int frm );
58 
59 int md2_readModel( FILE * file ) ;
60 void md2_freeModel( void );
61 void md2_getBoundingBox( float *minmax );
62 void md2_generateLightNormals( void );
63 int md2_getAnimationCount( void );
64 const char *md2_getAnimationName( int animation );
65 void md2_getAnimationFrames( int animation, int *startFrame, int *endFrame );
66 
67 void md2_makeFacetNormal( md2_triangle_t *t, int frame, float *fn );
68 void md2_normalize( float *n );
69 
70 void md2_populateModel( Model * kl3dModel ) ;
71 
72 gint md2_prompt_user( void );
73 
74 
75 /* STRUCTS ******************************************************************/
76 
77 struct doc_file_fmt fmt_md2 = {
78   "Quake2 model (md2)",
79   "md2",
80   md2_load_doc,
81   NULL,
82   NULL
83 };
84 
85 
86 /* FILE-SCOPE VARS **********************************************************/
87 
88 #define MD2_DEFAULT_SCALE_FACTOR 0.032
89 
90 int md2_current_frame;
91 int md2_total_frames;
92 float md2_scale_factor = MD2_DEFAULT_SCALE_FACTOR;
93 
94 md2_model_t *md2Model;
95 
96 float avertexnormals[ NUMVERTEXNORMALS ][ 3 ] = {
97 #include "fmt_md2_anorms.h"
98 };
99 
100 
101 
102 /* FUNCS ********************************************************************/
103 
104 
md2_load_doc(struct fu_file * file,Model * model)105 gint md2_load_doc( struct fu_file *file, Model *model ) {
106 
107 	int result;
108 
109 	md2_current_frame = 0;
110 	md2_total_frames = 0;
111 
112 // FIXME - check result
113 
114 	result = md2_readModel( file->fp );
115 	md2_generateLightNormals();
116 	result = md2_prompt_user();
117 
118 	md2_populateModel( model );
119 
120 
121 	md2_freeModel();
122 	return result;
123 }
124 
125 
md2_set_current_frame(int frm)126 void md2_set_current_frame( int frm ) {
127 
128 	if ( frm >= 0 && frm < md2_total_frames )
129 		md2_current_frame = frm;
130 	else
131 		md2_current_frame = 0;
132 
133 }
134 
135 
136 
137 
138 /*
139  * load model
140  */
md2_readModel(FILE * file)141 int md2_readModel( FILE * file ) {
142 
143 	byte buffer[ MD2_MAX_FRAMESIZE ];
144 	int i;
145 
146 	md2Model = ( md2_model_t * ) malloc ( sizeof ( md2_model_t ) );
147 	if ( !md2Model )
148 		return 0;
149 
150 	/* initialize model and read header */
151 	memset ( md2Model, 0, sizeof ( md2_model_t ) );
152 	fread ( &md2Model->header, sizeof ( md2_header_t ), 1, file );
153 
154 
155 #if 0
156 	printf ( "magic:\t\t%d\n", md2Model->header.magic );
157 	printf ( "version:\t\t%d\n", md2Model->header.version );
158 	printf ( "skinWidth:\t\t%d\n", md2Model->header.skinWidth );
159 	printf ( "skinHeight:\t\t%d\n", md2Model->header.skinHeight );
160 	printf ( "frameSize:\t\t%d\n", md2Model->header.frameSize );
161 	printf ( "numSkins:\t\t%d\n", md2Model->header.numSkins );
162 	printf ( "numVertices:\t\t%d\n", md2Model->header.numVertices );
163 	printf ( "numTexCoords:\t\t%d\n", md2Model->header.numTexCoords );
164 	printf ( "numTriangles:\t\t%d\n", md2Model->header.numTriangles );
165 	printf ( "numGlCommands:\t\t%d\n", md2Model->header.numGlCommands );
166 	printf ( "numFrames:\t\t%d\n", md2Model->header.numFrames );
167 	printf ( "offsetSkins:\t\t%d\n", md2Model->header.offsetSkins );
168 	printf ( "offsetTexCoords:\t%d\n", md2Model->header.offsetTexCoords );
169 	printf ( "offsetTriangles:\t%d\n", md2Model->header.offsetTriangles );
170 	printf ( "offsetFrames:\t\t%d\n", md2Model->header.offsetFrames );
171 	printf ( "offsetGlCommands:\t%d\n", md2Model->header.offsetGlCommands );
172 	printf ( "offsetEnd:\t\t%d\n", md2Model->header.offsetEnd );
173 #endif
174 
175 	if ( md2Model->header.magic != ( int ) ( ( '2' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' ) ) {
176 		fclose ( file );
177 		free ( md2Model );
178 		return 0;
179 	}
180 
181 	/* read skins */
182 	fseek ( file, md2Model->header.offsetSkins, SEEK_SET );
183 	if ( md2Model->header.numSkins > 0 ) {
184 		md2Model->skins = ( md2_skin_t * ) malloc ( sizeof ( md2_skin_t ) * md2Model->header.numSkins );
185 		if ( !md2Model->skins ) {
186 			md2_freeModel ();
187 			return 0;
188 		}
189 
190 		for ( i = 0; i < md2Model->header.numSkins; i++ )
191 			fread ( &md2Model->skins[ i ], sizeof ( md2_skin_t ), 1, file );
192 	}
193 
194 	/* read texture coordinates */
195 	fseek ( file, md2Model->header.offsetTexCoords, SEEK_SET );
196 	if ( md2Model->header.numTexCoords > 0 ) {
197 		md2Model->texCoords = ( md2_textureCoordinate_t * ) malloc ( sizeof ( md2_textureCoordinate_t ) * md2Model->header.numTexCoords );
198 		if ( !md2Model->texCoords ) {
199 			md2_freeModel ();
200 			return 0;
201 		}
202 
203 		for ( i = 0; i < md2Model->header.numTexCoords; i++ )
204 			fread ( &md2Model->texCoords[ i ], sizeof ( md2_textureCoordinate_t ), 1, file );
205 	}
206 
207 	/* read triangles */
208 	fseek ( file, md2Model->header.offsetTriangles, SEEK_SET );
209 	if ( md2Model->header.numTriangles > 0 ) {
210 		md2Model->triangles = ( md2_triangle_t * ) malloc ( sizeof ( md2_triangle_t ) * md2Model->header.numTriangles );
211 		if ( !md2Model->triangles ) {
212 			md2_freeModel ();
213 			return 0;
214 		}
215 
216 		for ( i = 0; i < md2Model->header.numTriangles; i++ )
217 			fread ( &md2Model->triangles[ i ], sizeof ( md2_triangle_t ), 1, file );
218 	}
219 
220 
221 	md2_total_frames = md2Model->header.numFrames;
222 
223 	/* read alias frames */
224 	fseek ( file, md2Model->header.offsetFrames, SEEK_SET );
225 	if ( md2Model->header.numFrames > 0 ) {
226 		md2Model->frames = ( md2_frame_t * ) malloc ( sizeof ( md2_frame_t ) * md2Model->header.numFrames );
227 		if ( !md2Model->frames ) {
228 			md2_freeModel ();
229 			return 0;
230 		}
231 
232 		for ( i = 0; i < md2Model->header.numFrames; i++ ) {
233 			md2_alias_frame_t *frame = ( md2_alias_frame_t * ) buffer;
234 			int j;
235 
236 			md2Model->frames[ i ].vertices = ( md2_triangleVertex_t * ) malloc ( sizeof ( md2_triangleVertex_t ) * md2Model->header.numVertices );
237 			if ( !md2Model->frames[ i ].vertices ) {
238 				md2_freeModel ();
239 				return 0;
240 			}
241 
242 			fread ( frame, 1, md2Model->header.frameSize, file );
243 			strcpy ( md2Model->frames[ i ].name, frame->name );
244 			for ( j = 0; j < md2Model->header.numVertices; j++ ) {
245 
246 				md2Model->frames[ i ].vertices[ j ].vertex[ 0 ] = ( ( ( float ) ( ( int ) frame->alias_vertices[ j ].vertex[ 0 ] ) * frame->scale[ 0 ] ) + frame->translate[ 0 ] );
247 				md2Model->frames[ i ].vertices[ j ].vertex[ 1 ] = ( ( ( float ) ( ( int ) frame->alias_vertices[ j ].vertex[ 1 ] ) * frame->scale[ 1 ] ) + frame->translate[ 1 ] );
248 				md2Model->frames[ i ].vertices[ j ].vertex[ 2 ] = ( ( ( float ) ( ( int ) frame->alias_vertices[ j ].vertex[ 2 ] ) * frame->scale[ 2 ] ) + frame->translate[ 2 ] );
249 
250 				md2Model->frames[ i ].vertices[ j ].normal[ 0 ] = avertexnormals[ frame->alias_vertices[ j ].lightNormalIndex ][ 0 ];
251 				md2Model->frames[ i ].vertices[ j ].normal[ 1 ] = avertexnormals[ frame->alias_vertices[ j ].lightNormalIndex ][ 1 ];
252 				md2Model->frames[ i ].vertices[ j ].normal[ 2 ] = avertexnormals[ frame->alias_vertices[ j ].lightNormalIndex ][ 2 ];
253 				//md2Model->frames[i].vertices[j].lightNormalIndex = frame->alias_vertices[j].lightNormalIndex;
254 			}
255 
256 		}
257 	}
258 
259 	/* read gl commands */
260 	fseek ( file, md2Model->header.offsetGlCommands, SEEK_SET );
261 	if ( md2Model->header.numGlCommands ) {
262 		md2Model->glCommandBuffer = ( int * ) malloc ( sizeof ( int ) * md2Model->header.numGlCommands );
263 		if ( !md2Model->glCommandBuffer ) {
264 			md2_freeModel ();
265 			return 0;
266 		}
267 
268 		fread ( md2Model->glCommandBuffer, sizeof ( int ), md2Model->header.numGlCommands, file );
269 	}
270 
271 	return 1;
272 }
273 
274 
275 
276 /*
277  * free model
278  */
md2_freeModel(void)279 void md2_freeModel( void ) {
280 	if ( md2Model ) {
281 		if ( md2Model->skins )
282 			free ( md2Model->skins );
283 
284 		if ( md2Model->texCoords )
285 			free ( md2Model->texCoords );
286 
287 		if ( md2Model->triangles )
288 			free ( md2Model->triangles );
289 
290 		if ( md2Model->frames ) {
291 			int i;
292 
293 			for ( i = 0; i < md2Model->header.numFrames; i++ ) {
294 				if ( md2Model->frames[ i ].vertices )
295 					free ( md2Model->frames[ i ].vertices );
296 			}
297 			free ( md2Model->frames );
298 		}
299 
300 		if ( md2Model->glCommandBuffer )
301 			free ( md2Model->glCommandBuffer );
302 
303 		free ( md2Model );
304 	}
305 }
306 
307 
308 
309 
310 /*
311  * center model
312  *
313  */
md2_getBoundingBox(float * minmax)314 void md2_getBoundingBox ( float *minmax ) {
315 	int i;
316 	float minx, maxx;
317 	float miny, maxy;
318 	float minz, maxz;
319 
320 	minx = miny = minz = 999999.0f;
321 	maxx = maxy = maxz = -999999.0f;
322 
323 	/* get bounding box */
324 	for ( i = 0; i < md2Model->header.numVertices; i++ ) {
325 		md2_triangleVertex_t *v = &md2Model->frames[ 0 ].vertices[ i ];
326 
327 		if ( v->vertex[ 0 ] < minx )
328 			minx = v->vertex[ 0 ];
329 		else if ( v->vertex[ 0 ] > maxx )
330 			maxx = v->vertex[ 0 ];
331 
332 		if ( v->vertex[ 1 ] < miny )
333 			miny = v->vertex[ 1 ];
334 		else if ( v->vertex[ 1 ] > maxy )
335 			maxy = v->vertex[ 1 ];
336 
337 		if ( v->vertex[ 2 ] < minz )
338 			minz = v->vertex[ 2 ];
339 		else if ( v->vertex[ 2 ] > maxz )
340 			maxz = v->vertex[ 2 ];
341 	}
342 
343 	minmax[ 0 ] = minx;
344 	minmax[ 1 ] = maxx;
345 	minmax[ 2 ] = miny;
346 	minmax[ 3 ] = maxy;
347 	minmax[ 4 ] = minz;
348 	minmax[ 5 ] = maxz;
349 }
350 
351 
md2_makeFacetNormal(md2_triangle_t * t,int frame,float * fn)352 void md2_makeFacetNormal ( md2_triangle_t *t, int frame, float *fn ) {
353 	float v1[ 3 ], v2[ 3 ];
354 	double angle;
355 
356 	v1[ 0 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 1 ] ].vertex[ 0 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 0 ];
357 	v1[ 1 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 1 ] ].vertex[ 1 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 1 ];
358 	v1[ 2 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 1 ] ].vertex[ 2 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 2 ];
359 
360 	v2[ 0 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 2 ] ].vertex[ 0 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 0 ];
361 	v2[ 1 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 2 ] ].vertex[ 1 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 1 ];
362 	v2[ 2 ] = md2Model->frames[ frame ].vertices[ t->vertexIndices[ 2 ] ].vertex[ 2 ] - md2Model->frames[ frame ].vertices[ t->vertexIndices[ 0 ] ].vertex[ 2 ];
363 
364 	angle = 1;
365 
366 	fn[ 0 ] = ( v1[ 1 ] * v2[ 2 ] - v1[ 2 ] * v2[ 1 ] ) * ( float ) angle;
367 	fn[ 1 ] = ( v1[ 2 ] * v2[ 0 ] - v1[ 0 ] * v2[ 2 ] ) * ( float ) angle;
368 	fn[ 2 ] = ( v1[ 0 ] * v2[ 1 ] - v1[ 1 ] * v2[ 0 ] ) * ( float ) angle;
369 }
370 
371 
372 
md2_normalize(float * n)373 void md2_normalize ( float *n ) {
374 	float l = ( float ) sqrt ( n[ 0 ] * n[ 0 ] + n[ 1 ] * n[ 1 ] + n[ 2 ] * n[ 2 ] );
375 
376 	if ( l != 0.0f ) {
377 		n[ 0 ] /= l;
378 		n[ 1 ] /= l;
379 		n[ 2 ] /= l;
380 	}
381 }
382 
383 
384 
md2_generateLightNormals(void)385 void md2_generateLightNormals( void ) {
386 	int i;
387 
388 	if ( !md2Model )
389 		return ;
390 
391 
392 	for ( i = 0; i < md2Model->header.numFrames; i++ ) {
393 		int j;
394 
395 		/* clear all normals */
396 		for ( j = 0; j < md2Model->header.numVertices; j++ ) {
397 			md2Model->frames[ i ].vertices[ j ].normal[ 0 ] = 0.0f;
398 			md2Model->frames[ i ].vertices[ j ].normal[ 1 ] = 0.0f;
399 			md2Model->frames[ i ].vertices[ j ].normal[ 2 ] = 0.0f;
400 		}
401 
402 		/* calc normals */
403 		for ( j = 0; j < md2Model->header.numTriangles; j++ ) {
404 			int k;
405 			float facetnormal[ 3 ];
406 
407 			md2_makeFacetNormal ( &md2Model->triangles[ j ], i, facetnormal );
408 
409 			for ( k = 0; k < 3; k++ ) {
410 				md2Model->frames[ i ].vertices[ md2Model->triangles[ j ].vertexIndices[ k ] ].normal[ 0 ] -= facetnormal[ 0 ];
411 				md2Model->frames[ i ].vertices[ md2Model->triangles[ j ].vertexIndices[ k ] ].normal[ 1 ] += facetnormal[ 2 ];
412 				md2Model->frames[ i ].vertices[ md2Model->triangles[ j ].vertexIndices[ k ] ].normal[ 2 ] -= facetnormal[ 1 ];
413 			}
414 		}
415 
416 		/* normalize normals */
417 		for ( j = 0; j < md2Model->header.numVertices; j++ )
418 			md2_normalize ( md2Model->frames[ i ].vertices[ j ].normal );
419 	}
420 }
421 
422 
423 
md2_getAnimationCount(void)424 int md2_getAnimationCount( void ) {
425 	int i, j, pos;
426 	int count;
427 	int lastId;
428 	char name[ 16 ], last[ 16 ];
429 
430 	strcpy ( last, md2Model->frames[ 0 ].name );
431 	pos = strlen ( last ) - 1;
432 	j = 0;
433 	while ( last[ pos ] >= '0' && last[ pos ] <= '9' && j < 2 ) {
434 		pos--;
435 		j++;
436 	}
437 	last[ pos + 1 ] = '\0';
438 
439 	lastId = 0;
440 	count = 0;
441 
442 	for ( i = 0; i <= md2Model->header.numFrames; i++ ) {
443 		if ( i == md2Model->header.numFrames )
444 			strcpy ( name, "" );  // some kind of a sentinel
445 		else
446 			strcpy ( name, md2Model->frames[ i ].name );
447 		pos = strlen ( name ) - 1;
448 		j = 0;
449 		while ( name[ pos ] >= '0' && name[ pos ] <= '9' && j < 2 ) {
450 			pos--;
451 			j++;
452 		}
453 		name[ pos + 1 ] = '\0';
454 
455 		if ( strcmp ( last, name ) ) {
456 			strcpy ( last, name );
457 			count++;
458 		}
459 	}
460 
461 	return count;
462 }
463 
464 
465 
md2_getAnimationName(int animation)466 const char * md2_getAnimationName ( int animation ) {
467 	int i, j, pos;
468 	int count;
469 	int lastId;
470 	static char last[ 32 ];
471 	char name[ 32 ];
472 
473 	strcpy ( last, md2Model->frames[ 0 ].name );
474 	pos = strlen ( last ) - 1;
475 	j = 0;
476 	while ( last[ pos ] >= '0' && last[ pos ] <= '9' && j < 2 ) {
477 		pos--;
478 		j++;
479 	}
480 	last[ pos + 1 ] = '\0';
481 
482 	lastId = 0;
483 	count = 0;
484 
485 	for ( i = 0; i <= md2Model->header.numFrames; i++ ) {
486 		if ( i == md2Model->header.numFrames )
487 			strcpy ( name, "" );  // some kind of a sentinel
488 		else
489 			strcpy ( name, md2Model->frames[ i ].name );
490 		pos = strlen ( name ) - 1;
491 		j = 0;
492 		while ( name[ pos ] >= '0' && name[ pos ] <= '9' && j < 2 ) {
493 			pos--;
494 			j++;
495 		}
496 		name[ pos + 1 ] = '\0';
497 
498 		if ( strcmp ( last, name ) ) {
499 			if ( count == animation )
500 				return last;
501 
502 			strcpy ( last, name );
503 			count++;
504 		}
505 	}
506 
507 	return 0;
508 }
509 
510 
511 
md2_getAnimationFrames(int animation,int * startFrame,int * endFrame)512 void md2_getAnimationFrames ( int animation, int *startFrame, int *endFrame ) {
513 	int i, j, pos;
514 	int count, numFrames, frameCount;
515 	int lastId;
516 	char name[ 16 ], last[ 16 ];
517 
518 	strcpy ( last, md2Model->frames[ 0 ].name );
519 	pos = strlen ( last ) - 1;
520 	j = 0;
521 	while ( last[ pos ] >= '0' && last[ pos ] <= '9' && j < 2 ) {
522 		pos--;
523 		j++;
524 	}
525 	last[ pos + 1 ] = '\0';
526 
527 	lastId = 0;
528 	count = 0;
529 	numFrames = 0;
530 	frameCount = 0;
531 
532 	for ( i = 0; i <= md2Model->header.numFrames; i++ ) {
533 		if ( i == md2Model->header.numFrames )
534 			strcpy ( name, "" );  // some kind of a sentinel
535 		else
536 			strcpy ( name, md2Model->frames[ i ].name );
537 		pos = strlen ( name ) - 1;
538 		j = 0;
539 		while ( name[ pos ] >= '0' && name[ pos ] <= '9' && j < 2 ) {
540 			pos--;
541 			j++;
542 		}
543 		name[ pos + 1 ] = '\0';
544 
545 		if ( strcmp ( last, name ) ) {
546 			strcpy ( last, name );
547 
548 			if ( count == animation ) {
549 				*startFrame = frameCount - numFrames;
550 				*endFrame = frameCount - 1;
551 				return ;
552 			}
553 
554 			count++;
555 			numFrames = 0;
556 		}
557 		frameCount++;
558 		numFrames++;
559 	}
560 
561 
562 	*startFrame = *endFrame = 0;
563 }
564 
565 
566 /* FUNCS TO POPULATE KL3D MODEL ********************************************/
567 
md2_populateModel(Model * kl3dModel)568 void md2_populateModel( Model * kl3dModel ) {
569 
570 	int i;
571 	Vertex **kl3dverts;
572 	md2_frame_t *f = &md2Model->frames[ md2_current_frame ];
573 
574 	/* Note - model_new has already set up the model for us, and
575 	has created an empty mesh and groupnode.  The model's current_mesh
576 	and current_node are assumed to be set appropriately.  All we have to
577 	do is put stuff in them. */
578 
579 /*
580 cout << "#Converted from an md2 model by Andrew's magical MD2->AC3D converter!!\n";
581 cout << "#Here's some info about the original md2 model...\n";
582 cout << "#magic:\t\t\t" << model->header.magic << endl;
583 cout << "#version:\t\t" << model->header.version << endl;
584 cout << "#skinWidth:\t\t" << model->header.skinWidth << endl;
585 cout << "#skinHeight:\t\t" << model->header.skinHeight << endl;
586 cout << "#frameSize:\t\t" << model->header.frameSize << endl;
587 cout << "#numSkins:\t\t" << model->header.numSkins << endl;
588 cout << "#numVertices:\t\t" << model->header.numVertices << endl;
589 cout << "#numTexCoords:\t\t" << model->header.numTexCoords << endl;
590 cout << "#numTriangles:\t\t" << model->header.numTriangles << endl;
591 cout << "#numGlCommands:\t\t" << model->header.numGlCommands << endl;
592 cout << "#numFrames:\t\t" << model->header.numFrames << endl;
593 cout << "#offsetSkins:\t\t" << model->header.offsetSkins << endl;
594 cout << "#offsetTexCoords:\t" << model->header.offsetTexCoords << endl;
595 cout << "#offsetTriangles:\t" << model->header.offsetTriangles << endl;
596 cout << "#offsetFrames:\t\t" << model->header.offsetFrames << endl;
597 cout << "#offsetGlCommands:\t" << model->header.offsetGlCommands << endl;
598 cout << "#offsetEnd:\t\t" << model->header.offsetEnd << endl;
599 */
600 
601 	kl3dverts = (Vertex **)malloc( sizeof( Vertex * ) * md2Model->header.numVertices );
602 
603 	mesh_set_name( kl3dModel->current_mesh, f->name );
604 
605 	/* create and add the vertices */
606 	for ( i = 0; i < md2Model->header.numVertices; i++ ) {
607 		Vertex *v;
608 		v = vertex_new();
609 		vector_copy( v->v, f->vertices[ i ].vertex );
610 
611 		kl3dverts[i] = v;
612 		model_vertex_add( kl3dModel, v );
613 		mesh_vertex_add( kl3dModel->current_mesh, v );
614 	}
615 
616 	/* create and add the triangles */
617 	for ( i = 0; i < md2Model->header.numTriangles; i++ ) {
618 		int j;
619 		md2_triangle_t *t = &md2Model->triangles[ i ];
620 		Poly *kl3dpoly;
621 
622 		kl3dpoly = poly_new();
623 
624 		/*
625 		The vertices for the triangles are given in reverse order, because
626 		md2's have cw triangles, but opengl expects ccw triangles
627 
628 		The "1.0 - textureCoord.y" thing is to flip the texture coordinate
629 		system around to match opengl's... textures created in graphics editors
630 		have the origin in the upper left, whereas ogl's is in the lower left.
631 		*/
632 
633 		for( j = 2; j >= 0; j-- ) {
634 			poly_add_vertex( kl3dpoly, kl3dverts[t->vertexIndices[ j ]] );
635 			kl3dpoly->tc[kl3dpoly->num_verts - 1]->x =
636 				( float ) md2Model->texCoords[ t->textureIndices[ j ] ].s /
637 				( float ) md2Model->header.skinWidth;
638 			kl3dpoly->tc[kl3dpoly->num_verts - 1]->y =
639 				1.0 - (
640 				( float ) md2Model->texCoords[ t->textureIndices[ j ] ].t /
641 				( float ) md2Model->header.skinHeight );
642 		}
643 
644 		mesh_polygon_add( kl3dModel->current_mesh, kl3dpoly );
645 	}
646 
647 
648 	if( md2_scale_factor > 0.0f ) {
649 		/* perform scaling of vertex coordinates */
650 		tools_vertices_scale_about_origin( kl3dModel,
651 			kl3dModel->current_mesh->vertices, md2_scale_factor, TRUE );
652 	}
653 
654 	free( kl3dverts );
655 }
656 
657 
658 
659 
660 /* GUI STUFF ***************************************************************/
661 
662 GtkWidget *md2_scale_entry = NULL;
663 GtkWidget *md2_frame_spinner = NULL;
664 
md2_prompt_user(void)665 gint md2_prompt_user( void ) {
666 
667 	GtkWidget *dialog;
668     GtkWidget *hbox, *widget;
669 	GtkAdjustment *adj;
670     gchar buf[32];
671 	gint dlg_response;
672 	int result = TRUE;
673 
674 	dialog = gtk_dialog_new_with_buttons ("MD2 Options",
675 										  GTK_WINDOW( TopLevelWindow ),
676 										  GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
677 										  GTK_STOCK_OK,
678 										  GTK_RESPONSE_OK,
679 										  GTK_STOCK_CANCEL,
680 										  GTK_RESPONSE_CANCEL,
681 										  NULL);
682 
683 	/* Scaling - frame */
684 	widget = gtk_frame_new("Scaling");
685 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), widget, TRUE, TRUE, 0);
686 
687 	/* Scaling - hbox */
688 	hbox = gtk_hbox_new(FALSE, 10);
689 	gtk_container_add(GTK_CONTAINER(widget), hbox);
690 
691 	/* Scaling - entry box */
692 	widget = gtk_label_new("Scaling Factor:");
693 	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
694 	md2_scale_entry = gtk_entry_new();
695 	sprintf(buf, "%g", md2_scale_factor);
696 	gtk_entry_set_text(GTK_ENTRY(md2_scale_entry), buf);
697 	gtk_box_pack_start(GTK_BOX(hbox), md2_scale_entry, TRUE, TRUE, 0);
698 
699 
700 	/* Select Frame - frame */
701 	widget = gtk_frame_new("Select Frame");
702 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), widget, TRUE, TRUE, 0);
703 
704 	/* Select Frame - hbox */
705 	hbox = gtk_hbox_new(FALSE, 10);
706 	gtk_container_add(GTK_CONTAINER(widget), hbox);
707 
708 	/* Select Frame - entry box */
709 	widget = gtk_label_new("Frame to load:");
710 	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
711 	adj = (GtkAdjustment *)gtk_adjustment_new(
712 			0., 0., (gdouble)(md2Model->header.numFrames) - 1.,
713 			1., 1., 1. );
714 	md2_frame_spinner = gtk_spin_button_new( adj, 1.0, 0 );
715 	gtk_box_pack_start(GTK_BOX(hbox), md2_frame_spinner, TRUE, TRUE, 0);
716 
717 	/* set up the OK button as the default widget */
718 	gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_OK );
719 	g_signal_connect( G_OBJECT( md2_scale_entry ), "activate",
720 					G_CALLBACK(gui_dialog_ok_cb), dialog );
721 	g_signal_connect( G_OBJECT( md2_frame_spinner ), "activate",
722 					G_CALLBACK(gui_dialog_ok_cb), dialog );
723 
724 	/* shows the dialog, and since it's modal, prevents rest of
725 	   kludge3d from doing stuff */
726 	gtk_widget_show_all (dialog);
727 
728 	/* runs a gtkmain until the user clicks on something */
729 	dlg_response = gtk_dialog_run( GTK_DIALOG (dialog) );
730 
731 	switch( dlg_response ) {
732 	case GTK_RESPONSE_OK:
733 		md2_scale_factor =
734 			atof(gtk_entry_get_text(GTK_ENTRY(md2_scale_entry)));
735 		if( md2_scale_factor < 0.0 )
736 			md2_scale_factor = -md2_scale_factor;
737 		md2_set_current_frame( gtk_spin_button_get_value_as_int(
738 			GTK_SPIN_BUTTON(md2_frame_spinner) ) );
739 		break;
740 	default:
741 	    md2_scale_factor = -1.;
742 		md2_current_frame = 0;
743 		result = FALSE;
744 		break;
745 	}
746 
747 	gtk_widget_destroy( dialog );
748 
749 	md2_scale_entry = NULL;
750 
751 printf( "md2_scale_factor is %f\n", md2_scale_factor );
752 printf( "md2_current_frame is %i\n", md2_current_frame );
753 
754 /* FIXME - possible leak - will the gtkadjustment be properly dereferenced
755 when the spinner is destroyed, or do *we* need to do that? */
756 
757 	return result;
758 }
759 
760 
761 
762 
763 
764 
765 
766 /******************************************************************
767  *
768  * DEAD CODE
769  *
770  *****************************************************************/
771 #if 0
772 
773 void md2_dumpModel( float scale ) {
774 	int i;
775 
776 	md2_frame_t *f = &md2Model->frames[ md2_current_frame ];
777 
778 cout << "AC3Db\n";
779 
780 /*
781 cout << "#Converted from an md2 model by Andrew's magical MD2->AC3D converter!!\n";
782 cout << "#Here's some info about the original md2 model...\n";
783 cout << "#magic:\t\t\t" << model->header.magic << endl;
784 cout << "#version:\t\t" << model->header.version << endl;
785 cout << "#skinWidth:\t\t" << model->header.skinWidth << endl;
786 cout << "#skinHeight:\t\t" << model->header.skinHeight << endl;
787 cout << "#frameSize:\t\t" << model->header.frameSize << endl;
788 cout << "#numSkins:\t\t" << model->header.numSkins << endl;
789 cout << "#numVertices:\t\t" << model->header.numVertices << endl;
790 cout << "#numTexCoords:\t\t" << model->header.numTexCoords << endl;
791 cout << "#numTriangles:\t\t" << model->header.numTriangles << endl;
792 cout << "#numGlCommands:\t\t" << model->header.numGlCommands << endl;
793 cout << "#numFrames:\t\t" << model->header.numFrames << endl;
794 cout << "#offsetSkins:\t\t" << model->header.offsetSkins << endl;
795 cout << "#offsetTexCoords:\t" << model->header.offsetTexCoords << endl;
796 cout << "#offsetTriangles:\t" << model->header.offsetTriangles << endl;
797 cout << "#offsetFrames:\t\t" << model->header.offsetFrames << endl;
798 cout << "#offsetGlCommands:\t" << model->header.offsetGlCommands << endl;
799 cout << "#offsetEnd:\t\t" << model->header.offsetEnd << endl;
800 */
801 cout << "MATERIAL \"\" rgb 1 1 1  amb 0.2 0.2 0.2  emis 0 0 0  spec 0.5 0.5 0.5  shi 10  trans 0\n";
802 cout << "OBJECT world\n";
803 cout << "kids 1\n";
804 cout << "OBJECT poly\n";
805 cout << "name \"" << md2_getAnimationName( 0 ) << "\"\n";
806 cout << "texture \"default.rgb\"\n";
807 //cout << "loc 0 0 0\n";
808 
809 // this writes out the mesh
810 cout << "numvert " << md2Model->header.numVertices << endl;
811 
812 	for ( i = 0; i < md2Model->header.numVertices; i++ ) {
813 
814 		// apparently, ac3d seems to use that screwy, retarded coordinate system (ie "y is up")
815 		// so we'll rotate the vertices around the x axis before we output them
816 		cout << f->vertices[ i ].vertex[ 0 ] * scale << " "
817 			 << f->vertices[ i ].vertex[ 2 ] * scale << " "
818 			 << f->vertices[ i ].vertex[ 1 ] * -1.0 * scale << endl;
819 
820 	}
821 
822 // this writes out the texture-mapping information
823 cout << "numsurf " << md2Model->header.numTriangles << endl;
824 
825 	for ( i = 0; i < md2Model->header.numTriangles; i++ ) {
826 		md2_triangle_t *t = &md2Model->triangles[ i ];
827 
828 		cout << "SURF 0x0\n";
829 		cout << "mat 0\n";
830 		cout << "refs 3\n";
831 
832 		// the vertices for the triangles are given in reverse order, because
833 		// md2's have cw triangles, but opengl expects ccw triangles
834 
835 		// the "1.0 - textureCoord.y" things are to flip the texture coordinate
836 		// system around to match opengl's... textures created in graphics editors
837 		// have the origin in the upper left, whereas ogl's is in the lower left.
838 
839 		cout << t->vertexIndices[ 2 ] << " ";
840 		cout << ( float ) md2Model->texCoords[ t->textureIndices[ 2 ] ].s / ( float ) md2Model->header.skinWidth << " ";
841 		cout << 1.0 - ( ( float ) md2Model->texCoords[ t->textureIndices[ 2 ] ].t / ( float ) md2Model->header.skinHeight ) << endl;
842 
843 		cout << t->vertexIndices[ 1 ] << " ";
844 		cout << ( float ) md2Model->texCoords[ t->textureIndices[ 1 ] ].s / ( float ) md2Model->header.skinWidth << " ";
845 		cout << 1.0 - ( ( float ) md2Model->texCoords[ t->textureIndices[ 1 ] ].t / ( float ) md2Model->header.skinHeight ) << endl;
846 
847 		cout << t->vertexIndices[ 0 ] << " ";
848 		cout << ( float ) md2Model->texCoords[ t->textureIndices[ 0 ] ].s / ( float ) md2Model->header.skinWidth << " ";
849 		cout << 1.0 - ( ( float ) md2Model->texCoords[ t->textureIndices[ 0 ] ].t / ( float ) md2Model->header.skinHeight ) << endl;
850 
851 	}
852 
853 cout << "kids 0\n";
854 
855 }
856 
857 
858 /*
859  * draw normal
860  *
861  */
862 void
863 Md2_Object::_md2_drawModel ( int frame ) {
864 	int i;
865 
866 	md2_frame_t *f = &model->frames[ frame ];
867 
868 	glBegin ( GL_TRIANGLES );
869 
870 	for ( i = 0; i < model->header.numTriangles; i++ ) {
871 		md2_triangle_t *t = &model->triangles[ i ];
872 		//int lightNormalIndex;
873 		/*
874 				lightNormalIndex = f->vertices[t->vertexIndices[0]].lightNormalIndex;
875 				glNormal3f (avertexnormals[lightNormalIndex][0],
876 					avertexnormals[lightNormalIndex][2],
877 					-avertexnormals[lightNormalIndex][1]);
878 		*/
879 		glNormal3f ( f->vertices[ t->vertexIndices[ 0 ] ].normal[ 0 ],
880 					 f->vertices[ t->vertexIndices[ 0 ] ].normal[ 2 ],
881 					 -f->vertices[ t->vertexIndices[ 0 ] ].normal[ 1 ] );
882 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 0 ] ].s / ( float ) model->header.skinWidth,
883 					   ( float ) model->texCoords[ t->textureIndices[ 0 ] ].t / ( float ) model->header.skinHeight );
884 		glVertex3f ( f->vertices[ t->vertexIndices[ 0 ] ].vertex[ 0 ],
885 					 f->vertices[ t->vertexIndices[ 0 ] ].vertex[ 1 ],
886 					 f->vertices[ t->vertexIndices[ 0 ] ].vertex[ 2 ] );
887 
888 		/*
889 				lightNormalIndex = f->vertices[t->vertexIndices[1]].lightNormalIndex;
890 				glNormal3f (avertexnormals[lightNormalIndex][0],
891 					avertexnormals[lightNormalIndex][2],
892 					-avertexnormals[lightNormalIndex][1]);
893 		*/
894 		glNormal3f ( f->vertices[ t->vertexIndices[ 1 ] ].normal[ 0 ],
895 					 f->vertices[ t->vertexIndices[ 1 ] ].normal[ 2 ],
896 					 -f->vertices[ t->vertexIndices[ 1 ] ].normal[ 1 ] );
897 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 1 ] ].s / ( float ) model->header.skinWidth,
898 					   ( float ) model->texCoords[ t->textureIndices[ 1 ] ].t / ( float ) model->header.skinHeight );
899 		glVertex3f ( f->vertices[ t->vertexIndices[ 1 ] ].vertex[ 0 ],
900 					 f->vertices[ t->vertexIndices[ 1 ] ].vertex[ 1 ],
901 					 f->vertices[ t->vertexIndices[ 1 ] ].vertex[ 2 ] );
902 		/*
903 				lightNormalIndex = f->vertices[t->vertexIndices[2]].lightNormalIndex;
904 				glNormal3f (avertexnormals[lightNormalIndex][0],
905 					avertexnormals[lightNormalIndex][2],
906 					-avertexnormals[lightNormalIndex][1]);
907 		*/
908 		glNormal3f ( f->vertices[ t->vertexIndices[ 2 ] ].normal[ 0 ],
909 					 f->vertices[ t->vertexIndices[ 2 ] ].normal[ 2 ],
910 					 -f->vertices[ t->vertexIndices[ 2 ] ].normal[ 1 ] );
911 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 2 ] ].s / ( float ) model->header.skinWidth,
912 					   ( float ) model->texCoords[ t->textureIndices[ 2 ] ].t / ( float ) model->header.skinHeight );
913 		glVertex3f ( f->vertices[ t->vertexIndices[ 2 ] ].vertex[ 0 ],
914 					 f->vertices[ t->vertexIndices[ 2 ] ].vertex[ 1 ],
915 					 f->vertices[ t->vertexIndices[ 2 ] ].vertex[ 2 ] );
916 	}
917 	glEnd ();
918 }
919 
920 
921 /*
922  * draw interpolated
923  *
924  */
925 void
926 Md2_Object::_md2_drawModeli ( int frame1, int frame2, float pol ) {
927 	int i;
928 
929 	md2_frame_t *f1 = &model->frames[ frame1 ];
930 	md2_frame_t *f2 = &model->frames[ frame2 ];
931 
932 	glBegin ( GL_TRIANGLES );
933 
934 	for ( i = 0; i < model->header.numTriangles; i++ ) {
935 		md2_triangle_t *t = &model->triangles[ i ];
936 		//int lightNormalIndex1, lightNormalIndex2;
937 		float x1, y1, z1, x2, y2, z2;
938 		float *n1, *n2;
939 
940 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 0 ] ].s / ( float ) model->header.skinWidth,
941 					   ( float ) model->texCoords[ t->textureIndices[ 0 ] ].t / ( float ) model->header.skinHeight );
942 		/*
943 				lightNormalIndex1 = f1->vertices[t->vertexIndices[0]].lightNormalIndex;
944 				lightNormalIndex2 = f2->vertices[t->vertexIndices[0]].lightNormalIndex;
945 				glNormal3f ((1.0f - pol) * avertexnormals[lightNormalIndex1][0] + pol * avertexnormals[lightNormalIndex2][0],
946 					(1.0f - pol) * avertexnormals[lightNormalIndex1][2] + pol * avertexnormals[lightNormalIndex2][2],
947 					(1.0f - pol) * -avertexnormals[lightNormalIndex1][1] + pol * -avertexnormals[lightNormalIndex2][1]);
948 		*/
949 		n1 = f1->vertices[ t->vertexIndices[ 0 ] ].normal;
950 		n2 = f2->vertices[ t->vertexIndices[ 0 ] ].normal;
951 		glNormal3f ( ( 1.0f - pol ) * n1[ 0 ] + pol * n2[ 0 ],
952 					 ( 1.0f - pol ) * n1[ 2 ] + pol * n2[ 2 ],
953 					 ( 1.0f - pol ) * -n1[ 1 ] + pol * -n2[ 1 ] );
954 
955 		x1 = f1->vertices[ t->vertexIndices[ 0 ] ].vertex[ 0 ];
956 		y1 = f1->vertices[ t->vertexIndices[ 0 ] ].vertex[ 1 ];
957 		z1 = f1->vertices[ t->vertexIndices[ 0 ] ].vertex[ 2 ];
958 		x2 = f2->vertices[ t->vertexIndices[ 0 ] ].vertex[ 0 ];
959 		y2 = f2->vertices[ t->vertexIndices[ 0 ] ].vertex[ 1 ];
960 		z2 = f2->vertices[ t->vertexIndices[ 0 ] ].vertex[ 2 ];
961 		glVertex3f ( x1 + pol * ( x2 - x1 ),
962 					 y1 + pol * ( y2 - y1 ),
963 					 z1 + pol * ( z2 - z1 ) );
964 
965 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 1 ] ].s / ( float ) model->header.skinWidth,
966 					   ( float ) model->texCoords[ t->textureIndices[ 1 ] ].t / ( float ) model->header.skinHeight );
967 		/*
968 				lightNormalIndex1 = f1->vertices[t->vertexIndices[1]].lightNormalIndex;
969 				lightNormalIndex2 = f2->vertices[t->vertexIndices[1]].lightNormalIndex;
970 				glNormal3f ((1.0f - pol) * avertexnormals[lightNormalIndex1][0] + pol * avertexnormals[lightNormalIndex2][0],
971 					(1.0f - pol) * avertexnormals[lightNormalIndex1][2] + pol * avertexnormals[lightNormalIndex2][2],
972 					(1.0f - pol) * -avertexnormals[lightNormalIndex1][1] + pol * -avertexnormals[lightNormalIndex2][1]);
973 		*/
974 		n1 = f1->vertices[ t->vertexIndices[ 1 ] ].normal;
975 		n2 = f2->vertices[ t->vertexIndices[ 1 ] ].normal;
976 		glNormal3f ( ( 1.0f - pol ) * n1[ 0 ] + pol * n2[ 0 ],
977 					 ( 1.0f - pol ) * n1[ 2 ] + pol * n2[ 2 ],
978 					 ( 1.0f - pol ) * -n1[ 1 ] + pol * -n2[ 1 ] );
979 
980 		x1 = f1->vertices[ t->vertexIndices[ 1 ] ].vertex[ 0 ];
981 		y1 = f1->vertices[ t->vertexIndices[ 1 ] ].vertex[ 1 ];
982 		z1 = f1->vertices[ t->vertexIndices[ 1 ] ].vertex[ 2 ];
983 		x2 = f2->vertices[ t->vertexIndices[ 1 ] ].vertex[ 0 ];
984 		y2 = f2->vertices[ t->vertexIndices[ 1 ] ].vertex[ 1 ];
985 		z2 = f2->vertices[ t->vertexIndices[ 1 ] ].vertex[ 2 ];
986 		glVertex3f ( x1 + pol * ( x2 - x1 ),
987 					 y1 + pol * ( y2 - y1 ),
988 					 z1 + pol * ( z2 - z1 ) );
989 
990 		glTexCoord2f ( ( float ) model->texCoords[ t->textureIndices[ 2 ] ].s / ( float ) model->header.skinWidth,
991 					   ( float ) model->texCoords[ t->textureIndices[ 2 ] ].t / ( float ) model->header.skinHeight );
992 		/*
993 				lightNormalIndex1 = f1->vertices[t->vertexIndices[2]].lightNormalIndex;
994 				lightNormalIndex2 = f2->vertices[t->vertexIndices[2]].lightNormalIndex;
995 				glNormal3f ((1.0f - pol) * avertexnormals[lightNormalIndex1][0] + pol * avertexnormals[lightNormalIndex2][0],
996 					(1.0f - pol) * avertexnormals[lightNormalIndex1][2] + pol * avertexnormals[lightNormalIndex2][2],
997 					(1.0f - pol) * -avertexnormals[lightNormalIndex1][1] + pol * -avertexnormals[lightNormalIndex2][1]);
998 		*/
999 		n1 = f1->vertices[ t->vertexIndices[ 2 ] ].normal;
1000 		n2 = f2->vertices[ t->vertexIndices[ 2 ] ].normal;
1001 		glNormal3f ( ( 1.0f - pol ) * n1[ 0 ] + pol * n2[ 0 ],
1002 					 ( 1.0f - pol ) * n1[ 2 ] + pol * n2[ 2 ],
1003 					 ( 1.0f - pol ) * -n1[ 1 ] + pol * -n2[ 1 ] );
1004 
1005 		x1 = f1->vertices[ t->vertexIndices[ 2 ] ].vertex[ 0 ];
1006 		y1 = f1->vertices[ t->vertexIndices[ 2 ] ].vertex[ 1 ];
1007 		z1 = f1->vertices[ t->vertexIndices[ 2 ] ].vertex[ 2 ];
1008 		x2 = f2->vertices[ t->vertexIndices[ 2 ] ].vertex[ 0 ];
1009 		y2 = f2->vertices[ t->vertexIndices[ 2 ] ].vertex[ 1 ];
1010 		z2 = f2->vertices[ t->vertexIndices[ 2 ] ].vertex[ 2 ];
1011 		glVertex3f ( x1 + pol * ( x2 - x1 ),
1012 					 y1 + pol * ( y2 - y1 ),
1013 					 z1 + pol * ( z2 - z1 ) );
1014 	}
1015 	glEnd ();
1016 }
1017 
1018 
1019 
1020 /*
1021  * draw with glcommands
1022  *
1023  */
1024 void
1025 Md2_Object::_md2_drawModelg ( int frame ) {
1026 	int i = 0;
1027 	int val = model->glCommandBuffer[ i++ ];
1028 
1029 	while ( val != 0 ) {
1030 		int count;
1031 
1032 		if ( val > 0 ) {
1033 			glBegin ( GL_TRIANGLE_STRIP );
1034 			count = val;
1035 		} else {
1036 			glBegin ( GL_TRIANGLE_FAN );
1037 			count = -val;
1038 		}
1039 
1040 		while ( count-- ) {
1041 			float s = *( float * ) & model->glCommandBuffer[ i++ ];
1042 			float t = *( float * ) & model->glCommandBuffer[ i++ ];
1043 			int index = model->glCommandBuffer[ i++ ];
1044 			//int lightNormalIndex = model->frames[frame].vertices[index].lightNormalIndex;
1045 
1046 			glTexCoord2f ( s, t );
1047 			/*
1048 						glNormal3f (avertexnormals[lightNormalIndex][0],
1049 							avertexnormals[lightNormalIndex][2],
1050 							-avertexnormals[lightNormalIndex][1]);
1051 			*/
1052 			glNormal3f ( model->frames[ frame ].vertices[ index ].normal[ 0 ],
1053 						 model->frames[ frame ].vertices[ index ].normal[ 2 ],
1054 						 -model->frames[ frame ].vertices[ index ].normal[ 1 ] );
1055 			glVertex3f ( model->frames[ frame ].vertices[ index ].vertex[ 0 ],
1056 						 model->frames[ frame ].vertices[ index ].vertex[ 1 ],
1057 						 model->frames[ frame ].vertices[ index ].vertex[ 2 ] );
1058 		}
1059 
1060 		glEnd ();
1061 
1062 		val = model->glCommandBuffer[ i++ ];
1063 	}
1064 }
1065 
1066 
1067 
1068 /*
1069  * draw with glcommands, interpolated
1070  *
1071  */
1072 void
1073 Md2_Object::_md2_drawModelgi ( int frame1, int frame2, float pol ) {
1074 	int i = 0;
1075 	int val = model->glCommandBuffer[ i++ ];
1076 
1077 	while ( val != 0 ) {
1078 		int count;
1079 
1080 		if ( val > 0 ) {
1081 			glBegin ( GL_TRIANGLE_STRIP );
1082 			count = val;
1083 		} else {
1084 			glBegin ( GL_TRIANGLE_FAN );
1085 			count = -val;
1086 		}
1087 
1088 		while ( count-- ) {
1089 			float s = *( float * ) & model->glCommandBuffer[ i++ ];
1090 			float t = *( float * ) & model->glCommandBuffer[ i++ ];
1091 			int index = model->glCommandBuffer[ i++ ];
1092 			//int lightNormalIndex1 = model->frames[frame1].vertices[index].lightNormalIndex;
1093 			//int lightNormalIndex2 = model->frames[frame2].vertices[index].lightNormalIndex;
1094 			float x1, y1, z1, x2, y2, z2;
1095 			float *n1 = model->frames[ frame1 ].vertices[ index ].normal;
1096 			float *n2 = model->frames[ frame2 ].vertices[ index ].normal;
1097 
1098 			/* texcoords don't need to be interpolated */
1099 			glTexCoord2f ( s, t );
1100 
1101 			/* interpolate light normal */
1102 			/*
1103 						glNormal3f ((1.0f - pol) * avertexnormals[lightNormalIndex1][0] + pol * avertexnormals[lightNormalIndex2][0],
1104 							(1.0f - pol) * avertexnormals[lightNormalIndex1][2] + pol * avertexnormals[lightNormalIndex2][2],
1105 							(1.0f - pol) * -avertexnormals[lightNormalIndex1][1] + pol * -avertexnormals[lightNormalIndex2][1]);
1106 			*/
1107 			glNormal3f ( ( 1.0f - pol ) * n1[ 0 ] + pol * n2[ 0 ],
1108 						 ( 1.0f - pol ) * n1[ 2 ] + pol * n2[ 2 ],
1109 						 ( 1.0f - pol ) * -n1[ 1 ] + pol * -n2[ 1 ] );
1110 
1111 			/* interpolate vertices */
1112 			x1 = model->frames[ frame1 ].vertices[ index ].vertex[ 0 ];
1113 			y1 = model->frames[ frame1 ].vertices[ index ].vertex[ 1 ];
1114 			z1 = model->frames[ frame1 ].vertices[ index ].vertex[ 2 ];
1115 
1116 			x2 = model->frames[ frame2 ].vertices[ index ].vertex[ 0 ];
1117 			y2 = model->frames[ frame2 ].vertices[ index ].vertex[ 1 ];
1118 			z2 = model->frames[ frame2 ].vertices[ index ].vertex[ 2 ];
1119 
1120 			glVertex3f ( x1 + pol * ( x2 - x1 ),
1121 						 y1 + pol * ( y2 - y1 ),
1122 						 z1 + pol * ( z2 - z1 ) );
1123 		}
1124 
1125 		glEnd ();
1126 
1127 		val = model->glCommandBuffer[ i++ ];
1128 	}
1129 }
1130 
1131 
1132 /*
1133  * draw model
1134  */
1135 void
1136 Md2_Object::md2_drawModel ( int frame1, int frame2, float pol ) {
1137 	if ( g_glcmds ) {
1138 		if ( g_interp )
1139 			_md2_drawModelgi ( frame1, frame2, pol );
1140 		else
1141 			_md2_drawModelg ( frame1 );
1142 	} else {
1143 		if ( g_interp )
1144 			_md2_drawModeli ( frame1, frame2, pol );
1145 		else
1146 			_md2_drawModel ( frame1 );
1147 	}
1148 }
1149 
1150 #endif
1151 
1152 
1153 
1154 
1155 
1156