
/////////////////////////////////////////////////////////////


// Tree macro for POVray 3.1a and above,

// (c) 1999 Steven Pigeon pigeon@iro.umontreal.ca


/////////////////////////////////////////////////////////////


/*
  
stone wall, like brick wall...

length : in 'slot' units  \___ breaks the wall in length x height boxes,
height : in 'slot' units  /    and each are allocated to different stones

min_stone_length, max_stone_length  \___ size of the stones
min_stone_height, max_stone_height  /

superparametres : controls the superellipsoids that form the wall
shrink: (fraction of a grid unit) that the superellipsoids recess

The resulting object is a 1x1x1 (pov units) cube, with its front, lower-left
corner at <0,0,0>. Resize it and translate it to your taste.

*/

//////////////////////////////////////////////////
#macro stone_wall2( wall_seed,
             wall_length, wall_height, 
             min_stone_length, max_stone_length,
             min_stone_height, max_stone_height,
             superparametres, 
             shrink,
             stone_texture, rgb_low, rgb_high,
             mortar_texture
            )
 #declare nseed = nseed+6;
 #local ra = seed(wall_seed);
 #local rb = seed(wall_seed+3);
 #local rc = seed(wall_seed+4);
 #local rd = seed(wall_seed+5);
 #local grid = array[wall_length+1][wall_height+1] // 'cause conditions are NOT short-cut like in C/C++

 stone_tag_fill(0,0,wall_length+1,wall_height+1,0)
  
 union
  {

   box { (shrink*(1+(rand(ra)-0.5)*shrinkz)), <wall_length,wall_height,1>-(shrink*(1+(rand(rd)-0.5)*shrinkz)) texture { mortar_texture } }
 #local _x=0;
 #local _y=0;

 #while (_y<wall_height)
  #declare _x = 0;

  #while (_x<wall_length)
   #local _lx = 0;
   #local _ly = 0;


   // find next free slot on this row
   #while ((_x < wall_length) & (grid[_x][_y]=1))
    #declare _x = _x +1;
   #end

   #if (_x < wall_length)
    
    #declare _lx=0;
    // find how wide is this slot
    #while ( ((_x+_lx)<wall_length) & (grid[_x+_lx][_y]=0) )
     #declare _lx = _lx + 1;
    #end
 

    // find how high is this slot
    #declare _ly = 0;
    #while ( ((_y+_ly)<wall_height) & (grid[_x][_y+_ly]=0) )
     #declare _ly = _ly + 1;
    #end

    //#if ((_lx>0) & (_ly>0))
    // compute bricksize according to available space
    #declare _lx = min(_lx, max(min_stone_length, int((max_stone_length+1)*rand(ra)) ));
    #declare _ly = min(_ly, max(min_stone_height, int((max_stone_height+1)*rand(ra)) )); 

    //box{ < _x,_y,0> <_x+_lx,_y+_ly,1> pigment { rgb < rand(ra),rand(ra),rand(ra)> } }

     superellipsoid {
      superparametres+<(rand(rb)-0.5)*superx,(rand(rb)-0.5)*supery>
      rotate <90,0,0>
      rotate <(rand(rb)-0.5)*alphx,(rand(rb)-0.5)*bety,(rand(rb)-0.5)*gammz>
      scale <_lx/2 - (shrink*(1+(rand(rb)-0.5)*shrinkz))/2,_ly/2 - (shrink*(1+(rand(rb)-0.5)*shrinkz))/2,1/2-(shrink*(1+(rand(rb)-0.5)*shrinkz))/2>
      translate <_x+_lx/2+(rand(rb)-0.5)*xetax,  _y+_ly/2+(rand(rb)-0.5)*yetay, 1/2+(rand(rb)-0.5)*zetaz+zetbz>                     
      //pigment { rgb < rand(ra),rand(ra),rand(ra)> }
      texture { stone_texture rotate rand(ra) translate rand(ra)}
      #local _t = rgb_low + rand(ra)*(rgb_high-rgb_low);
      pigment { rgb _t }
      #undef _t
     }
    stone_tag_fill(_x,_y,_lx,_ly,1)  
 
   #end // if (_x < wall_length)

   #declare _x = _x+ _lx; // skip this brick
  #end // while (_x < wall_length)

  // let's go to the next row  
  #declare _y = _y + 1;
 #end
  scale < 1/wall_length,1/wall_height,1>
 } 
#end

//////////////////////////////////////////////////
#macro stone_tag_fill(__x,__y,__lx,__ly, __f)
 #local _i=0;
 // initialize
 #while (_i<__lx)
  #local _j=0;
  #while (_j<__ly)
   #declare grid[__x+_i][__y+_j] = __f;
   #declare _j = _j+1;
  #end
  #declare _i = _i+1;
 #end
 #undef _i
#end

