00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "jed_defs.h"
00023 #include "toolkits/util/md2load.h"
00024 #include "lista.cc"
00025
00026 #include <string.h>
00027
00028 static void
00029 leer_bytes(FILE *f, void *buffer, int count) { fread (buffer, 1, count, f); }
00030
00031 #define MAX_TRIANGLES 4096
00032 #define MAX_VERTS 2048
00033 #define MAX_FRAMES 512
00034 #define MAX_SKINNAME 64
00035
00036
00037
00038
00039
00040 class COORDENADA_PIEL_MD2 {
00041 public:
00042 WORD s;
00043 WORD t;
00044 };
00045
00046 class POLIGONO_MD2
00047 {
00048 public:
00049 WORD index_xyz[3];
00050 WORD index_st[3];
00051 };
00052
00053 class N_MD2
00054 {
00055 public:
00056 BYTE v[3];
00057 BYTE lightnormalindex;
00058 };
00059
00060 class FRAME_ALIAS
00061 {
00062 public:
00063 float scale[3];
00064 float translate[3];
00065 char name[16];
00066 N_MD2 verts[1];
00067 };
00068
00069 class ENCABEZADO_MD2
00070 {
00071 public:
00072 DWORD id_md2;
00073 DWORD version;
00074 DWORD piel_xtam;
00075 DWORD piel_ytam;
00076 DWORD framesize;
00077 DWORD num_pieles;
00078 DWORD num_vertices;
00079 DWORD _num_st;
00080 DWORD num_triangulos;
00081 DWORD _num_glcmds;
00082 DWORD num_frames;
00083 DWORD ofs_skins;
00084 DWORD ofs_st;
00085 DWORD ofs_tris;
00086 DWORD ofs_frames;
00087 DWORD ofs_glcmds;
00088 DWORD ofs_end;
00089 };
00090
00091
00092
00093
00094
00095 LECTOR_QUAKE_MD2::LECTOR_QUAKE_MD2()
00104 {
00105 triangulos_arr = NULL;
00106 frames_arr = NULL;
00107 _num_frames = 0;
00108 _num_vertices = 0;
00109 _num_triangulos = 0;
00110 _nombre_piel = NULL;
00111 Piel = NULL;
00112 }
00113
00114 LECTOR_QUAKE_MD2::~LECTOR_QUAKE_MD2()
00115 {
00116 elim();
00117 }
00118
00119 void
00120 LECTOR_QUAKE_MD2::elim(void)
00121 {
00122 DWORD i;
00123
00124 if ( frames_arr ) {
00125 for ( i = 0; i < _num_frames; i++ ) delete frames_arr[i].arr_vertices;
00126 delete frames_arr;
00127 frames_arr = NULL;
00128 }
00129 if ( triangulos_arr ) {
00130 delete triangulos_arr;
00131 triangulos_arr = NULL;
00132 }
00133 if ( _nombre_piel ) {
00134 delete _nombre_piel;
00135 _nombre_piel = NULL;
00136 }
00137
00138 }
00139
00140 BOOLEAN
00141 LECTOR_QUAKE_MD2::leer(char *archivo_md2, char *archivo_piel,
00142 double factor_gamma)
00150 {
00151
00152 FILE *fd = fopen(archivo_piel, "rb");
00153 if ( !fd ) {
00154 fprintf(stderr,"<LECTOR_QUAKE_MD2> ERROR: no puedo abrir el archivo %s!\n",
00155 archivo_piel);
00156 fflush(stderr);
00157 return FALSE;
00158 }
00159 Piel = new IMAGEN_RGB();
00160 if ( !Piel || !Piel->importar_pcx(fd) ) {
00161 fprintf(stderr,"ERROR Abriendo la imagen.\n"); fflush(stderr);
00162 exit(1);
00163 }
00164
00165 BYTE funcion_gamma[256];
00166
00167 calcular_funcion_gamma(funcion_gamma, factor_gamma);
00168 Piel->aplicar_correccion_gamma(funcion_gamma);
00169
00170 _nombre_piel = new char[strlen(archivo_piel)+1];
00171 strcpy(_nombre_piel, archivo_piel);
00172
00173
00174 ENCABEZADO_MD2 encabezado;
00175
00176 fd = fopen (archivo_md2, "rb");
00177 if ( !fd ) {
00178 fprintf(stderr,"<LECTOR_QUAKE_MD2> ERROR: No puedo abrir el archivo %s!\n",
00179 archivo_md2);
00180 fflush(stderr);
00181 return FALSE;
00182 }
00183
00184 lea_DWORD_BE(&encabezado.id_md2, fd);
00185 lea_DWORD_BE(&encabezado.version, fd);
00186 lea_DWORD_BE(&encabezado.piel_xtam, fd);
00187 lea_DWORD_BE(&encabezado.piel_ytam, fd);
00188 lea_DWORD_BE(&encabezado.framesize, fd);
00189 lea_DWORD_BE(&encabezado.num_pieles, fd);
00190 lea_DWORD_BE(&encabezado.num_vertices, fd);
00191 lea_DWORD_BE(&encabezado._num_st, fd);
00192 lea_DWORD_BE(&encabezado.num_triangulos, fd);
00193 lea_DWORD_BE(&encabezado._num_glcmds, fd);
00194 lea_DWORD_BE(&encabezado.num_frames, fd);
00195 lea_DWORD_BE(&encabezado.ofs_skins, fd);
00196 lea_DWORD_BE(&encabezado.ofs_st, fd);
00197 lea_DWORD_BE(&encabezado.ofs_tris, fd);
00198 lea_DWORD_BE(&encabezado.ofs_frames, fd);
00199 lea_DWORD_BE(&encabezado.ofs_glcmds, fd)
00200 lea_DWORD_BE(&encabezado.ofs_end, fd);
00201
00202
00203 DWORD i, j;
00204
00205 _num_frames = encabezado.num_frames;
00206 _num_vertices = encabezado.num_vertices;
00207 _num_triangulos = encabezado.num_triangulos;
00208 triangulos_arr = new TRIANGULO_QUAKE [_num_triangulos];
00209 frames_arr = new CONFIGURACION_MESH [_num_frames];
00210
00211 for ( i = 0; i < _num_frames; i++ ) {
00212 frames_arr[i].arr_vertices = new VERTICE_GL[_num_vertices];
00213 }
00214
00215
00216 char *nombres_pieles;
00217 COORDENADA_PIEL_MD2 *puntos_uv =
00218 new COORDENADA_PIEL_MD2[encabezado._num_st];
00219 POLIGONO_MD2 tri;
00220
00221 nombres_pieles = new char [encabezado.num_pieles * MAX_SKINNAME];
00222 leer_bytes(fd, nombres_pieles, encabezado.num_pieles * MAX_SKINNAME);
00223 for ( i = 0; i < encabezado._num_st; i++ ) {
00224 lea_WORD_BE(&puntos_uv[i].s, fd);
00225 lea_WORD_BE(&puntos_uv[i].t, fd);
00226 }
00227
00228 for ( i = 0; i < _num_triangulos; i++ ) {
00229 lea_WORD_BE(&tri.index_xyz[0], fd);
00230 lea_WORD_BE(&tri.index_xyz[1], fd);
00231 lea_WORD_BE(&tri.index_xyz[2], fd);
00232 lea_WORD_BE(&tri.index_st[0], fd);
00233 lea_WORD_BE(&tri.index_st[1], fd);
00234 lea_WORD_BE(&tri.index_st[2], fd);
00235 triangulos_arr[i].p0 = tri.index_xyz[2];
00236 triangulos_arr[i].p1 = tri.index_xyz[1];
00237 triangulos_arr[i].p2 = tri.index_xyz[0];
00238 triangulos_arr[i].a_s = puntos_uv[tri.index_st[2]].s;
00239 triangulos_arr[i].a_t = puntos_uv[tri.index_st[2]].t;
00240 triangulos_arr[i].b_s = puntos_uv[tri.index_st[1]].s;
00241 triangulos_arr[i].b_t = puntos_uv[tri.index_st[1]].t;
00242 triangulos_arr[i].c_s = puntos_uv[tri.index_st[0]].s;
00243 triangulos_arr[i].c_t = puntos_uv[tri.index_st[0]].t;
00244 }
00245 delete puntos_uv;
00246 delete nombres_pieles;
00247
00248
00249 BYTE buffer[MAX_VERTS*4+128];
00250 FRAME_ALIAS *out;
00251
00252 for ( i = 0; i < _num_frames; i++ ) {
00253 out = (FRAME_ALIAS *)buffer;
00254 leer_bytes(fd, out, encabezado.framesize);
00255 for ( j = 0; j < _num_vertices; j++ ) {
00256 frames_arr[i].arr_vertices[j].x =
00257 out->verts[j].v[0] * out->scale[0] + out->translate[0];
00258 frames_arr[i].arr_vertices[j].y =
00259 out->verts[j].v[1] * out->scale[1] + out->translate[1];
00260 frames_arr[i].arr_vertices[j].z =
00261 out->verts[j].v[2] * out->scale[2] + out->translate[2];
00262 frames_arr[i].arr_vertices[j].u = -INFINITO;
00263 frames_arr[i].arr_vertices[j].v = -INFINITO;
00264 }
00265 }
00266 fclose (fd);
00267
00268 return TRUE;
00269 }
00270
00271 void
00272 LECTOR_QUAKE_MD2::init(BOOLEAN suavizar_normales)
00278 {
00279 DWORD i, j;
00280 VERTICE_GL *Geometria_nueva, *Consulta;
00281 long int tam_consulta;
00282
00283 printf("<LECTOR_QUAKE_MD2> Preprocesando %ld cuadros:\n[", _num_frames);
00284 fflush(stdout);
00285 for ( i = 0; i < _num_frames; i++ ) {
00286 printf("."); fflush(stdout);
00287 MESH *Tmp = exportar_MESH(i);
00288
00289 Tmp->get_vertices(&Consulta, &tam_consulta);
00290 actualizar_vertices(Consulta, tam_consulta, i);
00291 Tmp->init();
00292 if ( suavizar_normales ) Tmp->promediar_normales_vertice();
00293
00294
00295 Geometria_nueva = new VERTICE_GL[_num_triangulos * 3];
00296 for ( j = 0;
00297 j < (DWORD)tam_consulta && j < _num_triangulos * 3; j++ ) {
00298 Geometria_nueva[j] = Consulta[j];
00299 }
00300 geometrias_preprocesadas.anx(Geometria_nueva);
00301 delete Tmp;
00302 }
00303 printf("]\nOk!\n"); fflush(stdout);
00304
00305 }
00306
00307 DWORD LECTOR_QUAKE_MD2::num_frames(void) {return _num_frames;}
00308 DWORD LECTOR_QUAKE_MD2::num_vertices(void) {return _num_vertices;}
00309 DWORD LECTOR_QUAKE_MD2::num_triangulos(void){return _num_triangulos;}
00310
00311 #ifdef NONONO
00312 void
00313 LECTOR_QUAKE_MD2::pintar_gl(DWORD frame)
00318 {
00319 if ( frame >= _num_frames || frame < 0 ) return;
00320
00321
00322 static float modo_repetir[] = {GL_CLAMP};
00323 static GLfloat f_combinar[] = {GL_MODULATE};
00324 static GLfloat f_interpolar[] = {GL_LINEAR};
00325
00326 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, modo_repetir);
00327 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, modo_repetir);
00328 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, f_combinar);
00329 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f_interpolar);
00330 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f_interpolar);
00331 Piel->activar_gl();
00332 glEnable(GL_TEXTURE_2D);
00333
00334
00335 glScaled(0.05, 0.05, 0.05);
00336 glDisable(GL_LIGHTING);
00337 glColor3d(1, 1, 1);
00338
00339
00340 DWORD i;
00341
00342 for ( i = 0; i < _num_triangulos; i++ ) {
00343 glBegin(GL_TRIANGLES);
00344 glTexCoord2f((triangulos_arr[i].a_s)/(float)Piel->xtam(),
00345 (triangulos_arr[i].a_t)/(float)Piel->ytam());
00346 glVertex3f(frames_arr[frame].arr_vertices[triangulos_arr[i].p0].x,
00347 frames_arr[frame].arr_vertices[triangulos_arr[i].p0].y,
00348 frames_arr[frame].arr_vertices[triangulos_arr[i].p0].z);
00349 glTexCoord2f((triangulos_arr[i].b_s)/(float)Piel->xtam(),
00350 (triangulos_arr[i].b_t)/(float)Piel->ytam());
00351 glVertex3f(frames_arr[frame].arr_vertices[triangulos_arr[i].p1].x,
00352 frames_arr[frame].arr_vertices[triangulos_arr[i].p1].y,
00353 frames_arr[frame].arr_vertices[triangulos_arr[i].p1].z);
00354 glTexCoord2f((triangulos_arr[i].c_s)/(float)Piel->xtam(),
00355 (triangulos_arr[i].c_t)/(float)Piel->ytam());
00356 glVertex3f(frames_arr[frame].arr_vertices[triangulos_arr[i].p2].x,
00357 frames_arr[frame].arr_vertices[triangulos_arr[i].p2].y,
00358 frames_arr[frame].arr_vertices[triangulos_arr[i].p2].z);
00359 glEnd();
00360 }
00361
00362 glDisable(GL_TEXTURE_2D);
00363 }
00364 #endif
00365
00366
00367
00368 void
00369 LECTOR_QUAKE_MD2::actualizar_vertices(VERTICE_GL *V,
00370 long int , int cuadro)
00386 {
00387 WORD i;
00388 int j;
00389
00390 for ( i = 0, j = 0; i < (WORD)_num_triangulos; i++ ) {
00391 V[j] =
00392 frames_arr[cuadro].arr_vertices[triangulos_arr[i].p0];
00393 V[j].u = triangulos_arr[i].a_s / (float)Piel->xtam();
00394 V[j].v = triangulos_arr[i].a_t / (float)Piel->ytam();
00395 j++;
00396
00397 V[j] =
00398 frames_arr[cuadro].arr_vertices[triangulos_arr[i].p1];
00399 V[j].u = triangulos_arr[i].b_s / (float)Piel->xtam();
00400 V[j].v = triangulos_arr[i].b_t / (float)Piel->ytam();
00401 j++;
00402
00403 V[j] =
00404 frames_arr[cuadro].arr_vertices[triangulos_arr[i].p2];
00405 V[j].u = triangulos_arr[i].c_s / (float)Piel->xtam();
00406 V[j].v = triangulos_arr[i].c_t / (float)Piel->ytam();
00407 j++;
00408 }
00409 }
00410
00411 void
00412 LECTOR_QUAKE_MD2::actualizar_vertices_rapido(VERTICE_GL *V,
00413 long int , int cuadro)
00423 {
00424 WORD i;
00425
00426 if ( !geometrias_preprocesadas.tam() ) {
00427 fprintf(stderr, "<LECTOR_QUAKE_MD2> ERROR: Debe llamarse init() "
00428 "antes de usar actualizar_vertices_rapido.\n");
00429 fflush(stderr);
00430 return;
00431 }
00432
00433 VERTICE_GL *O = geometrias_preprocesadas[cuadro];
00434
00435 for ( i = 0; i < (WORD)_num_triangulos * 3; i++ ) {
00436 V[i] = O[i];
00437 }
00438 }
00439
00440 #define INTERPOLAR_VARIABLE(v, vi, vf, f, t) \
00441 ( v = (float)(vi + ((double)f) * ( (vf - vi) / ((double)t) )) )
00442
00443 void
00444 interpolar_vertice(VERTICE_GL *D, VERTICE_GL *Oi,
00445 VERTICE_GL *Of, int f, int t)
00453 {
00454 INTERPOLAR_VARIABLE(D->x, Oi->x, Of->x, f, t);
00455 INTERPOLAR_VARIABLE(D->y, Oi->y, Of->y, f, t);
00456 INTERPOLAR_VARIABLE(D->z, Oi->z, Of->z, f, t);
00457 INTERPOLAR_VARIABLE(D->nx, Oi->nx, Of->nx, f, t);
00458 INTERPOLAR_VARIABLE(D->ny, Oi->ny, Of->ny, f, t);
00459 INTERPOLAR_VARIABLE(D->nz, Oi->nz, Of->nz, f, t);
00460 D->u = Oi->u;
00461 D->v = Oi->v;
00462 }
00463
00464 void
00465 LECTOR_QUAKE_MD2::actualizar_vertices_rapido_i(VERTICE_GL *V,
00466 long int , int cuadro,
00467 int cuadroi, int cuadrof,
00468 int frame, int tam)
00473 {
00474 WORD i;
00475
00476 if ( !geometrias_preprocesadas.tam() ) {
00477 fprintf(stderr, "<LECTOR_QUAKE_MD2> ERROR: Debe llamarse init() "
00478 "antes de usar actualizar_vertices_rapido.\n");
00479 fflush(stderr);
00480 return;
00481 }
00482
00483 VERTICE_GL O, *Oi, *Of;
00484 int elcuadro = cuadro+1;
00485
00486 if ( elcuadro > cuadrof ) {
00487 elcuadro = cuadroi;
00488 }
00489
00490 Oi = geometrias_preprocesadas[cuadro];
00491 Of = geometrias_preprocesadas[elcuadro];
00492
00493 for ( i = 0; i < (WORD)_num_triangulos * 3; i++ ) {
00494 interpolar_vertice(&O, &Oi[i], &Of[i], frame, tam);
00495 V[i] = O;
00496 }
00497 }
00498
00499 MESH *
00500 LECTOR_QUAKE_MD2::exportar_MESH(int cuadro)
00525 {
00526 WORD i;
00527
00528
00529
00530
00531 VERTICE_GL *Copia_vertices = new VERTICE_GL[_num_triangulos * 3];
00532 TRIANGULO_GL *Copia_triangulos = new TRIANGULO_GL[_num_triangulos];
00533
00534 int j;
00535
00536 for ( i = 0, j = 0; i < (WORD)_num_triangulos; i++ ) {
00537 Copia_triangulos[i].p0 = j; j++;
00538 Copia_triangulos[i].p1 = j; j++;
00539 Copia_triangulos[i].p2 = j; j++;
00540 }
00541
00542
00543 actualizar_vertices(Copia_vertices, _num_triangulos*3, cuadro);
00544
00545
00546 MESH *G = new MESH(181 , FALSE, TRUE, 0.05);
00547
00548
00549 COLOR ambient, diffuse, specular;
00550
00551 ambient.r = ambient.g = ambient.b = 0.2f;
00552 diffuse.r = 0.85f; diffuse.g = 0.85f; diffuse.b = 0.1f;
00553 specular.r = specular.g = specular.b = 1.0;
00554 ambient.alpha = diffuse.alpha = specular.alpha = 1.0;
00555 G->anx_material(ambient, diffuse, specular, "WG_DEFAULT", "", 1);
00556
00557
00558 VERTICE_GL v;
00559
00560 for ( i = 0; i < (WORD)_num_triangulos*3; i++ ) {
00561 v.x = Copia_vertices[i].x;
00562 v.y = Copia_vertices[i].y;
00563 v.z = Copia_vertices[i].z;
00564 v.u = Copia_vertices[i].u;
00565 v.v = Copia_vertices[i].v;
00566 G->anx_vertex(v);
00567 }
00568
00569 for ( i = 0; i < (WORD)_num_triangulos; i++ ) {
00570 G->anx_triangle(Copia_triangulos[i], "WG_DEFAULT");
00571 }
00572
00573
00574 G->anexar_textura(Piel);
00575
00576
00577 delete Copia_vertices;
00578 Copia_vertices = NULL;
00579 delete Copia_triangulos;
00580 Copia_triangulos = NULL;
00581 G->set_material_global(TRUE);
00582 return G;
00583 }
00584
00585
00586
00587
00588
00589