//----------------------------------------------------------------------------
// William Baxter III's Ray Tracer
//
//     Project for Comp 238, Raster Graphics
//     University of North Carolina at Chapel Hill
//     
// $Id:$
//----------------------------------------------------------------------------

#include <assert.h>
#include "wb3Sphere.hpp"


wb3Sphere::wb3Sphere(const Vec3f& center, float radius) 
  : m_C(center)
{
  m_fR2 = radius * radius;
}

wb3Sphere::~wb3Sphere()
{
}


const wb3Artifact* wb3Sphere::Intersect(const Ray3f& r, float* dist,
                                        const wb3Artifact* ignore) const
{
  // Return nearest intersection along ray that is at least 
  // an epsilon away from the eye.  

  Vec3f d(m_C - r.m_p);
  float d2 = d.LengthSqr();
  float vdotd = r.m_v * d;
  float vdotd2 = vdotd * vdotd;
  float discrim = vdotd2 - 1.0f * (d2 - GetRadiusSqr());

  if (discrim < 0) 
    return 0; // no intersections

  float root_discrim = float(sqrt(discrim));
  float t;
  if (d2 > GetRadiusSqr()) { // eye is outside sphere
    // if sphere is in front of us then we want smaller t 
    t = vdotd - root_discrim;
    if (t>ms_fEps) { // and by a significant amount
      *dist = t;
      return this;
    }
  }
  // try bigger value
  t = vdotd + root_discrim;
  if (t>ms_fEps)
  {
    *dist = t;
    return this;
  }

  // all intersections were behind the eye
  return 0;
  
}

