/*============================================================================= Copyright (c) 2011-2019 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP #define SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP #include #include #include #include #include #include #include namespace sprout { namespace darkroom { namespace objects { template struct intersection_result; namespace detail { template struct intersection_result_impl; template struct intersection_result_impl > : public sprout::tuples::common_recursive_flex_type< typename sprout::darkroom::objects::intersection_result::type, Ray>::type... > {}; template struct intersection_result; template struct intersection_result : public Object::template intersection {}; template struct intersection_result : public sprout::darkroom::objects::detail::intersection_result_impl< Object, Ray, typename sprout::make_index_tuple::value>::type > {}; } // namespace detail // // intersection_result // template struct intersection_result : public sprout::darkroom::objects::detail::intersection_result< Object, Ray, sprout::darkroom::access::is_tuple::value > {}; template struct intersection_result : public sprout::darkroom::objects::intersection_result {}; template struct intersection_result : public sprout::darkroom::objects::intersection_result {}; template struct intersection_result : public sprout::darkroom::objects::intersection_result {}; // // intersect // template< typename Object, typename Ray, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type intersect(Object const& obj, Ray const& ray); template< typename Object, typename Ray, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type intersect(Object const& obj, Ray const& ray); namespace detail { template struct intersect_list_impl { private: template SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type comp(A const& a, B const& b) const { typedef typename sprout::darkroom::objects::intersection_result::type type; return sprout::darkroom::intersects::does_intersect(a) && sprout::darkroom::intersects::does_intersect(b) ? sprout::darkroom::intersects::distance(a) < sprout::darkroom::intersects::distance(b) ? sprout::tuples::recursive_flex(a) : sprout::tuples::recursive_flex(b) : sprout::darkroom::intersects::does_intersect(a) ? sprout::tuples::recursive_flex(a) : sprout::tuples::recursive_flex(b) ; } public: template SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type operator()(Objects const& objs, Ray const& ray) const { return comp( sprout::darkroom::objects::intersect(sprout::darkroom::access::get(objs), ray), intersect_list_impl()(objs, ray) ); } }; template<> struct intersect_list_impl<0> { public: template SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type operator()(Objects const& objs, Ray const& ray) const { return sprout::tuples::recursive_flex( sprout::darkroom::objects::intersect(sprout::darkroom::access::get<0>(objs), ray) ); } }; } // namespace detail // // intersect_list // template inline SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type intersect_list(Objects const& objs, Ray const& ray) { return sprout::darkroom::objects::detail::intersect_list_impl< sprout::darkroom::access::size::value - 1 >()(objs, ray); } // // intersect // template< typename Object, typename Ray, typename sprout::enabler_if::value>::type > inline SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type intersect(Object const& obj, Ray const& ray) { return obj.intersect(ray); } template< typename Object, typename Ray, typename sprout::enabler_if::value>::type > inline SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result::type intersect(Object const& obj, Ray const& ray) { return sprout::darkroom::objects::intersect_list(obj, ray); } } // namespace objects } // namespace darkroom } // namespace sprout #endif // #ifndef SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP