static int populate_shaders(Vector *shaders) { size_t i; size_t n; hash *shader; set *S; char *name, *vshader, *fshader; if (!shaders) return -1; n = sizeVector(shaders); for(i = 0; i < n; i++) { S = CreateSet(); shader = (hash *) atVector(shaders, i); name = (char *) FindHashElement(shader, "name"); vshader = (char *) FindHashElement(shader, "vshader"); fshader = (char *) FindHashElement(shader, "fshader"); if (!name) return i; if (!vshader) return i; if (!fshader) return i; InsertSetElement(S, "name"); InsertSetElement(S, "vshader"); InsertSetElement(S, "fshader"); RegisterShaderScene(name, vshader, fshader); // clean free(name); free(vshader); free(fshader); check_and_destroy("populate_shaders", shader, S); } DestroyVector(&shaders); return -1; }
static bool containsGPolygon(GArc arc, double x, double y) { double x0, y0, x1, y1; int crossings, i, n; GPoint *p0, *p1; Vector vertices; vertices = arc->u.polygonRep.vertices; crossings = 0; n = sizeVector(vertices); if (n < 2) return false; p0 = (GPoint *) getVector(vertices, 0); x0 = p0->x; y0 = p0->y; p1 = (GPoint *) getVector(vertices, n - 1); if (p0->x == p1->x && p0->y == p1->y) n--; for (i = 1; i <= n; i++) { p1 = (GPoint *) getVector(vertices, i % n); x1 = p1->x; y1 = p1->y; if ((y0 > y) != (y1 > y) && x - x0 < (x1 - x0) * (y - y0) / (y1 - y0)) { crossings++; } x0 = x1; y0 = y1; } return (crossings % 2 == 1); }
static int populate_gobjs(Vector *gObjects) { size_t i; size_t n; hash *gobj_hash; set *S; char *fname, *dirname; if (!gObjects) return -1; n = sizeVector(gObjects); for(i = 0; i < n; i++) { S = CreateSet(); gobj_hash = (hash *) atVector(gObjects, i); fname = (char *) FindHashElement(gobj_hash, "fname"); dirname= (char *) FindHashElement(gobj_hash, "dirname"); if (!fname) return i; if (!dirname) return i; InsertSetElement(S, "fname"); InsertSetElement(S, "dirname"); SceneRegisterGObject(dirname, fname); // clean free(fname); free(dirname); check_and_destroy("populate_gobjs", gobj_hash, S); } // clean DestroyVector(&gObjects); return -1; }
static void wipe_vector(Vector *v) { size_t i, n; char *str; n = sizeVector(v); for(i = 0; i < n; ++i) { str = atVector(v, i); free(str); } DestroyVector(&v); }
void delBlocoDB(Bloco *bloco) { unsigned int i = 0; unsigned int j = sizeVector(blocos_jogo); for (; i < j; ++i) { void *pos_vec = elementAtVector(blocos_jogo, i); if (*(Bloco**)pos_vec == bloco) { delBloco(bloco); pos_vec = get_back_element(blocos_jogo); pop_backVector(blocos_jogo); } } }
static void print_vector(Vector *v) { size_t i; size_t n = sizeVector(v); if (!n) return; n--; printf("["); for( i = 0; i < n; ++i) { printf("%s,", (char *) atVector(v, i)); } printf("%s]", (char *) atVector(v, n)); }
GObject getGObjectCompound(GCompound compound, double x, double y) { Vector contents; GObject gobj; int i, n; contents = compound->u.compoundRep.contents; n = sizeVector(contents); for (i = n - 1; i >= 0; i--) { gobj = getVector(contents, i); if (containsGObject(gobj, x, y)) return gobj; } return NULL; }
MultiBoundingBoxIC::MultiBoundingBoxIC(const InputParameters & parameters) : InitialCondition(parameters), _c1(getParam<std::vector<Point>>("corners")), _c2(getParam<std::vector<Point>>("opposite_corners")), _nbox(_c1.size()), _dim(_fe_problem.mesh().dimension()), _inside(sizeVector(getParam<std::vector<Real>>("inside"), _nbox)), _outside(getParam<Real>("outside")) { // make sure inputs are the same length if (_c2.size() != _nbox || _inside.size() != _nbox) mooseError("vector inputs must all be the same size"); }
static trfm3D *parse_trfms(Vector *trfms) { size_t i; size_t n = sizeVector(trfms); hash *trfm; trfm3D *T; T = CreateTrfm3D(); for(i = 0; i < n; ++i) { trfm = (hash *) atVector(trfms, i); apply_trfm(trfm, T); } DestroyVector(&trfms); return T; }
void freeGObject(GObject gobj) { Vector contents; int i, n; if (gobj->type == GPOLYGON) { contents = gobj->u.polygonRep.vertices; n = sizeVector(contents); for (i = 0; i < n; i++) { freeBlock(getVector(contents, i)); } freeBlock(contents); } else if (gobj->type == GCOMPOUND) { freeBlock(gobj->u.compoundRep.contents); } freeBlock(gobj); }
void removeGCompound(GCompound compound, GObject gobj) { Vector contents; int i, n; if (compound->type != GCOMPOUND) { error("remove: First argument is not a GCompound"); } contents = compound->u.compoundRep.contents; n = sizeVector(contents); for (i = 0; i < n; i++) { if (gobj == getVector(contents, i)) { removeVector(contents, i); break; } } removeOp(gobj); }
static int populate_avatars(Vector *avatars) { size_t i; size_t n; hash *avatar; char *name, *camera; char *aux; set *S; float radius; int err = 0; Avatar *newAvatar; Camera *theCamera; if(!avatars) return -1; n = sizeVector(avatars); for(i = 0; i < n; i++) { S = CreateSet(); err = 0; radius = 1.0; avatar = (hash *) atVector(avatars, i); name = (char *) FindHashElement(avatar, "name"); camera = (char *) FindHashElement(avatar, "camera"); theCamera = SceneFindCamera(camera); err += theCamera == NULL; if (!name) return i; if (!camera) return i; InsertSetElement(S, "name"); InsertSetElement(S, "camera"); err += read_hash_f(avatar, S, "radius", &radius); if (radius <= 0.0) err++; if (!err) { newAvatar = SceneRegisterAvatar(name, theCamera, radius); if(!newAvatar) { err++; } } // clean free(name); free(camera); check_and_destroy("populate_avatars", avatar, S); } return -1; }
static GRectangle getBoundsGPolygon(GPolygon poly) { Vector vertices; double xMin, yMin, xMax, yMax, x, y; int i, n; xMin = 0; yMin = 0; xMax = 0; yMax = 0; vertices = poly->u.polygonRep.vertices; n = sizeVector(vertices); for (i = 0; i < n; i++) { x = ((GPoint *) getVector(vertices, i))->x; y = ((GPoint *) getVector(vertices, i))->y; if (i == 0 || x < xMin) xMin = x; if (i == 0 || y < yMin) yMin = y; if (i == 0 || x > xMax) xMax = x; if (i == 0 || y > yMax) yMax = y; } return createGRectangle(xMin, yMin, xMax - xMin, yMax - yMin); }
int move_ball(Sprite *bola, Vector *vec_blocos) { //>>>>>>>>>>>>>>>>>>>>>> actualiza o bloco que simula a nave como um bloco para as colisões Bloco *nave_block = (Bloco*)get_back_element(vec_blocos); nave_block->sprite->x = nave_pos.x; nave_block->sprite->y = nave_pos.y; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> infos speed = sqrt(bola->xspeed * bola->xspeed + bola->yspeed * bola->yspeed); drawIntAt(pontuation, SCORE_X_POS, SCORE_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); drawIntAt(speed , SPEED_X_POS, SPEED_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); drawIntAt(lives, LIFES_X_POS, LIFES_Y_POS, NUMBER_FOREGROUND_COLOR, COUNTER_BACKGROUND, CHAR_SCALE, VIDEO_BASE_ADDRESS, codepage); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> colisão com as paredes Bool first_hit = true; //lado direito while ((bola->x + bola->width + COLLISION_DETECTION_OFFSET) > MAX_GAME_WINDOWS_X) { int new_xspeed = -abs(bola->xspeed); bola->xspeed = new_xspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); } first_hit = true; //lado esquerdo while ((bola->x - COLLISION_DETECTION_OFFSET) < MIN_GAME_WINDOWS_X) { int new_xspeed = abs(bola->xspeed); bola->xspeed = new_xspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); first_hit = false; } first_hit = true; //baixo while ((bola->y + bola->height + COLLISION_DETECTION_OFFSET) > MAX_GAME_WINDOWS_Y) { int new_yspeed = -abs(bola->yspeed); bola->yspeed = new_yspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&ground_hit); --lives; mili_sleep(10); delete_sprite(bola, VIDEO_BASE_ADDRESS); bola->x = (nave_pos.x + nave_parada->width / 2); bola->y = VRES * 0.82; bola->xspeed = 1; bola->yspeed = -2; first_hit = false; } first_hit = true; //cima while ((bola->y - COLLISION_DETECTION_OFFSET) < MIN_GAME_WINDOWS_Y) { int new_yspeed = abs(bola->yspeed); bola->yspeed = new_yspeed; animate_sprite(bola, VIDEO_BASE_ADDRESS); if (first_hit == true) play_note(&wall_hit); //mili_sleep(5000); first_hit = false; } //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Tipos de movimentos da bola para saber como calcular a colisao com os blocos unsigned int collision_type; if ((bola->xspeed >= 0) && (bola->yspeed <= 0)) collision_type = 0; if ((bola->xspeed <= 0) && (bola->yspeed < 0)) collision_type = 1; if ((bola->xspeed < 0) && (bola->yspeed >= 0)) collision_type = 2; if ((bola->xspeed > 0) && (bola->yspeed > 0)) collision_type = 3; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Calcula se ocorre colisão unsigned int size_vec_blocos = sizeVector(vec_blocos); unsigned int i; switch(collision_type) { case 0: { // bola a mover-se para NE (nordeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > (block->sprite->x - COLLISION_DETECTION_OFFSET)) && (abs(bola->x) < (block->sprite->x + block->sprite->width)) && (((bola->y + bola->height) > block->sprite->y)) && ((bola->y < (block->sprite->y + block->sprite->height + COLLISION_DETECTION_OFFSET))) ) { //determina o lado em que bateu a bola int dx = abs(bola->x + bola->width - block->sprite->x); int dy = abs(bola->y - (block->sprite->y + block->sprite->height)); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_LEFT_OFFSET_IN_XPM) && (abs(block->sprite->x + block->sprite->width - bola->x) > NAVE_RIGHT_OFFSET_IN_XPM))) { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 1: { // bola a mover-se para NO (noroeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > block->sprite->x) && (abs(bola->x) < (block->sprite->x + block->sprite->width + COLLISION_DETECTION_OFFSET)) && ((bola->y + bola->height) > block->sprite->y) && ((bola->y < (block->sprite->y + block->sprite->height + COLLISION_DETECTION_OFFSET))) ) { //determina o lado em que bateu a bola int dx = abs(block->sprite->x + block->sprite->width - bola->x); int dy = abs(block->sprite->y + block->sprite->height - bola->y); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_RIGHT_OFFSET_IN_XPM) && (abs(bola->x + bola->width - block->sprite->x) > NAVE_LEFT_OFFSET_IN_XPM))) { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de baixo do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 2: { // bola a mover-se para SO (sudueste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > block->sprite->x) && (abs(bola->x) < (block->sprite->x + block->sprite->width + COLLISION_DETECTION_OFFSET)) && ((bola->y + bola->height) > (block->sprite->y - COLLISION_DETECTION_OFFSET)) && (bola->y < (block->sprite->y + block->sprite->height)) ) { //determina o lado em que bateu a bola int dx = abs(block->sprite->x + block->sprite->width - bola->x); int dy = abs(bola->y + bola->height - block->sprite->y); //actualiza a velocidade da bola //Caso embata na nave considera apenas a parte da xpm que tem a nave if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_RIGHT_OFFSET_IN_XPM) && (abs(bola->x + bola->width - block->sprite->x)) > NAVE_LEFT_OFFSET_IN_XPM)) { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado direito do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } case 3: { // bola a mover-se para SE (sodeste) for (i = 0; i < size_vec_blocos; ++i) { Bloco* block = (Bloco*)elementAtVector(vec_blocos, i); //verifica se houve colisão (+-COLLISION_DETECTION_OFFSET para evitar sobreposição da bola com os blocos) if( (block->sprite->on_screen == true) && (abs(bola->x + bola->width) > (block->sprite->x - COLLISION_DETECTION_OFFSET)) && (abs(bola->x) < (block->sprite->x + block->sprite->width)) && ((bola->y + bola->height) > (block->sprite->y - COLLISION_DETECTION_OFFSET)) && (bola->y < (block->sprite->y + block->sprite->height)) ) { //determina o lado em que bateu a bola int dx = abs(bola->x + bola->width - block->sprite->x); int dy = abs(bola->y + bola->height - block->sprite->y); //actualiza a velocidade da bola if (block->nave == true) { if ((block->sprite->x < (block->sprite->width - NAVE_LEFT_OFFSET_IN_XPM - NAVE_RIGHT_OFFSET_IN_XPM)) //caso em que a nave esta do lado esquerdo || ((dx > NAVE_LEFT_OFFSET_IN_XPM) && (abs(block->sprite->x + block->sprite->width - bola->x)) > NAVE_RIGHT_OFFSET_IN_XPM)) { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&nave_hit); } } else { if (dx > dy) { //bateu da parte de cima do bloco int new_yspeed = -bola->yspeed; bola->yspeed = new_yspeed; } else { //bateu do lado esquerdo do bloco int new_xspeed = -bola->xspeed; bola->xspeed = new_xspeed; } play_note(&block_hit); } animate_sprite(bola, VIDEO_BASE_ADDRESS); //apaga bloco se não for a nave if (block->nave == false) { //mili_sleep(5000); block->sprite->on_screen = false; delete_sprite(block->sprite, VIDEO_BASE_ADDRESS); //acrescenta à pontuação o valor do bloco pontuation += block->pontuation; //actualiza o numeros de blocos que já foram destruidos ++blocos_destruidos; } return 0; } } break; } } animate_sprite(bola, VIDEO_BASE_ADDRESS); if (blocos_destruidos == (sizeVector(vec_blocos) - 1)) return 1; else if (lives < 0) return 2; else return 0; }
static int populate_cameras(Vector *cameras) { size_t i; size_t n; hash *camera; char *name, *type; char *aux; set *S; Vector *vpos, *vlat, *vup; float fovy, aspect, near, far; float pos[3]; float lookAt[3]; float up[3]; int err = 0; Camera *newCamera; if(!cameras) return -1; n = sizeVector(cameras); for(i = 0; i < n; i++) { S = CreateSet(); vpos = vlat = vup = NULL; err = 0; camera = (hash *) atVector(cameras, i); name = (char *) FindHashElement(camera, "name"); type = (char *) FindHashElement(camera, "type"); if (!name) return i; if (!type) return i; InsertSetElement(S, "name"); InsertSetElement(S, "type"); err += read_hash_f(camera, S, "fovy", &fovy); err += read_hash_f(camera, S, "aspect", &aspect); err += read_hash_f(camera, S, "near", &near); err += read_hash_f(camera, S, "far", &far); if (fovy < 0.0) err++; if (aspect < 0.0) err++; if (near <= 0.0) err++; if (near <= 0.0 || far < near) err++; if (strcmp("perspective", type)) { err++; fprintf(stderr, "[W] populate_cameras: unknown type camera %s. Skipping.\n", name); } vpos = FindHashElement(camera, "pos"); if (vpos) { InsertSetElement(S, "pos"); read_xyz(vpos, &pos[0], &pos[1], &pos[2]); } vlat = FindHashElement(camera, "lookAt"); if (vlat) { InsertSetElement(S, "lookAt"); read_xyz(vlat, &lookAt[0], &lookAt[1], &lookAt[2]); } vup = FindHashElement(camera, "up"); if (vup) { InsertSetElement(S, "up"); read_xyz(vup, &up[0], &up[1], &up[2]); } if (!err) { newCamera = SceneRegisterCamera(name); if(newCamera) { InitConicCamera(newCamera, fovy, aspect, near, far); if (vpos && vlat && vup) { SetCamera(newCamera, pos[0], pos[1], pos[2], lookAt[0], lookAt[1], lookAt[2], up[0], up[1], up[2]); } } else { err++; } } // clean free(name); free(type); check_and_destroy("populate_cameras", camera, S); } return -1; }
static Node *populate_nodes(hash *nodeH) { Vector *v; trfm3D *T; size_t i, n; char *name, *str; int has_gobj = 0; GObject *gobj; set *S; Node *myNode; S = CreateSet(); name = FindHashElement(nodeH, "name"); if (name) InsertSetElement(S, "name"); myNode = CreateNode(); v = FindHashElement(nodeH, "trfm"); if (v) { InsertSetElement(S, "trfm"); T = parse_trfms(v); SetTrfmNode(myNode, T); } str = FindHashElement(nodeH, "shader"); if (str) { InsertSetElement(S, "shader"); SetShaderNode(myNode, FindShaderScene(str)); free(str); } str = FindHashElement(nodeH, "gObj"); if (str) { InsertSetElement(S, "gObj"); has_gobj = 1; gobj = SceneFindNameGObject(str); if(!gobj) { fprintf(stderr, "[E] populate_node: %s not found\n", str); PrintRegisteredGobjs(); exit(1); } SetGobjNode(myNode, gobj); free(str); } v = (Vector *) FindHashElement(nodeH, "childs"); if (v) { InsertSetElement(S, "childs"); if (has_gobj) { fprintf(stderr, "[E] populate_nodes: node %s has gObj and children\n", name); exit(1); } n = sizeVector(v); for(i = 0; i < n; ++i) { AttachNode(myNode, populate_nodes((hash *) atVector(v, i))); } DestroyVector(&v); } DestroyTrfm3D(&T); check_and_destroy("populate_nodes", nodeH, S); return myNode; }
static int populate_lights(Vector *lights) { size_t i; size_t n; int s; hash *light_h; char *name, *type, *aux; Vector *v; set *S; float r, g, b, w; float rgb[3], pos4[4]; float cutoff = 30.0; float exp = 10.0; Light *l; if (!lights) return -1; n = sizeVector(lights); for(i = 0; i < n; i++) { S = CreateSet(); light_h = (hash *) atVector(lights, i); name = (char *) FindHashElement(light_h, "name"); type = (char *) FindHashElement(light_h, "type"); if (!check_light_type(type)) { fprintf(stderr, "[E] populate_lights: bad light type %s (possible values \"positional\", \"directional\", \"spotlight\")\n", type); exit(1); } if (!name) return i; if (!type) return i; InsertSetElement(S, "name"); InsertSetElement(S, "type"); l = SceneRegisterLight(name); v = (Vector *) FindHashElement(light_h, "pos"); if (v) { InsertSetElement(S, "pos"); read_xyz(v, &pos4[0], &pos4[1], &pos4[2]); pos4[3] = 1.0; if (!strcmp(type, "directional")) pos4[3] = 0.0; SetPositionLight(l, &pos4[0]); } v = (Vector *) FindHashElement(light_h, "amb"); if (v) { InsertSetElement(S, "amb"); read_xyz(v, &rgb[0], &rgb[1], &rgb[2]); SetAmbientLight(l, &rgb[0]); } v = (Vector *) FindHashElement(light_h, "dif"); if (v) { InsertSetElement(S, "dif"); read_xyz(v, &rgb[0], &rgb[1], &rgb[2]); SetDiffuseLight(l, &rgb[0]); } v = (Vector *) FindHashElement(light_h, "spec"); if (v) { InsertSetElement(S, "spec"); read_xyz(v, &rgb[0], &rgb[1], &rgb[2]); SetSpecularLight(l, &rgb[0]); } if (!strcmp(type, "spotlight")) { aux = (char *) FindHashElement(light_h, "exp"); if (aux) { InsertSetElement(S, "exp"); sscanf(aux, "%f", &exp); if (exp < 0) { fprintf(stderr, "[E] populate_lights: negative exponent\n"); exit(1); } free(aux); } aux = (char *) FindHashElement(light_h, "cutoff"); if (aux) { InsertSetElement(S, "cutoff"); sscanf(aux, "%f", &cutoff); if (exp < 0) { fprintf(stderr, "[E] populate_lights: negative cutoff\n"); exit(1); } free(aux); } rgb[0] = 0.577; rgb[1] = 0.577; rgb[2] = 0.577; v = (Vector *) FindHashElement(light_h, "spdir"); if (v) { InsertSetElement(S, "spdir"); read_xyz(v, &rgb[0], &rgb[1], &rgb[2]); } SetSpotLight(l, &rgb[0], cutoff, exp); } aux = (char *) FindHashElement(light_h, "switched"); if (aux) { InsertSetElement(S, "switched"); sscanf(aux, "%d", &s); if (!s) SwitchLight(l, 0); free(aux); } free(type); free(name); check_and_destroy("populate_lights", light_h, S); //DestroyHash(&light_h); } DestroyVector(&lights); return -1; }