DEPTH = 4
RADIUS = 1.0
SCALE = 0.3
EPSILON = 0.001
##COLORS = None
COLORS = [[1.0,1.0,0.8],[0.2,1.0,0.2],[0.5,0.5,1.0],[1.0,1.0,0.6],[1.0,0.0,0.0]]
REFLECT = 1

def formatted(num):
    global scene_file
    return str(round(num,3))
def strvec(vec):
    try:
        return "["+formatted(vec[0])+","+formatted(vec[1])+","+formatted(vec[2])+"]"
    except:
        return "["+strvec(vec[0])+","+strvec(vec[1])+","+strvec(vec[2])+"]"
scene_file = """image {
	//width 1280
	//height 800
	width 640
	height 400
	//width 512
	//height 320
	//width 320
	//height 200
	samples 1
}

camera {
	//position -2.0 1.0 3.0 center 0.0 0.0 0.0
	position -1.5 0.5 1.5 center 0.0 0.0 0.0
	up 0.0 1.0 0.0
	image_plane 1.0
}

light "light1" {
	color 1.0 1.0 1.0
	object:sphere {
		radius 0.5
		position 4 4 4
	}
}
"""

if COLORS == None:
    for i in xrange(DEPTH):
        scene_file += """
    material "sphere"""+str(i)+"""_material" {
            """
        if REFLECT!=0: scene_file += "action:reflect 0.2 "+str(REFLECT)
        scene_file += """
            //action:refract 1.0 1 index 1.5 8000.0
            action:shadow "light1" 100
            diffuse 1.0 1.0 1.0
            specular 1.0 1.0 1.0
            shininess 300
    }"""
else:
    for i in xrange(DEPTH):
        scene_file += """
    material "sphere"""+str(i)+"""_material" {
            """
        if REFLECT!=0: scene_file += "action:reflect 0.2 "+str(REFLECT)
        scene_file += """
            //action:refract 1.0 1 index 1.5 8000.0
            action:shadow "light1" 10
            diffuse """+formatted(COLORS[i][0])+" "+formatted(COLORS[i][1])+" "+formatted(COLORS[i][2])+"""
            specular 1.0 1.0 1.0
            shininess 300
    }"""
    
scene_file += """
scene {
	background 0 0 0
	"""

#HACK: CHANGE
import sys
sys.path.append("C:\\dev\\Python Projects\\Current\\OpenGL Library\\3 OpenGL Library")
from glLibImport import *

def get_rotations_octohedron(basis,depth):
    rotations = [ [], [[basis[0],90]], [[basis[0],-90]], [[basis[2],90]], [[basis[2],-90]] ]
    if depth == 0: rotations += [ [[basis[0],180]] ]
    return rotations
def calc():
    global icos_angle, phi
    phi = (1.0+(5.0**0.5)) / 2.0
    p1 = [0,1,phi]
    p2 = [1,phi,0]
    e = length(vec_subt(p1,p2)) #2.0
    r = length([1.0,phi])
    opp = e / 2.0
    hypot = r
    icos_angle = degrees(2.0*asin(opp/hypot))
def get_rotations_icosahedron(basis,depth):
    rotations = [
        [],
        
        [[basis[0],icos_angle]],
        [[basis[0],icos_angle],[basis[1], 72]],
        [[basis[0],icos_angle],[basis[1],144]],
        [[basis[0],icos_angle],[basis[1],216]],
        [[basis[0],icos_angle],[basis[1],288]],

        [[basis[0],180],[basis[0],-icos_angle],[basis[1],  0+36]],
        [[basis[0],180],[basis[0],-icos_angle],[basis[1], 72+36]],
        [[basis[0],180],[basis[0],-icos_angle],[basis[1],144+36]],
        [[basis[0],180],[basis[0],-icos_angle],[basis[1],216+36]],
        [[basis[0],180],[basis[0],-icos_angle],[basis[1],288+36]]
    ]
    if depth == 0: rotations += [ [[basis[0],180]] ]
    return rotations
calc()

to_add = {}
def add_level(basis,position,depth):
    if depth not in to_add.keys(): to_add[depth] = []
    sphere_declaration = ""
    sphere_declaration += "object:sphere {"
    sphere_declaration += " use \"sphere"+str(depth)+"_material\""
    sphere_declaration += " position """+formatted(position[0])+" "+formatted(position[1])+" "+formatted(position[2])
    sphere_declaration += " radius """+str(SCALE**depth)
    sphere_declaration += "}\n"
    to_add[depth].append(sphere_declaration)
    
    if depth==DEPTH-1: return

    rotations = get_rotations_icosahedron(basis,depth)

    for rotation in rotations:
        distance = RADIUS*(SCALE**depth) + RADIUS*(SCALE**(depth+1)) + EPSILON
        new_position = sc_vec(distance,basis[1])
        new_basis = list([list(vec) for vec in basis])
        for op in rotation:
            new_position = rotate_arbitrary_deg(new_position,op[0],op[1])
            new_basis[0] = rotate_arbitrary_deg(new_basis[0],op[0],op[1])
            new_basis[1] = rotate_arbitrary_deg(new_basis[1],op[0],op[1])
            new_basis[2] = rotate_arbitrary_deg(new_basis[2],op[0],op[1])
        new_position = vec_add(new_position,position)
        add_level(new_basis,new_position,depth+1)
add_level( [[1,0,0],[0,1,0],[0,0,1]], [0,0,0], 0)
number = 0
for i in xrange(DEPTH):
    for s in to_add[i]:
        scene_file += s
        number += 1

scene_file += """}"""

print number, "spheres"

file = open("scene.txt","w")
file.write(scene_file)
file.close()


















