// PoVRay 3.7 Scene File "Urbanism2_test.pov"
// author :  Thomas de Groot.
// date   :  March 2013
// version:  3-3-2013

// +w1000 +h650 +a0.3 +am2 +bm2 +wt6

//--------------------------------------------------------------------------
#version 3.7;

global_settings {
  assumed_gamma 1.0 
  radiosity {
    pretrace_start 0.08 
    pretrace_end   0.004
    count 50, 500
    nearest_count 10, 5
    error_bound 0.6 
    recursion_limit 2 
    low_error_factor .3 
    gray_threshold 0.0
    minimum_reuse 0.010
    maximum_reuse 0.1	
    brightness 1  

    adc_bailout 0.01/2
    normal off  
    media off   
    always_sample off 
    //max_sample 1.0
  }
}
#default{ finish{ ambient 0.0 diffuse 0.7 }} 
#default {pigment {rgb 1}}
//--------------------------------------------------------------------------
#include "colors.inc"
#include "shapes.inc"
#include "rand.inc"
//--------------------------------------------------------------------------
// camera ------------------------------------------------------------------
#declare Camera_0 = camera {perspective angle 90               // front view
                            location  <0.0 , 2.0 ,-2.8>
                            right     x*image_width/image_height
                            look_at   <0.0 , 0.0 , 0.0>}
#declare Camera_1 = camera {/*ultra_wide_angle*/ angle 90   // diagonal view
                            location  <2.0 , 2.0 ,-3.0>
                            right     x*image_width/image_height
                            look_at   <0.0 , 0.0 , 0.0>}
#declare Camera_2 = camera {/*ultra_wide_angle*/ angle 90  //right side view
                            location  <3.0 , 2.0 , 0.0>
                            right     x*image_width/image_height
                            look_at   <0.0 , 0.0 , 0.0>}
#declare Camera_3 = camera {/*ultra_wide_angle*/ angle 90        // top view
                            location  <0.0 , 5.0 ,-0.001>
                            right     x*image_width/image_height
                            look_at   <0.0 , 0.0 , 0.0>}
camera{Camera_0}
// sun ----------------------------------------------------------------------
light_source{< -3000,3000,3000> color White}
// sky ----------------------------------------------------------------------
sky_sphere { pigment { gradient <0,1,0>
                       color_map { [0.00 rgb <0.6,0.7,1.0>]
                                   [0.35 rgb <0.1,0.0,0.8>]
                                   [0.65 rgb <0.1,0.0,0.8>]
                                   [1.00 rgb <0.6,0.7,1.0>] 
                                 } 
                       scale 2         
                     } // end of pigment
           } //end of skysphere
// ground -------------------------------------------------------------------
plane{ <0,1,0>, 0 
       texture{ pigment{ color srgb<1.0, 0.9, 0.0>}
              } // end of texture
     } // end of plane
//---------------------------------------------------------------------------
//---------------------------- objects in scene ----------------------------
//---------------------------------------------------------------------------

 // ----------------- HF_Square macro ------------------
#declare Fn_1 =
 function(x, y, z)
  {1-(-f_snoise3d(x*2,y*2,z*2)*0.25)}
// -----------------------------------------------------
#declare Surface =
object{ HF_Square( Fn_1, //Function,
                     0, // UseUVheight:  0 or 1
                     1, // UseUVtexture: 0 or 1
               <50,50>, // Resolution,
                     1, // Smooth: 0 or 1
                     "",// FileName, ""=no file,
           <-1,0,-1>*2, //MnExt,
           <1,1,1>*2    //MxExt
                      ) //------------------------------ 
  texture{ pigment{ checker
                    color srgb <0.7, 0.6, 0>
                    color srgb <0.8, 0.7, 0>
                    scale 0.05}
           finish { phong 0.1}
         } // end of texture
  scale <1.5,0.5,1.5>*1
  rotate<0,0,0>
  //translate <0,-1.5,0>
} 

object {Surface}

// -----------------------------------------------------
//A Block object determines the size and form of a city block.
//The outer boundaries define the streets.
//Holes inside de Block define coutyards or alleys.
#declare Block =
difference {
box {
  <-1.00, -1.00, -1.00>,< 1.00, 1.00, 1.00>   
  scale <1.5, 1, 1.5>
} 
cylinder {
  <0, -1.5, 0>, <0, 2.00, 0>, 0.50 
  scale <1, 1 ,1>
  translate <-0, 0, 0>
}
cylinder {
  <0, -1.5, 0>, <0, 2.00, 0>, 0.30 
  scale <1, 1 ,1>
  translate <-0.5, 0, 0.5>
}
cylinder {
  <0, -1.5, 0>, <0, 2.00, 0>, 0.50 
  scale <1, 1 ,1>
  translate <0.5, 0, -0.5>
}
cylinder {
  <0, -1.5, 0>, <0, 2.00, 0>, 0.40 
  scale <1, 1 , 1>
  translate <0.0, 0, -1.0>
}
  rotate 35*y
}

// -----------------------------------------------------
//House elements.
#declare House =
difference {
  union {
    box {
      <-0.50, -0.50, -0.50>,< 0.50, 0.50, 0.50>   
    }
    box {
      <-0.49, 0.50, -0.49>,< 0.49, 0.70, 0.49>   
    }
  }
  box { //inner space
    <-0.48, -0.00, -0.48>,< 0.48, 0.36, 0.48>   
  }
  box { //door
    <-0.40, 0.00, -0.51>,<-0.20, 0.35, 0.51>   
  } 
  box { //window
    <-0.51, 0.25, -0.15>,< 0.51, 0.40, 0.00>   
  }
  scale 0.1
}

#declare Floor =
difference {
  box {
    <-0.50, 0.00, -0.50>,< 0.50, 0.70, 0.50> 
  }  
  box { //inner space
    <-0.50, -0.01, -0.50>,< 0.48, 0.41, 0.48> 
  }  
  box { //window
    <-0.15, 0.25, -0.51>,< 0.00, 0.40, 0.51>   
  }
  scale 0.1
}

#declare Dome =
union {
  sphere {
    <0, 0.7, 0>, 0.5 
    scale <1, 0.8, 1> 
  }
  cylinder {
    <0, 0, 0>, <0, 0.7, 0>, 0.5
  }
  scale 0.1
}

#declare Terrace =
box {
  <-0.45, 0.50, -0.45>,< 0.45, 1.10, 0.45>   
  scale 0.1
}

// -----------------------------------------------------
// -----------------------------------------------------
#declare Rand = seed (19323);
#declare Counter = 1;
#declare Numbers = 400;

#declare RandProb   = seed (9673);
#declare DomeProb   = 0.1;
#declare Floor1Prob = 0.5;
#fopen Domes "Domes_locs.inc" write
#fopen Houses "Houses_locs.inc" write

// -----------------------------------------------------
//first house to start the block's union
#declare Norm  = <0, 0, 0>;
#declare Start = VRand_In_Obj(Block, Rand);
#declare Pos   = trace (Surface, Start+<0, 100, 0>, -y, Norm );   

#declare HouseBlock =
difference {
  object {House}
  object {Terrace translate 0.001*y}
  scale <RRand(0.9, 1.1, Rand), 1, RRand(0.9, 1.1, Rand)>
  rotate RRand(-10, 10, Rand)*y 
  translate Pos
}

// -----------------------------------------------------
//incremental houses
#while (Counter < Numbers)
   
  #declare Norm  = <0, 0, 0>;
  #declare Start = VRand_In_Obj(Block, Rand);
  #declare Pos   = trace (Surface, Start+<0, 100, 0>, -y, Norm );
  
  //locations already inside a house are skipped. This reduces the number of overlaps.
  #if (!inside(HouseBlock, Pos))
      
    #declare Floorer = Prob (Floor1Prob, RandProb);
    #declare Domer   = Prob (DomeProb, RandProb);
      
    #local Trans = 
    transform {
      scale <RRand(0.9, 1.1, Rand), 1, RRand(0.9, 1.1, Rand)>
      rotate RRand(-10, 10, Rand)*y
    }
      
    //if no upper floor is present, data are written to file.
    #if (! Floorer)
      #local House_scale = <RRand(0.9, 1.1, Rand), 1, RRand(0.9, 1.1, Rand)>;
      #local House_rot = RRand(-10, 10, Rand);
      //-------------------------------------------------------------------------------------------------------
      //write location and scale of single floor houses to file
      #write (Houses, "<",str(Pos.x,3,4),", ",str(Pos.y,3,4),", ",str(Pos.z,3,4),">, ",
                      "<",str(House_scale.x,3,4),", ",str(House_scale.y,3,4),", ",str(House_scale.z,3,4),">, ",
                      str(House_rot,3,4),",\n")
      //-------------------------------------------------------------------------------------------------------
    
    //Upper floor is present. Testing for additional dome and if not, differencing the terrace.
    #else  
    
      #declare HouseBlock =
      #if (! Domer)
        difference { 
      #end
    
      union {
        object {HouseBlock} //this is an iterative object.
      
        #if (Domer)
          union { 
            object {House rotate int(RRand(0,4,Rand))*90*y}
            object {Floor rotate int(RRand(0,4,Rand))*90*y translate 0.05*y}
            #local Dome_scale = <RRand(0.9, 1.1, Rand), 1, RRand(0.9, 1.1, Rand)>;
            scale Dome_scale
            rotate RRand(-10, 10, Rand)*y 
            translate Pos
          }
        
          #if (Dome_scale.x < Dome_scale.z)
            #local Dome_scale = <Dome_scale.x, Dome_scale.y, Dome_scale.x>;
          #else
            #local Dome_scale = <Dome_scale.z, Dome_scale.y, Dome_scale.z>;
          #end
          //-------------------------------------------------------------------------------------------------------
          //write location and scale of dome to file
          #write (Domes, "<",str(Pos.x,3,4),", ",str(Pos.y,3,4),", ",str(Pos.z,3,4),">, ",
                         "<",str(Dome_scale.x,3,4),", ",str(Dome_scale.y,3,4),", ",str(Dome_scale.z,3,4),">",",\n")
          //-------------------------------------------------------------------------------------------------------
        
        #else
          union {
            object {House rotate int(RRand(0,4,Rand))*90*y}
            object {Floor rotate int(RRand(0,4,Rand))*90*y translate 0.05*y}
            transform {Trans}
            translate Pos
          }
        #end  //of Domer
      
      } //HouseBlock union
    
      //without dome, the terrace has to be differenced from the floor.
      #if (! Domer)
        object {Terrace
          translate 0.05*y
          transform {Trans}
          translate Pos
        }
      
        } //closing the HouseBlock difference
      #end  //of ! Domer 
             
    #end  //of ! Floorer        

    #declare Counter = Counter + 1; 
      
    #debug concat("houses: ", str(Counter,4,0),"\n") 

  #else
    
    //#debug "   no location found.\n"
      
  #end  //of inside

#end  //of Counter

#fclose Domes
#fclose Houses

// -----------------------------------------------------
#fopen Domes "Domes_locs.inc" read
#declare HouseBlock =
union {
  object {HouseBlock}
  #while (defined(Domes))
    #read (Domes, Pos, Dome_scale)
    object {Dome
      translate 0.05*y
      scale Dome_scale
      translate Pos
    }
  #end
}

// -----------------------------------------------------
#fopen Houses "Houses_locs.inc" read
#declare HouseBlock =
union {
  object {HouseBlock}
  #while (defined(Houses))
    #read (Houses, Pos, Scale, Rot)
    difference {
      object {House
        rotate int(RRand(0,4,Rand))*90*y
      }
      object {Terrace
        translate 0.01*y
      }
      scale Scale
      rotate Rot*y
      translate Pos
    }
  #end
}

// -----------------------------------------------------
/*
intersection {
  object {Block}
  object {HouseBlock}

    pigment {color rgb 1}  
    finish { specular 0.02 roughness 0.005 diffuse 0.7 } 

}
*/

object {HouseBlock
  pigment {color rgb 1}  
  finish { specular 0.02 roughness 0.005 diffuse 0.7 } 
}

// -----------------------------------------------------