
// POV-Ray Object File - Piano
// created 19-Mar-06
// last update 11-Apr-06
// Copyright ©2006 Glenn McCarter (glenn@mccarters.net). Some rights reserved.
// This work is licensed under the Creative Commons Attribution License
// To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/
//
// Required #include files: "GIncludeRH.inc"
//
// Objects:
// Piano
//
//
// Intended scale is English system (inches)
// Uses RH coordinate reference system (Z=up)
//
// Baby Grand Info (typical dimensions)
// Length: 5' 3" (161 cm)
// Width: 59" (149 cm)
// Height: 40" (101 cm)
//
// Length: 6' 11" (212 cm)
// Width: 61" (154 cm)
// Height: 40-1/2" (102 cm)
//
//
// This file is intended to be included in another POV-Ray scene file,
// but can be rendered alone.
#ifndef (ThisIsMaster) // If this include file was not called by another, then
	#declare RenderMe = 0; // supress self-rendering of other include files
	#declare ThisIsMaster = 1;
	#include "GIncludeRH.inc"
	// renderable sub includes go here
	#declare RenderMe = 1;
#end

//===============================================
//             Includes
//===============================================

// non-renderable sub includes go here

//===============================================
//             Variables
//===============================================

#declare PianoQuality = 1;
#declare KeySpacing = 1.08; // inches across

#if (RenderMe = 1)
	#local Radios=0;
#end


//===============================================
//             Textures
//===============================================

#declare PianoTex =
	texture {
		#switch ( PianoQuality )
		#case (1)
			pigment { color rgb<.967,.977,.996>*0.0035 }
//			finish { ambient 0.05 diffuse 0.4 specular 0.93 roughness 0.016 reflection 0.142 } // too grey on top
			finish { ambient 0.05 diffuse 0.4 specular 0.73 roughness 0.005 reflection 0.142 } // test
		#break
		#else
			pigment { color rgb<.967,.977,.996>*0.935 } // test
			finish { ambient 0.05 diffuse 0.4 specular 0.93 roughness 0.023 } // test
		#end
	}
#declare Piano2Tex =
	texture {
			pigment { color rgb<.967,.977,.996>*0.035 }
			finish { ambient 0.05 diffuse 0.4 specular 0.93 roughness 0.016 reflection 0.084 } // for frontpiece
	}
#declare PianoLegTex =
	texture {
		pigment { color rgb<.967,.977,.996>*0.105 }
		finish { ambient 0.05 diffuse 0.4 specular 0.93 roughness 0.023 }
	}
#declare IvoryWhiteKeyTex =
	texture {
		pigment {
			gradient x
			color_map {
				[ 0.92 rgb<1,1,1>*1.0 ]
				[ 0.94 rgb<1,1,1>*1.33 ]
				[ 0.96 rgb<1,1,1>*1.33 ]
				[ 0.97 rgb<1,1,1>*.13 ]
			}
			scale KeySpacing
		}
		#if (Radios)
//			finish { ambient 10 diffuse 0.4 specular 0 }
			finish { ambient 8 diffuse 0.2 specular 0.53 roughness 0.023 }
		#else
//			finish { ambient .3 diffuse 0.4 }
			finish { ambient 0.5 diffuse 0.2 specular 0.53 roughness 0.023 }
		#end
	}
#declare PianoHingeTex =
	texture {
		pigment {
			gradient x
			color_map {
				[ 0.5 color rgb<1,.87,.61> ]
				[ 0.5 color rgb<1,.87,.61>*0.6 ]
			}
			scale 1
		}
		finish { ambient 0.15 diffuse 0.5 specular 0.93 roughness 0.023 }
	}
#declare PianoBrassTex =
	texture {
		pigment { color rgb<1,.93,.53>*0.20 }
		#if (Radios)
			finish { ambient 12 diffuse 0.5 specular 0.93 roughness 0.023 metallic reflection 0.64 }
		#else
			finish { ambient 0.15 diffuse 0.5 specular 0.93 roughness 0.023 metallic reflection 0.64 }
		#end
	}
#declare PianoSteelTex =
	texture {
		pigment { color rgb<0.92,0.95,1.00>*0.85 }
		finish { ambient 0.15 diffuse 0.5 specular 0.93 roughness 0.023 }
	}


#declare TestWhiteTex =
	texture {
		pigment { color rgb<1,1,1> }
	}


//===============================================
//             Macros
//===============================================


//===============================================
//             Piano
//===============================================

// Piano high keys extend into +X, main body extends into +Y, Z=up

#declare PMR = 21; // Piano Main Radius
#declare PSR = 11; // Piano Secondary Radius
#declare PTR =  7; // Piano Third Radius
#declare PBL = 43; // Piano Box Length
#declare PBH = 12; // Piano Box Height
#declare BHY = 15; // Back Half Y-start
// overall length 5'4" (64")
// overall width 60"

#declare PianoBodyBackHalf =
	union {
	// If you really want the full piano model, contact me
	text {
		ttf "arialbd.ttf"
		"?" 1,0.24*x
		rotate x*90
		scale <20,2,20>
		translate <30,24,12>
		texture { PianoTex }
	}
	} // end union
#declare PianoBodyFrontHalf =
	difference {
		box { <0,0,0>,<60,BHY,PBH-1.0> } // main
		box { <1.20,-1,2.00>,<60-1.20,8,PBH-2> texture { Piano2Tex} } // keybox space
//		box { <1.20,-1,2.00>,<60-1.20,8,PBH-2> texture { Piano2Tex} } // keybox space
		box { <1.21,-1,2.01>,<60-1.21,7.2,PBH+1> } // top wide shelf
		box { <-1,-1,8>,<61,6.0,PBH+1> } // endcap top front
		box { <-1,-1,4.5>,<61,4,PBH> } // endcap bottom
		cylinder {<-1,4,4.5+3>,<61,4,4.5+3>,3 } // endcap
		box { <-1,-1,4.5-0.5>,<61,0.5,5> } // endcap front radius cutout
	} // end difference
#declare EndcapFrontRadius =
	union {
		cylinder { <0,0.5,4.0>,<1.20,0.5,4.0>,0.5 }
		cylinder { <60,0.5,4.0>,<60-1.20,0.5,4.0>,0.5 }
	} // end union
#declare PianoFrontLid =
//	box { <0,7.0,PBH-1.06>,<60,BHY-0.16,PBH> }
	object { RoundedHalfBox2(60,BHY-0.16-7.0,1.2,0.3) translate <0,7.0,PBH-1.2>}
#declare PianoHinge =
	cylinder { <0.7,0,0>,<60-0.7,0,0>,0.08 texture { PianoHingeTex } translate <0,BHY-0.08,PBH> }
#declare KeyFillerEnds =
	superellipsoid {
		<0.2,0.2>
		scale <2/2,8/2,2/2>
		texture { PianoTex }
	}
#declare Undertray =
	box { <0.7,0.7,-1.5>,<60-0.7,BHY+4,0> texture { Piano2Tex } }
#declare FrontLogo =
	text {
		ttf "arialbd.ttf"
		"YAMAHA" 1,0.24*x
		rotate x*90
		scale <1.2,1,1.2>
		texture { PianoBrassTex }
	}
#declare WhiteKeys =
	union {
		box { <0,0,-1>,<55,7,0> }
//		box { <0,-0.10,-0.05>,<55,0,0> }
		cylinder { <0,0,0>,<55,0,0>,0.05 translate <0,0.0,-0.025> }
		texture { IvoryWhiteKeyTex }
	} // end union
#declare BlackKey =
	superellipsoid {
		<0.2,0.2>
		scale <0.48/2,5/2,0.6/2>
		translate <-0.38/2,2.5,0>
		ZShear(y,0.35)
		texture { PianoLegTex }
	}

#declare BlackKeyOctave =
	union {
		object { BlackKey translate x*KeySpacing*0 }
		object { BlackKey translate x*KeySpacing*1 }
		object { BlackKey translate x*KeySpacing*3 }
		object { BlackKey translate x*KeySpacing*4 }
		object { BlackKey translate x*KeySpacing*5 }
	} // end union
#declare OctaveLength = KeySpacing*7;
#declare BlackKeyGroup =
	union {
		object { BlackKey translate x*KeySpacing }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*0,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*1,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*2,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*3,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*4,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*5,0,0> }
		object { BlackKeyOctave translate <KeySpacing*3+OctaveLength*6,0,0> }
	} // end union

#macro PCaster(RotAngle)
	union {
		superellipsoid {
			<0.4,0.4>
			scale <0.15/2,0.8/2,1.4/2>
			translate <0,0,0.6>
			ZShear(y,0.7)
			translate <0.7,-1.4,0.7>
		}
		superellipsoid {
			<0.4,0.4>
			scale <0.15/2,0.8/2,1.4/2>
			translate <0,0,0.6>
			ZShear(y,0.7)
			translate <-0.7,-1.4,0.7>
		}

		cylinder { <-0.4,0,0>,<0.4,0,0>,0.8 translate <0,-1.4,0.8> }
		torus { 0.73,0.07 rotate z*90 translate <-0.4,-1.4,0.8> }
		torus { 0.73,0.07 rotate z*90 translate < 0.4,-1.4,0.8> }
		texture { PianoBrassTex }
		rotate z*RotAngle
	} // end union
#end
#macro PianoLeg(RotAngle)
	#local PT = 2.1; // taper degrees each side
	union {
//		box { <-1.2,-1.2,3.2>,<1.2,1.2,27.5> }
		difference {
			box { <-2.0,-2.0,3.2>,<2.0,2.0,27.5> }
			box { <-3.0,-3.0,0>,<3.0,3.0,-33> rotate y*PT translate <5.0,0,27.5> }
			box { <-3.0,-3.0,0>,<3.0,3.0,-33> rotate y*-PT translate <-5.0,0,27.5> }

			box { <-3.0,-3.0,0>,<3.0,3.0,-33> rotate x*PT translate <0,-5.0,27.5> }
			box { <-3.0,-3.0,0>,<3.0,3.0,-33> rotate x*-PT translate <0,5.0,27.5> }
		} // end difference

		difference {
			box { <-2.3,-7,27.5-5>,<2.3,7,27.5> }
			cylinder { <-3,0,0>,<3,0,0>,6 translate <0,-7,26.5-8.2> }
			cylinder { <-3,0,0>,<3,0,0>,6 translate <0, 7,26.5-8.2> }
		} // end difference

		box { <-1.1,-1.1,2.2>,<1.1,1.1,3.2> texture { PianoBrassTex } }
		cylinder { <0,0,1.9>,<0,0,2.2>,0.9 texture { PianoBrassTex } }

		object { PCaster(RotAngle) }
		texture { PianoLegTex }
	} // end union
#end

#declare PPH = 24; // Piano Pedal Height
#declare PianoPedal =
	sphere_sweep { cubic_spline 5,
		<0,2,0>,0.5
		<0,0,0>,0.5
		<0,-2,0>,0.6
		<0,-4,0>,0.8
		<0,-5,0>,0.8
		scale <1,1,0.16>
		texture { PianoBrassTex }
	}

#declare PianoPedalGroup =
	union {
		box { <-0.6,0,0>,<0.6,1.2,PPH> translate <-3,1,0> }
		box { <-0.6,0,0>,<0.6,1.2,PPH> translate < 3,1,0> }
		box { <-4.5,0,0>,<4.5,4,2.5> }
		cylinder { <0,0,0>,<0,0,PPH>,0.14 translate <-3,4.2,1> texture { PianoSteelTex } }
		cylinder { <0,0,0>,<0,0,PPH>,0.14 translate < 0,4.2,1> texture { PianoSteelTex } }
		cylinder { <0,0,0>,<0,0,PPH>,0.14 translate < 3,4.2,1> texture { PianoSteelTex } }
		cylinder { <0,0,0>,<0,0,PPH*1.3>,0.22 rotate x*-25 translate <-3.6,2,2> }
		cylinder { <0,0,0>,<0,0,PPH*1.3>,0.22 rotate x*-25 translate < 3.6,2,2> }
		object { PianoPedal rotate z*-15 translate <-2.5,0,0.7> }
		object { PianoPedal translate < 0,0,0.7> }
		object { PianoPedal rotate z*15 translate < 2.5,0,0.7> }
		texture { PianoLegTex }
	} // end union

#declare PH=27.5; // height to raise all piano body elements
#declare Piano =
	union {

		object { PianoBodyBackHalf translate <0,0,PH> }
		object { PianoBodyFrontHalf translate <0,0,PH> }
		object { EndcapFrontRadius translate <0,0,PH> }
		object { PianoFrontLid translate <0,0,PH> }
		object { PianoHinge translate <0,0,PH> } 
		object { Undertray translate <0,0,PH> } 
		object { FrontLogo translate <27,8.99,PH+5.4> }
		object { WhiteKeys     translate <2.5-0.38/2,1,PH+2+0.78> } // height is to the top of the keys
		object { BlackKeyGroup translate <2.5,3,PH+2+1> }
		object { KeyFillerEnds translate <   1.5,4.6,PH+2.5> }
		object { KeyFillerEnds translate <60-1.5,4.6,PH+2.5> }

		object { PianoPedalGroup translate <30,12,2.5> }

		object { PianoLeg(-20) translate <   6,10,0> }
		object { PianoLeg( 40) translate <60-6,10,0> }
		object { PianoLeg(70) rotate z*90 translate <21,56,0> }

		texture { PianoTex }
	} // end union

//===============================================
//             Viewpoint 01
//===============================================

#if (RenderMe = 1)
global_settings {	max_trace_level 150 }
#declare TestSphere = sphere{ 0,12 pigment { color rgb<1,1,1> } }

	camera {
		perspective
		direction <0.0,     1.0,  0.0>
		sky       <0.0,     0.0,  1.0>  // Use right handed-system!
		up        <0.0,     0.0,  1.0>  // Where Z is up
		right     <1.33333, 0.0,  0.0>

		angle 38
		location  <6*Feet, -9*Feet, 6.5*Feet> // overall
		look_at <3*Feet,3*Feet,3.5*Feet>
//		location  <3*Feet, -1*Feet, 35*Feet> // top down
//		look_at <3*Feet,3*Feet,3*Feet>

	}

background { color rgb <0.276,0.567,0.982>*.97 } // sky blue
light_source
{ <140*Feet,-300*Feet,250*Feet>, 1.2
//  spotlight point_at <0,0*Feet,2*Feet> radius 25 falloff 36
}
light_source
{ <-140*Feet,-200*Feet,130*Feet>, <1.13,1.08,0.83>*.8
//  spotlight point_at <0,0,2*Feet> radius 25 falloff 36
}

plane { z,-0 pigment { checker rgb <1,1,1>, rgb <1,1,1>*.75 } scale 1*Feet }

//#include "GRuler.inc" // for testing only
//object { TestSphere scale 1 translate <0,0,10> }

#object { Piano rotate <0,0,10> }
//#object { Piano rotate <0,0,-90> translate <4*Feet,0,40>  }
//#object { Piano rotate <0,0,22> scale 4 translate <0,0,-100> } // keyboard closeup
#object { Piano rotate <83,0,15> translate <-8*Feet,20*Feet,15> }
#object { Piano rotate z*-40 translate <28,120,0> }
#object { Piano rotate z*-75 translate <-20,220,41> }
//#object { Piano scale 3 rotate z*-40 translate <-6*Feet,120,0> } // feet closeup
#end

