1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

[sprout.darkroom] implement refraction process

This commit is contained in:
bolero-MURAKAMI 2013-12-12 23:29:50 +09:00
parent 8e306168da
commit 63ac0d0df5
10 changed files with 494 additions and 69 deletions

View file

@ -218,14 +218,70 @@ namespace sprout {
// //
// refract // refract
// //
// namespace detail {
// template<typename Incident, typename Normal, typename Refraction, typename InNor, typename K>
// inline SPROUT_CONSTEXPR Incident
// refract_impl_1(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t, K const& k) {
// return k < 0 ? sprout::tuples::remake<Incident>(incid, 0, 0, 0)
// : sprout::darkroom::coords::sub(
// sprout::darkroom::coords::scale(incid, eta),
// sprout::darkroom::coords::scale(nor, eta * t * sprout::sqrt(k))
// )
// ;
// }
// template<typename Incident, typename Normal, typename Refraction, typename InNor>
// inline SPROUT_CONSTEXPR Incident
// refract_impl(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t) {
// return sprout::darkroom::coords::detail::refract_impl_1(
// incid, nor, eta,
// t, 1 - eta * eta * (1 - t * t)
// );
// }
// } // namespace detail
// template<typename Incident, typename Normal, typename Refraction>
// inline SPROUT_CONSTEXPR Incident
// refract(Incident const& incid, Normal const& nor, Refraction const& eta) {
// return sprout::darkroom::coords::detail::refract_impl(
// incid, nor, eta,
// sprout::darkroom::coords::dot(incid, nor)
// );
// }
// namespace detail {
// template<typename Incident, typename Normal, typename Refraction, typename InNor, typename K>
// inline SPROUT_CONSTEXPR Incident
// refract_impl_1(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t, K const& k) {
// return k < 0 ? sprout::tuples::remake<Incident>(incid, 0, 0, 0)
// : sprout::darkroom::coords::sub(
// sprout::darkroom::coords::scale(sprout::darkroom::coords::sub(incid, sprout::darkroom::coords::scale(nor, t)), eta),
// sprout::darkroom::coords::scale(nor, eta * t * sprout::math::sqrt(k))
// )
// ;
// }
// template<typename Incident, typename Normal, typename Refraction, typename InNor>
// inline SPROUT_CONSTEXPR Incident
// refract_impl(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t) {
// return sprout::darkroom::coords::detail::refract_impl_1(
// incid, nor, eta,
// t, 1 - eta * eta * (1 - t * t)
// );
// }
// } // namespace detail
// template<typename Incident, typename Normal, typename Refraction>
// inline SPROUT_CONSTEXPR Incident
// refract(Incident const& incid, Normal const& nor, Refraction const& eta) {
// return sprout::darkroom::coords::detail::refract_impl(
// incid, nor, eta,
// sprout::darkroom::coords::dot(incid, nor)
// );
// }
namespace detail { namespace detail {
template<typename Incident, typename Normal, typename Refraction, typename InNor, typename K> template<typename Incident, typename Normal, typename Refraction, typename InNor, typename K>
inline SPROUT_CONSTEXPR Incident inline SPROUT_CONSTEXPR Incident
refract_impl_1(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t, K const& k) { refract_impl_1(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t, K const& k) {
return k < 0 ? sprout::tuples::remake<Incident>(incid, 0, 0, 0) return k < 0 ? sprout::tuples::remake<Incident>(incid, 0, 0, 0)
: sprout::darkroom::coords::sub( : sprout::darkroom::coords::scale(
sprout::darkroom::coords::scale(incid, eta), sprout::darkroom::coords::add(incid, sprout::darkroom::coords::scale(nor, t - sprout::math::sqrt(k))),
sprout::darkroom::coords::scale(nor, eta * t * sprout::sqrt(k)) 1 / eta
) )
; ;
} }
@ -234,7 +290,7 @@ namespace sprout {
refract_impl(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t) { refract_impl(Incident const& incid, Normal const& nor, Refraction const& eta, InNor const& t) {
return sprout::darkroom::coords::detail::refract_impl_1( return sprout::darkroom::coords::detail::refract_impl_1(
incid, nor, eta, incid, nor, eta,
t, 1 - eta * eta * (1 - t * t) t, eta * eta + t * t - 1
); );
} }
} // namespace detail } // namespace detail
@ -243,7 +299,7 @@ namespace sprout {
refract(Incident const& incid, Normal const& nor, Refraction const& eta) { refract(Incident const& incid, Normal const& nor, Refraction const& eta) {
return sprout::darkroom::coords::detail::refract_impl( return sprout::darkroom::coords::detail::refract_impl(
incid, nor, eta, incid, nor, eta,
sprout::darkroom::coords::dot(incid, nor) -sprout::darkroom::coords::dot(incid, nor)
); );
} }
} // namespace coords } // namespace coords

View file

@ -143,7 +143,7 @@ namespace sprout {
refraction(T&&) refraction(T&&)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR((typename sprout::darkroom::access::element<3, sprout::darkroom::materials::material>::type()))) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR((typename sprout::darkroom::access::element<3, sprout::darkroom::materials::material>::type())))
{ {
return typename sprout::darkroom::access::element<1, sprout::darkroom::materials::material>::type(); return typename sprout::darkroom::access::element<3, sprout::darkroom::materials::material>::type();
} }
// //

View file

@ -10,6 +10,7 @@
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/tuple/flex.hpp>
#include <sprout/type_traits/enabler_if.hpp> #include <sprout/type_traits/enabler_if.hpp>
#include <sprout/darkroom/access/traits.hpp> #include <sprout/darkroom/access/traits.hpp>
#include <sprout/darkroom/access/access.hpp> #include <sprout/darkroom/access/access.hpp>
@ -22,16 +23,27 @@ namespace sprout {
struct intersection_result; struct intersection_result;
namespace detail { namespace detail {
template<typename Object, typename Ray, typename IndexTuple>
struct intersection_result_impl;
template<typename Object, typename Ray, sprout::index_t... Indexes>
struct intersection_result_impl<Object, Ray, sprout::index_tuple<Indexes...> >
: public sprout::tuples::common_recursive_flex_type<
typename sprout::darkroom::objects::intersection_result<typename sprout::darkroom::access::element<Indexes, Object>::type, Ray>::type...
>
{};
template<typename Object, typename Ray, bool IsTuple> template<typename Object, typename Ray, bool IsTuple>
struct intersection_result; struct intersection_result;
template<typename Object, typename Ray> template<typename Object, typename Ray>
struct intersection_result<Object, Ray, false> struct intersection_result<Object, Ray, false>
: public Object::template intersection<Ray> : public Object::template intersection<Ray>
{}; {};
template<typename Object, typename Ray> template<typename Object, typename Ray>
struct intersection_result<Object, Ray, true> struct intersection_result<Object, Ray, true>
: public sprout::darkroom::objects::intersection_result<typename sprout::darkroom::access::unit<Object>::type, Ray> : public sprout::darkroom::objects::detail::intersection_result_impl<
Object, Ray,
typename sprout::make_index_tuple<sprout::darkroom::access::size<Object>::value>::type
>
{}; {};
} // namespace detail } // namespace detail
@ -81,14 +93,15 @@ namespace sprout {
template<typename Objects, typename Ray, typename A, typename B> template<typename Objects, typename Ray, typename A, typename B>
SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result<Objects, Ray>::type SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result<Objects, Ray>::type
comp(A const& a, B const& b) const { comp(A const& a, B const& b) const {
typedef typename sprout::darkroom::objects::intersection_result<Objects, Ray>::type type;
return sprout::darkroom::intersects::does_intersect(a) return sprout::darkroom::intersects::does_intersect(a)
&& sprout::darkroom::intersects::does_intersect(b) && sprout::darkroom::intersects::does_intersect(b)
? sprout::darkroom::intersects::distance(a) < sprout::darkroom::intersects::distance(b) ? sprout::darkroom::intersects::distance(a) < sprout::darkroom::intersects::distance(b)
? a ? sprout::tuples::recursive_flex<type>(a)
: b : sprout::tuples::recursive_flex<type>(b)
: sprout::darkroom::intersects::does_intersect(a) : sprout::darkroom::intersects::does_intersect(a)
? a ? sprout::tuples::recursive_flex<type>(a)
: b : sprout::tuples::recursive_flex<type>(b)
; ;
} }
public: public:
@ -107,7 +120,9 @@ namespace sprout {
template<typename Objects, typename Ray> template<typename Objects, typename Ray>
SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result<Objects, Ray>::type SPROUT_CONSTEXPR typename sprout::darkroom::objects::intersection_result<Objects, Ray>::type
operator()(Objects const& objs, Ray const& ray) const { operator()(Objects const& objs, Ray const& ray) const {
return sprout::darkroom::objects::intersect(sprout::darkroom::access::get<0>(objs), ray); return sprout::tuples::recursive_flex(
sprout::darkroom::objects::intersect(sprout::darkroom::access::get<0>(objs), ray)
);
} }
}; };
} // namespace detail } // namespace detail

View file

@ -16,6 +16,7 @@
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/container/indexes.hpp> #include <sprout/container/indexes.hpp>
#include <sprout/darkroom/colors/rgb.hpp> #include <sprout/darkroom/colors/rgb.hpp>
#include <sprout/darkroom/renderers/calculate.hpp>
#include <sprout/darkroom/tracers/calculate.hpp> #include <sprout/darkroom/tracers/calculate.hpp>
namespace sprout { namespace sprout {
@ -114,7 +115,7 @@ namespace sprout {
>::static_size, >::static_size,
typename sprout::container_traits<Pixels>::size_type height typename sprout::container_traits<Pixels>::size_type height
= sprout::container_traits<Pixels>::static_size, = sprout::container_traits<Pixels>::static_size,
std::size_t depth_max = 8 std::size_t depth_max = sprout::darkroom::renderers::default_depth
) )
{ {
return sprout::darkroom::pixels::detail::generate_impl<Pixels>( return sprout::darkroom::pixels::detail::generate_impl<Pixels>(

View file

@ -15,29 +15,44 @@
namespace sprout { namespace sprout {
namespace darkroom { namespace darkroom {
namespace renderers { namespace renderers {
//
//
//
SPROUT_STATIC_CONSTEXPR std::size_t default_depth = 4;
// //
// calculate_result // calculate_result
// //
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions = double>
struct calculate_result struct calculate_result
: public sprout::identity<Color> : public sprout::identity<Color>
{}; {};
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions>
struct calculate_result<Color, Renderer const, Camera, Objects, Lights, Ray> struct calculate_result<Color, Renderer const, Camera, Objects, Lights, Ray, Refractions>
: public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray> : public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray, Refractions>
{}; {};
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions>
struct calculate_result<Color, Renderer volatile, Camera, Objects, Lights, Ray> struct calculate_result<Color, Renderer volatile, Camera, Objects, Lights, Ray, Refractions>
: public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray> : public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray, Refractions>
{}; {};
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions>
struct calculate_result<Color, Renderer const volatile, Camera, Objects, Lights, Ray> struct calculate_result<Color, Renderer const volatile, Camera, Objects, Lights, Ray, Refractions>
: public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray> : public sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray, Refractions>
{}; {};
// //
// calculate // calculate
// //
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions>
inline SPROUT_CONSTEXPR typename sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray, Refractions>::type
calculate(
Renderer const& renderer,
Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, std::size_t depth_max, Refractions const& refracs
)
{
return renderer.template operator()<Color>(camera, objs, lights, ray, depth_max, refracs);
}
template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Renderer, typename Camera, typename Objects, typename Lights, typename Ray>
inline SPROUT_CONSTEXPR typename sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray>::type inline SPROUT_CONSTEXPR typename sprout::darkroom::renderers::calculate_result<Color, Renderer, Camera, Objects, Lights, Ray>::type
calculate( calculate(

View file

@ -12,7 +12,13 @@
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/limits.hpp> #include <sprout/limits.hpp>
#include <sprout/utility/pair.hpp>
#include <sprout/tuple/functions.hpp> #include <sprout/tuple/functions.hpp>
#include <sprout/tuple/tuple/type_traits.hpp>
#include <sprout/tuple/tuple/make_tuple.hpp>
#include <sprout/tuple/tuple/get.hpp>
//#include <sprout/tuple/operation/push_back.hpp>
//#include <sprout/tuple/operation/pop_back.hpp>
#include <sprout/darkroom/access/access.hpp> #include <sprout/darkroom/access/access.hpp>
#include <sprout/darkroom/colors/rgb.hpp> #include <sprout/darkroom/colors/rgb.hpp>
#include <sprout/darkroom/coords/vector.hpp> #include <sprout/darkroom/coords/vector.hpp>
@ -35,14 +41,14 @@ namespace sprout {
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer, typename Ray, typename Refractions, typename Intersection, typename Renderer,
typename Direction typename Direction
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
color_1( color_1(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer, Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max, std::size_t depth_max, Refractions const& refracs,
Direction const& new_dir Direction const& new_dir
) const ) const
{ {
@ -54,20 +60,21 @@ namespace sprout {
sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir), sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir),
new_dir new_dir
), ),
depth_max - 1 depth_max - 1,
refracs
); );
} }
public: public:
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer typename Ray, typename Refractions, typename Intersection, typename Renderer
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
operator()( operator()(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer, Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max std::size_t depth_max, Refractions const& refracs
) const ) const
{ {
typedef typename std::decay< typedef typename std::decay<
@ -80,7 +87,7 @@ namespace sprout {
? color_1<Color>( ? color_1<Color>(
camera, objs, lights, camera, objs, lights,
ray, inter, renderer, ray, inter, renderer,
depth_max, depth_max, refracs,
sprout::darkroom::coords::reflect( sprout::darkroom::coords::reflect(
sprout::darkroom::rays::direction(ray), sprout::darkroom::rays::direction(ray),
sprout::darkroom::intersects::normal(inter) sprout::darkroom::intersects::normal(inter)
@ -91,49 +98,68 @@ namespace sprout {
} }
}; };
// //
// whitted_transparent // whitted_transmit
// //
class whitted_transparent { class whitted_transmit {
private: private:
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer, typename Ray, typename Refractions, typename Intersection, typename Renderer,
typename Direction typename Direction
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR sprout::pair<Color, bool>
color_1( color_1(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer, Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max, std::size_t depth_max, Refractions const& refracs,
Direction const& new_dir Direction const& new_dir
) const ) const
{ {
return !sprout::darkroom::coords::is_zero(new_dir) return sprout::darkroom::coords::is_zero(new_dir) ? sprout::pair<Color, bool>(sprout::tuples::make<Color>(0, 0, 0), true)
? sprout::darkroom::renderers::calculate<Color>( : sprout::darkroom::intersects::is_from_inside(inter) ? sprout::pair<Color, bool>(
renderer, sprout::darkroom::renderers::calculate<Color>(
camera, objs, lights, renderer,
sprout::tuples::remake<Ray>( camera, objs, lights,
ray, sprout::tuples::remake<Ray>(
sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir), ray,
new_dir sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir),
new_dir
),
depth_max - 1,
sprout::tuples::remake<Refractions>(refracs, 1.0)
//sprout::tuples::pop_back(refracs)
), ),
depth_max - 1 false
)
: sprout::pair<Color, bool>(
sprout::darkroom::renderers::calculate<Color>(
renderer,
camera, objs, lights,
sprout::tuples::remake<Ray>(
ray,
sprout::darkroom::rays::detach_position(sprout::darkroom::intersects::point_of_intersection(inter), new_dir),
new_dir
),
depth_max - 1,
sprout::tuples::remake<Refractions>(refracs, sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter)))
//sprout::tuples::push_back(refracs, sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter)))
),
false
) )
: sprout::tuples::make<Color>(0, 0, 0)
; ;
} }
public: public:
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection, typename Renderer typename Ray, typename Refractions, typename Intersection, typename Renderer
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR sprout::pair<Color, bool>
operator()( operator()(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, Intersection const& inter, Renderer const& renderer, Ray const& ray, Intersection const& inter, Renderer const& renderer,
std::size_t depth_max std::size_t depth_max, Refractions const& refracs
) const ) const
{ {
typedef typename std::decay< typedef typename std::decay<
@ -151,16 +177,18 @@ namespace sprout {
? color_1<Color>( ? color_1<Color>(
camera, objs, lights, camera, objs, lights,
ray, inter, renderer, ray, inter, renderer,
depth_max, depth_max, refracs,
sprout::darkroom::coords::refract( sprout::darkroom::coords::refract(
sprout::darkroom::rays::direction(ray), sprout::darkroom::rays::direction(ray),
sprout::darkroom::intersects::normal(inter), sprout::darkroom::intersects::normal(inter),
sprout::darkroom::intersects::is_from_inside(inter) sprout::darkroom::intersects::is_from_inside(inter)
? 1 / sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter)) ? sprout::tuples::get<sprout::tuples::tuple_size<Refractions>::value - 1>(refracs)
/ sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter))
: sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter)) : sprout::darkroom::materials::refraction(sprout::darkroom::intersects::material(inter))
/ sprout::tuples::get<sprout::tuples::tuple_size<Refractions>::value - 1>(refracs)
) )
) )
: sprout::tuples::make<Color>(0, 0, 0) : sprout::pair<Color, bool>(sprout::tuples::make<Color>(0, 0, 0), false)
; ;
} }
}; };
@ -174,11 +202,11 @@ namespace sprout {
private: private:
infinity_color_type infinity_color_; infinity_color_type infinity_color_;
private: private:
template<typename Color, typename Ray, typename Intersection> template<typename Color, typename Ray, typename Intersection, typename DiffuseColor, typename MirrorColor, typename TransparentColors>
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
color_3( color_3(
Ray const& ray, Intersection const& inter, Ray const& ray, Intersection const& inter,
Color const& diffuse_color, Color const& mirror_color, Color const& transparent_color DiffuseColor const& diffuse_color, MirrorColor const& mirror_color, TransparentColors const& transmit_colors
) const ) const
{ {
return sprout::darkroom::intersects::does_intersect(inter) return sprout::darkroom::intersects::does_intersect(inter)
@ -191,11 +219,16 @@ namespace sprout {
), ),
sprout::darkroom::colors::mul( sprout::darkroom::colors::mul(
mirror_color, mirror_color,
sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter)) !transmit_colors.second
? sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter))
: sprout::darkroom::materials::reflection(sprout::darkroom::intersects::material(inter))
+ sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter))
), ),
sprout::darkroom::colors::mul( sprout::darkroom::colors::mul(
transparent_color, transmit_colors.first,
sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter)) !transmit_colors.second
? sprout::darkroom::materials::alpha(sprout::darkroom::intersects::material(inter))
: 0
) )
) )
: sprout::darkroom::renderers::calculate_infinity<Color>(infinity_color_, sprout::darkroom::rays::direction(ray)) : sprout::darkroom::renderers::calculate_infinity<Color>(infinity_color_, sprout::darkroom::rays::direction(ray))
@ -204,12 +237,12 @@ namespace sprout {
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection typename Ray, typename Refractions, typename Intersection
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
color_2( color_2(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, std::size_t depth_max, Intersection const& inter, Ray const& ray, std::size_t depth_max, Refractions const& refracs, Intersection const& inter,
Color const& diffuse_color Color const& diffuse_color
) const ) const
{ {
@ -219,29 +252,29 @@ namespace sprout {
sprout::darkroom::renderers::whitted_mirror().template operator()<Color>( sprout::darkroom::renderers::whitted_mirror().template operator()<Color>(
camera, objs, lights, camera, objs, lights,
ray, inter, *this, ray, inter, *this,
depth_max depth_max, refracs
), ),
sprout::darkroom::renderers::whitted_transparent().template operator()<Color>( sprout::darkroom::renderers::whitted_transmit().template operator()<Color>(
camera, objs, lights, camera, objs, lights,
ray, inter, *this, ray, inter, *this,
depth_max depth_max, refracs
) )
); );
} }
template< template<
typename Color, typename Color,
typename Camera, typename Objects, typename Lights, typename Camera, typename Objects, typename Lights,
typename Ray, typename Intersection typename Ray, typename Refractions, typename Intersection
> >
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
color_1( color_1(
Camera const& camera, Objects const& objs, Lights const& lights, Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, std::size_t depth_max, Intersection const& inter Ray const& ray, std::size_t depth_max, Refractions const& refracs, Intersection const& inter
) const ) const
{ {
return color_2<Color>( return color_2<Color>(
camera, objs, lights, camera, objs, lights,
ray, depth_max, inter, ray, depth_max, refracs, inter,
sprout::darkroom::lights::calculate(lights, inter, objs) sprout::darkroom::lights::calculate(lights, inter, objs)
); );
} }
@ -253,6 +286,37 @@ namespace sprout {
explicit SPROUT_CONSTEXPR whitted_style(infinity_color_type const& infinity_color) explicit SPROUT_CONSTEXPR whitted_style(infinity_color_type const& infinity_color)
: infinity_color_(infinity_color) : infinity_color_(infinity_color)
{} {}
template<
typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions,
typename sprout::enabler_if<sprout::tuples::is_tuple<Refractions>::value>::type = sprout::enabler
>
SPROUT_CONSTEXPR Color
operator()(
Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, std::size_t depth_max, Refractions const& refracs
) const
{
return color_1<Color>(
camera, objs, lights,
ray, depth_max, refracs,
sprout::darkroom::objects::intersect(objs, ray)
);
}
template<
typename Color, typename Camera, typename Objects, typename Lights, typename Ray, typename Refractions,
typename sprout::enabler_if<!sprout::tuples::is_tuple<Refractions>::value>::type = sprout::enabler
>
SPROUT_CONSTEXPR Color
operator()(
Camera const& camera, Objects const& objs, Lights const& lights,
Ray const& ray, std::size_t depth_max, Refractions const& refracs
) const
{
return operator()<Color>(
camera, objs, lights,
ray, depth_max, sprout::tuples::make_tuple(refracs)
);
}
template<typename Color, typename Camera, typename Objects, typename Lights, typename Ray> template<typename Color, typename Camera, typename Objects, typename Lights, typename Ray>
SPROUT_CONSTEXPR Color SPROUT_CONSTEXPR Color
operator()( operator()(
@ -260,10 +324,9 @@ namespace sprout {
Ray const& ray, std::size_t depth_max Ray const& ray, std::size_t depth_max
) const ) const
{ {
return color_1<Color>( return operator()<Color>(
camera, objs, lights, camera, objs, lights,
ray, depth_max, ray, depth_max, sprout::tuples::make_tuple(1.0)
sprout::darkroom::objects::intersect(objs, ray)
); );
} }
}; };

View file

@ -11,6 +11,7 @@
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type_traits/identity.hpp> #include <sprout/type_traits/identity.hpp>
#include <sprout/darkroom/renderers/calculate.hpp>
namespace sprout { namespace sprout {
namespace darkroom { namespace darkroom {
@ -38,13 +39,24 @@ namespace sprout {
// //
// calculate // calculate
// //
template<typename Tracer, typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D, typename Refractions>
inline SPROUT_CONSTEXPR typename sprout::darkroom::tracers::calculate_result<Tracer, Renderer, Camera, Objects, Lights, Unit2D>::type
calculate(
Tracer const& tracer,
Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights,
Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height,
std::size_t depth_max, Refractions const& refracs
)
{
return tracer(renderer, camera, objs, lights, x, y, width, height, depth_max, refracs);
}
template<typename Tracer, typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D> template<typename Tracer, typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D>
inline SPROUT_CONSTEXPR typename sprout::darkroom::tracers::calculate_result<Tracer, Renderer, Camera, Objects, Lights, Unit2D>::type inline SPROUT_CONSTEXPR typename sprout::darkroom::tracers::calculate_result<Tracer, Renderer, Camera, Objects, Lights, Unit2D>::type
calculate( calculate(
Tracer const& tracer, Tracer const& tracer,
Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights,
Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height, Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height,
std::size_t depth_max = 8 std::size_t depth_max = sprout::darkroom::renderers::default_depth
) )
{ {
return tracer(renderer, camera, objs, lights, x, y, width, height, depth_max); return tracer(renderer, camera, objs, lights, x, y, width, height, depth_max);

View file

@ -25,11 +25,25 @@ namespace sprout {
public: public:
typedef Color color_type; typedef Color color_type;
public: public:
template<typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D, typename Refractions>
SPROUT_CONSTEXPR color_type operator()(
Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights,
Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height,
std::size_t depth_max, Refractions const& refracs
) const
{
return sprout::darkroom::renderers::calculate<color_type>(
renderer,
camera, objs, lights,
sprout::darkroom::cameras::calculate(camera, x, y, width, height),
depth_max, refracs
);
}
template<typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D> template<typename Renderer, typename Camera, typename Objects, typename Lights, typename Unit2D>
SPROUT_CONSTEXPR color_type operator()( SPROUT_CONSTEXPR color_type operator()(
Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights, Renderer const& renderer, Camera const& camera, Objects const& objs, Lights const& lights,
Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height, Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height,
std::size_t depth_max = 8 std::size_t depth_max = sprout::darkroom::renderers::default_depth
) const ) const
{ {
return sprout::darkroom::renderers::calculate<color_type>( return sprout::darkroom::renderers::calculate<color_type>(

View file

@ -14,5 +14,6 @@
#include <sprout/tuple/metafunctions.hpp> #include <sprout/tuple/metafunctions.hpp>
#include <sprout/tuple/functions.hpp> #include <sprout/tuple/functions.hpp>
#include <sprout/tuple/fused.hpp> #include <sprout/tuple/fused.hpp>
#include <sprout/tuple/flex.hpp>
#endif // #ifndef SPROUT_TUPLE_HPP #endif // #ifndef SPROUT_TUPLE_HPP

248
sprout/tuple/flex.hpp Normal file
View file

@ -0,0 +1,248 @@
/*=============================================================================
Copyright (c) 2011-2013 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_TUPLE_FLEX_HPP
#define SPROUT_TUPLE_FLEX_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple/metafunction.hpp>
#include <sprout/tuple/tuple/tuple.hpp>
#include <sprout/tuple/tuple/get.hpp>
#include <sprout/tuple/tuple/tuple_size.hpp>
#include <sprout/tuple/tuple/tuple_element.hpp>
#include <sprout/tuple/tuple/type_traits.hpp>
#include <sprout/tuple/flexibly_construct.hpp>
#include <sprout/tuple/indexes.hpp>
#include <sprout/utility/value_holder/value_holder.hpp>
#include <sprout/type_traits/identity.hpp>
#include <sprout/type_traits/common_decay.hpp>
namespace sprout {
namespace tuples {
//
// flex_tuple
//
template<typename... Types>
class flex_tuple {
public:
typedef sprout::tuples::tuple<Types...> tuple_type;
private:
typedef sprout::value_holder<tuple_type const&> holder_type;
private:
holder_type holder_;
public:
flex_tuple(flex_tuple const&) = default;
flex_tuple(flex_tuple&&) = default;
SPROUT_CONSTEXPR flex_tuple(tuple_type const& t)
: holder_(t)
{}
SPROUT_CONSTEXPR operator tuple_type const&() const {
return holder_.get();
}
template<typename... UTypes>
SPROUT_CONSTEXPR operator sprout::tuples::tuple<UTypes...>() const {
return sprout::tuples::tuple<UTypes...>(sprout::tuples::flexibly_construct, holder_.get());
}
};
//
// flex
//
template<typename T>
inline SPROUT_CONSTEXPR T const&
flex(T const& t) {
return t;
}
template<typename... Types>
inline SPROUT_CONSTEXPR sprout::tuples::flex_tuple<Types...>
flex(sprout::tuples::tuple<Types...> const& t) {
return sprout::tuples::flex_tuple<Types...>(t);
}
template<typename To, typename... Types>
inline SPROUT_CONSTEXPR To
flex(sprout::tuples::tuple<Types...> const& t) {
return sprout::tuples::flex(t);
}
//
// recursive_flex_tuple
//
template<typename... Types>
class recursive_flex_tuple
: public sprout::tuples::flex_tuple<Types...>
{
private:
typedef sprout::tuples::flex_tuple<Types...> base_type;
private:
template<typename... UTypes, sprout::index_t... Indexes>
static SPROUT_CONSTEXPR sprout::tuples::tuple<UTypes...>
implicit_conversion_impl(typename base_type::tuple_type const& t, sprout::index_tuple<Indexes...>) {
return sprout::tuples::tuple<UTypes...>(
sprout::tuples::flexibly_construct,
sprout::tuples::flex(sprout::tuples::get<Indexes>(t))...
);
}
public:
recursive_flex_tuple(recursive_flex_tuple const&) = default;
recursive_flex_tuple(recursive_flex_tuple&&) = default;
SPROUT_CONSTEXPR recursive_flex_tuple(typename base_type::tuple_type const& t)
: base_type(t)
{}
template<typename... UTypes>
SPROUT_CONSTEXPR operator sprout::tuples::tuple<UTypes...>() const {
return implicit_conversion_impl<UTypes...>(*this, sprout::make_index_tuple<sizeof...(Types)>::make());
}
};
//
// recursive_flex
//
template<typename T>
inline SPROUT_CONSTEXPR T const&
recursive_flex(T const& t) {
return t;
}
template<typename... Types>
inline SPROUT_CONSTEXPR sprout::tuples::recursive_flex_tuple<Types...>
recursive_flex(sprout::tuples::tuple<Types...> const& t) {
return sprout::tuples::recursive_flex_tuple<Types...>(t);
}
template<typename To, typename... Types>
inline SPROUT_CONSTEXPR To
recursive_flex(sprout::tuples::tuple<Types...> const& t) {
return sprout::tuples::recursive_flex(t);
}
//
// common_flex_type
//
template<typename... Types>
struct common_flex_type;
template<typename T>
struct common_flex_type<T>
: public sprout::common_decay<T>
{};
namespace detail {
template<typename T, typename U, typename IndexTuple>
struct common_flex_type_impl_2;
template<typename T, typename U, sprout::index_t... Indexes>
struct common_flex_type_impl_2<T, U, sprout::index_tuple<Indexes...> >
: public sprout::identity<
sprout::tuples::tuple<
typename sprout::tuples::common_flex_type<
typename sprout::tuples::tuple_element<Indexes, T>::type,
typename sprout::tuples::tuple_element<Indexes, U>::type
>::type...
>
>
{};
template<typename T, typename U, typename Enable = void>
struct common_flex_type_impl_1;
template<typename T, typename U>
struct common_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value < sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::common_flex_type<U>
{};
template<typename T, typename U>
struct common_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value > sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::common_flex_type<T>
{};
template<typename T, typename U>
struct common_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value == sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::detail::common_flex_type_impl_2<T, U, typename sprout::tuples::tuple_indexes<T>::type>
{};
template<typename T, typename U, typename Enable = void>
struct common_flex_type_impl;
template<typename T, typename U>
struct common_flex_type_impl<T, U, typename std::enable_if<(sprout::tuples::is_tuple<T>::value && sprout::tuples::is_tuple<U>::value)>::type>
: public sprout::tuples::detail::common_flex_type_impl_1<T, U>
{};
template<typename T, typename U>
struct common_flex_type_impl<T, U, typename std::enable_if<!(sprout::tuples::is_tuple<T>::value && sprout::tuples::is_tuple<U>::value)>::type>
: public sprout::common_decay<T, U>
{};
} // namespace detail
template<typename T, typename U>
struct common_flex_type<T, U>
: public sprout::tuples::detail::common_flex_type_impl<T, U>
{};
template<typename T, typename U, typename... Tail>
struct common_flex_type<T, U, Tail...>
: public sprout::tuples::common_flex_type<typename sprout::tuples::common_flex_type<T, U>::type, Tail...>
{};
//
// common_recursive_flex_type
//
template<typename... Types>
struct common_recursive_flex_type;
template<typename T>
struct common_recursive_flex_type<T>
: public sprout::tuples::common_flex_type<T>
{};
namespace detail {
template<typename T, typename U, typename IndexTuple>
struct common_recursive_flex_type_impl_2;
template<typename T, typename U, sprout::index_t... Indexes>
struct common_recursive_flex_type_impl_2<T, U, sprout::index_tuple<Indexes...> >
: public sprout::identity<
sprout::tuples::tuple<
typename sprout::tuples::common_recursive_flex_type<
typename sprout::tuples::tuple_element<Indexes, T>::type,
typename sprout::tuples::tuple_element<Indexes, U>::type
>::type...
>
>
{};
template<typename T, typename U, typename Enable = void>
struct common_recursive_flex_type_impl_1;
template<typename T, typename U>
struct common_recursive_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value < sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::common_recursive_flex_type<U>
{};
template<typename T, typename U>
struct common_recursive_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value > sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::common_recursive_flex_type<T>
{};
template<typename T, typename U>
struct common_recursive_flex_type_impl_1<T, U, typename std::enable_if<(sprout::tuples::tuple_size<T>::value == sprout::tuples::tuple_size<U>::value)>::type>
: public sprout::tuples::detail::common_recursive_flex_type_impl_2<T, U, typename sprout::tuples::tuple_indexes<T>::type>
{};
template<typename T, typename U, typename Enable = void>
struct common_recursive_flex_type_impl;
template<typename T, typename U>
struct common_recursive_flex_type_impl<T, U, typename std::enable_if<(sprout::tuples::is_tuple<T>::value && sprout::tuples::is_tuple<U>::value)>::type>
: public sprout::tuples::detail::common_recursive_flex_type_impl_1<T, U>
{};
template<typename T, typename U>
struct common_recursive_flex_type_impl<T, U, typename std::enable_if<!(sprout::tuples::is_tuple<T>::value && sprout::tuples::is_tuple<U>::value)>::type>
: public sprout::tuples::common_flex_type<T, U>
{};
} // namespace detail
template<typename T, typename U>
struct common_recursive_flex_type<T, U>
: public sprout::tuples::detail::common_recursive_flex_type_impl<T, U>
{};
template<typename T, typename U, typename... Tail>
struct common_recursive_flex_type<T, U, Tail...>
: public sprout::tuples::common_recursive_flex_type<typename sprout::tuples::common_recursive_flex_type<T, U>::type, Tail...>
{};
} // namespace tuples
using sprout::tuples::flex_tuple;
using sprout::tuples::flex;
using sprout::tuples::recursive_flex_tuple;
using sprout::tuples::recursive_flex;
using sprout::tuples::common_flex_type;
using sprout::tuples::common_recursive_flex_type;
} // namespace sprout
#endif // #ifndef SPROUT_TUPLE_FLEX_HPP