// ======================================================================
// CORES E TEXTURAS
#include "textures.inc"
#include "eixos.inc"
#include "transforms.inc"
#include "shapes.inc"
background{ color rgb < 0.75, 0.80, 0.85 > }

#declare tx_vidro = 
  texture{
    pigment{ color rgb < 0.85, 0.95, 1.00 > filter 0.70 }
    finish{ diffuse 0.03 reflection 0.35 ambient 0.02 specular 0.25 roughness 0.005 ior 1.5}
  }
#declare tx_xadrez =
  texture{
    pigment{ checker color rgb < 0.90, 0.90, 1.00 >, color rgb < 0.90, 1.00, 0.90> }
    finish{ diffuse 0.9 ambient 0.1 }
    scale 15.0
  }

// ======================================================================
// DESCRIÇÃO DA CENA 

plane {  <0,0,1>, -20 texture {  tx_xadrez  }  }

//Definição recursiva
// #macro interpola(tt, t1, t2, v1, v2)
//   ((t2-tt)*v1 + (tt-t1)*v2) / (t2-t1)
// #end
// 
// #macro interpola4(tt, t1, t2, v1, v2, v3, v4)
//   #local v12  = interpola(tt, t1, t2, v1, v2);
//   #local v23  = interpola(tt, t1, t2, v2, v3);
//   #local v34  = interpola(tt, t1, t2, v3, v4);
// 
//   #local v123 = interpola(tt, t1, t2, v12, v23);
//   #local v234 = interpola(tt, t1, t2, v23, v34);
// 
//   #local v1234 = interpola(tt, t1, t2, v123, v234);
//   v1234
// #end

//Definição Algébrica
#macro interpola4(tt, t1, t2, v1, v2, v3, v4)
  #local q=(tt-t1)/(t2-t1);
  1*(1-q)*(1-q)*(1-q)*v1 + 
  3*(1-q)*(1-q)*(  q)*v2 + 
  3*(1-q)*(  q)*(  q)*v3 + 
  1*(  q)*(  q)*(  q)*v4
#end

#macro curvaBezier(v1, v2, v3, v4, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro, )
  #local i=0;
  #while (i<=N)
    #local P=interpola4(i, 0, N, v1,v2,v3,v4);
    sphere { 
      P, Raio_Bola
      texture {Mat_Bola}
    }
    #if (i > 0)
      cylinder {
	Prev_P, P, Raio_Cilindro
	texture {Mat_Cilindro}
      }
    #end

    #local Prev_P = P;
    #local i=i+1;
  #end

  sphere {
    v1, Raio_Bola_Quadro
    texture {  Mat_Bola_Quadro  }
  }
  sphere { 
    v4, Raio_Bola_Quadro
    texture {  Mat_Bola_Quadro  }
  }
#end

#macro superficieBezier(v11, v12, v13, v14, v21, v22, v23, v24, v31, v32, v33, v34, v41, v42, v43, v44, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro, Mat_Superficie)
  bicubic_patch{
    type 1 u_steps 3 v_steps 3
    v41,v42,v43,v44,
    v31,v32,v33,v34,
    v21,v22,v23,v24,
    v11,v12,v13,v14
    texture {Mat_Superficie scale 10}
  }

  curvaBezier(v11, v12, v13, v14, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)
  curvaBezier(v41, v42, v43, v44, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)
  curvaBezier(v11, v21, v31, v41, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)
  curvaBezier(v14, v24, v34, v44, N, Raio_Bola, Raio_Cilindro, Raio_Bola_Quadro, Raio_Cilindro_Quadro, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)

  #local segs=4;
  #local i=1;
  #while (i<=segs)
    #local frac = i/(segs+1);
    curvaBezier(
      interpola4(frac, 0, 1, v11, v12, v13, v14),
      interpola4(frac, 0, 1, v21, v22, v23, v24),
      interpola4(frac, 0, 1, v31, v32, v33, v34),
      interpola4(frac, 0, 1, v41, v42, v43, v44),
      N, Raio_Bola/2, Raio_Cilindro/2, Raio_Bola_Quadro/2, Raio_Cilindro_Quadro/2, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)

    curvaBezier(
      interpola4(frac, 0, 1, v11, v21, v31, v41),
      interpola4(frac, 0, 1, v12, v22, v32, v42),
      interpola4(frac, 0, 1, v13, v23, v33, v43),
      interpola4(frac, 0, 1, v14, v24, v34, v44),
      N, Raio_Bola/2, Raio_Cilindro/2, Raio_Bola_Quadro/2, Raio_Cilindro_Quadro/2, Mat_Bola, Mat_Cilindro, Mat_Bola_Quadro, Mat_Cilindro_Quadro)
    #local i=i+1;
  #end
#end


#macro curvaBezierX(v1, v2, v3, v4)
  curvaBezier(v1,v2,v3,v4,  10,  2, 1.6, 3.0, 0.4, Sapphire_Agate, tx_vidro, Jade, Sapphire_Agate)
#end
#macro superficieBezierX(v11, v12, v13, v14, v21, v22, v23, v24, v31, v32, v33, v34, v41, v42, v43, v44)
  superficieBezier(v11, v12, v13, v14, v21, v22, v23, v24, v31, v32, v33, v34, v41, v42, v43, v44,  15,  0.5, 0.3, 0.6, 0.2, Sapphire_Agate, tx_vidro, Jade, Sapphire_Agate, Jade)
#end

#declare random_seed = seed (156);
#macro random() 
  rand(random_seed) 
#end
#macro srandom() 
  1-2*random()
#end
#macro vrandom() 
  vnormalize(< 1-2*random(), 1-2*random(), 1-2*random() >)
#end

#declare tamX = 5;
#declare tamY = 5;
#declare Points =  array[tamX][tamY];
#declare DirX   =  array[tamX][tamY];
#declare DirY   =  array[tamX][tamY];

#declare a=0;
#while (a<tamX)
  #declare b=0;
  #while (b<tamY)
    #declare Points[a][b] = 10*(<2*(a-(tamX-1)/2), 2*(b-(tamY-1)/2), 0> + 0.3*vrandom());
    #declare DirX  [a][b] = 10*(vnormalize(<1,0,0> + vrandom()));
    #declare DirY  [a][b] = 10*(vnormalize(<0,1,0> + vrandom()));
    #declare b=b+1;
  #end
  #declare a=a+1;
#end

#declare a=0;
#while (a<tamX-1)
  #declare b=0;
  #while (b<tamY-1)
    superficieBezierX(
      Points[a  ][b  ]               , Points[a  ][b  ]+DirX[a  ][b  ]               , Points[a+1][b  ]-DirX[a+1][b  ]               , Points[a+1][b  ],
      Points[a  ][b  ]+DirY[a  ][b  ], Points[a  ][b  ]+DirX[a  ][b  ]+DirY[a  ][b  ], Points[a+1][b  ]-DirX[a+1][b  ]+DirY[a+1][b  ], Points[a+1][b  ]+DirY[a+1][b  ],
      Points[a  ][b+1]-DirY[a  ][b+1], Points[a  ][b+1]+DirX[a  ][b+1]-DirY[a  ][b+1], Points[a+1][b+1]-DirX[a+1][b+1]-DirY[a+1][b+1], Points[a+1][b+1]-DirY[a+1][b+1],
      Points[a  ][b+1]               , Points[a  ][b+1]+DirX[a  ][b+1]               , Points[a+1][b+1]-DirX[a+1][b+1]               , Points[a+1][b+1],
    )   
    #declare b=b+1;
  #end
  #declare a=a+1;
#end



  union {
  #declare _P1=30*vrandom();
  #declare _P2=30*vrandom();

  #declare P1=30*vrandom();
  #declare P4=30*vrandom();
  #declare P2=P1+vlength(P4-P1)*vrandom();
  #declare P3=P4+vlength(P4-P1)*vrandom();

  #declare _P1=P1;
  #declare _P2=P2;

  #declare NSEGS=5;
  #declare i=0;
  #while (i<NSEGS)
    curvaBezierX(P1,P2,P3,P4)
    #declare P1=P4;
    #declare P2=2*P4-P3;
    #declare P4=30*vrandom();
    #declare P3=P4+vlength(P4-P1)*vrandom();

    #declare i=i+1;
    #if (i=NSEGS-1)
      #declare P4=_P1;
      #declare P3=2*_P1 - _P2;
    #end
  #end
  scale 0.5*<1,1,1>
  translate <0,0,30>
}


#include "camlight.inc" 
#declare centro_cena = <0,0,0>;
#declare raio_cena = 80;
#declare dir_camera = <5,5,5>; 
#declare dist_camera = 100;
#declare intens_luz = 1.00;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)