//----------------------------------------------------------------------------
// William Baxter III's Ray Tracer
//
//     Project for Comp 238, Raster Graphics
//     University of North Carolina at Chapel Hill
//     
// $Id:$
//----------------------------------------------------------------------------

#include "wb3Scene.hpp"

static const Vec3f ONES(1.0f,1.0f,1.0f);
wb3Material ms_SceneMaterial(Vec3f::ZERO, // ambient
                             Vec3f::ZERO, // diffuse
                             Vec3f::ZERO, // specular
                             ONES,        // reflectivity
                             ONES,        // refractivity
                             0,1.0);

wb3Scene::wb3Scene(wb3Artifact *pArtifact)
{
  m_pArtifact = pArtifact;
  m_fBGColor.x = 0;
  m_fBGColor.y = 0;
  m_fBGColor.z = 1.0;
  m_pMaterial = &ms_SceneMaterial;
}

wb3Scene::wb3Scene(wb3Artifact *pArtifact, float BGColor[3])
{
  m_pArtifact = pArtifact;
  m_fBGColor.x = BGColor[0];
  m_fBGColor.y = BGColor[1];
  m_fBGColor.z = BGColor[2];
  m_pMaterial = &ms_SceneMaterial;
}

//----------------------------------------------------------------------------
const wb3Artifact* wb3Scene::Intersect(const Ray3f& r, float *idist,
                                       const wb3Artifact* ignore) const
{
  return m_pArtifact->Intersect(r, idist, ignore);
}
//----------------------------------------------------------------------------
void wb3Scene::GetNormal(const Ray3f& r, const Vec3f &isect, Vec3f& normal) const
{
  m_pArtifact->GetNormal(r, isect, normal);
}
//----------------------------------------------------------------------------

void wb3Scene::Shade(const wb3Scene* scene, 
                     const wb3Artifact* from,
                     const wb3Artifact* hit,
                     const Ray3f& r, const Vec3f &isect, 
                     Vec3f& color, Vec3f& attenuation, int hits) const
{
  float t;
  // hit is the object most recently hit
  const wb3Artifact *newhit = Intersect(r, &t, hit);
  if (newhit) {
    const wb3Artifact *to;
    if (newhit == from) // we must be exiting the thing we were just in
    {
      to = scene; // bad assumption in a world of nested objects !!!
    }
    else
    {
      to = newhit;
    }
    newhit->Shade(scene, from, to, r, r[t], color, attenuation, hits);
  }
  else
    color = m_fBGColor.CompMult(attenuation);
}


