// MC930 - Laboratorio 5
// Douglas Gardim  RA: 008506 
//

// ======================================================================
// CÂMERA 

camera {
//  location  < 110.00, 80.00, 200.00 >  // Posição do observador.
  location  < 110.00, 80.00, 200.00 >  // Posição do observador.
  right     -1.00*x                 // Largura RELATIVA da imagem.
  up        0.50*y                 // Altura RELATIVA da imagem.      
  sky       y                      // Qual direção é "para cima"?
  look_at   <  0.00, 10.00, 0.00 >  // Para onde a câmera está apontando.
  angle 45
} 
// 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 {
  10 * < +15.0, +5.0, +5.0 >              // Posição da lâmpada.
  color rgb 1.2 * < 1.00, 1.00, 1.00 >   // Intensidade e corda luz.
} 

light_source {
  10 * < +50.0, +30.0, +50.0 >              // Posição da lâmpada.
  color rgb 1.2 * < 1.00, 1.00, 1.00 >   // Intensidade e corda luz.
} 

light_source {
  10 * < +50.0, -10.0, +10.0 >             // Posição da lâmpada.
  color rgb 0.8 * < 1.00, 1.00, 1.00 >   // Intensidade e corda luz.
} 

// RANDOM
#declare g = seed(23423);

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

background{ color rgb < 0.75, 0.80, 0.85 > }

#declare raio = 2.000;

#declare locomotivaBase =
  union {
    difference {
      box {
        <5, 0, -5>, <20, 15, 5>
      }
      box {
        <4, 1, -4>, <19, 14, 4>
      }
      box {
        <10.5, 8, -10>, <14.5, 13, 10>
      }
    }
    cylinder {
      <-20, 5, 0>, <5, 5, 0>, 5
    }
    box {
      <-20, 0, -5>, <5, 3, 5>
    }
    cone {
      <-10, 5, 0>, 1, <-10, 15, 0>, 5
    }
  }

#declare vagaoBase = 
  difference {
    box {
      <-20, 0, -5>, <20, 10, 5>
    }
    box {
      <-19, 1, -4>, <19, 9, 4>
    }
    union {
      #declare i = 0;
      #while (i < 3)
        box {
          <-17.5 + i * 13.75, 5, -10>, <-10 + i * 13.75, 9, 10>
        }
        #declare i = i + 1;
      #end
    }
  }

#declare corRodas = <0.4,0.4,0.4>;
#declare rodas = 
  difference {
    union {
      #declare i = 0;
      #while (i < 11)
        #if ((i < 2) | (i > 8))
        cylinder {
          <-15 + i * 3, -1, -5>, <-15 + i * 3, -1, 5>, 1
        }
        #end
        #declare i = i + 1;
      #end
    }
    box {
      <-20, -3, -4>, <20, 0, 4>
    }
    texture {
      pigment {color rgb corRodas}
      finish { 
        ambient 0.05 diffuse 0.05
        reflection corRodas
        specular 0.80 roughness 0.05
      }
    }
  }

#declare corTrilhos = <0.2,0.2,0.2>;
#declare trilhos =
  union {
    torus {
      80, 1
    }
    torus {
      70, 1
    }
    texture {
      pigment {color rgb corTrilhos}
      finish { 
        ambient 0.05 diffuse 0.05
        reflection corRodas
        specular 0.80 roughness 0.05
      }
    }
  }
  
#declare vagao =
  union {
    object {
      vagaoBase
      texture {
        pigment{color rgb <0.8, 0.8, 0.8>}
      }
    }
    object {rodas}
  }

#declare corLocomotiva = <0.8, 0.8, 0.8>;
#declare locomotiva =
  union {
    object {
      locomotivaBase
      texture {
        pigment {color rgb corLocomotiva}
        finish {ambient 0.2 diffuse 0.8}
      }
    }
    object {rodas}
  }

// Aqui está a cena, finalmente:
plane {y, 0
  texture {
    pigment{checker <0.2,0.2,0.2>,<0.3,0.3,0.3>}
    finish {ambient 0.2 diffuse 0.8}
    scale 30.0
  }
}

#declare posInic = 150;
#declare ini = 0.3;
#declare fin = 0.7;
#declare a = 1 / (ini*ini + ini*(fin-ini));
#if (clock < ini)
  #declare anguloAtual = (a * clock * clock) / 2;
#else 
  #if (clock < fin)
  #declare anguloAtual = 0.5;
    #declare vel = a * ini;
    #declare inic = (vel * ini) / 2;
    #declare anguloAtual = inic + vel * (clock - ini);
  #else
    #declare anguloAtual = 1 - (a * (1-clock) * (1-clock) / 2);
  #end
#end
#declare anguloAtual = - anguloAtual * 360 + posInic;
  
union {
  object{trilhos}
  union {
    #declare i = 0;
    #declare ang = 35;
    #declare angVag = 0;
    #while (i < 6)
      object {
        #if (i > 0)
          union {
            object {
              vagaoBase
              texture {
                pigment{color rgb <rand(g), rand(g), rand(g)>}
                finish { diffuse 0.5 specular 0.5 roughness 0.005 ambient 0.1 }
              }
            }
            object {rodas}
          }
        #else
          object {
            locomotiva
          }
        #end
	translate <0, 3, 74>
	rotate (anguloAtual + angVag) * y
      }
      #declare i = i + 1;
      #declare angVag = angVag + ang;
    #end
  }
}