1 /*************************************************************************/
2 /*  animation.h                                                          */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #ifndef ANIMATION_H
31 #define ANIMATION_H
32 
33 #include "resource.h"
34 /**
35 	@author Juan Linietsky <reduzio@gmail.com>
36 */
37 class Animation : public Resource {
38 
39 	OBJ_TYPE(Animation, Resource);
40 	RES_BASE_EXTENSION("anm");
41 
42 public:
43 	enum LoopMode {
44 
45 		LOOP_NONE,
46 		LOOP_ENABLED,
47 		LOOP_WRAP
48 	};
49 
50 	enum TrackType {
51 		TYPE_VALUE, ///< Set a value in a property, can be interpolated.
52 		TYPE_TRANSFORM, ///< Transform a node or a bone.
53 		TYPE_METHOD, ///< Call any method on a specific node.
54 	};
55 
56 	enum InterpolationType {
57 		INTERPOLATION_NEAREST,
58 		INTERPOLATION_LINEAR,
59 		INTERPOLATION_CUBIC
60 	};
61 
62 	enum UpdateMode {
63 		UPDATE_CONTINUOUS,
64 		UPDATE_DISCRETE,
65 		UPDATE_TRIGGER,
66 
67 	};
68 
69 private:
70 	struct Track {
71 
72 		TrackType type;
73 		InterpolationType interpolation;
74 		NodePath path; // path to something
75 		bool imported;
TrackTrack76 		Track() {
77 			interpolation = INTERPOLATION_LINEAR;
78 			imported = false;
79 		}
~TrackTrack80 		virtual ~Track() {}
81 	};
82 
83 	struct Key {
84 
85 		float transition;
86 		float time; // time in secs
KeyKey87 		Key() { transition = 1; }
88 	};
89 
90 	// transform key holds either Vector3 or Quaternion
91 	template <class T>
92 	struct TKey : public Key {
93 
94 		float time;
95 		T value;
96 	};
97 
98 	struct TransformKey {
99 
100 		Vector3 loc;
101 		Quat rot;
102 		Vector3 scale;
103 	};
104 
105 	/* TRANSFORM TRACK */
106 
107 	struct TransformTrack : public Track {
108 
109 		Vector<TKey<TransformKey> > transforms;
110 
TransformTrackTransformTrack111 		TransformTrack() { type = TYPE_TRANSFORM; }
112 	};
113 
114 	/* PROPERTY VALUE TRACK */
115 
116 	struct ValueTrack : public Track {
117 
118 		UpdateMode update_mode;
119 		bool update_on_seek;
120 		Vector<TKey<Variant> > values;
121 
ValueTrackValueTrack122 		ValueTrack() {
123 			type = TYPE_VALUE;
124 			update_mode = UPDATE_CONTINUOUS;
125 		}
126 	};
127 
128 	/* METHOD TRACK */
129 
130 	struct MethodKey : public Key {
131 
132 		StringName method;
133 		Vector<Variant> params;
134 	};
135 
136 	struct MethodTrack : public Track {
137 
138 		Vector<MethodKey> methods;
MethodTrackMethodTrack139 		MethodTrack() { type = TYPE_METHOD; }
140 	};
141 
142 	Vector<Track *> tracks;
143 
144 	/*
145 	template<class T>
146 	int _insert_pos(float p_time, T& p_keys);*/
147 
148 	template <class T>
149 	void _clear(T &p_keys);
150 
151 	template <class T, class V>
152 	int _insert(float p_time, T &p_keys, const V &p_value);
153 
154 	template <class K>
155 	inline int _find(const Vector<K> &p_keys, float p_time) const;
156 
157 	_FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const;
158 
159 	_FORCE_INLINE_ Vector3 _interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const;
160 	_FORCE_INLINE_ Quat _interpolate(const Quat &p_a, const Quat &p_b, float p_c) const;
161 	_FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, float p_c) const;
162 	_FORCE_INLINE_ float _interpolate(const float &p_a, const float &p_b, float p_c) const;
163 
164 	_FORCE_INLINE_ Animation::TransformKey _cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const;
165 	_FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const;
166 	_FORCE_INLINE_ Quat _cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const;
167 	_FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const;
168 	_FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const;
169 
170 	template <class T>
171 	_FORCE_INLINE_ T _interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool *p_ok) const;
172 
173 	_FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const;
174 	_FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const;
175 
176 	float length;
177 	float step;
178 	bool loop;
179 
180 	// bind helpers
181 private:
_transform_track_interpolate(int p_track,float p_time)182 	Array _transform_track_interpolate(int p_track, float p_time) const {
183 		Vector3 loc;
184 		Quat rot;
185 		Vector3 scale;
186 		transform_track_interpolate(p_track, p_time, &loc, &rot, &scale);
187 		Array ret;
188 		ret.push_back(loc);
189 		ret.push_back(rot);
190 		ret.push_back(scale);
191 		return ret;
192 	}
193 
_value_track_get_key_indices(int p_track,float p_time,float p_delta)194 	DVector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const {
195 
196 		List<int> idxs;
197 		value_track_get_key_indices(p_track, p_time, p_delta, &idxs);
198 		DVector<int> idxr;
199 
200 		for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
201 
202 			idxr.push_back(E->get());
203 		}
204 		return idxr;
205 	}
_method_track_get_key_indices(int p_track,float p_time,float p_delta)206 	DVector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const {
207 
208 		List<int> idxs;
209 		method_track_get_key_indices(p_track, p_time, p_delta, &idxs);
210 		DVector<int> idxr;
211 
212 		for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
213 
214 			idxr.push_back(E->get());
215 		}
216 		return idxr;
217 	}
218 
219 	bool _transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm);
220 	void _transform_track_optimize(int p_idx, float p_allowed_err = 0.05, float p_alowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125);
221 
222 protected:
223 	bool _set(const StringName &p_name, const Variant &p_value);
224 	bool _get(const StringName &p_name, Variant &r_ret) const;
225 	void _get_property_list(List<PropertyInfo> *p_list) const;
226 
227 	static void _bind_methods();
228 
229 public:
230 	int add_track(TrackType p_type, int p_at_pos = -1);
231 	void remove_track(int p_track);
232 
233 	int get_track_count() const;
234 	TrackType track_get_type(int p_track) const;
235 
236 	void track_set_path(int p_track, const NodePath &p_path);
237 	NodePath track_get_path(int p_track) const;
238 	int find_track(const NodePath &p_path) const;
239 	// transform
240 
241 	void track_move_up(int p_track);
242 	void track_move_down(int p_track);
243 
244 	void track_set_imported(int p_track, bool p_imported);
245 	bool track_is_imported(int p_track) const;
246 
247 	int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3());
248 	void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1);
249 	void track_set_key_transition(int p_track, int p_key_idx, float p_transition);
250 	void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value);
251 	int track_find_key(int p_track, float p_time, bool p_exact = false) const;
252 	void track_remove_key(int p_track, int p_idx);
253 	void track_remove_key_at_pos(int p_track, float p_pos);
254 	int track_get_key_count(int p_track) const;
255 	Variant track_get_key_value(int p_track, int p_key_idx) const;
256 	float track_get_key_time(int p_track, int p_key_idx) const;
257 	float track_get_key_transition(int p_track, int p_key_idx) const;
258 
259 	Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const;
260 	void track_set_interpolation_type(int p_track, InterpolationType p_interp);
261 	InterpolationType track_get_interpolation_type(int p_track) const;
262 
263 	Error transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const;
264 
265 	Variant value_track_interpolate(int p_track, float p_time) const;
266 	void value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const;
267 	void value_track_set_update_mode(int p_track, UpdateMode p_mode);
268 	UpdateMode value_track_get_update_mode(int p_track) const;
269 
270 	void method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const;
271 	Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
272 	StringName method_track_get_name(int p_track, int p_key_idx) const;
273 
274 	void set_length(float p_length);
275 	float get_length() const;
276 
277 	void set_loop(bool p_enabled);
278 	bool has_loop() const;
279 
280 	void set_step(float p_step);
281 	float get_step() const;
282 
283 	void clear();
284 
285 	void optimize(float p_allowed_linear_err = 0.05, float p_allowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125);
286 
287 	Animation();
288 	~Animation();
289 };
290 
291 VARIANT_ENUM_CAST(Animation::TrackType);
292 VARIANT_ENUM_CAST(Animation::InterpolationType);
293 VARIANT_ENUM_CAST(Animation::UpdateMode);
294 
295 #endif
296