#include "rand.inc"

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

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

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

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

#ifdef (USE_STRAW)

    #include "straw.inc"
    
#end

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

#local USE_HORSE = 1; // Include the horse

#local WheelThickness = 0.15;
#local AxleRadius = 0.075;
#local StickHeight = 1.1;
#local CartWidth = 1.5;

#local LightFactor = 0.9;
#local SpotColor = <0.2, 0.1, 0> * LightFactor;

#local TexSeed = seed (15);

// Wood texture
#local WoodTexture =
texture
{
    pigment
    {
        wood
        color_map
        {
            [0.6 color rgb <0.77, 0.62, 0.4> * LightFactor]
            [0.9 color rgb <0.65, 0.51, 0.1> * LightFactor]
        }
        
        warp { turbulence 0.3 }
    }
    
    normal { wrinkles 0.3 scale 0.5 }
    
    scale 0.1
}
texture
{
    pigment
    {
        bozo
        color_map
        {
            [0.7 color rgb SpotColor transmit 1]
            [0.8 color rgb SpotColor transmit 0.3]
        }
    }
    
    scale 0.05
}


#ifdef (USE_HORSE)

    #declare poseray_material= 
    texture
    {
        pigment
        {
            color rgb <0.729412,0.419608,0.270588> * LightFactor
        }
        finish { ambient 0 reflection {0} }
    }
    
    #include "horse.inc"

#end


// Wheel radii
#local RadiusSet =
union
{
    #local RadCount = 0;
    #local RadiusNum = 14;
    #while (RadCount < RadiusNum)
        cylinder
        {
            <0, 0, 0>,
            0.95 * <cos (2 * pi * RadCount / RadiusNum), sin (2 * pi * RadCount / RadiusNum), 0>,
            WheelThickness / 4
    
            texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
        }
        #declare RadCount = RadCount + 1;
    #end
}

// Cart wheel
#local Wheel =
union
{
    difference
    {
        cylinder
        {
            <0, 1, -WheelThickness/2>, <0, 1, WheelThickness/2>, 1
        }
        
        cylinder
        {
            <0, 1, -WheelThickness/2 * 1.01>, <0, 1, WheelThickness/2 * 1.01>, 0.98
        }
        
        texture
        {
            finish { specular 0.3 metallic roughness 0.05 reflection { 0.4 metallic } }

            pigment
            {
                color rgb <0.3, 0.3, 0.33> * LightFactor
            }
            
            normal { wrinkles 0.6 scale 0.05 }
        }
    }

    difference
    {
        cylinder
        {
            <0, 1, -WheelThickness/2 * 0.95>, <0, 1, WheelThickness/2 * 0.95>, 0.99
        }
        
        cylinder
        {
            <0, 1, -WheelThickness/2>, <0, 1, WheelThickness/2>, 0.9
        }

        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
    
    object { RadiusSet rotate 18*z translate 1*y }
    
    union
    {
        cone
        {
            <0, 1, 0>, 0.25, <0, 1, 0.1>, 0.15
        }

        cone
        {
            <0, 1, 0>, 0.25, <0, 1, -0.1>, 0.15
        }

        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
}

// Cart axle (with rounded caps)
#local Axle =
union
{
    cylinder
    {
        <0, 1, CartWidth/2 * 1.3>, <0, 1, -CartWidth/2 * 1.3>, AxleRadius
    }
    
    sphere
    {
        <0, 1, CartWidth/2 * 1.3>, AxleRadius
    }
    
    sphere
    {
        <0, 1, -CartWidth/2 * 1.3>, AxleRadius
    }
}


// Vertical sticks on the cart
#local Sticks =
union
{
    #local i = 0;
    #local StickCount = 4;
    #while (i < StickCount)
        #local xPos = (1.3 + 0.9) * i / (StickCount - 1);
        
        cylinder { <xPos, 0, 0>, <xPos, StickHeight, 0>, 0.03 }
        #declare i = i + 1;
    #end
}

// Boards on the sides of the cart
#local Boards =
union
{
    #local i = 0;
    #local BoardCount = 4;
    #while (i < BoardCount)
        box
        {
            <0, i / BoardCount, 0>,
            <1, 0.98 * (i + 1) / BoardCount, 0>
            texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
        }
        #declare i = i + 1;
    #end
}

#local CartBorder = (CartWidth - WheelThickness) / 2 * 0.9;

// Whole set of boards (four sides)
#local BoardSet =
union
{
    object
    {
        Boards
        scale <0.9 + 1.3, 0.9, 0.05>
        translate <-0.9, 1, CartBorder - 0.05>
    }
    
    object
    {
        Boards
        scale <0.9 + 1.3, 0.9, 0.05>
        translate <-0.9, 1, -CartBorder + 0.05>
    }
    
    object
    {
        Boards
        rotate 90*y
        scale <0.05, 0.9, (CartBorder - 0.05) * 2>
        translate <-0.9, 1, CartBorder - 0.05>
    }
    
    object
    {
        Boards
        rotate 90*y
        scale <0.05, 0.9, (CartBorder - 0.05) * 2>
        translate <1.3, 1, CartBorder - 0.05>
    }
}


// Straw on the cart

#ifdef (USE_STRAW)
    #local Straw1 =
    union
    {
        box
        {
            <-0.8, 0.1, 0.1>, <1.1, 0.8, 0.2>
            
            pigment
            {
                wrinkles
                color_map
                {
                    [0.33 color rgb StrawCol1]
                    [0.67 color rgb StrawCol2]
                }
                scale 0.005
            }
        }
        
        object
        {
            CreateStraw (<-0.9, 0, 0>, <1.2, 0.9, 0.1>, 0.01, 0.2, 1500, 15)
        }
    }
    
    #local Straw2 =
    union
    {
        box
        {
            <-CartBorder + 0.1, 0.1, 0.1>, <CartBorder - 0.1, 0.8, 0.2>
            
            pigment
            {
                wrinkles
                color_map
                {
                    [0.33 color rgb StrawCol1]
                    [0.67 color rgb StrawCol2]
                }
                scale 0.005
            }
        }
        
        object
        {
            CreateStraw (<-CartBorder, 0, 0>, <CartBorder, 0.9, 0.1>, 0.01, 0.2, 1000, 15)
        }
        
        rotate 90*y
    }
#end // USE_STRAW


// A cart
#declare Cart =
union
{
    object
    {
        Wheel
        translate <0, 0, CartWidth / 2>
    }
    
    object
    {
        Wheel rotate 180*y translate <0, 0, -CartWidth / 2>
    }
    
    object
    {
        Axle
        texture { WoodTexture scale <0.05, 0.05, 1>}
    }
    
    box
    {
        <-1.3, 0.95, -CartBorder>,
        < 1.3, 1.10, CartBorder>
        texture { WoodTexture rotate 91*z }
    }
    
    object { BoardSet }

    object
    {
        Sticks
        translate <-0.9, 1, CartBorder>
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }

    object
    {
        Sticks
        translate <-0.9, 1, -CartBorder>
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
    
    cylinder
    {
        <-1, 1 + StickHeight, CartBorder>,
        <1.4, 1 + StickHeight, CartBorder>, 0.05
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
    
    cylinder
    {
        <-1, 1 + StickHeight, -CartBorder>,
        <1.4, 1 + StickHeight, -CartBorder>, 0.05
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }

    #ifdef (USE_STRAW)
        
        object { Straw1 rotate 10*x translate <0, 1.8, -CartBorder + 0.1> }
        object { Straw2 rotate -10*z translate <-0.9, 1.8, 0> }
    
    #end
    
    // Seat
    box
    {
        <-1.2, 1.5, -CartBorder>,
        <-0.9, 1.6, CartBorder>
        texture { WoodTexture }
    }
    
    
    #ifdef (USE_HORSE)

        object
        {
            horse
            scale 18
            translate 1.35*y
            rotate 90*y
            translate <-3, 0, 0.25>
        }
    
    #end
    
        
    #local CylStart = <-1.1, 1, 0>;
    #local CylEnd = <-3, 1.6, 0>;
    
    cylinder
    {
        CylStart - z * (CartBorder - 0.05), CylEnd - z * (CartBorder - 0.05), 0.05
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
    
    cylinder
    {
        CylStart + z * (CartBorder - 0.05), CylEnd + z * (CartBorder - 0.05), 0.05
        texture { WoodTexture rotate 360 * (rand (TexSeed) * y + rand (TexSeed) * x) }
    }
    
    // The pack-saddle
    union
    {
        torus
        {
            0.45, 0.02
            scale <1, 4, 1>
            rotate 45*z
    
            scale <1, 1, 0.85>
            translate <-3.6, 1.8, 0>
        }

        torus    
        {
            0.55, 0.03
            scale <0.9, 3, 1>
            rotate 90*z
    
            scale <1, 1, 0.85>
            translate <-2.9, 1.45, 0>
        }

        #local i = 0;
        #while (i < 3)
            cylinder
            {
                CylStart - z * (CartBorder - 0.05) + (CylEnd - CylStart) * (0.9 + i * 0.03),
                CylStart - z * (CartBorder - 0.05) + (CylEnd - CylStart) * (0.9 + (i + 0.9) * 0.03),
                0.055
            }
            #declare i = i + 1;
        #end
                
        pigment { color rgb <0.4, 0.35, 0.35> * LightFactor }
    }
}


union
{
    #local i = 0;
    #local HairRadius = 0.002;
    #local HairSeed = seed (4);
    #local HairColor1 = <0.22, 0.20, 0.02>;
    #local HairColor2 = <0.30, 0.25, 0.05>;
    
    #while (i < 200)
        sphere_sweep
        {
            cubic_spline
            6,
            
            <-0.2, -0.20, 0>, HairRadius
            < 0.0,  0.00, 0>, HairRadius
            < 0.1, RRand (0.02, 0.10, HairSeed), 0>, HairRadius
            < 0.2, RRand (-0.35, -0.25, HairSeed), 0>, HairRadius
            < 0.2, RRand (-1.15, -1.05, HairSeed), 0>, HairRadius
            < 0.3, RRand (-1.20, -1.10, HairSeed), 0>, HairRadius
            
            texture
            {
                pigment
                {
                    color rgb HairColor1 + (HairColor2 - HairColor1) * rand (HairSeed)
                }
                
                finish
                {
                    specular 0.1 roughness 0.7
                }
            }
                        
            rotate y*RRand(-35, 35, HairSeed)
            translate <
                RRand(-0.05, 0.05, HairSeed),
                RRand(-0.05, 0.05, HairSeed),
                RRand(-0.1, 0.1, HairSeed)>
        }
        
        #declare i = i + 1;
    #end
    
    translate <-1.9, 1.9, 0>
}

/*
object
{
    Cart
//    rotate -30*y
}
*/