#include "GraphicalObject.h"

int GraphicalSphere::Intersect(const Ray &ray, real &dist)
{
   Vector3 dist_ = pt - ray.origin;
   real B = ray.direction * dist_;
   real D = B*B - dist_ * dist_ + r * r;
   
   if (D < 0.0)
      return 0;
   
   real sD = Sqrt(D);
   real t0 = B - sD;
   real t1 = B + sD;

   int retvalue = 0;

   if ((t0 > 0.1 ) && (t0 < dist)) {
     dist = t0;
     retvalue = 1;
   }
   if ((t1 > 0.1 ) && (t1 < dist)) {
     dist = t1;
     retvalue = 1;
   }

   return retvalue;
}


int GraphicalPlane::Intersect(const Ray &ray, real& dist)
{
	real d = normal * ray.direction;
	if (d != 0.0)
	{
	   real distance = (normal * ray.origin) / d;
	   if ((distance > 0.0001) && (distance < dist))
	   {
	     dist = distance;
       if (d < 0.0)
	       normal = -normal;
	     return 1;
	   }
	}
	return 0;
}


int GraphicalTriangle::Intersect(const Ray& ray, real& dist)
{
   Vector3 edge1, edge2, tvec, pvec, qvec;
   real det;
   real u,v,t;

   /* find vectors for two edges sharing vert0 */
   edge1 = py - pt;
   edge2 = pu - pt;

   /* begin calculating determinant - also used to calculate U parameter */
   pvec = ray.direction ^ edge2;

   /* if determinant is near zero, ray lies in plane of triangle */
   det = edge1 * pvec;

   if (det == 0.00)
      return 0;

   /* calculate distance from vert0 to ray origin */
   tvec = ray.origin - pt;

   /* calculate U parameter and test bounds */
   u = (tvec * pvec);
   if (u < 0.0 || u > det)
      return 0;

   /* prepare to test V parameter */
   qvec =  tvec ^ edge1;

    /* calculate V parameter and test bounds */
   v = ray.direction * qvec;
   if (v < 0.0 || u + v > det)
      return 0;

   /* calculate t, scale parameters, ray intersects triangle */
   t = edge2 * qvec;
   real inv_det = 1.0 / det;
   t *= inv_det;
   u *= inv_det;
   v *= inv_det;

   dist = t;

   return 1;
}


/*
int GraphicalQuad::Intersect(const Ray &ray, real& dist)
{
  return 0;
}
*/
