/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2
 *   as published by the Free Software Foundation.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *   Copyright (C) 2007  Benjamin Segovia <bsegovia@liris.cnrs.fr>
 */

#ifndef BVHLIB_INTERNAL_H_
#define BVHLIB_INTERNAL_H_

#include "specifics.h"

#include "math_vec.h"
#include "math_aabb.h"
#include "math_triangle.h"
#include "bvhlib.h"

#ifdef __SSE__
#include "math_fast_aabb.h"
#endif

#include <vector>

namespace bvhlib {
    static const int remap_other_axis[4] = {1, 2, 0, 1};
    enum {other_axis_n = 2};
    struct centroid_t : public vec_t {
        centroid_t() {}
        centroid_t(const triangle_t &t) : vec_t(
            t.verts[0].x + t.verts[1].x + t.verts[2].x,
            t.verts[0].y + t.verts[1].y + t.verts[2].y,
            t.verts[0].z + t.verts[1].z + t.verts[2].z) {}
    };
    /* Is the primitive in the left or the right bbox ? */
    enum {on_left = 0, on_right};
    /* n log(n) compiler with bounding box sweeping and SAH heuristics */
    struct compiler_t {
        /* When a partition is found, we store the position (left or right) of
         * each active primitive in this vector
         */
        std::vector<int> pos;
        /* indices sorted for each axis */
        std::vector<uint32_t> ids[3];
        /* vector when we have to dispatch the ids */
        std::vector<uint32_t> tmp_ids;
        /* bounding boxen of the triangles */
        std::vector<aabb_t> aabbs;
        /* right to left growing bounding boxen */
        std::vector<aabb_t> rl_aabbs;
        /* total number of triangles */
        int n;
        /* id where we can put the current node */
        uint32_t curr_id;
        /* bounding box of the scene */
        aabb_t scene_aabb;
        /* data which store (ray tracing customized) triangles */
        rt::wald_tri_t * __restrict acc;
        /* data which store (ray tracing customized) nodes and leaves */
        bvh::node_t * __restrict root;
        compiler_t() { curr_id = 0; }
        int injection(
            const triangle_t * const __restrict soup,
            const uint32_t tri_n,
            bvh::descriptor_t &fat);
        int compile();
    };
}

#endif

