// Bernardo do Amaral Teodosio - 167494 - MC937 A
// LAB 08

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

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

#local 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 }
  }

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

#local tx_fosca_2 = 
  texture{
    pigment{ color rgb < 0.40, 0.40, 0.40 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#local tx_fosca_3 = 
  texture{
    pigment{ color rgb < 1.00, 1.00, 0.00 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#local tx_fosca_black = 
  texture{
    pigment{ color rgb < 0.20, 0.20, 0.20 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#local tx_coke = 
  texture{
    pigment{ color rgb < 1, 0, 0 > }
    finish{ diffuse 0.2 reflection 0.7*< 1.00, 0.85, 0.30 > ambient 0.1 }
  }

#local tx_coke_2 = 
  texture{
    pigment{ color rgb < 0.9, 0.00, 0.00 > }
    finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#local tx_fosca_4 = 
  texture{
    pigment{ color rgb < 0.5, 0.9, 0.5 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#local 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 }
  }

#local 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 }
  }


#local 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
  }

#local tx_xadrez_2 =
  texture{
    pigment{ checker color rgb < 0.00, 0.02, 0.00 >, color rgb < 1.00, 0.97, 0.90 > }
    finish{ diffuse 0.9 ambient 0.1 }
    scale 1
  }

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

// Partes da cena:

#include "eixos.inc"

// Lab 5


// CRIA O CIRCULO USANDO O COUNT DE QUANTAS ESFERAS QUER
#macro createCircle(sphereRadius, sphereCount)
  union {
    #for(i, -pi, pi, 2*pi/sphereCount)
      sphere { <0, cos(i), sin(i)>, sphereRadius texture{ tx_coke_2 }}
    #end
  }
#end

#macro createCurve(sphereRadius)
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }

  union {
    #for(i, 0, 1, 0.001)
      #local MULTIPLIER = 10;
      #local value = i*MULTIPLIER;


      // part 1 (see notebook for parts)
      #if (i >= 0 & i < 1/8)
        #local tt0 = 0/8;
        #local tt1 = 1/8;
        #local vv0 = 0;
        #local vv1 = 1;
        #local targetValue = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 0, targetValue> }
      #end

      #if (i >= 1/8 & i < 2/8)
        #local tt0 = 1/8;
        #local tt1 = 2/8;
        #local vv0 = pi/2;
        #local vv1 = pi;
        #local alphaAngle = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 1 + cos(alphaAngle), 1 + sin(alphaAngle)>}
      #end

      #if (i >= 2/8 & i < 3/8)
        #local tt0 = 2/8;
        #local tt1 = 3/8;
        #local vv0 = 1;
        #local vv1 = 2;
        #local targetValue = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, targetValue, 2> }
      #end

      #if (i >= 3/8 & i < 4/8)
        #local tt0 = 3/8;
        #local tt1 = 4/8;
        #local vv0 = 3*pi/2;
        #local vv1 = 5*pi/2;
        #local alphaAngle = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 2 + cos(alphaAngle), 3 + sin(alphaAngle)>}
      #end

      #if (i >= 4/8 & i < 5/8)
        #local tt0 = 4/8;
        #local tt1 = 5/8;
        #local vv0 = 3;
        #local vv1 = 0;
        #local targetValue = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, targetValue - 1, 4> }
      #end

      #if (i >= 5/8 & i < 6/8)
        #local tt0 = 5/8;
        #local tt1 = 6/8;
        #local vv0 = pi/2;
        #local vv1 = pi;
        #local alphaAngle = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 0 + cos(alphaAngle) - 1, 3 + sin(alphaAngle)>}
      #end

      #if (i >= 6/8 & i < 7/8)
        #local tt0 = 6/8;
        #local tt1 = 7/8;
        #local vv0 = 3;
        #local vv1 = 0;
        #local targetValue = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 0 - 2, targetValue> }
      #end

      #if (i >= 7/8 & i < 8/8)
        #local tt0 = 7/8;
        #local tt1 = 8/8;
        #local vv0 = pi;
        #local vv1 = 2*pi;
        #local alphaAngle = vv0 + ((i - tt0)/(tt1 -  tt0)) * (vv1 - vv0);

        object { cursor translate <0, 0 + cos(alphaAngle) - 1, sin(alphaAngle)>}
      #end
    #end
  }
#end


#macro interpolNumber(t0, v0, t1, v1, tt)
  #local r = (tt - t0) / (t1 - t0);
  #local s = 1 - r;
  #local vv = s * v0 + r * v1;
  vv
#end

// returns a point
#macro interpol(t0, v0, t1, v1, tt)
  #local r = (tt - t0) / (t1 - t0);
  #local s = 1 - r;
  #local vv = s * v0 + r * v1;
  #local returnX = s * v0.x + r * v1.x;
  #local returnY = s * v0.y + r * v1.y;
  #local returnZ = s * v0.z + r * v1.z;

  <returnX, returnY, returnZ>
#end

#macro createSquare(sphereRadius)
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }
  union {
    #for(i, 0, 1, 0.001)
      #local multiplier = 5;
      #local value = i*multiplier;

      #if (i >= 0 & i < 1/4)
        #local t0 = 0/4;
        #local t1 = 1/4;
        #local v0 = <0, 0, 0>;
        #local v1 = <0, 0, 1>;

        // object { cursor translate <0, 0, interpolNumber(t0, v0, t1, v1, i)> }
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end

      #if (i >= 1/4 & i < 2/4)
        #local t0 = 1/4;
        #local t1 = 2/4;
        #local v0 = <0, 0, 1>;
        #local v1 = <0, 1, 1>;
        
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end
      
      #if (i >= 2/4 & i < 3/4)
        #local t0 = 2/4;
        #local t1 = 3/4;
        #local v0 = <0, 1, 1>;
        #local v1 = <0, 1, 0>;
        
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end

      #if (i >= 3/4 & i < 4/4)
        #local t0 = 3/4;
        #local t1 = 4/4;
        #local v0 = <0, 1, 0>;
        #local v1 = <0, 0, 0>;
        
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end
    #end
  }
#end 

#macro bezierArc(t0, t1, A, B, C, D, tt)
  #local AB = interpol(t0, A, t1, B, tt);
  #local BC = interpol(t0, B, t1, C, tt);
  #local CD = interpol(t0, C, t1, D, tt);

  #local ABC = interpol(t0, AB, t1, BC, tt);
  #local BCD = interpol(t0, BC, t1, CD, tt);

  #local ABCD = interpol(t0, ABC, t1, BCD, tt);

  ABCD
#end

#macro suavizar(P, N, i)
  // suaviza a juntaentre o arco i e o arco j =  mod(i+1, N)
  #local j = mod(i+1, N);
  #local vv = (P[j][1] - P[i][2])/2;
  #local P[i][2] = P[i][3] - vv;
  #local P[j][1] = P[j][0] + vv;
#end

#macro createStrangeFigure(sphereRadius)
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }
  union {
    #for(i, 0, 1, 0.01)
      #local A = <0, 0, 0>;
      #local B = <0, 1, 2>;
      #local C = <0, 2, -2>;
      #local D = <0, 3, 1>;


      object { cursor translate bezierArc(0, 1, A, B, C, D, i) }
    #end
  }
#end 




#macro createSmoothStrangeSquare(sphereRadius)
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }
  union {
    #for(i, 0, 1, 0.001)
      #if (i >= 0 & i < 1/4)
        #local t0 = 0/4;
        #local t1 = 1/4;

        #local PDA = <0, 0, 0>;
        #local VDA = <0, -2, 0.75>;

        #local PAB = <0, 0, 2>;
        #local VAB = <0, 2, 1.5>;

        #local A1 = PDA;
        #local A4 = PAB;

        #local A2 = A1 + VDA;
        #local A3 = A4 - VAB;

        object { cursor translate bezierArc(t0, t1, A1, A2, A3, A4, i) }
      #end

      #if (i >= 1/4 & i < 2/4)
        #local t0 = 1/4;
        #local t1 = 2/4;

        #local PDA = <0, 0, 0>;
        #local VDA = <0, -2, 0.75>;

        #local PAB = <0, 0, 2>;
        #local VAB = <0, 2, 1.5>;

        #local A1 = PEA;
        #local A4 = <0, 0, 2>;

        #local A2 = A1  + VDA;
        #local A3 = A4 - VAB;

        #local PBC = <0, 2, 2>;
        #local VBC = <0, 3, 1>;

        #local B1 = PAB;
        #local B4 = PBC;
        #local B2 = B1 + VAB;
        #local B3 = B4 - VBC;

        object { cursor translate bezierArc(t0, t1, B1, B2, B3, B4, i) }
      #end
      
      #if (i >= 2/4 & i < 3/4)
        #local t0 = 2/4;
        #local t1 = 3/4;

        #local A = <0, 2, 2>;
        #local B = <0, 3, 1>;
        #local C = <0, 1, 0.5>;
        #local D = <0, 2, 0>;

        object { cursor translate bezierArc(t0, t1, A, B, C, D, i) }
      #end

      #if (i >= 3/4 & i < 4/4)
        #local t0 = 3/4;
        #local t1 = 4/4;
        #local v0 = <0, 2, 0>;
        #local v1 = <0, 0, 0>;
        
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end
    #end
  }
#end 





#macro createStrangeSquare(sphereRadius)
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }
  union {
    #for(i, 0, 1, 0.001)
      #if (i >= 0 & i < 1/4)
        #local t0 = 0/4;
        #local t1 = 1/4;

        #local A = <0, 0, 0>;
        #local B = <0, -2, 0.75>;
        #local C = <0, 2, 1.5>;
        #local D = <0, 0, 2>;

        object { cursor translate bezierArc(t0, t1, A, B, C, D, i) }
      #end

      #if (i >= 1/4 & i < 2/4)
        #local t0 = 1/4;
        #local t1 = 2/4;

        #local A = <0, 0, 2>;
        #local B = <0, 0.5, 4>;
        #local C = <0, 1.25, 0>;
        #local D = <0, 2, 2>;

        object { cursor translate bezierArc(t0, t1, A, B, C, D, i) }
      #end
      
      #if (i >= 2/4 & i < 3/4)
        #local t0 = 2/4;
        #local t1 = 3/4;

        #local A = <0, 2, 2>;
        #local B = <0, 3, 1>;
        #local C = <0, 1, 0.5>;
        #local D = <0, 2, 0>;

        object { cursor translate bezierArc(t0, t1, A, B, C, D, i) }
      #end

      #if (i >= 3/4 & i < 4/4)
        #local t0 = 3/4;
        #local t1 = 4/4;
        #local v0 = <0, 2, 0>;
        #local v1 = <0, 0, 0>;
        
        object { cursor translate interpol(t0, v0, t1, v1, i) }
      #end
    #end
  }
#end 


// result in R
// interpol P and Q elements
// N is the number of lines
// interpol(t0, v0, t1, v1, tt)
#macro interpol1Matrix(P, Q, N, c0, c1, cc, R)
  #for(i, 0, N - 1, 1)
    #for(j, 0, 4 - 1, 1)
      #local R[i][j] = interpol(c0, P[i][j], c1, Q[i][j], cc);
    #end
  #end
#end

// P is the matrix
// N is the number of lines of the matrix P
// M is the number of spheres per arc
#macro noh(P, N, M)
  #local sphereRadius = 0.1;
  #local cursor = sphere{ < 0.00, 0.00, 0.00 >, sphereRadius texture{ tx_coke_2 } }

  union {
    #for(matrixLine, 0, N - 1, 1)
      #for(i, 0, 1, 1/M)
        object { cursor translate bezierArc(0, 1, P[matrixLine][0], P[matrixLine][1], P[matrixLine][2], P[matrixLine][3], i) }
      #end
    #end
  }
#end 


// result in R
// interpol P , matrix of 3 dimensions
// N is the number of lines. P[0] is a frame, represented by a matrix of N lines
// f0 and f1 are the indexes of P to be interpolated (the frame indexes)
// interpol(t0, v0, t1, v1, tt)
#macro interpolMatrix(P, f0, f1, N, c0, c1, cc, R)
  #for(i, 0, N - 1, 1)
    #for(j, 0, 4 - 1, 1)
      #local R[i][j] = interpol(c0, P[f0][i][j], c1, P[f1][i][j], cc);
    #end
  #end
#end


#include "pontos.inc"

#macro busca_tempo(clk, framesCount, frameTimeArray)
  #local valueToBeReturned = 0;

  #if (clk = 0)
    #local valueToBeReturned = 0;
  #elseif (clk = 1)
    #local valueToBeReturned = NK - 2;
  #else  
    #for(i, 0, framesCount - 1, 1)
      #if (clk >= frameTimeArray[i])
        #local valueToBeReturned = i;
      #end
    #end
  #end

  valueToBeReturned
#end

union {
  // object{ eixos(3.00) }
  
  // sphere{ < 0.00, 0.00 + 10 * clock, 0>, 0.1 texture{ tx_coke_2 } }


  // #local N = 4;
  // #if (clock <= 1/2)
  //   interpolMatrix(P, 0, 1, N, 0, 1/2, clock, R)
  //   object { noh(R, N, 100) }    
  // #else
  //   interpolMatrix(P, 1, 0, N, 1/2, 1, clock, R)
  //   object { noh(R, N, 100) }    
  // #end

  #local frameIndex = busca_tempo(clock, NK, tk);

  interpolMatrix(P, frameIndex, frameIndex + 1, N, 0, 1, clock, R)
  object { noh(R, N, 100) }   
}



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