summaryrefslogtreecommitdiff
path: root/hw2/src/boundingBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hw2/src/boundingBox.cpp')
-rw-r--r--hw2/src/boundingBox.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/hw2/src/boundingBox.cpp b/hw2/src/boundingBox.cpp
new file mode 100644
index 0000000..9708093
--- /dev/null
+++ b/hw2/src/boundingBox.cpp
@@ -0,0 +1,185 @@
+/******************************************************************/
+/* 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 "interval.h"
+#include "constants.h"
+#include "boundingBox.h"
+
+
+/////////////////
+// Constructor //
+/////////////////
+boundingBox::boundingBox(void)
+{
+ // create an empty box (i.e., 'left' lies right of 'right')
+ _lfb = vec3d(+LARGE);
+ _rbt = vec3d(-LARGE);
+}
+
+
+boundingBox::boundingBox(const vec3d& lfb, const vec3d& rbt)
+{
+ _lfb = lfb;
+ _rbt = rbt;
+
+ // Make sure each component in _lfb is smaller than _rbt
+ for(unsigned int i=0; i < vec3d::size(); i++)
+ if(_rbt[i] < _lfb[i]) std::swap(_rbt[i], _lfb[i]);
+
+ // Done.
+}
+
+
+boundingBox::boundingBox(const boundingBox& bb)
+{
+ _lfb = bb._lfb;
+ _rbt = bb._rbt;
+}
+
+
+//////////////
+// Operator //
+//////////////
+boundingBox& boundingBox::operator=(const boundingBox& src)
+{
+ _assign(src);
+ return *this;
+}
+
+
+boundingBox& boundingBox::operator+=(const boundingBox& bb)
+{
+ // compute the union of two bounding boxes
+ for(unsigned int i=0; i < vec3d::size(); i++)
+ {
+ if(_lfb[i] > bb._lfb[i]) _lfb[i] = bb._lfb[i];
+ if(_rbt[i] < bb._rbt[i]) _rbt[i] = bb._rbt[i];
+ }
+
+ return *this;
+}
+
+
+boundingBox boundingBox::operator+(const boundingBox& bb) const
+{
+ boundingBox result(*this);
+ result += bb;
+ return result;
+}
+
+
+boundingBox& boundingBox::operator+=(const vec3d& point)
+{
+ // expand the bounding box to include 'point' (+ a small epsilon)
+ for(unsigned int i=0; i < vec3d::size(); i++)
+ {
+ if(_lfb[i] > point[i]-EPSILON) _lfb[i] = point[i]-EPSILON;
+ if(_rbt[i] < point[i]+EPSILON) _rbt[i] = point[i]+EPSILON;
+ }
+}
+
+
+/////////////
+// Methods //
+/////////////
+bool boundingBox::isHit(const ray& r) const
+{
+ // init
+ interval boxInterval(0, +LARGE);
+
+ // for every slab
+ for(unsigned int i=0; i != vec3d::size(); i++)
+ {
+ // compute the slab
+ interval slab(_lfb[i], _rbt[i]);
+ slab -= r.origin()[i];
+
+ // check for the case where the ray is parallel to the slab
+ if(fabs(r.direction()[i]) < EPSILON)
+ {
+ // if identical signs => no hit
+ if((slab.lower() < 0.0f) == (slab.upper() < 0.0f))
+ return false;
+
+ // skip remainder to this iteration
+ continue;
+ }
+ else
+ slab /= r.direction()[i];
+
+ // intersect
+ boxInterval.intersect(slab);
+ if(boxInterval.empty())
+ return false;
+ }
+
+ // Done.
+ return true;
+}
+
+
+vec3d boundingBox::center(void) const
+{
+ return 0.5f * (_lfb + _rbt);
+}
+
+
+vec3d boundingBox::corner(bool left, bool front, bool bottom) const
+{
+ return vec3d( left ? _lfb.x : _rbt.x,
+ front ? _lfb.y : _rbt.y,
+ bottom ? _lfb.z : _rbt.z );
+}
+
+
+//////////////
+// Mutators //
+//////////////
+boundingBox& boundingBox::transform(const transformation3d& t)
+{
+ boundingBox result;
+ for(unsigned int i=0; i <= 1; i++)
+ for(unsigned int j=0; j <= 1; j++)
+ for(unsigned int k=0; k <= 1; k++)
+ result += t.transformPoint(corner(i,j,k));
+
+ // Done.
+ _swap(result);
+ return *this;
+}
+
+
+boundingBox& boundingBox::inverseTransform(const transformation3d& t)
+{
+ boundingBox result;
+ for(unsigned int i=0; i <= 1; i++)
+ for(unsigned int j=0; j <= 1; j++)
+ for(unsigned int k=0; k <= 1; k++)
+ result += t.inverseTransformPoint(corner(i,j,k));
+
+ // Done.
+ _swap(result);
+ return *this;
+}
+
+/////////////////////
+// Private Methods //
+/////////////////////
+void boundingBox::_swap(boundingBox& bb)
+{
+ swap(_lfb, bb._lfb);
+ swap(_rbt, bb._rbt);
+}
+
+
+void boundingBox::_assign(const boundingBox& bb)
+{
+ _lfb = bb._lfb;
+ _rbt = bb._rbt;
+}