
#include <cstdio>
#include <cmath>
#include <cfloat>

#include "vec.h"
#include "mat.h"
#include "mesh.h"
#include "wavefront.h"
#include "image.h"
#include "image_io.h"
#include "orbiter.h"

#include "bvh.h"


int main( int argc, char **argv )
{
    const char *file= "geometry.obj";
    if(argc > 1) file= argv[1];
    
    Mesh mesh= read_mesh(file);
    if(mesh == Mesh::error())
        return 1;
    
    BVH bvh= make_bvh(mesh.positions());
    mesh.release();
    
    Orbiter camera;
    camera.read_orbiter("orbiter.txt");
    
    // go
    Image image(1024, 640);
    
    Point d0;
    Vector dx, dy;
    Point o= camera.position();
    camera.frame(image.width(), image.height(), 1, 45, d0, dx, dy);
    
    box_n= 0;
    tri_n= 0;
#pragma omp parallel for schedule(dynamic, 16)
    for(int y= 0; y < image.height(); y++)
    for(int x= 0; x < image.width(); x++)
    {
        Point e= d0 + (float) x * dx + (float) y * dy;
        Ray ray= make_ray(o, e);

        Hit hit;
        if(intersect(bvh, ray, FLT_MAX, hit))
        {
            Color color= White();
            float cos_theta= std::abs(dot(hit.n, normalize(Vector(hit.p, o))) );
            image(x, y)= Color(color * cos_theta, 1);
        }
    }
    
    printf("triangles %lu %f/ray, boxes %lu %f/ray\n", tri_n, (float) tri_n / (float) image.size(), box_n, (float) box_n / (float) image.size());
    
    write_image(image, "render.png");
    return 0;
}
