1 /*************************************************************************/
2 /*  animation.cpp                                                        */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 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 
31 #include "animation.h"
32 #include "scene/scene_string_names.h"
33 
34 #include "core/math/geometry.h"
35 
36 #define ANIM_MIN_LENGTH 0.001
37 
_set(const StringName & p_name,const Variant & p_value)38 bool Animation::_set(const StringName &p_name, const Variant &p_value) {
39 
40 	String name = p_name;
41 
42 	if (name.begins_with("tracks/")) {
43 
44 		int track = name.get_slicec('/', 1).to_int();
45 		String what = name.get_slicec('/', 2);
46 
47 		if (tracks.size() == track && what == "type") {
48 
49 			String type = p_value;
50 
51 			if (type == "transform") {
52 
53 				add_track(TYPE_TRANSFORM);
54 			} else if (type == "value") {
55 
56 				add_track(TYPE_VALUE);
57 			} else if (type == "method") {
58 
59 				add_track(TYPE_METHOD);
60 			} else if (type == "bezier") {
61 
62 				add_track(TYPE_BEZIER);
63 			} else if (type == "audio") {
64 
65 				add_track(TYPE_AUDIO);
66 			} else if (type == "animation") {
67 
68 				add_track(TYPE_ANIMATION);
69 			} else {
70 
71 				return false;
72 			}
73 
74 			return true;
75 		}
76 
77 		ERR_FAIL_INDEX_V(track, tracks.size(), false);
78 
79 		if (what == "path")
80 			track_set_path(track, p_value);
81 		else if (what == "interp")
82 			track_set_interpolation_type(track, InterpolationType(p_value.operator int()));
83 		else if (what == "loop_wrap")
84 			track_set_interpolation_loop_wrap(track, p_value);
85 		else if (what == "imported")
86 			track_set_imported(track, p_value);
87 		else if (what == "enabled")
88 			track_set_enabled(track, p_value);
89 		else if (what == "keys" || what == "key_values") {
90 
91 			if (track_get_type(track) == TYPE_TRANSFORM) {
92 
93 				TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]);
94 				PoolVector<float> values = p_value;
95 				int vcount = values.size();
96 				ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 11
97 
98 				PoolVector<float>::Read r = values.read();
99 
100 				tt->transforms.resize(vcount / 12);
101 
102 				for (int i = 0; i < (vcount / 12); i++) {
103 
104 					TKey<TransformKey> &tk = tt->transforms.write[i];
105 					const float *ofs = &r[i * 12];
106 					tk.time = ofs[0];
107 					tk.transition = ofs[1];
108 
109 					tk.value.loc.x = ofs[2];
110 					tk.value.loc.y = ofs[3];
111 					tk.value.loc.z = ofs[4];
112 
113 					tk.value.rot.x = ofs[5];
114 					tk.value.rot.y = ofs[6];
115 					tk.value.rot.z = ofs[7];
116 					tk.value.rot.w = ofs[8];
117 
118 					tk.value.scale.x = ofs[9];
119 					tk.value.scale.y = ofs[10];
120 					tk.value.scale.z = ofs[11];
121 				}
122 
123 			} else if (track_get_type(track) == TYPE_VALUE) {
124 
125 				ValueTrack *vt = static_cast<ValueTrack *>(tracks[track]);
126 				Dictionary d = p_value;
127 				ERR_FAIL_COND_V(!d.has("times"), false);
128 				ERR_FAIL_COND_V(!d.has("values"), false);
129 				if (d.has("cont")) {
130 					bool v = d["cont"];
131 					vt->update_mode = v ? UPDATE_CONTINUOUS : UPDATE_DISCRETE;
132 				}
133 
134 				if (d.has("update")) {
135 					int um = d["update"];
136 					if (um < 0)
137 						um = 0;
138 					else if (um > 3)
139 						um = 3;
140 					vt->update_mode = UpdateMode(um);
141 				}
142 
143 				PoolVector<float> times = d["times"];
144 				Array values = d["values"];
145 
146 				ERR_FAIL_COND_V(times.size() != values.size(), false);
147 
148 				if (times.size()) {
149 
150 					int valcount = times.size();
151 
152 					PoolVector<float>::Read rt = times.read();
153 
154 					vt->values.resize(valcount);
155 
156 					for (int i = 0; i < valcount; i++) {
157 
158 						vt->values.write[i].time = rt[i];
159 						vt->values.write[i].value = values[i];
160 					}
161 
162 					if (d.has("transitions")) {
163 
164 						PoolVector<float> transitions = d["transitions"];
165 						ERR_FAIL_COND_V(transitions.size() != valcount, false);
166 
167 						PoolVector<float>::Read rtr = transitions.read();
168 
169 						for (int i = 0; i < valcount; i++) {
170 
171 							vt->values.write[i].transition = rtr[i];
172 						}
173 					}
174 				}
175 
176 				return true;
177 
178 			} else if (track_get_type(track) == TYPE_METHOD) {
179 
180 				while (track_get_key_count(track))
181 					track_remove_key(track, 0); //well shouldn't be set anyway
182 
183 				Dictionary d = p_value;
184 				ERR_FAIL_COND_V(!d.has("times"), false);
185 				ERR_FAIL_COND_V(!d.has("values"), false);
186 
187 				PoolVector<float> times = d["times"];
188 				Array values = d["values"];
189 
190 				ERR_FAIL_COND_V(times.size() != values.size(), false);
191 
192 				if (times.size()) {
193 
194 					int valcount = times.size();
195 
196 					PoolVector<float>::Read rt = times.read();
197 
198 					for (int i = 0; i < valcount; i++) {
199 
200 						track_insert_key(track, rt[i], values[i]);
201 					}
202 
203 					if (d.has("transitions")) {
204 
205 						PoolVector<float> transitions = d["transitions"];
206 						ERR_FAIL_COND_V(transitions.size() != valcount, false);
207 
208 						PoolVector<float>::Read rtr = transitions.read();
209 
210 						for (int i = 0; i < valcount; i++) {
211 
212 							track_set_key_transition(track, i, rtr[i]);
213 						}
214 					}
215 				}
216 			} else if (track_get_type(track) == TYPE_BEZIER) {
217 
218 				BezierTrack *bt = static_cast<BezierTrack *>(tracks[track]);
219 				Dictionary d = p_value;
220 				ERR_FAIL_COND_V(!d.has("times"), false);
221 				ERR_FAIL_COND_V(!d.has("points"), false);
222 
223 				PoolVector<float> times = d["times"];
224 				PoolRealArray values = d["points"];
225 
226 				ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
227 
228 				if (times.size()) {
229 
230 					int valcount = times.size();
231 
232 					PoolVector<float>::Read rt = times.read();
233 					PoolVector<float>::Read rv = values.read();
234 
235 					bt->values.resize(valcount);
236 
237 					for (int i = 0; i < valcount; i++) {
238 
239 						bt->values.write[i].time = rt[i];
240 						bt->values.write[i].transition = 0; //unused in bezier
241 						bt->values.write[i].value.value = rv[i * 5 + 0];
242 						bt->values.write[i].value.in_handle.x = rv[i * 5 + 1];
243 						bt->values.write[i].value.in_handle.y = rv[i * 5 + 2];
244 						bt->values.write[i].value.out_handle.x = rv[i * 5 + 3];
245 						bt->values.write[i].value.out_handle.y = rv[i * 5 + 4];
246 					}
247 				}
248 
249 				return true;
250 			} else if (track_get_type(track) == TYPE_AUDIO) {
251 
252 				AudioTrack *ad = static_cast<AudioTrack *>(tracks[track]);
253 				Dictionary d = p_value;
254 				ERR_FAIL_COND_V(!d.has("times"), false);
255 				ERR_FAIL_COND_V(!d.has("clips"), false);
256 
257 				PoolVector<float> times = d["times"];
258 				Array clips = d["clips"];
259 
260 				ERR_FAIL_COND_V(clips.size() != times.size(), false);
261 
262 				if (times.size()) {
263 
264 					int valcount = times.size();
265 
266 					PoolVector<float>::Read rt = times.read();
267 
268 					ad->values.clear();
269 
270 					for (int i = 0; i < valcount; i++) {
271 
272 						Dictionary d2 = clips[i];
273 						if (!d2.has("start_offset"))
274 							continue;
275 						if (!d2.has("end_offset"))
276 							continue;
277 						if (!d2.has("stream"))
278 							continue;
279 
280 						TKey<AudioKey> ak;
281 						ak.time = rt[i];
282 						ak.value.start_offset = d2["start_offset"];
283 						ak.value.end_offset = d2["end_offset"];
284 						ak.value.stream = d2["stream"];
285 
286 						ad->values.push_back(ak);
287 					}
288 				}
289 
290 				return true;
291 			} else if (track_get_type(track) == TYPE_ANIMATION) {
292 
293 				AnimationTrack *an = static_cast<AnimationTrack *>(tracks[track]);
294 				Dictionary d = p_value;
295 				ERR_FAIL_COND_V(!d.has("times"), false);
296 				ERR_FAIL_COND_V(!d.has("clips"), false);
297 
298 				PoolVector<float> times = d["times"];
299 				PoolVector<String> clips = d["clips"];
300 
301 				ERR_FAIL_COND_V(clips.size() != times.size(), false);
302 
303 				if (times.size()) {
304 
305 					int valcount = times.size();
306 
307 					PoolVector<float>::Read rt = times.read();
308 					PoolVector<String>::Read rc = clips.read();
309 
310 					an->values.resize(valcount);
311 
312 					for (int i = 0; i < valcount; i++) {
313 
314 						TKey<StringName> ak;
315 						ak.time = rt[i];
316 						ak.value = rc[i];
317 						an->values.write[i] = ak;
318 					}
319 				}
320 
321 				return true;
322 			} else {
323 				return false;
324 			}
325 		} else
326 			return false;
327 	} else
328 		return false;
329 
330 	return true;
331 }
332 
_get(const StringName & p_name,Variant & r_ret) const333 bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
334 
335 	String name = p_name;
336 
337 	if (name == "length")
338 		r_ret = length;
339 	else if (name == "loop")
340 		r_ret = loop;
341 	else if (name == "step")
342 		r_ret = step;
343 	else if (name.begins_with("tracks/")) {
344 
345 		int track = name.get_slicec('/', 1).to_int();
346 		String what = name.get_slicec('/', 2);
347 		ERR_FAIL_INDEX_V(track, tracks.size(), false);
348 		if (what == "type") {
349 
350 			switch (track_get_type(track)) {
351 
352 				case TYPE_TRANSFORM: r_ret = "transform"; break;
353 				case TYPE_VALUE: r_ret = "value"; break;
354 				case TYPE_METHOD: r_ret = "method"; break;
355 				case TYPE_BEZIER: r_ret = "bezier"; break;
356 				case TYPE_AUDIO: r_ret = "audio"; break;
357 				case TYPE_ANIMATION: r_ret = "animation"; break;
358 			}
359 
360 			return true;
361 
362 		} else if (what == "path")
363 			r_ret = track_get_path(track);
364 		else if (what == "interp")
365 			r_ret = track_get_interpolation_type(track);
366 		else if (what == "loop_wrap")
367 			r_ret = track_get_interpolation_loop_wrap(track);
368 		else if (what == "imported")
369 			r_ret = track_is_imported(track);
370 		else if (what == "enabled")
371 			r_ret = track_is_enabled(track);
372 		else if (what == "keys") {
373 
374 			if (track_get_type(track) == TYPE_TRANSFORM) {
375 
376 				PoolVector<real_t> keys;
377 				int kk = track_get_key_count(track);
378 				keys.resize(kk * 12);
379 
380 				PoolVector<real_t>::Write w = keys.write();
381 
382 				int idx = 0;
383 				for (int i = 0; i < track_get_key_count(track); i++) {
384 
385 					Vector3 loc;
386 					Quat rot;
387 					Vector3 scale;
388 					transform_track_get_key(track, i, &loc, &rot, &scale);
389 
390 					w[idx++] = track_get_key_time(track, i);
391 					w[idx++] = track_get_key_transition(track, i);
392 					w[idx++] = loc.x;
393 					w[idx++] = loc.y;
394 					w[idx++] = loc.z;
395 
396 					w[idx++] = rot.x;
397 					w[idx++] = rot.y;
398 					w[idx++] = rot.z;
399 					w[idx++] = rot.w;
400 
401 					w[idx++] = scale.x;
402 					w[idx++] = scale.y;
403 					w[idx++] = scale.z;
404 				}
405 
406 				w.release();
407 				r_ret = keys;
408 				return true;
409 
410 			} else if (track_get_type(track) == TYPE_VALUE) {
411 
412 				const ValueTrack *vt = static_cast<const ValueTrack *>(tracks[track]);
413 
414 				Dictionary d;
415 
416 				PoolVector<float> key_times;
417 				PoolVector<float> key_transitions;
418 				Array key_values;
419 
420 				int kk = vt->values.size();
421 
422 				key_times.resize(kk);
423 				key_transitions.resize(kk);
424 				key_values.resize(kk);
425 
426 				PoolVector<float>::Write wti = key_times.write();
427 				PoolVector<float>::Write wtr = key_transitions.write();
428 
429 				int idx = 0;
430 
431 				const TKey<Variant> *vls = vt->values.ptr();
432 
433 				for (int i = 0; i < kk; i++) {
434 
435 					wti[idx] = vls[i].time;
436 					wtr[idx] = vls[i].transition;
437 					key_values[idx] = vls[i].value;
438 					idx++;
439 				}
440 
441 				wti.release();
442 				wtr.release();
443 
444 				d["times"] = key_times;
445 				d["transitions"] = key_transitions;
446 				d["values"] = key_values;
447 				if (track_get_type(track) == TYPE_VALUE) {
448 					d["update"] = value_track_get_update_mode(track);
449 				}
450 
451 				r_ret = d;
452 
453 				return true;
454 
455 			} else if (track_get_type(track) == TYPE_METHOD) {
456 
457 				Dictionary d;
458 
459 				PoolVector<float> key_times;
460 				PoolVector<float> key_transitions;
461 				Array key_values;
462 
463 				int kk = track_get_key_count(track);
464 
465 				key_times.resize(kk);
466 				key_transitions.resize(kk);
467 				key_values.resize(kk);
468 
469 				PoolVector<float>::Write wti = key_times.write();
470 				PoolVector<float>::Write wtr = key_transitions.write();
471 
472 				int idx = 0;
473 				for (int i = 0; i < track_get_key_count(track); i++) {
474 
475 					wti[idx] = track_get_key_time(track, i);
476 					wtr[idx] = track_get_key_transition(track, i);
477 					key_values[idx] = track_get_key_value(track, i);
478 					idx++;
479 				}
480 
481 				wti.release();
482 				wtr.release();
483 
484 				d["times"] = key_times;
485 				d["transitions"] = key_transitions;
486 				d["values"] = key_values;
487 				if (track_get_type(track) == TYPE_VALUE) {
488 					d["update"] = value_track_get_update_mode(track);
489 				}
490 
491 				r_ret = d;
492 
493 				return true;
494 			} else if (track_get_type(track) == TYPE_BEZIER) {
495 
496 				const BezierTrack *bt = static_cast<const BezierTrack *>(tracks[track]);
497 
498 				Dictionary d;
499 
500 				PoolVector<float> key_times;
501 				PoolVector<float> key_points;
502 
503 				int kk = bt->values.size();
504 
505 				key_times.resize(kk);
506 				key_points.resize(kk * 5);
507 
508 				PoolVector<float>::Write wti = key_times.write();
509 				PoolVector<float>::Write wpo = key_points.write();
510 
511 				int idx = 0;
512 
513 				const TKey<BezierKey> *vls = bt->values.ptr();
514 
515 				for (int i = 0; i < kk; i++) {
516 
517 					wti[idx] = vls[i].time;
518 					wpo[idx * 5 + 0] = vls[i].value.value;
519 					wpo[idx * 5 + 1] = vls[i].value.in_handle.x;
520 					wpo[idx * 5 + 2] = vls[i].value.in_handle.y;
521 					wpo[idx * 5 + 3] = vls[i].value.out_handle.x;
522 					wpo[idx * 5 + 4] = vls[i].value.out_handle.y;
523 					idx++;
524 				}
525 
526 				wti.release();
527 				wpo.release();
528 
529 				d["times"] = key_times;
530 				d["points"] = key_points;
531 
532 				r_ret = d;
533 
534 				return true;
535 			} else if (track_get_type(track) == TYPE_AUDIO) {
536 
537 				const AudioTrack *ad = static_cast<const AudioTrack *>(tracks[track]);
538 
539 				Dictionary d;
540 
541 				PoolVector<float> key_times;
542 				Array clips;
543 
544 				int kk = ad->values.size();
545 
546 				key_times.resize(kk);
547 
548 				PoolVector<float>::Write wti = key_times.write();
549 
550 				int idx = 0;
551 
552 				const TKey<AudioKey> *vls = ad->values.ptr();
553 
554 				for (int i = 0; i < kk; i++) {
555 
556 					wti[idx] = vls[i].time;
557 					Dictionary clip;
558 					clip["start_offset"] = vls[i].value.start_offset;
559 					clip["end_offset"] = vls[i].value.end_offset;
560 					clip["stream"] = vls[i].value.stream;
561 					clips.push_back(clip);
562 					idx++;
563 				}
564 
565 				wti.release();
566 
567 				d["times"] = key_times;
568 				d["clips"] = clips;
569 
570 				r_ret = d;
571 
572 				return true;
573 			} else if (track_get_type(track) == TYPE_ANIMATION) {
574 
575 				const AnimationTrack *an = static_cast<const AnimationTrack *>(tracks[track]);
576 
577 				Dictionary d;
578 
579 				PoolVector<float> key_times;
580 				PoolVector<String> clips;
581 
582 				int kk = an->values.size();
583 
584 				key_times.resize(kk);
585 				clips.resize(kk);
586 
587 				PoolVector<float>::Write wti = key_times.write();
588 				PoolVector<String>::Write wcl = clips.write();
589 
590 				const TKey<StringName> *vls = an->values.ptr();
591 
592 				for (int i = 0; i < kk; i++) {
593 
594 					wti[i] = vls[i].time;
595 					wcl[i] = vls[i].value;
596 				}
597 
598 				wti.release();
599 				wcl.release();
600 
601 				d["times"] = key_times;
602 				d["clips"] = clips;
603 
604 				r_ret = d;
605 
606 				return true;
607 			}
608 		} else
609 			return false;
610 	} else
611 		return false;
612 
613 	return true;
614 }
615 
_get_property_list(List<PropertyInfo> * p_list) const616 void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
617 	for (int i = 0; i < tracks.size(); i++) {
618 
619 		p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
620 		p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
621 		p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
622 		p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
623 		p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
624 		p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
625 		p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
626 	}
627 }
628 
add_track(TrackType p_type,int p_at_pos)629 int Animation::add_track(TrackType p_type, int p_at_pos) {
630 
631 	if (p_at_pos < 0 || p_at_pos >= tracks.size())
632 		p_at_pos = tracks.size();
633 
634 	switch (p_type) {
635 
636 		case TYPE_TRANSFORM: {
637 
638 			TransformTrack *tt = memnew(TransformTrack);
639 			tracks.insert(p_at_pos, tt);
640 		} break;
641 		case TYPE_VALUE: {
642 
643 			tracks.insert(p_at_pos, memnew(ValueTrack));
644 
645 		} break;
646 		case TYPE_METHOD: {
647 
648 			tracks.insert(p_at_pos, memnew(MethodTrack));
649 
650 		} break;
651 		case TYPE_BEZIER: {
652 
653 			tracks.insert(p_at_pos, memnew(BezierTrack));
654 
655 		} break;
656 		case TYPE_AUDIO: {
657 
658 			tracks.insert(p_at_pos, memnew(AudioTrack));
659 
660 		} break;
661 		case TYPE_ANIMATION: {
662 
663 			tracks.insert(p_at_pos, memnew(AnimationTrack));
664 
665 		} break;
666 		default: {
667 
668 			ERR_PRINT("Unknown track type");
669 		}
670 	}
671 	emit_changed();
672 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
673 	return p_at_pos;
674 }
675 
remove_track(int p_track)676 void Animation::remove_track(int p_track) {
677 
678 	ERR_FAIL_INDEX(p_track, tracks.size());
679 	Track *t = tracks[p_track];
680 
681 	switch (t->type) {
682 
683 		case TYPE_TRANSFORM: {
684 
685 			TransformTrack *tt = static_cast<TransformTrack *>(t);
686 			_clear(tt->transforms);
687 
688 		} break;
689 		case TYPE_VALUE: {
690 
691 			ValueTrack *vt = static_cast<ValueTrack *>(t);
692 			_clear(vt->values);
693 
694 		} break;
695 		case TYPE_METHOD: {
696 
697 			MethodTrack *mt = static_cast<MethodTrack *>(t);
698 			_clear(mt->methods);
699 
700 		} break;
701 		case TYPE_BEZIER: {
702 
703 			BezierTrack *bz = static_cast<BezierTrack *>(t);
704 			_clear(bz->values);
705 
706 		} break;
707 		case TYPE_AUDIO: {
708 
709 			AudioTrack *ad = static_cast<AudioTrack *>(t);
710 			_clear(ad->values);
711 
712 		} break;
713 		case TYPE_ANIMATION: {
714 
715 			AnimationTrack *an = static_cast<AnimationTrack *>(t);
716 			_clear(an->values);
717 
718 		} break;
719 	}
720 
721 	memdelete(t);
722 	tracks.remove(p_track);
723 	emit_changed();
724 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
725 }
726 
get_track_count() const727 int Animation::get_track_count() const {
728 
729 	return tracks.size();
730 }
731 
track_get_type(int p_track) const732 Animation::TrackType Animation::track_get_type(int p_track) const {
733 
734 	ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_TRANSFORM);
735 	return tracks[p_track]->type;
736 }
737 
track_set_path(int p_track,const NodePath & p_path)738 void Animation::track_set_path(int p_track, const NodePath &p_path) {
739 
740 	ERR_FAIL_INDEX(p_track, tracks.size());
741 	tracks[p_track]->path = p_path;
742 	emit_changed();
743 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
744 }
745 
track_get_path(int p_track) const746 NodePath Animation::track_get_path(int p_track) const {
747 
748 	ERR_FAIL_INDEX_V(p_track, tracks.size(), NodePath());
749 	return tracks[p_track]->path;
750 }
751 
find_track(const NodePath & p_path) const752 int Animation::find_track(const NodePath &p_path) const {
753 
754 	for (int i = 0; i < tracks.size(); i++) {
755 
756 		if (tracks[i]->path == p_path)
757 			return i;
758 	};
759 	return -1;
760 };
761 
track_set_interpolation_type(int p_track,InterpolationType p_interp)762 void Animation::track_set_interpolation_type(int p_track, InterpolationType p_interp) {
763 
764 	ERR_FAIL_INDEX(p_track, tracks.size());
765 	ERR_FAIL_INDEX(p_interp, 3);
766 	tracks[p_track]->interpolation = p_interp;
767 	emit_changed();
768 }
769 
track_get_interpolation_type(int p_track) const770 Animation::InterpolationType Animation::track_get_interpolation_type(int p_track) const {
771 
772 	ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
773 	return tracks[p_track]->interpolation;
774 }
775 
track_set_interpolation_loop_wrap(int p_track,bool p_enable)776 void Animation::track_set_interpolation_loop_wrap(int p_track, bool p_enable) {
777 	ERR_FAIL_INDEX(p_track, tracks.size());
778 	tracks[p_track]->loop_wrap = p_enable;
779 	emit_changed();
780 }
781 
track_get_interpolation_loop_wrap(int p_track) const782 bool Animation::track_get_interpolation_loop_wrap(int p_track) const {
783 
784 	ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
785 	return tracks[p_track]->loop_wrap;
786 }
787 
788 // transform
789 /*
790 template<class T>
791 int Animation::_insert_pos(float p_time, T& p_keys) {
792 
793 	// simple, linear time inset that should be fast enough in reality.
794 
795 	int idx=p_keys.size();
796 
797 	while(true) {
798 
799 
800 		if (idx==0 || p_keys[idx-1].time < p_time) {
801 			//condition for insertion.
802 			p_keys.insert(idx,T());
803 			return idx;
804 		} else if (p_keys[idx-1].time == p_time) {
805 
806 			// condition for replacing.
807 			return idx-1;
808 		}
809 
810 		idx--;
811 	}
812 
813 }
814 */
815 template <class T, class V>
_insert(float p_time,T & p_keys,const V & p_value)816 int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
817 
818 	int idx = p_keys.size();
819 
820 	while (true) {
821 
822 		// Condition for replacement.
823 		if (idx > 0 && Math::is_equal_approx(p_keys[idx - 1].time, p_time)) {
824 			float transition = p_keys[idx - 1].transition;
825 			p_keys.write[idx - 1] = p_value;
826 			p_keys.write[idx - 1].transition = transition;
827 			return idx - 1;
828 
829 			// Condition for insert.
830 		} else if (idx == 0 || p_keys[idx - 1].time < p_time) {
831 
832 			p_keys.insert(idx, p_value);
833 			return idx;
834 		}
835 
836 		idx--;
837 	}
838 
839 	return -1;
840 }
841 
842 template <class T>
_clear(T & p_keys)843 void Animation::_clear(T &p_keys) {
844 
845 	p_keys.clear();
846 }
847 
transform_track_get_key(int p_track,int p_key,Vector3 * r_loc,Quat * r_rot,Vector3 * r_scale) const848 Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
849 
850 	ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
851 	Track *t = tracks[p_track];
852 
853 	TransformTrack *tt = static_cast<TransformTrack *>(t);
854 	ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
855 	ERR_FAIL_INDEX_V(p_key, tt->transforms.size(), ERR_INVALID_PARAMETER);
856 
857 	if (r_loc)
858 		*r_loc = tt->transforms[p_key].value.loc;
859 	if (r_rot)
860 		*r_rot = tt->transforms[p_key].value.rot;
861 	if (r_scale)
862 		*r_scale = tt->transforms[p_key].value.scale;
863 
864 	return OK;
865 }
866 
transform_track_insert_key(int p_track,float p_time,const Vector3 & p_loc,const Quat & p_rot,const Vector3 & p_scale)867 int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot, const Vector3 &p_scale) {
868 
869 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
870 	Track *t = tracks[p_track];
871 	ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, -1);
872 
873 	TransformTrack *tt = static_cast<TransformTrack *>(t);
874 
875 	TKey<TransformKey> tkey;
876 	tkey.time = p_time;
877 	tkey.value.loc = p_loc;
878 	tkey.value.rot = p_rot;
879 	tkey.value.scale = p_scale;
880 
881 	int ret = _insert(p_time, tt->transforms, tkey);
882 	emit_changed();
883 	return ret;
884 }
885 
track_remove_key_at_position(int p_track,float p_pos)886 void Animation::track_remove_key_at_position(int p_track, float p_pos) {
887 
888 	int idx = track_find_key(p_track, p_pos, true);
889 	ERR_FAIL_COND(idx < 0);
890 	track_remove_key(p_track, idx);
891 }
892 
track_remove_key(int p_track,int p_idx)893 void Animation::track_remove_key(int p_track, int p_idx) {
894 
895 	ERR_FAIL_INDEX(p_track, tracks.size());
896 	Track *t = tracks[p_track];
897 
898 	switch (t->type) {
899 		case TYPE_TRANSFORM: {
900 
901 			TransformTrack *tt = static_cast<TransformTrack *>(t);
902 			ERR_FAIL_INDEX(p_idx, tt->transforms.size());
903 			tt->transforms.remove(p_idx);
904 
905 		} break;
906 		case TYPE_VALUE: {
907 
908 			ValueTrack *vt = static_cast<ValueTrack *>(t);
909 			ERR_FAIL_INDEX(p_idx, vt->values.size());
910 			vt->values.remove(p_idx);
911 
912 		} break;
913 		case TYPE_METHOD: {
914 
915 			MethodTrack *mt = static_cast<MethodTrack *>(t);
916 			ERR_FAIL_INDEX(p_idx, mt->methods.size());
917 			mt->methods.remove(p_idx);
918 
919 		} break;
920 		case TYPE_BEZIER: {
921 
922 			BezierTrack *bz = static_cast<BezierTrack *>(t);
923 			ERR_FAIL_INDEX(p_idx, bz->values.size());
924 			bz->values.remove(p_idx);
925 
926 		} break;
927 		case TYPE_AUDIO: {
928 
929 			AudioTrack *ad = static_cast<AudioTrack *>(t);
930 			ERR_FAIL_INDEX(p_idx, ad->values.size());
931 			ad->values.remove(p_idx);
932 
933 		} break;
934 		case TYPE_ANIMATION: {
935 
936 			AnimationTrack *an = static_cast<AnimationTrack *>(t);
937 			ERR_FAIL_INDEX(p_idx, an->values.size());
938 			an->values.remove(p_idx);
939 
940 		} break;
941 	}
942 
943 	emit_changed();
944 }
945 
track_find_key(int p_track,float p_time,bool p_exact) const946 int Animation::track_find_key(int p_track, float p_time, bool p_exact) const {
947 
948 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
949 	Track *t = tracks[p_track];
950 
951 	switch (t->type) {
952 		case TYPE_TRANSFORM: {
953 
954 			TransformTrack *tt = static_cast<TransformTrack *>(t);
955 			int k = _find(tt->transforms, p_time);
956 			if (k < 0 || k >= tt->transforms.size())
957 				return -1;
958 			if (tt->transforms[k].time != p_time && p_exact)
959 				return -1;
960 			return k;
961 
962 		} break;
963 		case TYPE_VALUE: {
964 
965 			ValueTrack *vt = static_cast<ValueTrack *>(t);
966 			int k = _find(vt->values, p_time);
967 			if (k < 0 || k >= vt->values.size())
968 				return -1;
969 			if (vt->values[k].time != p_time && p_exact)
970 				return -1;
971 			return k;
972 
973 		} break;
974 		case TYPE_METHOD: {
975 
976 			MethodTrack *mt = static_cast<MethodTrack *>(t);
977 			int k = _find(mt->methods, p_time);
978 			if (k < 0 || k >= mt->methods.size())
979 				return -1;
980 			if (mt->methods[k].time != p_time && p_exact)
981 				return -1;
982 			return k;
983 
984 		} break;
985 		case TYPE_BEZIER: {
986 
987 			BezierTrack *bt = static_cast<BezierTrack *>(t);
988 			int k = _find(bt->values, p_time);
989 			if (k < 0 || k >= bt->values.size())
990 				return -1;
991 			if (bt->values[k].time != p_time && p_exact)
992 				return -1;
993 			return k;
994 
995 		} break;
996 		case TYPE_AUDIO: {
997 
998 			AudioTrack *at = static_cast<AudioTrack *>(t);
999 			int k = _find(at->values, p_time);
1000 			if (k < 0 || k >= at->values.size())
1001 				return -1;
1002 			if (at->values[k].time != p_time && p_exact)
1003 				return -1;
1004 			return k;
1005 
1006 		} break;
1007 		case TYPE_ANIMATION: {
1008 
1009 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1010 			int k = _find(at->values, p_time);
1011 			if (k < 0 || k >= at->values.size())
1012 				return -1;
1013 			if (at->values[k].time != p_time && p_exact)
1014 				return -1;
1015 			return k;
1016 
1017 		} break;
1018 	}
1019 
1020 	return -1;
1021 }
1022 
track_insert_key(int p_track,float p_time,const Variant & p_key,float p_transition)1023 void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition) {
1024 
1025 	ERR_FAIL_INDEX(p_track, tracks.size());
1026 	Track *t = tracks[p_track];
1027 
1028 	switch (t->type) {
1029 
1030 		case TYPE_TRANSFORM: {
1031 
1032 			Dictionary d = p_key;
1033 			Vector3 loc;
1034 			if (d.has("location"))
1035 				loc = d["location"];
1036 
1037 			Quat rot;
1038 			if (d.has("rotation"))
1039 				rot = d["rotation"];
1040 
1041 			Vector3 scale;
1042 			if (d.has("scale"))
1043 				scale = d["scale"];
1044 
1045 			int idx = transform_track_insert_key(p_track, p_time, loc, rot, scale);
1046 			track_set_key_transition(p_track, idx, p_transition);
1047 
1048 		} break;
1049 		case TYPE_VALUE: {
1050 
1051 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1052 
1053 			TKey<Variant> k;
1054 			k.time = p_time;
1055 			k.transition = p_transition;
1056 			k.value = p_key;
1057 			_insert(p_time, vt->values, k);
1058 
1059 		} break;
1060 		case TYPE_METHOD: {
1061 
1062 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1063 
1064 			ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY);
1065 
1066 			Dictionary d = p_key;
1067 			ERR_FAIL_COND(!d.has("method") || d["method"].get_type() != Variant::STRING);
1068 			ERR_FAIL_COND(!d.has("args") || !d["args"].is_array());
1069 
1070 			MethodKey k;
1071 
1072 			k.time = p_time;
1073 			k.transition = p_transition;
1074 			k.method = d["method"];
1075 			k.params = d["args"];
1076 
1077 			_insert(p_time, mt->methods, k);
1078 
1079 		} break;
1080 		case TYPE_BEZIER: {
1081 
1082 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1083 
1084 			Array arr = p_key;
1085 			ERR_FAIL_COND(arr.size() != 5);
1086 
1087 			TKey<BezierKey> k;
1088 			k.time = p_time;
1089 			k.value.value = arr[0];
1090 			k.value.in_handle.x = arr[1];
1091 			k.value.in_handle.y = arr[2];
1092 			k.value.out_handle.x = arr[3];
1093 			k.value.out_handle.y = arr[4];
1094 			_insert(p_time, bt->values, k);
1095 
1096 		} break;
1097 		case TYPE_AUDIO: {
1098 
1099 			AudioTrack *at = static_cast<AudioTrack *>(t);
1100 
1101 			Dictionary k = p_key;
1102 			ERR_FAIL_COND(!k.has("start_offset"));
1103 			ERR_FAIL_COND(!k.has("end_offset"));
1104 			ERR_FAIL_COND(!k.has("stream"));
1105 
1106 			TKey<AudioKey> ak;
1107 			ak.time = p_time;
1108 			ak.value.start_offset = k["start_offset"];
1109 			ak.value.end_offset = k["end_offset"];
1110 			ak.value.stream = k["stream"];
1111 			_insert(p_time, at->values, ak);
1112 
1113 		} break;
1114 		case TYPE_ANIMATION: {
1115 
1116 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1117 
1118 			TKey<StringName> ak;
1119 			ak.time = p_time;
1120 			ak.value = p_key;
1121 
1122 			_insert(p_time, at->values, ak);
1123 
1124 		} break;
1125 	}
1126 
1127 	emit_changed();
1128 }
1129 
track_get_key_count(int p_track) const1130 int Animation::track_get_key_count(int p_track) const {
1131 
1132 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1133 	Track *t = tracks[p_track];
1134 
1135 	switch (t->type) {
1136 
1137 		case TYPE_TRANSFORM: {
1138 
1139 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1140 			return tt->transforms.size();
1141 		} break;
1142 		case TYPE_VALUE: {
1143 
1144 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1145 			return vt->values.size();
1146 
1147 		} break;
1148 		case TYPE_METHOD: {
1149 
1150 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1151 			return mt->methods.size();
1152 		} break;
1153 		case TYPE_BEZIER: {
1154 
1155 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1156 			return bt->values.size();
1157 		} break;
1158 		case TYPE_AUDIO: {
1159 
1160 			AudioTrack *at = static_cast<AudioTrack *>(t);
1161 			return at->values.size();
1162 		} break;
1163 		case TYPE_ANIMATION: {
1164 
1165 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1166 			return at->values.size();
1167 		} break;
1168 	}
1169 
1170 	ERR_FAIL_V(-1);
1171 }
1172 
track_get_key_value(int p_track,int p_key_idx) const1173 Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
1174 
1175 	ERR_FAIL_INDEX_V(p_track, tracks.size(), Variant());
1176 	Track *t = tracks[p_track];
1177 
1178 	switch (t->type) {
1179 
1180 		case TYPE_TRANSFORM: {
1181 
1182 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1183 			ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), Variant());
1184 
1185 			Dictionary d;
1186 			d["location"] = tt->transforms[p_key_idx].value.loc;
1187 			d["rotation"] = tt->transforms[p_key_idx].value.rot;
1188 			d["scale"] = tt->transforms[p_key_idx].value.scale;
1189 
1190 			return d;
1191 		} break;
1192 		case TYPE_VALUE: {
1193 
1194 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1195 			ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), Variant());
1196 			return vt->values[p_key_idx].value;
1197 
1198 		} break;
1199 		case TYPE_METHOD: {
1200 
1201 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1202 			ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), Variant());
1203 			Dictionary d;
1204 			d["method"] = mt->methods[p_key_idx].method;
1205 			d["args"] = mt->methods[p_key_idx].params;
1206 			return d;
1207 
1208 		} break;
1209 		case TYPE_BEZIER: {
1210 
1211 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1212 			ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant());
1213 
1214 			Array arr;
1215 			arr.resize(5);
1216 			arr[0] = bt->values[p_key_idx].value.value;
1217 			arr[1] = bt->values[p_key_idx].value.in_handle.x;
1218 			arr[2] = bt->values[p_key_idx].value.in_handle.y;
1219 			arr[3] = bt->values[p_key_idx].value.out_handle.x;
1220 			arr[4] = bt->values[p_key_idx].value.out_handle.y;
1221 			return arr;
1222 
1223 		} break;
1224 		case TYPE_AUDIO: {
1225 
1226 			AudioTrack *at = static_cast<AudioTrack *>(t);
1227 			ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
1228 
1229 			Dictionary k;
1230 			k["start_offset"] = at->values[p_key_idx].value.start_offset;
1231 			k["end_offset"] = at->values[p_key_idx].value.end_offset;
1232 			k["stream"] = at->values[p_key_idx].value.stream;
1233 			return k;
1234 
1235 		} break;
1236 		case TYPE_ANIMATION: {
1237 
1238 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1239 			ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
1240 
1241 			return at->values[p_key_idx].value;
1242 
1243 		} break;
1244 	}
1245 
1246 	ERR_FAIL_V(Variant());
1247 }
1248 
track_get_key_time(int p_track,int p_key_idx) const1249 float Animation::track_get_key_time(int p_track, int p_key_idx) const {
1250 
1251 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1252 	Track *t = tracks[p_track];
1253 
1254 	switch (t->type) {
1255 
1256 		case TYPE_TRANSFORM: {
1257 
1258 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1259 			ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
1260 			return tt->transforms[p_key_idx].time;
1261 		} break;
1262 		case TYPE_VALUE: {
1263 
1264 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1265 			ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
1266 			return vt->values[p_key_idx].time;
1267 
1268 		} break;
1269 		case TYPE_METHOD: {
1270 
1271 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1272 			ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
1273 			return mt->methods[p_key_idx].time;
1274 
1275 		} break;
1276 		case TYPE_BEZIER: {
1277 
1278 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1279 			ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), -1);
1280 			return bt->values[p_key_idx].time;
1281 
1282 		} break;
1283 		case TYPE_AUDIO: {
1284 
1285 			AudioTrack *at = static_cast<AudioTrack *>(t);
1286 			ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
1287 			return at->values[p_key_idx].time;
1288 
1289 		} break;
1290 		case TYPE_ANIMATION: {
1291 
1292 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1293 			ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
1294 			return at->values[p_key_idx].time;
1295 
1296 		} break;
1297 	}
1298 
1299 	ERR_FAIL_V(-1);
1300 }
1301 
track_set_key_time(int p_track,int p_key_idx,float p_time)1302 void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
1303 
1304 	ERR_FAIL_INDEX(p_track, tracks.size());
1305 	Track *t = tracks[p_track];
1306 
1307 	switch (t->type) {
1308 
1309 		case TYPE_TRANSFORM: {
1310 
1311 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1312 			ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
1313 			TKey<TransformKey> key = tt->transforms[p_key_idx];
1314 			key.time = p_time;
1315 			tt->transforms.remove(p_key_idx);
1316 			_insert(p_time, tt->transforms, key);
1317 			return;
1318 		}
1319 		case TYPE_VALUE: {
1320 
1321 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1322 			ERR_FAIL_INDEX(p_key_idx, vt->values.size());
1323 			TKey<Variant> key = vt->values[p_key_idx];
1324 			key.time = p_time;
1325 			vt->values.remove(p_key_idx);
1326 			_insert(p_time, vt->values, key);
1327 			return;
1328 		}
1329 		case TYPE_METHOD: {
1330 
1331 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1332 			ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
1333 			MethodKey key = mt->methods[p_key_idx];
1334 			key.time = p_time;
1335 			mt->methods.remove(p_key_idx);
1336 			_insert(p_time, mt->methods, key);
1337 			return;
1338 		}
1339 		case TYPE_BEZIER: {
1340 
1341 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1342 			ERR_FAIL_INDEX(p_key_idx, bt->values.size());
1343 			TKey<BezierKey> key = bt->values[p_key_idx];
1344 			key.time = p_time;
1345 			bt->values.remove(p_key_idx);
1346 			_insert(p_time, bt->values, key);
1347 			return;
1348 		}
1349 		case TYPE_AUDIO: {
1350 
1351 			AudioTrack *at = static_cast<AudioTrack *>(t);
1352 			ERR_FAIL_INDEX(p_key_idx, at->values.size());
1353 			TKey<AudioKey> key = at->values[p_key_idx];
1354 			key.time = p_time;
1355 			at->values.remove(p_key_idx);
1356 			_insert(p_time, at->values, key);
1357 			return;
1358 		}
1359 		case TYPE_ANIMATION: {
1360 
1361 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1362 			ERR_FAIL_INDEX(p_key_idx, at->values.size());
1363 			TKey<StringName> key = at->values[p_key_idx];
1364 			key.time = p_time;
1365 			at->values.remove(p_key_idx);
1366 			_insert(p_time, at->values, key);
1367 			return;
1368 		}
1369 	}
1370 
1371 	ERR_FAIL();
1372 }
1373 
track_get_key_transition(int p_track,int p_key_idx) const1374 float Animation::track_get_key_transition(int p_track, int p_key_idx) const {
1375 
1376 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1377 	Track *t = tracks[p_track];
1378 
1379 	switch (t->type) {
1380 
1381 		case TYPE_TRANSFORM: {
1382 
1383 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1384 			ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
1385 			return tt->transforms[p_key_idx].transition;
1386 		} break;
1387 		case TYPE_VALUE: {
1388 
1389 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1390 			ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
1391 			return vt->values[p_key_idx].transition;
1392 
1393 		} break;
1394 		case TYPE_METHOD: {
1395 
1396 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1397 			ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
1398 			return mt->methods[p_key_idx].transition;
1399 
1400 		} break;
1401 		case TYPE_BEZIER: {
1402 
1403 			return 1; //bezier does not really use transitions
1404 		} break;
1405 		case TYPE_AUDIO: {
1406 
1407 			return 1; //audio does not really use transitions
1408 		} break;
1409 		case TYPE_ANIMATION: {
1410 
1411 			return 1; //animation does not really use transitions
1412 		} break;
1413 	}
1414 
1415 	ERR_FAIL_V(0);
1416 }
1417 
track_set_key_value(int p_track,int p_key_idx,const Variant & p_value)1418 void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p_value) {
1419 
1420 	ERR_FAIL_INDEX(p_track, tracks.size());
1421 	Track *t = tracks[p_track];
1422 
1423 	switch (t->type) {
1424 
1425 		case TYPE_TRANSFORM: {
1426 
1427 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1428 			ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
1429 
1430 			Dictionary d = p_value;
1431 
1432 			if (d.has("location"))
1433 				tt->transforms.write[p_key_idx].value.loc = d["location"];
1434 			if (d.has("rotation"))
1435 				tt->transforms.write[p_key_idx].value.rot = d["rotation"];
1436 			if (d.has("scale"))
1437 				tt->transforms.write[p_key_idx].value.scale = d["scale"];
1438 
1439 		} break;
1440 		case TYPE_VALUE: {
1441 
1442 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1443 			ERR_FAIL_INDEX(p_key_idx, vt->values.size());
1444 
1445 			vt->values.write[p_key_idx].value = p_value;
1446 
1447 		} break;
1448 		case TYPE_METHOD: {
1449 
1450 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1451 			ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
1452 
1453 			Dictionary d = p_value;
1454 
1455 			if (d.has("method"))
1456 				mt->methods.write[p_key_idx].method = d["method"];
1457 			if (d.has("args"))
1458 				mt->methods.write[p_key_idx].params = d["args"];
1459 
1460 		} break;
1461 		case TYPE_BEZIER: {
1462 
1463 			BezierTrack *bt = static_cast<BezierTrack *>(t);
1464 			ERR_FAIL_INDEX(p_key_idx, bt->values.size());
1465 
1466 			Array arr = p_value;
1467 			ERR_FAIL_COND(arr.size() != 5);
1468 
1469 			bt->values.write[p_key_idx].value.value = arr[0];
1470 			bt->values.write[p_key_idx].value.in_handle.x = arr[1];
1471 			bt->values.write[p_key_idx].value.in_handle.y = arr[2];
1472 			bt->values.write[p_key_idx].value.out_handle.x = arr[3];
1473 			bt->values.write[p_key_idx].value.out_handle.y = arr[4];
1474 
1475 		} break;
1476 		case TYPE_AUDIO: {
1477 
1478 			AudioTrack *at = static_cast<AudioTrack *>(t);
1479 			ERR_FAIL_INDEX(p_key_idx, at->values.size());
1480 
1481 			Dictionary k = p_value;
1482 			ERR_FAIL_COND(!k.has("start_offset"));
1483 			ERR_FAIL_COND(!k.has("end_offset"));
1484 			ERR_FAIL_COND(!k.has("stream"));
1485 
1486 			at->values.write[p_key_idx].value.start_offset = k["start_offset"];
1487 			at->values.write[p_key_idx].value.end_offset = k["end_offset"];
1488 			at->values.write[p_key_idx].value.stream = k["stream"];
1489 
1490 		} break;
1491 		case TYPE_ANIMATION: {
1492 
1493 			AnimationTrack *at = static_cast<AnimationTrack *>(t);
1494 			ERR_FAIL_INDEX(p_key_idx, at->values.size());
1495 
1496 			at->values.write[p_key_idx].value = p_value;
1497 
1498 		} break;
1499 	}
1500 
1501 	emit_changed();
1502 }
1503 
track_set_key_transition(int p_track,int p_key_idx,float p_transition)1504 void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) {
1505 
1506 	ERR_FAIL_INDEX(p_track, tracks.size());
1507 	Track *t = tracks[p_track];
1508 
1509 	switch (t->type) {
1510 
1511 		case TYPE_TRANSFORM: {
1512 
1513 			TransformTrack *tt = static_cast<TransformTrack *>(t);
1514 			ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
1515 			tt->transforms.write[p_key_idx].transition = p_transition;
1516 		} break;
1517 		case TYPE_VALUE: {
1518 
1519 			ValueTrack *vt = static_cast<ValueTrack *>(t);
1520 			ERR_FAIL_INDEX(p_key_idx, vt->values.size());
1521 			vt->values.write[p_key_idx].transition = p_transition;
1522 
1523 		} break;
1524 		case TYPE_METHOD: {
1525 
1526 			MethodTrack *mt = static_cast<MethodTrack *>(t);
1527 			ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
1528 			mt->methods.write[p_key_idx].transition = p_transition;
1529 
1530 		} break;
1531 		case TYPE_BEZIER:
1532 		case TYPE_AUDIO:
1533 		case TYPE_ANIMATION: {
1534 			// they don't use transition
1535 		} break;
1536 	}
1537 
1538 	emit_changed();
1539 }
1540 
1541 template <class K>
_find(const Vector<K> & p_keys,float p_time) const1542 int Animation::_find(const Vector<K> &p_keys, float p_time) const {
1543 
1544 	int len = p_keys.size();
1545 	if (len == 0)
1546 		return -2;
1547 
1548 	int low = 0;
1549 	int high = len - 1;
1550 	int middle = 0;
1551 
1552 #ifdef DEBUG_ENABLED
1553 	if (low > high)
1554 		ERR_PRINT("low > high, this may be a bug");
1555 #endif
1556 
1557 	const K *keys = &p_keys[0];
1558 
1559 	while (low <= high) {
1560 
1561 		middle = (low + high) / 2;
1562 
1563 		if (Math::is_equal_approx(p_time, keys[middle].time)) { //match
1564 			return middle;
1565 		} else if (p_time < keys[middle].time)
1566 			high = middle - 1; //search low end of array
1567 		else
1568 			low = middle + 1; //search high end of array
1569 	}
1570 
1571 	if (keys[middle].time > p_time)
1572 		middle--;
1573 
1574 	return middle;
1575 }
1576 
_interpolate(const Animation::TransformKey & p_a,const Animation::TransformKey & p_b,float p_c) const1577 Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const {
1578 
1579 	TransformKey ret;
1580 	ret.loc = _interpolate(p_a.loc, p_b.loc, p_c);
1581 	ret.rot = _interpolate(p_a.rot, p_b.rot, p_c);
1582 	ret.scale = _interpolate(p_a.scale, p_b.scale, p_c);
1583 
1584 	return ret;
1585 }
1586 
_interpolate(const Vector3 & p_a,const Vector3 & p_b,float p_c) const1587 Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const {
1588 
1589 	return p_a.linear_interpolate(p_b, p_c);
1590 }
_interpolate(const Quat & p_a,const Quat & p_b,float p_c) const1591 Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const {
1592 
1593 	return p_a.slerp(p_b, p_c);
1594 }
_interpolate(const Variant & p_a,const Variant & p_b,float p_c) const1595 Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const {
1596 
1597 	Variant dst;
1598 	Variant::interpolate(p_a, p_b, p_c, dst);
1599 	return dst;
1600 }
1601 
_interpolate(const float & p_a,const float & p_b,float p_c) const1602 float Animation::_interpolate(const float &p_a, const float &p_b, float p_c) const {
1603 
1604 	return p_a * (1.0 - p_c) + p_b * p_c;
1605 }
1606 
_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) const1607 Animation::TransformKey Animation::_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 {
1608 
1609 	Animation::TransformKey tk;
1610 
1611 	tk.loc = p_a.loc.cubic_interpolate(p_b.loc, p_pre_a.loc, p_post_b.loc, p_c);
1612 	tk.scale = p_a.scale.cubic_interpolate(p_b.scale, p_pre_a.scale, p_post_b.scale, p_c);
1613 	tk.rot = p_a.rot.cubic_slerp(p_b.rot, p_pre_a.rot, p_post_b.rot, p_c);
1614 
1615 	return tk;
1616 }
_cubic_interpolate(const Vector3 & p_pre_a,const Vector3 & p_a,const Vector3 & p_b,const Vector3 & p_post_b,float p_c) const1617 Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const {
1618 
1619 	return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c);
1620 }
_cubic_interpolate(const Quat & p_pre_a,const Quat & p_a,const Quat & p_b,const Quat & p_post_b,float p_c) const1621 Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const {
1622 
1623 	return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c);
1624 }
_cubic_interpolate(const Variant & p_pre_a,const Variant & p_a,const Variant & p_b,const Variant & p_post_b,float p_c) const1625 Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const {
1626 
1627 	Variant::Type type_a = p_a.get_type();
1628 	Variant::Type type_b = p_b.get_type();
1629 	Variant::Type type_pa = p_pre_a.get_type();
1630 	Variant::Type type_pb = p_post_b.get_type();
1631 
1632 	//make int and real play along
1633 
1634 	uint32_t vformat = 1 << type_a;
1635 	vformat |= 1 << type_b;
1636 	vformat |= 1 << type_pa;
1637 	vformat |= 1 << type_pb;
1638 
1639 	if (vformat == ((1 << Variant::INT) | (1 << Variant::REAL)) || vformat == (1 << Variant::REAL)) {
1640 		//mix of real and int
1641 
1642 		real_t p0 = p_pre_a;
1643 		real_t p1 = p_a;
1644 		real_t p2 = p_b;
1645 		real_t p3 = p_post_b;
1646 
1647 		float t = p_c;
1648 		float t2 = t * t;
1649 		float t3 = t2 * t;
1650 
1651 		return 0.5f * ((p1 * 2.0f) +
1652 							  (-p0 + p2) * t +
1653 							  (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
1654 							  (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
1655 
1656 	} else if ((vformat & (vformat - 1))) {
1657 
1658 		return p_a; //can't interpolate, mix of types
1659 	}
1660 
1661 	switch (type_a) {
1662 
1663 		case Variant::VECTOR2: {
1664 
1665 			Vector2 a = p_a;
1666 			Vector2 b = p_b;
1667 			Vector2 pa = p_pre_a;
1668 			Vector2 pb = p_post_b;
1669 
1670 			return a.cubic_interpolate(b, pa, pb, p_c);
1671 		}
1672 		case Variant::RECT2: {
1673 
1674 			Rect2 a = p_a;
1675 			Rect2 b = p_b;
1676 			Rect2 pa = p_pre_a;
1677 			Rect2 pb = p_post_b;
1678 
1679 			return Rect2(
1680 					a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
1681 					a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
1682 		}
1683 		case Variant::VECTOR3: {
1684 
1685 			Vector3 a = p_a;
1686 			Vector3 b = p_b;
1687 			Vector3 pa = p_pre_a;
1688 			Vector3 pb = p_post_b;
1689 
1690 			return a.cubic_interpolate(b, pa, pb, p_c);
1691 		}
1692 		case Variant::QUAT: {
1693 
1694 			Quat a = p_a;
1695 			Quat b = p_b;
1696 			Quat pa = p_pre_a;
1697 			Quat pb = p_post_b;
1698 
1699 			return a.cubic_slerp(b, pa, pb, p_c);
1700 		}
1701 		case Variant::AABB: {
1702 
1703 			AABB a = p_a;
1704 			AABB b = p_b;
1705 			AABB pa = p_pre_a;
1706 			AABB pb = p_post_b;
1707 
1708 			return AABB(
1709 					a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
1710 					a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
1711 		}
1712 		default: {
1713 
1714 			return _interpolate(p_a, p_b, p_c);
1715 		}
1716 	}
1717 }
_cubic_interpolate(const float & p_pre_a,const float & p_a,const float & p_b,const float & p_post_b,float p_c) const1718 float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
1719 
1720 	return _interpolate(p_a, p_b, p_c);
1721 }
1722 
1723 template <class T>
_interpolate(const Vector<TKey<T>> & p_keys,float p_time,InterpolationType p_interp,bool p_loop_wrap,bool * p_ok) const1724 T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const {
1725 
1726 	int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end)
1727 
1728 	if (len <= 0) {
1729 		// (-1 or -2 returned originally) (plus one above)
1730 		// meaning no keys, or only key time is larger than length
1731 		if (p_ok)
1732 			*p_ok = false;
1733 		return T();
1734 	} else if (len == 1) { // one key found (0+1), return it
1735 
1736 		if (p_ok)
1737 			*p_ok = true;
1738 		return p_keys[0].value;
1739 	}
1740 
1741 	int idx = _find(p_keys, p_time);
1742 
1743 	ERR_FAIL_COND_V(idx == -2, T());
1744 
1745 	bool result = true;
1746 	int next = 0;
1747 	float c = 0;
1748 	// prepare for all cases of interpolation
1749 
1750 	if (loop && p_loop_wrap) {
1751 		// loop
1752 		if (idx >= 0) {
1753 
1754 			if ((idx + 1) < len) {
1755 
1756 				next = idx + 1;
1757 				float delta = p_keys[next].time - p_keys[idx].time;
1758 				float from = p_time - p_keys[idx].time;
1759 
1760 				if (Math::is_zero_approx(delta))
1761 					c = 0;
1762 				else
1763 					c = from / delta;
1764 
1765 			} else {
1766 
1767 				next = 0;
1768 				float delta = (length - p_keys[idx].time) + p_keys[next].time;
1769 				float from = p_time - p_keys[idx].time;
1770 
1771 				if (Math::is_zero_approx(delta))
1772 					c = 0;
1773 				else
1774 					c = from / delta;
1775 			}
1776 
1777 		} else {
1778 			// on loop, behind first key
1779 			idx = len - 1;
1780 			next = 0;
1781 			float endtime = (length - p_keys[idx].time);
1782 			if (endtime < 0) // may be keys past the end
1783 				endtime = 0;
1784 			float delta = endtime + p_keys[next].time;
1785 			float from = endtime + p_time;
1786 
1787 			if (Math::is_zero_approx(delta))
1788 				c = 0;
1789 			else
1790 				c = from / delta;
1791 		}
1792 
1793 	} else { // no loop
1794 
1795 		if (idx >= 0) {
1796 
1797 			if ((idx + 1) < len) {
1798 
1799 				next = idx + 1;
1800 				float delta = p_keys[next].time - p_keys[idx].time;
1801 				float from = p_time - p_keys[idx].time;
1802 
1803 				if (Math::is_zero_approx(delta))
1804 					c = 0;
1805 				else
1806 					c = from / delta;
1807 
1808 			} else {
1809 
1810 				next = idx;
1811 			}
1812 
1813 		} else {
1814 
1815 			// only allow extending first key to anim start if looping
1816 			if (loop)
1817 				idx = next = 0;
1818 			else
1819 				result = false;
1820 		}
1821 	}
1822 
1823 	if (p_ok)
1824 		*p_ok = result;
1825 	if (!result)
1826 		return T();
1827 
1828 	float tr = p_keys[idx].transition;
1829 
1830 	if (tr == 0 || idx == next) {
1831 		// don't interpolate if not needed
1832 		return p_keys[idx].value;
1833 	}
1834 
1835 	if (tr != 1.0) {
1836 
1837 		c = Math::ease(c, tr);
1838 	}
1839 
1840 	switch (p_interp) {
1841 
1842 		case INTERPOLATION_NEAREST: {
1843 
1844 			return p_keys[idx].value;
1845 		} break;
1846 		case INTERPOLATION_LINEAR: {
1847 
1848 			return _interpolate(p_keys[idx].value, p_keys[next].value, c);
1849 		} break;
1850 		case INTERPOLATION_CUBIC: {
1851 			int pre = idx - 1;
1852 			if (pre < 0)
1853 				pre = 0;
1854 			int post = next + 1;
1855 			if (post >= len)
1856 				post = next;
1857 
1858 			return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c);
1859 
1860 		} break;
1861 		default: return p_keys[idx].value;
1862 	}
1863 
1864 	// do a barrel roll
1865 }
1866 
transform_track_interpolate(int p_track,float p_time,Vector3 * r_loc,Quat * r_rot,Vector3 * r_scale) const1867 Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
1868 
1869 	ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1870 	Track *t = tracks[p_track];
1871 	ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
1872 
1873 	TransformTrack *tt = static_cast<TransformTrack *>(t);
1874 
1875 	bool ok = false;
1876 
1877 	TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok);
1878 
1879 	if (!ok)
1880 		return ERR_UNAVAILABLE;
1881 
1882 	if (r_loc)
1883 		*r_loc = tk.loc;
1884 
1885 	if (r_rot)
1886 		*r_rot = tk.rot;
1887 
1888 	if (r_scale)
1889 		*r_scale = tk.scale;
1890 
1891 	return OK;
1892 }
1893 
value_track_interpolate(int p_track,float p_time) const1894 Variant Animation::value_track_interpolate(int p_track, float p_time) const {
1895 
1896 	ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
1897 	Track *t = tracks[p_track];
1898 	ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant());
1899 	ValueTrack *vt = static_cast<ValueTrack *>(t);
1900 
1901 	bool ok = false;
1902 
1903 	Variant res = _interpolate(vt->values, p_time, (vt->update_mode == UPDATE_CONTINUOUS || vt->update_mode == UPDATE_CAPTURE) ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok);
1904 
1905 	if (ok) {
1906 
1907 		return res;
1908 	}
1909 
1910 	return Variant();
1911 }
1912 
_value_track_get_key_indices_in_range(const ValueTrack * vt,float from_time,float to_time,List<int> * p_indices) const1913 void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const {
1914 
1915 	if (from_time != length && to_time == length)
1916 		to_time = length * 1.001; //include a little more if at the end
1917 	int to = _find(vt->values, to_time);
1918 
1919 	if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) {
1920 		//find exact (0 delta), return if found
1921 		p_indices->push_back(to);
1922 		return;
1923 	}
1924 	// can't really send the events == time, will be sent in the next frame.
1925 	// if event>=len then it will probably never be requested by the anim player.
1926 
1927 	if (to >= 0 && vt->values[to].time >= to_time)
1928 		to--;
1929 
1930 	if (to < 0)
1931 		return; // not bother
1932 
1933 	int from = _find(vt->values, from_time);
1934 
1935 	// position in the right first event.+
1936 	if (from < 0 || vt->values[from].time < from_time)
1937 		from++;
1938 
1939 	int max = vt->values.size();
1940 
1941 	for (int i = from; i <= to; i++) {
1942 
1943 		ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
1944 		p_indices->push_back(i);
1945 	}
1946 }
1947 
value_track_get_key_indices(int p_track,float p_time,float p_delta,List<int> * p_indices) const1948 void Animation::value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
1949 
1950 	ERR_FAIL_INDEX(p_track, tracks.size());
1951 	Track *t = tracks[p_track];
1952 	ERR_FAIL_COND(t->type != TYPE_VALUE);
1953 
1954 	ValueTrack *vt = static_cast<ValueTrack *>(t);
1955 
1956 	float from_time = p_time - p_delta;
1957 	float to_time = p_time;
1958 
1959 	if (from_time > to_time)
1960 		SWAP(from_time, to_time);
1961 
1962 	if (loop) {
1963 
1964 		from_time = Math::fposmod(from_time, length);
1965 		to_time = Math::fposmod(to_time, length);
1966 
1967 		if (from_time > to_time) {
1968 			// handle loop by splitting
1969 			_value_track_get_key_indices_in_range(vt, from_time, length, p_indices);
1970 			_value_track_get_key_indices_in_range(vt, 0, to_time, p_indices);
1971 			return;
1972 		}
1973 	} else {
1974 
1975 		if (from_time < 0)
1976 			from_time = 0;
1977 		if (from_time > length)
1978 			from_time = length;
1979 
1980 		if (to_time < 0)
1981 			to_time = 0;
1982 		if (to_time > length)
1983 			to_time = length;
1984 	}
1985 
1986 	_value_track_get_key_indices_in_range(vt, from_time, to_time, p_indices);
1987 }
1988 
value_track_set_update_mode(int p_track,UpdateMode p_mode)1989 void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
1990 
1991 	ERR_FAIL_INDEX(p_track, tracks.size());
1992 	Track *t = tracks[p_track];
1993 	ERR_FAIL_COND(t->type != TYPE_VALUE);
1994 	ERR_FAIL_INDEX((int)p_mode, 4);
1995 
1996 	ValueTrack *vt = static_cast<ValueTrack *>(t);
1997 	vt->update_mode = p_mode;
1998 }
1999 
value_track_get_update_mode(int p_track) const2000 Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
2001 
2002 	ERR_FAIL_INDEX_V(p_track, tracks.size(), UPDATE_CONTINUOUS);
2003 	Track *t = tracks[p_track];
2004 	ERR_FAIL_COND_V(t->type != TYPE_VALUE, UPDATE_CONTINUOUS);
2005 
2006 	ValueTrack *vt = static_cast<ValueTrack *>(t);
2007 	return vt->update_mode;
2008 }
2009 
2010 template <class T>
_track_get_key_indices_in_range(const Vector<T> & p_array,float from_time,float to_time,List<int> * p_indices) const2011 void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const {
2012 
2013 	if (from_time != length && to_time == length)
2014 		to_time = length * 1.01; //include a little more if at the end
2015 
2016 	int to = _find(p_array, to_time);
2017 
2018 	// can't really send the events == time, will be sent in the next frame.
2019 	// if event>=len then it will probably never be requested by the anim player.
2020 
2021 	if (to >= 0 && p_array[to].time >= to_time)
2022 		to--;
2023 
2024 	if (to < 0)
2025 		return; // not bother
2026 
2027 	int from = _find(p_array, from_time);
2028 
2029 	// position in the right first event.+
2030 	if (from < 0 || p_array[from].time < from_time)
2031 		from++;
2032 
2033 	int max = p_array.size();
2034 
2035 	for (int i = from; i <= to; i++) {
2036 
2037 		ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
2038 		p_indices->push_back(i);
2039 	}
2040 }
2041 
track_get_key_indices_in_range(int p_track,float p_time,float p_delta,List<int> * p_indices) const2042 void Animation::track_get_key_indices_in_range(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
2043 
2044 	ERR_FAIL_INDEX(p_track, tracks.size());
2045 	const Track *t = tracks[p_track];
2046 
2047 	float from_time = p_time - p_delta;
2048 	float to_time = p_time;
2049 
2050 	if (from_time > to_time)
2051 		SWAP(from_time, to_time);
2052 
2053 	if (loop) {
2054 
2055 		if (from_time > length || from_time < 0)
2056 			from_time = Math::fposmod(from_time, length);
2057 
2058 		if (to_time > length || to_time < 0)
2059 			to_time = Math::fposmod(to_time, length);
2060 
2061 		if (from_time > to_time) {
2062 			// handle loop by splitting
2063 
2064 			switch (t->type) {
2065 
2066 				case TYPE_TRANSFORM: {
2067 
2068 					const TransformTrack *tt = static_cast<const TransformTrack *>(t);
2069 					_track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices);
2070 					_track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices);
2071 
2072 				} break;
2073 				case TYPE_VALUE: {
2074 
2075 					const ValueTrack *vt = static_cast<const ValueTrack *>(t);
2076 					_track_get_key_indices_in_range(vt->values, from_time, length, p_indices);
2077 					_track_get_key_indices_in_range(vt->values, 0, to_time, p_indices);
2078 
2079 				} break;
2080 				case TYPE_METHOD: {
2081 
2082 					const MethodTrack *mt = static_cast<const MethodTrack *>(t);
2083 					_track_get_key_indices_in_range(mt->methods, from_time, length, p_indices);
2084 					_track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices);
2085 
2086 				} break;
2087 				case TYPE_BEZIER: {
2088 
2089 					const BezierTrack *bz = static_cast<const BezierTrack *>(t);
2090 					_track_get_key_indices_in_range(bz->values, from_time, length, p_indices);
2091 					_track_get_key_indices_in_range(bz->values, 0, to_time, p_indices);
2092 
2093 				} break;
2094 				case TYPE_AUDIO: {
2095 
2096 					const AudioTrack *ad = static_cast<const AudioTrack *>(t);
2097 					_track_get_key_indices_in_range(ad->values, from_time, length, p_indices);
2098 					_track_get_key_indices_in_range(ad->values, 0, to_time, p_indices);
2099 
2100 				} break;
2101 				case TYPE_ANIMATION: {
2102 
2103 					const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
2104 					_track_get_key_indices_in_range(an->values, from_time, length, p_indices);
2105 					_track_get_key_indices_in_range(an->values, 0, to_time, p_indices);
2106 
2107 				} break;
2108 			}
2109 			return;
2110 		}
2111 	} else {
2112 
2113 		if (from_time < 0)
2114 			from_time = 0;
2115 		if (from_time > length)
2116 			from_time = length;
2117 
2118 		if (to_time < 0)
2119 			to_time = 0;
2120 		if (to_time > length)
2121 			to_time = length;
2122 	}
2123 
2124 	switch (t->type) {
2125 
2126 		case TYPE_TRANSFORM: {
2127 
2128 			const TransformTrack *tt = static_cast<const TransformTrack *>(t);
2129 			_track_get_key_indices_in_range(tt->transforms, from_time, to_time, p_indices);
2130 
2131 		} break;
2132 		case TYPE_VALUE: {
2133 
2134 			const ValueTrack *vt = static_cast<const ValueTrack *>(t);
2135 			_track_get_key_indices_in_range(vt->values, from_time, to_time, p_indices);
2136 
2137 		} break;
2138 		case TYPE_METHOD: {
2139 
2140 			const MethodTrack *mt = static_cast<const MethodTrack *>(t);
2141 			_track_get_key_indices_in_range(mt->methods, from_time, to_time, p_indices);
2142 
2143 		} break;
2144 		case TYPE_BEZIER: {
2145 
2146 			const BezierTrack *bz = static_cast<const BezierTrack *>(t);
2147 			_track_get_key_indices_in_range(bz->values, from_time, to_time, p_indices);
2148 
2149 		} break;
2150 		case TYPE_AUDIO: {
2151 
2152 			const AudioTrack *ad = static_cast<const AudioTrack *>(t);
2153 			_track_get_key_indices_in_range(ad->values, from_time, to_time, p_indices);
2154 
2155 		} break;
2156 		case TYPE_ANIMATION: {
2157 
2158 			const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
2159 			_track_get_key_indices_in_range(an->values, from_time, to_time, p_indices);
2160 
2161 		} break;
2162 	}
2163 }
2164 
_method_track_get_key_indices_in_range(const MethodTrack * mt,float from_time,float to_time,List<int> * p_indices) const2165 void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const {
2166 
2167 	if (from_time != length && to_time == length)
2168 		to_time = length * 1.01; //include a little more if at the end
2169 
2170 	int to = _find(mt->methods, to_time);
2171 
2172 	// can't really send the events == time, will be sent in the next frame.
2173 	// if event>=len then it will probably never be requested by the anim player.
2174 
2175 	if (to >= 0 && mt->methods[to].time >= to_time)
2176 		to--;
2177 
2178 	if (to < 0)
2179 		return; // not bother
2180 
2181 	int from = _find(mt->methods, from_time);
2182 
2183 	// position in the right first event.+
2184 	if (from < 0 || mt->methods[from].time < from_time)
2185 		from++;
2186 
2187 	int max = mt->methods.size();
2188 
2189 	for (int i = from; i <= to; i++) {
2190 
2191 		ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
2192 		p_indices->push_back(i);
2193 	}
2194 }
2195 
method_track_get_key_indices(int p_track,float p_time,float p_delta,List<int> * p_indices) const2196 void Animation::method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
2197 
2198 	ERR_FAIL_INDEX(p_track, tracks.size());
2199 	Track *t = tracks[p_track];
2200 	ERR_FAIL_COND(t->type != TYPE_METHOD);
2201 
2202 	MethodTrack *mt = static_cast<MethodTrack *>(t);
2203 
2204 	float from_time = p_time - p_delta;
2205 	float to_time = p_time;
2206 
2207 	if (from_time > to_time)
2208 		SWAP(from_time, to_time);
2209 
2210 	if (loop) {
2211 
2212 		if (from_time > length || from_time < 0)
2213 			from_time = Math::fposmod(from_time, length);
2214 
2215 		if (to_time > length || to_time < 0)
2216 			to_time = Math::fposmod(to_time, length);
2217 
2218 		if (from_time > to_time) {
2219 			// handle loop by splitting
2220 			_method_track_get_key_indices_in_range(mt, from_time, length, p_indices);
2221 			_method_track_get_key_indices_in_range(mt, 0, to_time, p_indices);
2222 			return;
2223 		}
2224 	} else {
2225 
2226 		if (from_time < 0)
2227 			from_time = 0;
2228 		if (from_time > length)
2229 			from_time = length;
2230 
2231 		if (to_time < 0)
2232 			to_time = 0;
2233 		if (to_time > length)
2234 			to_time = length;
2235 	}
2236 
2237 	_method_track_get_key_indices_in_range(mt, from_time, to_time, p_indices);
2238 }
method_track_get_params(int p_track,int p_key_idx) const2239 Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
2240 
2241 	ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
2242 	Track *t = tracks[p_track];
2243 	ERR_FAIL_COND_V(t->type != TYPE_METHOD, Vector<Variant>());
2244 
2245 	MethodTrack *pm = static_cast<MethodTrack *>(t);
2246 
2247 	ERR_FAIL_INDEX_V(p_key_idx, pm->methods.size(), Vector<Variant>());
2248 
2249 	const MethodKey &mk = pm->methods[p_key_idx];
2250 
2251 	return mk.params;
2252 }
method_track_get_name(int p_track,int p_key_idx) const2253 StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
2254 
2255 	ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
2256 	Track *t = tracks[p_track];
2257 	ERR_FAIL_COND_V(t->type != TYPE_METHOD, StringName());
2258 
2259 	MethodTrack *pm = static_cast<MethodTrack *>(t);
2260 
2261 	ERR_FAIL_INDEX_V(p_key_idx, pm->methods.size(), StringName());
2262 
2263 	return pm->methods[p_key_idx].method;
2264 }
2265 
bezier_track_insert_key(int p_track,float p_time,float p_value,const Vector2 & p_in_handle,const Vector2 & p_out_handle)2266 int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) {
2267 
2268 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
2269 	Track *t = tracks[p_track];
2270 	ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
2271 
2272 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2273 
2274 	TKey<BezierKey> k;
2275 	k.time = p_time;
2276 	k.value.value = p_value;
2277 	k.value.in_handle = p_in_handle;
2278 	if (k.value.in_handle.x > 0) {
2279 		k.value.in_handle.x = 0;
2280 	}
2281 	k.value.out_handle = p_out_handle;
2282 	if (k.value.out_handle.x < 0) {
2283 		k.value.out_handle.x = 0;
2284 	}
2285 
2286 	int key = _insert(p_time, bt->values, k);
2287 
2288 	emit_changed();
2289 
2290 	return key;
2291 }
2292 
bezier_track_set_key_value(int p_track,int p_index,float p_value)2293 void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_value) {
2294 
2295 	ERR_FAIL_INDEX(p_track, tracks.size());
2296 	Track *t = tracks[p_track];
2297 	ERR_FAIL_COND(t->type != TYPE_BEZIER);
2298 
2299 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2300 
2301 	ERR_FAIL_INDEX(p_index, bt->values.size());
2302 
2303 	bt->values.write[p_index].value.value = p_value;
2304 	emit_changed();
2305 }
2306 
bezier_track_set_key_in_handle(int p_track,int p_index,const Vector2 & p_handle)2307 void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle) {
2308 
2309 	ERR_FAIL_INDEX(p_track, tracks.size());
2310 	Track *t = tracks[p_track];
2311 	ERR_FAIL_COND(t->type != TYPE_BEZIER);
2312 
2313 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2314 
2315 	ERR_FAIL_INDEX(p_index, bt->values.size());
2316 
2317 	bt->values.write[p_index].value.in_handle = p_handle;
2318 	if (bt->values[p_index].value.in_handle.x > 0) {
2319 		bt->values.write[p_index].value.in_handle.x = 0;
2320 	}
2321 	emit_changed();
2322 }
bezier_track_set_key_out_handle(int p_track,int p_index,const Vector2 & p_handle)2323 void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
2324 
2325 	ERR_FAIL_INDEX(p_track, tracks.size());
2326 	Track *t = tracks[p_track];
2327 	ERR_FAIL_COND(t->type != TYPE_BEZIER);
2328 
2329 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2330 
2331 	ERR_FAIL_INDEX(p_index, bt->values.size());
2332 
2333 	bt->values.write[p_index].value.out_handle = p_handle;
2334 	if (bt->values[p_index].value.out_handle.x < 0) {
2335 		bt->values.write[p_index].value.out_handle.x = 0;
2336 	}
2337 	emit_changed();
2338 }
bezier_track_get_key_value(int p_track,int p_index) const2339 float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
2340 
2341 	ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
2342 	Track *t = tracks[p_track];
2343 	ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0);
2344 
2345 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2346 
2347 	ERR_FAIL_INDEX_V(p_index, bt->values.size(), 0);
2348 
2349 	return bt->values[p_index].value.value;
2350 }
bezier_track_get_key_in_handle(int p_track,int p_index) const2351 Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
2352 
2353 	ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
2354 	Track *t = tracks[p_track];
2355 	ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
2356 
2357 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2358 
2359 	ERR_FAIL_INDEX_V(p_index, bt->values.size(), Vector2());
2360 
2361 	return bt->values[p_index].value.in_handle;
2362 }
bezier_track_get_key_out_handle(int p_track,int p_index) const2363 Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
2364 
2365 	ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
2366 	Track *t = tracks[p_track];
2367 	ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
2368 
2369 	BezierTrack *bt = static_cast<BezierTrack *>(t);
2370 
2371 	ERR_FAIL_INDEX_V(p_index, bt->values.size(), Vector2());
2372 
2373 	return bt->values[p_index].value.out_handle;
2374 }
2375 
_bezier_interp(real_t t,const Vector2 & start,const Vector2 & control_1,const Vector2 & control_2,const Vector2 & end)2376 static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, const Vector2 &start, const Vector2 &control_1, const Vector2 &control_2, const Vector2 &end) {
2377 	/* Formula from Wikipedia article on Bezier curves. */
2378 	real_t omt = (1.0 - t);
2379 	real_t omt2 = omt * omt;
2380 	real_t omt3 = omt2 * omt;
2381 	real_t t2 = t * t;
2382 	real_t t3 = t2 * t;
2383 
2384 	return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
2385 }
2386 
bezier_track_interpolate(int p_track,float p_time) const2387 float Animation::bezier_track_interpolate(int p_track, float p_time) const {
2388 	//this uses a different interpolation scheme
2389 	ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
2390 	Track *track = tracks[p_track];
2391 	ERR_FAIL_COND_V(track->type != TYPE_BEZIER, 0);
2392 
2393 	BezierTrack *bt = static_cast<BezierTrack *>(track);
2394 
2395 	int len = _find(bt->values, length) + 1; // try to find last key (there may be more past the end)
2396 
2397 	if (len <= 0) {
2398 		// (-1 or -2 returned originally) (plus one above)
2399 		return 0;
2400 	} else if (len == 1) { // one key found (0+1), return it
2401 		return bt->values[0].value.value;
2402 	}
2403 
2404 	int idx = _find(bt->values, p_time);
2405 
2406 	ERR_FAIL_COND_V(idx == -2, 0);
2407 
2408 	//there really is no looping interpolation on bezier
2409 
2410 	if (idx < 0) {
2411 		return bt->values[0].value.value;
2412 	}
2413 
2414 	if (idx >= bt->values.size() - 1) {
2415 		return bt->values[bt->values.size() - 1].value.value;
2416 	}
2417 
2418 	float t = p_time - bt->values[idx].time;
2419 
2420 	int iterations = 10;
2421 
2422 	float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes
2423 	float low = 0; // 0% of the current animation segment
2424 	float high = 1; // 100% of the current animation segment
2425 	float middle;
2426 
2427 	Vector2 start(0, bt->values[idx].value.value);
2428 	Vector2 start_out = start + bt->values[idx].value.out_handle;
2429 	Vector2 end(duration, bt->values[idx + 1].value.value);
2430 	Vector2 end_in = end + bt->values[idx + 1].value.in_handle;
2431 
2432 	//narrow high and low as much as possible
2433 	for (int i = 0; i < iterations; i++) {
2434 
2435 		middle = (low + high) / 2;
2436 
2437 		Vector2 interp = _bezier_interp(middle, start, start_out, end_in, end);
2438 
2439 		if (interp.x < t) {
2440 			low = middle;
2441 		} else {
2442 			high = middle;
2443 		}
2444 	}
2445 
2446 	//interpolate the result:
2447 	Vector2 low_pos = _bezier_interp(low, start, start_out, end_in, end);
2448 	Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end);
2449 	float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
2450 
2451 	return low_pos.linear_interpolate(high_pos, c).y;
2452 }
2453 
audio_track_insert_key(int p_track,float p_time,const RES & p_stream,float p_start_offset,float p_end_offset)2454 int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset, float p_end_offset) {
2455 
2456 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
2457 	Track *t = tracks[p_track];
2458 	ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1);
2459 
2460 	AudioTrack *at = static_cast<AudioTrack *>(t);
2461 
2462 	TKey<AudioKey> k;
2463 	k.time = p_time;
2464 	k.value.stream = p_stream;
2465 	k.value.start_offset = p_start_offset;
2466 	if (k.value.start_offset < 0)
2467 		k.value.start_offset = 0;
2468 	k.value.end_offset = p_end_offset;
2469 	if (k.value.end_offset < 0)
2470 		k.value.end_offset = 0;
2471 
2472 	int key = _insert(p_time, at->values, k);
2473 
2474 	emit_changed();
2475 
2476 	return key;
2477 }
2478 
audio_track_set_key_stream(int p_track,int p_key,const RES & p_stream)2479 void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream) {
2480 
2481 	ERR_FAIL_INDEX(p_track, tracks.size());
2482 	Track *t = tracks[p_track];
2483 	ERR_FAIL_COND(t->type != TYPE_AUDIO);
2484 
2485 	AudioTrack *at = static_cast<AudioTrack *>(t);
2486 
2487 	ERR_FAIL_INDEX(p_key, at->values.size());
2488 
2489 	at->values.write[p_key].value.stream = p_stream;
2490 
2491 	emit_changed();
2492 }
2493 
audio_track_set_key_start_offset(int p_track,int p_key,float p_offset)2494 void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p_offset) {
2495 
2496 	ERR_FAIL_INDEX(p_track, tracks.size());
2497 	Track *t = tracks[p_track];
2498 	ERR_FAIL_COND(t->type != TYPE_AUDIO);
2499 
2500 	AudioTrack *at = static_cast<AudioTrack *>(t);
2501 
2502 	ERR_FAIL_INDEX(p_key, at->values.size());
2503 
2504 	if (p_offset < 0)
2505 		p_offset = 0;
2506 
2507 	at->values.write[p_key].value.start_offset = p_offset;
2508 
2509 	emit_changed();
2510 }
2511 
audio_track_set_key_end_offset(int p_track,int p_key,float p_offset)2512 void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_offset) {
2513 
2514 	ERR_FAIL_INDEX(p_track, tracks.size());
2515 	Track *t = tracks[p_track];
2516 	ERR_FAIL_COND(t->type != TYPE_AUDIO);
2517 
2518 	AudioTrack *at = static_cast<AudioTrack *>(t);
2519 
2520 	ERR_FAIL_INDEX(p_key, at->values.size());
2521 
2522 	if (p_offset < 0)
2523 		p_offset = 0;
2524 
2525 	at->values.write[p_key].value.end_offset = p_offset;
2526 
2527 	emit_changed();
2528 }
2529 
audio_track_get_key_stream(int p_track,int p_key) const2530 RES Animation::audio_track_get_key_stream(int p_track, int p_key) const {
2531 
2532 	ERR_FAIL_INDEX_V(p_track, tracks.size(), RES());
2533 	const Track *t = tracks[p_track];
2534 	ERR_FAIL_COND_V(t->type != TYPE_AUDIO, RES());
2535 
2536 	const AudioTrack *at = static_cast<const AudioTrack *>(t);
2537 
2538 	ERR_FAIL_INDEX_V(p_key, at->values.size(), RES());
2539 
2540 	return at->values[p_key].value.stream;
2541 }
audio_track_get_key_start_offset(int p_track,int p_key) const2542 float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
2543 
2544 	ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
2545 	const Track *t = tracks[p_track];
2546 	ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
2547 
2548 	const AudioTrack *at = static_cast<const AudioTrack *>(t);
2549 
2550 	ERR_FAIL_INDEX_V(p_key, at->values.size(), 0);
2551 
2552 	return at->values[p_key].value.start_offset;
2553 }
audio_track_get_key_end_offset(int p_track,int p_key) const2554 float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
2555 
2556 	ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
2557 	const Track *t = tracks[p_track];
2558 	ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
2559 
2560 	const AudioTrack *at = static_cast<const AudioTrack *>(t);
2561 
2562 	ERR_FAIL_INDEX_V(p_key, at->values.size(), 0);
2563 
2564 	return at->values[p_key].value.end_offset;
2565 }
2566 
2567 //
2568 
animation_track_insert_key(int p_track,float p_time,const StringName & p_animation)2569 int Animation::animation_track_insert_key(int p_track, float p_time, const StringName &p_animation) {
2570 
2571 	ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
2572 	Track *t = tracks[p_track];
2573 	ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, -1);
2574 
2575 	AnimationTrack *at = static_cast<AnimationTrack *>(t);
2576 
2577 	TKey<StringName> k;
2578 	k.time = p_time;
2579 	k.value = p_animation;
2580 
2581 	int key = _insert(p_time, at->values, k);
2582 
2583 	emit_changed();
2584 
2585 	return key;
2586 }
2587 
animation_track_set_key_animation(int p_track,int p_key,const StringName & p_animation)2588 void Animation::animation_track_set_key_animation(int p_track, int p_key, const StringName &p_animation) {
2589 
2590 	ERR_FAIL_INDEX(p_track, tracks.size());
2591 	Track *t = tracks[p_track];
2592 	ERR_FAIL_COND(t->type != TYPE_ANIMATION);
2593 
2594 	AnimationTrack *at = static_cast<AnimationTrack *>(t);
2595 
2596 	ERR_FAIL_INDEX(p_key, at->values.size());
2597 
2598 	at->values.write[p_key].value = p_animation;
2599 
2600 	emit_changed();
2601 }
2602 
animation_track_get_key_animation(int p_track,int p_key) const2603 StringName Animation::animation_track_get_key_animation(int p_track, int p_key) const {
2604 
2605 	ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
2606 	const Track *t = tracks[p_track];
2607 	ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, StringName());
2608 
2609 	const AnimationTrack *at = static_cast<const AnimationTrack *>(t);
2610 
2611 	ERR_FAIL_INDEX_V(p_key, at->values.size(), StringName());
2612 
2613 	return at->values[p_key].value;
2614 }
2615 
set_length(float p_length)2616 void Animation::set_length(float p_length) {
2617 
2618 	if (p_length < ANIM_MIN_LENGTH) {
2619 		p_length = ANIM_MIN_LENGTH;
2620 	}
2621 	length = p_length;
2622 	emit_changed();
2623 }
get_length() const2624 float Animation::get_length() const {
2625 
2626 	return length;
2627 }
2628 
set_loop(bool p_enabled)2629 void Animation::set_loop(bool p_enabled) {
2630 
2631 	loop = p_enabled;
2632 	emit_changed();
2633 }
has_loop() const2634 bool Animation::has_loop() const {
2635 
2636 	return loop;
2637 }
2638 
track_set_imported(int p_track,bool p_imported)2639 void Animation::track_set_imported(int p_track, bool p_imported) {
2640 
2641 	ERR_FAIL_INDEX(p_track, tracks.size());
2642 	tracks[p_track]->imported = p_imported;
2643 }
2644 
track_is_imported(int p_track) const2645 bool Animation::track_is_imported(int p_track) const {
2646 
2647 	ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
2648 	return tracks[p_track]->imported;
2649 }
2650 
track_set_enabled(int p_track,bool p_enabled)2651 void Animation::track_set_enabled(int p_track, bool p_enabled) {
2652 
2653 	ERR_FAIL_INDEX(p_track, tracks.size());
2654 	tracks[p_track]->enabled = p_enabled;
2655 	emit_changed();
2656 }
2657 
track_is_enabled(int p_track) const2658 bool Animation::track_is_enabled(int p_track) const {
2659 
2660 	ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
2661 	return tracks[p_track]->enabled;
2662 }
2663 
track_move_up(int p_track)2664 void Animation::track_move_up(int p_track) {
2665 
2666 	if (p_track >= 0 && p_track < (tracks.size() - 1)) {
2667 
2668 		SWAP(tracks.write[p_track], tracks.write[p_track + 1]);
2669 	}
2670 
2671 	emit_changed();
2672 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
2673 }
2674 
track_move_down(int p_track)2675 void Animation::track_move_down(int p_track) {
2676 
2677 	if (p_track > 0 && p_track < tracks.size()) {
2678 
2679 		SWAP(tracks.write[p_track], tracks.write[p_track - 1]);
2680 	}
2681 
2682 	emit_changed();
2683 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
2684 }
2685 
track_move_to(int p_track,int p_to_index)2686 void Animation::track_move_to(int p_track, int p_to_index) {
2687 
2688 	ERR_FAIL_INDEX(p_track, tracks.size());
2689 	ERR_FAIL_INDEX(p_to_index, tracks.size() + 1);
2690 	if (p_track == p_to_index || p_track == p_to_index - 1)
2691 		return;
2692 
2693 	Track *track = tracks.get(p_track);
2694 	tracks.remove(p_track);
2695 	// Take into account that the position of the tracks that come after the one removed will change.
2696 	tracks.insert(p_to_index > p_track ? p_to_index - 1 : p_to_index, track);
2697 
2698 	emit_changed();
2699 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
2700 }
2701 
track_swap(int p_track,int p_with_track)2702 void Animation::track_swap(int p_track, int p_with_track) {
2703 
2704 	ERR_FAIL_INDEX(p_track, tracks.size());
2705 	ERR_FAIL_INDEX(p_with_track, tracks.size());
2706 	if (p_track == p_with_track)
2707 		return;
2708 	SWAP(tracks.write[p_track], tracks.write[p_with_track]);
2709 
2710 	emit_changed();
2711 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
2712 }
2713 
set_step(float p_step)2714 void Animation::set_step(float p_step) {
2715 
2716 	step = p_step;
2717 	emit_changed();
2718 }
2719 
get_step() const2720 float Animation::get_step() const {
2721 
2722 	return step;
2723 }
2724 
copy_track(int p_track,Ref<Animation> p_to_animation)2725 void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
2726 	ERR_FAIL_COND(p_to_animation.is_null());
2727 	ERR_FAIL_INDEX(p_track, get_track_count());
2728 	int dst_track = p_to_animation->get_track_count();
2729 	p_to_animation->add_track(track_get_type(p_track));
2730 
2731 	p_to_animation->track_set_path(dst_track, track_get_path(p_track));
2732 	p_to_animation->track_set_imported(dst_track, track_is_imported(p_track));
2733 	p_to_animation->track_set_enabled(dst_track, track_is_enabled(p_track));
2734 	p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_track));
2735 	p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_track));
2736 	if (track_get_type(p_track) == TYPE_VALUE) {
2737 		p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
2738 	}
2739 
2740 	for (int i = 0; i < track_get_key_count(p_track); i++) {
2741 		p_to_animation->track_insert_key(dst_track, track_get_key_time(p_track, i), track_get_key_value(p_track, i), track_get_key_transition(p_track, i));
2742 	}
2743 }
2744 
_bind_methods()2745 void Animation::_bind_methods() {
2746 
2747 	ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
2748 	ClassDB::bind_method(D_METHOD("remove_track", "track_idx"), &Animation::remove_track);
2749 	ClassDB::bind_method(D_METHOD("get_track_count"), &Animation::get_track_count);
2750 	ClassDB::bind_method(D_METHOD("track_get_type", "track_idx"), &Animation::track_get_type);
2751 	ClassDB::bind_method(D_METHOD("track_get_path", "track_idx"), &Animation::track_get_path);
2752 	ClassDB::bind_method(D_METHOD("track_set_path", "track_idx", "path"), &Animation::track_set_path);
2753 	ClassDB::bind_method(D_METHOD("find_track", "path"), &Animation::find_track);
2754 
2755 	ClassDB::bind_method(D_METHOD("track_move_up", "track_idx"), &Animation::track_move_up);
2756 	ClassDB::bind_method(D_METHOD("track_move_down", "track_idx"), &Animation::track_move_down);
2757 	ClassDB::bind_method(D_METHOD("track_move_to", "track_idx", "to_idx"), &Animation::track_move_to);
2758 	ClassDB::bind_method(D_METHOD("track_swap", "track_idx", "with_idx"), &Animation::track_swap);
2759 
2760 	ClassDB::bind_method(D_METHOD("track_set_imported", "track_idx", "imported"), &Animation::track_set_imported);
2761 	ClassDB::bind_method(D_METHOD("track_is_imported", "track_idx"), &Animation::track_is_imported);
2762 
2763 	ClassDB::bind_method(D_METHOD("track_set_enabled", "track_idx", "enabled"), &Animation::track_set_enabled);
2764 	ClassDB::bind_method(D_METHOD("track_is_enabled", "track_idx"), &Animation::track_is_enabled);
2765 
2766 	ClassDB::bind_method(D_METHOD("transform_track_insert_key", "track_idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key);
2767 	ClassDB::bind_method(D_METHOD("track_insert_key", "track_idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
2768 	ClassDB::bind_method(D_METHOD("track_remove_key", "track_idx", "key_idx"), &Animation::track_remove_key);
2769 	ClassDB::bind_method(D_METHOD("track_remove_key_at_position", "track_idx", "position"), &Animation::track_remove_key_at_position);
2770 	ClassDB::bind_method(D_METHOD("track_set_key_value", "track_idx", "key", "value"), &Animation::track_set_key_value);
2771 	ClassDB::bind_method(D_METHOD("track_set_key_transition", "track_idx", "key_idx", "transition"), &Animation::track_set_key_transition);
2772 	ClassDB::bind_method(D_METHOD("track_set_key_time", "track_idx", "key_idx", "time"), &Animation::track_set_key_time);
2773 	ClassDB::bind_method(D_METHOD("track_get_key_transition", "track_idx", "key_idx"), &Animation::track_get_key_transition);
2774 
2775 	ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
2776 	ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
2777 	ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
2778 	ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "exact"), &Animation::track_find_key, DEFVAL(false));
2779 
2780 	ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
2781 	ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
2782 
2783 	ClassDB::bind_method(D_METHOD("track_set_interpolation_loop_wrap", "track_idx", "interpolation"), &Animation::track_set_interpolation_loop_wrap);
2784 	ClassDB::bind_method(D_METHOD("track_get_interpolation_loop_wrap", "track_idx"), &Animation::track_get_interpolation_loop_wrap);
2785 
2786 	ClassDB::bind_method(D_METHOD("transform_track_interpolate", "track_idx", "time_sec"), &Animation::_transform_track_interpolate);
2787 	ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode);
2788 	ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode);
2789 
2790 	ClassDB::bind_method(D_METHOD("value_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_value_track_get_key_indices);
2791 
2792 	ClassDB::bind_method(D_METHOD("method_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_method_track_get_key_indices);
2793 	ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
2794 	ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
2795 
2796 	ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track_idx", "time", "value", "in_handle", "out_handle"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()));
2797 
2798 	ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "track_idx", "key_idx", "value"), &Animation::bezier_track_set_key_value);
2799 	ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle"), &Animation::bezier_track_set_key_in_handle);
2800 	ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle"), &Animation::bezier_track_set_key_out_handle);
2801 
2802 	ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "track_idx", "key_idx"), &Animation::bezier_track_get_key_value);
2803 	ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_in_handle);
2804 	ClassDB::bind_method(D_METHOD("bezier_track_get_key_out_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_out_handle);
2805 
2806 	ClassDB::bind_method(D_METHOD("bezier_track_interpolate", "track_idx", "time"), &Animation::bezier_track_interpolate);
2807 
2808 	ClassDB::bind_method(D_METHOD("audio_track_insert_key", "track_idx", "time", "stream", "start_offset", "end_offset"), &Animation::audio_track_insert_key, DEFVAL(0), DEFVAL(0));
2809 	ClassDB::bind_method(D_METHOD("audio_track_set_key_stream", "track_idx", "key_idx", "stream"), &Animation::audio_track_set_key_stream);
2810 	ClassDB::bind_method(D_METHOD("audio_track_set_key_start_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_start_offset);
2811 	ClassDB::bind_method(D_METHOD("audio_track_set_key_end_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_end_offset);
2812 	ClassDB::bind_method(D_METHOD("audio_track_get_key_stream", "track_idx", "key_idx"), &Animation::audio_track_get_key_stream);
2813 	ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
2814 	ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
2815 
2816 	ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key);
2817 	ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
2818 	ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "track_idx", "key_idx"), &Animation::animation_track_get_key_animation);
2819 
2820 	ClassDB::bind_method(D_METHOD("set_length", "time_sec"), &Animation::set_length);
2821 	ClassDB::bind_method(D_METHOD("get_length"), &Animation::get_length);
2822 
2823 	ClassDB::bind_method(D_METHOD("set_loop", "enabled"), &Animation::set_loop);
2824 	ClassDB::bind_method(D_METHOD("has_loop"), &Animation::has_loop);
2825 
2826 	ClassDB::bind_method(D_METHOD("set_step", "size_sec"), &Animation::set_step);
2827 	ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
2828 
2829 	ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
2830 	ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track);
2831 
2832 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001"), "set_length", "get_length");
2833 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop");
2834 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "step", PROPERTY_HINT_RANGE, "0,4096,0.001"), "set_step", "get_step");
2835 
2836 	ADD_SIGNAL(MethodInfo("tracks_changed"));
2837 
2838 	BIND_ENUM_CONSTANT(TYPE_VALUE);
2839 	BIND_ENUM_CONSTANT(TYPE_TRANSFORM);
2840 	BIND_ENUM_CONSTANT(TYPE_METHOD);
2841 	BIND_ENUM_CONSTANT(TYPE_BEZIER);
2842 	BIND_ENUM_CONSTANT(TYPE_AUDIO);
2843 	BIND_ENUM_CONSTANT(TYPE_ANIMATION);
2844 
2845 	BIND_ENUM_CONSTANT(INTERPOLATION_NEAREST);
2846 	BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR);
2847 	BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC);
2848 
2849 	BIND_ENUM_CONSTANT(UPDATE_CONTINUOUS);
2850 	BIND_ENUM_CONSTANT(UPDATE_DISCRETE);
2851 	BIND_ENUM_CONSTANT(UPDATE_TRIGGER);
2852 	BIND_ENUM_CONSTANT(UPDATE_CAPTURE);
2853 }
2854 
clear()2855 void Animation::clear() {
2856 
2857 	for (int i = 0; i < tracks.size(); i++)
2858 		memdelete(tracks[i]);
2859 	tracks.clear();
2860 	loop = false;
2861 	length = 1;
2862 	emit_changed();
2863 	emit_signal(SceneStringNames::get_singleton()->tracks_changed);
2864 }
2865 
_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)2866 bool Animation::_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) {
2867 
2868 	real_t c = (t1.time - t0.time) / (t2.time - t0.time);
2869 	real_t t[3] = { -1, -1, -1 };
2870 
2871 	{ //translation
2872 
2873 		const Vector3 &v0 = t0.value.loc;
2874 		const Vector3 &v1 = t1.value.loc;
2875 		const Vector3 &v2 = t2.value.loc;
2876 
2877 		if (v0.is_equal_approx(v2)) {
2878 			//0 and 2 are close, let's see if 1 is close
2879 			if (!v0.is_equal_approx(v1)) {
2880 				//not close, not optimizable
2881 				return false;
2882 			}
2883 
2884 		} else {
2885 
2886 			Vector3 pd = (v2 - v0);
2887 			float d0 = pd.dot(v0);
2888 			float d1 = pd.dot(v1);
2889 			float d2 = pd.dot(v2);
2890 			if (d1 < d0 || d1 > d2) {
2891 				return false;
2892 			}
2893 
2894 			Vector3 s[2] = { v0, v2 };
2895 			real_t d = Geometry::get_closest_point_to_segment(v1, s).distance_to(v1);
2896 
2897 			if (d > pd.length() * p_alowed_linear_err) {
2898 				return false; //beyond allowed error for colinearity
2899 			}
2900 
2901 			if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err)
2902 				return false;
2903 
2904 			t[0] = (d1 - d0) / (d2 - d0);
2905 		}
2906 	}
2907 
2908 	{ //rotation
2909 
2910 		const Quat &q0 = t0.value.rot;
2911 		const Quat &q1 = t1.value.rot;
2912 		const Quat &q2 = t2.value.rot;
2913 
2914 		//localize both to rotation from q0
2915 
2916 		if (q0.is_equal_approx(q2)) {
2917 
2918 			if (!q0.is_equal_approx(q1))
2919 				return false;
2920 
2921 		} else {
2922 
2923 			Quat r02 = (q0.inverse() * q2).normalized();
2924 			Quat r01 = (q0.inverse() * q1).normalized();
2925 
2926 			Vector3 v02, v01;
2927 			real_t a02, a01;
2928 
2929 			r02.get_axis_angle(v02, a02);
2930 			r01.get_axis_angle(v01, a01);
2931 
2932 			if (Math::abs(a02) > p_max_optimizable_angle)
2933 				return false;
2934 
2935 			if (v01.dot(v02) < 0) {
2936 				//make sure both rotations go the same way to compare
2937 				v02 = -v02;
2938 				a02 = -a02;
2939 			}
2940 
2941 			real_t err_01 = Math::acos(v01.normalized().dot(v02.normalized())) / Math_PI;
2942 			if (err_01 > p_alowed_angular_err) {
2943 				//not rotating in the same axis
2944 				return false;
2945 			}
2946 
2947 			if (a01 * a02 < 0) {
2948 				//not rotating in the same direction
2949 				return false;
2950 			}
2951 
2952 			real_t tr = a01 / a02;
2953 			if (tr < 0 || tr > 1)
2954 				return false; //rotating too much or too less
2955 
2956 			t[1] = tr;
2957 		}
2958 	}
2959 
2960 	{ //scale
2961 
2962 		const Vector3 &v0 = t0.value.scale;
2963 		const Vector3 &v1 = t1.value.scale;
2964 		const Vector3 &v2 = t2.value.scale;
2965 
2966 		if (v0.is_equal_approx(v2)) {
2967 			//0 and 2 are close, let's see if 1 is close
2968 			if (!v0.is_equal_approx(v1)) {
2969 				//not close, not optimizable
2970 				return false;
2971 			}
2972 
2973 		} else {
2974 
2975 			Vector3 pd = (v2 - v0);
2976 			float d0 = pd.dot(v0);
2977 			float d1 = pd.dot(v1);
2978 			float d2 = pd.dot(v2);
2979 			if (d1 < d0 || d1 > d2) {
2980 				return false; //beyond segment range
2981 			}
2982 
2983 			Vector3 s[2] = { v0, v2 };
2984 			real_t d = Geometry::get_closest_point_to_segment(v1, s).distance_to(v1);
2985 
2986 			if (d > pd.length() * p_alowed_linear_err) {
2987 				return false; //beyond allowed error for colinearity
2988 			}
2989 
2990 			t[2] = (d1 - d0) / (d2 - d0);
2991 		}
2992 	}
2993 
2994 	bool erase = false;
2995 	if (t[0] == -1 && t[1] == -1 && t[2] == -1) {
2996 
2997 		erase = true;
2998 	} else {
2999 
3000 		erase = true;
3001 		real_t lt = -1;
3002 		for (int j = 0; j < 3; j++) {
3003 			//search for t on first, one must be it
3004 			if (t[j] != -1) {
3005 				lt = t[j]; //official t
3006 				//validate rest
3007 				for (int k = j + 1; k < 3; k++) {
3008 					if (t[k] == -1)
3009 						continue;
3010 
3011 					if (Math::abs(lt - t[k]) > p_alowed_linear_err) {
3012 						erase = false;
3013 						break;
3014 					}
3015 				}
3016 				break;
3017 			}
3018 		}
3019 
3020 		ERR_FAIL_COND_V(lt == -1, false);
3021 
3022 		if (erase) {
3023 
3024 			if (Math::abs(lt - c) > p_alowed_linear_err) {
3025 				//todo, evaluate changing the transition if this fails?
3026 				//this could be done as a second pass and would be
3027 				//able to optimize more
3028 				erase = false;
3029 			}
3030 		}
3031 	}
3032 
3033 	return erase;
3034 }
3035 
_transform_track_optimize(int p_idx,float p_allowed_linear_err,float p_allowed_angular_err,float p_max_optimizable_angle)3036 void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
3037 
3038 	ERR_FAIL_INDEX(p_idx, tracks.size());
3039 	ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM);
3040 	TransformTrack *tt = static_cast<TransformTrack *>(tracks[p_idx]);
3041 	bool prev_erased = false;
3042 	TKey<TransformKey> first_erased;
3043 
3044 	Vector3 norm;
3045 
3046 	for (int i = 1; i < tt->transforms.size() - 1; i++) {
3047 
3048 		TKey<TransformKey> &t0 = tt->transforms.write[i - 1];
3049 		TKey<TransformKey> &t1 = tt->transforms.write[i];
3050 		TKey<TransformKey> &t2 = tt->transforms.write[i + 1];
3051 
3052 		bool erase = _transform_track_optimize_key(t0, t1, t2, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle, norm);
3053 		if (erase && !prev_erased) {
3054 			norm = (t2.value.loc - t1.value.loc).normalized();
3055 		}
3056 
3057 		if (prev_erased && !_transform_track_optimize_key(t0, first_erased, t2, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle, norm)) {
3058 			//avoid error to go beyond first erased key
3059 			erase = false;
3060 		}
3061 
3062 		if (erase) {
3063 
3064 			if (!prev_erased) {
3065 				first_erased = t1;
3066 				prev_erased = true;
3067 			}
3068 
3069 			tt->transforms.remove(i);
3070 			i--;
3071 
3072 		} else {
3073 			prev_erased = false;
3074 			norm = Vector3();
3075 		}
3076 	}
3077 }
3078 
optimize(float p_allowed_linear_err,float p_allowed_angular_err,float p_max_optimizable_angle)3079 void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
3080 
3081 	for (int i = 0; i < tracks.size(); i++) {
3082 
3083 		if (tracks[i]->type == TYPE_TRANSFORM)
3084 			_transform_track_optimize(i, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle);
3085 	}
3086 }
3087 
Animation()3088 Animation::Animation() {
3089 
3090 	step = 0.1;
3091 	loop = false;
3092 	length = 1;
3093 }
3094 
~Animation()3095 Animation::~Animation() {
3096 
3097 	for (int i = 0; i < tracks.size(); i++)
3098 		memdelete(tracks[i]);
3099 }
3100