summaryrefslogtreecommitdiff
path: root/hw6/src/intersectionPoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hw6/src/intersectionPoint.cpp')
-rw-r--r--hw6/src/intersectionPoint.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/hw6/src/intersectionPoint.cpp b/hw6/src/intersectionPoint.cpp
new file mode 100644
index 0000000..5b1d15e
--- /dev/null
+++ b/hw6/src/intersectionPoint.cpp
@@ -0,0 +1,342 @@
+/******************************************************************/
+/* This file is part of the homework assignments for CSCI-427/527 */
+/* at The College of William & Mary and authored by Pieter Peers. */
+/* No part of this file, whether altered or in original form, can */
+/* be distributed or used outside the context of CSCI-427/527 */
+/* without consent of either the College of William & Mary or */
+/* Pieter Peers. */
+/******************************************************************/
+#include <cassert>
+#include "shader_base.h"
+#include "intersectionPoint.h"
+
+/////////////////
+// Constructor //
+/////////////////
+intersectionPoint::intersectionPoint(void)
+{
+ _hit = false;
+}
+
+
+intersectionPoint::intersectionPoint(const ray& r, float rayParameter, const std::shared_ptr<const shader_base>& shader, const vec3d& normal, const vec3d& axis, const vec2d& textureCoordinate)
+{
+ // copy
+ _ray = r;
+ _rayParameter = rayParameter;
+ _hit = true;
+ _shader = shader;
+ _normal = normalize(normal);
+ _axis = normalize(axis);
+ _textureCoordinate = textureCoordinate;
+
+ // compute position
+ _position = _ray(_rayParameter);
+}
+
+
+intersectionPoint::intersectionPoint(const intersectionPoint& ip)
+{
+ _hit = ip._hit;
+
+ // copy remainder if hit
+ if(_hit)
+ {
+ _ray = ip._ray;
+ _rayParameter = ip._rayParameter;
+ _shader = ip._shader;
+ _normal = ip._normal;
+ _position = ip._position;
+ _axis = ip._axis;
+ _textureCoordinate = ip._textureCoordinate;
+ }
+ else _shader = nullptr;
+}
+
+///////////////
+// Operators //
+///////////////
+intersectionPoint& intersectionPoint::operator=(const intersectionPoint& ip)
+{
+ _assign(ip);
+ return *this;
+}
+
+
+bool intersectionPoint::operator<(const intersectionPoint& ip) const
+{
+ // handle case where either one of the intersectionPoints is not a hit
+ // => assume no-hit equals a hit at infinity
+ if(!_hit) return false;
+ if(!ip._hit) return true;
+
+ // decide based on rayParameter
+ return _rayParameter < ip._rayParameter;
+}
+
+
+bool intersectionPoint::operator>(const intersectionPoint& ip) const
+{
+ // handle case where either one of the intersectionPoints is not a hit
+ // => assume no-hit equals a hit at infinity
+ if(!_hit) return true;
+ if(!ip._hit) return false;
+
+ // decide based on rayParameter
+ return _rayParameter > ip._rayParameter;
+}
+
+
+bool intersectionPoint::operator<(const lightSample& ls) const
+{
+ // handle case where this is not a hit
+ if(!_hit) return false;
+
+ // decide based on rayParameter
+ return _rayParameter < ls.distance();
+}
+
+
+bool intersectionPoint::operator>(const lightSample& ls) const
+{
+ // handle case where this is not a hit
+ if(!_hit) return true;
+
+ // decide based on rayParameter
+ return _rayParameter > ls.distance();
+}
+
+////////////////
+// Inspectors //
+////////////////
+bool intersectionPoint::isHit(void) const
+{
+ return _hit;
+}
+
+
+shaderProperties intersectionPoint::getShaderProperties(void) const
+{
+ assert(hasShader());
+ return _shader->properties(*this);
+}
+
+
+bool intersectionPoint::hasShader(void) const
+{
+ return (_shader != nullptr);
+}
+
+
+float intersectionPoint::distance(const intersectionPoint& ip) const
+{
+ // set distance to infinity of one of the two points is not a hit
+ if(!_hit || !ip._hit) return +LARGE;
+
+ // compute distance
+ return _position.distance(ip._position);
+}
+
+
+const vec3d& intersectionPoint::position(void) const
+{
+ return _position;
+}
+
+
+const vec3d& intersectionPoint::direction(void) const
+{
+ return _ray.direction();
+}
+
+
+const vec2d& intersectionPoint::textureCoordinate(void) const
+{
+ return _textureCoordinate;
+}
+
+
+const vec3d& intersectionPoint::normal(void) const
+{
+ return _normal;
+}
+
+
+coordinateTransformation intersectionPoint::shadingFrame(void) const
+{
+ // transform => to global shading frame
+ // inverseTransform => to local shading frame
+ return coordinateTransformation(_normal, _axis);
+}
+
+
+//////////////
+// Mutators //
+//////////////
+void intersectionPoint::transform(const transformation3d& t)
+{
+ // sanity check
+ if(!_hit) return;
+
+ /// transform
+ _ray.transform(t);
+ _position = t.transformPoint(_position);
+ _normal = t.transformNormal(_normal);
+ _axis = t.transformNormal(_axis);
+
+ // recompute the ray parameter (to account for potential scaling)
+ _rayParameter = _ray(_position);
+}
+
+
+void intersectionPoint::inverseTransform(const transformation3d& t)
+{
+ // sanity check
+ if(!_hit) return;
+
+ // inverse transform
+ _ray.inverseTransform(t);
+ _position = t.inverseTransformPoint(_position);
+ _normal = t.inverseTransformNormal(_normal);
+ _axis = t.inverseTransformNormal(_axis);
+
+ // recompute the ray parameter (to account for potential scaling)
+ _rayParameter = _ray(_position);
+}
+
+
+void intersectionPoint::transformShadingFrame(const transformation3d& sft)
+{
+ // sanity check
+ if(!_hit) return;
+
+ // Note: shading frame transformation are defined
+ // with respect to the local shading frame (i.e., N=Z, axis=X)
+ transformation3d t = shadingFrame();
+
+ // transform
+ _normal = t.transformNormal( sft.transformNormal(vec3d(0.0f, 0.0f, 1.0f)) );
+ _axis = t.transformNormal( sft.transformNormal(vec3d(1.0f, 0.0f, 0.0f)) );
+
+ // Done.
+}
+
+
+void intersectionPoint::inverseTransformShadingFrame(const transformation3d& sft)
+{
+ // sanity check
+ if(!_hit) return;
+
+ // Note: shading frame transformation are defined
+ // with respect to the local shading frame (i.e., N=Z, axis=X)
+ // Note: this transformation will not undo the effects of
+ // transformShadingFrame since the local shading frame
+ // is altered by the transformation (and thus the frame
+ // with respect to which the inverseTransformation is
+ // applied)
+ transformation3d t = shadingFrame();
+
+ // transform
+ _normal = t.transformNormal( sft.inverseTransformNormal(vec3d(0.0f, 0.0f, 1.0f)) );
+ _axis = t.transformNormal( sft.inverseTransformNormal(vec3d(1.0f, 0.0f, 0.0f)) );
+
+ // Done.
+}
+
+
+void intersectionPoint::setShader(const std::shared_ptr<const class shader_base>& shader)
+{
+ _shader = shader;
+}
+
+
+/////////////
+// Methods //
+/////////////
+color intersectionPoint::shade(const vec3d& out) const
+{
+ assert(hasShader());
+ if(!_hit) return color(0.0f);
+ return _shader->shade(*this, out);
+}
+
+color intersectionPoint::shade(const lightSample& ls) const
+{
+ assert(hasShader());
+ if(!_hit) return color(0.0f);
+ return _shader->shade(*this, ls.directionToLight()) * ls.emittance();
+}
+
+
+float intersectionPoint::reflectivity(void) const
+{
+ assert(hasShader());
+
+ // get reflectivity
+ float albedo = _shader->reflectivity(*this);
+
+ // cannot reflect more than 100%
+ assert(albedo <= 1.0f);
+
+ // Done.
+ return albedo;
+}
+
+
+color intersectionPoint::reflectance(const vec3d& out) const
+{
+ assert(hasShader());
+ return _shader->reflectance(*this, out);
+}
+
+
+brdfSample intersectionPoint::sample(float r1, float r2) const
+{
+ assert(hasShader());
+ return _shader->sample(*this, r1, r2);
+}
+
+
+color intersectionPoint::emittance(void) const
+{
+ assert(hasShader());
+ return _shader->emittance(*this);
+}
+
+
+/////////////////////
+// Private Methods //
+/////////////////////
+void intersectionPoint::_assign(const intersectionPoint& ip)
+{
+ // sanity check
+ if(&ip == this) return;
+
+ // copy if hit
+ _hit = ip._hit;
+ if(_hit)
+ {
+ _ray = ip._ray;
+ _rayParameter = ip._rayParameter;
+ _position = ip._position;
+ _normal = ip._normal;
+ _axis = ip._axis;
+ _textureCoordinate = ip._textureCoordinate;
+ _shader = ip._shader;
+ }
+ else _shader = nullptr;
+}
+
+
+void intersectionPoint::_swap(intersectionPoint& ip)
+{
+ swap(_ray, ip._ray);
+ std::swap(_hit, ip._hit);
+ std::swap(_rayParameter, ip._rayParameter);
+ swap(_position, ip._position);
+ swap(_normal, ip._normal);
+ swap(_axis, ip._axis);
+ swap(_textureCoordinate, ip._textureCoordinate);
+ std::swap(_shader, ip._shader);
+}
+