Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

3dsload.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= 3dsload.h                         Septiembre de 1998, noviembre de 1999 =
00003 //=-------------------------------------------------------------------------=
00004 //= Sistema de lectura de archivos binarios en formato Autodesk-3DS.        =
00005 //=-------------------------------------------------------------------------=
00006 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00007 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00008 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00009 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00010 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00011 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00012 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00013 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00014 //=-------------------------------------------------------------------------=
00015 //= Codigo original:                                                        =
00016 //=  3D Studio object reader by David Farrell, fdavid@cyberramp.net         =
00017 //= Modificado por Oscar J. Chavarro G.            oscarchavarro@hotmail.co =
00018 //===========================================================================
00019 
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include "toolkits/util/3dsload.h"
00024 #include "matriz4.h"
00025 #include "arreglo.cc"
00026 
00027 //===========================================================================
00028 //= Constantes y macros                                                     =
00029 //===========================================================================
00030 
00031 //#define DEBUG_3DS 1
00032 
00033 #define COMPARAR_MM()                           \
00034         if ( v.x < min.x ) min.x = v.x;       \
00035         if ( v.y < min.y ) min.y = v.y;       \
00036         if ( v.z < min.z ) min.z = v.z;       \
00037         if ( v.x > max.x ) max.x = v.x;       \
00038         if ( v.y > max.y ) max.y = v.y;       \
00039         if ( v.z > max.z ) max.z = v.z;
00040 
00041 #define ADVERTIR_FALLAS()                                                 \
00042     if ( Scene->flag_material_por_defecto ) {                             \
00043 printf("\n");                                                             \
00044 printf("WARNING: This model uses default materials. 3D Studio saves no\n" \
00045 "       information about default materials, so View3DS substitutes\n"    \
00046 "       an all-white material in its place. Therefore, some of the\n"     \
00047 "       model may appear as bright white. To fix this, name each\n"       \
00048 "       material in 3D Studio.\n");                                       \
00049     }                                                                     \
00050     if ( Scene->flag_caras_dobles ) {                                     \
00051 printf("\n");                                                             \
00052 printf("WARNING: This model contains double-sided polygons.\n"            \
00053 "         The number of triangles in this model has now\n"                \
00054 "         DOUBLED. If possible, re-do the model in\n"                     \
00055 "         3D Studio without double-sided materials.\n"                    \
00056 "         Use a normal threshold of at least 90.\n"                       \
00057 "         Also, stripification will not work properly.\n");               \
00058     }                                                                     \
00059     printf("\n");
00060 
00061 #define VERIFICAR(p)                                                    \
00062     if ( !(p) ) {                                                       \
00063         fprintf(stderr, "<ESCENA_3DS> ERROR Asignando memoria!\n");     \
00064         fflush(stderr);                                                 \
00065         exit(1);                                                        \
00066     }
00067 
00068 //===========================================================================
00069 //= Variables globales                                                      =
00070 //===========================================================================
00071 
00072 static char *  ULTIMO_archivo = NULL;
00073 
00074 //===========================================================================
00075 //= Funciones utilitarias                                                   =
00076 //===========================================================================
00077 
00078 static void
00079 dsetpos(DWORD pos, FILE *fd)
00083 {
00084     if( fseek(fd, (long)pos, SEEK_SET) != 0 ) {
00085         fprintf(stderr, "<3DS_LOAD> - ERROR FATAL posicionando dentro de\n"
00086                 "    \"%s\".", ULTIMO_archivo);
00087         fflush(stderr);
00088         exit(1);
00089     }
00090 }
00091 
00092 static DWORD
00093 dgetpos(FILE *fd)
00097 {
00098     long pos;
00099     if( (pos=ftell(fd)) == -1L ) {
00100         fprintf(stderr, "Error getting fileposition\n");
00101         fflush(stderr);
00102     }
00103 
00104     return (DWORD) pos;
00105 }
00106 
00107 //===========================================================================
00108 //= CLASE MESH_3DS                                                          =
00109 //===========================================================================
00110 
00111 MESH_3DS::MESH_3DS() /*: arr_jed(1)*/
00112 {
00113     // OJO: La idea era cambiar esto por arr_jed... pero NI IDEA de porque eso
00114     //      no canciona!... el tipo simplemente se muere!
00115     jed_arr = NULL;
00116     jed_tam = 0;
00117     con_matriz = FALSE;
00118 }
00119 
00120 
00121 void
00122 MESH_3DS::asignar_material_por_defecto(WORD nf)
00123 /* WG function*/
00124 {
00125     MATERIAL_ARR *binding;
00126     int n;
00127     unsigned long int nn;
00128 
00129     binding = anx_data();
00130 
00131     /* The material name is first */
00132     strcpy(binding->name, "WG_DEFAULT");
00133 
00134     /* Then the number of faces */
00135     nn = 0x0000FFFFL & (unsigned long int)nf;
00136     binding->NumFaces = (unsigned int)nn;
00137     binding->faces = new UWORD[(unsigned int)nn];
00138 
00139     /* Bind the faces to the material */
00140     for ( n = 0; n < nf; n++ ) {
00141         binding->faces[n] = (unsigned short)n; // OJO!
00142     }
00143 
00144   #ifdef DEBUG_3DS
00145     printf(" Read Material %s with %d faces\n", name, nf);
00146   #endif
00147 } 
00148 
00149 //= Metodos de lectura (leer_trozo_*) =======================================
00150 
00151 void
00152 MESH_3DS::leer_trozo_VERTLIST(void)
00156 {
00157     UWORD nv;
00158     unsigned int n;
00159 
00160     lea_WORD_BE(&nv, fd);
00161     vertices_tam = nv;
00162 
00163     vertices_arr = new VERTLIST_DATA[nv];
00164     VERIFICAR(vertices_arr);
00165     for( n = 0; n < nv; n++ ) {
00166         lea_FLOAT32_BE(&vertices_arr[n].x, fd);
00167         lea_FLOAT32_BE(&vertices_arr[n].y, fd);
00168         lea_FLOAT32_BE(&vertices_arr[n].z, fd);
00169     }
00170 
00171   #ifdef DEBUG_3DS
00172     printf("  - Read Vertex List with %d vertices\n", nv);
00173   #endif
00174 }
00175 
00176 WORD
00177 MESH_3DS::leer_trozo_FACELIST(void)
00182 {
00183     WORD nv;
00184     WORD swap;
00185     WORD n;
00186     DWORD mm;
00187 
00188     lea_WORD_BE(&nv, fd);
00189     mm = 0x0000FFFFL & (unsigned long int)nv;
00190     nv = (unsigned int)mm;
00191 
00192     NumFaces = (unsigned int)nv;
00193 
00194     /* OJO: nv es unsigned int, nunca va a ocurrir esto!
00195     if ( nv < 0 ) {
00196         fprintf(stderr, "<MESH_3DS> Error de representacion numerica.\n");
00197         fprintf(stderr, "  - La geometria deberia tener un numero positivo\n"
00198         "    de triangulos, pero la rutina de lectura entendio %ld.\n",
00199                 (long)nv);
00200         fflush(stderr);
00201         exit(-666);
00202     }
00203     */
00204 
00205     facelist = new FACELIST_DATA[nv];
00206     VERIFICAR(facelist);
00207     for( n = 0; n < nv; n++ ) {
00208         lea_WORD_BE(&facelist[n].p0, fd);
00209         lea_WORD_BE(&facelist[n].p1, fd);
00210         lea_WORD_BE(&facelist[n].p2, fd);
00211         lea_WORD_BE(&facelist[n].flags, fd);
00212         /* 0x07 means that the AB, BC, and CA edges are all wound 
00213          * in the reverse order, so swap the last two vertices */
00214         // OJO! Esta vaina no tiene sentido!
00215         /*
00216         La idea es que los 3 bits menos significativos de `flags` tienen
00217         las orientaciones de los lados AB, BC y CA del triangulo actual...
00218         si 3ds fuera decente, eso siempre seria 0x00 o en el peor de los
00219         casos 0x03, pero los demas casos... NO TIENEN SENTIDO!
00220         */
00221         if ( facelist[n].flags == 0x07 ) {
00222         //if ( (facelist[n].flags & 0x01) ) { // Esta condicion supone que la
00223                                             // orientacion del triangulo esta
00224                                             // dada por la orientacion de su
00225                                             // primer lado (AB). --> MAL!
00226             swap = facelist[n].p1;
00227             facelist[n].p1 = facelist[n].p2;
00228             facelist[n].p2 = swap;
00229         }
00230     }
00231 
00232   #ifdef DEBUG_3DS
00233     printf("  - Read Face List with %d faces\n", nv);
00234   #endif
00235 
00236     return nv; /* WG */
00237 }
00238 
00239 void
00240 MESH_3DS::leer_trozo_MAPLIST(void)
00241 /* Reads in the mapping list/texture coords. for the current mesh object */
00242 {
00243     unsigned int nv;
00244     unsigned int n;
00245     unsigned long int nn;
00246 
00247     lea_WORD_BE(&nv, fd);
00248     nn = 0x0000FFFFL & (unsigned long int)nv;
00249     nv = (unsigned int)nn;
00250     NumMaps=nv;
00251 
00252     maplist = new MAPLIST_DATA[nv];
00253     VERIFICAR(maplist);
00254     for(n=0; n<nv; n++) {
00255         lea_FLOAT32_BE(&maplist[n].u, fd);
00256         lea_FLOAT32_BE(&maplist[n].v, fd);
00257     }
00258 
00259   #ifdef DEBUG_3DS
00260     printf(" Read Map List with %d maps\n", nv);
00261   #endif
00262 }
00263 
00264 void
00265 MESH_3DS::leer_trozo_TRMATRIX(void)
00266 /*Reads in the translation matrix for the current mesh object.
00267   I'm not sure when this is used in a 3DS model. */
00268 {
00269     int i;
00270     for ( i = 0; i < 12; i++ ) {
00271         lea_FLOAT32_BE(&TraMatrix[i], fd);
00272     }
00273     con_matriz=TRUE;
00274 
00275   #ifdef DEBUG_3DS
00276     printf("  - Read Translation Matrix\n");
00277     printf("      %4.4f %4.4f %4.4f %4.4f\n",
00278            TraMatrix[0], TraMatrix[3], TraMatrix[6], TraMatrix[9]);
00279     printf("      %4.4f %4.4f %4.4f %4.4f\n",
00280            TraMatrix[1], TraMatrix[4], TraMatrix[7], TraMatrix[10]);
00281     printf("      %4.4f %4.4f %4.4f %4.4f\n",
00282            TraMatrix[2], TraMatrix[5], TraMatrix[8], TraMatrix[11]);
00283   #endif
00284 }
00285 
00286 void
00287 MESH_3DS::leer_trozo_FACEMAT(void)
00288 /*Assigns the material in this chunk to the faces specified. 
00289   Each material has a list of indexes into the face array to
00290   mark which faces use which material. */
00291 /* Changed word nf; word face; to uword's
00292  * Thanks to Eran Gottlieb */
00293 {
00294     UWORD nf;
00295     UWORD face;
00296     char name[50];
00297     MATERIAL_ARR *binding;
00298     int i;
00299 
00300     binding = anx_data();
00301 
00302     // Lea el nombre del material, es una cadena terminada en '\0'
00303     i = 0;
00304     do {
00305         lea_BYTE(&name[i++], fd);
00306     } while( name[i-1] != '\0' && i < (int)sizeof(name) );
00307     name[i-1]='\0';
00308     strcpy(binding->name, name);
00309 
00310     /* Then the number of faces */
00311     lea_WORD_BE(&nf, fd);
00312     binding->NumFaces = (unsigned int)nf;
00313     binding->faces = new UWORD[nf];
00314 
00315     /* Bind the faces to the material */
00316     for ( i = 0; i < nf; i++ ) {
00317         lea_WORD_BE(&face, fd);
00318         binding->faces[i] = face;
00319     }
00320 
00321   #ifdef DEBUG_3DS
00322     printf("  - Read Material \"%s\" with %d faces\n", name, nf);
00323   #endif
00324 } 
00325 
00326 //===========================================================================
00327 //= Funciones que leen trozos de nivel 4                                    =
00328 //= Los metodos de la clase MESH_3DS tambien manejan lecturas de nivel 4    =
00329 //===========================================================================
00330 
00331 void
00332 ESCENA_3DS::leer_trozo_MAPFILENAME(DWORD /*p*/, TEXTURE_DATA *texture)
00333 {
00334     int n;
00335     char name[MAXNAMESIZE];
00336 
00337     n = 0;
00338     do {
00339         lea_BYTE(&name[n++], fd);
00340     } while( name[n-1] != '\0' && n < (int)sizeof(name) );
00341     name[n-1]='\0';
00342   
00343     strcpy(texture->texturename, name);
00344 
00345   #ifdef DEBUG_3DS
00346     printf("  - Read Texture Name: %s\n", name);
00347   #endif
00348 }
00349 
00350 void
00351 ESCENA_3DS::leer_trozo_AMOUNT(WORD *amount)
00352 {
00353     WORD temp;
00354 
00355     lea_WORD_BE(&temp, fd);
00356     *amount = temp;
00357 }
00358 
00359 void
00360 ESCENA_3DS::leer_trozo_RGBByte(COLOR *rgb) 
00361 /* Reads in an RGB byte triplet */
00362 {
00363     BYTE red, green, blue;
00364 
00365     lea_BYTE(&red, fd);
00366     lea_BYTE(&green, fd);
00367     lea_BYTE(&blue, fd);
00368     rgb->r = (float)(red)/256.0f;
00369     rgb->g = (float)(green)/256.0f;
00370     rgb->b = (float)(blue)/256.0f;
00371 
00372   #ifdef DEBUG_3DS
00373     printf("  - Tripla RGB_BYTE: <%f, %f, %f>\n", rgb->r, rgb->g, rgb->b);
00374   #endif
00375 }
00376 
00377 void
00378 ESCENA_3DS::leer_trozo_RGBFloat(COLOR *rgb)
00379 /* Reads in an RGB FP triplet */
00380 {
00381     lea_FLOAT32_BE(&rgb->r, fd);
00382     lea_FLOAT32_BE(&rgb->g, fd);
00383     lea_FLOAT32_BE(&rgb->b, fd);
00384 
00385   #ifdef DEBUG_3DS
00386     printf("  - Tripla RGB_FLOAT: <%f, %f, %f>\n", rgb->r, rgb->g, rgb->b);
00387   #endif
00388 }
00389 
00390 //===========================================================================
00391 //= Funciones que leen trozos de nivel 3 - control de trozos de nivel 4     =
00392 //===========================================================================
00393 
00394 void
00395 ESCENA_3DS::leer_trozo_TEXTURE(DWORD p, TEXTURE_DATA *texture)
00396 {
00397     UWORD id;
00398     DWORD len, pc;
00399 
00400     while((pc=dgetpos(fd)) < p) {
00401         lea_WORD_BE(&id, fd);
00402         lea_DWORD_BE(&len, fd);
00403         switch((unsigned int)id) {
00404           case CHUNK3DS_MAPFILENAME: 
00405             leer_trozo_MAPFILENAME(pc+len, texture); 
00406             break;
00407           default: 
00408             dsetpos(pc+len, fd);
00409         }
00410     }
00411 }  
00412 
00413 void
00414 ESCENA_3DS::leer_trozo_TRANSPARENCY(DWORD p, FLOAT32 *alpha)
00415 /* I interpret the transparency information as the alpha
00416  * value for the entire material */
00417 {
00418     UWORD id;
00419     DWORD len, pc;
00420     WORD amount = 0;
00421 
00422     while((pc=dgetpos(fd)) < p) {
00423         lea_WORD_BE(&id, fd);
00424         lea_DWORD_BE(&len, fd);
00425         switch( (unsigned int)id ) {
00426           case CHUNK3DS_AMOUNT: leer_trozo_AMOUNT(&amount); break;
00427           default: dsetpos(pc+len, fd);
00428         }
00429     }
00430 
00431     (*alpha) = (FLOAT32)amount / 100.0f;
00432     if (*alpha < .01) (*alpha) = 1.0;
00433     else flag_alpha_blending = TRUE;
00434 
00435   #ifdef DEBUG_3DS
00436     printf("  - Canal Alpha (transparencia): %f\n", *alpha);
00437   #endif
00438 }
00439 
00440 void
00441 ESCENA_3DS::leer_trozo_DOUBLESIDED(int *material_doublesided)
00442 /*
00443  * I assume that if one material is doublesided, they all are,
00444  * so turn on a global doublesided flag
00445  */
00446 {
00447     *material_doublesided = 1;
00448     flag_caras_dobles = TRUE;
00449 
00450   #ifdef DEBUG_3DS
00451     printf(" Doublesided Material\n");
00452   #endif
00453 }
00454 
00455 void
00456 ESCENA_3DS::leer_trozo_MATNAME(DWORD /*p*/, MATERIAL_3DS *mat)
00457 /* Reads in the name of the material */
00458 {
00459     int n;
00460     char name[MAXNAMESIZE];
00461   
00462     n = 0;
00463     do {
00464         lea_BYTE(&name[n++], fd);
00465     } while( name[n-1] != '\0' && n < (int)sizeof(name) );
00466     name[n-1]='\0';
00467 
00468     strcpy(mat->name, name);
00469 
00470   #ifdef DEBUG_3DS
00471     printf("Leyendo el material \"%s\":\n", name);
00472   #endif
00473 }
00474 
00475 void
00476 ESCENA_3DS::leer_trozo_SHADING(DWORD p, COLOR *rgb)
00477 /* Reads in a color assignment */
00478 {
00479     UWORD id;
00480     DWORD len, pc;
00481 
00482     while( (pc = dgetpos(fd)) < p ) {
00483         lea_WORD_BE(&id, fd);
00484         lea_DWORD_BE(&len, fd);
00485         switch( (unsigned int)id ) {
00486           case CHUNK3DS_RGB1: leer_trozo_RGBFloat(rgb); break;
00487           case CHUNK3DS_RGB2: leer_trozo_RGBByte (rgb); break;
00488           default: dsetpos(pc+len, fd);
00489         }
00490     }
00491 }
00492 
00493 void
00494 ESCENA_3DS::leer_trozo_TRIMESH(DWORD p, char *name)
00499 {
00500     UWORD id;
00501     WORD fl = 0; /* WG */
00502     DWORD len, pc;
00503     MESH_3DS *meshobj;
00504     BOOLEAN found_facemat = FALSE;
00505 
00506     meshobj = anx_mesh();
00507 
00508     strcpy(meshobj->name, name);
00509     while( (pc=dgetpos(fd)) < p ) {
00510         lea_WORD_BE(&id, fd);
00511         lea_DWORD_BE(&len, fd);
00512         switch( (int)id ) {
00513           case CHUNK3DS_VERTLIST: meshobj->leer_trozo_VERTLIST(); break;
00514           case CHUNK3DS_FACELIST: fl = meshobj->leer_trozo_FACELIST(); break;
00515           case CHUNK3DS_MAPLIST:  meshobj->leer_trozo_MAPLIST(); break;
00516           case CHUNK3DS_TRMATRIX: meshobj->leer_trozo_TRMATRIX(); break;
00517           case CHUNK3DS_FACEMAT:
00518             meshobj->leer_trozo_FACEMAT();
00519             found_facemat = TRUE;
00520             break;
00521        /* case CHUNK3DS_SMOOLIST: */  // IGNORADO
00522           default: 
00523           #ifdef DEBUG_3DS
00524             fprintf(stderr,
00525               "<ESCENA_3DS> - WARNING: "
00526                     "Ignorando un chunk desconocido (tipo %Xh, longitud %ld)\n",
00527               id, len);
00528             fflush(stderr);
00529             printf("  - Posicionando en %ld... (p = %ld)\t", pc+len, p); 
00530             fflush(stdout);
00531           #endif
00532             dsetpos(pc+len, fd);
00533           #ifdef DEBUG_3DS
00534             printf("Ok.\n\n"); fflush(stdout);
00535           #endif
00536         }
00537     }
00538 
00539     if ( !found_facemat ) {
00540         flag_material_por_defecto = TRUE;
00541         meshobj->asignar_material_por_defecto(fl); /*W.G.*/
00542     }
00543 }
00544 
00545 //===========================================================================
00546 //= Funciones que leen trozos de nivel 2 - control de trozos de nivel 1     =
00547 //===========================================================================
00548 
00549 void
00550 ESCENA_3DS::leer_trozo_MATERIAL(DWORD p)
00551 /*
00552   Fills out the current material with the information contained 
00553   in these chunks
00554   */
00555 {
00556     unsigned short id;
00557     DWORD len, pc;
00558 
00559     MATERIAL_3DS *materialobj = anx_material();
00560 
00561     while((pc=dgetpos(fd)) < p) {
00562         lea_WORD_BE(&id, fd);
00563         lea_DWORD_BE(&len, fd);
00564 
00565         switch((unsigned int)id) {
00566           case CHUNK3DS_MATNAME: 
00567             leer_trozo_MATNAME(pc+len, materialobj); 
00568             break;
00569           case CHUNK3DS_AMBIENT: 
00570             leer_trozo_SHADING(pc+len, &materialobj->ambient);
00571             break;
00572           case CHUNK3DS_DIFFUSE: 
00573             leer_trozo_SHADING(pc+len, &materialobj->diffuse);
00574             break;
00575           case CHUNK3DS_SPECULAR:
00576             leer_trozo_SHADING(pc+len, &materialobj->specular);
00577             break;
00578           case CHUNK3DS_TEXTURE:
00579             leer_trozo_TEXTURE(pc+len, &materialobj->texture);
00580             break;
00581           case CHUNK3DS_DOUBLESIDED:
00582             leer_trozo_DOUBLESIDED(&materialobj->doublesided);
00583             break;
00584           case CHUNK3DS_TRANSPARENCY:
00585             leer_trozo_TRANSPARENCY(pc+len, &materialobj->alpha);
00586             break;
00587           default: 
00588             dsetpos(pc+len, fd);
00589             break;
00590         }
00591     }
00592 }
00593 
00594 void
00595 ESCENA_3DS::leer_trozo_OBJBLOCK(DWORD p)
00600 {
00601     UWORD id;
00602     DWORD len, pc;
00603     char name[MAXNAMESIZE];
00604 
00605     /* The object name is always the first item */
00606     int n = 0;
00607     do {
00608         lea_BYTE(&name[n++], fd);
00609     } while( name[n-1] != '\0' && n < (int)sizeof(name) );
00610     name[n-1]='\0';
00611 
00612   #ifdef DEBUG_3DS
00613     printf("Read Object \"%s\"\n", name);
00614   #endif
00615 
00616     while( (pc=dgetpos(fd)) < p ) {
00617         lea_WORD_BE(&id, fd);
00618         lea_DWORD_BE(&len, fd);
00619         switch((int)id) {
00620           case CHUNK3DS_TRIMESH: 
00621           #ifdef DEBUG_3DS
00622             printf(" - Leo TRIMESH:\n");
00623           #endif
00624             leer_trozo_TRIMESH(pc+len, name);
00625             break;
00626         /*
00627           case CHUNK3DS_LIGHT:
00628           case CHUNK3DS_CAMERA:
00629          */
00630           default: dsetpos(pc+len, fd);
00631         }
00632     }
00633 
00634    #ifdef DEBUG_3DS
00635      printf("  - Listo OBJ.\n");
00636    #endif
00637 
00638     dsetpos(p, fd);
00639 }
00640 
00641 void
00642 ESCENA_3DS::leer_trozo_OBJMESH(DWORD p)
00650 {
00651     UWORD id;
00652     DWORD len, pc;
00653 
00654     while( (pc=dgetpos(fd)) < p ) {
00655         lea_WORD_BE(&id, fd);
00656         lea_DWORD_BE(&len, fd);
00657         switch( id ) {
00658           case CHUNK3DS_MATERIAL: 
00659             leer_trozo_MATERIAL(pc+len); 
00660             break;
00661           case CHUNK3DS_OBJBLOCK: 
00662             leer_trozo_OBJBLOCK(pc+len); 
00663             break;
00664           case CHUNK3DS_BKGCOLOR:
00665             //printf(
00666             //  "<ESCENA_3DS> OJO: Estoy ignorando un trozo BKGCOLOR (%d).\n",
00667             //  len);
00668             //fflush(stdout);
00669             dsetpos(pc+len, fd);
00670             break;
00671           case CHUNK3DS_AMBCOLOR:
00672             //printf(
00673             //  "<ESCENA_3DS> OJO: Estoy ignorando un trozo AMBCOLOR (%d).\n",
00674             //  len);
00675             //fflush(stdout);
00676             dsetpos(pc+len, fd);
00677             break;
00678           default:
00679             dsetpos(pc+len, fd);
00680             break;
00681         }
00682     }
00683 }
00684 
00685 //===========================================================================
00686 //= Funciones que leen trozos de nivel 0 - control de trozos de nivel 1     =
00687 //===========================================================================
00688 
00689 void
00690 ESCENA_3DS::leer_trozo_MAIN(DWORD p)
00694 {
00695     UWORD id;
00696     DWORD len, pc;
00697   #ifdef DEBUG_3DS
00698     DWORD i;
00699     BYTE b;
00700   #endif
00701   
00702     while( (pc = dgetpos(fd) ) < p) {
00703         lea_WORD_BE(&id, fd);
00704         lea_DWORD_BE(&len, fd);
00705         switch( id ) {
00706           case CHUNK3DS_OBJMESH:
00707             leer_trozo_OBJMESH((DWORD)(pc+len)); 
00708             break;
00709           case CHUNK3DS_KEYFRAMER:
00710             dsetpos(pc+len, fd);
00711           #ifdef DEBUG_3DS
00712             fprintf(stderr,
00713               "<ESCENA_3DS> - WARNING: Ignorando informacion del KEYFRAMER\n");
00714             fflush(stderr);
00715           #endif
00716             break;
00717 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00718 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00719 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00720 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00721 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00722           default:
00723           #ifdef DEBUG_3DS
00724             fprintf(stderr,
00725               "<ESCENA_3DS> - WARNING: "
00726                     "Ignorando un chunk desconocido (tipo %Xh, longitud %ld)\n",
00727               id, len);
00728             fflush(stderr);
00729             printf("El chunk ignorado contiene lo siguiente:\n");
00730             fflush(stdout);
00731             for ( i = 0; i < len; i++ ) {
00732                 fread(&b, sizeof(BYTE), 1, fd);
00733                 printf("%02X ", b); fflush(stdout);
00734                 if ( i > 0 && (i%16 == 0) ) {
00735                     printf("\n"); fflush(stdout);
00736                 }
00737             }
00738             printf("\n"); fflush(stdout);
00739             fseek(fd, -len, SEEK_CUR);
00740             for ( i = 0; i < len; i++ ) {
00741                 fread(&b, sizeof(BYTE), 1, fd);
00742                 if ( b == '\a' || b == '\n' || b == '\t' ) {
00743                     printf(".");
00744                   }
00745                   else {
00746                     printf("%c", b); fflush(stdout);
00747                 }
00748                 if ( i > 0 && (i%16 == 0) ) {
00749                     printf(" "); fflush(stdout);
00750                 }
00751                 if ( i > 0 && (i%64 == 0) ) {
00752                     printf("\n"); fflush(stdout);
00753                 }
00754             }
00755             printf("\n\n"); fflush(stdout);
00756           #endif
00757             dsetpos(pc+len, fd);
00758             break;
00759         }
00760     }
00761 }
00762 
00763 //===========================================================================
00764 //= CLASE ESCENA_3DS - El resto de sus metodos                              =
00765 //===========================================================================
00766 
00767 ESCENA_3DS::ESCENA_3DS(char *archivo) : arr_mesh(1), arr_material(1)
00768 {
00769     //- init -----------------------------------------------------------------
00770     flag_material_por_defecto = FALSE;
00771     flag_alpha_blending = FALSE;
00772     flag_caras_dobles = FALSE;
00773 
00774     //- Abra y prepare el archivo de entrada ---------------------------------
00775     FILE *fd;
00776 
00777     fd = fopen(archivo, "rb");
00778     if( !fd ) {
00779         fprintf(stderr, "<ESCENA_3DS> - ERROR leyendo el archivo \"%s\"\n",
00780                 archivo);
00781         fflush(stderr);
00782         _muerta = TRUE;
00783         return;
00784     }
00785     _nombre_de_archivo = new char[strlen(archivo)+1];
00786     ULTIMO_archivo = _nombre_de_archivo;
00787     strcpy(_nombre_de_archivo, archivo);
00788 
00789     //- Read in the file and place it in *scene -------------------------------
00790     if ( !leer(fd) ) {
00791         fprintf(stderr, "<ESCENA_3DS> Error al leer \"%s\"!\n", archivo);
00792         fflush(stderr);
00793         fclose(fd);
00794         _muerta = TRUE;
00795         return;
00796     }
00797     fclose(fd);
00798 
00799   #ifdef NONONO
00800     ADVERTIR_FALLAS();
00801   #endif
00802 
00803     _muerta = FALSE;
00804 }
00805 
00806 ESCENA_3DS::~ESCENA_3DS()
00807 {
00808     int n,m;
00809 
00810     for( n = arr_mesh.tam()-1; n >= 0; n-- ) {
00811         MESH_3DS *mobj = &arr_mesh[n];
00812 
00813         if(mobj->maplist)  delete mobj->maplist;
00814         if(mobj->facelist) delete mobj->facelist;
00815         if(mobj->vertices_arr) delete mobj->vertices_arr;
00816 
00817         //------------------------------------------------------------
00818         if ( mobj->jed_arr ) {
00819             for ( m = 0; m < mobj->jed_tam; m++ ) {
00820                 if ( mobj->jed_arr[m].faces ) {
00821                     delete mobj->jed_arr[m].faces;
00822                 }
00823             }
00824             free(mobj->jed_arr);
00825         }
00826         //------------------------------------------------------------
00827     }
00828     arr_mesh.elim();
00829     arr_material.elim();
00830 }
00831 
00832 BOOLEAN ESCENA_3DS::muerta(void) {    return _muerta;    }
00833 
00834 MESH_3DS *
00835 ESCENA_3DS::anx_mesh(void)
00836 /* Enlarge the scene array to hold a new mesh object */
00837 {
00838     //-----------------------------------------------------------------------
00839     MESH_3DS o;
00840 
00841     if( !arr_mesh.anx(o) ) {
00842         fprintf(stderr, "<ESCENA_3DS> Error de memoria en anx_mesh.\n");
00843         fflush(stderr);
00844     }
00845 
00846     //-----------------------------------------------------------------------
00847     MESH_3DS *obj;
00848 
00849     obj = &arr_mesh[arr_mesh.tam()-1];
00850     memset(obj, 0, sizeof(MESH_3DS));
00851     obj->fd = fd;
00852 
00853     return obj;
00854 }
00855 
00856 MATERIAL_ARR *
00857 MESH_3DS::anx_data(void)
00858 /* Enlarges the bindings array to hold another bindings list */
00859 {
00860     //-----------------------------------------------------------------------
00861 /*
00862     MATERIAL_ARR o;
00863 
00864     if( !arr_jed.anx(o) ) {
00865         fprintf(stderr, "<ESCENA_3DS> Error de memoria en anx_data.\n");
00866         fflush(stderr);
00867     }
00868 */
00869     void *mem;
00870     mem = realloc(jed_arr, sizeof(MATERIAL_ARR)*(jed_tam+1));
00871     if( !mem ) {
00872         fprintf(stderr, "<ESCENA_3DS> Error de memoria en anx_data.\n");
00873         fflush(stderr);
00874     }
00875     jed_arr = (MATERIAL_ARR *)mem;
00876     jed_tam++;
00877 
00878     //-----------------------------------------------------------------------
00879     MATERIAL_ARR *obj;
00880 
00881     obj = &jed_arr[jed_tam-1];
00882     memset(obj, 0, sizeof(MATERIAL_ARR));
00883     
00884     return obj;
00885 }
00886 
00887 MATERIAL_3DS *
00888 ESCENA_3DS::anx_material(void)
00889 /* Enlarge the scene array to hold a new material */
00890 {
00891     //-----------------------------------------------------------------------
00892     MATERIAL_3DS o;
00893 
00894     if( !arr_material.anx(o) ) {
00895         fprintf(stderr, "<ESCENA_3DS> Error de memoria en anx_material.\n");
00896         fflush(stderr);
00897     }
00898     //-----------------------------------------------------------------------
00899     MATERIAL_3DS *obj;
00900 
00901     obj = &arr_material[arr_material.tam()-1];
00902     memset(obj, 0, sizeof(MATERIAL_3DS));
00903 
00904     return obj;
00905 }
00906 
00907 BOOLEAN
00908 ESCENA_3DS::leer(FILE *_fd)
00914 {
00915     UWORD id;
00916     DWORD len, pc;
00917 
00918     fd = _fd;
00919 
00920     //- Verifique el encabezado del archico 3DS -----------------------------
00921     pc = dgetpos(fd);
00922     lea_WORD_BE(&id, fd);
00923     lea_DWORD_BE(&len, fd);
00924         //printf("Empiezo a leer 3DS, con longitud %X\n", len);
00925         //printf("El primer id CHUNK3DS_MAIN (%Xh) es %Xh\n",
00926         //        CHUNK3DS_MAIN, id);
00927 
00928     if( (WORD)id != (WORD)CHUNK3DS_MAIN ) {
00929         fprintf(stderr, 
00930                 "<ESCENA_3DS> - ERROR:\n"
00931                 "    El primer id no es CHUNK3DS_MAIN (%Xh), sino %Xh\n",
00932                 CHUNK3DS_MAIN, id);
00933         fflush(stderr);
00934         return FALSE;
00935     }
00936 
00937     //- Lea los trozos del archivo ------------------------------------------
00938     leer_trozo_MAIN(pc+len); // Notese que aqui se hace todo
00939     return TRUE;
00940 }
00941 
00942 //===========================================================================
00943 //= FUNCIONES PARA EXPORTAR DATOS DE ESTA REPRESENTACION A DATOS AQUYNZA    =
00944 //===========================================================================
00945 
00946 // COMENTADO
00947         // Apply this material's translation matrix to this material's vertices
00948         // This doesn't seem to work as a normal transformation matrix, so this
00949         // part is commented out.
00950         /*
00951         if ( meshobj->con_matriz ) {
00952             m = meshobj->TraMatrix;
00953             for ( y = 0; y < meshobj->vertices_tam; y++ ) {
00954                 prime.x = m[0]*meshobj->vertices_arr[y].x +
00955                           m[3]*meshobj->vertices_arr[y].y +
00956                           m[6]*meshobj->vertices_arr[y].z;
00957                 prime.y = m[1]*meshobj->vertices_arr[y].x +
00958                           m[4]*meshobj->vertices_arr[y].y +
00959                           m[7]*meshobj->vertices_arr[y].z;
00960                 prime.z = m[2]*meshobj->vertices_arr[y].x +
00961                           m[5]*meshobj->vertices_arr[y].y +
00962                           m[8]*meshobj->vertices_arr[y].z;
00963                 prime.x += m[9];
00964                 prime.y += m[10];
00965                 prime.z += m[11];
00966                 meshobj->vertices_arr[y].x = prime.x;
00967                 meshobj->vertices_arr[y].y = prime.y;
00968                 meshobj->vertices_arr[y].z = prime.z;
00969             }
00970         }
00971         */
00972 
00973 void
00974 importar_3DS(ESCENA_3DS *Scene, MESH *Geometria, BOOLEAN *flag_blend,
00975              double *Escala_optima)
00984 {
00985     int i;
00986 
00987     Geometria->set_nombre_de_archivo(Scene->_nombre_de_archivo);
00988 
00989     //- Exporte materiales -------------------------------------------------
00990     COLOR ambient, diffuse, specular;
00991 
00992     if ( Scene->flag_material_por_defecto ) {
00993         //- Felizmente es barato tener oro en la realidad virtual :-)
00994         ambient.r = ambient.g = ambient.b = 0.2f;
00995         diffuse.r = 0.85f;
00996         diffuse.g = 0.85f;
00997         diffuse.b = 0.1f;
00998         specular.r = specular.g = specular.b = 1.0;
00999         ambient.alpha = diffuse.alpha = specular.alpha = 1.0;
01000         Geometria->anx_material(ambient, diffuse, specular,
01001                                 "WG_DEFAULT", "", 1);
01002       #ifdef DEBUG_3DS
01003         printf("<importe_3DS> OJO: Voy con el material por defecto!\n");
01004         fflush(stdout);
01005       #endif
01006     }
01007 
01008     for ( i = 0; i < Scene->arr_material.tam(); i++ ) {
01009         // OJO: Aquien se le pone el canal alpha?
01010         MATERIAL_3DS *mat = &Scene->arr_material[i];
01011         ambient.r = mat->ambient.r/2;
01012         ambient.g = mat->ambient.g/2;
01013         ambient.b = mat->ambient.b/2;
01014         ambient.alpha = 1.0;
01015         diffuse.r = mat->diffuse.r;
01016         diffuse.g = mat->diffuse.g;
01017         diffuse.b = mat->diffuse.b;
01018         //diffuse.alpha = mat->alpha;
01019         diffuse.alpha = 1.0;
01020         specular.r = mat->specular.r;
01021         specular.g = mat->specular.g;
01022         specular.b = mat->specular.b;
01023         specular.alpha = 1.0;
01024         Geometria->anx_material(ambient, diffuse, specular,
01025                                 mat->name, mat->texture.texturename,
01026                                 mat->doublesided);
01027     }
01028 
01029     // Esto es para calcular el factor de escala optima
01030     VECTOR min, max, factor;
01031 
01032     min.x = INFINITO;
01033     min.y = INFINITO;
01034     min.z = INFINITO;
01035     max.x = -INFINITO;
01036     max.y = -INFINITO;
01037     max.z = -INFINITO;
01038 
01039     //- Exporte la geometria y la topologia de la malla ----------------------
01040     TRIANGULO_GL tri;
01041     VERTICE_GL v;
01042     int y;
01043     unsigned int z;
01044     int current;
01045     FLOAT32 swap;
01046     char *name;
01047     MATRIZ_4x4 R;
01048     VECTOR p;
01049 
01050     // OJO: 3D Studio, respecto a AQUYNZA, suele ver sus coordenadas 90
01051     //      grados volteada...
01052     R.rotacion_angulos_euler(DEG2RAD(-90), 0, DEG2RAD(90)); 
01053 
01054     for ( current = 0, i = 0; i < Scene->arr_mesh.tam(); i++ ) {
01055         MESH_3DS *entidad = &Scene->arr_mesh[i];
01056 
01057         for ( y = 0; y < entidad->vertices_tam; y++ ) {
01058             // OJO: Porque toca hacer esto? [Swap y and z (.3ds wierdness)]
01059             swap = -entidad->vertices_arr[y].y;
01060             entidad->vertices_arr[y].y = entidad->vertices_arr[y].z;
01061             entidad->vertices_arr[y].z = swap;
01062         }
01063 
01064         // Ingrese los vertices a la malla
01065         for ( y = 0; y < entidad->vertices_tam; y++ ) {
01066             v.x = entidad->vertices_arr[y].x;
01067             v.y = entidad->vertices_arr[y].y;
01068             v.z = entidad->vertices_arr[y].z;
01069             if ( entidad->NumMaps ) {
01070                 v.u = entidad->maplist[y].u;
01071                 v.v = entidad->maplist[y].v;
01072             }
01073             else {
01074                 v.u = v.x;
01075                 v.v = v.y;
01076             }
01077             COMPARAR_MM();
01078             p.x = v.x; p.y = v.y; p.z = v.z;
01079             p = R*p;
01080             v.x = (float)p.x; v.y = (float)p.y; v.z = (float)p.z;
01081             v.nx = v.ny = 0;
01082             v.nz = 1;
01083             Geometria->anx_vertex(v);
01084         }
01085 
01086         factor = max - min;
01087         *(Escala_optima) = 5/factor.norma();
01088 
01089         // Ingrese los triangulos a la malla
01090         for ( y = 0; y < entidad->jed_tam; y++ ) {
01091             name = entidad->jed_arr[y].name;
01092             for ( z = 0; z < entidad->jed_arr[y].NumFaces; z++ ) {
01093                 /* Flip the polygon orientation by using points (0,2,1) */
01094                 tri.p0 =
01095                  entidad->facelist[entidad->jed_arr[y].faces[z]].p0 + current;
01096                 tri.p1 =
01097                  entidad->facelist[entidad->jed_arr[y].faces[z]].p2 + current;
01098                 tri.p2 =
01099                  entidad->facelist[entidad->jed_arr[y].faces[z]].p1 + current;
01100                 Geometria->anx_triangle(tri, name);
01101             }
01102         }
01103         current += entidad->vertices_tam;
01104     }
01105 
01106     (*flag_blend) = Scene->flag_alpha_blending;
01107 
01108     Geometria->init();
01109 }
01110 
01111 //===========================================================================
01112 //= EOF                                                                     =
01113 //===========================================================================
01114 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.