// Fabio de Souza Azevedo - RA 952215
// 2021-10-13
//
// TP08 (ou 07?) - Animação do robô alienigenoide - filme, com Bezier

// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2022-01-06 04:55:54 by stolfi

// ======================================================================
// CORES E TEXTURAS

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

#declare tx_plastico = 
  texture{
    pigment{ color rgb < 0.10, 0.80, 1.00 > }
    finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_fosca = 
  texture{
    pigment{ color rgb < 1.00, 0.80, 0.10 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare tx_espelho = 
  texture{
    pigment{ color rgb < 1.00, 0.85, 0.30 > }
    finish{ diffuse 0.2 reflection 0.7*< 1.00, 0.85, 0.30 > ambient 0.1 }
  }

#declare tx_vidro = 
  texture{
    pigment{ color rgb < 0.85, 0.95, 1.00 > filter 0.70 }
    finish{ diffuse 0.03 reflection 0.25 ambient 0.02 specular 0.25 roughness 0.005 }
  }

#declare tx_verde_escuro =
  texture{
    pigment { color rgb <0, 0.5, 0> }
    //finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_verde_claro =
  texture{
    pigment { color rgb <0, 1.0, 0> }
    //finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_azul_escuro = 
  texture{
    pigment { color rgb<0, 0, 0.5> }
    //finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }
  
#declare tx_azul_escuro_espelhado = 
  texture{
    pigment { color rgb<0, 0, 0.5> }
    finish{ diffuse 0.2 reflection 0.7*<0, 0, 0.5> ambient 0.1 }
  }

#declare tx_verm_escuro = 
  texture{
    pigment { color rgb<0.5, 0, 0> }
    //finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_verm_transp = 
  texture{
    pigment { color rgbt <1, 0, 0, 0.5> }
    //finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_xadrez =
  texture{
    pigment{ checker color rgb < 0.10, 0.32, 0.60 >, color rgb < 1.00, 0.97, 0.90 > }
    finish{ diffuse 0.9 ambient 0.1 }
    scale 2.0
  }

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

// Partes da cena:

// Pernas

#macro pe()
  #local uu = 1.0;
  box { <+0.0, -uu, 0.0>, <+4.0*uu, +uu, +uu> }
#end

#macro pe_tornozelo(ang_pe)
  #local rr = 1.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    object {
      pe()
      translate <0, 0, -rr> rotate <0, +ang_pe, 0>
      texture { tx_verde_claro }
    }
  }
#end

#macro canela(ang_pe)
  #local rr = 1.0;
  #local comp = 8.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    cylinder { 0, <0.0, 0.0, -comp>, 0.7*rr texture { tx_verde_claro } }
    object { pe_tornozelo(ang_pe) translate <0.0, 0.0, -comp> }
  }
#end

#macro perna(ang_joelho, ang_pe)
  #local rr = 1.0;
  #local comp = 10.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    cylinder { 0, <0.0, 0.0, -comp>, 0.7*rr texture { tx_verde_claro } }
    object {
      canela(ang_pe)
      rotate <0, ang_joelho, 0>
      translate <0.0, 0.0, -comp>
    }
  }
#end

#declare alt_quadril = 6.0;
#macro quadril(ang_femur_dir, ang_joelho_dir, ang_pe_dir,
               ang_femur_esq, ang_joelho_esq, ang_pe_esq)
  #local rr = 4.0;
  union {
    cylinder { 0, <0, 0, alt_quadril>, rr texture { tx_verm_escuro/*tx_verm_transp*/ } }
    // perna direita
    object {
      perna(ang_joelho_dir, ang_pe_dir)
      rotate ang_femur_dir*y
      translate -rr*y
    }
    // perna esquerda
    object {
      perna(ang_joelho_esq, ang_pe_esq)
      rotate ang_femur_esq*y
      translate +rr*y
    }
  }
#end

// Braços

#macro garra()
  #local uu = 1.0;
  box { <0.0, -uu, 0.0>, <+uu, +uu, -4.0*uu> }  
#end

#macro mao(ang_garras)
  #local rr = 1.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    // garra anterior
    object {
      garra()
      translate <0,0,0> rotate <0, -0.5*ang_garras, 0>
      texture { tx_verde_claro }
    }
    // garra posterior
    object {
      garra()
      translate <-rr,0,0> rotate <0, +0.5*ang_garras, 0>
      texture { tx_verde_escuro }
    }
  }
#end

#macro antebraco(ang_mao, ang_garras)
  // {ang_mao} = Giro da mao em relação ao eixo do antebraço
  #local rr = 1.0;
  #local comp = 6.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    cylinder { 0, <0.0, 0.0, -comp>, 0.7*rr texture { tx_verde_claro } }
    object {
      mao(ang_garras)
      rotate <0, 0, ang_mao>
      translate <0.0, 0.0, -comp>
    }
  }
#end

#macro braco(ang_cotovelo, ang_mao, ang_garras)
  #local rr = 1.0;
  #local comp = 6.0;
  union {
    sphere { 0, rr texture { tx_verde_escuro } }
    cylinder { 0, <0.0, 0.0, -comp>, 0.7*rr texture { tx_verde_claro } }
    object {
      antebraco(ang_mao, ang_garras)
      rotate <0, ang_cotovelo, 0>
      translate <0.0, 0.0, -comp>
    }
  }
#end

#declare alt_ombro = 8.0;
#macro ombro(ang_ombro_dir, ang_cotovelo_dir, ang_mao_dir, ang_garras_dir,
             ang_ombro_esq, ang_cotovelo_esq, ang_mao_esq, ang_garras_esq)
  #local r_base = 4.0;
  #local r_topo = 7.0;
  union {
    //cylinder { 0, <0, 0, alt_ombro>, r texture { tx_verm_escuro/*tx_verm_transp*/ } }
    cone { <0, 0, 0>, r_base, <0, 0, alt_ombro>, r_topo texture { tx_verm_escuro/*tx_verm_transp*/ } }
    // braço direito
    object {
      braco(ang_cotovelo_dir, ang_mao_dir, ang_garras_dir)
      rotate <0, ang_ombro_dir, 0>
      translate <0, -r_topo, alt_ombro>
    }
    // braço esquerdo
    object {
      braco(ang_cotovelo_esq, ang_mao_esq, ang_garras_esq)
      rotate <0, ang_ombro_esq, 0>
      translate <0, +r_topo, alt_ombro>
    }
  }
#end

#macro cabeca()
  #local alt = 6.0;
  #local r_base = 1;
  #local r_topo = 4*r_base;
  union {
    cylinder { 0, <0, 0, 2.0>, r_base texture { tx_verde_escuro } }
    cone { <0, 0, 2.0>, r_base, <0, 0, 2.0+alt>, r_topo texture { tx_verde_claro } }
  }
#end

#macro robo(ang_ombro_dir, ang_cotovelo_dir, ang_mao_dir, ang_garras_dir
            ang_ombro_esq, ang_cotovelo_esq, ang_mao_esq, ang_garras_esq,
            ang_femur_dir, ang_joelho_dir, ang_pe_dir,
            ang_femur_esq, ang_joelho_esq, ang_pe_esq)
  union {
    object { quadril(ang_femur_dir, ang_joelho_dir, ang_pe_dir,
                     ang_femur_esq, ang_joelho_esq, ang_pe_esq) }
    object {
      ombro(ang_ombro_dir, ang_cotovelo_dir, ang_mao_dir, ang_garras_dir,
            ang_ombro_esq, ang_cotovelo_esq, ang_mao_esq, ang_garras_esq)
      translate <0,0,+alt_quadril>
    }
    object { cabeca() translate <0,0, alt_quadril+alt_ombro> }
  }
#end

#macro robo_vet(params)
  robo(params[ 0], // ang_ombro_dir
       params[ 1], // ang_cotovelo_dir
       params[ 2], // ang_mao_dir
       params[ 3], // ang_garras_dir
       params[ 4], // ang_ombro_esq
       params[ 5], // ang_cotovelo_esq
       params[ 6], // ang_mao_esq
       params[ 7], // ang_garras_esq
       params[ 8], // ang_femur_dir
       params[ 9], // ang_joelho_dir
       params[10], // ang_pe_dir
       params[11], // ang_femur_esq
       params[12], // ang_joelho_esq
       params[13]  // ang_pe_esq
      ) 
#end

#macro interpola1(tt, tt0,tt1, vv0,vv1)
  #local rr = (tt - tt0)/(tt1 - tt0);
  #local vv = (1-rr)*vv0 + rr*vv1;
  vv
#end

#macro quadro(tf)
  #local T0 = 0.00;
  //#local P0 = ...
  #local P0_ang_ombro_dir = 0;
  #local P0_ang_ombro_esq = -20;
  #local P0_ang_femur_dir = 0;
  #local P0_ang_femur_esq = 0;

  #local T1 = 0.25;
  //#local P1 = ...
  #local P1_ang_ombro_dir = 0; //-90;
  #local P1_ang_ombro_esq = 0; //+90;
  #local P1_ang_femur_dir = -25; //-45;
  #local P1_ang_femur_esq = +25; //+45;

  #local T2 = 0.50;
  //#local P2 = ...
  #local P2_ang_ombro_dir = 40; //-180;
  #local P2_ang_ombro_esq = 0; //+180;
  #local P2_ang_femur_dir = 0;
  #local P2_ang_femur_esq = 0;

  #local T3 = 0.80;
  //#local P3 = ...
  #local P3_ang_ombro_dir = 0; //-270;
  #local P3_ang_ombro_esq = 30; //+270;
  #local P3_ang_femur_dir = +25; //+45;
  #local P3_ang_femur_esq = -25; //-45;

  #local T4 = 1.00;
  //#local P4 = P0
  #local P4_ang_ombro_dir = P0_ang_ombro_dir;
  #local P4_ang_ombro_esq = P0_ang_ombro_esq;
  #local P4_ang_femur_dir = P0_ang_femur_dir;
  #local P4_ang_femur_esq = P0_ang_femur_esq;


  #if ((T0 <= tf) & (tf < T1))
    //#local tt = (tf - T0)/(T1 - T0);
    //#local qd = robo interpola(tt, P0, P1);
    #local ang_ombro_dir = interpola1(tf, T0,T1, P0_ang_ombro_dir, P1_ang_ombro_dir);
    #local ang_ombro_esq = interpola1(tf, T0,T1, P0_ang_ombro_esq, P1_ang_ombro_esq);
    #local ang_femur_dir = interpola1(tf, T0,T1, P0_ang_femur_dir, P1_ang_femur_dir);
    #local ang_femur_esq = interpola1(tf, T0,T1, P0_ang_femur_esq, P1_ang_femur_esq);

  #elseif ((T1 <= tf) & (tf < T2))
    //#local tt = (tf - T1)/(T2 - T1);
    //#local qd = robo interpola(tt, P1, P2);
    #local ang_ombro_dir = interpola1(tf, T1,T2, P1_ang_ombro_dir, P2_ang_ombro_dir);
    #local ang_ombro_esq = interpola1(tf, T1,T2, P1_ang_ombro_esq, P2_ang_ombro_esq);
    #local ang_femur_dir = interpola1(tf, T1,T2, P1_ang_femur_dir, P2_ang_femur_dir);
    #local ang_femur_esq = interpola1(tf, T1,T2, P1_ang_femur_esq, P2_ang_femur_esq);

  #elseif ((T2 <= tf) & (tf < T3))
    //#local tt = (tf - T2)/(T3 - T2);
    //#local qd = robo interpola(tt, P2, P3);
    #local ang_ombro_dir = interpola1(tf, T2,T3, P2_ang_ombro_dir, P3_ang_ombro_dir);
    #local ang_ombro_esq = interpola1(tf, T2,T3, P2_ang_ombro_esq, P3_ang_ombro_esq);
    #local ang_femur_dir = interpola1(tf, T2,T3, P2_ang_femur_dir, P3_ang_femur_dir);
    #local ang_femur_esq = interpola1(tf, T2,T3, P2_ang_femur_esq, P3_ang_femur_esq);

  #elseif ((T3 <= tf) & (tf <= T4))
    //#local tt = (tf - T3)/(T4 - T3);
    //#local qd = robo interpola(tt, P3, P4);
    #local ang_ombro_dir = interpola1(tf, T3,T4, P3_ang_ombro_dir, P4_ang_ombro_dir);
    #local ang_ombro_esq = interpola1(tf, T3,T4, P3_ang_ombro_esq, P4_ang_ombro_esq);
    #local ang_femur_dir = interpola1(tf, T3,T4, P3_ang_femur_dir, P4_ang_femur_dir);
    #local ang_femur_esq = interpola1(tf, T3,T4, P3_ang_femur_esq, P4_ang_femur_esq);
  #end
  //qd
  robo(ang_ombro_dir,0,0,30, ang_ombro_esq,0,0,90, // ombro
       ang_femur_dir,0,0, ang_femur_esq,0,0) // quadril
#end

#include "eixos.inc"

// Aqui está a cena, finalmente:

object { eixos(8.0) }


//object { quadro(0.000) /*translate <0,-8,0>*/ }
//object { quadro(0.250) /*translate <0,-4,0>*/ }
object { quadro(clock) translate 0 }
//object { quadro(0.750) translate <0,4,0> }
//object { quadro(1.000) translate <0,8,0> }


// **********

// Ordem dos parâmetros no vetor:
// {ang_ombro_dir, ang_cotovelo_dir, ang_mao_dir, ang_garras_dir,
//  ang_ombro_esq, ang_cotovelo_esq, ang_mao_esq, ang_garras_esq,
//  ang_femur_dir, ang_joelho_dir, ang_pe_dir,
//  ang_femur_esq, ang_joelho_esq, ang_pe_esq}

#declare num_params = 14;
#declare P0 = array[num_params] {-45, -45, 0, +45,  0, 0, 0, +45,    0,   0,   0,  -30, +90, -60};
#declare P1 = array[num_params] {  0,   0, 0, +45,  0, 0, 0, +45,  -30, +90, -60,    0,   0,   0};

#declare P2 = array[num_params] {0, 0, 0, +45,  0, 0, 0, +45,    0,   0,   0,  -30, +90, -60};
#declare P3 = array[num_params] {0, 0, 0, +45,  0, 0, 0, +45,  -30, +90, -60,    0,   0,   0};

// object { robo_vet(P0) scale 0.5 translate <0, -10, 0> }
  // Puxando a perna esquerda

// object { robo_vet(P1) scale 0.5 translate <0, +10, 0> }
  // Puxando a perna direita

// object { quadril(0, 0, 0,  -30, +90, -60) } // -60 = -(-30+90); -30 = -(-15+45); +40 = -(-70+30)


#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 1.00 >;
#declare raio_cena = 35;
#declare dir_camera = <7,3,2>;//< 0.5, 7.00,  2.00 >; //< 7.00, 3.00, 4.00 >; //< 7.00, 0.5, 2.00 >; //< 7.00, 14.00, 4.00 >; // < 7.00, 3.00, 4.00 >;
#declare dist_camera = 4*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)