
#ifndef _BVH_H
#define BVH_H

#include "vec.h"
#include "color.h"
#include "ray.h"
#include "bbox.h"

//! representation d'un triangle.
struct Triangle
{
    Triangle( ) : a(), b(), c() {}
    Triangle( const Point& _a, const Point& _b, const Point& _c ) : a(_a), b(_b), c(_c) {}
    
    Point a;
    Point b;
    Point c;
};

bool intersect( const Triangle& triangle, const Ray& ray, const float hitmax, float &t );
bool intersect( const BBox& box, const Ray& ray, const float hitmax, float &tmin, float& tmax );

//! representation d'un noeud du bvh.
struct BVHNode
{
    BVHNode( ) : left(nullptr), right(nullptr), triangle(nullptr), box() {}
    
    BVHNode *left;
    BVHNode *right;
    Triangle *triangle;
    BBox box;
};

BVHNode *create_node( const BBox& box, BVHNode *left, BVHNode *right );
BVHNode *create_leaf( const BBox& box, Point *triangle );

//! representation du bvh.
struct BVH
{
    BVH( ) : triangles(), root(nullptr), box() {}
    
    std::vector<Triangle> triangles;
    BVHNode *root;
    BBox box;
};

BVH make_bvh( const std::vector<vec3>& positions );

extern unsigned long int box_n;
extern unsigned long int tri_n;

bool intersect( const BVH& bvh, const Ray& ray, const float tmax, Hit& hit );

#endif
