// ============================================================================
// MC930A - Computacao Grafica    =============================================
// Eduardo Uemura Okada RA 001606 =============================================
// Laboratorio XX                 =============================================
// ============================================================================

// ============================================================================
// Declaracao de constantes ===================================================
// ============================================================================

// Modos de texturas
#declare MODO_SOLIDO  = 0;
#declare MODO_CRISTAL = 1;
#declare MODO_ESPELHO = 2;
#declare MODO_VIDRO   = 3;

// Fator de distancia para a camera
#declare V_MAX = 5;

// Vistas default para camera
#declare V_ISOMETRICA_ESQUERDA = < -V_MAX ,  V_MAX    , -V_MAX    >;
#declare V_ISOMETRICA_DIREITA  = <  V_MAX ,  V_MAX    , -V_MAX    >;
#declare V_LATERAL_ESQUERDA    = < -V_MAX ,  V_MAX/10 , -V_MAX    >;
#declare V_LATERAL_DIREITA     = <  V_MAX ,  V_MAX/10 , -V_MAX    >;
#declare V_SUPERIOR_DIANTEIRA  = <    0   ,  V_MAX*2  , -V_MAX/10 >;
#declare V_SUPERIOR_POSTERIOR  = <    0   ,  V_MAX*2  ,  V_MAX/10 >;
#declare V_INFERIOR_DIANTEIRA  = <    0   , -V_MAX*2  , -V_MAX/10 >;
#declare V_INFERIOR_POSTERIOR  = <    0   , -V_MAX*2  ,  V_MAX/10 >;
#declare V_FRONTAL = <0,V_MAX/10,-V_MAX>;
#declare V_CUSTOM = <0.5,1,-1>;
#declare V_CENTRO = <0,0,0>;

// Normais para os planos
#declare P_EIXO_X = <0,1,0>;
#declare P_EIXO_Y = <1,0,0>;
#declare P_EIXO_Z = <0,0,1>;

// Clock do lab
#declare clock0 = clock;
#declare clock1 = mod ( clock+0.5,1 );

// ============================================================================
// Declaracao de macros utilitarias e texturas ================================
// ============================================================================

#macro TexturaSolida ( Cor )
texture {
	pigment { color rgb Cor }
	finish { diffuse 0.5 specular 0.5 roughness 0.005 ambient 0.1 } 
}
#end

#macro TexturaCristal ( Cor )
texture {
	finish { ambient 0.1 diffuse 0.1 reflection 0.25 specular 1 roughness 0.001 }
	pigment { color Cor filter 1 }
}
interior { ior 1.5 }
#end

#macro TexturaEspelho ( Cor )
texture { 
	finish { ambient 0.05 diffuse 0.05 reflection Cor specular 0.20 roughness 0.05 }
	pigment { rgb Cor }
}
#end

#macro TexturaVidro ( Cor )
texture {
	pigment { color Cor filter 1.05 }
	finish { phong 0.9 phong_size 40 reflection 0.2 }
}
interior { ior 1.53 }
#end


#macro SelecionaCor ( Cor, Modo )
        #switch ( Modo )
                #case ( MODO_SOLIDO )
                        TexturaSolida (Cor)
                #break
                #case ( MODO_CRISTAL )
                        TexturaCristal (Cor)
                #break
                #case ( MODO_ESPELHO )
                        TexturaEspelho (Cor)
                #break
		#case ( MODO_VIDRO )
			TexturaVidro (Cor)
		#break
        #end
#end

#macro Camera ( Visao, Alvo )
camera { location Visao sky y look_at Alvo }
#end

#macro FonteLuz ( Posicao, Cor, Intensidade )
light_source { Posicao color rgb Intensidade * Cor }
#end

#macro Plano ( Tipo, Posicao, Cor1, Cor2 )
plane { Tipo, Posicao pigment { checker color rgb Cor1 color rgb Cor2 } }
#end

#macro Ceu ( CorBaixa, CorAlta )
sky_sphere {
	pigment {
		gradient y color_map { [ 0.5  color CorAlta ] [ 1.0  color CorBaixa ] }
		scale 2 translate -1
	}
}
#end

#macro CeuAzulNublado()
sky_sphere {
	pigment {
		gradient y color_map {
			[0.000 0.002 color rgb <0.0, 0.2, 1.0> color rgb <0.0, 0.2, 1.0>]
			[0.002 0.200 color rgb <0.0, 0.1, 0.8> color rgb <0.3, 0.2, 0.2>]
		}
		scale 2 translate -1
	}
	pigment {
		bozo turbulence 0.65 octaves 6 omega 0.7 lambda 2 color_map {
			[0.0 0.1 color rgb <0.85, 0.85, 0.85> color rgb <0.75, 0.75, 0.75>]
			[0.1 0.5 color rgb <0.75, 0.75, 0.75> color rgbt <1, 1, 1, 1>]
			[0.5 1.0 color rgbt <1, 1, 1, 1> color rgbt <1, 1, 1, 1>]
		}
		scale <0.2, 0.5, 0.2>
	}
	rotate -135*x
}
#end

#macro NevoaSinistra(Distancia, Altura, Cor)
fog {
	distance Distancia
	color rgbf Cor fog_type 2 fog_offset Altura fog_alt 1.0
}
#end

// ============================================================================
// Declaracao de macros e objetos basicos =====================================
// ============================================================================
// Todos os objetos gerados ao redor de <0,0,0>                

#macro Paralelepipedo ( Tam, Cor, Modo, Rotacao, Posicao )
box { -Tam/2 Tam/2 SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao }
#end

#macro Cone ( Base, Topo, Altura, Cor, Modo, Rotacao, Posicao )
cone {
	< 0, -Altura/2, 0>, Base < 0, Altura/2, 0>, Topo SelecionaCor ( Cor, Modo )
	rotate Rotacao translate Posicao
}
#end

#macro Cilindro ( Altura, Raio, Cor, Modo, Rotacao, Posicao )
cylinder {
	< 0, -Altura/2, 0 >, < 0, Altura/2, 0 >, Raio SelecionaCor ( Cor, Modo )
	rotate Rotacao translate Posicao
}
#end

#macro Torus ( Menor, Maior, Cor, Modo, Rotacao, Posicao )
torus { Maior, Menor SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao }
#end

#macro Esfera ( Raio, Cor, Modo, Rotacao, Posicao )
sphere { <0,0,0>, Raio SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao }
#end

#macro Texto ( Dado, Fonte, Grossura, Espaco, Cor, Modo, Rotacao, Posicao )
text {
	ttf Fonte Dado Grossura,Espaco SelecionaCor ( Cor, Modo )
	rotate Rotacao translate Posicao
}
#end

// ============================================================================
// Montagem de pecas compostas ================================================
// ============================================================================

#macro SemiEsfera ( Raio, Cor, Modo, Rotacao, Posicao )
difference {
	Esfera ( Raio, Cor, Modo, <0,0,0>, <0,-Raio/2,0> )
	Paralelepipedo ( <Raio*2+2,Raio*2+2,Raio*2+2>, Cor, Modo, <0,0,0>, < 0,-Raio/2-Raio-1,0 >)
	SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao
}
#end

#macro Bastonete ( Altura, Raio, Cor, Modo, Rotacao, Posicao )
union {
	Cilindro ( Altura-2*Raio+0.001, Raio, Cor, Modo, <0,0,0>, <0,0,0> )
	SemiEsfera ( Raio, Cor, Modo, <0,0,0>, <0,(Altura-Raio)/2,0> )
	SemiEsfera ( Raio, Cor, Modo, <0,0,180>, <0,-(Altura-Raio)/2,0> )
	SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao
}
#end

#macro OrbitaEsferas ( Raio, Orbita, Passos, Cor, Modo, Rotacao, Posicao )
#declare angulo = 0;
union {
	#while ( angulo < 2*pi )
		Esfera ( Raio, Cor, Modo, <0,0,0>, <Orbita*cos(angulo),Orbita*sin(angulo),0> )
		#declare angulo = angulo + 2*pi/Passos;
	#end
	SelecionaCor ( Cor, Modo ) rotate Rotacao translate Posicao
}
#end

#macro Taca ( Tamx, Tamy, Tamz, Cor, Modo, Rotacao, Posicao )
lathe {
	quadratic_spline 20,
	<0,0>, <2,0>, <2,0.5>, <1,1>, <0.5,1.5>, <0.35,3.5>, <1,4>, <2,4.5>, <2.5,5>,
	<2.7,5.5>, <2.6,6.5>, <2.5,7.5>, <2.4,7.5>, <2.5,6.5>, <2.6,5.5>, <2.4,5>,
	<1.9,4.5>, <0.9,4>, <.35,3.8>, <0,3.7>
	SelecionaCor ( Cor, Modo ) translate <0,-3.75,0>
	scale < Tamx/5.4, Tamy/7.5, Tamz/5.4 > rotate Rotacao translate Posicao
}
#end

#declare CorLuz = <0.95,0.95,0.95>;
#declare CorCabo = <0.8,0.8,0.8>;
#declare CorContato = <0.1,0.1,0.1>;
#macro Lampada ( Altura, Raio, Intensidade, Cor, Modo, Rotacao, Posicao )
union {
	// Bulbo
	lathe {
		cubic_spline 17,
		<0,0>,<1,0.2>,<1.8,1>,<1.9,2>,<1.5,3>,<1,4>,<0.8,5>,<0,5>,
		<0,4.1>,<0.7,4.1>,<0.9,4>,<1.4,3>,<1.8,2>,<1.7,1>,<0.9,0.2>,<0,0.1>,<0,0>
		SelecionaCor ( Cor, Modo )
	}
	// Cabo
	lathe {
		cubic_spline 14,
		<0,4.9>,<0.9,4.9>,<1,5>,<1,5.1>,<0.9,5.2>,<0.9,5.3>,<1,5.4>,
		<1,5.5>,<0.9,5.6>,<0.9,5.7>,<1,5.8>,<1,5.9>,<0.9,6>,<0,6>
		SelecionaCor ( CorCabo, MODO_ESPELHO )
	}
	// Contato exterior
	lathe {
		cubic_spline 7,
		<0,5.9>,<0.5,5.9>,<0.5,6.05>,<0.4,6>,<0.3,6.05>,<0.2,6.1>,<0,6.1>
		SelecionaCor ( CorContato, MODO_ESPELHO )
	}
	// Fonte de luz
	FonteLuz ( <0,1,0>, CorLuz, Intensidade )
	translate <0,-3.05,0>
	scale <Raio/1.9,Altura/6.1,Raio/1.9>
	rotate Rotacao translate Posicao
}
#end

// Virado para esquerda
#macro BuracoNegro(Tamanho,Cor,Modo,Rotacao,Posicao)
	difference {
		Cilindro ( 1, 0.500001, Cor, MODO_SOLIDO, <0,0,90>, 0 )
		Esfera ( 0.5, Cor, MODO_SOLIDO, 0, <-0.5,0,0> )
		SelecionaCor ( Cor, Modo )
		scale Tamanho rotate Rotacao translate Posicao
	}
#end

#macro Sol ( Posicao )
	FonteLuz ( Posicao, 1, 100 )
#end

#macro FundoEspaco ( Rotacao, Posicao )
	object {
		Paralelepipedo ( <100,100,1>, 0, MODO_SOLIDO, 0, 0 )
		pigment { image_map { jpeg "fundo.jpg" } scale<50,50,1> }
		rotate Rotacao translate Posicao
	}
#end

#macro BrasilSaindo(Threshold, Terra, CilForca, Distancia, Tamanho, Rotacao, Posicao)
	blob {
		threshold Threshold
		sphere { <0,0,0>, 1, Terra pigment { image_map {png "earth-land.png" map_type 1} rotate <-20,-150-85,0>} }
		cylinder { <0+Distancia,0,0>, <1+Distancia,0,0>, 0.3, CilForca pigment { color rgb <0.6,1,0.6> } }
		finish { phong 1 }
		scale Tamanho rotate Rotacao translate Posicao
	}
#end

// ============================================================================
// Montagem de pecas finais e da cena =========================================
// ============================================================================

// ============================================================================
// Camera e Iluminacao ========================================================
// ============================================================================

Camera ( V_LATERAL_DIREITA, V_CENTRO )

FonteLuz ( <10.0,10.0,-10.0>, <1,1,1>, 2 )
FonteLuz ( < -4.0, 4.0,-4.0>, <1,1,1>, 1 )

// ============================================================================
// Composicao da Cena =========================================================
// ============================================================================

// background { color rgb 0 }

sky_sphere { pigment { image_map { jpeg "fundo.jpg" } } }

// BuracoNegro(<0.2,1,1>,1,MODO_SOLIDO,<0,-45,0>,0)
BrasilSaindo(0.5,1,0.4,0.5 + (1-clock)*0.5,3,<0,-30 + clock*60,20*clock>,0)
FundoEspaco (0,<0,0,10>)
// BuracoNegro(<0.1,2,2>,0,MODO_ESPELHO,<0,-30+clock*60,20*clock>,<3,0,0>)

/*
blob {
	threshold 0.65
	sphere { <5,0,0>, 8, 1 pigment {color rgb <0.6,1,0.6>} }
	//sphere { <-5,0,0>, 8, 1 pigment {color rgb <1,0.6,0.6>} }
	cylinder { <-10,0,0>, <0,0,0>, 4, 0.5 pigment { color rgb 0 } }
	finish { phong 1 }
}
*/


// Interfaces das macros:
// ----------------------
// Camera ( Visao, Alvo )
// FonteLuz ( Posicao, Cor, Intensidade )
// Plano ( Tipo, Posicao, Cor1, Cor2 )
// Ceu ( CorBaixa, CorAlta )
// Paralelepipedo ( Tam, Cor, Modo, Rotacao, Posicao )
// Cone ( Base, Topo, Altura, Cor, Modo, Rotacao, Posicao )
// Cilindro ( Altura, Raio, Cor, Modo, Rotacao, Posicao )
// Torus ( Menor, Maior, Cor, Modo, Rotacao, Posicao )
// Esfera ( Raio, Cor, Modo, Rotacao, Posicao )
// Texto ( Dado, Fonte, Grossura, Espaco, Cor, Modo, Rotacao, Posicao )
// SemiEsfera ( Raio, Cor, Modo, Rotacao, Posicao )
// Bastonete ( Altura, Raio, Cor, Modo, Rotacao, Posicao )
// OrbitaEsferas ( Raio, Orbita, Passos, Cor, Modo, Rotacao, Posicao )
// Taca ( Tamx, Tamy, Tamz, Cor, Modo, Rotacao, Posicao )