Shooting Rays

Now it's time to get to the very core of ray tracing, e.g. shooting the rays;
But first we will create a header file which contains commonly used math constants and functions.
Create a file called Math.H

#ifndef _Math_H
#define _Math_H

#include <math.h>
#include <OSL/Imathx.h>

#define M_INFINITY 1.0e38
#define M_EPSILON  1.0e-10

#endif // Math.H

That's all there is to it for now, we will come back to this file in later tutorials.

Now for the interesting part!
We define the Ray class in a file called Ray.H according to this:

#ifndef _Ray_H
#define _Ray_H

#include <iostream>
#include "Math.H"

class Ray {
public:
// Initialize ray with undefined origin and direction
Ray()
: mint(0.0f),
maxt(M_INFINITY),
time(0.0f),
depth(0)
{
}

// Initialize ray with origin and direction
Ray(const Vec3 &orig,
const Vec3 &dir,
Float start,
Float end = M_INFINITY,
Float t = 0.0f,
int d = 0)
: o(orig),
d(dir),
mint(start),
maxt(end),
time(t),
depth(d)
{
}

// Initialize ray from origin, direction and parent ray
Ray(const Vec3 &orig,
const Vec3 &dir,
const Ray &parent,
Float start,
Float end = M_INFINITY
)
: o(orig),
d(dir),
mint(start),
maxt(end),
time(parent.time),
depth(parent.depth + 1)
{
}

// Function operator for ray
Vec3 operator()(Float t) const
{
return (o + d * t);
}

// Print ray to stream
friend std::ostream& operator<<(std::ostream &stream, const Ray &r)
{
stream << r.o << "->" << r.d
<< "e[" << r.mint << ", " << r.maxt << "]"
<< ", time: " << r.time
<< ", depth: " << r.depth;
return stream;
}

// Public data
Vec3 o;
Vec3 d;
mutable Float mint, maxt;
Float time;
int depth;
int depth;
};

#endif // Ray_H

A ray consists of a starting point and a vector, where o the the point of origin and d is the velocity vector.
Shooting rays is described as a parametric equaltion r(t) = o + dt, which is equal to a point in space at a certain value of the parameter t. We also keep the maximum and minumum values of t in the vector class, as this makes it possible to remember where the ray intersected a shape.

Some ideas for the ray interface has been "borrowed" from the the Physically Based Rendering Techniques Renderer, a.k.a pbrt, enjoy!