#include "InfinitePlane.hxx"
InfinitePlane::InfinitePlane(const Vec3f& a, const Vec3f& n, Shader* shader)
- : Primitive(shader),
+ : Primitive(shader),
m_a(a),
m_n(n)
{
-
+
}
InfinitePlane::~InfinitePlane()
{
Vec3f diff = m_a - ray.origin();
float t = diff.dot(m_n) / ray.direction().dot(m_n);
- if (t < 1e-5 || t > ray.t())
+ if (t < 1e-5 || t > ray.t())
return false;
ray.setT(t);
return true;
Vec3f
InfinitePlane::GetNormal(Ray& ray)
{
- return Vec3f();
+ // We already have the surface normal
+ return m_n;
}
#include "Sphere.hxx"
Sphere::Sphere(const Vec3f& center, float radius, Shader* shader)
- : Primitive(shader),
+ : Primitive(shader),
m_center(center),
m_radius(radius)
{
if( B*B-4*A*C < 0 )
return false;
-
+
float root = sqrtf(B*B-4*A*C);
float t = (-B-root)/(2.0f*A);
if(t > ray.t())
return false;
-
+
if( t < 1e-6 )
{
t = (-B+root)/(2.0f*A);
Vec3f
Sphere::GetNormal(Ray& ray)
{
- return Vec3f();
+ // We don't want to modify the ray (probably this is not needed, but I am
+ // too lazy to think about it now ...)
+ Ray tempRay = ray;
+
+ // Surface normal is the difference between intersection and center point
+ Intersect(tempRay);
+ // intersection
+ Vec3f i = tempRay.origin() + tempRay.direction() * tempRay.t();
+ // normal
+ Vec3f n = (i - m_center);
+ n.normalize();
+ return n;
}
{
const Vec3f edge1 = m_b-m_a;
const Vec3f edge2 = m_c-m_a;
-
+
const Vec3f pvec = ray.direction().cross(edge2);
-
+
const float det = edge1.dot(pvec);
if (fabs(det) < Epsilon) return false;
-
+
const float inv_det = 1.0f / det;
-
+
const Vec3f tvec = ray.origin()-m_a;
float lambda = tvec.dot( pvec );
lambda *= inv_det;
-
- if (lambda < 0.0f || lambda > 1.0f)
+
+ if (lambda < 0.0f || lambda > 1.0f)
return false;
const Vec3f qvec = tvec.cross(edge1);
float mue = ray.direction().dot(qvec);
mue *= inv_det;
-
- if (mue < 0.0f || mue+lambda > 1.0f)
+
+ if (mue < 0.0f || mue+lambda > 1.0f)
return false;
float f = edge2.dot(qvec);
f *= inv_det;
- if (ray.t() <= f || f < 1e-4 )
+ if (ray.t() <= f || f < 1e-4 )
return false;
-
+
ray.setT(f);
-
+
return true;
}
Vec3f
Triangle::GetNormal(Ray& ray)
{
- return Vec3f();
+ // normal is cross product of spanning vectors
+ Vec3f n = (m_c - m_a) % (m_c - m_b);
+ n.normalize();
+ return n;
}