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