#ifndef SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP #define SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP #include #include #include #include namespace sprout { namespace darkroom { namespace objects { // // intersect // template SPROUT_CONSTEXPR inline typename Object::template intersection::type intersect(Object const& obj, Ray const& ray) { return obj.intersect(ray); } // // intersect_list // namespace detail { template struct intersect_list_impl { private: template SPROUT_CONSTEXPR typename sprout::darkroom::access::unit::type ::template intersection::type comp(A const& a, B const& b) const { return sprout::darkroom::intersects::does_intersect(a) && sprout::darkroom::intersects::does_intersect(b) ? sprout::darkroom::intersects::distance(a) < sprout::darkroom::intersects::distance(b) ? a : b : sprout::darkroom::intersects::does_intersect(a) ? a : b ; } public: template SPROUT_CONSTEXPR typename sprout::darkroom::access::unit::type ::template intersection::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::access::unit::type ::template intersection::type operator()(Objects const& objs, Ray const& ray) const { return sprout::darkroom::objects::intersect(sprout::darkroom::access::get<0>(objs), ray); } }; } // namespace detail template SPROUT_CONSTEXPR inline typename sprout::darkroom::access::unit::type ::template intersection::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); } } // namespace objects } // namespace darkroom } // namespace sprout #endif // #ifndef SPROUT_DARKROOM_OBJECTS_INTERSECT_HPP