// ===================================================================
// $Id: ray.cpp,v 1.3 2002/12/20 20:36:09 havran Exp $
// ray.cpp
//
//      CRay class .. defining ray (oriented half line in R^3) methods
//
// Licence and usage conditions in November 2003:
// This file can be used and modified only with written permission of
// Vlastimil Havran, Pohodli 27, 57001 Litomysl, the Czech Republic.
// This library is granted to be used by Polina Kondratieva within
// her MPI HIWI job working on BRDFLIB library. The usage condition
// may change in the next version of the library. At the moment,
// the library development is supported by Max-Planck-Institut for
// Informatik, Stuhlsatzenhausweg 85, 66123 Saarbruecken Germany
// See WWW: http://www.mpi-sb.mpg.de
// REPLACEMENT_STRING
//
// Initial coding by Vlastimil Havran and Jiri Bittner, 1997.
//
// Given to BRDFLIB project for the Polina Kondratieva's
// HIWI JOB assignment in November 2003.
// ===================================================================


// BRDFLIB headers
#include "config.h"
#include "ray.h"


__BEGIN_BRDFLIB_SOURCE

// =========================================================
// CRay .. static item used for generation of unique ID for
// each instantiated ray

// it has to start from 1, since 0 is default and for the first
// ray initial value 0 will not work .. V.H.
// The value 0 is reserved for particular purpose - the rays
// that are converted to canonical space and thus the mailbox
// rayID identification does not work for them!
int
CRay::genID = 1;

// Precompute some CRay parameters. Most of them is used for
// ropes traversal.

void
CRay::Init()
{
  // apply the standard precomputation
  Precompute();
}

void
CRay::Precompute()
{
  // Removed on 13/11/2002 - frequency of use is very low
  // ll = loc * loc;
  // ld = loc * dir;
  // dd = dir * dir;

  // initialize inverted dir
  invDir.SetValue(0.0);
  
  //SetID(); // uncomment for debugging
}

void
CRay::SetLoc(const CVector3D &l)
{
  loc = l;
}

void
CRay::ComputeInvertedDir() const
{
  if ( (invDir.x != 0.0) ||
       (invDir.y != 0.0) ||
       (invDir.z != 0.0) )
    return; // has been already precomputed

  const float eps = 1e-6;
  const float invEps = 1e6;
  
  // it does change the ray direction very slightly,
  // but the size direction vector is not practically changed
  
  if (fabs(dir.x) < eps) {
    if (dir.x < 0.0)
      invDir.x = -invEps;
    else
      invDir.x = invEps;
  }
  else
    invDir.x = 1.0 / dir.x;
  
  if (fabs(dir.y) < eps) {
    if (dir.y < 0.0)
      invDir.y = -invEps;
    else
      invDir.y = invEps;
  }
  else
    invDir.y = 1.0 / dir.y;
  
  if (fabs(dir.z) < eps) {
    if (dir.z < 0.0)
      invDir.z = -invEps;
    else
      invDir.z = invEps;
  }
  else
    invDir.z = 1.0 / dir.z;

  return;
}


__END_BRDFLIB_SOURCE
