#version unofficial Megapov 0.5; #include "colors.inc" //#include "woods.inc" #include "macros2.inc" camera { location <2,3,-5>*4 look_at <0,0,0> } light_source { <150,500,-300> color White } // Settings #declare Max = 500; // Maximum number of cubes #declare Bound1 = <-8,-8,-8>; // Bounding box coordinates #declare Bound2 = <8,8,8>; // Note this only bounds the center of the cubes, the edges can still stick out #declare MinRad = .2; // Minimum box size (measured from center to face) #declare MaxRad = 1; // Maximum box size #declare FailThreshold=30; // If this many cubes are generated consecutively that intersect, the bounding region is assumed to be full and the generator exits #declare Rnd = seed(6889); // Duh #declare Location = array[Max] // Stores coords of successful cubes #declare Rotation = array[Max] // Stores rotation of successful cubes #declare Radius = array[Max] // Stores size of successful cubes #declare ctr=0;#while(ctr; #declare Rotation[ctr]=<0,0,0>; #declare Radius[ctr]=0; #declare ctr=ctr+1;#end #declare Corners = array[Max][8] // Stores points at corners of cubes to avoid redundant calculations #declare ctr=0;#while(ctr; // Location #local Rad = rand(Rnd)*RadRange+MinRad; // Size #local Rot = *360; // Rotation // Find corners of cube #local Corner1 = array[8]{<-1,-1,-1>,<-1,-1,1>,<-1,1,-1>,<-1,1,1>,<1,-1,-1>,<1,-1,1>,<1,1,-1>,<1,1,1>} #local ctr=0; #while (ctr<8) #local Corner1[ctr] = vrotate(Corner1[ctr],Rot)*Rad+Loc; // Rotate corner points and translate into place #local Corners[tot][ctr] = Corner1[ctr]; // Stores corner points #local ctr=ctr+1; #end #declare Cube1 = box { -Rad,Rad rotate Rot translate Loc } // Cube to be tested // Intersection testing #local Int = 0; // Stores result of intersection test #local Comp = 0; #while (Comp < num) #if ( vlength(Loc-Location[Comp]) < (Rad+Radius[Comp])*Root3 ) // Test only if cubes are close enough to intersect #declare Cube2 = box { -Radius[Comp],Radius[Comp] rotate Rotation[Comp] translate Location[Comp] } // Cube to be tested against #local p1 = 0; #while (p1 < 7) #local p2 = p1+1; #while (p2 < 8) #local IntVec = <0,0,0>; #local bla=trace ( Cube2,Corner1[p1],Corner1[p2],IntVec ); // Check edges of cube1 for intersection with cube2 #if (IntVec.x != 0 | IntVec.y != 0 | IntVec.z != 0) #local Int=1; #end #local bla=trace ( Cube1,Corners[Comp][p1],Corners[Comp][p2],IntVec ); // Check edges of cube2 for intersection with cube1 #if (IntVec.x != 0 | IntVec.y != 0 | IntVec.z != 0) #local Int=1; #end #local p2=p2+1+Int*10; // If intersection found exit loop #end #local p1=p1+1+Int*10; // If intersection found exit loop #end #end #local Comp=Comp+1+Int*num; // If intersection found exit loop #end // Check and store data #if (Int=0) #declare Location[num]=Loc; #declare Rotation[num]=Rot; #declare Radius[num]=Rad; object { Cube1 pigment { color RGB( < rand(Rnd)*150+120, sin(rand(Rnd)*pi-pi/2)*.25+.5, sqrt(1-(rand(Rnd)-1)^2)*.5+.5 > ) } finish { specular 1 roughness .006 } normal { average normal_map { [rand(Rnd) wrinkles .5 scale .1] [rand(Rnd) crackle .9 scale .3 slope_map { [0.0,<-.5,1>][0.2,<.5,.4>][0.5 <.4,-.1>][1.0 <.4,0>] }] [rand(Rnd) bumps .6 scale .05] } } } #declare num=num+1; #declare tot=tot+1; #declare fails=0; #else #declare fails=fails+1; #end #render concat(str(tot,4,0),"/",str(Max,4,0)," ",str(fails,2,0),"/",str(FailThreshold,2,0),"\r") #if (fails>FailThreshold) #declare num=Max; // If threshold reached exit loop #end #end #render "\n" } /*union { #local ctr1=0; #while (ctr1