00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "jed_gl.h"
00023 #include "lista.cc"
00024 #include "core/cosas/cosa.h"
00025 #include "toolkits/media/jed_img.h"
00026 #include "toolkits/geom/mesh.h"
00027 #include "toolkits/util/3dsload.h"
00028 #include "matriz4.h"
00029
00030 #include "core/cosas/espacio.h"
00031
00032 #include <ctype.h>
00033 #include <string.h>
00034 #include <stdlib.h>
00035
00036
00037
00038
00039
00040 #define ESPERO(tipo, msg) \
00041 if ( tipo_token != (tipo) ) { \
00042 fprintf(stderr, "<COSA> ERROR: Esperaba %s y recibi [%s].\n", \
00043 (msg), cad); fflush(stderr); return FALSE; \
00044 }
00045
00046
00047
00048
00049
00050 COSA::COSA()
00053 {
00054
00055 _masa = 1.0f;
00056 _ke = 0.7f;
00057
00058 _posicion.x = 0;
00059 _posicion.y = 0;
00060 _posicion.z = 0;
00061 _velocidad.x = 0;
00062 _velocidad.y = 0;
00063 _velocidad.z = 0;
00064 _estoy_fijo = FALSE;
00065 Padre = NULL;
00066 _nombre_padre = NULL;
00067 _tipo_de_cosa = CC_DESCONOCIDA;
00068
00069
00070 if ( LOS_materiales.tam() < 1 ) {
00071 Material = new MATERIAL;
00072 if ( !Material ) { exit(1); }
00073 LOS_materiales.anx(Material);
00074 }
00075 Material = LOS_materiales[0];
00076 _color = Material->difusa();
00077 }
00078
00079 COSA::~COSA()
00080 {
00081 ;
00082 }
00083
00084 int COSA::tipo_de_cosa(void) { return _tipo_de_cosa; }
00085 BOOLEAN COSA::estoy_fijo(void) { return _estoy_fijo; }
00086 COLOR COSA::color(void) { return _color; }
00087 MATERIAL * COSA::material(void) { return Material; }
00088
00089 double
00090 COSA::altura(VECTOR p)
00096 {
00097 if ( _tipo_de_cosa == CC_ESPACIO_ABIERTO ) {
00098 return ((ESPACIO_ABIERTO*)this)->altura_espacio(p);
00099 }
00100 return 0;
00101 }
00102
00103 VECTOR
00104 COSA::posicion(void)
00110 {
00111 return _posicion;
00112 }
00113
00114 VECTOR
00115 COSA::posicion_absoluta(VECTOR )
00122 {
00123
00124
00125
00126
00127 return _posicion;
00128
00129 }
00130
00131 QUATERNION
00132 COSA::orientacion_absoluta(void)
00139 {
00140 QUATERNION resultado;
00141
00142 if ( Padre ) {
00143 resultado = Padre->orientacion_absoluta() * resultado;
00144 }
00145 resultado.normalizar();
00146 return resultado;
00147 }
00148
00149 static VECTOR TMP_vector;
00150 static double TMP_double;
00151
00152 BOOLEAN
00153 COSA::consultar_variable(const char *nombre_variable, int &tipo, void **ref)
00163 {
00164 VECTOR centro_de_masa(0, 0, 0);
00165
00166 if ( strcmp(nombre_variable, "masa") == 0 ) {
00167 tipo = T_FLOAT; (*ref) = &_masa; return TRUE;
00168 }
00169
00170
00171 else if ( strcmp(nombre_variable, "x") == 0 ) {
00172 tipo = T_FLOAT; (*ref) = &_posicion.x; return TRUE;
00173 }
00174 else if ( strcmp(nombre_variable, "y") == 0 ) {
00175 tipo = T_FLOAT; (*ref) = &_posicion.y; return TRUE;
00176 }
00177 else if ( strcmp(nombre_variable, "z") == 0 ) {
00178 tipo = T_FLOAT; (*ref) = &_posicion.z; return TRUE;
00179 }
00180 else if ( strcmp(nombre_variable, "altura") == 0 ) {
00181 tipo = T_FLOAT;
00182 TMP_double = 0;
00183 if ( Padre ) {
00184 TMP_double = Padre->altura(_posicion);
00185 }
00186 (*ref) = &TMP_double;
00187 return TRUE;
00188 }
00189 else if ( strcmp(nombre_variable, "posicion") == 0 ) {
00190 TMP_vector = posicion_absoluta(centro_de_masa);
00191 tipo = T_VECTOR; (*ref) = &TMP_vector; return TRUE;
00192 }
00193 else if ( strcmp(nombre_variable, "velocidad") == 0 ) {
00194 tipo = T_VECTOR; (*ref) = &_velocidad; return TRUE;
00195 }
00196 ;
00197 return FALSE;
00198 }
00199
00200 BOOLEAN
00201 COSA::actualizar_variable(const char *nombre_variable, int tipo, void *ref)
00202 {
00203
00204 #ifdef NONONO
00205 if ( strcmp(nombre_variable, "masa") == 0 ) {
00206 tipo = T_FLOAT; (*ref) = &_masa; return TRUE;
00207 }
00208
00209
00210 else
00211 else if ( strcmp(nombre_variable, "posicion") == 0 ) {
00212 TMP_vector = posicion_absoluta(centro_de_masa);
00213 tipo = T_VECTOR; (*ref) = &TMP_vector; return TRUE;
00214 }
00215 else
00216 #endif
00217
00218 if ( strcmp(nombre_variable, "velocidad") == 0 && tipo == T_VECTOR ) {
00219 set_velocidad_absoluta( *((VECTOR*)ref) );
00220 return TRUE;
00221 }
00222 else if ( strcmp(nombre_variable, "posicion")==0 && tipo == T_VECTOR ) {
00223 _posicion = ( *((VECTOR*)ref) );
00224 return TRUE;
00225 }
00226 else if ( strcmp(nombre_variable, "x") == 0 && tipo == T_FLOAT ) {
00227 _posicion.x = ( *((double*)ref) );
00228 return TRUE;
00229 }
00230 else if ( strcmp(nombre_variable, "y") == 0 && tipo == T_FLOAT ) {
00231 _posicion.y = ( *((double*)ref) );
00232 return TRUE;
00233 }
00234 else if ( strcmp(nombre_variable, "z") == 0 && tipo == T_FLOAT ) {
00235 _posicion.z = ( *((double*)ref) );
00236 return TRUE;
00237 }
00238 else if ( strcmp(nombre_variable, "altura") == 0 && tipo == T_FLOAT ) {
00239 double altura_actual, altura_deseada;
00240
00241 altura_deseada = ( *((double*)ref) );
00242 if ( Padre ) {
00243 altura_actual = Padre->altura(_posicion);
00244 _posicion.z += (altura_deseada - altura_actual);
00245 }
00246 else {
00247 _posicion.z = altura_deseada;
00248 }
00249 return TRUE;
00250 }
00251 ;
00252 return FALSE;
00253 }
00254
00255 char *
00256 COSA::nombre_padre(void) {
00257 return _nombre_padre;
00258 }
00259
00260 void
00261 COSA::asociar_padre(COSA *p)
00262 {
00263 Padre = p;
00264 }
00265
00266 COSA *
00267 COSA::crear_copia(void)
00273 {
00274 return NULL;
00275 }
00276
00277 BOOLEAN
00278 COSA::resolver(LISTA <COSA *> * )
00279 {
00280 return TRUE;
00281 }
00282
00283 void
00284 COSA::leer_material(char *nombre)
00285 {
00286 int i;
00287
00288 des_comille(nombre);
00289 for ( i = 0; i < LOS_materiales.tam(); i++ ) {
00290 if ( strcmp(nombre, LOS_materiales[i]->nombre()) == 0 ) {
00291 Material = LOS_materiales[i];
00292 return;
00293 }
00294 }
00295 fprintf(stderr,
00296 "<COSA> Warning: no se encuentra el material \"%s\".\n"
00297 "Tomando el material por defecto.\n", nombre);
00298 }
00299
00300 void
00301 COSA::grabar_basico(FILE *fd)
00302 {
00303 char n1[200];
00304 char n2[200];
00305 char n3[200];
00306
00307 sprintf(n1, "%f", _posicion.x); simplifique_real(n1);
00308 sprintf(n2, "%f", _posicion.y); simplifique_real(n2);
00309 sprintf(n3, "%f", _posicion.z); simplifique_real(n3);
00310 fprintf(fd, " posicion <%s, %s, %s>, ", n1, n2, n3);
00311
00312 sprintf(n1, "%f", _velocidad.x); simplifique_real(n1);
00313 sprintf(n2, "%f", _velocidad.y); simplifique_real(n2);
00314 sprintf(n3, "%f", _velocidad.z); simplifique_real(n3);
00315 fprintf(fd, "velocidad <%s, %s, %s>\n", n1, n2, n3);
00316
00317 sprintf(n1, "%f", _masa); simplifique_real(n1);
00318 fprintf(fd, " masa %s, ", n1);
00319
00320 sprintf(n1, "%f", _ke); simplifique_real(n1);
00321 fprintf(fd, "ke %s,\n", n1);
00322 }
00323
00324 BOOLEAN
00325 COSA::leer_basico(TOKENIZADOR *Sabiondo, char *cad, BOOLEAN *cmc)
00333 {
00334 int tipo_token = TK_DESCONOCIDO;
00335 int i;
00336
00337 if ( strcmp(cad, "posicion") == 0 ) {
00338 tipo_token = Sabiondo->siguiente_token(cad);
00339 ESPERO(TK_VECTOR_INICIO, "el inicio de un VECTOR");
00340 _posicion.x = atof(&cad[1]);
00341 tipo_token = Sabiondo->siguiente_token(cad);
00342 ESPERO(TK_NUMERO, "un numero (dato 2 de un VECTOR)");
00343 _posicion.y = atof(cad);
00344 tipo_token = Sabiondo->siguiente_token(cad);
00345 ESPERO(TK_VECTOR_FIN, "el final de un VECTOR");
00346 cad[strlen(cad) - 1] = '\0';
00347 _posicion.z = atof(cad);
00348 }
00349 else if ( strcmp(cad, "velocidad") == 0 ) {
00350 tipo_token = Sabiondo->siguiente_token(cad);
00351 ESPERO(TK_VECTOR_INICIO, "el inicio de un VECTOR");
00352 _velocidad.x = atof(&cad[1]);
00353 tipo_token = Sabiondo->siguiente_token(cad);
00354 ESPERO(TK_NUMERO, "un numero (dato 2 de un VECTOR)");
00355 _velocidad.y = atof(cad);
00356 tipo_token = Sabiondo->siguiente_token(cad);
00357 ESPERO(TK_VECTOR_FIN, "el final de un VECTOR");
00358 cad[strlen(cad) - 1] = '\0';
00359 _velocidad.z = atof(cad);
00360 }
00361 else if ( strcmp(cad, "masa") == 0 ) {
00362 tipo_token = Sabiondo->siguiente_token(cad);
00363 ESPERO(TK_NUMERO, "un numero");
00364 _masa = atof(cad);
00365 }
00366 else if ( strcmp(cad, "ke") == 0 ) {
00367 tipo_token = Sabiondo->siguiente_token(cad);
00368 ESPERO(TK_NUMERO, "un numero");
00369 _ke = atof(cad);
00370 if ( _ke > 1 ) _ke = 1;
00371 if ( _ke < 0 ) _ke = 0;
00372 }
00373 else if ( strcmp(cad, "estoy_fijo") == 0 ) {
00374 tipo_token = Sabiondo->siguiente_token(cad);
00375 ESPERO(TK_IDENTIFICADOR, "un identificador (4)");
00376 for ( i = 0; cad[i]; i++ ) cad[i] = (char)toupper(cad[i]);
00377 if ( strstr(cad, "TRUE") || strstr(cad, "SI") ) {
00378 _estoy_fijo = TRUE;
00379 }
00380 else {
00381 _estoy_fijo = FALSE;
00382 }
00383 }
00384 else if ( strcmp(cad, "material") == 0 ) {
00385 tipo_token = Sabiondo->siguiente_token(cad);
00386 ESPERO(TK_CADENA, "una cadena");
00387 leer_material(cad);
00388 }
00389 else if ( strcmp(cad, "color") == 0 ) {
00390 tipo_token = Sabiondo->siguiente_token(cad);
00391 ESPERO(TK_VECTOR_INICIO, "el inicio de un COLOR");
00392 _color.r = (float)atof(&cad[1]);
00393 tipo_token = Sabiondo->siguiente_token(cad);
00394 ESPERO(TK_NUMERO, "un numero (dato 2 de un COLOR)");
00395 _color.g = (float)atof(cad);
00396 tipo_token = Sabiondo->siguiente_token(cad);
00397 ESPERO(TK_VECTOR_FIN, "el final de un COLOR");
00398 cad[strlen(cad) - 1] = '\0';
00399 _color.b = (float)atof(cad);
00400 (*cmc) = TRUE;
00401 }
00402 else if ( strcmp(cad, "padre") == 0 ) {
00403 tipo_token = Sabiondo->siguiente_token(cad);
00404 ESPERO(TK_CADENA, "el nombre de una cosa padre");
00405 des_comille(cad);
00406 _nombre_padre = new char[strlen(cad) + 1];
00407 if ( !_nombre_padre ) {
00408 fprintf(stderr, "<COSA> - ERROR: "
00409 "No hay memoria!\n");
00410 fflush(stderr);
00411 return FALSE;
00412 }
00413 strcpy(_nombre_padre, cad);
00414 }
00415
00416 return TRUE;
00417 }
00418
00419 void
00420 COSA::limpiar_fuerzas(void)
00421 {
00422 int i;
00423
00424 for ( i = 0; i < lista_fuerzas_externas.tam(); i++ ) {
00425 delete lista_fuerzas_externas[i];
00426 }
00427 lista_fuerzas_externas.elim();
00428 }
00429
00430 void
00431 COSA::aplicar_campo_vectorial(CAMPO_VECTORIAL *Campo)
00432 {
00433 VECTOR centro_de_masa(0,0,0);
00434 VECTOR p = posicion_absoluta(centro_de_masa);
00435
00436
00437 anexar_fuerza(Campo->valor(p) * _masa, p);
00438 }
00439
00440 void
00441 COSA::aplicar_drag(double Kd)
00442 {
00443 VECTOR centro_de_masa(0,0,0);
00444
00445
00446 anexar_fuerza(velocidad_absoluta() * Kd,
00447 posicion_absoluta(centro_de_masa));
00448 }
00449
00450 double
00451 COSA::interseccion(RAYO * , VECTOR * , VECTOR * )
00455 {
00456
00457 printf("Guepa!\n"); fflush(stdout);
00458
00459 return 0;
00460 }
00461
00462 VECTOR
00463 COSA::velocidad_angular_absoluta(void)
00464 {
00465 VECTOR nulo(0, 0, 0);
00466
00467
00468 return nulo;
00469 }
00470
00471 void
00472 COSA::set_velocidad_angular_absoluta(VECTOR )
00473 {
00474 ;
00475 }
00476
00477 MATRIZ_4x4
00478 COSA::tensor_de_inercia(void)
00479 {
00480 MATRIZ_4x4 identidad;
00481
00482 return identidad;
00483 }
00484
00485 void
00486 COSA::pintar_povray(FILE *fd)
00487 {
00488 fprintf(fd, "// <COSA> - WARNING: hay algo no definido!\n");
00489 }
00490
00491
00492
00493
00494
00495 COSA_FLEXIBLE::COSA_FLEXIBLE() : COSA()
00496 {
00497 ;
00498 }
00499
00500 COSA_FLEXIBLE::~COSA_FLEXIBLE()
00501 {
00502 ;
00503 }
00504
00505
00506
00507
00508