diff options
author | 53hornet <53hornet@gmail.com> | 2019-02-02 23:33:15 -0500 |
---|---|---|
committer | 53hornet <53hornet@gmail.com> | 2019-02-02 23:33:15 -0500 |
commit | db072ad4dc181eca5a1458656b130beb43f475bf (patch) | |
tree | a3c03c7f5497cb70503e2486662fa85cfb53415a /hw5/src/boundedVolumeNode.cpp | |
download | csci427-master.tar.xz csci427-master.zip |
Diffstat (limited to 'hw5/src/boundedVolumeNode.cpp')
-rw-r--r-- | hw5/src/boundedVolumeNode.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/hw5/src/boundedVolumeNode.cpp b/hw5/src/boundedVolumeNode.cpp new file mode 100644 index 0000000..577e855 --- /dev/null +++ b/hw5/src/boundedVolumeNode.cpp @@ -0,0 +1,71 @@ +/******************************************************************/ +/* 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 <algorithm> + +#include "boundedVolumeNode.h" +#include "random_number.h" + +boundedVolumeNode::boundedVolumeNode(const std::vector<std::shared_ptr<const boundedPrimitive>>::iterator& start, const std::vector<std::shared_ptr<const boundedPrimitive>>::iterator& end) + + : _left(nullptr), _right(nullptr), boundedPrimitive() +{ + assert(std::distance(start, end) > 1); + + // compute the bounding box + for_each(start, end, [&](const std::shared_ptr<const boundedPrimitive>& prim) + { + _bb += prim->boundingbox(); + }); + + // select random splitting dimension & pivot + unsigned int split = random_int(2); + float pivot = _bb.center()[split]; + + // partition + auto middle = std::partition(start, end, [&](const std::shared_ptr<const boundedPrimitive>& prim) + { + return prim->boundingbox().center()[split] < pivot; + }); + + // special case: all centers are the same. + if(start == middle) middle++; + + // create _left (recurse if more than one primitive) + if(std::distance(start, middle) == 1) + _left = *start; + else + _left = std::shared_ptr<const boundedPrimitive>(new boundedVolumeNode(start, middle)); + + // create _right (recurse if more than one primitive) + if(std::distance(middle, end) == 1) + _right = *middle; + else + _right = std::shared_ptr<const boundedPrimitive>(new boundedVolumeNode(middle, end)); + + // Done. +} + +intersectionPoint boundedVolumeNode::intersect(const ray& r) const +{ + intersectionPoint leftIp, rightIp; + + // check left child + if(_left && _left->hitBoundingBox(r)) + leftIp = _left->intersect(r); + + // check right child + if(_right && _right->hitBoundingBox(r)) + rightIp = _right->intersect(r); + + // return closest + return std::min(leftIp, rightIp); +} + + |