Rev 208 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#ifndef __RAY_H__
#define __RAY_H__
#include "CGLA/Vec3f.h"
#include "Geometry/TriMesh.h"
namespace Geometry
{
const double d_eps = 0.000001;
const float f_eps = 0.01f;
struct Ray
{
// Constructor
Ray()
: origin(0), direction(0), hit_pos(0), hit_normal(0),
has_hit(false), dist(CGLA::BIG), ior(1), u(0), v(0),
hit_object(0)
{ }
CGLA::Vec3f origin;
CGLA::Vec3f direction;
CGLA::Vec3f hit_pos;
CGLA::Vec3f hit_normal;
bool has_hit; // Did the ray hit an object
double dist; // Distance from origin to current intersection
float ior; // Current index of refraction for media
float u, v; // uv-coordinates on current surface
float ran;
int trace_depth; // Current recursion number
int hit_face_id;
int id;
Geometry::TriMesh* hit_object;
void reset()
{
dist = CGLA::BIG;
hit_object = 0;
u=0;
v=0;
has_hit=false;
}
void reflect(const CGLA::Vec3f &normal)
{
assert(dot(direction, normal) < 0);
direction = normal*2.0f*dot(-direction,normal) + direction;
}
void refract(const CGLA::Vec3f& normal, float new_ior)
{
float ref_ratio = ior/new_ior;
float cos_N_I = dot(normal, direction);
CGLA::Vec3f norm(normal);
if(cos_N_I > 0)
{
norm = -norm;
cos_N_I = dot(norm, direction);
}
float selector = 1 + (ref_ratio*ref_ratio)*(cos_N_I*cos_N_I - 1);
if(selector > 0)
{
direction = norm*(ref_ratio*(-cos_N_I) - sqrt(selector))
+ direction*ref_ratio;
ior = new_ior;
}
else
// Total internal reflection.
reflect(normal);
}
};
}
#endif