// Persistence of Vision Ray Tracer Scene Description File // File: grasspatch.inc // Vers: 1.0 of grasspatch.inc for POV-Ray 3.1 // Desc: Draws a patch of grass based on a few simple variables // Include at the beginning of the file // Date: 01/18/2000 // Auth: Josh English #declare HelloGrassPatch = true; #ifndef(HelloBezier) #include "bezier.inc" #end #macro DrawBlade(s1,s2,s3) ConnectSmooth(s1,s2) ConnectSmooth(s1,s3) #end #macro RangedRand(mn,mx,sv) mn + rand(sv)*(mx-mn) #end #declare Blade_Tex = texture { pigment { rgb <0,0.3,0> } finish { phong 0.25 ambient 0.2 } } #declare Blade_Height_Minimum = 1.75; #declare Blade_Height_Maximum = 3; // New on 1-22 #declare Blade_Detail = 10; #declare Max_Blade_Angle = 45; #declare Min_Blade_Angle = 10; // until here #declare someseed = seed(2345); #declare xseed = seed(42); #declare zseed = seed(369); #declare Blade_Density = 2; // per unit #declare Patch_Rotation = 0; #declare Patch_Translation = <0,0,0>; #declare Patch_Shape = 1; // 0 for circle, 1 for square, 2 for polygon // used for PatchShape 0 (Circle) #declare Clump_Radius_Minimum = 0; #declare Clump_Radius_Maximum = 2; // used for PatchShape 1 (Square) #declare Patch_X_Minimum = -5; #declare Patch_X_Maximum = 5; #declare Patch_Z_Minimum = -5; #declare Patch_Z_Maximum = 5; // used for PatchShape 2 (Polygon) #declare Patch_Sides = 3; #declare Poly_Radius_Range = 0.333; #declare RadialOffset = 0; // used for PatchShape 3 (Curve) #declare Patch_Path = array[4] { <-3,0,0>, <-1,0,5>, <1,0,-5> <3,0,0> } #declare Path_Density = 6; #declare Path_Points = 20; #declare PlotPoints = false; #declare Spread_Correction = 1; #ifndef(NumberOfBlades) #declare NumberOfBlades = 100; #end // New on 3-2-00 // This should allow us to make the blades further away less // detailed, thus saving parse and render times #declare Blade_Scale = 1; #declare Blade_Width = 0.075; #declare Use_Blade_Distance = false; #declare Camera_Position = <0,0,-4>; #declare Max_Blade_Detail = 20; #declare Min_Blade_Detail = 5; #declare Max_Detail_Distance = 1; #declare Min_Detail_Distance = 10; #macro FillOutBlade(A) #local cpnt = vrotate(,<0,45,0>); #local ccpnt = vrotate(,<0,-45,0>); #declare ClockwiseSpline = array[4] { A[0] + cpnt, A[1] + cpnt, A[2] + <-0.1,0,-.1>, A[3] + <0,0,-0.01> } #declare CounterSpline = array[4] { A[0] + ccpnt, A[1] + ccpnt, A[2] + <-0.1,0,0.1>, A[3] + <0,0,0.01> } #end // From MyMaxs #macro Return(sd,ed,sr,er,rd,dg) #local a = (rd - sd)/(ed-sd); #local a = pow(a,dg); #local b = sr + a*(er-sr); max(min(b,er),sr) #end // the big macro #macro PlantPatch() #declare Temp_Number = NumberofPoints; #declare NumberofPoints = Blade_Detail; #declare Blade_Count = 0; #declare Clump_Radius_Range = Clump_Radius_Maximum - Clump_Radius_Minimum; #declare Blade_X_Range = Patch_X_Maximum - Patch_X_Minimum; #declare Blade_Z_Range = Patch_Z_Maximum - Patch_Z_Minimum; #declare Blade_Distance = 1/Blade_Density; #declare X_Start = Patch_X_Minimum + 0.5*Blade_Distance; #declare Z_Start = Patch_Z_Minimum + 0.5*Blade_Distance; // Find how many blades to use #switch(Patch_Shape) #case(1) // Square #declare NumberOfBlades = Blade_Density * Blade_X_Range * Blade_Density * Blade_Z_Range; #break #case(3) // Curve #declare NumberOfBlades = Path_Points * Path_Density; #break #else #declare NumberOfBlades = pow(Blade_Density,2) * int(pi*(pow(Clump_Radius_Maximum,2) - pow(Clump_Radius_Minimum,2))); #end #declare X_Count = X_Start; #declare Z_Count = Z_Start; #declare thisStop = 0; #declare thisCycle = 1; #declare BezTex = Blade_Tex // #debug concat("\nX_range is " + str(Blade_X_Range,3,3)) // #debug concat("\nZ_range is " + str(Blade_Z_Range,3,3)) #debug concat("\nTotal number of dots is " , str(NumberOfBlades,3,0)) #while (Blade_Count < NumberOfBlades) // Find the placement of the blade #switch(Patch_Shape) #case (1) // Square shape #declare px = X_Count + rand(xseed)*2*Blade_Distance - Blade_Distance; #declare pz = Z_Count + rand(zseed)*2*Blade_Distance - Blade_Distance; #if ( px > Patch_X_Maximum ) #declare px = Patch_X_Maximum; #end #if ( px < Patch_X_Minimum ) #declare px = Patch_X_Minimum; #end #if ( pz > Patch_Z_Maximum ) #declare pz = Patch_Z_Maximum; #end #if ( pz < Patch_Z_Minimum ) #declare pz = Patch_Z_Minimum; #end #declare X_Count = X_Count + Blade_Distance; #break #case(2) // Polygon // Step one find a random angle #declare thisAngle = rand(someseed) *360; // Step two find the maximum radius #declare tempRadRAnge = Poly_Radius_Range*Clump_Radius_Maximum; #declare thisMaxRadius = Clump_Radius_Maximum - abs(sin(thisAngle/360*pi*Patch_Sides))*tempRadRAnge; // Step three find a random radius #declare thisRadius = pow(rand(someseed),Spread_Correction)*thisMaxRadius; #declare thisPoint = vrotate(,<0,(thisAngle+RadialOffset),0>); #declare px = thisPoint.x; #declare pz = thisPoint.z; #break #case(3) //Curve #declare thisCenter = ReturnPosition(Patch_Path,thisStop); #declare thisRadius = pow(rand(someseed),Spread_Correction); #declare thisPoint = ; #declare thisPoint = vrotate(thisPoint,<0,rand(someseed)*360,0>); #declare thisPoint = thisPoint + thisCenter; #declare px = thisPoint.x; #declare pz = thisPoint.z; #declare thisCycle = thisCycle + 1; #break #else // circular #declare subr = pow(rand(someseed),Spread_Correction); #declare subr = Clump_Radius_Minimum + subr*Clump_Radius_Range; #declare thispoint = ; #declare thispoint = vrotate(thispoint,<0,rand(someseed)*360,0>); #declare px = thispoint.x; #declare pz = thispoint.z; #end // Create the Blade #local h4 = RangedRand(Blade_Height_Minimum,Blade_Height_Maximum,someseed); #local r4 = RangedRand(tan(radians(Min_Blade_Angle))*h4,tan(radians(Max_Blade_Angle))*h4,someseed); #local curve = RangedRand(0.667,1.333,someseed); #declare CentralSpline = array[4] { <0,0,0> <0,h4/3,0> <0,curve*h4,0> } FillOutBlade(CentralSpline) #if (PlotPoints) sphere { 0.25 texture {BezTex} scale Blade_Scale translate Patch_Translation} #else // calculate detail (if necessary) #if (Use_Blade_Distance) #local Distance = vlength((+Patch_Translation)-Camera_Position); #declare NumberofPoints = Return(Max_Detail_Distance,Min_Detail_Distance,Max_Blade_Detail,Min_Blade_Detail,Distance,1); // #degub concat("\nDistance is " + str(Distance,3,3)) // #debug concat(" Number of Points is " + str(NumberofPoints,3,3)) #end union { DrawBlade(CentralSpline,ClockwiseSpline,CounterSpline) rotate rand(someseed)*360*y scale Blade_Scale translate+Patch_Translation } #end // Reset X_Count and Z_Count if necessary #if (X_Count > Patch_X_Maximum) #declare Z_Count = Z_Count + Blade_Distance; #declare X_Count = X_Start; #end // Reset thisStop and thisCycle if necessary #if ( thisCycle > Path_Density ) #declare thisStop = thisStop + (1/Path_Points); #declare thisCycle = 1; #end #declare Blade_Count = Blade_Count + 1; #end #declare NumberofPoints = Temp_Number; #end