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

e_abierto.C

Ir a la documentación de este archivo.
00001 
00002 //===========================================================================
00003 //= e_abierto.cc                                             Enero del 2000 =
00004 //=-------------------------------------------------------------------------=
00005 //= Definicion de ESPACIO_ABIERTO                                           =
00006 //=-------------------------------------------------------------------------=
00007 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00008 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00009 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00010 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00011 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00012 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00013 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00014 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00015 //=-------------------------------------------------------------------------=
00016 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00017 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00018 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00019 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00020 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00021 //===========================================================================
00022 
00023 #include "core/cosas/espacio.h"
00024 
00025 #ifdef VEL_ROSITA
00026     #include "core/cosas/e_abierto.h"
00027 #endif
00028 
00029 #include "arreglo.cc"
00030 #include "lista.cc"
00031 #include "toolkits/util/regexp.h"
00032 
00033 #include <ctype.h>
00034 #include <string.h>
00035 #include <stdlib.h>
00036 
00037 //===========================================================================
00038 //= VARIABLES GLOBALES Y MACROS                                             =
00039 //===========================================================================
00040 
00041 #define ESPERO(tipo, msg) \
00042     if ( tipo_token != (tipo) ) { \
00043      fprintf(stderr, "<ESPACIO_ABIERTO> ERROR: Esperaba %s y recibi [%s].\n", \
00044           (msg), cad); fflush(stderr);  return FALSE; \
00045     }
00046 
00047 
00048 #define GENERAR_ESQUINAS(e)                                     \
00049     (e)[0].x = mmi.x;    (e)[0].y = mmi.y;    (e)[0].z = mmi.z; \
00050     (e)[1].x = mmx.x;    (e)[1].y = mmi.y;    (e)[1].z = mmi.z; \
00051     (e)[2].x = mmi.x;    (e)[2].y = mmi.y;    (e)[2].z = mmx.z; \
00052     (e)[3].x = mmx.x;    (e)[3].y = mmi.y;    (e)[3].z = mmx.z; \
00053     (e)[4].x = mmi.x;    (e)[4].y = mmx.y;    (e)[4].z = mmi.z; \
00054     (e)[5].x = mmx.x;    (e)[5].y = mmx.y;    (e)[5].z = mmi.z; \
00055     (e)[6].x = mmi.x;    (e)[6].y = mmx.y;    (e)[6].z = mmx.z; \
00056     (e)[7].x = mmx.x;    (e)[7].y = mmx.y;    (e)[7].z = mmx.z;
00057 
00058 //===========================================================================
00059 //= Clase ESPACIO_ABIERTO                                                   =
00060 //===========================================================================
00061 
00062 ESPACIO_ABIERTO::ESPACIO_ABIERTO() : ESPACIO(), arr_parches(1)
00063 {
00064     target_xpos = 12654; // Por sobre bogota...
00065     target_ypos = 10190;
00066     target_xtam = 250;
00067     target_ytam = 250;
00068     Dem = NULL;
00069     Paleta = NULL;
00070     preprocesada = FALSE;
00071     _escala = 1.0/10000.0;
00072     _exageracion = 1;
00073     _tipo_de_cosa = CC_ESPACIO_ABIERTO;
00074 }
00075 
00076 ESPACIO_ABIERTO::~ESPACIO_ABIERTO()
00077 {
00078     int i;
00079 
00080     for ( i = 0; i < arr_parches.tam(); i++ ) {
00081         delete arr_parches[i];
00082     }
00083     arr_parches.elim();
00084     if ( Paleta ) delete Paleta;
00085     if ( Medio ) delete Medio;
00086     Medio = FALSE;
00087 }
00088 
00089 BOOLEAN
00090 ESPACIO_ABIERTO::leer_espacio(TOKENIZADOR *Sabiondo, LISTA <GLOBAL_DEM *> *Lst)
00091 {
00092     char cad[1000];
00093     int tipo_token = TK_DESCONOCIDO, pos, i;
00094     BOOLEAN con_mi_color = FALSE;
00095     EXPRESION_REGULAR tmp;
00096 
00097     //- Ejecute el parser especifico de la COSA_RIGIDA -----------------
00098     pos = 1;
00099     while ( tipo_token != TK_CERRAR) {
00100         tipo_token = Sabiondo->siguiente_token(cad);
00101         switch ( pos ) {
00102             case 1:
00103               ESPERO(TK_CADENA, "una cadena");
00104               if ( strlen(cad) > MAX_CAD-1 ) cad[MAX_CAD-1] = '\0'; 
00105               des_comille(cad);
00106               set_nombre(cad);
00107               pos++;
00108               break;
00109             case 2:  ESPERO(TK_ABRIR, "\"{\"");  pos++; break;
00110             default:
00111               if ( tipo_token == TK_CERRAR ) break;
00112               ESPERO(TK_IDENTIFICADOR, "un identificador (3)");
00113               if ( strcmp(cad, "espacio") == 0 ) {
00114                   tipo_token = Sabiondo->siguiente_token(cad);
00115                   ESPERO(TK_CADENA, "una cadena");
00116                   // OJO: Es responsabilidad del UNIVERSO asignarme luego
00117                   // mi ESPACIO
00118                   //printf("  - espacio: %s\n", cad); 
00119                 }
00120                 else if ( strcmp(cad, "paleta") == 0 ) {
00121                   tipo_token = Sabiondo->siguiente_token(cad);
00122                   ESPERO(TK_CADENA, "una cadena (archivo de paleta)");
00123                   des_comille(cad);
00124                   Paleta = new PALETA();
00125                   if ( !Paleta || !Paleta->leer(Sabiondo) ) {
00126                       return FALSE;
00127                   }
00128                 }
00129                 else if ( strcmp(cad, "escala") == 0 ) {
00130                   tipo_token = Sabiondo->siguiente_token(cad);
00131                   ESPERO(TK_CADENA, "una cadena (expresion regular)");
00132                   des_comille(cad);
00133                   tmp.init(cad);
00134                   _escala = tmp.evaluar(0);
00135                 }
00136                 else if ( strcmp(cad, "exageracion") == 0 ) {
00137                   tipo_token = Sabiondo->siguiente_token(cad);
00138                   ESPERO(TK_CADENA, "una cadena (expresion regular)");
00139                   des_comille(cad);
00140                   tmp.init(cad);
00141                   _exageracion = tmp.evaluar(0);
00142                 }
00143                 else if ( strcmp(cad, "xpos") == 0 ) {
00144                   tipo_token = Sabiondo->siguiente_token(cad);
00145                   ESPERO(TK_NUMERO, "un numero");
00146                   target_xpos = atol(cad);
00147                 }
00148                 else if ( strcmp(cad, "ypos") == 0 ) {
00149                   tipo_token = Sabiondo->siguiente_token(cad);
00150                   ESPERO(TK_NUMERO, "un numero");
00151                   target_ypos = atol(cad);
00152                 }
00153                 else if ( strcmp(cad, "xtam") == 0 ) {
00154                   tipo_token = Sabiondo->siguiente_token(cad);
00155                   ESPERO(TK_NUMERO, "un numero");
00156                   target_xtam = atol(cad);
00157                 }
00158                 else if ( strcmp(cad, "ytam") == 0 ) {
00159                   tipo_token = Sabiondo->siguiente_token(cad);
00160                   ESPERO(TK_NUMERO, "un numero");
00161                   target_ytam = atol(cad);
00162                 }
00163                 else if ( strcmp(cad, "dem") == 0 ) {
00164                   tipo_token = Sabiondo->siguiente_token(cad);
00165                   ESPERO(TK_CADENA, "una cadena");
00166                   des_comille(cad);
00167                   for ( i = 0; i < Lst->tam(); i++ ) {
00168                       if ( strcmp((*Lst)[i]->nombre(), cad) == 0 ) {
00169                           Dem = (*Lst)[i];
00170                           break;
00171                       }
00172                   }
00173                 }
00174                 else if ( strcmp(cad, "MEDIO") == 0 ) {
00175                     if ( !Medio->leer(Sabiondo) ) {
00176                         fprintf(stderr, 
00177                             "<ESPACIO_ABIERTO> ERROR leyendo el MEDIO.\n");
00178                         fflush(stderr);
00179                         return FALSE;
00180                     }
00181                 }
00182                 else if ( 
00183                   !leer_basico(Sabiondo, cad, &con_mi_color) ||
00184                   !leer_rigida(Sabiondo, cad) 
00185                 ) return FALSE;
00186               ;
00187               break;
00188         }
00189     }
00190 
00191     //- Postprocesamiento de datos -------------------------------------
00192     if ( !con_mi_color ) _color = Material->difusa();
00193 
00194     if ( !Dem ) {
00195         fprintf(stderr, "<ESPACIO_ABIERTO> ERROR - "
00196             "No se tengo un DEM de donde leer altimetria!\n");
00197         fflush(stderr);
00198         return FALSE;
00199     }
00200 
00201     resolver_tensor_de_inercia(); // OJO: Depende de la geometria!
00202     init();
00203     return TRUE;
00204 }
00205 
00206 void
00207 ESPACIO_ABIERTO::init(void)
00213 {
00214     PARCHE_TERRENO *P;
00215     long int ancho_x = 20, ancho_y = 20;
00216     long int xtam = target_xtam+1;
00217     long int ytam = target_ytam+1;
00218     long int x, y, dx, dy;
00219 
00220     printf("Procesando un terreno con %ld parches: \n[", 
00221         ((xtam-1)/ancho_x)*((ytam-1)/ancho_y));
00222     fflush(stdout);
00223     for ( x = 0; x < xtam-1; x += ancho_x ) {
00224         dx = ancho_x;
00225         if ( x + dx > xtam-1 ) dx = xtam - x - 1;
00226         for ( y = 0; y < ytam-1; y += ancho_y ) {
00227             dy = ancho_y;
00228             if ( y + dy > ytam-1 )  dy = ytam - y - 1;
00229             P = new PARCHE_TERRENO;
00230             P->Geometria = 
00231                 new TERRENO(Dem, target_xpos+x, target_ypos+y, dx+3, dy+3, 
00232                             _escala, _exageracion);
00233             if ( Paleta ) {
00234                 P->Geometria->set_paleta(Paleta);
00235             }
00236             arr_parches.anx(P);
00237             P->delta_x = (double)x/(0.001/_escala);
00238             P->delta_y = -(double)y/(0.001/_escala);
00239             printf("."); fflush(stdout);
00240         }
00241     }
00242     printf("]\nOk!\n"); fflush(stdout);
00243 
00244     preprocesada = TRUE;
00245 }
00246 
00247 #ifdef GL_ENABLED
00248 void
00249 ESPACIO_ABIERTO::pintar_gl(CALIDAD_VISUAL *Calidad, CAMARA *Camara)
00250 {
00251     if ( !preprocesada ) init();
00252     Medio->activar_gl(Calidad, Camara);
00253 
00254 //#ifdef NONONO
00255 
00256     //- Inicializacion geometrica (OJO!) ------------------------------------
00257     VECTOR centro_de_masa(0, 0, 0);
00258     MATRIZ_4x4 R;
00259     VECTOR p = posicion_absoluta(centro_de_masa);
00260 
00261     glPushMatrix();
00262     glTranslatef((float)p.x, (float)p.y, (float)p.z);
00263     R.importar_quaternion(orientacion_absoluta());
00264     R.cargar_gl();
00265 
00266     //-----------------------------------------------------------------------
00267     int i, j;
00268     MATERIAL m;
00269     VECTOR mmi(0, 0, 0), mmx(1, 1, 1);
00270     VECTOR esquinas[8];
00271     GEOMETRIA *G;
00272 
00273     glTranslated(-((double)target_xtam/(0.001/_escala))/2, 
00274                 ((double)target_ytam/(0.001/_escala))/2, 0);
00275     for ( i = 0; i < arr_parches.tam(); i++ ) {
00276         G = arr_parches[i]->Geometria;
00277         G->minmax(&mmi, &mmx);
00278         GENERAR_ESQUINAS(esquinas);
00279         for ( j = 0; j < 8; j++ ) {
00280             esquinas[j].x -= ((double)target_xtam/(0.001/_escala))/2;
00281             esquinas[j].x += arr_parches[i]->delta_x;
00282             esquinas[j].y += ((double)target_ytam/(0.001/_escala))/2;
00283             esquinas[j].y += arr_parches[i]->delta_y;
00284             esquinas[j] = posicion_absoluta(esquinas[j]);
00285         }
00286         if ( !Camara->minmax_visible(esquinas) ) continue;
00287         glPushMatrix();
00288         glTranslated(arr_parches[i]->delta_x, arr_parches[i]->delta_y, 0);
00289         G->pintar_gl(Calidad, &m, Camara);
00290         glPopMatrix();
00291     }
00292     glPopMatrix();
00293 //#endif
00294 
00295     //-----------------------------------------------------------------------
00296     Medio->post_pintar_gl(Calidad, Camara);
00297 }
00298 #endif // GL_ENABLED
00299 
00300 double
00301 ESPACIO_ABIERTO::altura_espacio(VECTOR p)
00302 {
00303     //- Calcule la maxima altura que puede tener el terreno -----------------
00304     VECTOR mmi(0, 0, 0), mmx(1, 1, 1);
00305     double max_z = -INFINITO;
00306     int i;
00307 
00308     for ( i = 0; i < arr_parches.tam(); i++ ) {
00309         arr_parches[i]->Geometria->minmax(&mmi, &mmx);
00310         if ( mmx.z > max_z ) max_z = mmx.z;
00311     }
00312 
00313     //- Determine la altura basado en el metodo del rayo y la interseccion --
00314     double a;
00315     RAYO r;
00316     VECTOR d, n; // Dummies
00317 
00318     r.origen = p;
00319     r.origen.z = max_z + 1;
00320     r.direccion.x = 0;  // OJO: Esta direccion debe generalizarse para 
00321     r.direccion.y = 0;  //      permitir el concepto de "abajo" basado en
00322     r.direccion.z = -1; //      el campo gravitatorio...
00323 
00324     a = interseccion(&r, &d, &n); // OJO: Es altura 0 si no hay terreno ahi.
00325     if ( a < EPSILON ) return 0;
00326     return p.z - d.z;
00327 }
00328 
00329 void
00330 ESPACIO_ABIERTO::anexar_objetos_rayables(
00331     ARREGLO <OBJETO_RAYABLE *> & arr_objetos)
00332 {
00333     int i;
00334     OBJETO_RAYABLE *O = NULL;
00335     VECTOR p;
00336     VECTOR centro_de_masa(0, 0, 0);
00337 
00338     p = posicion_absoluta(centro_de_masa);
00339     p.x -= ( (double)target_xtam/(0.001/_escala) ) / 2;
00340     p.y += ( (double)target_ytam/(0.001/_escala) ) / 2;
00341     for ( i = 0; i < arr_parches.tam(); i++ ) {
00342         O = new OBJETO_RAYABLE;
00343         O->Geometria = arr_parches[i]->Geometria;
00344 
00345         O->posicion = p;
00346         O->posicion.x += arr_parches[i]->delta_x;
00347         O->posicion.y += arr_parches[i]->delta_y;
00348         O->R.importar_quaternion(orientacion_absoluta());
00349 
00350         O->R_i = O->R.inversa();
00351         O->ambiente = material()->ambiente();
00352         O->especular = material()->especular();
00353         O->phong_exp = material()->phong_exp();
00354         O->phong_coef = material()->phong_coef();
00355         O->difusa = color();
00356 
00357         arr_objetos.anx(O);
00358     }
00359 }
00360 
00361 double
00362 ESPACIO_ABIERTO::interseccion(RAYO *Rayo, VECTOR *Punto, VECTOR *Normal)
00363 {
00364     int i;
00365     double distancia_minima = INFINITO, d = 0, T = 0;
00366     MATRIZ_4x4 R, R_i;
00367     VECTOR po, pf, pff;
00368     VECTOR n(0, 0, 0);
00369     VECTOR p, nn;
00370     RAYO mi_rayo;
00371 
00372     R.importar_quaternion(orientacion_absoluta());
00373     R_i = R.inversa();
00374     po = posicion_absoluta(n);
00375     po.x -= ( (double)target_xtam/(0.001/_escala) ) / 2;
00376     po.y += ( (double)target_ytam/(0.001/_escala) ) / 2;
00377 
00378     for ( i = 0; i < arr_parches.tam(); i++ ) {
00379         //- Pre-acomodo el rayito para la operacion centrada en el origen ---
00380         pf = po;
00381         pf.x += arr_parches[i]->delta_x;
00382         pf.y += arr_parches[i]->delta_y;
00383 
00384         mi_rayo.origen = Rayo->origen - pf;
00385         mi_rayo.origen = R_i * mi_rayo.origen;
00386         mi_rayo.direccion = R_i * Rayo->direccion;
00387         mi_rayo.direccion.normalizar(); // Esto es necesario?
00388 
00389         //-------------------------------------------------------------------
00390         T = arr_parches[i]->Geometria->interseccion(&mi_rayo, p, nn);
00391         if ( (T > EPSILON) && (T < distancia_minima) ) {
00392             distancia_minima = T;
00393             d = T;
00394             pff = pf;
00395             (*Punto) = p;
00396             (*Normal) = nn;
00397         }
00398     }
00399 
00400     if ( d > EPSILON ) {
00401         // Retorno los resultados a coordenadas globales
00402         (*Punto)  = R * (*Punto);
00403         (*Punto)  = (*Punto) + pff;
00404         (*Normal) = R * (*Normal);
00405     }
00406     return d;
00407 }
00408 
00409 //===========================================================================
00410 //= EOF                                                                     =
00411 //===========================================================================
00412 

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.