// Twice truncated icosahedron normals
// Last edited on 2013-02-02 13:48:57 by stolfilocal

#macro set_normals_bitrunc_icosahedron(uu, tu, tx, k)
  // Fills the array {uu[k..k+179]} with the vertices of a bitruncated icosahedron.
  // Also sets {tu[k..k+179]} to {tx}
  // These vertices fit into the faces of the {icosahedron+dodecahedron+truncated_icosahedron}.
  // Returns the next free index.
  
  // Vertices of dodecahedron are {(±fa, ±fb, 0)/mab} rotated to the right:
  #local fa = 1.0;
  #local fb = (sqrt(5) - 1)/2;
  #local mab = sqrt(fa*fa + fb*fb);
  
  // Vertices of icosahedron are {(±fc, 0, ±fd)/mcd} rotated to the right, and {(±fe, ±fe, ±fe)}:
  #local fc = (2*fa+fb);
  #local fd = fa;
  #local mcd = sqrt(fc*fc + fd*fd);
  
  #local fe = (fa+fb);
  #local me = fe*sqrt(3);
  
  // Vertices of the truncated icosahedron are barycenters: 
  //  {(±fg, ±fh,   0)/mgh}  rotated to the right (12)
  //  {(±fp, ±fq, ±fr)/mpqr} rotated to the right (24)
  //  {(±fi, ±fj, ±fk)/mijk} rotated to the right (24)
  #local fg = fa/mab + 2*fc/mcd;
  #local fh = fb/mab;
  #local mgh = sqrt(fg*fg + fh*fh);
  
  #local fp = fa/mab + fc/mcd + fe/me;
  #local fq = fb/mab + fe/me;
  #local fr = fd/mcd + fe/me;
  #local mpqr = sqrt(fp*fp + fq*fq + fr*fr);
  
  #local fi = fa/mab + fd/mcd + fe/me;
  #local fj = fb/mab + fc/mcd + fe/me;
  #local fk = fe/me;
  #local mijk = sqrt(fi*fi + fj*fj + fk*fk);
  
  // Vertices of the bitruncated icosahedron are barycenters: 
  //  {(±fA, ±fB,   0)/mAB}  rotated to the right (12)
  //  {(±fC, ±fD,   0)/mCD}  rotated to the right (12)
  //  {(±fX, ±fY,   0)/mXY}  rotated to the right (12)
  //  {(±fE, ±fF, ±fG)/mEFG} rotated to the right (24)
  //  {(±fH, ±fI, ±fJ)/mHIJ} rotated to the right (24)
  //  {(±fK, ±fL, ±fM)/mKLM} rotated to the right (24)
  //  {(±fN, ±fP, ±fQ)/mNPQ} rotated to the right (24)
  //  {(±fR, ±fS, ±fT)/mRST} rotated to the right (24)
  //  {(±fU, ±fV, ±fW)/mUVW} rotated to the right (24)

  #local fA = 2*fi/mijk + fd/mcd;
  #local fB = 2*fj/mijk + fc/mcd;
  #local mAB = sqrt(fA*fA + fB*fB);
  
  #local fC = fd/mcd;
  #local fD = 2*fg/mgh + fc/mcd;
  #local mCD = sqrt(fC*fC + fD*fD);
  
  #local fE = fp/mpqr + fg/mgh + fc/mcd;
  #local fF = fq/mpqr + fh/mgh ;
  #local fG = fr/mpqr          + fd/mcd;
  #local mEFG = sqrt(fE*fE + fF*fF + fG*fG);
  
  #local fH = fg/mgh + fp/mpqr + fa/mab;
  #local fI = fh/mgh + fq/mpqr + fb/mab;
  #local fJ = fr/mpqr;
  #local mHIJ = sqrt(fH*fH + fI*fI + fJ*fJ);
  
  #local fK = fp/mpqr + fi/mijk + fa/mab;
  #local fL = fq/mpqr + fj/mijk + fb/mab;
  #local fM = fr/mpqr + fk/mijk;
  #local mKLM = sqrt(fK*fK + fL*fL + fM*fM);
  
  #local fN = fp/mpqr + fi/mijk + fe/me;
  #local fP = fq/mpqr + fj/mijk + fe/me;
  #local fQ = fr/mpqr + fk/mijk + fe/me;
  #local mNPQ = sqrt(fN*fN + fP*fP + fQ*fQ);
  
  #local fR = fp/mpqr + fj/mijk + fc/mcd;
  #local fS = fq/mpqr + fk/mijk;
  #local fT = fr/mpqr + fi/mijk + fd/mcd;
  #local mRST = sqrt(fR*fR + fS*fS + fT*fT);
  
  #local fU = fp/mpqr + fj/mijk + fe/me;
  #local fV = fq/mpqr + fk/mijk + fe/me;
  #local fW = fr/mpqr + fi/mijk + fe/me;
  #local mUVW = sqrt(fU*fU + fV*fV + fW*fW);
  
  #local fX = 2*fi/mijk + fa/mab;
  #local fY = 2*fj/mijk + fb/mab;
  #local mXY = sqrt(fX*fX + fY*fY);

  #local iu = -1;
  #while (iu <= +1) 
    #local iv = -1;
    #while (iv <= +1)
      #declare uu[k] = < iu*fA, iv*fB, 0 >/mAB; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < 0, iv*fA, iu*fB >/mAB; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < iu*fB, 0, iv*fA >/mAB; #declare tu[k] = tx; #local k = k + 1;
      
      #declare uu[k] = < iu*fC, iv*fD, 0 >/mCD; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < 0, iv*fC, iu*fD >/mCD; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < iu*fD, 0, iv*fC >/mCD; #declare tu[k] = tx; #local k = k + 1;
      
      #declare uu[k] = < iu*fX, iv*fY, 0 >/mXY; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < 0, iv*fX, iu*fY >/mXY; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < iu*fY, 0, iv*fX >/mXY; #declare tu[k] = tx; #local k = k + 1;
      
      #local iw = -1;
      #while (iw <= +1)
        #declare uu[k] = < iu*fE, iv*fF, iw*fG >/mEFG; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fG, iu*fE, iv*fF >/mEFG; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fF, iw*fG, iu*fE >/mEFG; #declare tu[k] = tx; #local k = k + 1;

        #declare uu[k] = < iu*fH, iv*fI, iw*fJ >/mHIJ; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fJ, iu*fH, iv*fI >/mHIJ; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fI, iw*fJ, iu*fH >/mHIJ; #declare tu[k] = tx; #local k = k + 1;
      
        #declare uu[k] = < iu*fK, iv*fL, iw*fM >/mKLM; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fM, iu*fK, iv*fL >/mKLM; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fL, iw*fM, iu*fK >/mKLM; #declare tu[k] = tx; #local k = k + 1;

        #declare uu[k] = < iu*fN, iv*fP, iw*fQ >/mNPQ; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fQ, iu*fN, iv*fP >/mNPQ; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fP, iw*fQ, iu*fN >/mNPQ; #declare tu[k] = tx; #local k = k + 1;
      
        #declare uu[k] = < iu*fR, iv*fS, iw*fT >/mRST; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fT, iu*fR, iv*fS >/mRST; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fS, iw*fT, iu*fR >/mRST; #declare tu[k] = tx; #local k = k + 1;

        #declare uu[k] = < iu*fU, iv*fV, iw*fW >/mUVW; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fW, iu*fU, iv*fV >/mUVW; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fV, iw*fW, iu*fU >/mUVW; #declare tu[k] = tx; #local k = k + 1;
      
        #local iw = iw + 2;
      #end
      #local iv = iv + 2;
    #end
    #local iu = iu + 2;
  #end
  (k)
#end