/************************************************************************************************
 *                                                                                              *
 * Camera Class for ray-tracing                                                                 *
 *   Important difference with other implementation: Viewplane is included implicitly in Camera.*
 *                                                                                              *
 * The Camera is specified by,                                                                  *
 *   1)camera center, i.e. eye                                                                  *
 *   2)lookAt center, i.e. at                                                                   *
 *   3)up vector                                                                                *
 *   4)fov                                                                                      *
 *   5)aspect                                                                                   *
 *                                                                                              *
 * The viewplane is implicitly located some position from 'eye' to 'at', so that the v value    *
 * (y direction) in the viewplane spaned by fov ranges from -1 to +1.                           *
 *                                                                                              *
 * The lookAt center is significant only in the sense to derive the unit vector from eye to at, *
 *    i.e. W vector.                                                                            *
 *                                                                                              *
 * For up vector, only its projection onto view plane, i.e, V unit vector, is significant.      *
 *                                                                                              *
 * The most important function in Camera class is the GetRay(), which return ray given u-v      *
 * coordinates in viewplane.                                                                    *
 *                                                                                              *
 *                                                                                              *
 *                                          XianMing Chen, Jan 13, 2002                         *
 *                                                                                              *
 ************************************************************************************************/



#ifndef _CAMERA_H_
#define _CAMERA_H_

#include "Ray.h"

class Camera {
 public:
    Camera() : eye(0,0,3), at(0,0,0), up(0,1,0), fov(90.0), aspect(1.0) { }
    ~Camera() { }

    void SetEye(const Vector& e) { eye = e; }
    Vector GetEye() const { return eye; }

    void SetAt(const Vector& a) { at = a; }
    Vector GetAt() const { return at; }

    void SetUp(const Vector& u) { up = u; }
    Vector GetUp() const { return up; }

    void SetFov(double f) { fov = f; }
    double GetFov() const { return fov; }

    void SetAspect(double a) { aspect = a; }
    double GetAspect() const { return aspect; }

    void Init(); // calculate U,V,W vectors and w (distance to viewplane)

    Vector GetRayDirection(double u, double v) { assert(v<=1.0); return (u*U + v*V + w*W); }

    friend ostream& operator<< (ostream& os, const Camera& camera);

 private:
    Vector eye;
    Vector at;
    Vector up;
    double fov;
    double aspect;

    Vector U;   //UVW: left-handed eye-coordinate unit vectors.
    Vector V;
    Vector W;
    double w;   //distance to viewplane
};



#endif

