sprout/darkroom/cameras/simple_camera.hpp 視点と回転の設定を実装

This commit is contained in:
bolero-MURAKAMI 2011-12-12 17:23:54 +09:00
parent c86fa430c1
commit 3e028096fd
5 changed files with 191 additions and 17 deletions

View file

@ -2,6 +2,7 @@
#define SPROUT_DARKROOM_CAMERAS_HPP
#include <sprout/config.hpp>
#include <sprout/darkroom/cameras/angle_of_view.hpp>
#include <sprout/darkroom/cameras/simple_camera.hpp>
#endif // #ifndef SPROUT_DARKROOM_CAMERAS_HPP

View file

@ -0,0 +1,27 @@
#ifndef SPROUT_DARKROOM_CAMERAS_ANGLE_OF_VIEW_HPP
#define SPROUT_DARKROOM_CAMERAS_ANGLE_OF_VIEW_HPP
#include <sprout/config.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/darkroom/coords/vector.hpp>
namespace sprout {
namespace darkroom {
namespace cameras {
//
// angle_of_view_reference
//
struct angle_of_view_reference {
public:
enum values {
long_side,
short_side,
width,
height
};
};
} // namespace cameras
} // namespace darkroom
} // namespace sprout
#endif // #ifndef SPROUT_DARKROOM_CAMERAS_ANGLE_OF_VIEW_HPP

View file

@ -1,31 +1,134 @@
#ifndef SPROUT_DARKROOM_CAMERAS_SIMPLE_CAMERA_HPP
#define SPROUT_DARKROOM_CAMERAS_SIMPLE_CAMERA_HPP
#include <cmath>
#include <sprout/config.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/darkroom/coords/vector.hpp>
#include <sprout/darkroom/cameras/angle_of_view.hpp>
namespace sprout {
namespace darkroom {
namespace cameras {
template<typename Unit = double>
//
// 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 sprout::tuples::tuple<unit_type, unit_type, unit_type> position_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
{
using std::sqrt;
using std::sin;
using std::cos;
return transform_1(
c,
u * cos(rotate_) - v * sin(rotate_),
u * sin(rotate_) + v * cos(rotate_),
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:
SPROUT_CONSTEXPR explicit basic_simple_camera(
unit_type const& far_plane
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)
{}
SPROUT_CONSTEXPR ray_type operator()(unit_type const& u, unit_type const& v) const {
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_type(0, 0, 0),
sprout::darkroom::coords::normalize(position_type(u, v, far_plane_))
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)
)
);
}
};
@ -34,8 +137,27 @@ namespace sprout {
//
template<typename Unit>
SPROUT_CONSTEXPR inline sprout::darkroom::cameras::basic_simple_camera<Unit>
make_simple_camera(Unit const& far_plane) {
return sprout::darkroom::cameras::basic_simple_camera<Unit>(far_plane);
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

View file

@ -114,6 +114,23 @@ namespace sprout {
;
}
//
// cross
//
template<typename Vector1, typename Vector2>
SPROUT_CONSTEXPR inline Vector1 cross(Vector1 const& lhs, Vector2 const& rhs) {
return sprout::tuples::remake_clone<Vector1>(
lhs,
sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::z(rhs)
- sprout::darkroom::coords::z(lhs) * sprout::darkroom::coords::y(rhs)
,
sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::x(rhs)
- sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::y(rhs)
,
sprout::darkroom::coords::x(lhs) * sprout::darkroom::coords::y(rhs)
- sprout::darkroom::coords::y(lhs) * sprout::darkroom::coords::x(rhs)
);
}
//
// normalize
//
namespace detail {
@ -139,6 +156,16 @@ namespace sprout {
);
}
//
// resize
//
template<typename Vector, typename Fac>
SPROUT_CONSTEXPR inline Vector resize(Vector const& lhs, Fac const& rhs) {
return sprout::darkroom::coords::detail::normalize_impl(
lhs,
sprout::darkroom::coords::length(lhs) / rhs
);
}
//
// reflect
//
template<typename Incident, typename Normal>

View file

@ -21,17 +21,17 @@ namespace sprout {
typename Camera,
typename Objects,
typename Lights,
typename Unit
typename Unit2D
>
SPROUT_CONSTEXPR color_type operator()(
Renderer const& renderer,
Camera const& camera,
Objects const& objs,
Lights const& lights,
Unit const& x,
Unit const& y,
Unit const& width,
Unit const& height,
Unit2D const& x,
Unit2D const& y,
Unit2D const& width,
Unit2D const& height,
std::size_t depth_max = 8
) const
{
@ -39,10 +39,7 @@ namespace sprout {
camera,
objs,
lights,
camera.template operator()(
static_cast<typename Camera::unit_type>(x) / width - 0.5,
-(static_cast<typename Camera::unit_type>(y) / height - 0.5)
),
camera.template operator()(x, y, width, height),
depth_max
);
}