From 7a2c1f3713be127f6e4361fd8f426e78e8965bab Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Wed, 20 Jan 2010 02:34:16 +0100 Subject: [PATCH] solution to assignment 2.2 b): surface normalsD --- InfinitePlane.cxx | 9 +++++---- Sphere.cxx | 19 +++++++++++++++---- Triangle.cxx | 27 +++++++++++++++------------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/InfinitePlane.cxx b/InfinitePlane.cxx index 442da19..54c9570 100644 --- a/InfinitePlane.cxx +++ b/InfinitePlane.cxx @@ -1,11 +1,11 @@ #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() @@ -17,7 +17,7 @@ InfinitePlane::Intersect(Ray& ray) { 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; @@ -26,5 +26,6 @@ InfinitePlane::Intersect(Ray& ray) Vec3f InfinitePlane::GetNormal(Ray& ray) { - return Vec3f(); + // We already have the surface normal + return m_n; } diff --git a/Sphere.cxx b/Sphere.cxx index 3c19afa..5706cc3 100644 --- a/Sphere.cxx +++ b/Sphere.cxx @@ -1,7 +1,7 @@ #include "Sphere.hxx" Sphere::Sphere(const Vec3f& center, float radius, Shader* shader) - : Primitive(shader), + : Primitive(shader), m_center(center), m_radius(radius) { @@ -20,12 +20,12 @@ Sphere::Intersect(Ray& ray) 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); @@ -39,5 +39,16 @@ Sphere::Intersect(Ray& ray) 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; } diff --git a/Triangle.cxx b/Triangle.cxx index 761abcb..456c6d8 100644 --- a/Triangle.cxx +++ b/Triangle.cxx @@ -20,40 +20,43 @@ Triangle::Intersect(Ray& ray) { 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; } -- 2.20.1