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

luz.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= luz.h                                                     Marzo de 1999 =
00003 //=-------------------------------------------------------------------------=
00004 //= Definiciones de la clase LUZ.                                           =
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 "matriz4.h"
00023 #include "toolkits/entorno/luz.h"
00024 
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <stdlib.h>
00028 
00029 #include "jed_gl.h"
00030 
00031 #define ESPERO(tipo, msg) \
00032     if ( tipo_token != (tipo) ) { \
00033         fprintf(stderr, "<LUZ> ERROR: Esperaba %s y recibi [%s].\n", \
00034           (msg), cad); fflush(stderr);  return FALSE; \
00035     }
00036 
00037 static int NUM_luces = 0;
00038 
00039 //===========================================================================
00040 //= CLASE LUZ                                                               =
00041 //===========================================================================
00042 
00043 LUZ::LUZ()
00044 {
00045     _tipo = TDL_OMNIDIRECCIONAL;
00046     _color.r = _color.g = _color.b = 1.0f;
00047     _color.alpha = 1.0f;
00048     _color_sombras.r = _color_sombras.g = _color_sombras.b = 0;
00049     _color_sombras.alpha = 1.0f;
00050     _posicion.x = _posicion.y = _posicion.z = 4.0;
00051     _angulo = 60.0;
00052 
00053     MATRIZ_4x4 R; // Matriz identidad
00054 
00055     _orientacion = R.exportar_quaternion();
00056 
00057     _nombre_padre = NULL;
00058     Padre = NULL;
00059 
00060     necesito_actualizarme = TRUE;
00061     id = NUM_luces;
00062     NUM_luces++;
00063 
00064     //int luces_GL = 8;
00065 
00066     // OJO!: Esto en Mesa siempre esta retornando 0!
00067     //glGetIntegerv(GL_MAX_LIGHTS, &luces_GL);
00068 
00069 /*
00070     if ( id > luces_GL-1 ) {
00071         fprintf(stderr, "<LUZ> - Warning: OpenGL no soporta mas de %d luces.\n"
00072             "                 La %d-esima luz ha sido desactivada.\n", 
00073             id, luces_GL);
00074         fflush(stderr);
00075         id = -1;
00076         return;
00077     }
00078 */
00079 }
00080 
00081 LUZ::~LUZ()
00082 {
00083     if ( _nombre_padre ) delete _nombre_padre;
00084 }
00085 
00086 void
00087 LUZ::set_id(int i)
00090 {
00091     id = i;
00092 }
00093 
00094 void
00095 LUZ::set_color_sombras(COLOR c)
00096 {
00097     _color_sombras = c;
00098 }
00099 
00100 char *
00101 LUZ::nombre_padre(void) { 
00102     return _nombre_padre;
00103 }
00104 
00105 void
00106 LUZ::asociar_padre(ENTIDAD *p)
00107 {
00108     Padre = p;
00109 }
00110 
00111 BOOLEAN
00112 LUZ::leer(TOKENIZADOR *Sabiondo)
00113 {
00114     char cad[1000];
00115     int tipo_token = TK_DESCONOCIDO, pos;
00116     MATRIZ_4x4 R;
00117     double magnitud, yaw, pitch, roll;
00118     VECTOR direccion;
00119 
00120     pos = 1;
00121     while ( tipo_token != TK_CERRAR ) {
00122         tipo_token = Sabiondo->siguiente_token(cad);
00123         switch ( pos ) {
00124             case 1:
00125               ESPERO(TK_CADENA, "una cadena");
00126               if ( strlen(cad) > MAX_CAD-1 ) cad[MAX_CAD-1] = '\0'; 
00127               des_comille(cad);
00128               set_nombre(cad);
00129               pos++;
00130               break;
00131             case 2:  ESPERO(TK_ABRIR, "\"{\"");  pos++; break;
00132             default:
00133               if ( tipo_token == TK_CERRAR ) break;
00134               ESPERO(TK_IDENTIFICADOR, "un identificador (1)");
00135               if ( strcmp(cad, "color") == 0 ) {
00136                   tipo_token = Sabiondo->siguiente_token(cad);
00137                   ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00138                   _color.r = (float)atof(&cad[1]);
00139                   tipo_token = Sabiondo->siguiente_token(cad);
00140                   ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00141                   _color.g = (float)atof(cad);
00142                   tipo_token = Sabiondo->siguiente_token(cad);
00143                   ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00144                   cad[strlen(cad) - 1] = '\0';
00145                   _color.b = (float)atof(cad);
00146                 }
00147                 else if ( strcmp(cad, "posicion") == 0 ) {
00148                   tipo_token = Sabiondo->siguiente_token(cad);
00149                   ESPERO(TK_VECTOR_INICIO, "el inicio de un VECTOR");
00150                   _posicion.x = atof(&cad[1]);
00151                   tipo_token = Sabiondo->siguiente_token(cad);
00152                   ESPERO(TK_NUMERO, "un numero (dato 2 de un VECTOR)");
00153                   _posicion.y = atof(cad);
00154                   tipo_token = Sabiondo->siguiente_token(cad);
00155                   ESPERO(TK_VECTOR_FIN, "el final de un VECTOR");
00156                   cad[strlen(cad) - 1] = '\0';
00157                   _posicion.z = atof(cad);
00158                 }
00159                 else if ( strcmp(cad, "orientacion") == 0 ) {
00160                   tipo_token = Sabiondo->siguiente_token(cad);
00161                   ESPERO(TK_NUMERO, "un numero (magnitud de rotacion)");
00162                   magnitud = DEG2RAD(atof(cad));  // OJO: Y este signo que?
00163                   tipo_token = Sabiondo->siguiente_token(cad);
00164                   ESPERO(TK_VECTOR_INICIO, "el inicio de un VECTOR");
00165                   direccion.x = atof(&(cad[1]));
00166                   tipo_token = Sabiondo->siguiente_token(cad);
00167                   ESPERO(TK_NUMERO, "un numero (dato 2 de un VECTOR)");
00168                   direccion.y = atof(cad);
00169                   tipo_token = Sabiondo->siguiente_token(cad);
00170                   ESPERO(TK_VECTOR_FIN, "el final de un VECTOR");
00171                   cad[strlen(cad) - 1] = '\0';
00172                   direccion.z = atof(cad);
00173                   direccion.normalizar();
00174                   _orientacion.importar_angulo_eje(magnitud, direccion);
00175                 }
00176                 else if ( strcmp(cad, "orientacion_euler") == 0 ) {
00177                   tipo_token = Sabiondo->siguiente_token(cad);
00178                   ESPERO(TK_VECTOR_INICIO, "el inicio de un VECTOR");
00179                   yaw = DEG2RAD(atof(&(cad[1])));
00180                   tipo_token = Sabiondo->siguiente_token(cad);
00181                   ESPERO(TK_NUMERO, "un numero (dato 2 de un VECTOR)");
00182                   pitch = DEG2RAD(atof(cad));
00183                   tipo_token = Sabiondo->siguiente_token(cad);
00184                   ESPERO(TK_VECTOR_FIN, "el final de un VECTOR");
00185                   cad[strlen(cad) - 1] = '\0';
00186                   roll = DEG2RAD(atof(cad));
00187                   R.rotacion_angulos_euler(yaw, pitch, roll);
00188                   _orientacion = R.exportar_quaternion();
00189                 }
00190                 else if ( strcmp(cad, "angulo") == 0 ) {
00191                   tipo_token = Sabiondo->siguiente_token(cad);
00192                   ESPERO(TK_NUMERO, "un numero (angulo de luz)");
00193                   _angulo = atof(cad);
00194                 }
00195                 else if ( strcmp(cad, "exponente_foco") == 0 ) {
00196                   tipo_token = Sabiondo->siguiente_token(cad);
00197                   ESPERO(TK_NUMERO, "un numero (exponente_foco de luz)");
00198                   _exponente_foco = atof(cad);
00199                 }
00200                 else if ( strcmp(cad, "direccional") == 0 ) {
00201                   _tipo = TDL_DIRECCIONAL;
00202                 }
00203                 else if ( strcmp(cad, "omnidireccional") == 0 ) {
00204                   _tipo = TDL_OMNIDIRECCIONAL;
00205                 }
00206                 else if ( strcmp(cad, "padre") == 0 ) {
00207                     tipo_token = Sabiondo->siguiente_token(cad);
00208                     ESPERO(TK_CADENA, "el nombre de una cosa padre");
00209                     des_comille(cad);
00210                     _nombre_padre = new char[strlen(cad) + 1];
00211                     if ( !_nombre_padre ) {
00212                         fprintf(stderr, "<LUZ> - ERROR: No hay memoria!\n");
00213                         fflush(stderr);
00214                         return FALSE;
00215                     }
00216                     strcpy(_nombre_padre, cad);
00217                 }
00218               ;
00219               break;
00220         }
00221     }
00222 
00223     return TRUE;
00224 }
00225 
00226 #ifdef GL_ENABLED
00227 void
00228 LUZ::activar_gl(void)
00234 {
00235     if ( id < 0 ) return;
00236 
00237     //- Configuraciones globales del modelo de iluminacion ------------------
00238     GLfloat global_ambient[] = {0, 0, 0, 1};
00239     GLfloat global_twoside[] = {GL_TRUE};  // OJO!: Esto es ineficiente!
00240 
00241     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);   // OJO! Esta
00242     glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, global_twoside);  // cableado!
00243     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // OJO: ?
00244     glEnable(GL_LIGHTING);
00245 
00246     glEnable((GLenum)(GL_LIGHT0 + id));
00247  
00248     //-----------------------------------------------------------------------
00249     VECTOR p_pos(0, 0, 0);
00250     void *interfaz;
00251     int tipo;
00252 
00253     if ( Padre && Padre->consultar_variable("posicion", tipo, &interfaz) ) {
00254         if ( tipo == T_VECTOR ) p_pos = (*(VECTOR *)interfaz);
00255     }
00256 
00257     float position[] = {(float)(_posicion.x + p_pos.x),
00258                         (float)(_posicion.y + p_pos.y),
00259                         (float)(_posicion.z + p_pos.z),
00260                         1.0f};
00261 
00262     glLightfv((GLenum)(GL_LIGHT0 + id), GL_POSITION, position);
00263 
00264     //- Configuraciones de la direcionalidad de la luz ----------------------
00265     MATRIZ_4x4 R, R1, R2, T1, T2;
00266     VECTOR rayito(1, 0, 0);
00267     float direccion[3];
00268     QUATERNION p_ori;
00269 
00270     if ( _tipo != TDL_DIRECCIONAL ) {
00271         glLightf((GLenum)(GL_LIGHT0 + id), GL_SPOT_CUTOFF, 180);
00272       }
00273       else {
00274         T1.translacion(-_posicion.x, -_posicion.y, -_posicion.z);
00275         T2.translacion(-p_pos.x, -p_pos.y, -p_pos.z);
00276         R1.importar_quaternion(_orientacion);
00277         if ( Padre && Padre->consultar_variable("orientacion_absoluta", tipo, &interfaz) &&
00278              tipo == T_QUATERNION ) {
00279             p_ori = (*(QUATERNION *)interfaz);
00280             R2.importar_quaternion(p_ori);
00281             R = R1.inversa() * (T1 * (R2.inversa() * T2));
00282           }
00283           else {
00284             R = R1.inversa() * (T1 * T2);
00285         }
00286         rayito = R.inversa() * rayito;
00287         direccion[0] = (float)rayito.x;
00288         direccion[1] = (float)rayito.y;
00289         direccion[2] = (float)rayito.z;
00290         glLightf((GLenum)(GL_LIGHT0 + id), GL_SPOT_EXPONENT, (float)_exponente_foco);
00291         glLightf((GLenum)(GL_LIGHT0 + id), GL_SPOT_CUTOFF, (float)_angulo);
00292         glLightfv((GLenum)(GL_LIGHT0 + id), GL_SPOT_DIRECTION, direccion);
00293     }
00294 
00295     //- Solo la posicion y orientacion de actualizan incondicionalmente -----
00296   //if ( !necesito_actualizarme ) return; // OJO: Revisar si es conveniente...
00297 
00298     //- Configuracion de los parametros de esta luz -------------------------
00299     // Una luz de un color dado, en un cuarto obscuro en donde las
00300     // sombras se ven como (0.1, 0.1, 0.1)... (OJO: Esta cableado!)
00301     GLfloat color_sombras[4] = {_color_sombras.r, 
00302         _color_sombras.g, _color_sombras.b, _color_sombras.alpha}; 
00303     GLfloat color_brillitos[4] = {1.0f, 1.0f, 1.0f, 1.0f};
00304     GLfloat color_de_la_luz[4] = {_color.r, _color.g, _color.b, _color.alpha};
00305 
00306     glLightfv((GLenum)(GL_LIGHT0 + id), GL_AMBIENT, color_sombras);
00307     glLightfv((GLenum)(GL_LIGHT0 + id), GL_DIFFUSE, color_de_la_luz);
00308     glLightfv((GLenum)(GL_LIGHT0 + id), GL_SPECULAR, color_brillitos); 
00309     glEnable(GL_NORMALIZE); // OJO!: Esto no deberia ser necesario,
00310         // pero si no se usa, se danna el modelo de iluminacion...
00311         // Revisar porque pasa eso, y revisar el impacto del glScale en 
00312         // las normales...
00313 
00314     necesito_actualizarme = FALSE;
00315 }
00316 #endif // GL_ENABLED
00317 
00318 void
00319 LUZ::activar_povray(FILE *fd)
00320 {
00321     //-----------------------------------------------------------------------
00322     VECTOR p_pos(0, 0, 0), p;
00323     void *interfaz;
00324     int tipo;
00325 
00326     if ( Padre && Padre->consultar_variable("posicion", tipo, &interfaz) ) {
00327         if ( tipo == T_VECTOR ) p_pos = (*(VECTOR *)interfaz);
00328     }
00329 
00330     p = _posicion + p_pos;
00331 
00332     fprintf(fd, "light_source { <%f, %f, %f> color White}\n",
00333         p.x, p.y, p.z);
00334 }
00335 
00336 //===========================================================================
00337 //= EOF                                                                     =
00338 //===========================================================================
00339 

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.