// Truncated icosahedron normals
// Last edited on 2013-02-01 22:22:38 by stolfilocal

#macro set_normals_trunc_icosahedron(uu, tu, tx, k)
  // Fills the array {uu[k..k+59]} with the vertices of a truncated icosahedron.
  // Also sets {tu[k..k+59]} to {tx}
  // These vertices fit into the faces of the {icosahedron+dodecahedron}.
  // 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);
  
  #local iu = -1;
  #while (iu <= +1) 
    #local iv = -1;
    #while (iv <= +1)
      #declare uu[k] = < iu*fg, iv*fh, 0 >/mgh; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < 0, iv*fg, iu*fh >/mgh; #declare tu[k] = tx; #local k = k + 1;
      #declare uu[k] = < iu*fh, 0, iv*fg >/mgh; #declare tu[k] = tx; #local k = k + 1;
      
      #local iw = -1;
      #while (iw <= +1)
        #declare uu[k] = < iu*fp, iv*fq, iw*fr >/mpqr; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fr, iu*fp, iv*fq >/mpqr; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fq, iw*fr, iu*fp >/mpqr; #declare tu[k] = tx; #local k = k + 1;

        #declare uu[k] = < iu*fi, iv*fj, iw*fk >/mijk; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iw*fk, iu*fi, iv*fj >/mijk; #declare tu[k] = tx; #local k = k + 1;
        #declare uu[k] = < iv*fj, iw*fk, iu*fi >/mijk; #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