// various geometric transformation macros
// 
#include "transforms.inc"
#include "teartex.inc"
#include "spraydef.inc"

#if (IsLand) // Placement variables
	#declare Land = height_field {
	  png "texland.png"
	  smooth
	  translate <-.5, 0.25, -.5>
	  texture { texLand }
		scale <1e5, 4500, 1e5>
	}
	#declare wtBase = <3500.00, 1e6, 5000.00>;
	#declare ctBase = <3005.00, 1e6, 5000.00>;
	#declare csBase = <4500, 34000,  6500>;
	#declare csBase1 = < 7000, 40000, 18600>;
	#declare skBase = < 7008, 40000, 18570>;
	#declare csNorm = <0,0,0>;
	#declare cSrc = trace(Land, csBase, -y, csNorm)+y*5;
	#declare cSrc1 = trace(Land, csBase1, -y, csNorm)+y*5;
	#declare cTrg = trace(Land, ctBase, -y, csNorm);
	#declare wPos = trace(Land, wtBase, -y, csNorm);
	#declare skPos = trace(Land, skBase, -y, csNorm)+y*.8;
	#if (cSrc.y<20) #declare cSrc = <cSrc.x, 1000, cSrc.z>; #end
	#declare cDir = vnormalize (cTrg-cSrc1);
	#declare cUp = vnormalize ( vcross(x, cDir) );
	#declare cRgt = vcross( cDir, cUp );
	//#debug concat("Intersection found at ",vstr(3,cSrc1,",",0,3)," .\n")

	#macro CamPos(ofs) cRgt*ofs.x + cUp*ofs.y + cDir*ofs.z #end
#end

#declare bSeed = seed(4981);
#macro vMinSwap(i,j) 
	#if(j.x<i.x) #local s = i.x; #local i.x=j.x; #local j.x=s; #end 
	#if(j.y<i.y) #local s = i.y; #local i.y=j.y; #local j.y=s; #end 
	#if(j.z<i.z) #local s = i.z; #local i.z=j.z; #local j.z=s; #end 
#end
#macro vInterp(vn,vx,sd) <vn.x+rand(sd)*(vx.x-vn.x), vn.y+rand(sd)*(vx.y-vn.y), vn.z+rand(sd)*(vx.z-vn.z)> #end

#declare fpnCut = function { pattern { agate agate_turb 0.6 scale 5 } }
#declare fnBall = function { sqrt(x*x+y*y+z*z)-1 }

#macro TestGrid(siz, sep, c0, c1, c2)
	union {
		sphere { 0, siz pigment { rgb c0 } }
		sphere { x*siz*sep, siz pigment { rgb c1 } }
		sphere { z*siz*sep, siz pigment { rgb c2 } }
		translate y*siz
	}
#end

#declare tpSiz = 1000;
#declare tpHgt = 300;

#macro Boulder(szMin, szMax, mCut, tex)
	// Establish size order: Max >= Min >= Cut
	vMinSwap(szMin, szMax)

	// Get actual size and acquire components
	#local szReal = vInterp(szMin,szMax,bSeed);
	#local szShift = vInterp(<0,0,0>,<1e4,1e4,1e4>,bSeed);
	#local sx = szReal.x; #local sy = szReal.y; #local sz = szReal.z;
	#local shx = szShift.x; #local shy = szShift.y; #local shz = szShift.z;
	#local mxRad = max(szReal.x,szReal.y,szReal.z);

	isosurface {
		function { fnBall( x/sx, y/sy, z/sz ) + mCut*fpnCut(x+shx,y+shy,z+shz) }
		contained_by { sphere { 0, mxRad } }
		max_gradient 10
		accuracy 0.01
		translate y*sy
		texture { tex }
	}
#end

#macro fBoulder(szMin, szMax, mCut, pos, tex, strAns)
	// Establish size order: Max >= Min >= Cut
	vMinSwap(szMin, szMax)

	// Get actual size and acquire components
	#local szReal = vInterp(szMin,szMax,bSeed);
	#local szShift = vInterp(<0,0,0>,<1e4,1e4,1e4>,bSeed);
	#local mxRad = max(szReal.x,szReal.y,szReal.z);
	#local bldLoc = pos+y*szReal.y;

	#local strAns = concat( "isosurface {\n  function { fnBall( x/",str(szReal.x,0,5),", y/",
		str(szReal.y,0,5),", z/",str(szReal.z,0,5)," ) + ",str(mCut,0,5),"*fpnCut(x-",
		str(szShift.x,0,5),",y-",str(szShift.y,0,5),",z-",str(szShift.z,0,5),
		") }\n	contained_by { sphere { 0, ",str(mxRad,0,5)," } }\n  max_gradient 10\n  ",
		"accuracy 0.01\n  translate <",vstr(3,bldLoc,", ",0,5),">\n  texture { texBoulder translate <",
		vstr(3,szShift,", ",0,5),"> }\n}\n")
#end

#macro RockField(nm, sd, oFile)
	#fopen pFile oFile write
	#local csNorm = <0,0,0>;
	#local i = 0;
	#declare b1Seed = seed(sd);
	#while (i<800)
		#declare hgt = 4000;
		#while (hgt>2000)
			#local px = (rand(b1Seed)-.5)*50000;
			#local pz = (rand(b1Seed)-.5)*50000;
			#local bldBase = <px, 1e5, pz>;
			#declare bldPos = trace(Land, bldBase, -y, csNorm);
			#declare hgt = bldPos.y;
			//#debug concat("Checking rock #",str(i,0,0)," at <",vstr(3,bldPos,",",0,3),">\n")
		#end
		//#debug concat("Accepted rock #",str(i,0,0)," at <",vstr(3,bldPos,",",0,3),">\n")
		#local bldString = ""
		fBoulder( <75, 50, 75>, <275, 150, 275>, 45, bldPos, texBoulder, bldString )
		#write ( pFile, bldString )
		#local i = i + 1;
	#end
	#fclose pFile
#end

//Volcano(Land, "lava.inc")
//RockField(800,1295,"rocks.inc") 

#declare Boulders = union { #include "rocks.inc" }

#declare TearPool = isosurface {
	function { y-tpHgt+fpnWater(x,0,z) }
	max_gradient 15
	accuracy 0.01
	contained_by { box { <-tpSiz, -tpHgt*.1, -tpSiz>, <tpSiz, tpHgt, tpSiz> } }
	material { texPool }
}

// Volcano
#declare Lava = union { 
	#include "lava.inc"
	texture { texLava }
	interior { intLava }
}

// Smoke
#declare Smoke = isosurface {
	function { x*x + z*z - min(y, 20) + 7*fpnCut(x,y,z) }
	contained_by { box { <-4.5, 0, -4.5>, <4.5, 5e4, 4.5> } }
	max_gradient 23
	accuracy 0.004
  hollow
  pigment { rgbt 1 }
  scale 1000
  interior { intSmoke }
}

// Skulls
#declare Tooth = difference {
	intersection {
		sphere { 0, 1 }
		plane { -z, 0 }
		plane {-x, 0 rotate z* 6 }
		plane { x, 0 rotate z*- 6 }
		plane {-y, 0 rotate x*-45 }
	}
	sphere { 0, 1 scale <1, 0.90, 1> }
	translate y*-.95
	scale <.2, .1, .3>
	rotate x*90
}

#declare Jaw = union {
	object { Tooth translate z*0.3 rotate y*  5 }
	object { Tooth translate z*0.3 rotate y* -5 }
	object { Tooth translate z*0.3 rotate y* 15 }
	object { Tooth translate z*0.3 rotate y*-15 }
	object { Tooth scale <1, 1.4, 1> translate z*0.3 rotate y* 25 }
	object { Tooth scale <1, 1.4, 1> translate z*0.3 rotate y*-25 }
	object { Tooth translate z*0.3 rotate y* 35 }
	object { Tooth translate z*0.3 rotate y*-35 }
	object { Tooth translate z*0.3 rotate y* 45 }
	object { Tooth translate z*0.3 rotate y*-45 }
	scale <1, 0.3, 0.7>
}

#declare SkullBody = blob {
	threshold 0.1
	sphere { < 0.00, 0.50,-0.20>, 0.50, 1 scale <1.5, 1.0, 2.0> }
	sphere { < 0.00, 0.35,-0.20>, 0.40,-3 scale <1.3, 1.2, 2.0> }
	sphere { < 0.00, 0.20,-0.20>, 0.50, 1 scale <1.1, 1.0, 2.0> }
	sphere { < 0.20, 0.40, 0.10>, 0.30, 1 scale <1.0, 1.0, 0.9> }
	sphere { <-0.20, 0.40, 0.10>, 0.30, 1 scale <1.0, 1.0, 0.9> }
	sphere { < 0.00, 0.35,-0.10>, 0.30, 1 scale <1.4, 1.0, 2.0> }
	sphere { < 0.00, 0.20, 0.20>, 0.30, 1 scale <1.7, 1.0, 1.0> }
	sphere { < 0.00, 0.20, 0.10>, 0.30,-2 scale <1.7, 1.5, 1.0> }
	sphere { < 0.15, 0.60, 0.10>, 0.10,-3 scale <1.2, 1.0, 4.0> }
	sphere { < 0.00, 0.40, 0.07>, 0.10,-3 scale <1.0, 1.0, 4.0> }
	sphere { <-0.15, 0.60, 0.10>, 0.10,-3 scale <1.2, 1.0, 4.0> }
	sphere { < 0.00, 0.20, 0.12>, 0.10,-3 scale <3.0, 1.0, 5.0> }
}

#declare Skull = union {
	object { SkullBody }
	object { Jaw rotate x*-20 translate <0.00, 0.20, 0.25> }
	object { Jaw rotate <-20, 0, 180> translate <0.00, 0.20, 0.25> }
	texture { Bone }
	scale 0.5
}

#declare CopyRight = text {
	ttf "cas_antn.ttf" "(C)2002 by David Wallace" 0.1, 0
	scale .3
	Reorient_Trans(x, -cRgt)
	translate cSrc1 + CamPos(<-3, -4.7, 10>)
	texture { txtCaption }
}