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