-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcamera.inl
117 lines (105 loc) · 2.76 KB
/
camera.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//
// camera.inl
// Simpleton Engine
//
// Created by Indi Kernick on 15/11/17.
// Copyright © 2017 Indi Kernick. All rights reserved.
//
inline void Cam2D::Camera::setPos(const glm::vec2 pos) {
props.pos = pos;
}
inline void Cam2D::Camera::setZoom(const float scale) {
props.scale = scale;
}
inline void Cam2D::Camera::setAngle(const float angle) {
props.angle = angle;
}
namespace Cam2D::detail {
// http://stackoverflow.com/a/48741208
template <PropID PROP>
constexpr std::true_type isTarget(const Target<PROP> &) {
return {};
}
template <PropID PROP>
constexpr std::false_type isTarget(const Animate<PROP> &) {
return {};
}
template <typename T>
constexpr bool is_target_v = decltype(isTarget(std::declval<T>()))::value;
template <typename, typename, typename, size_t I = 0>
struct Split;
template <
size_t... TARGET_IDX,
size_t... ANIM_IDX,
size_t N
>
struct Split<
std::index_sequence<TARGET_IDX...>,
std::index_sequence<ANIM_IDX...>,
std::tuple<>,
N
> {
using Targets = std::index_sequence<TARGET_IDX...>;
using Anims = std::index_sequence<ANIM_IDX...>;
};
template <
size_t... TARGET_IDX,
size_t... ANIM_IDX,
size_t I,
typename T,
typename... Tail
>
struct Split<
std::index_sequence<TARGET_IDX...>,
std::index_sequence<ANIM_IDX...>,
std::tuple<T, Tail...>,
I
> : std::conditional_t<
is_target_v<T>,
Split<
std::index_sequence<TARGET_IDX..., I>,
std::index_sequence<ANIM_IDX...>,
std::tuple<Tail...>,
I + 1
>,
Split<
std::index_sequence<TARGET_IDX...>,
std::index_sequence<ANIM_IDX..., I>,
std::tuple<Tail...>,
I + 1
>
> {};
}
template <typename... Args>
void Cam2D::Camera::update(const Params params, Args &&... args) {
using Split = detail::Split<
std::index_sequence<>,
std::index_sequence<>,
std::tuple<std::decay_t<Args>...>
>;
updateImpl(
params,
typename Split::Targets{},
typename Split::Anims{},
std::forward_as_tuple(args...)
);
}
template <size_t... TARGET_IDX, size_t... ANIM_IDX, typename Tuple>
void Cam2D::Camera::updateImpl(
const Params params,
std::index_sequence<TARGET_IDX...>,
std::index_sequence<ANIM_IDX...>,
const Tuple &tuple
) {
Props targetProps = props;
((
getProp<std::decay_t<std::tuple_element_t<TARGET_IDX, Tuple>>::PROP>(targetProps)
= std::get<TARGET_IDX>(tuple).calcTarget(props, params)
), ...);
((
getProp<std::decay_t<std::tuple_element_t<ANIM_IDX, Tuple>>::PROP>(targetProps)
= std::get<ANIM_IDX>(tuple).calculate(props, params, getProp<std::decay_t<std::tuple_element_t<ANIM_IDX, Tuple>>::PROP>(targetProps))
), ...);
props = targetProps;
transform.calculate(props, params);
}