/******************************************************************/ /* 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 #include #include "boundedVolumeNode.h" #include "random_number.h" boundedVolumeNode::boundedVolumeNode(const std::vector>::iterator& start, const std::vector>::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& 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& 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(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(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); }