diff options
Diffstat (limited to 'hw6/src/intersectionPoint.cpp')
-rw-r--r-- | hw6/src/intersectionPoint.cpp | 342 |
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); +} + |