#pragma once #ifndef __BOUNDINGBOX_HPP__ #define __BOUNDINGBOX_HPP__ #include "Vector3.hpp" #include <type_traits> #include <iterator> #include <numeric> #include <functional> #include <array> namespace Math { class BoundingBox { public: enum BoxCorner { NEAR_BOTTOM_LEFT, NEAR_BOTTOM_RIGHT, NEAR_TOP_LEFT, NEAR_TOP_RIGHT, FAR_BOTTOM_LEFT, FAR_BOTTOM_RIGHT, FAR_TOP_LEFT, FAR_TOP_RIGHT }; typedef std::array<Vector3, 8> CornerArray; private: Vector3 minimum_; Vector3 maximum_; public: //-------------------------------------------------------------------------- // Constructors // BoundingBox(); BoundingBox(const Vector3& minimum, const Vector3& maximum); BoundingBox(const BoundingBox& box) : minimum_(box.minimum_), maximum_(box.maximum_) { } //-------------------------------------------------------------------------- // Assignment // BoundingBox& operator = (const BoundingBox& box) { minimum_ = box.minimum_; maximum_ = box.maximum_; return *this; } //-------------------------------------------------------------------------- // Comparison // bool operator == (const BoundingBox& box) const { return minimum_ == box.minimum_ && maximum_ == box.maximum_; } bool operator != (const BoundingBox& box) const { return minimum_ != box.minimum_ || maximum_ != box.maximum_; } bool contains(const Vector3& point) const; bool is_empty() const { return minimum_ == maximum_; } //-------------------------------------------------------------------------- // Accessors // void set(const Vector3& minimum, const Vector3& maximum); const Vector3& minimum_corner() const { return minimum_; } const Vector3& maximum_corner() const { return maximum_; } Vector3 get_corner(BoxCorner corner) const; CornerArray get_all_corners() const; //-------------------------------------------------------------------------- // Computation // static BoundingBox compute_containing_box(const BoundingBox& a, const BoundingBox& b); template <class Iterator> typename std::enable_if<std::is_same<typename std::iterator_traits<Iterator>::value_type, BoundingBox>::value, BoundingBox>::type static compute_containing_box(Iterator begin, Iterator end) { if (begin != end) { BoundingBox bounds = *begin++; return std::accumulate(begin, end, bounds, std::ptr_fun(&compute_containing_box)); } return BoundingBox(); } }; } // namespace Math #endif // __BOUNDINGBOX_HPP__