#include "glass.inc"

#local MetalTex =
texture
{
    pigment { color rgb <0.34, 0.36, 0.3> }

    finish { specular 0.7 roughness 0.6 metallic reflection { 0.3 metallic } }

    normal
    {
        average
        normal_map
        {
            [1.0 wrinkles 0.4 scale 0.01 ]
            [1.0 bozo 1 scale 0.07 ]
        }
    }
}


#local Base =
union
{
    cylinder
    {
        <0, 0, 0>, <0, 0.05, 0>, 0.5
    }
    
    cone
    {
        <0, 0.05, 0>, 0.5, <0, 0.2, 0>, 0.45
    }
    
    cylinder
    {
        <0, 0.2, 0>, <0, 0.4, 0>, 0.45
    }
    
    cone
    {
        <0, 0.4, 0>, 0.45, <0, 0.5, 0>, 0.3
    }   

    cylinder
    {
        <0, 0.5, 0>, <0, 0.52, 0>, 0.2
    }
    
    cone
    {
        <0, 0.52, 0>, 0.2, <0, 0.6, 0>, 0.15
    }
    
    cylinder
    {
        <0, 0.6, 0>, <0, 0.62, 0>, 0.1
    }
    
    cone
    {
        <0, 0.62, 0>, 0.1, <0, 0.65, 0>, 0.05
    }
    
    cylinder
    {
        <0, 0.65, 0>, <0, 0.67, 0>, 0.3
    }
    
    torus
    {
        0.3, 0.01
        translate <0, 0.66, 0>
    }
    
    // Gas tap    
    cylinder
    {
        <0, 0.45, -0.37>, <0, 0.5, -0.40>, 0.05
    }

    cylinder
    {
        <0, 0.5, -0.40>, <0, 0.5 + 0.05/2, -0.40 - 0.03/2>, 0.06
    }
}


#local E = 2.7182818284590452354;

// 1.756 is equal to -ProductLog[-1, -1/Sqrt[2E]] (in Mathematica notation),
// and it is such that the function will have a radius of 1/2 at y = 1.  The
// sqrt(E) factor is used to normalize the shape so that the largest radius
// is exactly 1.
#local GlassFunction = function (c) { 1.756 * sqrt (E * abs(c)) * exp (-1.756 * c) }

#local Glass =
isosurface
{
    function { pow(x, 2) + pow(z, 2) - pow(GlassFunction (y), 2) }
    contained_by { box { <-1, 0, -1>, <1, 1, 1> } }
    accuracy 0.01
    max_gradient 8
}

#local Wire =
isosurface
{
    function { pow (x - GlassFunction(y) * cos (pi * y), 2) +
        pow (z - GlassFunction(y) * sin (pi * y), 2) - 0.001 }
    contained_by { box { <-1, 0, -1>, <1, 1, 1> } }
    accuracy 0.01
    max_gradient 35.5
}

#local BorderHF =
height_field
{
    png "lant-border.png"
    water_level 0.1
    scale <1 * 500 / 524, 0.02, 1>
    rotate -90*x
    translate <-0.5, 0.005, 0>
}

#local Border =
union
{
    object { BorderHF }
    object { BorderHF scale <1, 1, -1> }
}

#local Cap =
union
{
    difference
    {
        cone
        {
            <0, 1.15, 0>, 0.24, <0, 1.25, 0>, 0.21
        }
        
        union
        {
            cone
            {
                <0, 1.15, 0>, 0.23, <0, 1.25, 0>, 0.20
            }

            #local i = 0;
            #while (i < 8)
                cylinder
                {
                    <cos(pi * (2 * i / 8)), 0, sin (pi * (2 * i / 8))>,
                    <cos(pi * (2 * i / 8 + 1)), 0, sin (pi * (2 * i / 8 + 1))>,
                    0.01
                }
                
                #declare i = i + 1;
            #end

            translate <0, 1.2, 0>
        }
    }
    
    cone
    {
        <0, 1.25, 0>, 0.21, <0, 1.30, 0>, 0.25
    }
    
    cylinder
    {
        <0, 1.30, 0>, <0, 1.31, 0>, 0.28
    }
    
    torus
    {
        0.28, 0.005
        translate <0, 1.305, 0>
    }
    
    cone
    {
        <0, 1.31, 0>, 0.28, <0. 1.35, 0>, 0.2
    }
    
    cylinder
    {
        <0, 1.35, 0>, <0, 1.5, 0>, 0.2
    }
    
    cone
    {
        <0, 1.5, 0>, 0.2, <0, 1.55, 0>, 0.15
    }    
}

#local Roof =
union
{
    #local i = 0;
    #while (i < 8)
        cylinder
        {
            0.14 * <cos(2 * pi * i/8), 0, sin(2 * pi * i/8)>,
            0.14 * <cos(2 * pi * i/8), 0.3, sin(2 * pi * i/8)>,
            0.01
        }
        
        #declare i = i + 1;
    #end
    
    intersection
    {
        difference
        {
            sphere { <0, -0.32, 0>, 0.4 }
            sphere { <0, -0.32, 0>, 0.39 }
        }
        box { <-0.5, 0.03, -0.5>, <0.5, 0.5, 0.5> }
    }

    translate <0, 1.55, 0>
}

#local HandleRadius = 0.01;
#local Handle =
sphere_sweep
{
    b_spline
    6,
    
    <-0.25, -0.1, 0>, HandleRadius,
    <-0.30,  0.0, 0>, HandleRadius,
    <-0.32,  0.6, 0>, HandleRadius,
    < 0.31,  0.6, 0>, HandleRadius,
    < 0.30,  0.0, 0>, HandleRadius,
    < 0.25, -0.2, 0>, HandleRadius
    
    translate <0, 1.3, 0>
}


#declare Lantern =
union
{
    object { Base texture { MetalTex } }
    object
    {
        Border scale <1.2, 1.2, 1> translate <0, 0.25, 0>
        texture { MetalTex } 
    }
    object { Handle texture { MetalTex } }
    
    union
    {
        difference
        {
            object { Glass }
            object { Glass scale 0.97 translate 0.01*y }
            texture
            {
                pigment { color <0.97, 0.99, 0.98, 0.97> }
                normal { crackle 0.4 scale 0.05 }
                finish { F_Glass5 }
            }
        }
        
        union
        {
            object { Wire }
            object { Wire scale <-1, 1, 1> }
            object { Wire rotate 180*y }
            object { Wire rotate 180*y scale <-1, 1, 1> }
            
            texture { MetalTex } 
        }
        
        scale <0.4, 0.6, 0.4>
        translate <0, 0.61, 0>
    }
    
    object { Cap texture { MetalTex } }
    object { Roof texture { MetalTex } }
    
    // Wick
    cylinder
    {
        <0, 0.67, 0>, <0, 0.72, 0>, 0.05
        pigment { color rgb 0 }
    }
    
}


///////////////////////////////////////////////////////////

/*
camera
{
    location <1, 1.5, -2>
    look_at <0, 1, 0>
}

light_source
{
    <-10, 20, -30>
    color rgb 1
}

light_source
{
    <10, 5, -30>
    color rgb 0.3
}

plane
{
    y, 0
    pigment { color rgb 0.7 }
}

object
{
    Lantern
}
*/