/* Spline Tree Include File v1.1 (c) 2000 Andrew Clinton Requires the Pov-Ray 3.1 Superpatch or MegaPov Patch to run. This file WILL NOT work with the official Pov-Ray 3.1 Refer to "readme.txt" for documentation. Version History --------------- 1.1 - 03/26/00 - Removed probability restriction for leaves - Rearanged code so each object receives a custom transformation - Fixed bug where repeated warning messages were generated - Trace speed doubled - Memory usage and parsing time improved - Added example scenes - Changed simplify variable properties - Removed simplify segments variable (now included in simplify array) - Removed branchnoise variable - Removed splinepoints variable - rdeviance now behaves more realistically - Other minor technical improvements 1.0 - 02/15/00 - First version posted --------------- Questions contact: Andrew Clinton clintona@ibm.net http://povplace.addr.com/ */ #declare eggs = 0; #declare statisticsCnt = array[100] #local I=0; #while (I < 100) #declare statisticsCnt[I] = 0; #declare I=I+1; #end //macro rn //Generates a random number using random variable index and range absrange //starting at 0 #macro rn (index,absrange) (rand(rv[index])*absrange) #end //macro rr //Generates a random number using random variable index and range absrange //centered on 0 #macro rr (index,absrange) ((rand(rv[index])-0.5)*absrange) #end //Macro point_to - returns the rotation to realign from +y to another axis. //Based on a macro by David Fontaine #macro point_to(p) #if (p.x=0 & p.y=0 & p.z=0) #local RotX=0; #else #local RotX=degrees(atan2(sqrt(pow(p.x,2)+pow(p.z,2)),p.y)); #end #if (p.x=0 & p.z=0) #local RotY=0; #else #local RotY=degrees(atan2(p.x,p.z)); #end #end //Macro splinetree #macro splinetree (level, leadslope, currentpos, currentrot) //Give some feedback #declare statisticsCnt[level] = statisticsCnt[level] + 1; #ifdef(feedback) #switch (level) #case (0) #debug "\nParsing Tree..." #break; #case (1) #debug "\n..Level 1" #break; #case (2) #debug "\n....Level 2" #break; #end #end //Generate a spline to be used for the branch #local actualdeviance = splinedeviance[level]*branchlength[level]; #local branchspline = spline { cubic_spline -0.5, <0, -0.5*branchlength[level], tan(radians(leadslope))*0.5> 0, <0, 0, 0> 0.5, 1, 1.5, } //Create the branch using the above spline #if (!simplify[level]) blob { threshold 0.6 #local splineposition = 0; #while (splineposition <= 1) #local instwidth = branchwidth[level]-((branchwidth[level]-branchwidth[level+1])*splineposition); #local scaleval = ; #local rotateval = point_to(vrotate(vnormalize(branchspline(splineposition+0.001)-branchspline(splineposition)),currentrot)); #local translateval = vrotate(branchspline(splineposition),currentrot)+currentpos; sphere { 0,1,1 scale scaleval rotate rotateval translate translateval } #local splineposition = splineposition + ((branchquality[level]/1.5)*instwidth)/branchlength[level]; #end clipped_by { plane { -y,branchwidth[level] rotate currentrot translate currentpos } } texture { branchtexture rotate currentrot } } #else union { #local splineposition = 0; #local increment = 1/simplify[level]; #while (splineposition < 0.999) #local instwidth = branchwidth[level]-((branchwidth[level]-branchwidth[level+1])*splineposition); #local instwidth2 = branchwidth[level]-((branchwidth[level]-branchwidth[level+1])*(splineposition+increment)); sphere { branchspline(splineposition), instwidth*0.6 } cone { branchspline(splineposition), instwidth*0.6 branchspline(splineposition+increment), instwidth2*0.6 } #local splineposition = splineposition + increment; #end texture { branchtexture } rotate currentrot translate currentpos } #end //Here we go... Down a recursion level... #local currrec = recursionmax - rn(0,1)*branchlengthturb*recursionmax; #if (level < currrec) //If not a terminal branch, split the branch. //Seamlessly continue the parent branch #local newpos = vrotate(branchspline(1),currentrot)+currentpos; #local newrot = point_to(vrotate(vnormalize(branchspline(1)-branchspline(0.999)),currentrot)); splinetree(level+1,0,newpos,newrot) //Divide according the the divisions variable #local division = 1; #local staticrand = rn(0,360); #while (division < divisions[level]) #local xrotate = (rdeviance[level]/2)+(rn(0,(rdeviance[level]/2))); #local yrotate = ((division*360)/divisions[level])+rr(0,(360/(divisions[level]*3))+staticrand); #local newpos = vrotate((branchspline(1-(tdeviance[level]*rand(rv[0])))),currentrot)+currentpos; #local newrot = point_to(vrotate(vrotate(<0,1,0>,),currentrot)); splinetree(level+1,xrotate,newpos,newrot) #local division = division + 1; #end #while(rand(rv[0]),),currentrot)); splinetree(recursionmax,xrotate,newpos,newrot) #end #else //If we are on a terminal branch, create leaves. #ifdef(leafarray) #ifndef(totalprob) #local counter = 0; #local totalprob = 0; #while (counter < dimension_size(leafprob,1)) #declare totalprob = totalprob + leafprob[counter]; #local counter = counter + 1; #end #end #local randomnumber = rand(rv[1]); #local currentprob = 0; #local intcount = 0; #while(currentprob < totalprob) #if((currentprob<=randomnumber)&(randomnumber<=(currentprob+leafprob[intcount]))) #local scaleval = leafscale+rr(1,leafscale*0.3); #local rotateval = point_to(vrotate(vrotate(<0,1,0>,),currentrot)); #local translateval = vrotate(branchspline(0.98),currentrot)+currentpos; object { leafarray[intcount] scale scaleval rotate rotateval * leafturb[intcount] #if (!leafturb[intcount]) #declare eggs = eggs+1; #debug concat("\nstraight Object No.",str(eggs,0,0)) rotate 90*x #end translate translateval } #end #local currentprob = currentprob + leafprob[intcount]; #local intcount = intcount + 1; #end //while loop #end //ifdef leafarray #end //End #if (down a level) #end #macro Statistic () #debug "\n\nTrees containing\n" #local I=0; #while (I <= recursionmax) #debug concat("Level ",str(I,0,0)," Branches: ",str(statisticsCnt[I],0,0),"\n") #declare I=I+1; #end #debug "\n" #end // End of file