00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include <math.h>
00063 #include <stdio.h>
00064 #include <stdlib.h>
00065 #include <string.h>
00066
00067 #include "toolkits/geom/mesh.h"
00068 #include "matriz4.h"
00069 #include "lista.cc"
00070 #include "arreglo.cc"
00071
00072 #ifdef GL_VERSION_1_1 // OJO: Toca revisar si esta vaina funciona bien!
00073 #define GL_COMPLETO
00074 #endif
00075
00076 #if PLATAFORMA == SGI
00077 #undef GL_COMPLETO // OJO: Esto es un machete!
00078 #endif
00079
00080
00081
00082
00083
00084
00085
00086 #define VERIFICAR(m) \
00087 if ( !m ) { \
00088 fprintf(stderr, "<MESH> ERROR: Falla de memoria dinamica.\n"); \
00089 fflush(stderr); \
00090 exit(-1); \
00091 }
00092
00093 #define VERIFICAR1(m) \
00094 if ( !m ) { \
00095 fprintf(stderr, "<MESH> ERROR: Falla de memoria dinamica (STRIP).\n");\
00096 fflush(stderr); \
00097 exit(-1); \
00098 }
00099
00100
00101
00102
00103
00104
00105 #define cos_angle(a, b) \
00106 ((a)->nx * (b)->nx) + ((a)->ny * (b)->ny) + ((a)->nz * (b)->nz)
00107
00108 #define COMPARAR_MM() \
00109 if ( p.x < _min.x ) _min.x = p.x; \
00110 if ( p.y < _min.y ) _min.y = p.y; \
00111 if ( p.z < _min.z ) _min.z = p.z; \
00112 if ( p.x > _max.x ) _max.x = p.x; \
00113 if ( p.y > _max.y ) _max.y = p.y; \
00114 if ( p.z > _max.z ) _max.z = p.z;
00115
00116
00117
00118
00119
00120 MESH::MESH(int threshold, BOOLEAN strips, BOOLEAN center_model, double scale)
00121 : arr_vertices(VERTEXBLOCKSIZE), arr_trozos_gl(1),
00122 arr_colores(VERTEXBLOCKSIZE), listas_de_referencias(VERTEXBLOCKSIZE)
00141 {
00142
00143 vertice_promedio.x = vertice_promedio.y = vertice_promedio.z = 0;
00144
00145
00146 material_global = FALSE;
00147 calcular_normales = TRUE;
00148 preprocesada = FALSE;
00149 #ifdef GL_ENABLED
00150 preprocesada_gl = FALSE;
00151 #endif
00152 modo_tiras_de_triangulos = FALSE;
00153 centrar_modelo = FALSE;
00154 preservar_bordes = FALSE;
00155 Arr_control = NULL;
00156 pintar_normales = FALSE;
00157 pintar_debug_vertices = FALSE;
00158 pintar_debug_triangulos = FALSE;
00159 index_debug_vertice = 0;
00160 index_debug_triangulo = 0;
00161 mostrar_tiras = FALSE;
00162 con_minmax = FALSE;
00163 ultima_tira = 0;
00164 _invertir_orden = FALSE;
00165
00166 #if PLATAFORMA == i386_WIN32_VC // OJO: Esto es un machete, debido a falta de
00167 con_lista_gl = FALSE;
00168 #else // con el SDK de Windows.
00169 con_lista_gl = FALSE;
00170 #endif
00171
00172 normales_de_triangulo = FALSE;
00173
00174
00175 _nombre_de_archivo = NULL;
00176 if ( strips ) modo_tiras_de_triangulos = TRUE;
00177 if ( center_model ) centrar_modelo = TRUE;
00178 if ( threshold ) {
00179 cos_threshold = (GLfloat)cos(threshold*PI/180.0);
00180 preservar_bordes = TRUE;
00181 if ( threshold > 180 ) normales_de_triangulo = TRUE;
00182 }
00183 else {
00184 preservar_bordes = FALSE;
00185 normales_de_triangulo = TRUE;
00186 }
00187 escala = scale;
00188
00189 imagen = NULL;
00190 }
00191
00192 MESH::~MESH(void)
00197 {
00198 int i;
00199
00200
00201
00202 arr_vertices.elim();
00203 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00204 arr_trozos_gl[i].arr_triangulos.elim();
00205 delete arr_trozos_gl[i].triangulos_gl;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 if ( _nombre_de_archivo ) {
00218 delete _nombre_de_archivo;
00219 }
00220 listas_de_referencias.elim();
00221 arr_trozos_gl.elim();
00222 }
00223
00224
00225
00226 void
00227 MESH::get_vertices(VERTICE_GL **V, long int *n)
00238 {
00239 (*V) = arr_vertices.data();
00240 (*n) = arr_vertices.tam();
00241
00242
00243
00244
00245 if ( con_lista_gl ) {
00246
00247
00248 con_lista_gl = FALSE;
00249 }
00250 }
00251
00252 void
00253 MESH::set_invertir_orden(BOOLEAN o)
00254 {
00255 _invertir_orden = o;
00256 }
00257
00258 void
00259 MESH::set_nombre_de_archivo(char *c)
00260 {
00261 _nombre_de_archivo = c;
00262 }
00263
00264 void
00265 MESH::set_escala(double e)
00266 {
00267 escala = e;
00268 }
00269
00270 inline GLfloat
00271 MESH::angulo_de_vertice(TRIANGULITO *triangle, GLuint vertex)
00281 {
00282 double a,b,c;
00283
00284 if ( triangle->p0 == vertex ) {
00285 a = DISTANCIA_VGL(&arr_vertices[triangle->p0],
00286 &arr_vertices[triangle->p1]);
00287 b = DISTANCIA_VGL(&arr_vertices[triangle->p0],
00288 &arr_vertices[triangle->p2]);
00289 c = DISTANCIA_VGL(&arr_vertices[triangle->p1],
00290 &arr_vertices[triangle->p2]);
00291 }
00292 else if ( triangle->p1 == vertex ) {
00293 a = DISTANCIA_VGL(&arr_vertices[triangle->p1],
00294 &arr_vertices[triangle->p0]);
00295 b = DISTANCIA_VGL(&arr_vertices[triangle->p1],
00296 &arr_vertices[triangle->p2]);
00297 c = DISTANCIA_VGL(&arr_vertices[triangle->p2],
00298 &arr_vertices[triangle->p0]);
00299 }
00300 else if (triangle->p2 == vertex) {
00301 a = DISTANCIA_VGL(&arr_vertices[triangle->p2],
00302 &arr_vertices[triangle->p0]);
00303 b = DISTANCIA_VGL(&arr_vertices[triangle->p2],
00304 &arr_vertices[triangle->p1]);
00305 c = DISTANCIA_VGL(&arr_vertices[triangle->p0],
00306 &arr_vertices[triangle->p1]);
00307 }
00308 else {
00309
00310 fprintf(stderr, "!");
00311 return 60;
00312 }
00313 ;
00314
00315 return (GLfloat)acos( (c*c - a*a - b*b) / (2*a*b) );
00316 }
00317
00318 void
00319 MESH::calcule_normales_vertice(void)
00326 {
00327 int orig_arr_vertices_tam;
00328 int i;
00329 long int error_vertice_suelto = 0;
00330
00331 orig_arr_vertices_tam = arr_vertices.tam();
00332
00333
00334 int j;
00335 TRIANGULITO *pptr;
00336
00337 if ( normales_de_triangulo ) {
00338 for ( j = 0; j < arr_trozos_gl.tam(); j++ ) {
00339 for ( i = 0; i < arr_trozos_gl[j].arr_triangulos.tam(); i++ ) {
00340 pptr=&(arr_trozos_gl[j].arr_triangulos[i]);
00341 arr_vertices[pptr->p0].nx = pptr->nx;
00342 arr_vertices[pptr->p0].ny = pptr->ny;
00343 arr_vertices[pptr->p0].nz = pptr->nz;
00344 arr_vertices[pptr->p1].nx = pptr->nx;
00345 arr_vertices[pptr->p1].ny = pptr->ny;
00346 arr_vertices[pptr->p1].nz = pptr->nz;
00347 arr_vertices[pptr->p2].nx = pptr->nx;
00348 arr_vertices[pptr->p2].ny = pptr->ny;
00349 arr_vertices[pptr->p2].nz = pptr->nz;
00350 }
00351 }
00352 }
00353
00354
00355 BOOLEAN ya_hice_vertice_nuevo;
00356 TRIANGLENODE *ptr;
00357 TRIANGLENODE *qtr;
00358 GLfloat TotalAngles;
00359 GLfloat VertexAngle;
00360 GLfloat magnitude;
00361
00362 for ( i = 0; !normales_de_triangulo && i < arr_vertices.tam(); i++ ) {
00363
00364
00365 arr_vertices[i].nx = arr_vertices[i].ny = arr_vertices[i].nz = 0;
00366 ya_hice_vertice_nuevo = FALSE;
00367 TotalAngles = 0;
00368
00369
00370 ptr = listas_de_referencias[i];
00371 while ( ptr ) {
00372 if ( preservar_bordes &&
00373 cos_angle(listas_de_referencias[i]->triangle,
00374 ptr->triangle) <= cos_threshold) {
00375
00376 if ( !ya_hice_vertice_nuevo ) {
00377
00378
00379 ya_hice_vertice_nuevo = TRUE;
00380
00381
00382 anx_vertex(arr_vertices[i]);
00383 vertice_promedio.x -= arr_vertices[i].x;
00384 vertice_promedio.y -= arr_vertices[i].y;
00385 vertice_promedio.z -= arr_vertices[i].z;
00386 }
00387
00388
00389
00390 qtr = ptr;
00391 ptr = ptr->sig;
00392 qtr->sig = listas_de_referencias[arr_vertices.tam()-1];
00393 listas_de_referencias[arr_vertices.tam()-1] = qtr;
00394
00395
00396 if ( qtr->triangle->p0 == (GLuint)i ) {
00397 qtr->triangle->p0 = arr_vertices.tam()-1;
00398 }
00399 if ( qtr->triangle->p1 == (GLuint)i ) {
00400 qtr->triangle->p1 = arr_vertices.tam()-1;
00401 }
00402 if ( qtr->triangle->p2 == (GLuint)i ) {
00403 qtr->triangle->p2 = arr_vertices.tam()-1;
00404 }
00405 }
00406 else {
00407
00408
00409 VertexAngle = angulo_de_vertice(ptr->triangle, i);
00410 arr_vertices[i].nx += ptr->triangle->nx * VertexAngle;
00411 arr_vertices[i].ny += ptr->triangle->ny * VertexAngle;
00412 arr_vertices[i].nz += ptr->triangle->nz * VertexAngle;
00413 TotalAngles += VertexAngle;
00414 ptr = ptr->sig;
00415 }
00416 }
00417
00418
00419 if ( IGUAL(0.0, TotalAngles) ) {
00420
00421 error_vertice_suelto++;
00422 arr_vertices[i].nz = 1;
00423 continue;
00424 }
00425 arr_vertices[i].nx /= TotalAngles;
00426 arr_vertices[i].ny /= TotalAngles;
00427 arr_vertices[i].nz /= TotalAngles;
00428
00429 magnitude = (GLfloat)sqrt(
00430 ((arr_vertices[i].nx * arr_vertices[i].nx) +
00431 (arr_vertices[i].ny * arr_vertices[i].ny) +
00432 (arr_vertices[i].nz * arr_vertices[i].nz)) );
00433 arr_vertices[i].nx /= magnitude;
00434 arr_vertices[i].ny /= magnitude;
00435 arr_vertices[i].nz /= magnitude;
00436 }
00437
00438
00439 if ( centrar_modelo ) {
00440 vertice_promedio.x /= orig_arr_vertices_tam;
00441 vertice_promedio.y /= orig_arr_vertices_tam;
00442 vertice_promedio.z /= orig_arr_vertices_tam;
00443
00444 for ( i = 0; i < arr_vertices.tam(); i++ ) {
00445 arr_vertices[i].x -= vertice_promedio.x;
00446 arr_vertices[i].y -= vertice_promedio.y;
00447 arr_vertices[i].z -= vertice_promedio.z;
00448
00449
00450
00451
00452
00453 }
00454 }
00455
00456 if ( error_vertice_suelto ) {
00457 fprintf(stderr, "<MESH> - Warning: %ld vertices sueltos, de los "
00458 "%ld vertices del modelo\n",
00459 error_vertice_suelto, arr_vertices.tam());
00460 fflush(stderr);
00461 }
00462 }
00463
00464 void
00465 MESH::cree_lista_de_referencias(void)
00477 {
00478 TRIANGULITO *Triangulo;
00479 TRIANGLENODE *qtr;
00480 int i, j;
00481
00482 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00483 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
00484
00485
00486
00487 Triangulo = &arr_trozos_gl[i].arr_triangulos[j];
00488
00489
00490 qtr = new TRIANGLENODE;
00491 qtr->triangle = Triangulo;
00492
00493 qtr->sig = listas_de_referencias[Triangulo->p0];
00494 listas_de_referencias[Triangulo->p0] = qtr;
00495
00496
00497 qtr = new TRIANGLENODE;
00498 qtr->triangle = Triangulo;
00499
00500 qtr->sig = listas_de_referencias[Triangulo->p1];
00501 listas_de_referencias[Triangulo->p1] = qtr;
00502
00503
00504 qtr = new TRIANGLENODE;
00505 qtr->triangle = Triangulo;
00506
00507 qtr->sig = listas_de_referencias[Triangulo->p2];
00508 listas_de_referencias[Triangulo->p2] = qtr;
00509 }
00510 }
00511 }
00512
00513 void
00514 MESH::init(void)
00539 {
00540 #ifdef DEBUG_MESH
00541 int vertices_originales = arr_vertices.tam();
00542 #endif
00543 int i, acum_triangulos = 0;
00544
00545 #ifdef DEBUG_MESH
00546 printf("<MESH>: Recibo un modelo con %ld vertices\n", arr_vertices.tam());
00547 printf("<MESH>: precalculando normales para los vertices... ");
00548 fflush(stdout);
00549 #endif
00550
00551 if ( calcular_normales ) {
00552 cree_lista_de_referencias();
00553 calcule_normales_vertice();
00554 }
00555
00556
00557 #ifdef DEBUG_MESH
00558 printf("Ok!\n"); fflush(stdout);
00559 #endif
00560
00561 if ( modo_tiras_de_triangulos && ultima_tira == 0 ) crear_tiras();
00562 else if ( ultima_tira == 0 ) crear_trozos_gl();
00563
00564 #ifdef DEBUG_MESH
00565 if ( preservar_bordes ) {
00566 printf("<MESH>: Se han generado %ld vertices nuevos con normales para "
00567 "preservar\n la apariencia de los bordes en la geometria"
00568 " del modelo.\n", arr_vertices.tam() - vertices_originales);
00569 }
00570 #endif
00571
00572 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00573 acum_triangulos += arr_trozos_gl[i].arr_triangulos.tam();
00574 }
00575 #ifdef DEBUG_MESH
00576 printf("<MESH>: El modelo quedo con %ld vertices y %d triangulos\n",
00577 arr_vertices.tam(), acum_triangulos);
00578 #endif
00579
00580 preprocesada = TRUE;
00581 }
00582
00583 void
00584 MESH::promediar_normales_vertice(void)
00598 {
00599 long i, j;
00600 ARREGLO <BOOLEAN> arr_banderas(arr_vertices.tam());
00601
00602
00603 for ( i = 0; i < arr_vertices.tam(); i++ ) {
00604 arr_banderas.anx(FALSE);
00605 }
00606
00607
00608 for ( i = 0; i < arr_vertices.tam(); i++ ) {
00609
00610 if ( arr_banderas[i] ) continue;
00611 arr_banderas[i] = TRUE;
00612
00613 ARREGLO <int> arr_vecinos(100);
00614 arr_vecinos.anx(i);
00615 for ( j = i+1; j < arr_vertices.tam(); j++ ) {
00616 if ( !arr_banderas[j] &&
00617 DISTANCIA_VGL(&arr_vertices[i], &arr_vertices[j]) < 30*EPSILON
00618 ) {
00619 arr_banderas[j] = TRUE;
00620 arr_vecinos.anx(j);
00621 }
00622 }
00623
00624 VECTOR n(0, 0, 0);
00625
00626 for ( j = 0; j < arr_vecinos.tam(); j++ ) {
00627 n.x += arr_vertices[arr_vecinos[j]].nx;
00628 n.y += arr_vertices[arr_vecinos[j]].ny;
00629 n.z += arr_vertices[arr_vecinos[j]].nz;
00630 }
00631 n.normalizar();
00632 for ( j = 0; j < arr_vecinos.tam(); j++ ) {
00633 arr_vertices[arr_vecinos[j]].nx = (float)n.x;
00634 arr_vertices[arr_vecinos[j]].ny = (float)n.y;
00635 arr_vertices[arr_vecinos[j]].nz = (float)n.z;
00636 }
00637 }
00638 }
00639
00640
00641
00642 void
00643 MESH::crear_trozos_gl(void)
00651 {
00652 int i, j;
00653
00654 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00655 arr_trozos_gl[i].triangulos_gl =
00656 new TRIANGULO_GL[arr_trozos_gl[i].arr_triangulos.tam()+1];
00657 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
00658 arr_trozos_gl[i].triangulos_gl[j].p0 =
00659 arr_trozos_gl[i].arr_triangulos[j].p0;
00660 arr_trozos_gl[i].triangulos_gl[j].p1 =
00661 arr_trozos_gl[i].arr_triangulos[j].p1;
00662 arr_trozos_gl[i].triangulos_gl[j].p2 =
00663 arr_trozos_gl[i].arr_triangulos[j].p2;
00664 }
00665 }
00666
00667 #ifdef NO_FUNCIONA
00668
00669 double x1, y1, z1, nx1, ny1, nz1;
00670 double x2, y2, z2, nx2, ny2, nz2;
00671 double x3, y3, z3, nx3, ny3, nz3;
00672 VECTOR l1, l2, normal, anti_normal;
00673 int a, b, c;
00674 GLuint tmp;
00675
00676 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00677 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
00678 a = arr_trozos_gl[i].triangulos_gl[j].p0;
00679 b = arr_trozos_gl[i].triangulos_gl[j].p1;
00680 c = arr_trozos_gl[i].triangulos_gl[j].p2;
00681 nx1 = arr_vertices[a].nx;
00682 ny1 = arr_vertices[a].ny;
00683 nz1 = arr_vertices[a].nz;
00684 x1 = arr_vertices[a].x;
00685 y1 = arr_vertices[a].y;
00686 z1 = arr_vertices[a].z;
00687 nx2 = arr_vertices[b].nx;
00688 ny2 = arr_vertices[b].ny;
00689 nz2 = arr_vertices[b].nz;
00690 x2 = arr_vertices[b].x;
00691 y2 = arr_vertices[b].y;
00692 z2 = arr_vertices[b].z;
00693 nx3 = arr_vertices[c].nx;
00694 ny3 = arr_vertices[c].ny;
00695 nz3 = arr_vertices[c].nz;
00696 x3 = arr_vertices[c].x;
00697 y3 = arr_vertices[c].y;
00698 z3 = arr_vertices[c].z;
00699 normal.x = nx3;
00700 normal.y = ny3;
00701 normal.z = nz3;
00702 l1.x = x1 - x3; l1.y = y1 - y3; l1.z = z1 - z3;
00703 l2.x = x2 - x3; l2.y = y2 - y3; l2.z = z2 - z3;
00704 anti_normal = l1.producto_cruz(l2);
00705
00706 if ( anti_normal.producto_punto(normal) < 0 ) {
00707 printf("~"); fflush(stdout);
00708 tmp = arr_trozos_gl[i].triangulos_gl[j].p1;
00709 arr_trozos_gl[i].triangulos_gl[j].p1 =
00710 arr_trozos_gl[i].triangulos_gl[j].p0;
00711 arr_trozos_gl[i].triangulos_gl[j].p0 = tmp;
00712 }
00713 }
00714 }
00715 printf("Voy...\n");
00716 fflush(stdout);
00717 #endif // NO_FUNCIONA
00718
00719 }
00720
00721 void
00722 MESH::crear_tiras(void)
00730 {
00731
00732 int i,j;
00733 FILE *fd_in, *fd_out;
00734 char line[256];
00735 char filename[256];
00736 char command[256];
00737
00738 printf("<MESH> Generando tiras de triangulos para %ld trozos: [ ",
00739 arr_trozos_gl.tam());
00740 fflush(stdout);
00741
00742
00743 int longitudes_actual;
00744 int inicios_actual;
00745 BOOLEAN primera_tira;
00746
00747 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
00748 longitudes_actual = 0;
00749 inicios_actual = 0;
00750 primera_tira = TRUE;
00751
00752 sprintf(filename, "temp%d.obj", i);
00753 fd_out = fopen(filename, "w");
00754 exportar_obj(fd_out, i);
00755 fclose(fd_out);
00756
00757
00758 #if PLATAFORMA == i386_WIN32_VC
00759 sprintf(command, "stripe -p %s > shudup", filename); system(command);
00760 sprintf(command, "erase shudup"); system(command);
00761 sprintf(command, "erase %s", filename); system(command);
00762 #endif
00763 #if PLATAFORMA != i386_WIN32_VC
00764 sprintf(command, "stripe %s > /dev/null", filename); system(command);
00765 sprintf(command, "rm %s", filename); system(command);
00766 #endif
00767
00768
00769 strcat(filename, "f");
00770 fd_in = fopen(filename,"r");
00771
00772
00773 while ( fscanf(fd_in, "%s", line) != EOF ) {
00774 switch( line[0] ) {
00775 case '#':
00776 case 'v':
00777 while (fgetc(fd_in) != '\n');
00778 break;
00779 case 't':
00780 if ( primera_tira ) {
00781 primera_tira = FALSE;
00782 }
00783 else {
00784 arr_trozos_gl[i].inicios_tiras.anx(inicios_actual);
00785 arr_trozos_gl[i].longitudes_tiras.anx(longitudes_actual);
00786 longitudes_actual = 0;
00787 }
00788 break;
00789 case 'q':
00790 case '%':
00791 break;
00792 default:
00793 arr_trozos_gl[i].indices_vertices_tiras.anx((GLuint)(atoi(line)-1));
00794 inicios_actual++;
00795 longitudes_actual++;
00796 break;
00797 }
00798 }
00799 arr_trozos_gl[i].inicios_tiras.anx(inicios_actual);
00800 arr_trozos_gl[i].longitudes_tiras.anx(longitudes_actual);
00801 fclose(fd_in);
00802
00803
00804 #if PLATAFORMA == i386_WIN32_VC
00805 sprintf(command, "erase %s", filename); system(command);
00806 #endif
00807 #if PLATAFORMA != i386_WIN32_VC
00808 sprintf(command, "rm %s", filename); system(command);
00809 #endif
00810
00811 for ( j = 0; j < arr_trozos_gl[i].indices_vertices_tiras.tam(); j++ ) {
00812 if (
00813
00814
00815 arr_trozos_gl[i].indices_vertices_tiras[j] > (GLuint)(arr_vertices.tam()-1)
00816 ) {
00817 exit(-1);
00818 }
00819 }
00820 printf("."); fflush(stdout);
00821 }
00822 printf(" ] Ok.\n"); fflush(stdout);
00823 con_minmax = FALSE;
00824 }
00825
00826
00827
00828 int
00829 MESH::encontrar_material(char *name)
00830
00831 {
00832 int n;
00833
00834 for ( n = 0; n < arr_trozos_gl.tam(); n++ ) {
00835 if ( strcmp(name, arr_trozos_gl[n].material.nombre()) == 0 ) {
00836 return n;
00837 }
00838 }
00839
00840 if ( n >= arr_trozos_gl.tam() ) {
00841 if ( arr_trozos_gl.tam() ) {
00842 fprintf(stderr, "!");
00843 fflush(stderr);
00844 return 0;
00845 }
00846 fprintf(stderr, "<MESH> - ERROR: No se encuentra el material \"%s\"\n",
00847 name);
00848 fprintf(stderr, "<MESH> No hay materiales, abortando"); fflush(stderr);
00849 exit(-1);
00850 }
00851 return 0;
00852 }
00853
00854 BOOLEAN
00855 MESH::calcule_normal_triangulo(TRIANGULITO *Triangulo)
00861 {
00862 VECTOR normal, p0, p1, p2, a, b;
00863
00864 p0.x = arr_vertices[Triangulo->p0].x;
00865 p0.y = arr_vertices[Triangulo->p0].y;
00866 p0.z = arr_vertices[Triangulo->p0].z;
00867 p1.x = arr_vertices[Triangulo->p1].x;
00868 p1.y = arr_vertices[Triangulo->p1].y;
00869 p1.z = arr_vertices[Triangulo->p1].z;
00870 p2.x = arr_vertices[Triangulo->p2].x;
00871 p2.y = arr_vertices[Triangulo->p2].y;
00872 p2.z = arr_vertices[Triangulo->p2].z;
00873
00874 a = p1 - p0;
00875 b = p2 - p0;
00876 normal = a.producto_cruz(b);
00877
00878 if ( normal.norma() == 0 ) {
00879
00880 fprintf(stderr, "-"); fflush(stdout);
00881 return FALSE;
00882 }
00883
00884 normal.normalizar();
00885
00886 Triangulo->nx = (float)normal.x;
00887 Triangulo->ny = (float)normal.y;
00888 Triangulo->nz = (float)normal.z;
00889
00890 return TRUE;
00891 }
00892
00893 void
00894 MESH::anx_indice_tira(long int i)
00898 {
00899 arr_trozos_gl[0].indices_vertices_tiras.anx(i);
00900 }
00901
00902 void
00903 MESH::anx_tira(void)
00908 {
00909 long int a = arr_trozos_gl[0].indices_vertices_tiras.tam();
00910 arr_trozos_gl[0].inicios_tiras.anx(ultima_tira);
00911 arr_trozos_gl[0].longitudes_tiras.anx(a-ultima_tira);
00912 modo_tiras_de_triangulos = TRUE;
00913 ultima_tira = a;
00914 }
00915
00916 void
00917 MESH::anx_vertex(VERTICE_GL v)
00918
00919 {
00920
00921 arr_vertices.anx(v);
00922
00923
00924 vertice_promedio.x += v.x;
00925 vertice_promedio.y += v.y;
00926 vertice_promedio.z += v.z;
00927
00928
00929
00930
00931
00932 listas_de_referencias.anx(NULL);
00933 }
00934
00935 void
00936 MESH::anx_color(GLubyte r, GLubyte g, GLubyte b)
00937 {
00938 arr_colores.anx(r);
00939 arr_colores.anx(g);
00940 arr_colores.anx(b);
00941 }
00942
00943 void
00944 MESH::anx_triangle(TRIANGULO_GL tri, char *nombre_material)
00949 {
00950
00951 unsigned long int ta;
00952
00953 ta = arr_vertices.tam();
00954 if ( tri.p0 >= ta || tri.p1 >= ta || tri.p2 >= ta ) return;
00955
00956
00957
00958
00959 int MatNum;
00960 TROZO_GL *list;
00961
00962 MatNum = encontrar_material(nombre_material);
00963 list = &arr_trozos_gl[MatNum];
00964
00965
00966 TRIANGULITO t;
00967
00968 if ( _invertir_orden ) {
00969 t.p0 = tri.p0;
00970 t.p1 = tri.p2;
00971 t.p2 = tri.p1;
00972 }
00973 else {
00974 t.p0 = tri.p0;
00975 t.p1 = tri.p1;
00976 t.p2 = tri.p2;
00977 }
00978
00979
00980 if ( !calcule_normal_triangulo(&t) ) return;
00981 list->arr_triangulos.anx(t);
00982 }
00983
00984 void
00985 MESH::anx_material(COLOR ambient, COLOR diffuse, COLOR specular,
00986 char *name, char *texname, int caras_dobles)
00987
00988 {
00989
00990 COLOR e(0, 0, 0);
00991 TROZO_GL t;
00992
00993 t.material.set_nombre(name);
00994 strcpy(t.texturename, texname);
00995 t.material.set_ambiente(ambient);
00996 t.material.set_difusa(diffuse);
00997 t.material.set_especular(specular);
00998 t.material.set_emision(e);
00999 t.material.set_transparencia(1);
01000 if ( caras_dobles ) {
01001 t.material.set_doble_cara(TRUE);
01002 }
01003
01004
01005 arr_trozos_gl.anx(t);
01006 }
01007
01008
01009
01010 void
01011 MESH::anexar_textura(IMAGEN *img)
01012 {
01013 if ( imagen ) delete imagen;
01014 imagen = img;
01015 }
01016
01017 int
01018 MESH::clasificar_punto(VECTOR )
01019 {
01020 return 0;
01021 }
01022
01023 void
01024 MESH::minmax(VECTOR *min, VECTOR *max)
01025 {
01026 int i, j, k;
01027 VECTOR p;
01028
01029 if ( !preprocesada ) {
01030 init();
01031 }
01032
01033 if ( !con_minmax ) {
01034 _min.x = INFINITO;
01035 _min.y = INFINITO;
01036 _min.z = INFINITO;
01037 _max.x = -INFINITO;
01038 _max.y = -INFINITO;
01039 _max.z = -INFINITO;
01040
01041 for ( i = 0; !modo_tiras_de_triangulos && i < arr_trozos_gl.tam(); i++ ) {
01042 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
01043 p.x = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].x;
01044 p.y = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].y;
01045 p.z = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].z;
01046 COMPARAR_MM();
01047 p.x = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].x;
01048 p.y = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].y;
01049 p.z = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].z;
01050 COMPARAR_MM();
01051 p.x = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].x;
01052 p.y = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].y;
01053 p.z = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].z;
01054 COMPARAR_MM();
01055 }
01056 }
01057
01058 for ( i = 0; modo_tiras_de_triangulos && i < arr_trozos_gl.tam(); i++ ) {
01059 for ( j = 0; j < arr_trozos_gl[i].indices_vertices_tiras.tam(); j++ ) {
01060 k = arr_trozos_gl[i].indices_vertices_tiras[j];
01061 p.x = arr_vertices[k].x;
01062 p.y = arr_vertices[k].y;
01063 p.z = arr_vertices[k].z;
01064 COMPARAR_MM();
01065 p.x = arr_vertices[k].x;
01066 p.y = arr_vertices[k].y;
01067 p.z = arr_vertices[k].z;
01068 COMPARAR_MM();
01069 p.x = arr_vertices[k].x;
01070 p.y = arr_vertices[k].y;
01071 p.z = arr_vertices[k].z;
01072 COMPARAR_MM();
01073 }
01074 }
01075
01076 _min.x *= escala;
01077 _min.y *= escala;
01078 _min.z *= escala;
01079 _max.x *= escala;
01080 _max.y *= escala;
01081 _max.z *= escala;
01082 con_minmax = TRUE;
01083 }
01084 (*min) = _min;
01085 (*max) = _max;
01086 }
01087
01088 void
01089 MESH::pintar_aqz(FILE *fd)
01090 {
01091 fprintf(fd, " // Pilas: No hay pintar_aqz... \n");
01092 fprintf(fd, " geometria ESFERA 1 \"\"\n");
01093 }
01094
01095 void
01096 MESH::pintar_povray(FILE *fd)
01097 {
01098 float x1, y1, z1;
01099 float x2, y2, z2;
01100 float x3, y3, z3;
01101
01102
01103
01104 int i, j;
01105
01106 if ( !preprocesada ) init();
01107
01108 fprintf(fd, "merge {\n");
01109 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
01110 fprintf(fd, "mesh {\n");
01111 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
01112
01113
01114
01115 x1 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].x;
01116 y1 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].y;
01117 z1 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p0].z;
01118
01119
01120
01121 x2 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].x;
01122 y2 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].y;
01123 z2 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p1].z;
01124
01125
01126
01127 x3 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].x;
01128 y3 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].y;
01129 z3 = arr_vertices[arr_trozos_gl[i].triangulos_gl[j].p2].z;
01130
01131 fprintf(fd, " triangle {<%f,%f,%f>,<%f,%f,%f>,<%f,%f,%f>}\n",
01132 x1*escala, y1*escala, z1*escala, x2*escala, y2*escala,
01133 z2*escala, x3*escala, y3*escala, z3*escala);
01134
01135 #ifdef NO_FUNCIONA_ESTO_EN_POV
01136 fprintf(fd, " smooth_triangle {");
01137 fprintf(fd, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,",
01138 x1*escala, nx1, y1*escala, ny1, z1*escala, nz1);
01139 fprintf(fd, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>,",
01140 x2*escala, nx2, y2*escala, ny2, z2*escala, nz2);
01141 fprintf(fd, "<%.4f,%.4f,%.4f>,<%.4f,%.4f,%.4f>}\n",
01142 x3*escala, nx3, y3*escala, ny3, z3*escala, nz3);
01143 #endif
01144 }
01145 arr_trozos_gl[i].material.activar_povray(fd);
01146 fprintf(fd, "}");
01147 }
01148
01149
01150 }
01151
01152
01153
01154 int
01155 MESH::num_grupos(void)
01160 {
01161 return arr_trozos_gl.tam();
01162 }
01163
01164 long int
01165 MESH::num_vertices(void)
01166 {
01167 return arr_vertices.tam();
01168 }
01169
01170 long int
01171 MESH::num_triangulos(void)
01172 {
01173 int i;
01174 long int accum = 0;
01175
01176 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
01177 accum += arr_trozos_gl[i].arr_triangulos.tam();
01178 }
01179 return accum;
01180 }
01181
01182 void
01183 MESH::controlar(BOOLEAN *arr_control)
01189 {
01190 Arr_control = arr_control;
01191 #ifdef GL_ENABLED
01192 preprocesada_gl = FALSE;
01193 #endif
01194 }
01195
01196 void
01197 MESH::set_pintado_normales(BOOLEAN c)
01198 {
01199 pintar_normales = c;
01200 #ifdef GL_ENABLED
01201 preprocesada_gl = FALSE;
01202 #endif
01203 }
01204
01205 void
01206 MESH::set_debug_vertices(BOOLEAN c)
01207 {
01208 pintar_debug_vertices = c;
01209 #ifdef GL_ENABLED
01210 preprocesada_gl = FALSE;
01211 #endif
01212 }
01213
01214 void
01215 MESH::set_debug_triangulos(BOOLEAN c)
01216 {
01217 pintar_debug_triangulos = c;
01218 #ifdef GL_ENABLED
01219 preprocesada_gl = FALSE;
01220 #endif
01221 }
01222
01223 void
01224 MESH::set_debug_vertices_index(long int i)
01225 {
01226 index_debug_vertice = i;
01227 }
01228
01229 void
01230 MESH::set_debug_triangulos_index(long int i)
01231 {
01232 index_debug_triangulo = i;
01233 }
01234
01235 void
01236 MESH::set_material_global(BOOLEAN m)
01237 {
01238 material_global = m;
01239 #ifdef GL_ENABLED
01240 preprocesada_gl = FALSE;
01241 #endif
01242 }
01243
01244 void
01245 MESH::set_debug_tiras(BOOLEAN t)
01246 {
01247 mostrar_tiras = t;
01248 #ifdef GL_ENABLED
01249 preprocesada_gl = FALSE;
01250 #endif
01251 }
01252
01253 void
01254 MESH::imprimir(BOOLEAN full_report)
01255 {
01256 int i, j, num_tri;
01257 long int ttt = 0;
01258 long int tttiras = 0;
01259 long int num_con_textura = 0;
01260
01261 if ( !preprocesada ) init();
01262
01263
01264 for ( i = 0; i < arr_trozos_gl.tam(); i++ ) {
01265 if ( arr_trozos_gl[i].texturename &&
01266 strlen(arr_trozos_gl[i].texturename) ) {
01267 num_con_textura++;
01268 }
01269 }
01270
01271
01272 if ( full_report ) {
01273 printf(
01274 "= MESH ====================================================================\n"
01275 );
01276
01277 if ( _nombre_de_archivo ) {
01278 printf(" - Geometria importada del archivo \"%s\".\n",
01279 _nombre_de_archivo);
01280 }
01281
01282 printf(" - Modo: %s %s uso de listas precompiladas OpenGL\n",
01283 modo_tiras_de_triangulos?"tiras de triangulos":
01284 "triangulos sueltos",
01285 con_lista_gl?"con":"sin");
01286 #ifdef GL_COMPLETO
01287 printf(" - Usando primitivas de OpenGL 1.1 (arreglos de datos)\n");
01288 #endif
01289 #ifndef GL_COMPLETO
01290 printf(
01291 " - Usando primitivas de OpenGL 1.0 (SIN arreglos de datos)\n");
01292 #endif
01293 }
01294
01295 if ( full_report ) {
01296 printf(" - %ld vertices en la estructura\n", num_vertices());
01297 fflush(stdout);
01298 }
01299 char cc;
01300
01301 if ( arr_trozos_gl.tam() < 1 ) {
01302 printf(" - ESTRUCTURA VACIA!\n");
01303 }
01304 else {
01305 if ( full_report ) {
01306 if ( arr_trozos_gl.tam() == 1 ) {
01307 printf(" - La estructura consiste de un solo grupo\n");
01308 }
01309 else{
01310 printf(" - La estructura contiene %ld grupos:\n",
01311 arr_trozos_gl.tam());
01312 }
01313 }
01314 for ( i = 0; !modo_tiras_de_triangulos && i < arr_trozos_gl.tam(); i++ ) {
01315 if ( full_report ) {
01316 if ( !Arr_control ) {
01317 cc = '=';
01318 }
01319 else if ( Arr_control[i] ) {
01320 cc = '*';
01321 }
01322 else {
01323 cc = '.';
01324 }
01325 ;
01326 printf(" [%c] Grupo %d: %ld triangulos.\n", cc, i+1,
01327 arr_trozos_gl[i].arr_triangulos.tam());
01328 }
01329 ttt += arr_trozos_gl[i].arr_triangulos.tam();
01330 }
01331 for ( i = 0; modo_tiras_de_triangulos && i < arr_trozos_gl.tam(); i++ ) {
01332 if ( full_report ) {
01333 if ( !Arr_control ) {
01334 cc = '=';
01335 }
01336 else if ( Arr_control[i] ) {
01337 cc = '*';
01338 }
01339 else {
01340 cc = '.';
01341 }
01342 ;
01343 printf(" [%c] Grupo %2d: %3ld tiras, ", cc, i+1,
01344 arr_trozos_gl[i].longitudes_tiras.tam());
01345 }
01346 num_tri = 0;
01347 for ( j = 0; j < arr_trozos_gl[i].longitudes_tiras.tam(); j++ ) {
01348
01349 num_tri += arr_trozos_gl[i].longitudes_tiras[j];
01350 tttiras++;
01351 }
01352 if ( full_report ) {
01353 printf("%d triangulos (%.2f triangulos por tira)\n", num_tri,
01354 (double)num_tri/(double)arr_trozos_gl[i].longitudes_tiras.tam());
01355 }
01356 ttt += num_tri;
01357 }
01358 }
01359
01360 if ( full_report ) {
01361 printf(" - %ld triangulos en total.\n", ttt);
01362 printf(" - %ld nombres de textura definidos.\n", num_con_textura);
01363 printf(
01364 "===========================================================================\n"
01365 );
01366 printf("\n");
01367 }
01368 else {
01369 printf("%ld triangulos, ", ttt);
01370 if ( arr_trozos_gl.tam() != 1 ) {
01371 printf("%ld trozos, %ld referencias a textura.",
01372 arr_trozos_gl.tam(), num_con_textura);
01373 }
01374 else {
01375 printf("1 trozo.");
01376 }
01377 if ( modo_tiras_de_triangulos ) {
01378 printf(" %ld tiras, %.2f triangulos por tira, %ld referencias a textura.", tttiras,
01379 (double)ttt/(double)tttiras, num_con_textura);
01380 }
01381 if ( _nombre_de_archivo ) {
01382 printf("\t%s", _nombre_de_archivo);
01383 }
01384 printf("\n");
01385 }
01386
01387 fflush(stdout);
01388 }
01389
01390 BOOLEAN
01391 MESH::exportar_obj(FILE *fd, int i)
01396 {
01397 int j;
01398
01399 fprintf(fd, "# Archivo .obj generado por AQUYNZA\n");
01400 for ( j = 0; j < arr_vertices.tam(); j++ ) {
01401 fprintf(fd, "v %f %f %f\n",
01402 arr_vertices[j].x, arr_vertices[j].y, arr_vertices[j].z);
01403 }
01404 fprintf(fd, "\n");
01405 for ( j = 0; j < arr_trozos_gl[i].arr_triangulos.tam(); j++ ) {
01406
01407
01408 fprintf(fd,
01409 "f %d %d %d\n",
01410 arr_trozos_gl[i].arr_triangulos[j].p0+1,
01411 arr_trozos_gl[i].arr_triangulos[j].p1+1,
01412 arr_trozos_gl[i].arr_triangulos[j].p2+1);
01413 }
01414 return TRUE;
01415 }
01416
01417 void
01418 MESH::anexar_trozo_obj(char *linea)
01432 {
01433 TRIANGULO_GL t, t2, t3, t4, t5, t6, t7;
01434
01435
01436 t.p0 = 0; t.p1 = 0; t.p2 = 0;
01437 t2.p0 = 0; t2.p1 = 0; t2.p2 = 0;
01438 t3.p0 = 0; t3.p1 = 0; t3.p2 = 0;
01439 t4.p0 = 0; t4.p1 = 0; t4.p2 = 0;
01440 t5.p0 = 0; t5.p1 = 0; t5.p2 = 0;
01441 t6.p0 = 0; t6.p1 = 0; t6.p2 = 0;
01442 t7.p0 = 0; t7.p1 = 0; t7.p2 = 0;
01443
01444
01445 char *ptr;
01446 LISTA <char*> tokens;
01447 int i;
01448
01449
01450 for ( ptr = strtok(linea, " \t\n"); ptr; ptr = strtok(NULL, " \t\n") ) {
01451 tokens.anx(ptr);
01452 }
01453 for ( i = 0; i < (int)strlen(linea); i++ ) {
01454 if ( linea[i] == '/' ) linea[i] = ' ';
01455 }
01456
01457 for ( i = 0; i < tokens.tam(); i++ ) {
01458 switch ( i ) {
01459 case 0: break;
01460 case 1: t.p0 = atoi(tokens[i]) - 1; break;
01461 case 2: t.p1 = atoi(tokens[i]) - 1; break;
01462 case 3: t.p2 = atoi(tokens[i]) - 1; break;
01463 case 4:
01464 t2.p0 = t.p0;
01465 t2.p1 = t.p2;
01466 t2.p2 = atoi(tokens[i]) - 1;
01467 anx_triangle(t2, "WG_DEFAULT");
01468 break;
01469 case 5:
01470 t3.p0 = t2.p0;
01471 t3.p1 = t2.p2;
01472 t3.p2 = atoi(tokens[i]) - 1;
01473 anx_triangle(t3, "WG_DEFAULT");
01474 break;
01475 case 6:
01476 t4.p0 = t3.p0;
01477 t4.p1 = t3.p2;
01478 t4.p2 = atoi(tokens[i]) - 1;
01479 anx_triangle(t4, "WG_DEFAULT");
01480 break;
01481 case 7:
01482 t5.p0 = t4.p0;
01483 t5.p1 = t4.p2;
01484 t5.p2 = atoi(tokens[i]) - 1;
01485 anx_triangle(t5, "WG_DEFAULT");
01486 break;
01487 case 8:
01488 t6.p0 = t5.p0;
01489 t6.p1 = t5.p2;
01490 t6.p2 = atoi(tokens[i]) - 1;
01491 anx_triangle(t6, "WG_DEFAULT");
01492 break;
01493 case 9:
01494 t7.p0 = t6.p0;
01495 t7.p1 = t6.p2;
01496 t7.p2 = atoi(tokens[i]) - 1;
01497 anx_triangle(t7, "WG_DEFAULT");
01498 break;
01499 default: break;
01500 }
01501 }
01502 anx_triangle(t, "WG_DEFAULT");
01503 tokens.elim();
01504 }
01505
01506 BOOLEAN
01507 MESH::importar_obj(char *archivo, double *Escala_optima)
01508 {
01509 FILE *fd;
01510 char linea[1024];
01511
01512
01513 fd = fopen(archivo, "rt");
01514 if ( !fd ) {
01515 fprintf(stderr, "ERROR: No se puede abrir el archivo!\n");
01516 fflush(stderr);
01517 return FALSE;
01518 }
01519 set_nombre_de_archivo(archivo);
01520
01521
01522 VECTOR min, max, factor;
01523 VECTOR accum(0, 0, 0);
01524
01525 min.x = INFINITO;
01526 min.y = INFINITO;
01527 min.z = INFINITO;
01528 max.x = -INFINITO;
01529 max.y = -INFINITO;
01530 max.z = -INFINITO;
01531
01532
01533
01534
01535 COLOR ambient, diffuse, specular;
01536
01537
01538 ambient.r = ambient.g = ambient.b = 0.2f;
01539 diffuse.r = 0.85f;
01540 diffuse.g = 0.85f;
01541 diffuse.b = 0.1f;
01542 specular.r = specular.g = specular.b = 1.0;
01543 ambient.alpha = diffuse.alpha = specular.alpha = 1.0;
01544 anx_material(ambient, diffuse, specular, "WG_DEFAULT", "", 0);
01545
01546
01547 VECTOR e;
01548 MATRIZ_4x4 R;
01549 VERTICE_GL v;
01550 char *ptr;
01551
01552
01553
01554 R.rotacion_angulos_euler(DEG2RAD(-90), 0, DEG2RAD(90));
01555
01556 while ( fgets(linea, 1023, fd) ) {
01557 if ( linea[0] == 'v' && linea[1] == ' ' ) {
01558
01559 ptr = strtok(linea, " \t\n");
01560 ptr = strtok(NULL, " \t\n");
01561 e.x = atof(ptr);
01562 ptr = strtok(NULL, " \t\n");
01563 e.y = atof(ptr);
01564 ptr = strtok(NULL, " \t\n");
01565 e.z = atof(ptr);
01566 e = R * e;
01567 accum = accum + e;
01568
01569
01570 v.x = (float)e.x;
01571 v.y = (float)e.y;
01572 v.z = (float)e.z;
01573
01574
01575
01576
01577
01578
01579
01580 if ( v.x < min.x ) min.x = v.x;
01581 if ( v.y < min.y ) min.y = v.y;
01582 if ( v.z < min.z ) min.z = v.z;
01583 if ( v.x > max.x ) max.x = v.x;
01584 if ( v.y > max.y ) max.y = v.y;
01585 if ( v.z > max.z ) max.z = v.z;
01586
01587 anx_vertex(v);
01588 }
01589 if ( linea[0] == 'f' && linea[1] == ' ' ) {
01590 anexar_trozo_obj(linea);
01591 }
01592 }
01593
01594
01595 VECTOR p;
01596 VECTOR o(0, 0, 0);
01597 int i;
01598 double theta, phi;
01599
01600 factor = max - min;
01601 *(Escala_optima) = 5/factor.norma();
01602
01603
01604
01605
01606 for ( i = 0; i < arr_vertices.tam(); i++ ) {
01607
01608 p.x = arr_vertices[i].x;
01609 p.y = arr_vertices[i].y;
01610 p.z = arr_vertices[i].z;
01611 p = p - o;
01612 p.normalizar();
01613
01614 phi = acos(p.z);
01615 if ( fabs(sin(phi)) < EPSILON ) theta = 0;
01616 if ( p.y > -EPSILON ) theta = acos(p.x/sin(phi));
01617 else theta = 2*PI - acos(p.x/sin(phi));
01618
01619 theta /= 2*PI;
01620 phi /= -PI;
01621 while( phi < 0 ) phi += 1;
01622 while( theta < 0 ) theta += 1;
01623 while( phi > 1 ) phi -= 1;
01624 while( theta > 1 ) theta -= 1;
01625
01626
01627
01628 arr_vertices[i].u = (float)(theta);
01629
01630
01631
01632 arr_vertices[i].v = (float)(phi);
01633 }
01634
01635
01636 calcular_normales = TRUE;
01637
01638 return TRUE;
01639 }
01640
01641
01642
01643
01644