//#####################################################################
// Copyright 2002-2008, Robert Bridson, Ronald Fedkiw, Eran Guendelman, Jon Gretarsson, Andrew Selle.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class RAY_ACCEL
//#####################################################################
#ifndef __RAY_ACCEL__
#define __RAY_ACCEL__

#include <Core/Basic_Geometry/SEGMENT_1D.h>
#include <Core/Basic_Geometry/SEGMENT_2D.h>
#include <Core/Basic_Geometry/SEGMENT_3D.h>
#include <Core/Math_Tools/RANGE.h>
#include <Core/Vectors/VECTOR.h>
#include <cmath>
namespace PhysBAM{

template<class TV>
class RAY_ACCEL
{
public:
    typedef typename TV::SCALAR T;
    enum WORKAROUND {d=TV::m};
    typedef VECTOR<int,TV::m> IV;
    TV inverse_direction;
    IV direction_is_negative;

    RAY_ACCEL() = default;
    
    RAY_ACCEL(const RAY<TV>& ray)
    {
        Set(ray);
    }
    
    void Set(const RAY<TV>& ray)
    {
        const T tolerance=(T)1e-10,large_number=(T)1e10;
        for(int i=0;i<TV::m;i++)
        {
            if(ray.direction(i)<0){direction_is_negative(i)=1;inverse_direction(i)=(ray.direction(i)<-tolerance)?1/ray.direction(i):-large_number;}
            else{direction_is_negative(i)=0;inverse_direction(i)=(ray.direction(i)>tolerance)?1/ray.direction(i):large_number;}
        }
    }
};
}
#endif
