// Random Skyline Generator // Name: skyline.inc // Author: Bram Lambrecht // // Directions: To use this random skyline generator, // add the following lines to a POV file: // // #declare space_between_buildings = 40; // #declare num_buildings = 20; // #declare skyline_seed = 18; // #include "skyline.inc" // // This will create an object called "skyline" which // is a row of between 15 and 20 buildings, spaced an // average of 40 units apart. (To change these numbers, // just change the values in the "#declare" lines above) // You can then use the skyline row by including a line // like this in your POV file: // // object { skyline } // // You can add any transformations (scale, rotate, // translate,etc.) to that line. If you want to create // a whole city, just make multiple calls to "skyline.inc" // with different "skyline_seed"s, and then translate each // "skyline" object a different amount along the x-axis. // Enjoy! // // Note: if you display any images publicly in which you // use this include file, please include the // appropriate credit. Thanks! // #ifndef (skyline_seed) #declare skyline_seed = 1; #end #ifndef (space_between_buildings) #declare space_between_buildings = 0; #end #ifndef (num_buildings) #declare num_buildings = 20; #end #macro building1 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building numlevels, // number of staggered levels lchange // fraction of total width to change at each level ) union { #local level_height = bheight/(numlevels+2); box { <-bwidth/2, 0, -bdepth/2>, } #local level = 1; #while ( level < numlevels ) box { <-(bwidth - (level*lchange*bwidth))/2, -(level_height*3+(level-1)*level_height), -(bdepth - (level*lchange*bdepth))/2>, <(bwidth - (level*lchange*bwidth))/2, -(level_height*3+(level)*level_height), (bdepth - (level*lchange*bdepth))/2> } #local level = level + 1; #end } #end #macro building2 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building numbars, // number of vertical cutouts bardepth, // depth of cutouts barwidth, // width of cutouts bartop, // distance from top of cutout to top of building ) difference { box { <-bwidth/2, 0, 0>, } union { #local bar_spacing = (bdepth - numbars*barwidth)/(numbars+1); #local counter = 0; #while ( counter < numbars ) #local counter = counter + 1; box { , } #end } translate z*-bdepth/2 } #end #macro building3 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building numbars, // number of horizontal cutouts bardepth, // depth of cutouts barheight, // height of cutouts barup, // distance up from bottom of building where cutouts begin ) difference { box { <-bwidth/2, 0, -bdepth/2>, } union { #local bar_spacing = (bheight - barup - numbars*barheight)/numbars; #local counter = 0; #while ( counter < numbars ) box { , } #local counter = counter + 1; #end } } #end #macro building4 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building numpeaks, peakheight, ) #local counter=0; prism { linear_sweep linear_spline -bwidth/2, bwidth/2, 3+numpeaks*2, <0,0>, #while (counter < numpeaks) , #local counter = counter+1; , #end ,<0,0> rotate x*90 rotate y*-90 translate z*-bdepth/2 } #end #macro building5 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building numstacks, stackradius, stacktoprad, stackheight, ) union { box { <-bwidth/2, 0, 0>, } #local sspacing = (bdepth - numstacks*2*stackradius)/(numstacks+1); #local counter = 0; #while ( counter < numstacks ) #local counter = counter + 1; cone { <0, -bheight, counter*(sspacing+2*stackradius)-stackradius>, stackradius <0, -stackheight, counter*(sspacing+2*stackradius)-stackradius>, stacktoprad } #end translate z*-bdepth/2 } #end #macro building6 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building sbwidth, domerad, ) union { box { <-bwidth/2, 0, -bdepth/2>, } box { <-bwidth/2-sbwidth/2, 0, -bdepth/2-sbwidth/2>, <-bwidth/2+sbwidth/2, -bheight-sbwidth/4, -bdepth/2+sbwidth/2> } box { , } box { <-bwidth/2-sbwidth/2, 0, bdepth/2-sbwidth/2>, <-bwidth/2+sbwidth/2, -bheight-sbwidth/4, bdepth/2+sbwidth/2> } box { , } sphere { <0, 0, 0>, domerad scale <1,.5,1> translate y*-bheight} } #end #macro building7 ( bheight, // y-dimension of building bwidth, // x-dimension of building bdepth, // z-dimension of building centerwidth, centerextr, cutoff, ) prism { conic_sweep linear_spline cutoff, 1, 21, // the number of points making up the shape... <-bwidth/2,-bdepth/2>,<-bwidth/2,-centerwidth/2>,<-(bwidth/2+centerextr), -centerwidth/2>, <-(bwidth/2+centerextr), centerwidth/2>,<-bwidth/2,centerwidth/2>, <-bwidth/2,bdepth/2>,<-centerwidth/2,bdepth/2>,<-centerwidth/2,bdepth/2+centerextr>, ,, ,,, ,, ,,, <-centerwidth/2, -(bdepth/2+centerextr)>,<-centerwidth/2, -bdepth/2>,<-bwidth/2,-bdepth/2> translate y*-1 scale <1, bheight, 1> } #end #declare skyline = union { #local totalbuildings = int(((1.5+rand(seed(skyline_seed))*.5)/2) * num_buildings); #local totalwidth=0; #local i = 1; #while ( i <= totalbuildings ) #local which_building = rand(seed(i*12345*skyline_seed)); #local bheight = (1+rand(seed(i*23456*skyline_seed))*.5)/1.5; #local bwidth = (1+rand(seed(i*34567*skyline_seed))*.5)/1.5; #local bdepth = (1+rand(seed(i*45678*skyline_seed))*.5)/1.5; #local R1 = rand(seed(i*56789*skyline_seed)); #local R2 = rand(seed(i*67891*skyline_seed)); #local R3 = rand(seed(i*78912*skyline_seed)); #local R4 = rand(seed(i*89123*skyline_seed)); #local rcolor1 = rand(seed(i*91234*skyline_seed)); #local rcolor2 = rand(seed(i*98765*skyline_seed)); object { #switch ( rand(seed(which_building*i)) ) #range (0,.1) building1 ( bheight*120, bwidth*40, #declare bspacing = bdepth*40; bspacing, int(R1*4)+1, (.5+R2*.5)/2*.4 ) #break #range (.1,.3) building2 ( bheight*110, bwidth*40, #declare bspacing = bdepth*60; bspacing, int((1+R1*.5)/1.5*10), R2*5, R3*5, R4*30-10, ) #break #range (.3,.45) building3 ( bheight*60, bwidth*50, #declare bspacing = bdepth*80; bspacing, int((1+R1*.5)/1.5*8), R2*5, R3*8, R4*30-10, ) #break #range (.45,.55) building4 ( bheight*50, bwidth*45, #declare bspacing = bdepth*60; bspacing, int((.5+R1*.5)/2*8), (.5+R2*.5)*15, ) #break #range (.55,.65) building5 ( bheight*35, bwidth*30, #declare bspacing = bdepth*45; bspacing, int(R1*4)+1, (.5+R2*.5)*.5, (.5+R3*.5)*.4, (.5+R4*.5)*50, ) #break #range (.65,.78) union { object { building4 ( bheight*50, bwidth*45, #declare bspacing1 = bdepth*60; bspacing1, int((.5+R1*.5)/2*8), (.5+R2*.5)*15, ) translate z*bspacing1/2 } object { building5 ( bheight*35, #declare bspacing2 = bdepth*30; bspacing2, bdepth*45, int(R1*5)+1, (1.5+R2*.5)/2*5, (1.5+R3*.5)/2*4, (1.5+R4*.5)/2*80, ) rotate y*90 translate z*-bspacing2/2 } #declare bspacing = bspacing1 + bspacing2; translate z*(-bspacing/2+bspacing2) } #break #range (.78,.85) building6 ( bheight*50, bwidth*45, #declare bspacing = bdepth*50; bspacing, R1*10, (1.5+R2*.5)/2*bwidth*45/2, ) #break #else building7 ( bheight*150, bwidth*40, #declare bspacing = bdepth*40; bspacing, R1*20, R2*8, R3*.6, ) #end texture { pigment { color rgb <(1+rcolor1*.5)/1.5*.7,(1+rcolor1*.5)/1.5*.7,(1.5+rcolor2*.5)/2> } } translate z*(bspacing/2+totalwidth+(1+R3*.5)/3*space_between_buildings) translate x*(R4*20-10) } #local totalwidth=totalwidth+bspacing+(1+R3*.5)/3*space_between_buildings; #local i = i + 1; #end translate z*-totalwidth/2 } // EOF