/*
    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) 2006  Thierry Berger-Perrin <tbptbp@gmail.com>
*/
#ifndef MATH_AABB_H
#define MATH_AABB_H

#include "math_vec.h"
#include "math_utility.h"    // minf/maxf

struct aabb_t {
    vec_t pmin, pmax;
    aabb_t() {}
    aabb_t(const vec_t &v1, const vec_t &v2): pmin(v1), pmax(v2) {}
    explicit aabb_t(float min_value, float max_value)
        : pmin(vec_t(min_value, min_value, min_value)),
          pmax(vec_t(max_value, max_value, max_value)) {}

    //static aabb_t from_triangle(const triangle_t &t) { return t.get_aabb(); }
    // 'this' will encompass 'this' & b.
    FINLINE void compose(const aabb_t &b) {
        pmin.x = minf(pmin.x, b.pmin.x);
        pmin.y = minf(pmin.y, b.pmin.y);
        pmin.z = minf(pmin.z, b.pmin.z);
        pmax.x = maxf(pmax.x, b.pmax.x);
        pmax.y = maxf(pmax.y, b.pmax.y);
        pmax.z = maxf(pmax.z, b.pmax.z);
    }
    FINLINE float half_surface_area() const {
        const vec_t e(get_extent());
        return e.x*e.y + e.y*e.z + e.x*e.z;
    }
    FINLINE double get_area() const {
        const vec_t ext(pmax-pmin);
        return double(ext.x)*double(ext.y) + double(ext.y)*double(ext.z) + double(ext.x)*double(ext.z);
    }
    vec_t get_extent() const { return pmax-pmin; }
};

#endif
