mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2024-11-12 21:09:01 +00:00
153 lines
5.6 KiB
C++
153 lines
5.6 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2011-2017 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_CAMERAS_SIMPLE_CAMERA_HPP
|
|
#define SPROUT_DARKROOM_CAMERAS_SIMPLE_CAMERA_HPP
|
|
|
|
#include <sprout/config.hpp>
|
|
#include <sprout/tuple/tuple.hpp>
|
|
#include <sprout/math/sin.hpp>
|
|
#include <sprout/math/cos.hpp>
|
|
#include <sprout/math/sqrt.hpp>
|
|
#include <sprout/darkroom/coords/vector.hpp>
|
|
#include <sprout/darkroom/cameras/angle_of_view.hpp>
|
|
|
|
namespace sprout {
|
|
namespace darkroom {
|
|
namespace cameras {
|
|
//
|
|
// basic_simple_camera
|
|
//
|
|
template<typename Unit = double, typename Position = sprout::tuples::tuple<Unit, Unit, Unit> >
|
|
class basic_simple_camera {
|
|
public:
|
|
typedef Unit unit_type;
|
|
typedef Position position_type;
|
|
typedef sprout::tuples::tuple<position_type, position_type> ray_type;
|
|
typedef sprout::darkroom::cameras::angle_of_view_reference angle_of_view_reference;
|
|
private:
|
|
unit_type far_plane_;
|
|
angle_of_view_reference::values reference_value_;
|
|
position_type position_;
|
|
position_type fixation_point_;
|
|
unit_type rotate_;
|
|
private:
|
|
SPROUT_CONSTEXPR position_type
|
|
transform_1(position_type const& c, unit_type const& u, unit_type const& v, unit_type const& l) const {
|
|
return sprout::darkroom::coords::add(
|
|
c,
|
|
position_type(
|
|
sprout::darkroom::coords::z(c) * u / l,
|
|
v,
|
|
-sprout::darkroom::coords::x(c) * u / l
|
|
)
|
|
);
|
|
}
|
|
SPROUT_CONSTEXPR position_type
|
|
transform(position_type const& c, unit_type const& u, unit_type const& v) const {
|
|
return transform_1(
|
|
c,
|
|
u * sprout::cos(rotate_) - v * sprout::sin(rotate_),
|
|
u * sprout::sin(rotate_) + v * sprout::cos(rotate_),
|
|
sprout::sqrt(
|
|
sprout::darkroom::coords::x(c) * sprout::darkroom::coords::x(c)
|
|
+ sprout::darkroom::coords::z(c) * sprout::darkroom::coords::z(c)
|
|
)
|
|
);
|
|
}
|
|
template<typename Unit2D>
|
|
SPROUT_CONSTEXPR position_type
|
|
reference_width(
|
|
Unit2D const& x, Unit2D const& y,
|
|
Unit2D const& width, Unit2D const& height,
|
|
unit_type const& rate
|
|
) const
|
|
{
|
|
return transform(
|
|
sprout::darkroom::coords::resize(
|
|
sprout::darkroom::coords::sub(fixation_point_, position_),
|
|
far_plane_
|
|
),
|
|
static_cast<unit_type>(x) / width - 0.5,
|
|
-((static_cast<unit_type>(y) / height - 0.5) * rate)
|
|
);
|
|
}
|
|
template<typename Unit2D>
|
|
SPROUT_CONSTEXPR position_type
|
|
reference_height(
|
|
Unit2D const& x, Unit2D const& y,
|
|
Unit2D const& width, Unit2D const& height,
|
|
unit_type const& rate
|
|
) const
|
|
{
|
|
return transform(
|
|
sprout::darkroom::coords::resize(
|
|
sprout::darkroom::coords::sub(fixation_point_, position_),
|
|
far_plane_
|
|
),
|
|
(static_cast<unit_type>(x) / width - 0.5) * rate,
|
|
-(static_cast<unit_type>(y) / height - 0.5)
|
|
);
|
|
}
|
|
public:
|
|
explicit SPROUT_CONSTEXPR basic_simple_camera(
|
|
unit_type const& far_plane,
|
|
angle_of_view_reference::values reference_value = angle_of_view_reference::long_side,
|
|
position_type const& position = position_type(0, 0, -1),
|
|
position_type const& fixation_point = position_type(0, 0, 0),
|
|
unit_type const& rotate = 0
|
|
)
|
|
: far_plane_(far_plane)
|
|
, reference_value_(reference_value)
|
|
, position_(position)
|
|
, fixation_point_(fixation_point)
|
|
, rotate_(rotate)
|
|
{}
|
|
template<typename Unit2D>
|
|
SPROUT_CONSTEXPR ray_type
|
|
operator()(Unit2D const& x, Unit2D const& y, Unit2D const& width, Unit2D const& height) const {
|
|
return ray_type(
|
|
position_,
|
|
sprout::darkroom::coords::normalize(
|
|
(reference_value_ == angle_of_view_reference::long_side && width >= height)
|
|
|| (reference_value_ == angle_of_view_reference::short_side && width < height)
|
|
|| reference_value_ == angle_of_view_reference::width
|
|
? reference_width(x, y, width, height, static_cast<unit_type>(height) / width)
|
|
: reference_height(x, y, width, height, static_cast<unit_type>(width) / height)
|
|
)
|
|
);
|
|
}
|
|
};
|
|
//
|
|
// make_simple_camera
|
|
//
|
|
template<typename Unit>
|
|
inline SPROUT_CONSTEXPR sprout::darkroom::cameras::basic_simple_camera<Unit>
|
|
make_simple_camera(
|
|
Unit const& far_plane,
|
|
typename sprout::darkroom::cameras::basic_simple_camera<Unit>::angle_of_view_reference::values reference_value
|
|
= sprout::darkroom::cameras::basic_simple_camera<Unit>::angle_of_view_reference::long_side,
|
|
typename sprout::darkroom::cameras::basic_simple_camera<Unit>::position_type const& position
|
|
= typename sprout::darkroom::cameras::basic_simple_camera<Unit>::position_type(0, 0, -1),
|
|
typename sprout::darkroom::cameras::basic_simple_camera<Unit>::position_type const& fixation_point
|
|
= typename sprout::darkroom::cameras::basic_simple_camera<Unit>::position_type(0, 0, 0),
|
|
Unit const& rotate = 0
|
|
)
|
|
{
|
|
return sprout::darkroom::cameras::basic_simple_camera<Unit>(
|
|
far_plane,
|
|
reference_value,
|
|
position,
|
|
fixation_point,
|
|
rotate
|
|
);
|
|
}
|
|
} // namespace cameras
|
|
} // namespace darkroom
|
|
} // namespace sprout
|
|
|
|
#endif // #ifndef SPROUT_DARKROOM_CAMERAS_SIMPLE_CAMERA_HPP
|