/**********************************************************************************
 Persistence of Vision Ray Tracer Scene Description File
 File name   : Visibility Test.pov
 Version     : 3.7
 Description : test scene for the visibility test macro by Gilles Tran
               
 Date        : July 2009 / May 2013
 Author      : Thomas A. M. de Groot
**********************************************************************************/

// Render settings (right-click on a line below):
// +w640 +h640 +a0.3 +am2

#version 3.7;

#default {pigment {rgb <1,0,0>}}
#default {finish {ambient 0 diffuse 1}}

#include "colors.inc"
#include "rand.inc"

global_settings {
  assumed_gamma 1.0
}

// ----------------------------------------
#declare SeeScreen = on; //switch for testing the pseudo screen
#declare Write     = on; //switch for writing object positions

#declare CamLoc = <0.0, 0.5, -4>;
#declare CamEye = <0.0, 0.0,  0.0>;
#declare CamSky = y;
#declare AspectRatio = image_width/image_height;
#declare CamAng  = 50;
#declare CamZoom = 1.5;

// ----------------------------------------
camera {
  location  CamLoc
  sky				CamSky
  up				CamSky
  direction z*CamZoom
  right     x*AspectRatio
  look_at   CamEye
  angle     CamAng
}

// =====================================================================================
// visibility test code by Gilles Tran,
// derived from work by
// John Van Sickle and Christoph Hormann
// --------------------------------------
#declare CamD=vnormalize(CamEye-CamLoc);         // direction of camera view
#declare CamR=vnormalize(vcross(CamSky,CamD));   // to the right
#declare CamU=vnormalize(vcross(CamD,CamR));     // camera up

#declare Screen= // pseudo screen to test the visibility of an object
mesh{
  triangle{0,x,x+y}
  triangle{0,y,x+y}
  translate -0.5*(x+y)
  scale <AspectRatio,1,1>
  translate CamZoom*z
  matrix < CamR.x,  CamR.y,  CamR.z,
           CamU.x,  CamU.y,  CamU.z,
           CamD.x,  CamD.y,  CamD.z,
           CamLoc.x,CamLoc.y,CamLoc.z >
}

//Set SeeScreen on to test if the pseudo screen is covering completely the output window.
//You can control this by increasing or decreasing the CamZoom value.
// After testing, switch SeeScreen off.
#if (SeeScreen)
  object{Screen pigment{rgbf<1,0,0,0.9>} }
#end

#macro IsObjectVisible(PosObject)
// this macro tests the position of the object against the pseudo screen
  #local Norm1 = <0, 0, 0>;
  #local PosTemp= trace (Screen,PosObject,-PosObject+CamLoc,Norm1);
  #if (vlength(Norm1)!=0)
    true;
  #else
    false;
  #end
#end
// =====================================================================================


sky_sphere {
  pigment {
    gradient y
    color_map {
      [0.0 rgb <0.6,0.7,1.0>]
      [0.7 rgb <0.0,0.1,0.8>]
    }
  }
}

light_source {
  <0, 0, 0>            // light's position (translated below)
  color rgb <1, 1, 1>  // light's color
  translate <-30, 30, -30>
}

// ----------------------------------------

#declare Plane =
plane {
  y, -1
  pigment { color rgb <0.7,0.5,0.3> }
}

object {Plane}

sphere { 0.0, 0.1 translate <0.0, -0.9, -4>}//at writing x- & z-position of the camera

#declare Sphere =
sphere {
  0.0, 0.1
  texture {
    pigment {
      radial
      frequency 8
      color_map {
        [0.00 color rgb <1.0,0.4,0.2> ]
        [0.33 color rgb <0.2,0.4,1.0> ]
        [0.66 color rgb <0.4,1.0,0.2> ]
        [1.00 color rgb <1.0,0.4,0.2> ]
      }
    }
    finish{
      specular 0.6
    }
  }
  translate 0.1*y
}

//=============================================================================
#declare Box = box {<-10, 1, -10>,<10, 2, 10>}
#declare Seed = seed(1);
#declare N = 1000;
#declare C = 0;

#if (Write)
#fopen Objects "Objects.inc" write

#while (C <= N)
  #declare Norm = <0,0,0>;
  #declare Start = VRand_In_Obj(Box, Seed);
  #declare Pos = trace (Plane, Start, -y, Norm);
  #declare Visible = IsObjectVisible(Pos)
  #if (Visible)
    #write (Objects, Pos, ",\n")
    #declare C = C+1;
  #end
#end

#fclose Objects
#end

#fopen Objects "Objects.inc" read

#while (defined (Objects))
  #read (Objects, Pos)
  object {Sphere translate Pos}

#end