// ======================================================================
// MC937A/MO603A – Computacao Grafica - 2023-S2
// Trabalho de laboratorio 09 - 2023-11-22
// Robô preguiça, mas animado (2)
//
// RA108231 - Oscar dos Santos Esgalha Neto
// ======================================================================
background{ color rgb < 0.7, 0.7, 0.9 > }

#declare textura = texture{
  pigment{ color rgb < 0.7, 0.4, 0.2 > }
  finish{ diffuse 0.8 ambient 0.1 }
}

#declare RAIO_MEMBRO = 0.25;

#macro pescobaixo(P2, P3, P4)
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 3, 0, 0 >,
    RAIO_MEMBRO
    texture { textura }
  }
  #local sub = object { pescotopo(P3, P4) }
  union {
    object { tronco }
    object { sub rotate P2 * y translate <3, 0, 0> }
  }
#end

#macro pescotopo(P3, P4)
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 3, 0, 0 >,
    RAIO_MEMBRO
    texture { textura }
  }
  #local sub = object { cabeca() }
  union {
    object { tronco }
    object { sub translate <1, 0, 0> rotate P3 * y rotate P4 * z translate <3, 0, 0> }
  }
#end

#macro cabeca()
  #local tronco = sphere {
      <0, 0, 0>,
      1
      texture { textura }
  }
  #local olho = sphere {
      <0, 0, 0>,
      0.2
      texture {
        pigment{ color rgb < 0.1, 0.1, 0.1 > }
        finish{ diffuse 0.8 ambient 0.1 }
      }
  }
  union {
    object { tronco }
    object { olho translate <1, 0.2, 0> }
    object { olho translate <1, -0.2, 0> }
  }
#end

#macro membro(L3, L4)
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 3, 0, 0 >,
    RAIO_MEMBRO
    texture { textura }
  }
  #local sub = object { submembro(L4) }
  union {
    object { tronco }
    object { sub rotate L3 * y translate <3, 0, 0> }
  }
#end

#macro submembro(L4)
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 3, 0, 0 >,
    RAIO_MEMBRO
    texture { textura }
  }
  #local sub = object { pata() }
  union {
    object { tronco }
    object { sub rotate L4 * y translate <3, 0, 0> }
  }
#end

#macro pata()
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 1, 0, 0 >,
    RAIO_MEMBRO
    texture { textura }
  }
  tronco
#end

#macro robo(
  P1, P2, P3, P4,
  E11, E12, E13, E14,
  E21, E22, E23, E24,
  D11, D12, D13, D14,
  D21, D22, D23, D24
)
  #local raio_tronco = RAIO_MEMBRO * 4;
  #local tronco = cylinder{
    < 0, 0, 0 >,
    < 6, 0, 0 >,
    raio_tronco
    texture { textura }
  }
  union {
    object { tronco }
    object { pescobaixo(P2, P3, P4) rotate P1 * z translate <6, 0, 0> }
    object { membro(E13, E14) rotate E11 * y rotate E12 * z translate <1, raio_tronco, 0> }
    object { membro(D13, D14) rotate D11 * y rotate D12 * z translate <1, -raio_tronco, 0> }
    object { membro(E23, E24) rotate E21 * y rotate E22 * z translate <5, raio_tronco, 0> }
    object { membro(D23, D24) rotate D21 * y rotate D22 * z translate <5, -raio_tronco, 0> }
  }
#end

#declare NP = 20;

#macro empacota(
  A0, A1, A2, A3,
  A4, A5, A6, A7,
  A8, A9, A10, A11,
  A12, A13, A14, A15, 
  A16, A17, A18, A19)

  #local P = array[NP];
  #local P[0] = A0;
  #local P[1] = A1;
  #local P[2] = A2;
  #local P[3] = A3;
  #local P[4] = A4;
  #local P[5] = A5;
  #local P[6] = A6;
  #local P[7] = A7;
  #local P[8] = A8;
  #local P[9] = A9;
  #local P[10] = A10;
  #local P[11] = A11;
  #local P[12] = A12;
  #local P[13] = A13;
  #local P[14] = A14;
  #local P[15] = A15;
  #local P[16] = A16;
  #local P[17] = A17;
  #local P[18] = A18;
  #local P[19] = A19;

  P
#end

#macro acha_quadro(tt, NQ, TQ)
  #local k = 0;
  #while(k < NQ - 1 & TQ[k+1] < tt)
    #local k = k + 1;
  #end
  k
#end

#macro interpola_quadros(
  tt, ta, Pa, tb, Pb,
  A0, A1, A2, A3,
  A4, A5, A6, A7,
  A8, A9, A10, A11,
  A12, A13, A14, A15, 
  A16, A17, A18, A19
  )

  #local s = (tt - ta)/(tb - ta);
  #declare A0 = (1-s)*Pa[0] + s*Pb[0];
  #declare A1 = (1-s)*Pa[1] + s*Pb[1];
  #declare A2 = (1-s)*Pa[2] + s*Pb[2];
  #declare A3 = (1-s)*Pa[3] + s*Pb[3];
  #declare A4 = (1-s)*Pa[4] + s*Pb[4];
  #declare A5 = (1-s)*Pa[5] + s*Pb[5];
  #declare A6 = (1-s)*Pa[6] + s*Pb[6];
  #declare A7 = (1-s)*Pa[7] + s*Pb[7];
  #declare A8 = (1-s)*Pa[8] + s*Pb[8];
  #declare A9 = (1-s)*Pa[9] + s*Pb[9];
  #declare A10 = (1-s)*Pa[10] + s*Pb[10];
  #declare A11 = (1-s)*Pa[11] + s*Pb[11];
  #declare A12 = (1-s)*Pa[12] + s*Pb[12];
  #declare A13 = (1-s)*Pa[13] + s*Pb[13];
  #declare A14 = (1-s)*Pa[14] + s*Pb[14];
  #declare A15 = (1-s)*Pa[15] + s*Pb[15];
  #declare A16 = (1-s)*Pa[16] + s*Pb[16];
  #declare A17 = (1-s)*Pa[17] + s*Pb[17];
  #declare A18 = (1-s)*Pa[18] + s*Pb[18];
  #declare A19 = (1-s)*Pa[19] + s*Pb[19];
#end

#macro cena(tt)

  #local NQ = 10;
  #local TQ = array[NQ+1];
  #local PQ = array[NQ+1];

  #local TQ[0] = 0.0;
  #local PQ[0] = empacota(
    30, 15, 15, 30,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[1] = 0.1;
  #local PQ[1] = empacota(
    30, 30, 15, 60,
    60, 90, 45, 90,
    90, 90, 0, 0,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[2] = 0.2;
  #local PQ[2] = empacota(
    30, 15, 15, 30,
    60, 90, 45, 90,
    60, 90, 60, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[3] = 0.3;
  #local PQ[3] = empacota(
    30, 30, 15, 0,
    90, 90, 0, 0,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[4] = 0.4;
  #local PQ[4] = empacota(
    30, 15, 15, -30,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[5] = 0.5;
  #local PQ[5] = empacota(
    30, 30, 15, -60,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    90, -90, 0, 0,
  )

  #local TQ[6] = 0.6;
  #local PQ[6] = empacota(
    30, 15, 15, -30,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[7] = 0.7;
  #local PQ[7] = empacota(
    30, 30, 15, 0,
    60, 90, 45, 90,
    60, 90, 45, 90,
    90, -90, 0, 0,
    60, -90, 45, 90,
  )

  #local TQ[8] = 0.8;
  #local PQ[8] = empacota(
    30, 15, 15, 30,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local TQ[9] = 0.9;
  #local PQ[9] = empacota(
    30, 30, 15, 60,
    60, 90, 45, 90,
    60, 90, 45, 90,
    60, -90, 45, 90,
    60, -90, 45, 90,
  )

  #local k = acha_quadro(tt, NQ, TQ);
  #local A0 = 0; #local A1 = 0; #local A2 = 0; #local A3 = 0; #local A4 = 0;
  #local A5 = 0; #local A6 = 0; #local A7 = 0; #local A8 = 0; #local A9 = 0;
  #local A10 = 0; #local A11 = 0; #local A12 = 0; #local A13 = 0; #local A14 = 0;
  #local A15 = 0;  #local A16 = 0; #local A17 = 0; #local A18 = 0; #local A19 = 0;

  #local altura = 0.1 * sin(tt * 4 * pi);
  #local dx = 10 - 10 * tt;

  interpola_quadros(
    tt, TQ[k], PQ[k], TQ[k+1], PQ[k+1],
    A0, A1, A2, A3,
    A4, A5, A6, A7,
    A8, A9, A10, A11,
    A12, A13, A14, A15, 
    A16, A17, A18, A19
  )
  union {
    cylinder{
      < -30, 0, 0 >,
      < 30, 0, 0 >,
      1
      texture { textura }
      translate <0, 0, 4.5>
    }
    object {
      robo(
        A0, A1, A2, A3,
        A4, A5, A6, A7,
        A8, A9, A10, A11,
        A12, A13, A14, A15, 
        A16, A17, A18, A19
      )
      rotate -180 * y
      translate <dx, 0, altura>
    }
  }
#end

object {
  cena(clock)
}

#include "camlight.inc"
#declare centro_cena = < 0, 0, 3.00 >;
#declare raio_cena = 20.0;
#declare dir_camera = < 1, 1, 0 >;
#declare dist_camera = 5*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)