#ifndef RealisticThinLenseCamera_HXX
#define RealisticThinLenseCamera_HXX

#include "PerspectiveCamera.hxx"

/* Realistic Thin Lense Camera
 *
 * Implements a simple camera with depth of field
 *
 * Miguel Granados, Richard Socher
 * Core Lecture in Computer Graphics by Prof. Dr. Philipp Slusallek
 * University of Saarland
 * WS2006/2007
 */


// by using PerspectiveCamera as a base class, we can use its features
class RealisticThinLenseCamera : public PerspectiveCamera
{
	//size of lense (needed for moving the ray.org around) instead of leaving it at a 1px pinhole camera
	float xLength, yLength;
	// distance of focus plane from pos
	float focalLength;

public:
	RealisticThinLenseCamera(Vec3f pos,Vec3f dir,Vec3f up,float angle, int resX, int resY,
					float focalLength, float xLength=0.1, float yLength=0.1
		):PerspectiveCamera(pos,dir,up,angle,resX,resY), //call base class constructor
		xLength(xLength), yLength(yLength), focalLength(focalLength) // initialize here or define as public?
	{}

	// overload of initray function, first standard initialization of a ray through given pixel x,y
	// ray origin is then modified for rays not hitting objects in the focal distance
	virtual bool InitRay(float x, float y, Ray &ray)
	{
		// Initialize the original ray
		PerspectiveCamera::InitRay(x,y,ray);

		//calculate the intersection point of ray and focus plane, with: cos(<(zAxis,ray.dir)) = focalLength/t
		float alpha = Dot(zAxis,ray.dir);
		float t = focalLength / alpha ;
		Vec3f pointOnFocusedPlane = ray.org + t*ray.dir;

		// change org by (drand48()-0.5) \in [-.5,.5]
		ray.org = ray.org + ((float)drand48()-0.5f)*xLength*xAxis + ((float)drand48()-0.5f)*yLength*yAxis;

		// set new direction of ray as substraction: (hitpoint on plane)-ray.org
		// this way all elements except those on the focus plane are blurred
		ray.dir = pointOnFocusedPlane - ray.org;
		Normalize(ray.dir);

		return true;
	};
};
#endif

