// PoVRay 3.7 Scene File "Urbanism3_macro.pov" // This file is licensed under the terms of the CC-LGPL // author : Thomas de Groot. // date : March 2013 // version: 2013.04.08 // +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.2> 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 } } // ground ------------------------------------------------------------------- plane { <0,1,0>, -10 texture { pigment {color srgb<1.0, 0.9, 0.0>}} } //--------------------------------------------------------------------------- //---------------------------- 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 } normal {granite 0.5 scale 0.001} finish {diffuse 0.7} } scale <2.5, 1, 2.5> translate -1*y } 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.50, -0.10, -1.50>,< 1.50, 0.10, 1.50>} cylinder {<0, -0.15, 0>, <0, 0.15, 0>, 0.50} box {<-0.10, -0.16, -1.51>,< 0.10, 0.16, 1.51>} box {<-1.51, -0.16, -0.10>,< 1.51, 0.16, 0.10>} cylinder {<1.50, -0.15, -1.50>, <1.50, 0.15, -1.50>, 0.50} rotate 45*y } // ----------------------------------------------------- //House elements. Because of the inside() test, the ground //floor should always be closed. #declare House = difference { union { box { <-0.50, -1.50, -0.50>,< 0.50, 0.50, 0.50> } box { <-0.49, 0.50, -0.49>,< 0.49, 0.70, 0.49> } } box { //doorway <-0.40, 0.01, -0.51>,<-0.20, 0.35, -0.48> } box { //door <-0.39, 0.02, -0.51>,<-0.21, 0.34, -0.475> pigment {rgb 0} } box { //doorway <-0.40, 0.01, 0.48>,<-0.20, 0.35, 0.51> } box { //door <-0.39, 0.02, 0.475>,<-0.21, 0.34, 0.51> pigment {rgb 0} } box { //window frame <-0.51, 0.25, -0.15>,< -0.48, 0.40, 0.00> } box { //window <-0.51, 0.26, -0.14>,< -0.475, 0.39, -0.01> pigment {rgb 0} } box { //window frame < 0.48, 0.25, -0.15>,< 0.51, 0.40, 0.00> } box { //window < 0.475, 0.26, -0.14>,< 0.51, 0.39, -0.01> } 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 Tower = difference { union { box {<-0.50, 0.70, -0.50>,< 0.50, 2.00, 0.50>} box {<-0.50, 0.00, -0.50>,< 0.50, 0.70, 0.50>} } box {<-0.80, -0.10, -0.51>,< 0.00, 2.65, 0.51> rotate -2*z translate <-0.50, 0.70, 0.00>} box {<-0.80, -0.10, -0.51>,< 0.00, 2.65, 0.51> rotate -2*z translate <-0.50, 0.70, 0.00> rotate 90*y} box {<-0.80, -0.10, -0.51>,< 0.00, 2.65, 0.51> rotate -2*z translate <-0.50, 0.70, 0.00> rotate 180*y} box {<-0.80, -0.10, -0.51>,< 0.00, 2.65, 0.51> rotate -2*z translate <-0.50, 0.70, 0.00> rotate -90*y} box {<-0.30, 1.80, -0.30>,< 0.30, 2.10, 0.30>} scale 0.1 } #declare Terrace = box { <-0.45, 0.50, -0.45>,< 0.45, 1.10, 0.45> scale 0.1 } // ======================================================================================== #macro Orientation(Block, Loc) // ======================================================================================== #local Dir0 = <10e9,0,0>; #local Norm0 = <0,0,0>; #declare NormMin = Norm0; #local Intersec = trace (Block, Loc, Dir0, Norm0); #declare IntersecMin = Intersec; #declare NormMin = Norm0; #declare DistMin = VDist (Loc,Intersec); #for (Angle, 0, 330, 30) #local Norm0 = <0,0,0>; #local Dir = vaxis_rotate (Dir0, , Angle); #local Intersec = trace (Block, Loc, Dir, Norm0); #local Dist = VDist (Loc,Intersec); //------------------------------------------------------------------------- //only uncomment if you want to see the rays and the normals during testing /* #if (vlength(Norm0)!=0) cylinder { Intersec, Intersec+Norm0, .1 texture { pigment {color red 1} } } cylinder { Loc, Intersec, .02 texture { pigment {color blue 1} } } #end */ //------------------------------------------------------------------------- #if (Dist < DistMin) #declare NormMin = Norm0; #declare DistMin = Dist; #declare IntersecMin = Intersec; #end #end //of for // ======================================================================================== #end //of Orientation macro // ======================================================================================== // ======================================================================================== #macro Urbanism (Surface, Block, Numbers, ScaleFactor, Rot, FloorProb, DomeProb, TowerProb, Verbose) // ======================================================================================== #local Rand = seed (19323); #local Counter = 0; #local RandProb = seed (9673); #fopen Domes "Domes_locs.inc" write // ----------------------------------------------------- //Initializing the block's unions #local Norm = <0, 0, 0>; #local Start = VRand_In_Obj(Block, Rand); #local Pos = trace (Surface, Start+<0, 100, 0>, -y, Norm ); #local HouseBlock = box {-1,1 translate -100*y} #local Single = object {HouseBlock} // ----------------------------------------------------- //incremental houses #while (Counter < Numbers) //The house block starts with larger houses and ends with smaller ones #local Scaling = 1.0; #local Limit = 0.05; #if (Counter < Numbers*0.33) #local Scaling = 1.50; #local Limit = 0.075; #elseif (Counter < Numbers*0.66) #local Scaling = 1.25; #local Limit = 0.062; #end //finding a random location: #local Norm = <0, 0, 0>; #local Start = VRand_In_Obj(Block, Rand); #local Pos = trace (Surface, Start+<0, 100, 0>, -y, Norm ); //searching for the closest Block face (house orientation macro): Orientation (Block, Start) //Determining the street height at the closest block face: #if (DistMin<0.1) #local StreetNorm = <0, 0, 0>; #local StreetHeight = trace (Surface, IntersecMin+<0,100,0>, -y, StreetNorm); #local Pos = ; //cylinder {Start, IntersecMin, 0.011 texture {pigment {color green 1}}} #end //locations already inside a house are skipped. This reduces the number of overlaps. #if (inside (HouseBlock, Pos) | inside (Single, Pos) | DistMin < Limit) //#debug " no location found.\n" #else //searching for the closest Block face (house orientation macro): Orientation (Block, Start) #local Floorer = Prob (FloorProb, RandProb); #local Domer = Prob (DomeProb, RandProb); #local Scale = ; #local Rot = RRand(-Rot, Rot, Rand); //if no upper floor is present, data are written to file. #if (! Floorer) #local House_scale = ; #local House_rot = RRand(-Rot, Rot, Rand); #local Single = difference { union { object {Single} object {House rotate int(RRand(0,4,Rand))*90*y scale House_scale Reorient_Trans(x, ) rotate House_rot*y translate Pos } } object {Terrace scale House_scale Reorient_Trans(x, ) translate 0.001*y rotate House_rot*y translate Pos } } //Upper floor is present. Testing for additional dome and if not, differencing the terrace. #else #local HouseBlock = #if (! Domer) difference { #end union { object {HouseBlock} //this is an iterative object. #if (Domer) #local Dome_scale = ; #local Tower_rot = RRand(-Rot, Rot, Rand); union { object {House rotate int(RRand(0,4,Rand))*90*y scale Dome_scale Reorient_Trans(x, ) } object {Floor rotate int(RRand(0,4,Rand))*90*y scale Dome_scale Reorient_Trans(x, ) translate 0.05*y } rotate Tower_rot*y translate Pos } #if (Dome_scale.x < Dome_scale.z) #local Dome_scale = ; #else #local Dome_scale = ; #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),">, ", "<",str(NormMin.x,3,4),", ",str(NormMin.y,3,4),", ",str(NormMin.z,3,4),">, ", str(Tower_rot,3,4),",\n") //------------------------------------------------------------------------------------------------------- #else union { object {House rotate int(RRand(0,4,Rand))*90*y scale Scale Reorient_Trans(x, ) } object {Floor rotate int(RRand(0,4,Rand))*90*y scale Scale Reorient_Trans(x, ) translate 0.05*y } rotate Rot*y translate Pos } #end //of Domer } //HouseBlock union //without dome, the terrace has to be differenced from the floor. #if (! Domer) object {Terrace scale Scale Reorient_Trans(x, ) rotate Rot*y translate 0.05*y translate Pos } } //closing the HouseBlock difference #end //of ! Domer #end //of ! Floorer #local Counter = Counter + 1; #if (Verbose) #debug concat(" houses: ", str(Counter,4,0),"\n") #end #end //of inside #end //of Counter #fclose Domes // ----------------------------------------------------- #fopen Domes "Domes_locs.inc" read #local HouseBlock = union { object {HouseBlock} #while (defined(Domes)) #read (Domes, Pos, Dome_scale, NormMin, Tower_rot) #local Towerer = Prob (TowerProb, RandProb); #if (Towerer) object {Tower scale Dome_scale Reorient_Trans(x, ) rotate Tower_rot*y translate 0.05*y translate Pos } #else object {Dome translate 0.05*y scale Dome_scale translate Pos } #end #end } // ----------------------------------------------------- union { object {HouseBlock} object {Single} } #debug "Done.\n\n" // ======================================================================================== #end //of macro // ======================================================================================== //calling the macro: object { Urbanism ( Surface, // the surface upon which the houses are to be traced Block, // the object defining the boundaries of the house block 50, // the number of houses 0.2, // the scale factor by which the houses are randomly scaled in x- and z-direction 2, // the maximum random rotation angle around the y-axis (keep low) 0.5, // the probability for a first floor [0-1] 0.2, // the brobability for a dome or a tower [0-1] 0.2, // the probability for a tower instead of a dome [0-1] on // verbose ) pigment {color rgb 1} normal {granite 0.2 scale 0.001} finish { specular 0.02 roughness 0.005 diffuse 0.7 } } //or: #declare MyObject = Urbanism (....) // -----------------------------------------------------