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

terreno_lod.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= terreno.cc                                                Mayo del 2000 =
00003 //=-------------------------------------------------------------------------=
00004 //= Definicion de la clase TERRENO_LOD                                      =
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 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00016 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00017 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00018 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00019 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00020 //===========================================================================
00021 
00022 #include "toolkits/geom/geometria.h"
00023 #include "lista.cc"
00024 
00025 #ifdef VEL_ROSITA
00026     #include "toolkits/geom/terreno_lod.h"
00027 #endif
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 
00032 //===========================================================================
00033 //= Constantes y macros                                                     =
00034 //===========================================================================
00035 
00036 #define FACTOR 5000
00037 
00038 #define VERIFICAR(p)                                            \
00039     if ( !(p) ) {                                               \
00040         fprintf(stderr, "<TERRENO_LOD> ERROR: No hay memoria!\n");  \
00041         fflush(stderr);                                         \
00042         exit(1);                                                \
00043     }
00044 
00045 #ifdef GL_ENABLED
00046 static double x00, y00, z00;
00047 
00048 #define RENDER_VERTEX(v) \
00049     x00 = vertices_arr[((v).y+1)*_x_tam+((v).x+1)].x; \
00050     y00 = vertices_arr[((v).y+1)*_x_tam+((v).x+1)].y; \
00051     z00 = vertices_arr[((v).y+1)*_x_tam+((v).x+1)].z; \
00052     glVertex3d(x00, y00, z00); 
00053 #endif
00054 
00055 #define aVERTICE(v) atributos_arr[((v).y)*_x_tam + ((v).x)]
00056 #define VERTICE_VALIDO(v) \
00057     ((v)->y >= 0 && (v)->y <= _y_tam-3 && (v)->x >= 0 && (v)->x <= _x_tam-3)
00058 
00059 // OJO: Este `*EEE` es un machete!
00060 #define EEE 10
00061 #define ALTURA_MUESTRA_PA_NORMALES(x, y) (vertices_arr[(y)*_x_tam+(x)].z*EEE)
00062 
00063 //===========================================================================
00064 //= Variables globales                                                      =
00065 //===========================================================================
00066 
00107 static int normal_pattern[9][6] = {
00108     {0, 0, 0, 0, 0, 8},  // tipo 0
00109     {0, 0, 0, 2, 2, 4},  // tipo 1
00110     {0, 0, 0, 4, 4, 0},  // tipo 2
00111     {2, 2, 0, 0, 0, 4},  // tipo 3
00112     {1, 1, 2, 1, 1, 2},  // tipo 4
00113     {0, 0, 4, 2, 2, 0},  // tipo 5
00114     {4, 4, 0, 0, 0, 0},  // tipo 6
00115     {2, 2, 4, 0, 0, 0},  // tipo 7
00116     {0, 0, 8, 0, 0, 0}   // tipo 8
00117 };
00118 
00134 static int lados_primarios[6][2] = {
00135     {1, 0}, {1, -1}, {0, -1}, {-1, 0}, {-1, 1}, {0, 1}  };
00136 static int lados_secundarios[6][2] = {
00137     {1, -1}, {0, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 0}  };
00138 
00139 //#define DEBUG_LOD_PADRES 1
00140 
00141 #ifdef DEBUG_LOD_PADRES
00142 LISTA <COORDENADA_2D *> LISTA_padres;
00143 #endif
00144 
00145 //===========================================================================
00146 //= Funciones utilitarias                                                   =
00147 //===========================================================================
00148 
00149 int
00150 potencia2(int entrada)
00151 {
00152     int i;
00153 
00154     for ( i = 1; i < 32; i++ ) {
00155         if ( (0x01 << (i-1)) & entrada  ) {
00156             return i-1;
00157         }
00158     }
00159     return 0;
00160 }
00161 
00162 //===========================================================================
00163 //= Clase TERRENO_LOD                                                       =
00164 //===========================================================================
00165 
00166 TERRENO_LOD::TERRENO_LOD(GLOBAL_DEM *Fuente,
00167         long int origen_x, long int origen_y, long int xtam, long int ytam,
00168         double escala, double exageracion)
00173 {
00174     //- Preparativos basicos ------------------------------------------------
00175     imagen = NULL;
00176     VERIFICAR(Fuente);
00177     _escala = escala;
00178     nivel_anterior = 0;
00179     ptr = 0;
00180 
00181     _factor_exageracion = exageracion;
00182 
00183     //- Importacion de la geometria del terreno (vertices) ------------------
00184     long int i;
00185 
00186     _x_tam = xtam;
00187     _y_tam = ytam;
00188     dimension = potencia2(_x_tam-3);
00189     vertices_tam = xtam * ytam;
00190     vertices_arr = new VERTICE_GL[vertices_tam];
00191     atributos_arr = new _TERRENO_LOD_ATRIBUTO_VERTICE[vertices_tam];
00192 
00193     Fuente->exportar_vertices(vertices_arr, origen_x, origen_y, xtam, ytam);
00194 
00195     for ( i = 0; i < vertices_tam; i++ ) {
00196         // Inicializacion de vertices
00197         vertices_arr[i].y += 1000; // Esto corre dos fila.  Recuerde que las
00198                                    // celdas son de 1000 * 1000 metros.
00199         vertices_arr[i].x -= 1000;
00200         // Tenga en cuenta que una escala de 1/50K convierte cuadros de un
00201         // km^2 a un tamanno "manejable" (a escala de metros)...
00202         vertices_arr[i].x *= (float)escala;
00203         vertices_arr[i].y *= (float)escala;
00204         vertices_arr[i].z *= (float)escala*(float)_factor_exageracion;
00205     }
00206 
00207     //- Calculo del min-max -------------------------------------------------
00208     int x, y;
00209 
00210     _min.x = INFINITO;
00211     _min.y = INFINITO;
00212     _min.z = INFINITO;
00213     _max.x = -INFINITO;
00214     _max.y = -INFINITO;
00215     _max.z = -INFINITO;
00216     for ( y = 1; y < _y_tam-1; y++ ) {
00217         for ( x = 1; x < _x_tam-1; x++ ) {
00218             i = _x_tam * y + x;
00219             if ( vertices_arr[i].x < _min.x ) _min.x = vertices_arr[i].x;
00220             if ( vertices_arr[i].y < _min.y ) _min.y = vertices_arr[i].y;
00221             if ( vertices_arr[i].z < _min.z ) _min.z = vertices_arr[i].z;
00222             if ( vertices_arr[i].x > _max.x ) _max.x = vertices_arr[i].x;
00223             if ( vertices_arr[i].y > _max.y ) _max.y = vertices_arr[i].y;
00224             if ( vertices_arr[i].z > _max.z ) _max.z = vertices_arr[i].z;
00225         }
00226     }
00227 
00228     //- Calculo de normales -------------------------------------------------
00229     VECTOR n(0, 0, 1);
00230     for ( y = 0; y < _y_tam; y++ ) {
00231         for ( x = 0; x < _x_tam; x++ ) {
00232             n = calcule_normal(x, y);
00233             vertices_arr[y*_x_tam+x].nx = (float)n.x;
00234             vertices_arr[y*_x_tam+x].ny = (float)n.y;
00235             vertices_arr[y*_x_tam+x].nz = (float)n.z;
00236         }
00237     }
00238 }
00239 
00240 TERRENO_LOD::~TERRENO_LOD()
00241 {
00242     if ( imagen ) delete imagen;
00243     delete vertices_arr;
00244 }
00245 
00246 //= Operaciones del calculo de normales =====================================
00247 
00248 VECTOR
00249 TERRENO_LOD::calcule_subnormal(int x1, int y1, int x2, int y2, int x3, int y3)
00254 {
00255     VECTOR sub_normal, a, b;
00256     VECTOR p1; 
00257     VECTOR p2;
00258     VECTOR p3;
00259 
00260     p1.x = (float)x1;
00261     p1.y = (float)y1;
00262     p1.z = (float)ALTURA_MUESTRA_PA_NORMALES(x1, y1);
00263     p2.x = (float)x2;
00264     p2.y = (float)y2;
00265     p2.z = (float)ALTURA_MUESTRA_PA_NORMALES(x2, y2);
00266     p3.x = (float)x3;
00267     p3.y = (float)y3;
00268     p3.z = (float)ALTURA_MUESTRA_PA_NORMALES(x3, y3);
00269 
00270     a.x = (p2.x - p1.x);
00271     a.y = (p2.y - p1.y);
00272     a.z = (p2.z - p1.z);
00273     b.x = (p3.x - p1.x);
00274     b.y = (p3.y - p1.y);
00275     b.z = (p3.z - p1.z);
00276 
00277     sub_normal = a.producto_cruz(b);
00278     sub_normal.normalizar();
00279 
00280     return sub_normal;
00281 }
00282 
00283 VECTOR
00284 TERRENO_LOD::calcule_normal(int x, int y)
00290 {
00291     VECTOR normal(0, 0, 0);
00292 
00293     //- Clasificacion del vertice -------------------------------------------
00294     int tipo;
00295 
00296     if ( y == _y_tam - 1 && x == _x_tam - 1 ) tipo = 8;
00297     else if ( y == 0 && x == _x_tam - 1 ) tipo = 2;
00298     else if ( x == 0 && y == _y_tam - 1 ) tipo = 6;
00299     else if ( y == 0 && x == 0 ) tipo = 0;
00300     else if ( y == _y_tam - 1 ) tipo = 7;
00301     else if ( y == 0 ) tipo = 1;
00302     else if ( x == _x_tam - 1 ) tipo = 5;
00303     else if ( x == 0 ) tipo = 3;
00304     else tipo = 4;
00305 
00306     //- Calculo del promedio ponderado entre las normales incidentes --------
00307     int t, contribucion;
00308 
00309     for ( t = 0; t < 6; t++ ) {  // Recorra los triangulos incidentes en (x,y)
00310         contribucion = normal_pattern[tipo][t];
00311         if ( contribucion > 0 ) {
00312             VECTOR sub_normal = calcule_subnormal(
00313                 x,                           y, 
00314                 x + lados_primarios[t][0],   y + lados_primarios[t][1],
00315                 x + lados_secundarios[t][0], y + lados_secundarios[t][1]
00316             );
00317             normal.x += sub_normal.x;
00318             normal.y += sub_normal.y;
00319             normal.z += sub_normal.z;
00320         }
00321     }
00322 
00323     //- Finalle feliz -------------------------------------------------------
00324     normal = normal * (-1);
00325     normal.normalizar();
00326     return normal;
00327 }
00328 
00329 //===========================================================================
00330 
00331 void
00332 TERRENO_LOD::anexar_textura(IMAGEN *img)
00333 {
00334   #ifdef GL_ENABLED
00335     if ( imagen ) delete imagen;
00336     imagen = img;
00337   #endif
00338 }
00339 
00340 int
00341 TERRENO_LOD::clasificar_punto(VECTOR p)
00348 {
00349     double d = DISTANCIA(0, 0, 0, p.x, p.y, p.z);
00350 
00351     if ( IGUAL(1, d ) ) {
00352         return 0;
00353       }
00354       else if ( d < 1 ) {
00355         return 1;
00356     }
00357     return -1; // Notese que este es el caso "else", no usar else para que
00358                // esta funcion siempre retorne algo de manera explicita...
00359 }
00360 
00361 void
00362 TERRENO_LOD::minmax(VECTOR *min, VECTOR *max)
00363 {
00364     min->x = _min.x;
00365     min->y = _min.y;
00366     min->z = _min.z;
00367     max->x = _max.x;
00368     max->y = _max.y;
00369     max->z = _max.z;
00370 }
00371 
00372 #ifdef GL_ENABLED
00373 
00374 BOOLEAN
00375 TERRENO_LOD::elem_buffer(COORDENADA_2D &o)
00376 {
00377     if ( o == buffer[0] || o == buffer[1] ) {
00378         return TRUE;
00379     }
00380     return FALSE;
00381 }
00382 
00383 void
00384 TERRENO_LOD::toggle_ptr(void)
00385 {
00386     if ( ptr == 0 ) ptr = 1;
00387     else ptr = 0;
00388 }
00389 
00390 void
00391 TERRENO_LOD::pintar_cuadrante_gl(COORDENADA_2D l, COORDENADA_2D t, 
00392                                  COORDENADA_2D r, int nivel)
00401 {
00402     if ( nivel <= 0 ) return;                    // 1
00403     if ( !aVERTICE(t).enabled() ) return;        // 2
00404 
00405     pintar_cuadrante_gl(l, (l+r)/2, t, nivel-1); // 3
00406     if ( !elem_buffer(t) ) {                     // 4
00407         if ( (nivel + nivel_anterior) % 2 ) {    // 5
00408             toggle_ptr();                        // 6
00409           }
00410           else {                                 // 7
00411             RENDER_VERTEX(buffer[(ptr+1)%2]);    // 8
00412         }
00413         RENDER_VERTEX(t);                        // 9
00414         buffer[ptr] = t;                         // 10
00415         nivel_anterior = nivel;                  // 11
00416     }
00417     pintar_cuadrante_gl(t, (l+r)/2, r, nivel-1); // 12
00418 }
00419 
00420 void
00421 TERRENO_LOD::update_vertex(COORDENADA_2D *v)
00426 {
00427     //if ( aVERTICE(*v).locked() ) return;                              // 1
00428 
00429     int i;
00430     COORDENADA_2D parentT0, parentT1;
00431     int branchT0, branchT1;
00432 
00433     for ( i = 0; i < 4; i++ ) {                                         // 2
00434         if ( !aVERTICE(*v).dependency(i) ) {                            // 2
00435             if ( aVERTICE(*v).enabled() != aVERTICE(*v).activated() ) { // 3
00436                 aVERTICE(*v).set_enabled(~aVERTICE(*v).enabled());      // 4
00437                 consultar_padres(v, &parentT0, &parentT1,
00438                                     &branchT0, &branchT1, 1);
00439                 notify(&parentT0, branchT0, aVERTICE(*v).enabled());    // 5
00440                 notify(&parentT1, branchT1, aVERTICE(*v).enabled());    // 6
00441             }
00442         }
00443     }
00444 }
00445 
00446 void
00447 TERRENO_LOD::notify(COORDENADA_2D *v, int child, BOOLEAN state)
00452 {
00453     if ( !VERTICE_VALIDO(v) ) return;                                   // 1
00454     aVERTICE(*v).set_dependency(child, state);                          // 2
00455     //if ( aVERTICE(*v).locked() ) return;                              // 3
00456 
00457     int i;
00458     COORDENADA_2D parentT0, parentT1;
00459     int branchT0, branchT1;
00460 
00461     for ( i = 0; i < 4; i++ ) {                                         // 4
00462         if ( !aVERTICE(*v).dependency(i) ) {                            // 4
00463             if ( !aVERTICE(*v).activated() ) {                          // 5
00464                 aVERTICE(*v).set_enabled(FALSE);                        // 6
00465                 consultar_padres(v, &parentT0, &parentT1,
00466                                     &branchT0, &branchT1, 1);
00467                 notify(&parentT0, branchT0, FALSE);                     // 7
00468                 notify(&parentT1, branchT1, FALSE);                     // 8
00469             }
00470           }
00471           else {                                                        // 9
00472             if ( !aVERTICE(*v).enabled() ) {                            // 10
00473                 aVERTICE(*v).set_enabled(TRUE);                         // 11
00474                 consultar_padres(v, &parentT0, &parentT1,
00475                                     &branchT0, &branchT1, 1);
00476                 notify(&parentT0, branchT0, TRUE);                      // 12
00477                 notify(&parentT1, branchT1, TRUE);                      // 13
00478             }
00479 
00480         }
00481     }
00482 }
00483 
00484 void
00485 TERRENO_LOD::consultar_padres(COORDENADA_2D *h, 
00486                               COORDENADA_2D *p1, COORDENADA_2D *p2, 
00487                               int *i1, int *i2, int nivel)
00501 {
00502     int longitud = 0x01 << (nivel-1);
00503     int x, y;
00504     int hx, hy;
00505 
00506     hx = h->x / longitud;
00507     hy = h->y / longitud;
00508     (*i1) = 666;
00509     (*i2) = 666;
00510 
00511     if ( (hx%2) == 0 && (hy%2) != 0 ) {
00512         p1->x = h->x - longitud;
00513         p1->y = h->y;
00514         (*i1) = 1;
00515         p2->x = h->x + longitud;
00516         p2->y = h->y;
00517         (*i2) = 3;
00518       }
00519       else if ( (hx%2) != 0 && (hy%2) == 0 ) {
00520         p1->x = h->x;
00521         p1->y = h->y - longitud;
00522         (*i1) = 0;
00523         p2->x = h->x;
00524         p2->y = h->y + longitud;
00525         (*i2) = 2;
00526       }
00527       else if ( (hx%2) != 0 && (hy%2) != 0 ) {
00528         x = hx/2;
00529         y = hy/2;
00530         if ( (x%2 == 0) && (y%2 == 0) ) {
00531             p1->x = h->x - longitud;
00532             p1->y = h->y + longitud;
00533             (*i1) = 1;
00534             p2->x = h->x + longitud;
00535             p2->y = h->y - longitud;
00536             (*i2) = 3;
00537           }
00538           else if ( (x%2 != 0) && (y%2 == 0) ) {
00539             p1->x = h->x + longitud;
00540             p1->y = h->y + longitud;
00541             (*i1) = 2;
00542             p2->x = h->x - longitud;
00543             p2->y = h->y - longitud;
00544             (*i2) = 0;
00545           }
00546           else if ( (x%2 == 0) && (y%2 != 0) ) {
00547             p1->x = h->x - longitud;
00548             p1->y = h->y - longitud;
00549             (*i1) = 0;
00550             p2->x = h->x + longitud;
00551             p2->y = h->y + longitud;
00552             (*i2) = 2;
00553           }
00554           else if ( (x%2 != 0) && (y%2 != 0) ) {
00555             p1->x = h->x - longitud;
00556             p1->y = h->y + longitud;
00557             (*i1) = 1;
00558             p2->x = h->x + longitud;
00559             p2->y = h->y - longitud;
00560             (*i2) = 3;
00561           }
00562         ;
00563       }
00564       else {
00565         if ( nivel >= dimension ) {
00566             p1->x = -1;
00567             p1->y = -1;
00568             p2->x = -1;
00569             p2->y = -1;
00570             (*i1) = 4;
00571             (*i2) = 4;
00572           }
00573           else {
00574             consultar_padres(h, p1, p2, i1, i2, nivel+1);
00575         }
00576       }
00577     ;
00578 }
00579 
00580 
00581 void
00582 TERRENO_LOD::pintar_tiras_gl(void)
00591 {
00592     //- Pinte los 4 cuadrantes ---------------------------------------------
00593     int i, n;
00594     COORDENADA_2D l, t, r;
00595     int x_max, y_max;
00596     static int q[4][3][2] =  {
00597         {{0, 0}, {1, 1}, {2, 0}},  // Cuadrante q[0]
00598         {{2, 0}, {1, 1}, {2, 2}},  // Cuadrante q[1]
00599         {{2, 2}, {1, 1}, {0, 2}},  // Cuadrante q[2]
00600         {{0, 2}, {1, 1}, {0, 0}}   // Cuadrante q[3]
00601     };
00602 
00603     //- Preparativos -
00604     x_max = _x_tam - 3;
00605     y_max = _y_tam - 3;
00606     glColor3d(0.0, 0.9, 0.0);
00607     n = potencia2(x_max);
00608 
00609     //- Adaptacion del macroalgoritmo original del paper... -
00610     glBegin(GL_TRIANGLE_STRIP);           // 1 Enter triangle mesh mode
00611     l.x = q[0][0][0]*(x_max/2);           // 2 Render vertex q0l
00612     l.y = q[0][0][1]*(y_max/2);
00613     RENDER_VERTEX(l);
00614     buffer[ptr] = l;                      // 3
00615     nivel_anterior = 0;                   // 4
00616 
00617     for ( i = 0; i < 4; i++ ) {           // 5
00618         l.x = q[i][0][0]*(x_max/2);  l.y = q[i][0][1]*(y_max/2);
00619         t.x = q[i][1][0]*(x_max/2);  t.y = q[i][1][1]*(y_max/2);
00620         r.x = q[i][2][0]*(x_max/2);  r.y = q[i][2][1]*(y_max/2);
00621 
00622         if ( !(nivel_anterior % 2) ) {    // 6 if previous level is even
00623             toggle_ptr();                 // 7 toggle ptr
00624           }
00625           else {                          // 8
00626                                           // 9 swap vertices in graphics buffer
00627             RENDER_VERTEX(buffer[(ptr+1)%2]);
00628         }
00629         RENDER_VERTEX(l);                 // 10 Render vertex qil
00630         buffer[ptr] = l;                  // 11
00631         nivel_anterior = 2*n + 1;         // 12
00632         pintar_cuadrante_gl(l,t,r, 2*n);  // 13
00633     }
00634     l.x = q[i%4][0][0]*(x_max/2);         // 14 Render vertex q0l
00635     l.y = q[i%4][0][1]*(y_max/2);
00636     RENDER_VERTEX(l);
00637     glEnd();                              // 15
00638 
00639     //-----------------------------------------------------------------------
00640 #ifdef NONONO
00641     // Pintar las normales
00642     int y, x;
00643     glDisable(GL_LIGHTING);
00644     glColor3f(1, 1, 0);
00645     for ( y = 1; y < _y_tam-1; y++ ) {
00646       glBegin(GL_LINES);
00647         for ( x = 1; x < _x_tam - 1; x++ ) {
00648             glVertex3f(vertices_arr[y*_x_tam+x].x,
00649                        vertices_arr[y*_x_tam+x].y,
00650                        vertices_arr[y*_x_tam+x].z);
00651         glVertex3f(vertices_arr[y*_x_tam+x].x+vertices_arr[y*_x_tam+x].nx/4,
00652                    vertices_arr[y*_x_tam+x].y+vertices_arr[y*_x_tam+x].ny/4,
00653                    vertices_arr[y*_x_tam+x].z+vertices_arr[y*_x_tam+x].nz/4);
00654         }
00655       glEnd();
00656     }
00657 #endif
00658 
00659     //-----------------------------------------------------------------------
00660 #ifdef DEBUG_TERRENO_LOD
00661     VERTICE_GL v;
00662     int i;
00663 
00664     glDisable(GL_LIGHTING);
00665     glColor3d(color_debug.r, color_debug.g, color_debug.b);
00666     for ( i = 0; i < arr_debug_x.tam(); i++ ) {
00667         glPushMatrix();
00668         v = vertices_arr[arr_debug_y[i]*_x_tam+arr_debug_x[i]];
00669         glTranslated(v.x, v.y, v.z);
00670         pintar_cubo(0.01);
00671         glPopMatrix();
00672     }
00673 
00674 #endif
00675 
00676 }
00677 
00678 void
00679 TERRENO_LOD::pintar_gl(CALIDAD_VISUAL *Calidad, MATERIAL* Material,
00680                    CAMARA * /*Camara*/)
00681 {
00682     //----------------------------------------------------------------------
00683 #ifdef NONONO
00684     long int i;
00685 
00686     // Pintado de vertices
00687     glColor3f(1, 1, 1);
00688     glDisable(GL_LIGHTING);
00689     glBegin(GL_POINTS);
00690     for ( i = 0; i < vertices_tam; i++ ) {
00691         glVertex3fv(&vertices_arr[i].x);
00692     }
00693     glEnd();
00694 #endif
00695 
00696     //- Evaluacion del algoritmo de niveles de detalle ---------------------
00697     int x, y;
00698     COORDENADA_2D v;
00699 
00700     for ( y = 0; y < _y_tam-2; y++ ) {
00701         for ( x = 0; x < _x_tam-2; x++ ) {
00702             v.x = x; v.y = y;
00703             //if ( x == 3 && y == 0 ) {
00704             if ( vertices_arr[(v.y+1)*_x_tam+(v.x+1)].z > 0 ) {
00705                 aVERTICE(v).set_activated(TRUE);
00706               }
00707               else {
00708                 aVERTICE(v).set_activated(FALSE);
00709             }
00710             update_vertex(&v);
00711 
00712             //printf("%.2f ", vertices_arr[(v.y+1)*_x_tam+(v.x+1)].z);
00713 
00714         }
00715         printf("\n"); fflush(stdout);
00716     }
00717 
00718 #ifdef DEBUG_LOD_PADRES
00719     COORDENADA_2D *Vv, p1, p2;
00720     int i1, i2;
00721 
00722     for ( y = 0; y < _y_tam-2; y++ ) {
00723         for ( x = 0; x < _x_tam-2; x++ ) {
00724             Vv = new COORDENADA_2D;
00725             Vv->x = x;  Vv->y = y;
00726             LISTA_padres.anx(Vv);
00727 
00728             consultar_padres(Vv, &p1, &p2, &i1, &i2, 1);
00729             Vv = new COORDENADA_2D;
00730             Vv->x = p1.x;  Vv->y = p1.y;
00731             LISTA_padres.anx(Vv);       
00732 
00733             Vv = new COORDENADA_2D;
00734             Vv->x = p2.x;  Vv->y = p2.y;
00735             LISTA_padres.anx(Vv);       
00736         }
00737     }
00738 #endif
00739 
00740     //- Pintado de bordes --------------------------------------------------
00741     COLOR cb(1, 0, 0);
00742 
00743     if ( Calidad->con_bordes ) {
00744         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00745         if ( !Calidad->con_caras ) glDisable(GL_CULL_FACE);
00746         Calidad->activar_bordes_gl(cb, Material);
00747         glShadeModel(GL_SMOOTH);
00748         pintar_tiras_gl();
00749     }
00750 
00751     if ( Calidad->con_cajas ) PINTAR_MINMAX_GL();
00752 
00753     //- Pintado de caras ---------------------------------------------------
00754     COLOR c(1, 1, 1);
00755 
00756     if ( Calidad->con_caras ) {
00757         glEnable(GL_CULL_FACE);
00758         glCullFace(GL_BACK);
00759         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00760         Material->activar_gl();
00761         Calidad->activar_caras_gl(c, Material);
00762         if ( imagen && Calidad->con_textura ) {
00763             imagen->activar_gl();
00764             glEnable(GL_TEXTURE_2D);
00765             Calidad->activar_textura_gl();
00766           }
00767           else if ( Calidad->con_caustics ) {
00768             Calidad->activar_textura_gl();
00769           }
00770           else {
00771             glDisable(GL_TEXTURE_2D);
00772         }
00773 
00774         ACTIVAR_POLYGON_OFFSET();
00775 
00776         glEnable(GL_COLOR_MATERIAL);
00777         glColorMaterial(GL_FRONT, GL_DIFFUSE);
00778         pintar_tiras_gl();
00779 
00780         glDisable(GL_COLOR_MATERIAL);
00781 
00782         DESACTIVAR_POLYGON_OFFSET();
00783         glDisable(GL_TEXTURE_2D);
00784     }
00785 
00786     //-----------------------------------------------------------------------
00787 #ifdef DEBUG_LOD_PADRES
00788     long int iii, i;
00789     double xx=0.0, yy=0.0, zz=0.0;
00790     double px=0.0, py=0.0, pz=0.0;
00791     double dx=0.02, dy=0.02, dz=0.05;
00792 
00793     // Pintado de padres
00794     glDisable(GL_LIGHTING);
00795     glDisable(GL_DEPTH_TEST);
00796     for ( i = 0; i < LISTA_padres.tam(); i += 3 ) {
00797         // pinto el centro
00798         if ( VERTICE_VALIDO(LISTA_padres[i]) ) {
00799             iii = (LISTA_padres[i]->y+1) * _x_tam + (LISTA_padres[i]->x+1);
00800             xx= vertices_arr[iii].x;
00801             yy= vertices_arr[iii].y;
00802             zz= vertices_arr[iii].z;
00803             glColor3f(1, 0, 0);
00804             glBegin(GL_LINES);
00805             glVertex3f(xx-dx, yy-dy, zz+dz);
00806             glVertex3f(xx+dx, yy+dy, zz+dz);
00807             glVertex3f(xx-dx, yy+dy, zz+dz);
00808             glVertex3f(xx+dx, yy-dy, zz+dz);
00809             glEnd();
00810         }
00811 
00812         // pinto el padre 1
00813         if ( VERTICE_VALIDO(LISTA_padres[i+1]) ) {
00814             iii = (LISTA_padres[i+1]->y+1) * _x_tam + (LISTA_padres[i+1]->x+1);
00815             px= vertices_arr[iii].x;
00816             py= vertices_arr[iii].y;
00817             pz= vertices_arr[iii].z;
00818             glColor3f(1, 0.5, 0.7);
00819             glBegin(GL_LINES);
00820             glVertex3f(xx, yy, zz+dz);
00821             glVertex3f(px, py, pz);
00822             glEnd();
00823         }
00824 
00825         // pinto el padre 2
00826         if ( VERTICE_VALIDO(LISTA_padres[i+2]) ) {
00827             iii = (LISTA_padres[i+2]->y+1) * _x_tam + (LISTA_padres[i+2]->x+1);
00828             px= vertices_arr[iii].x;
00829             py= vertices_arr[iii].y;
00830             pz= vertices_arr[iii].z;
00831             glColor3f(1, 0.7, 0.5);
00832             glBegin(GL_LINES);
00833             glVertex3f(xx, yy, zz+dz);
00834             glVertex3f(px, py, pz+2*dz);
00835             glEnd();
00836         }
00837 
00838     }
00839 
00840     for ( i = 0; i < LISTA_padres.tam(); i++ ) {
00841         delete LISTA_padres[i];
00842     }
00843     LISTA_padres.elim();
00844     glEnable(GL_DEPTH_TEST);
00845 #endif
00846 
00847 
00848 }
00849 #endif
00850 
00851 void
00852 TERRENO_LOD::pintar_aqz(FILE *fd)
00853 {
00854     fprintf(fd, "    // Pilas: No hay pintar_aqz... \n");
00855     fprintf(fd, "    geometria ESFERA 1 \"\"\n");
00856 }
00857 
00858 void
00859 TERRENO_LOD::pintar_povray(FILE *fd)
00860 {
00861     fprintf(fd,
00862         "sphere {\n"
00863         "    <0, 0, 0>, %f\n",
00864         1.0
00865     );
00866 }
00867 
00868 GEOMETRIA *
00869 TERRENO_LOD::crear_copia(void)
00873 {
00874     TERRENO_LOD *e;
00875 
00876     e = new TERRENO_LOD(NULL, 0, 0, 1, 1, 1, 1);
00877     if ( !e ) return NULL;
00878 
00879     (*e) = (*this);
00880 
00881     if ( imagen ) {
00882         e->imagen = imagen->copie();
00883         if ( !e->imagen ) {
00884             fprintf(stderr,
00885             "<TERRENO_LOD> Warning: no se pudo replicar una textura.\n");
00886             fflush(stderr);
00887         }
00888     }
00889 
00890     return (GEOMETRIA *)e;
00891 }
00892 
00893 #ifdef NONONO
00894 double
00895 TERRENO_LOD::altura(double x, double y)
00899 {
00900     int i, j;
00901 
00902     i = coord2index_x(x);
00903     j = coord2index_x(y);
00904     if ( i >= 0 && i < _x_tam &&
00905          j >= 0 && j < _y_tam ) {
00906 /* OJO: ESTO ESTA MAL! Debe tenerse en cuenta los triangulos... */
00907 // Se puede hacer facil con la operacion de interseccion!
00908         return vertices_arr[(i) + _x_tam*(j)].z;
00909     }
00910     return 0;
00911 }
00912 #endif
00913 
00914 BOOLEAN
00915 TERRENO_LOD::seleccionar(RAYO *Rayito, int *i, int *j)
00916 {
00917     VECTOR p, n;
00918     if ( !interseccion(Rayito, p, n) ) return FALSE;
00919     p.x += 500*_escala;
00920     p.y += 500*_escala;
00921     (*i) = coord2index_x(p.x) + 2; // OJO! porque con + 2?
00922     (*j) = coord2index_y(p.y) - 1; // OJO! porque con - 1?
00923     return TRUE;
00924 }
00925 
00926 //===========================================================================
00927 //= EOF                                                                     =
00928 //===========================================================================
00929 

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.