// File         : the_mirror.hxx
// Author       : Paul A. Koshevoy
// Created      : Fri Apr 23 17:46:20 MDT 2004
// Copyright    : (C) 2004
// License      : GPL.
// Description  : 

#ifndef THE_MIRROR_HXX_
#define THE_MIRROR_HXX_

// local includes:
#include "v3x1p3x1.hxx"
#include "the_triangle.hxx"
#include "the_array.hxx"


//----------------------------------------------------------------
// the_mirror_t
// 
class the_mirror_t
{
public:
  the_mirror_t(const the_array_t<the_triangle_t> & tria):
    tria_(tria)
  {}
  
  // calculate ray b, reflection of ray a with respect to this mirror,
  // return false if the reflection is impossible:
  bool reflect(const the_ray_t & a, the_ray_t & b) const
  {
    for (unsigned int i = 0; i < 2; i++)
    {
      const the_triangle_t & tri = tria_[i];
      
      // make sure the ray intersect the triangle:
      p3x1_t bar_pt;
      if (tri.intersect(a, bar_pt) == false) continue;
      
      // make sure the ray is pointing at the triangle from the front,
      // not from behind:
      v3x1_t normal = tri.normal(bar_pt);
      if (normal * a.v() >= 0) continue;
      
      v3x1_t unit_a = !(a.v());
      v3x1_t unit_b = unit_a - 2.0 * normal * (normal * unit_a);
      
      // setup the reflection ray:
      b.p() = tri.to_wcs(bar_pt);
      b.v() = a.v().norm() * unit_b;
      
      return true;
    }
    
    return false;
  }
  
private:
  // disable default constructor and assignment operator:
  the_mirror_t();
  the_mirror_t & operator = (const the_mirror_t & mirror);
  
  // due to performance considerations this class only references a set
  // of triangles representing the mirror surface, it does not own them:
  const the_array_t<the_triangle_t> & tria_;
};


#endif // THE_MIRROR_HXX_

