00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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;
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
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
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));
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
00238 GLfloat global_ambient[] = {0, 0, 0, 1};
00239 GLfloat global_twoside[] = {GL_TRUE};
00240
00241 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
00242 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, global_twoside);
00243 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
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
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
00296
00297
00298
00299
00300
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);
00310
00311
00312
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
00338
00339