// Persistence of Vision Ray Tracer Scene Description File
// File: walls.pov
// Vers: 3.5
// Desc: Walls, ceiling and parquet
// Date: 2003/05/10
// Auth: Maurizio Tomasi

#include "arrays.inc"
#include "rand.inc"
#include "shapes.inc"

#include "new-wood.inc"
#include "banister.inc"
#include "big_banister.inc"

// ---------------------------------------------
// Parquet textures

#local ParquetSeed = seed (15);

#macro CreateParquetText1 ()

    texture 
    { 
        Rand_Array_Item (Wood1, ParquetSeed)
        finish { WoodFinish1 }

        rotate RRand (-4, 4, ParquetSeed)*y
    }

#end

#macro CreateParquetText2 ()

    texture
    {
        Rand_Array_Item (Wood2, ParquetSeed)
        finish { WoodFinish1 }

        rotate 90*y
        rotate RRand (-4, 4, ParquetSeed)*y
    }

#end


#local WallpaperNormal =
normal
{
    granite 0.8
    scale 0.05
}

#local TransparentText =
pigment 
{ 
    color rgb 0 transmit 1 
}

#local BorderLine =
pigment 
{ 
    color rgb <0.05, 0.01, 0.01> transmit 0 
}

#local MotiveFn =
function
{
    (1+5*cos(50*x)*cos(50*x))/(1+2*cos(100*x)*cos(100*x))
}

#local BaseMotive =
pigment 
{ 
    function { MotiveFn (x, y / 0.1220, z) }
    
    color_map
    {
        [0.00 color rgb <0.00, 0.20, 0.00>]
        [0.40 color rgb <0.00, 0.20, 0.00>]
        [0.40 color rgb <0.00, 0.07, 0.00>]
        [1.00 color rgb <0.20, 0.07, 0.05>]
    }
}

#local WallpaperTexture =
texture 
{ 
    pigment
    {
        image_map
        {
            png "wallpaper.png"
        }
        scale 0.15
    }

    normal { WallpaperNormal }    
}
texture
{
    // Vertical stripes of dirt
    pigment
    {
        agate
        color_map
        {
            [0.50 color rgb <0.3, 0.3, 0.1> transmit 1.0]
            [0.70 color rgb <0.3, 0.3, 0.1> transmit 0.5]
            [0.90 color rgb <0.3, 0.3, 0.1> transmit 1.0]
        }
        
        scale <0.3, 1.0, 0.3> * 0.25
    }
}
texture
{
    pigment
    {
        gradient y
        pigment_map
        {
            [0.1620 BaseMotive ]
            [0.1620 BorderLine ]
            [0.1680 BorderLine ]
            [0.1680 TransparentText ]
        }
        
        scale 8
    }
    
    normal { WallpaperNormal }
}

// ---------------------------------------------
// Walls


plane 
{
    // Ground
    y, -4
    pigment { color rgb <0.7,0.5,0.3> }
}


box
{
    // Roof
    
    <-4, 6.5, -8>, <3, 9, 15>
    CreateParquetText1 ()
}

#local WallTexture = texture { pigment { color rgb 0.7 } }

/*
   z
   ^
   |
   |  +-+------------------+
   |  | |         8        |
 z4+  | +----------------+-+
   |  | |                | |
   |  | |        7       | |
   |  | |                | |
 z3+  | +--------+-+-|9|-+ +
   |  | |        |1|     | |
   |  | |    1   |0|     | |
   |  | |        | |     | |
 z2+  |4+--+-----+-+     | |
   |  | |  |       |     |5|
   |  | |  |       |     | |
   |  | |11|       |  3  | |
   |  | |  |       |     | |
   |  | |  |       |     | |
 z1+  | +--+-------+     | |
   |  | |          |     | |
   |  | |    2     |     | |
   |  | |          |     | |
 z0+  +-+----------+-----+-+
   |    |         6        |
   |    +------------------+
   |
   +----+----------+-----+-+--> x
        x0         x1    x2
 */

#local x0 = -3.75;
#local x1 = 0.0;
#local x2 = 3.0; // it was 2.75

#local z0 = -7.0;
#local z1 = -3.0;
#local z2 = 3.0;
#local z3 = 7.0;
#local z4 = 14.0;

#local DoorHeight = 2.5;
#local DoorWidth = abs (x2 - x1) - 1.50;

box
{
    // 1
    <x0, -4, z2>, <x1 - 0.01, 8, z3>
    texture 
    { 
        WallpaperTexture 
        translate -1.5*y
    }
}

box 
{
    // 2
    <x0, -4, z0>, <x1, 8, z1>
    texture 
    { 
        WallpaperTexture 
        rotate 90*y
    }
}

#ifdef (USE_PARQUET)
    union
    {
        intersection
        {
            // 3
            box 
            {
                <x1, -0.5, z0>, <x2, 0.5, z3> 
                pigment { color rgb 0 }
            }
        
            union
            {
            #include "parquet.inc"
            
                rotate -45*y
                scale <0.16, 0.05, 0.16>
                translate <2.95, -0.05, -3.5>
            }
        }
        
        box 
        { 
            <x1, -0.5, z0>, <x2, -0.1, z3> 
            pigment { color rgb 0 } 
        }
    }
#else
    box
    {
        // 3
        <x1, -0.5, z0>, <x2, 0, z3>
        
        CreateParquetText1 ()
    }
#end

difference
{
    // 4
    
    box
    {
        <x0 - 0.5, -4, z0>, <x0, 8, z4>
        texture 
        { 
            WallpaperTexture 
            rotate 90*y
            translate -1.5*y
        }
    }
    
    object
    {
        box
        {
            <x0 - 1, -0.5, -2>, <x0 + 1, 1.5, 2>
        }

        /*
        box
        {
            <x0 - 1, 1.5, 8.5>, <x0 + 1, 5, 12.5>
        }
        */
    }
        
    cutaway_textures
}

box
{
    // 5
    <x2, -4, z0>, <x2 + 0.5, 8, z4 + 1.0>
    texture 
    { 
        WallpaperTexture 
        rotate 90*y
    }
}

box
{
    // 6
    <x1, -4, z0 - 1>, <x2, 8, z0>
    texture { WallpaperTexture }
}

box
{
    // 7
    
    <x0, -0.5, z3>, <x2, 0, z4>
    
    CreateParquetText1 ()
}

box
{
    // 8
    
    <x0, -4, z4>, <x2, 8, z4 + 1>
    texture { WallpaperTexture }
}

difference
{
    // 9
    
    box
    {
        <x0, 0, z3 - 0.2>, <x2, 8, z3>
        texture { WallpaperTexture }
    }
    
    box
    {
        <(x1 + x2)/2 - DoorWidth/2, -0.5, 6>, 
        <(x1 + x2)/2 + DoorWidth/2, DoorHeight, 8>
    }

    cutaway_textures
}

box
{
    // 10
    <x1 - 0.5, 0, z2 + 0.01>, <x1, 8, z3>
    texture 
    { 
        WallpaperTexture 
        rotate 90*y
    }
}

box
{
    // 11
    <x0, -2.0, z1>, <x1, -1.5, z2>
    CreateParquetText1 ()
}


// ---------------------------------------------
// Door jamb

#local JambThickness = 0.25;
#local StripeRadius = 0.015;

#local JambTexture =
    texture 
    { 
        pigment
        {
            marble
            warp { turbulence 2 }
            
            color_map
            {
                [0.4 color rgb <0.60, 0.60, 0.65> * 1.5]
                [1.0 color rgb <0.55, 0.50, 0.55> * 1.2]
            }
            
            scale 0.2
        }
    }

#local JambVerticalPart =
union
{
    // Column
    difference
    {
        box
        {
            JambThickness/2 * <-1, -0.1, -1>,
            JambThickness/2 * < 1,  0.0,  1> + DoorHeight*y
        }
        
        union
        {
            #local Count = -JambThickness/2 * 0.9;
            
            #while (Count < JambThickness/2 * 0.9)
                object
                {
                    Round_Cylinder_Union (JambThickness/2 * <0, 0.0, -1> + 0.2*y,
                                          JambThickness/2 * <0, 0.0, -1> + (DoorHeight - 0.1)*y,
                                          StripeRadius, StripeRadius * 3/5)
                    
                    translate Count * 0.8 * x
                }
                
                #declare Count = Count + StripeRadius * 4.5;
            #end
        }
    }
    
    // Base
    difference
    {
        prism
        {
            quadratic_spline
            -1, 1, 8,
            
            < 1.0, 1.0>,
            < 1.0, 0.0>,
            <-2.0, 0.0>,
            <-2.0, 0.3>,
            <-1.2, 0.8>,
            <-1.0, 1.0>,
            < 1.0, 1.0>,
            < 1.0, 0.0>
        }
        
        union
        {
            box
            {
                < 1.0, -1.1, 0.0>,
                < 1.5,  1.1, 1.0>
            }
    
            box
            {
                <-2.5, -1.1, 1.0>,
                < 1.5,  1.1, 1.5>
            }
    
            box
            {
                <-2.5, -1.1, 0.995>,
                <-1.0,  1.1, 1.100>
            }
    
            box
            {
                <-2.5, -1.1, -0.1>,
                <-2.0,  1.1,  1.1>
            }
    
            box
            {
                <-2.5, -1.1, -0.5>,
                < 1.5,  1.1,  0.0>
            }
        }
                
        rotate -90*x
        rotate -90*y
        scale <JambThickness/2, 0.2, JambThickness/2>
    }

    texture { JambTexture }
}

#local TriangleHeight = 0.6;
#local TriangleVertexes = array[3]
{
    <           0, 0>,
    <-DoorWidth/2 - JambThickness/2, 0>,
    <           0, TriangleHeight>
}

#local HalfTriangle =
union
{
    intersection
    {
        prism
        {
            linear_spline
            0.0, 0.1, 4,
     
            TriangleVertexes[0],
            TriangleVertexes[1],
            TriangleVertexes[2],
            TriangleVertexes[0]       
            
            rotate -90*x
        }
        
        height_field
        {
            jpeg "triangle.jpg"
            
            rotate -90*x
            scale <TriangleVertexes[1].x, TriangleHeight, 0.03>
        }
        
        translate -0.01*z
    }
    
    #local Thickness = array[5] { 0.03, 0.02, 0.03, 0.01, 0.02 };
    #local Depth = array[5] { 1.1, 0.7, 0.9, 0.7, 0.4 };
    #local M = abs(TriangleVertexes[2].y / TriangleVertexes[1].x);
    #local InvPerpM = (sqrt(1 + M*M) - 1) / M;
    #local Angle = 180/pi*atan (M);

    #local Count = 0;
    #local CurThickness = 0.0;
    #while (Count < dimension_size (Thickness, 1))

        box
        {
            <TriangleVertexes[1].x + (CurThickness + Thickness[Count]/2)/ InvPerpM, 
                TriangleVertexes[0].y + Thickness[Count], 0>
            <TriangleVertexes[0].x, TriangleVertexes[0].y, -Depth[Count] * JambThickness/2>
            
            translate CurThickness*y
        }

        box
        {
            <0, 0, -JambThickness/2 * Depth[Count]>,
            
            <sqrt(pow (-TriangleVertexes[1].x - CurThickness / InvPerpM, 2.0)
                  + pow (TriangleHeight - 2 * CurThickness, 2.0)), -Thickness[Count], 0>
            
            rotate Angle*z
            translate <TriangleVertexes[1].x, TriangleVertexes[1].y, 0>
            translate <CurThickness / InvPerpM, CurThickness, 0>
        }
        
        #declare CurThickness = CurThickness + Thickness[Count];
        #declare Count = Count + 1;
    #end

    difference
    {        
        box
        {
            <TriangleVertexes[1].x, 0.0, 0>
            <TriangleVertexes[0].x, -0.1, -JambThickness/2>
        }

        box
        {
            <TriangleVertexes[1].x + 0.05, -0.025, -JambThickness/2 * 0.75>
            <                        0.00, -0.075, -JambThickness/2 * 1.25>
        }
    }
        
    texture { JambTexture }
    translate <0, DoorHeight + 0.1, -0.1>
}

#local HalfJamb =
union
{
    object 
    {
        JambVerticalPart
        translate -DoorWidth/2 * x
    }
    
    object { HalfTriangle }
}
        
union
{
    object { HalfJamb }
    object { HalfJamb scale <-1, 1, 1> }
    
    translate <(x1 + x2)/2, 0, z3 - JambThickness/2>
}


// ---------------------------------------------
// Small portraits near the door

#macro CreatePortrait (PosY, ImageName)
union
{
    // Frame
    height_field
    {
        png "oval_frame.png"
        smooth
        water_level 0.01
        
        rotate -90*x
        
        texture
        {
            pigment { color rgb <0.4, 0.2, 0.0> }
            
            finish { specular 0.5 roughness 0.08 }
        }
    }
    
    disc
    {
        <0.5, 0.5, 0.0>, -z, 0.4
        
        pigment 
        { 
            image_map
            {
                jpeg ImageName
                interpolate 2
            }
        }
    }
    
    scale <1.0, 624/416, 0.1> * 0.2
    translate <x2 - 0.45, PosY, z3 - 0.2>
}
#end

CreatePortrait (1.5, "painting2.jpg")

CreatePortrait (2.0, "painting3.jpg")


// ---------------------------------------------
// Banisters

#ifdef (USE_BANISTERS)

    // If BigFlag != 0 then create a big column
    #macro Column (BasePoint, Height, Radius, BigFlag)
        union
        {
            torus
            {
                Radius/2, Radius/10
                translate BasePoint + (Height/5 + Radius/10)*y
            }
            
            box
            {
               <-Radius, Height,    -Radius>,
               < Radius, 4/5*Height, Radius>
               
               translate BasePoint
            }
            
            torus
            {
                Radius/2, Radius/10
                translate BasePoint + (4/5*Height - Radius/10)*y
            }

            #local SORHeight = Height - 1/5*Height - 4/10*Radius;
            #local SORBaseY = 2/10*Radius;

            object
            {
                #if (BigFlag = 0)
                    BigBanisterColumn
                    scale <1/0.4, 1/6.2, 1/0.4>

                #else
                    BanisterColumn
                    scale <1/0.631, 1/7.808, 1/0.631>
                #end
                
                scale <Radius, SORHeight, Radius>
                translate BasePoint + SORBaseY*y
            }
        }
    #end

    #local BanistersTexture =
    texture 
    { 
        pigment 
        { 
            granite
            color_map
            {
                [0.00 color rgb <0.40, 0.35, 0.35> * 1.2]
                [0.04 color rgb <0.40, 0.10, 0.10> * 1.2]
                [0.08 color rgb <0.40, 0.35, 0.35> * 1.2]
                [0.12 color rgb 0.06 * 1.2]
                [0.60 color rgb 0.12 * 1.2]
                [0.80 color rgb 0.12 * 1.2]
                [1.00 color rgb 0.06 * 1.2]
            }
            
            scale 0.4
        } 
        
        normal
        {
            wrinkles 0.15
            scale 0.01
        }
        
        finish
        {
            specular 0.5
            roughness 0.04
            
            // reflection 0.15
        }
    }

    #local ColumnRadius = 0.05;

    #local Banisters =
    union
    {
        union
        {
            // Column near the wall
            object
            {
                Round_Box_Union (<x1 + 0.07, -1, z1 - 0.08>,
                                 <x1 + 0.13,  4, z1 + 0.08>, 0.02)
            }
            object
            {
                Round_Box_Union (<x1 - 0.17, -1, z1 - 0.06>,
                                 <x1 + 0.17,  4, z1 + 0.06>, 0.01)
            }
            
            // Handrails
            object
            {
                Round_Box_Union (<x1 - 0.15, 1.00, z1>,
                                 <x1 + 0.15, 1.10, -1>, 0.02)
            }
        
            object
            {
                Round_Box_Union (<x1 - 0.13, 1.00, z1>,
                                 <x1 + 0.13, 1.15, -1.1>, 0.02)
            }
            
            // Base 
            object
            {
                Round_Box_Union (<x1 - 0.15, 0.00, z1>,
                                 <x1 + 0.15, 0.15, -1>, 0.02)
            }
        
            object
            {
                Round_Box_Union (<x1 - 0.13, 0.00, z1>,
                                 <x1 + 0.13, 0.20, -1>, 0.02)
            }
            
            // Knob base
            box 
            { 
                <-0.5, 0, -0.5>, <0.5, 0.25, 0.5> 
                scale 0.1/0.5
                translate <x1, 1.15, -1.25>
            }
            
            // Columns on the passage
            
            #local CurZ = -1 - 0.12;
            #local Count = 0;
            #while (CurZ > z1)
            
                object
                {
                    Column (<x1, 0.20, CurZ>, 0.8, ColumnRadius, Count)
                }
                
                #declare CurZ = CurZ - 0.5;
                #declare Count = Count + 1;
            #end
            
            texture { BanistersTexture }
        }

        // Knob        
        sor
        {
            6,
            <0.2,-0.05>,
            <0.2, 0.25>,
            <0.5, 0.40>,
            <0.5, 0.60>,
            <0.2, 0.70>,
            <0.1, 0.71>
            
            scale 0.1/0.5
            translate <x1, 1.15, -1.25>
        }
    }
    
    
        
    #ifdef (USE_STAIRWAY)
        #local StepWidth = 0.2;
        #local StepHeight = 0.08;
        #local NumOfSteps = 10;
        #local XShift = -0.08;
        
        union
        {
            #local Count = 1;
            #while (Count < NumOfSteps)
                // Step
                box
                {
                    <-Count * StepWidth + XShift - 0.1,
                     -Count * StepHeight + 0.01,
                     -1.0>,
                     
                    <-Count * StepWidth + XShift + 0.1,
                     -(Count + 1) * StepHeight + 0.01, 
                     1.0>
                }
                
                Column (<-Count * StepWidth + XShift,
                         -Count * StepHeight + 0.15,
                         -1 - 0.14>,
                        0.9, ColumnRadius, 1)
                        
                Column (<-Count * StepWidth + XShift, 
                         -Count * StepHeight + 0.15,
                         1 + 0.14>,
                        0.9, ColumnRadius, 1)
                
                #declare Count = Count + 1;
            #end
            texture { BanistersTexture }
        }
        
        // Handrails
        #local Transf =
        transform
        {
            matrix
            <
            1.0, StepHeight / StepWidth, 0.0,
            0.0, 1.0, 0.0, 
            0.0, 0.0, 1.0,
            0.0, 0.0, 0.0  // translation
            >
        }

        #local Handrail =
        union
        {
            object
            {
                Round_Box_Union (
                    <-Count * NumOfSteps - 0.1, -0.02, -1 - 0.15 - 0.12>,
                    <                     -0.1,  0.10, -1 - 0.15 + 0.12>, 0.06)
                
                transform { Transf }
            }
        
            object
            {
                Round_Box_Union (
                    <-Count * NumOfSteps - 0.1,  0.00, -1 - 0.15 - 0.08>,
                    <                     -0.1,  0.20, -1 - 0.15 + 0.08>, 0.06)
                
                transform { Transf }
            }
        }
        
        union
        {
            object { Handrail }
            object { Handrail translate 0.95*y }
            
            object { Handrail scale <1, 1, -1> }
            object 
            { 
                Handrail 
                scale <1, 1, -1> 
                translate 0.95*y 
            }
        
            pigment { color rgb 0.1 }
        }
        
    #end // USE_STAIRWAY
    
    object
    { 
        Banisters
        translate -0.08*x
        texture { BanistersTexture }
    }
    
    object 
    { 
        Banisters 
        translate -0.08*x
        scale <1, 1, -1> 
        
        texture { BanistersTexture rotate <12, -5, 7> }
    }
    
    box
    {
        <x1 - 0.15, -0.1, z1>, <x1 + 0.15, 0.01, z2>
        
        CreateParquetText1 ()
        
        translate -0.08*x
    }

#end // USE_BANISTERS
