//***********************************************************************
//*** 6.o exercício de computação gráfica   *****************************
//*** Luciano Ludka Cordeiro - ra992077     *****************************
//*** Campinas, 8 de outubro de 2003.       *****************************
//***********************************************************************

//***********************************************************************
//*** Setagem de parâmetros da cena   ***********************************
//***********************************************************************
//deve-se setar a quantidade de nós disponíveis na rede (nNodes x nNodes)
#declare nNodes = 9 ;

//e aqui deve-se setar a probabilidade de ocorrer aresta
#declare prob = 0.65;
//bem como a probabilidade de uma aresta estar transmitindo um pacote
#declare probPac = 0.9;

//pode-se também setar a semente geradora do randômico,
#declare semente = 75136942;

//melhores combinações:
//nN 8, p 0.6, pP0.9, s 75136942
 
//***********************************************************************
//*** Câmera e iluminação da cena   *************************************
//*********************************************************************** 

/*
//esta câmera vê a posição simetricamente, de cima
camera {
  location  <(nNodes/2),(nNodes/2),3*(nNodes/2)-3*clock*(nNodes/5)>  // Posição do observador.
  right     -0.75*x                // Largura RELATIVA da imagem.
  up        1.00*y                 // Altura RELATIVA da imagem.      
  sky       z                      // Qual direção é "para cima"?
  look_at   <(nNodes/2),(nNodes/2), 00.00 >  // Para onde a câmera está apontando.
}
*/

//esta câmera vê de uma posição mais estilizada
camera {
  location  <clock,2*clock,(nNodes/6)>// Posição do observador.
  right     -0.75*x                // Largura RELATIVA da imagem.
  up        1.00*y                 // Altura RELATIVA da imagem.      
  sky       z                      // Qual direção é "para cima"?
  look_at   <(nNodes/4)-clock,(nNodes/3)+2*clock, 00.00 >  // Para onde a câmera está apontando.
}


// Nota: os parâmetros "right" e "up" devem ter a mesma proporção
// que os parâmetros ${WIDTH} e ${HEIGHT} no Makefile.

//***********************************************************************
//*** Fontes de Luz   ***************************************************
//***********************************************************************

light_source {
   < 0.2 * nNodes, 0.2 * nNodes, 7>           // Posição da lâmpada.
   color rgb 1.3 * < 1.00, 1.00, 1.00 >       // Intensidade e corda luz.
   }

light_source {
   <(1*nNodes), (1*nNodes), -6>           // Posição da lâmpada.
   color rgb 2.5 * < 1.00, 1.00, 1.00 >   // Intensidade e corda luz.
   }  

//***********************************************************************
//*** declaração das cores utilizadas ***********************************
//***********************************************************************
#declare vermelho = 
   texture {
      pigment { color rgb < 1.20, 0.20, 0.20 > }
      finish { diffuse 0.5 specular 0.5 roughness 0.005 ambient 0.1 }
   }
#declare preto = 
   texture {
      pigment { color rgb < 0.00, 0.00, 0.00 > }	
   }
#declare cor_cristal = < 0.70, 0.85, 1.35>;
#declare tx_cristal =
   texture{
      finish{
         ambient 0.1 diffuse 0.1
	 reflection 0.25
	 specular 1 roughness 0.001
      }	
      pigment{ color cor_cristal filter 1}
   }

//***********************************************************************
//*** declaração dos objetos utilizados *********************************
//***********************************************************************
#declare espessura = 0.06;
#declare raio = 0.20; //raio da esfera (estação)
#declare fonte = seed(semente); //inicializa gerador randômico

#declare estacao =
   sphere {
      < 0.00, 0.00, 0.00 >, 
      raio 
      texture { vermelho }
   }

#declare pacote =
   sphere{
      < 0.00, 0.00, 0.00>,
      espessura
      texture { preto }
   }

#declare linha_v =
   cylinder {
      < 0.00, 0.00, 0.00 >,
      < 0.00, 1.00, 0.00 >,
      espessura
      texture { tx_cristal }
   }

#declare linha_h =
   object{linha_v rotate<0,0,-90>}

#declare nodes =
   union{
      #declare i = 0;
      #while(i < nNodes)
         #declare j = 0;
         #while(j < nNodes)
            object{estacao translate <i, j, 0>}
            #declare j = j+1;
         #end    
         #declare i=i+1;
      #end
   }

#declare linhas_v = 
union{
   #declare i=0;
   #while(i<nNodes)
       #declare j = 0;
       #while(j<(nNodes-1))
          #if(rand(fonte)<prob)  
             object{linha_v translate <i,j,0>}
             #if(rand(fonte)<probPac)
                #declare posAux = mod(rand(fonte)+clock, 1);
                object{pacote scale <1,1+2*rand(fonte),1> translate <i,j+posAux,0>} 
             #end
          #end
          #declare j=j+1;
       #end
       #declare i=i+1;
   #end
}

//esta parte do código precisou realmente ser reescrita, pois uma 
//repetição não geraria uma nova cadeia de elementos
#declare linhas_h = 
union{
   #declare i=0;
   #while(i<(nNodes-1))
       #declare j = 0;
       #while(j<nNodes)
          #if(rand(fonte)<prob)  
             object{linha_h translate <i,j,0>}
  	     #if(rand(fonte)<probPac)  
                #declare posAux = mod(rand(fonte)+clock, 1);	
                object{pacote scale <1+2*rand(fonte),1, 1> translate <i+posAux,j,0>} 
             #end
          #end
          #declare j=j+1;
       #end
       #declare i=i+1;
   #end
}

//***********************************************************************
//*** DECLARAÇÃO DA CENA - OBJETOS MONTADOS    **************************
//***********************************************************************

background{ color rgb < 0.50, 0.50, 0.50 > }

union{  
   // object{bola texture{preto}} // para conferir a origem
   object{ nodes }	
   object{linhas_v}	
   object{linhas_h}
}