Antkeeper  0.0.1
animation-channel.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_ANIMATION_CHANNEL_HPP
21 #define ANTKEEPER_ANIMATION_CHANNEL_HPP
22 
23 #include <list>
24 #include <set>
25 #include <tuple>
26 
32 template <typename T>
34 {
35 public:
37  typedef std::tuple<float, T> keyframe;
38 
44  explicit animation_channel(int id);
45 
48 
51 
54 
60  void insert_keyframe(const keyframe& k);
61 
68  void remove_keyframes(float start, float end);
69 
71  void remove_keyframes();
72 
79  std::array<const keyframe*, 2> find_keyframes(float position) const;
80 
88  std::list<keyframe> find_keyframes(float start, float end) const;
89 
91  int get_id() const;
92 
94  float get_duration() const;
95 
96 private:
97  struct keyframe_compare
98  {
99  inline bool operator()(const keyframe& lhs, const keyframe& rhs) const
100  {
101  return std::get<0>(lhs) < std::get<0>(rhs);
102  }
103  };
104 
105  int id;
106  std::set<keyframe, keyframe_compare> keyframes;
107 };
108 
109 template <typename T>
111  id(id),
112  keyframes(keyframe_compare())
113 {}
114 
115 template <typename T>
118 {}
119 
120 template <typename T>
122  id(other.id),
123  keyframes(other.keyframes)
124 {}
125 
126 template <typename T>
128 {
129  id = other.id;
130  keyframes = other.keyframes;
131  return *this;
132 }
133 
134 template <typename T>
136 {
137  keyframes.emplace(k);
138 }
139 
140 template <typename T>
141 void animation_channel<T>::remove_keyframes(float start, float end)
142 {
143  auto lower_bound = keyframes.lower_bound({start, T()});
144  auto upper_bound = keyframes.upper_bound({end, T()});
145  keyframes.erase(lower_bound, upper_bound);
146 }
147 
148 template <typename T>
150 {
151  keyframes.clear();
152 }
153 
154 template <typename T>
155 std::array<const typename animation_channel<T>::keyframe*, 2> animation_channel<T>::find_keyframes(float position) const
156 {
157  // Find the following keyframe
158  auto upper_bound = keyframes.upper_bound({position, T()});
159 
160  // Find the preceding keyframe
161  auto lower_bound = upper_bound;
162  --lower_bound;
163 
164  std::array<const keyframe*, 2> frames;
165  frames[0] = (lower_bound != keyframes.end()) ? &(*lower_bound) : nullptr;
166  frames[1] = (upper_bound != keyframes.end()) ? &(*upper_bound) : nullptr;
167 
168  return frames;
169 }
170 
171 template <typename T>
172 std::list<typename animation_channel<T>::keyframe> animation_channel<T>::find_keyframes(float start, float end) const
173 {
174  std::list<keyframe> keyframe_list;
175 
176  auto lower_bound = keyframes.lower_bound({start, T()});
177  auto upper_bound = keyframes.upper_bound({end, T()});
178  for (auto iterator = lower_bound; iterator != upper_bound; ++iterator)
179  {
180  keyframe_list.push_back(*iterator);
181  }
182 
183  return keyframe_list;
184 }
185 
186 template <typename T>
188 {
189  return id;
190 }
191 
192 template <typename T>
194 {
195  if (keyframes.empty())
196  {
197  return 0.0;
198  }
199 
200  return std::get<0>(*keyframes.rbegin());
201 }
202 
203 #endif // ANTKEEPER_ANIMATION_CHANNEL_HPP
Single channel in a keyframe animation.
int get_id() const
Returns the ID of the animation channel.
float get_duration() const
Returns the duration of the animation channel.
std::tuple< float, T > keyframe
Keyframe consisting of a time and a value.
animation_channel()
Creates an animation channel.
std::array< const keyframe *, 2 > find_keyframes(float position) const
Finds the keyframes to the left and right of position.
animation_channel & operator=(const animation_channel &other)
Assigns the contents of another channel to this channel.
void insert_keyframe(const keyframe &k)
Adds a keyframe to the animation.
void remove_keyframes()
Removes all keyframes from the animation.
entt::entity id
Entity ID type.
Definition: id.hpp:28