#include #include #include "cenario.hpp" Cenario::Cenario( FILE *fp ) { // inicializa os totais total_objetos = 0; total_materiais = 0; total_luzes = 0; cor_de_fundo.read( fp ); char filename[80]; fscanf( fp, " %s ", filename ); if (strcmp(filename, "null")) { img_de_fundo = new Imagem( filename ); if (!img_de_fundo->IsValid()) { delete img_de_fundo; img_de_fundo = 0; } } else img_de_fundo = 0; } Cenario::~Cenario() { Zera(); if (img_de_fundo) delete img_de_fundo; } void Cenario::Zera() { int i; for (i=0;iIntercepta( r_vis ); if ( (t_atual > t_min) && ( objeto_proximo==-1 || t_atual < t ) ) { t = t_atual; objeto_proximo = i; } } //Houve interseção? (sem interseção: objeto_proximo = -1) if (objeto_proximo>=0) { ponto = r_vis.QualPonto(t); return( CorDoPonto( objeto_proximo, ponto, r_vis, profundidade ) ); } else return( cor_de_fundo ); } //------------------------------------------// // Correspondente ao SHADE da transparência // //------------------------------------------// Cor_rgb Cenario::CorDoPonto(int num_obj, Vetor_3D ponto, Raio r_vis, int profundidade) { int i, j=0, bool_sombra, ind_textura; float nl, t, rv, coef_reflexao, nv; static v=0; Cor_rgb final, intermediaria, ilumina; Vetor_3D normal_ponto, direcao_luz, reflexao_luz, direcao_vista, reflexao_vista; Raio sombra, reflexao; //== cálculos iniciais ==// normal_ponto = objetos[num_obj]->Normal(ponto); ind_textura = objetos[num_obj]->Indice_textura(); // calcula a direção da vista normalizada para usar no cálculo da difusa direcao_vista.Copia( r_vis.Origem() ); direcao_vista.Subtrai( r_vis.Destino() ); direcao_vista.Normaliza(); //=======================// //== loop para todas as luzes (cálculo da difusa e especular) ==/ for(i=0;iPosicao()); // Verifica se há sombra para a luz i sombra.Atribui(ponto, direcao_luz); for(j=0;jIntercepta( sombra ); if ( INSIDE(t,ZERO,1) ) //0.00001 para evitar sombra de objetos sobrepostos { bool_sombra = 1; break; } } // Se não houver sombra if ( !bool_sombra ) { //calcula a difusa direcao_luz.Subtrai(ponto); direcao_luz.Normaliza(); nl = direcao_luz.ProdutoEscalar( normal_ponto ); intermediaria.Copia(luzes[i]->Intensidade()); intermediaria.Multiplica(nl); ilumina.Copia(objetos[num_obj]->Cor_difusa(ponto, materiais[ind_textura])); ilumina.Indexa(intermediaria); final.Soma(ilumina); //calcula a especular reflexao_luz.Copia(normal_ponto); // reflexao_luz.Divide(1/(nl*2)); //Foley 16.16 reflexao_luz.Subtrai(direcao_luz); // rv = reflexao_luz.ProdutoEscalar(direcao_vista); //Foley 16.17 if ( rv > 0.1 ) { rv = (float)pow(rv,materiais[ind_textura]->Indice_especular()); ilumina.Copia(materiais[ind_textura]->Coeficiente_especular()); ilumina.Multiplica(rv); final.Soma(ilumina); } } } //calcula a cor_ambiente final.Soma(materiais[ind_textura]->Ambiente()); //calcula a reflexão coef_reflexao = materiais[ind_textura]->Indice_reflexao(); if ( coef_reflexao > 0 && profundidade < MAX_PROFUNDIDADE ) { nv = direcao_vista.ProdutoEscalar( normal_ponto ); reflexao_vista.Copia(normal_ponto); // reflexao_vista.Divide(1/(nv*2)); //Foley 16.16 reflexao_vista.Subtrai(direcao_vista); // reflexao_vista.Soma(ponto); reflexao.Atribui(ponto,reflexao_vista); intermediaria = Intercepta( reflexao, profundidade + 1 ); intermediaria.Multiplica( coef_reflexao ); final.Soma(intermediaria); } return final; }