// XMAS trio
// inspired by the in-scene soundtrack band of "gegen den strom"
// 12/2018 POVaddict

// set to 1 for text in glass balls
#declare WITH_TEXT = 0;

camera {
	location <0, 4.8, -60>
	direction 5*z
	look_at <0, 2.4, 0>
}

light_source {
	<5, 10, -20> color rgb 1
	area_light 10*x, 10*y, 5, 5
	jitter adaptive 1
}

light_source {
	<-15, 8, -3> color rgb .8
	area_light 10*x, 10*y, 5, 5
	jitter adaptive 1
}

// snowman body
#declare SBody = union {
	sphere { 0, 1 translate 1*y }
	sphere { 0, .7 translate 2.5*y }
	sphere { 0, .5 translate 3.5*y }
}
// snowman arm
#declare SArm = union {
	sphere { 0, .3 }
	sphere { 0, .2 translate <-.3, -.3, -.1> }
	sphere { 0, .18 translate <-.5, -.5, -.3> }
}
// snowman mouth
#declare SMouth = difference {
	cylinder { -.05*z, .05*z, .3 }
	cylinder { -.07*z, .07*z, .32 translate .1*y }
	scale <.8, .6, 1>
}
// snowman hat
#declare SHat = union {
	cylinder { 0*y, .7*y, .35 }
	cylinder { -.02*y, .02*y, .6 }
	translate -.35*y
}

// whole snowman
#macro Snowman(LRot, RRot)
union {
	union {
		// body
		object {
			SBody
		}
		// right arm
		object {
			SArm
			rotate RRot*x
			translate <-.7, 2.6, 0>
		}
		// left arm
		object {
			SArm
			rotate LRot*x
			scale <-1, 1, 1>
			translate <.7, 2.6, 0>
		}
		pigment { rgb 1 }
		normal { crackle .1 scale .1 }
	}
	// eyes
	sphere { 0, .07 pigment { rgb 0 } translate <-.2, 3.7, -.4> }
	sphere { 0, .07 pigment { rgb 0 } translate <.2, 3.7, -.4> }
	// nose
	cone {
		0, .07, -.5*z, 0
		pigment { rgb<1, .7, 0> }
		finish { ambient .4 }
		translate <0, 3.6, -.45>
	}
	// mouth
	object { SMouth pigment { rgb 0 } translate <0, 3.42, -.385> }
	// hat
	object {
		SHat
		pigment { rgb .2 }
		finish { phong .7 }
		rotate <-2, 10, -15>
		translate <.15, 4.25, 0>
	}
}
#end

// accordion keys
#declare A_Keys = union {
#declare C = 0;
#while (C < 15)
	// white key
	box {
		<-1, .02, -.4>, <1, .38, 0>
		translate .4*(15-C)*y
		pigment { rgb 1 }
		finish { phong .7 }
	}
	#if ((mod(C, 7) = 1) + (mod(C, 7) = 2) + (mod(C, 7) = 4) + (mod(C, 7) = 5) + (mod(C, 7) = 6))
	// black key
	box {
		<-.4, .3, -.6>, <1, .5, 0>
		translate .4*(15-C)*y
		pigment { rgb 0 }
		finish { phong .7 }
	}
	#end
	#declare C = C + 1;
#end
}

// accordion body (left part)
#declare A_Body_Left = union {
	box { <-1.3, .2, -.1>, <1.3, 6.6, .5> }
	box {
		<-.4, .2, -4>, <.4, 6.6, 0>
		rotate -10*y
		translate 1.6*x
	}
	box {
		<-.4, .2, -4>, <.4, 6.6, 0>
		translate 2.2*x
	}
	pigment {
		agate
		color_map {
			[0 color rgb<.4, .05, .01>]
			[1 color rgb<.7, .05, .1>]
		}
	}
}

// bellow segment
#declare B_Segment = union {
	difference {
		box { <-.2, .2, -4>, <.2, 6.6, 0> }
		plane { x, 0 rotate -30*z translate <-.15, 6, 0 > }
		plane { x, 0 rotate 30*z translate <-.15, 1, 0 > }
		plane { -x, 0 rotate 30*z translate <.15, 6, 0 > }
		plane { -x, 0 rotate -30*z translate <.15, 1, 0 > }
		plane { x, 0 rotate -30*y translate <-.15, 0, -3.5> }
		plane { x, 0 rotate 30*y translate <-.15, 0, 0> }
		plane { -x, 0 rotate 30*y translate <.15, 0, -3.5> }
		plane { -x, 0 rotate -30*y translate <.15, 0, 0> }
		pigment { rgb .75 }
	}
	#local Low = .65;
	#local High = 6.35;
	#local Near = -3.8;
	#local Far = .1;
	#local Rad = .06;
	union {
		cylinder { <-.2, Low, Far>, <-.2, High, Far>, Rad }
		cylinder { <-.2, Low, Near>, <-.2, High, Near>, Rad }
		cylinder { <-.2, Low, Far>, <-.2, Low, Near>, Rad }
		cylinder { <-.2, High, Far>, <-.2, High, Near>, Rad }
		sphere { <-.2, High, Far>, Rad }
		sphere { <-.2, Low, Far>, Rad }
		sphere { <-.2, High, Near>, Rad }
		sphere { <-.2, Low, Near>, Rad }
		translate .2*x
		pigment { rgb .2 }
		finish { phong .75 metallic reflection .6 }
	}
}

// accordion body (right part)
#declare A_Body_Right = intersection {
	box { <0, .2, -4>, <1.7, 6.6, 0> }
	plane { -z, 0 rotate -20*y translate -3.9*z }
	pigment {
		agate
		color_map {
			[0 color rgb<.4, .05, .01>]
			[1 color rgb<.7, .05, .1>]
		}
	}
}

// accordion bellow
#declare A_Bellow = union {
	#declare C = 0;
	#while (C < 20)
		object {
			B_Segment
			translate 5*y
			rotate -1.8*C*z
			translate -5*y
			translate .02*C*x
		}
		#declare C = C + 1;
	#end
}

// whole accordion
#declare Accordion = union {
	object { A_Keys }
	object { A_Body_Left }
	object { A_Bellow translate 2.6*x }
	object { A_Body_Right rotate -36*z translate <5.8, -1, 0> }
}

// metal part
#declare MetalPart = union {
	sphere { -.25*y, .05 }
	cylinder { -.25*y, .25*y, .05 }
	sphere { .25*y, .05 }
}

// drum
#declare Drum = union {
	union {
		disc { 0, y, 2 translate .1*y }
		disc { 0, y, 2 translate 1.7*y }
		pigment { rgb 1 }
		finish { phong .75 reflection .2 }
	}
	difference {
		cylinder { 0*y, 1.8*y, 2.02 }
		cylinder { -.1*y, 1.9*y, 2 }
		pigment {
			wood
			turbulence .7
			scale <1, .2, 1>
			color_map {
				[0 rgb<.6, .1, .01>]
				[1 rgb<.7, .3, .1>]
			}
		}
	}
	union {
		#declare C = 0;
		#while (C < 10)
			object {
				MetalPart
				translate <2, .25, 0>
				rotate 36*C*y
			}
			object {
				MetalPart
				translate <2, 1.55, 0>
				rotate 36*C*y
			}
			#declare C = C + 1;
		#end
		pigment { rgb 1 }
		finish { phong .7 metallic reflection .9 }
	}
}

// timpani
#declare Timpani = union {
	object { Drum scale .75 }
	// timpani stand
	union {
		sphere { -2*y, .07 translate -1.55*z }
		cylinder { -2*y, 0*y, .07 translate -1.55*z }
		sphere { 0*y, .07 translate -1.55*z }
		sphere { -2*y, .07 translate 1.55*z }
		cylinder { -2*y, 0*y, .07 translate 1.55*z }
		sphere { 0*y, .07 translate 1.55*z }
		rotate 75*z
		translate .9*y
		pigment { rgb .5 }
		finish { phong .7 metallic reflection .7 }
	}
}

// torus part
#macro TPart(ROut, RIn, Ang)
intersection {
	torus { ROut, RIn rotate 90*x }
	intersection {
		plane { x, 0 }
		plane { -x, 0 rotate Ang*z }
	}
}
#end

// lower tuba part
#declare LowerTuba = union {
	torus { 2, .4 rotate 90*x }

	cylinder { <-1.4, -.8, -.5>, <1.6, -.8, -.5>, .2 }
	sphere { <1.6, -.8, -.5>, .2 }

	cylinder { <-1.4, -1.3, -.5>, <1.4, -1.3, -.5>, .2 }
	sphere { <1.4, -1.3, -.5>, .2 }
	
	intersection {
		torus { .25, .2 rotate 90*x }
		plane { x, 0 }
		translate <-1.4, -1.05, -.5>
	}
}

// upper tuba part
#declare UpperTuba = union {
	torus {
		2, 1.5 rotate 90*x
		clipped_by { cylinder { -3*z, 0*z, 2 } }
	}
	torus { 2, .02 rotate 90*x translate -1.5*z }
	cylinder { 0*z, .5*z, .5 }
	object { TPart(1, .5, 120) rotate 90*y translate <0, -1, .5> }
}

// tuba
#declare Tuba = union {
	object { LowerTuba translate 2*y }
	object { UpperTuba translate <0, 5.5, -1> rotate -20*z }
	pigment { rgb<1, .9, .4> }
	finish { phong .75 metallic reflection .7 }
	normal { bozo .01 scale .05 }
}

// letter in glass ball
#macro GlassLetter(Text, Adj)
union {
	#if (WITH_TEXT = 1)
	text {
		ttf "cyrvetic.ttf", Text, 0, 0
		translate <Adj, -.4, 0>
		pigment { rgb <1, .6, .1> }
		finish { ambient .4 }
	}
	#end
	difference {
		sphere { 0, .9 }
		sphere { 0, .899 }
		pigment { rgbf <.9, .9, 1, 1> }
		finish { phong .5 reflection .4 }
	}
}
#end

// ===================================================================

// accordion player
object {
	Snowman(0, 45)
	rotate -20*y
	translate -6*x
}
object {
	Accordion
	rotate <0, 0, 15>
	rotate -20*y
	scale .17
	translate <-6.3, 1.6, -1>
}

// drummer
object {
	Snowman(0, 75)
}
object {
	Timpani
	rotate -75*z
	rotate 15*y
	translate <-2.8, 1.8, 0>
}
object {
	Drum
	scale .4
	rotate 90*x
	rotate -15*y
	translate <.5, .8, -2>
}
object {
	Drum
	scale .4
	rotate 90*x
	rotate -70*y
	rotate -2*z
	translate <2.4, .8, -.5>
}

// tuba player
object {
	Snowman(45, 0)
	rotate 20*y
	translate 5*x
}
object {
	Tuba
	scale .6
	rotate 20*y
	rotate 30*x
	rotate -20*z
	translate <4.5, 1, -1>
}

// merry christmas
union {
	object { GlassLetter("M", -.4) scale .7 translate -2*x }
	object { GlassLetter("E", -.3) scale .7 translate -.5*x }
	object { GlassLetter("R", -.3) scale .7 translate 1*x }
	object { GlassLetter("R", -.3) scale .7 translate 2.5*x }
	object { GlassLetter("Y", -.3) scale .7 translate 4*x }
	translate <-.5, 7.5, 5>
}
union {
	object { GlassLetter("C", -.4) scale .7 translate -6*x }
	object { GlassLetter("H", -.3) scale .7 translate -4.5*x }
	object { GlassLetter("R", -.3) scale .7 translate -3*x }
	object { GlassLetter("I", -.1) scale .7 translate -1.5*x }
	object { GlassLetter("S", -.3) scale .7 translate 0*x }
	object { GlassLetter("T", -.4) scale .7 translate 1.5*x }
	object { GlassLetter("M", -.4) scale .7 translate 3*x }
	object { GlassLetter("A", -.4) scale .7 translate 4.5*x }
	object { GlassLetter("S", -.3) scale .7 translate 6*x }
	translate <0, 6, 5>
}

// ground plane
plane {
	y, 0
	pigment {
		bozo
		frequency 10
		color_map {
			[0 rgb <.5, .4, .3>]
			[.5 rgb <.7, .6, .5>]
			[1 rgb <.5, .4, .3>]
		}
	}
}