// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2020-09-30 19:57:13 by jstolfi

// ======================================================================
// 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 }
  }

// ======================================================================
// MEMBRO
#declare UNIT = 1;
#declare OFFSET_MULTIPLIER = 1.1;

#macro hand()
cone {
  <0, 0, 0>, UNIT / 2
  <0, UNIT, 0>, 0
  texture { tx_plastico }
}
#end

#macro elbow(hand_yaw)
union {
  cylinder {
    <0, 0, 0>, <0, UNIT * 2, 0>, UNIT / 2
    texture { tx_plastico }
  }
  object {
    hand()
    rotate <0, 0, -hand_yaw>
    translate <0, UNIT * 2, 0>
  }
}
#end

#macro shoulder(elbow_yaw, hand_yaw)
union {
  cylinder {
    <0, 0, 0>, <0, UNIT * 2, 0>, UNIT / 2
    texture { tx_plastico }
  }
  object {
    elbow(hand_yaw)
    rotate <0, 0, -elbow_yaw>
    translate <0, UNIT * 2, 0>
  }
}
#end

#macro member(shoulder_pitch, shoulder_yaw, elbow_yaw, hand_yaw)
object {
  shoulder(elbow_yaw, hand_yaw)
  rotate <shoulder_pitch, 0, -shoulder_yaw>
}
#end

// ======================================================================
// CABECA

#macro head()
cone {
  <0, 0, 0>, UNIT
  <UNIT * 2, 0, 0>, 0
  texture { tx_plastico }
}
#end

#macro neck(head_pitch, head_roll)
union {
  cylinder {
    <0, 0, 0>, <0, 0, UNIT * 2>, UNIT / 1.5
    texture { tx_plastico }
  }
  object {
    head()
    rotate <0, head_pitch, -head_roll>
    translate <0, 0, UNIT * 2> * OFFSET_MULTIPLIER
  }
}
#end

#macro spine(neck_pitch, head_pitch, head_roll)
union {
  cylinder {
    <0, 0, 0>, <0, 0, UNIT>, UNIT / 1.5
    texture { tx_plastico }
  }
  object {
    neck(head_pitch, head_roll)
    rotate <0, neck_pitch, 0>
    translate <0, 0, UNIT> * OFFSET_MULTIPLIER
  }
}
#end

#macro upper(spine_roll, neck_pitch, head_pitch, head_roll)
object {
  spine(neck_pitch, head_pitch, head_roll)
  rotate <0, 0, -spine_roll>
}
#end

// ======================================================================
// CORPO
#declare PROPORTIONS = <1, 1.5, 2.5> * UNIT;

#macro hip()
box {
  -PROPORTIONS, PROPORTIONS
  texture { tx_plastico }
}
#end

#macro sloth(
  shoulder_pitch1, shoulder_yaw1, elbow_yaw1, hand_yaw1,
  shoulder_pitch2, shoulder_yaw2, elbow_yaw2, hand_yaw2,
  shoulder_pitch3, shoulder_yaw3, elbow_yaw3, hand_yaw3,
  shoulder_pitch4, shoulder_yaw4, elbow_yaw4, hand_yaw4,
  spine_roll, neck_pitch, head_pitch, head_roll
)
union {
  hip()
  object {
    member(shoulder_pitch1, shoulder_yaw1, elbow_yaw1, hand_yaw1)
    translate <0, PROPORTIONS.y, PROPORTIONS.z * 0.6>
  }
  object {
    member(shoulder_pitch2, shoulder_yaw2, elbow_yaw2, hand_yaw2)
    translate <0, PROPORTIONS.y, -PROPORTIONS.z * 0.6>
  }
  object {
    member(shoulder_pitch3, shoulder_yaw3, elbow_yaw3, hand_yaw3)
    translate <0, PROPORTIONS.y, PROPORTIONS.z * 0.6>
    scale <1.0, -1.0, 1.0>
  }
  object {
    member(shoulder_pitch4, shoulder_yaw4, elbow_yaw4, hand_yaw4)
    translate <0, PROPORTIONS.y, -PROPORTIONS.z * 0.6>
    scale <1.0, -1.0, 1.0>
  }
  object {
    upper(spine_roll, neck_pitch, head_pitch, head_roll)
    translate <0, 0, PROPORTIONS.z>
  }
}
#end


#declare hands_start_keyframe = array[4] { 30 , 30, 15, 0 };
#declare hands_end_keyframe = array[4] { 45 , 65, 65, 35 };
#macro hands_animation(tt)
  #local angles = array[4];
  #local current = 0;

  #while (current < 4)
    #if (tt < 0.4)
      #local normalized_time = tt / 0.4;
      #local angles[current] = hands_start_keyframe[current] * (1 - normalized_time) + hands_end_keyframe[current] * normalized_time;
    #end
    #if (tt >= 0.4 & tt <= 0.6)
      #local angles[current] = hands_end_keyframe[current];
    #end
    #if (tt > 0.6)
      #local normalized_time = (tt - 0.6) / 0.4;
      #local angles[current] = hands_end_keyframe[current] * (1 - normalized_time) + hands_start_keyframe[current] * normalized_time;
    #end
    #local current = current + 1;
  #end
  
  angles
#end

#declare head_idle_keyframe = array[4] { 10, 15, 30, 0 };
#declare head_bob_amplitude = array[4] {0, 0, 0, 50};
#macro head_animation(tt)
  #local angles = array[4];
  #local current = 0;

  #while (current < 4)
    #if (tt < 0.4 | tt > 0.6)
      #local angles[current] = head_idle_keyframe[current];
    #else
      #local normalized_time = (tt - 0.4) / 0.2;
      #local angles[current] = head_bob_amplitude[current] * sin(normalized_time * 2 * pi) + head_idle_keyframe[current];
    #end
    #local current = current + 1;
  #end
  
  angles
#end

// ======================================================================
// DESCRI��O DA CENA 

#declare raio = 2.000;

#include "eixos.inc"

#macro cena(tt)
  #local TR_hands = hands_animation(tt);
  #local TL_hands = hands_animation(tt);
  #local head_angles = head_animation(tt);

  sloth(
    TR_hands[0], TR_hands[1], TR_hands[2], TR_hands[3], // TR member
    -45, 45, 45, 45, // BR member
    TL_hands[0], TL_hands[1], TL_hands[2], TL_hands[3], // TL member
    -45, 30, 40, 30, // TR member
    head_angles[0], head_angles[1], head_angles[2], head_angles[3]   // Head
    )
#end

union{
  object{ eixos(3.00) }

  cena(clock)
}

#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 1.00 >;
#declare raio_cena = 10.0;
#declare dir_camera = < 14.00, 7.00, 4.00 >;
#declare dist_camera = 10*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)


// 45 , 65, 65, 45, // TR member
//     -45, 45, 45, 45, // BR member
//     45 , 65, 65, 45, // TL member
//     -45, 30, 40, 30, // TR member
//     10, 15, 30, 50 

// 30 , 30, 15, 0, // TR member
// -45, 45, 45, 45, // BR member
// 30 , 30, 15, 0, // TL member
// -45, 30, 40, 30, // TR member
// 10, 15, 30, 50   // Head