#version 3.7;



global_settings{ 

  assumed_gamma 1.0

  max_trace_level 200

} 

background { colour rgb 0 }



#include "colors.inc"

#include "textures.inc"

#include "golds.inc"

#include "woods.inc"



#declare CamFactor = frame_number/100;

#declare CamFactor = 1000;

#declare CamAngle = frame_number;

#declare Cam0Location =  < 0.0 , 1*(1+CamFactor) ,0>;



#declare Cam0Location = vrotate(Cam0Location, <0, 0, CamAngle>);

#declare Cam0Location = vrotate(Cam0Location, <0, CamAngle, 0>) + (<-3, 3, -3>*(1+CamFactor));







#declare Cam1Location =  <8.0 , 1.5 ,5>;



/*

  Declare the illusion camera pointing along the z-axis

*/

#declare UseIllusionCamera = 1;

#if (UseIllusionCamera)

  camera {  

        location Cam0Location

        look_at   <0.0 , 0.0 , 0.0>

        direction z * (1+CamFactor)

        right image_width / image_height * x

    }

#else

// Use this camera to see how the wedges work.

camera {

        location Cam1Location

        look_at   0 // Cam0Location / 2

        direction z * 1

        right image_width / image_height * x

    }

#end





light_source{vrotate(<1500,1500,-2500>,<0, CamAngle, 0>) color White*0.25}

light_source{vrotate(<1500,1250,-2500>,<0, 90+CamAngle, 0>) color White*0.5}

light_source{vrotate(<1500, 750,-2500>,<0, 270+CamAngle, 0>) color White*0.5}





     

#declare R = 0.25;   //radius of the tubes

#declare r = 0.25;//0.375;  //radius of the spheres





#declare CornerPositions = array [2][4]

{

  {<-1,-1,-1>,< 1,-1,-1>,<1,-1, 1>,<-1,-1, 1>},

  {<-1, 1,-1>,< 1, 1,-1>,<1, 1, 1>,<-1, 1, 1>}

}



#declare CubeTexture = texture {

      pigment { color rgb<0.9, 0.9, 0.9> }

      finish { ambient 0.2 diffuse 0.7 }

     };

#declare CubeTexture = texture { T_Wood1 };



#declare BottomCylinders = array [4]

{

cylinder {CornerPositions[0][0],CornerPositions[0][1],R  texture { CubeTexture rotate y * 90}}

cylinder {CornerPositions[0][1],CornerPositions[0][2],R  texture { CubeTexture rotate y *  0}}

cylinder {CornerPositions[0][2],CornerPositions[0][3],R  texture { CubeTexture rotate y * 90}}

cylinder {CornerPositions[0][3],CornerPositions[0][0],R  texture { CubeTexture rotate y *  0}}



}



#declare VerticalCylinders = array [4]

{

  union {

    sphere {CornerPositions[0][0],R}

    cylinder {CornerPositions[0][0],CornerPositions[1][0],R}

    sphere {CornerPositions[1][0],R}

//    sphere {CornerPositions[1][0] + < 0, 0.4, 0>,R/4 pigment { Red}}

    texture { CubeTexture rotate x * 90}

    }

  union {

    sphere {CornerPositions[0][1],R}

    cylinder {CornerPositions[0][1],CornerPositions[1][1],R}

    sphere {CornerPositions[1][1],R}

//    sphere {CornerPositions[1][1] + < 0, 0.4, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][1] + < 0, 0.5, 0>,R/4 pigment { Red}}

    texture { CubeTexture rotate x * 90}

    }

  union {

    sphere {CornerPositions[0][2],R}

    cylinder {CornerPositions[0][2],CornerPositions[1][2],R}

    sphere {CornerPositions[1][2],R}

//    sphere {CornerPositions[1][2] + < 0, 0.4, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][2] + < 0, 0.5, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][2] + < 0, 0.6, 0>,R/4 pigment { Red}}

    texture { CubeTexture rotate x * 90}

    }

  union {

    sphere {CornerPositions[0][3],R}

    cylinder {CornerPositions[0][3],CornerPositions[1][3],R}

    sphere {CornerPositions[1][3],R}

//    sphere {CornerPositions[1][3] + < 0, 0.4, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][3] + < 0, 0.5, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][3] + < 0, 0.6, 0>,R/4 pigment { Red}}

//    sphere {CornerPositions[1][3] + < 0, 0.7, 0>,R/4 pigment { Red}}

    texture { CubeTexture rotate x * 90}

    }

}



#declare TopCylinders = array [4]

{

cylinder {CornerPositions[1][0],CornerPositions[1][1],R  texture { CubeTexture rotate y * 90}}

cylinder {CornerPositions[1][1],CornerPositions[1][2],R  texture { CubeTexture rotate y *  0}}

cylinder {CornerPositions[1][2],CornerPositions[1][3],R  texture { CubeTexture rotate y * 90}}

cylinder {CornerPositions[1][3],CornerPositions[1][0],R  texture { CubeTexture rotate y *  0}}



}



#declare c = 0;

#declare ShadowCube = union {

#while (c < 4)

  object { TopCylinders[c]}

  object { BottomCylinders[c]}

  object { VerticalCylinders[c]}

  #declare c = c + 1;

#end

}









/*

Macro YWedge() defines the vertical 

section we need to cut out so that

the post in the back becomes visible

*/

 

 

/*******Here's where my problem lies, I need to translate the planes in sucg a way that they are being tracked upon animation*******/ 

#macro YWedge( Cam, Top, Bottom )



  /*

  The wedge needs to be limited by 2

  lines off sight at the top and bottom.

  */

  #local ViewVector = vlength(<0, Top.y , Top.z>-<0, Cam.y, Cam.z>);

  #local Alpha = degrees(asin((Top.y-Cam.y)/ ViewVector));

  #local TopPlane = plane { -y, 0 rotate x * -Alpha }

  

  #local ViewVector = vlength(<0, Bottom.y , Bottom.z>-<0, Cam.y, Cam.z>);

  #local Alpha = degrees(asin((Bottom.y-Cam.y)/ ViewVector));

  #local BottomPlane = plane { y, 0 rotate x * -Alpha }

  

  #local ViewVector = vlength(<Bottom.x ,0, Bottom.z>-<Cam.x, 0, Cam.z>);

  #local WedgeLength = vlength(Cam);

  /*

  ViewVector is the distance from the 

  camera position to the vertical

  post that we want to make visible.

  Distance is calculated along the y = 0 plane.

  */

  #local r = R;

  #local Alpha = asin(r / ViewVector) * 180 / pi;

  /*

  Alpha is the angle between the line

  that goes through the center of the

  vertical post and the line that

  touches the outside of the post

  */

  #declare Plane1 = plane {-x, 0 rotate y*Alpha};

  #declare Plane2 = plane { x, 0 rotate y*-Alpha};



  /*

  We declare 2 planes that touch

  left and right side of the post

  */     

  

  #declare wedge = difference {

    box {-WedgeLength*1.1, WedgeLength*1.1}

    object { Plane1 }

    object { Plane2 }

    }   

  /*

  We then create a wedge which

  starts at the camera view point

  and covers the post we want to

  make visible

  */



  #local Xdist = Top.x - Cam.x  ;

  #declare Angle = degrees(asin(Xdist/ViewVector));



  /*

  "Angle" is the angle between the z-axis

  and the line through the post we want to

  make visible.

  */

      difference {

	object { wedge rotate y * Angle }

	object { TopPlane }

	object { BottomPlane }

	translate Cam

    pigment {Red} 

  }

#end



#macro XWedge( Cam, Left, Right )



  /*

  The wedge needs to be limited by 2

  lines off sight at the left and right.

  */

  #local ViewVector = vlength(< Left.x,0 , Left.z>-<Cam.x, 0, Cam.z>);

  #local Alpha = degrees(asin((Left.x-Cam.x)/ ViewVector));

  #local LeftPlane = plane {  x, 0 rotate y *  Alpha }

  

  #local ViewVector = vlength(< Right.x , 0, Right.z>-<Cam.x, 0, Cam.z>);

  #local Alpha = degrees(asin((Right.x-Cam.x)/ ViewVector));

  #local RightPlane = plane {-x, 0 rotate y *  Alpha }

  





  #local ViewVector = vlength( <0, Left.y, Left.z> - <0, Cam.y, Cam.z> );

  #local WedgeLength = vlength(Cam);

  #local r = R;

  #local Alpha = degrees(asin(r / ViewVector));

  #declare Plane1 = plane {-y, 0 rotate x *-Alpha};

  #declare Plane2 = plane { y, 0 rotate x * Alpha};



  /*

  We declare 2 planes that touch

  left and right side of the post

  */

  #declare wedge = difference {

    box {-WedgeLength*1.1, WedgeLength*1.1}

    object { Plane1 }

    object { Plane2 }

    }

  /*

  We then create a wedge which

  starts at the camera view point

  and covers the post we want to

  make visible

  */



  #local Ydist = Left.y - Cam.y  ;

  #declare Angle = degrees(asin(Ydist/ViewVector));



  /*

  "Angle" is the angle between the z-axis

  and the line through the post we want to

  make visible.

  */

    difference {

      object { wedge rotate x * -Angle }

      object { LeftPlane }

      object { RightPlane }

      translate Cam

    pigment {Green} 

    }

#end



#macro ZWedge( Cam, Front, Back )



  #local ViewVector = vlength(< Back.x, 0, Back.z>-<Cam.x, 0, Cam.z>);

  #local Alpha = degrees(asin((Back.z-Cam.z)/ ViewVector));

  #local BackPlane = plane { -z, 0 rotate y * -Alpha }

  

  #local ViewVector = vlength(< Front.x , 0, Front.z>-<Cam.x, 0, Cam.z>);

  #local Alpha = degrees(asin((Front.z-Cam.z)/ ViewVector));

  #local FrontPlane = plane { z, 0 rotate y * -Alpha }

  





  #local ViewVector = vlength( <Front.x, Front.y, 0> - <Cam.x, Cam.y, 0> );

  #local WedgeLength = vlength(Cam);

  #local D = R;

  #local Alpha = degrees(asin(D / ViewVector));

  #declare Plane1 = plane {-y, 0 rotate z * Alpha};

  #declare Plane2 = plane { y, 0 rotate z *-Alpha};



  #declare wedge = difference {

    box {-WedgeLength*1.1, WedgeLength*1.1}

    object { Plane1 }

    object { Plane2 }

    }



  #local dist = Front.y - Cam.y;

  #declare Angle = degrees(asin(dist/ViewVector));



    difference {

      object { wedge rotate z * Angle }

      object { BackPlane }

      object { FrontPlane }

      translate Cam

    pigment {Blue} 

    }

#end



  

#declare Wedges =

union {

  YWedge(Cam0Location,CornerPositions[1][2],CornerPositions[0][2])

  XWedge(Cam0Location,CornerPositions[0][3],CornerPositions[0][2])

  ZWedge(Cam0Location,CornerPositions[0][1],CornerPositions[0][2])

  }

  

  

  

  

#if (UseIllusionCamera)

  

#declare TopCylinders[0] =

  difference {

    object { TopCylinders[0] }

    object { Wedges }

    }

#declare TopCylinders[3] =

  difference {

    object { TopCylinders[3] }

    object { Wedges }

    }

#declare VerticalCylinders[0] =

  difference {

    object { VerticalCylinders[0] }

    object { Wedges }

    }

#else

#declare TopCylinders[0] =

  union {

    object { TopCylinders[0] }

    object { Wedges }

    }

#end



// Assemble all cylinders



#declare c = 0;

#declare ImpossibleCube = union {

#while (c < 4)

  object { TopCylinders[c]}

  object { BottomCylinders[c]}

  object { VerticalCylinders[c]}

  #declare c = c + 1;

#end

}



object {ImpossibleCube no_shadow }



// This is why the shadow will never show the trick.

//object {ShadowCube texture { T_Gold_1B } no_image}