#include "math.h"
#include "camera.h"

camera::camera(
    point3  lookfrom,
    point3  lookat,
    vec3    vup,
    double  vfov,   // vertical field of view in degrees
    double  aspect_ratio,
    double  aperture,
    double  focus_dist)
{
    auto theta = math::degrees_to_radians(vfov);
    auto h = tan(theta/2);
    auto viewport_height = 2.0 * h;
    auto viewport_width = aspect_ratio * viewport_height;

    w_ = normalize(lookfrom - lookat);
    u_ = normalize(cross(vup, w_));
    v_ = cross(w_, u_);

    origin_ = lookfrom;
    horizontal_ = focus_dist * viewport_width * u_;
    vertical_ = focus_dist * viewport_height * v_;
    lower_left_corner_ = origin_ - horizontal_/2 - vertical_/2 - focus_dist * w_;

    lens_radius_ = aperture / 2;
}

ray camera::get_ray(double s, double t) const
{
    vec3 rd = lens_radius_ * vec3::random_in_unit_disk();
    vec3 offset = (u_ * rd.x()) + (v_ * rd.y());

    return ray(
        origin_ + offset,
        lower_left_corner_ + s*horizontal_ + t*vertical_ - origin_ - offset);
}
