// Persistence of Vision Ray Tracer Scene Description File
// File: machine.pov
// Vers: 3.5
// Desc: Definition of the SewingMachine object
// Date: 2003/01/19
// Auth: Maurizio Tomasi

#include "rounded-plate.inc"

#declare USE_BENCH = 1;
#declare USE_MACHINE_BODY = 1;
#declare USE_PEDAL = 1;
#declare USE_FEET = 1;

/* Create a wireframe-like object from a greyscale PNG image.
 * The object will be centered at <0, 0, 0> and facing upwards
 * (y axis).  Its size is <1.0, 0.05, 1.0>. */

#macro CreateWire (file_name)
    #local BaseObj =
    height_field {
      png file_name
      smooth        
      water_level 0.1
      
      translate <-0.5, -0.5, -0.5>
      scale <1.0, 0.05, 1.0>
    }
    
    union
    {
        object
        {
            BaseObj
            scale <-1.0, 1.0, 1.0>
            translate <0, 0.05/(2+0.5), 0>
        }
        
        object
        {
            BaseObj
            rotate 180*z
            translate <0, -0.05/(2+0.5), 0>
        }
    }
#end


//////////////////////////////////////////////////////////////////
// Base of the sewing-machine (made by metal wires)

// The smallest box that contains the base is:
// box { <-0.5, 0, 0>, <0.5, 2, 1> }


#ifdef (USE_FEET)

    #declare MachineFoot =
    object
    {
        CreateWire ("foot.png")
        
        rotate -90*x
        scale <1.0, 2.0, 0.4>
        translate <0.0, 2.0/2, 0.0>
    }
    
    #declare Singer =
    object
    {
        CreateWire ("Singer.png")
    
        rotate 90*y
        rotate 90*z
        scale <0.2, 1.7, 1.0>
        translate <0, -0.2, 0>
    }

#end

#ifdef (USE_PEDAL)

    #local Handle =
    object
    {
        CreateWire ("handle.png")

        rotate -90*x
        rotate 90*y    
        scale <0.4, 0.3, 0.2>
    }


    #declare Pedal =
    union
    {
        object
        {
            CreateWire ("motive.png")
        
            rotate 90*y
            scale <0.67, 0.5, 0.6>
            rotate -15*z
            translate <0, 0.2, 0.5>
        }
        
        object { Handle translate <0, 0.3, 0.1> }
        
        object { Handle scale <1, 1, -1> translate <0, 0.3, 0.9> }
    }
#end

#local WheelCenter = <0.0, 1.2, 1.0 - 0.08>;
#local WheelRadius = 0.45;

#declare Wheel =
object
{
    CreateWire ("wheel.png")
    
    rotate 25*y // Give a small "tilt"
    rotate -90*x
    scale <WheelRadius * 2, WheelRadius * 2, 0.75>
    translate WheelCenter
}

#declare Stick =
union
{
    #local Pt1 = <-0.3, 0.27, 1.0 - 0.2>;
    #local Pt2 = <-0.05, 1.30, 1.0 - 0.2>;
    #local Direction = Pt2 - Pt1;
    
    cylinder
    {
        Pt1, Pt2, 0.02
    }
    
    cylinder
    {
        Pt1, Pt1+Direction*0.05, 0.03
    }

    cylinder
    {
        Pt2-Direction*0.05, Pt2, 0.03
    }
}


#declare Base =
union
{
    #ifdef (USE_FEET)
    
        object { MachineFoot }
        object { MachineFoot translate <0, 0, 1> }
        object { Singer translate <0, 1.33, 0.5> }
    
    #end
    
    object { Wheel }
    
    #ifdef (USE_PEDAL)
        
        object { Pedal }
        
    #end
    
    object { Stick }

    #local rad = 0.025;    
    sphere_sweep
    {
        cubic_spline
        6,
        
        //<0, 0.00, 0.65>, rad
        //<0, 0.00, 0.70>, rad
        <0, 0.00, 0.73>, rad
        <0, 0.08, 0.80>, rad
        <0, 0.00, 0.87>, rad
        <0, 0.00, 0.90>, rad
        <0, 0.00, 1.00>, rad
        <0, 0.00, 1.10>, rad
        
        rotate 60*z
        translate <0, 0.75 + WheelRadius, 0>
    }
    
    sphere
    {
        <0, 0.75 + WheelRadius, 1>, rad*2
    }
    
    texture
    {
        pigment
        {
            //color rgb <0.15, 0.15, 0.27>
            color rgb <0.15, 0.15, 0.20>
        }
        
        finish
        {
            diffuse 0.4
            specular 0.7 roughness 0.7 metallic
            reflection { 0.05 metallic }            
        }
    }
}


#declare MachineBodyTexture =
texture
{
    pigment
    {
        agate
        agate_turb 1.3
        color_map
        {
            [0 0.9 color rgb 0.13 color rgb 0.05]
            [0.9 1.0 color rgb 0.15 color rgb <0.10, 0.11, 0.05>]
        }
        scale 0.15
    }
    
    finish
    {
        specular 0.9 roughness 0.1
        
        reflection 
        {
            0.2
            falloff 2.0
            exponent 0.1
            metallic
        }                
    }
}

#declare SingerTexture =
texture
{
    pigment
    {
        image_map
        {
            png "body.png"
        }
        
        rotate -90*y
        scale <1, 0.245, 0.5>
        translate <0, 0, -0.1>
    }
    
    finish
    {
        specular 0.9 roughness 0.1
        
        reflection 
        {
            0.2
            falloff 2.0
            exponent 0.1
            metallic
        }                
    }
    
    normal
    {
        bozo 1
        scale 0.03
    }
}

//////////////////////////////////////////////////////////////////
// Bench

// The smallest box that contains the bench is:
// box { <-0.5, 2, 0>, <0.5, 2.1, 1> }


#ifdef (USE_BENCH)

    #local Wood1Pigment =
    pigment
    {
        wood
        scale 0.1
        turbulence 0.5
        rotate 17*x
        rotate -28*y
        
        color_map
        {
            [0.0 0.5 color rgb <0.58, 0.20, 0.12> color rgb <0.83, 0.61, 0.28>]
            [0.5 1.0 color rgb <0.83, 0.61, 0.28> color rgb <0.58, 0.20, 0.12>]
        }
    }
    
    #local Wood2Pigment =
    pigment
    {
        wood
        scale 0.05
        turbulence 0.9
        rotate -62*x
        rotate 71*y
        
        color_map
        {
            [0.0 0.5 color rgb <0.29, 0.10, 0.06> color rgb <0.42, 0.32, 0.14>]
            [0.5 1.0 color rgb <0.42, 0.32, 0.14> color rgb <0.29, 0.10, 0.06>]
        }
    }
    
    #local BenchTexture =
    texture
    {
        pigment
        {
            average
            pigment_map 
            {
                [0.5 Wood1Pigment]
                [1.0 Wood2Pigment]
            }
        }
        
        normal
        {
            wrinkles 0.6
            turbulence 0.3
            scale 0.3
        }
        
        finish {
            ambient 0.0
            diffuse 0.75
            brilliance 4
        }
    }
    
    #declare BenchLayers =
    union
    {
        #local StartY = 1.93;
        
        #local Thickness = 0.02;
        object
        {
            RoundedPlate (Thickness, BenchTexture, BenchTexture)
            translate StartY*y
        }
        #local StartY = StartY + 2 * Thickness;
    
        #local Thickness = 0.05;
        object
        {
            RoundedPlate (Thickness, BenchTexture, BenchTexture)
            translate StartY*y
        }
        #local StartY = StartY + Thickness;
        
        #local Thickness = 0.02;
        object
        {
            RoundedPlate (Thickness, BenchTexture, BenchTexture)
            translate StartY*y
        }
        #local StartY = StartY + Thickness;
    
        translate <0, 0, 0.5>
    }
    
    #declare SecretBox =
        box { <-0.12, 1.98, 0.15>, <0.12, 2.05, 0.30> }

    #declare Bench =
    union
    {
        difference
        {
            object { BenchLayers }
            object { SecretBox pigment { color rgb 0 } }
            cutaway_textures
        }

        difference
        {
            object
            {
                SecretBox
                scale <1, 0.993, 1>
            }
            
            cylinder
            {
                0, y, 0.06
                scale 0.2
                translate <0, 1.98, 0.228>
            }

            texture
            {
                pigment
                {
                    color rgb 0.2
                }
                
                finish
                {
                    diffuse 0.2
                    specular 0.6
                    metallic
                    reflection { 1.3 metallic }
                }
            }
        }
    }
    
#end // USE_BENCH

#ifdef (USE_MACHINE_BODY)
    
    #local LittleWheelCenter = <0.0, 2.32, 1.0 - 0.08>;
    #local LittleWheelRadius = 0.12;
    
    #declare LittleWheel =
    union
    {
        union
        {
            difference
            {
                torus { LittleWheelRadius, 0.02 }
                torus { LittleWheelRadius * 1.03, 0.018 }
            }
            
            cylinder { 0, -0.3*y, 0.03 }
            
            texture { MachineBodyTexture }
        }
        
        // Radii
        union
        {
            #local Count = 0;
            #while (Count < 360)
                cylinder
                {
                    0,
                    LittleWheelRadius * 0.8 *
                        <cos(radians(13 + Count)), 0, sin(radians(13 + Count))>,
                    0.012
                }
                #declare Count = Count + 45;
            #end
            
            texture
            {
                pigment
                {
                    color rgb <1, 1, 0.7>
                }
                
                finish
                {
                    phong 0.7
                    phong_size 2.5
                    reflection { 0.5 metallic }
                }
            }
        }    
        
        rotate 90*x
        translate LittleWheelCenter
    }

#end // USE_BENCH

//////////////////////////////////////////////////////////////////
// Belt

#ifdef (USE_MACHINE_BODY)

    #macro Belt(Radius)
        union
        {
            object
            {
                #local Pt1 = WheelCenter + 0.99 *
                    WheelRadius * <cos (radians(10)), sin (radians(10)), 0>;
                #local Pt2 = LittleWheelCenter + 0.95 *
                    LittleWheelRadius * <cos (radians(10)), sin (radians(10)), 0>;
                
                cylinder
                {
                    Pt1, Pt2, Radius
                }
            }
            
            object
            {
                #local Pt1 = WheelCenter + 0.99 *
                    WheelRadius * <cos (radians(180 - 10)), sin (radians(180 - 10)), 0>;
                #local Pt2 = LittleWheelCenter + 0.95 *
                    LittleWheelRadius * <cos (radians(180 - 10)), sin (radians(180 - 10)), 0>;
        
                cylinder
                {
                    Pt1, Pt2, Radius
                }
            }
        }
        
    #end
        
#end // USE_MACHINE_BODY

//////////////////////////////////////////////////////////////////
// The Needle Box

#declare BoxButton =
union
{
        // A button
        cylinder { 0, -0.01*z, 0.01 }
        cylinder { -0.01*z, -0.015*z, 0.022 }
}

#include "needle_base.inc"

#declare NeedleBox =
union
{
    union
    {
        height_field
        {
            png "needlebox.png"
            smooth
            
            rotate -90*x
            scale <0.15, 0.19, 0.002>
            translate <-0.075, -0.06 - 0.002, -0.025>
        }
        
        box { <-0.075, -0.06, -0.025>, <0.075, 0.13, 0.05> }
        box { <-0.065, -0.13, -0.015>, <0.065, -0.06, 0.04> }
        box { <-0.04, -0.16, -0.005>, <0.04, -0.13, 0.02> }

        object { BoxButton translate <0, -0.05, 0> }
        object { BoxButton scale 0.65 translate <0, -0.03, 0> }
                
        translate <0, 2.27, 0.228>
        
        texture { MachineBodyTexture }
    }
    
    union
    {
        // The needle
        cylinder
        {
            0, y, 0.020
            scale 0.2
            translate <0, 2.06, 0.238>
        }
        
        cylinder
        {
            0, y, 0.025
            scale 0.2
            translate <0.02, 2.065, 0.240>
        }

        object
        {
            NeedleBase
            rotate 90*y
            scale <0.08, 0.1, 0.08>
            translate <0, 2.065, 0.238>
        }
        
        cylinder
        {
            0, 0.4*y, 0.020
            scale 0.2
            translate <0.0, 2.35, 0.238>
        }

        cylinder
        {
            0, 0.6*y, 0.020
            scale 0.2
            translate <0.04, 2.35, 0.238>
        }
        
        texture
        {
            pigment { color rgb 1 }
            finish
            {
                specular 0.7 roughness 0.2
                reflection { 0.4 metallic }
            }
        }
    }
}


//////////////////////////////////////////////////////////////////
// A Reel of Thread

#declare Reel =
union
{
    /*
    cylinder
    {
        -0.5*y, 0.5*y, 0.3
        
        texture
        {
            pigment
            {
                image_map
                {
                    jpeg "reed.jpg"
                    map_type 2 // Cylindrical wrapping
                }
                translate -0.5*y
            }

            finish
            {
                diffuse 1.6
            }
        }
    }
    */

    isosurface
    {
        function { pow(x, 2) + pow(z, 2) - pow(0.3 + 0.3*(abs(sin(2*pi*y*30)) - 1), 2) }
            
        contained_by
        {
            box { <-0.35, -0.5, -0.35>, <0.35, 0.5, 0.35> }
        }
        
        max_gradient 22
        
        pigment { color rgb 1.2 }
    }

    cylinder
    {
        -0.6*y, 0.6*y, 0.1
        pigment { color rgb <214, 186, 156> / 255 }
    }
}

#declare Thread =
sphere_sweep
{
    b_spline
    4,
    
    <0, 0.6, 0.3>, 0.002
    <0, 0.12, 0>, 0.002
    <0, 0.05, -1>, 0.002
    <0, 0.15, -1.2> ,0.002
    
    pigment { color rgb 1.75 }
}


//////////////////////////////////////////////////////////////////
// The Thimble

#include "thimble.inc"

#declare ThimbleTexture =
texture
{
    pigment { color rgb <0.7, 0.74, 0.12> * 1.25 }
    normal { leopard 15 scale 0.001 }
    finish { specular 0.7 metallic }
}


//////////////////////////////////////////////////////////////////
// The Sewing-machine

#ifdef (USE_MACHINE_BODY)
    
    #include "sew-body.inc"

#end

//////////////////////////////////////////////////////////////////
// The Sewing-machine

#local Pos = <-0.05, 1.2, -1.3>;
#declare MachineLight =
light_source
{
    Pos
    color 0.4
    fade_power 1.5
    fade_distance 1.0
    shadowless
}

#local MachineBelt =
object { Belt (0.01) }

#declare SewingMachine =
union
{
/*    light_group
    {
        light_source { MachineLight }
        object { Base }
        global_lights on
    }
*/
    object { Base }    

    #ifdef (USE_BENCH)
        union
        {
            object
            {
                CreateWire ("scissor.png")
                
                scale <0.32, 0.4, 0.725>*0.4
                rotate 78*y
                translate <0.40, 2.07, 0.1>
                texture
                {
                    pigment { color rgb 0.2 }
                    finish
                    {
                        specular 0.3 metallic
                        reflection { 0.1 metallic }
                    }                    
                }                
            }

            object
            {
                Thimble
                scale <0.054, 0.054, 0.045>*0.7
                translate <0.30, 2.043, 0.3>
                texture { ThimbleTexture }
            }
            
            box
            {
                <-0.45, 1.8, 0.1>, <0.45, 1.93, 0.3>
                pigment { color rgb <0.05, 0.06, 0.14> }
            }

            #ifdef (USE_MACHINE_BODY)
            difference { 
            #end
    
            object { Bench scale <1.05, 1, 1.05> }
                    
            #ifdef (USE_MACHINE_BODY)
                object { Belt (0.02) pigment { color rgb 0 } }
                
                cutaway_textures
            }
            #end
        }
    #end

    #ifdef (USE_MACHINE_BODY)
        union
        {
            object { MachineBelt }
            
            difference
            {
                torus { WheelRadius, 0.01 rotate 90*x translate WheelCenter }
                box { min_extent (MachineBelt) + 0.03*y, max_extent (MachineBelt) }
            }
            
            difference
            {
                torus { LittleWheelRadius, 0.01 rotate 90*x translate LittleWheelCenter }
                box { min_extent (MachineBelt) - 0.03*y, max_extent (MachineBelt) }
            }

            texture
            {
                pigment { color rgb <0.1, 0.1, 0.12> }
                
                finish { specular 0.6 roughness 0.1 metallic }
            }
        }
    #end

    object { NeedleBox }
    
    union
    {
        object { Reel scale <0.14, 0.14, 0.12> rotate 2*x }
        object { Thread scale <1, 1, 0.64> translate <0, -0.15, 0.08> }
        translate <0, 2.49, 0.7>
    }

    #ifdef (USE_MACHINE_BODY)    
    
        object
        {
            SewBody
            rotate -90*x
            rotate 90*y
            scale <0.15, 0.2, 0.2>
            translate <0, 2.3, 0.45>
            
            texture { SingerTexture }
        }
        
        union
        {
            object
            {
                LittleWheel
            }
            
            box
            {
                <-0.15, 2.03, 0.60>, <0.15, 2.05, 0.85>
            }
            
            texture { MachineBodyTexture }        
        }
        
    #end
}
