00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00029
00030
00031
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
00070
00071
00072 static char * ULTIMO_archivo = NULL;
00073
00074
00075
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
00109
00110
00111 MESH_3DS::MESH_3DS()
00112 {
00113
00114
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
00124 {
00125 MATERIAL_ARR *binding;
00126 int n;
00127 unsigned long int nn;
00128
00129 binding = anx_data();
00130
00131
00132 strcpy(binding->name, "WG_DEFAULT");
00133
00134
00135 nn = 0x0000FFFFL & (unsigned long int)nf;
00136 binding->NumFaces = (unsigned int)nn;
00137 binding->faces = new UWORD[(unsigned int)nn];
00138
00139
00140 for ( n = 0; n < nf; n++ ) {
00141 binding->faces[n] = (unsigned short)n;
00142 }
00143
00144 #ifdef DEBUG_3DS
00145 printf(" Read Material %s with %d faces\n", name, nf);
00146 #endif
00147 }
00148
00149
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
00195
00196
00197
00198
00199
00200
00201
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
00213
00214
00215
00216
00217
00218
00219
00220
00221 if ( facelist[n].flags == 0x07 ) {
00222
00223
00224
00225
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;
00237 }
00238
00239 void
00240 MESH_3DS::leer_trozo_MAPLIST(void)
00241
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
00267
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
00289
00290
00291
00292
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
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
00311 lea_WORD_BE(&nf, fd);
00312 binding->NumFaces = (unsigned int)nf;
00313 binding->faces = new UWORD[nf];
00314
00315
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
00328
00329
00330
00331 void
00332 ESCENA_3DS::leer_trozo_MAPFILENAME(DWORD , 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
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
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
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
00416
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
00444
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 , MATERIAL_3DS *mat)
00457
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
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;
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
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);
00542 }
00543 }
00544
00545
00546
00547
00548
00549 void
00550 ESCENA_3DS::leer_trozo_MATERIAL(DWORD p)
00551
00552
00553
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
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
00628
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
00666
00667
00668
00669 dsetpos(pc+len, fd);
00670 break;
00671 case CHUNK3DS_AMBCOLOR:
00672
00673
00674
00675
00676 dsetpos(pc+len, fd);
00677 break;
00678 default:
00679 dsetpos(pc+len, fd);
00680 break;
00681 }
00682 }
00683 }
00684
00685
00686
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
00718
00719
00720
00721
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
00765
00766
00767 ESCENA_3DS::ESCENA_3DS(char *archivo) : arr_mesh(1), arr_material(1)
00768 {
00769
00770 flag_material_por_defecto = FALSE;
00771 flag_alpha_blending = FALSE;
00772 flag_caras_dobles = FALSE;
00773
00774
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
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
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
00859 {
00860
00861
00862
00863
00864
00865
00866
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
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
00921 pc = dgetpos(fd);
00922 lea_WORD_BE(&id, fd);
00923 lea_DWORD_BE(&len, fd);
00924
00925
00926
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
00938 leer_trozo_MAIN(pc+len);
00939 return TRUE;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
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
00990 COLOR ambient, diffuse, specular;
00991
00992 if ( Scene->flag_material_por_defecto ) {
00993
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
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
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
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
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
01051
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
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
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
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
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
01113
01114