1/**************************************************************************/
2/* animation.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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
33#include "core/io/marshalls.h"
34#include "core/math/geometry_3d.h"
35#include "scene/scene_string_names.h"
36
37bool Animation::_set(const StringName &p_name, const Variant &p_value) {
38 String prop_name = p_name;
39
40 if (p_name == SNAME("_compression")) {
41 ERR_FAIL_COND_V(tracks.size() > 0, false); //can only set compression if no tracks exist
42 Dictionary comp = p_value;
43 ERR_FAIL_COND_V(!comp.has("fps"), false);
44 ERR_FAIL_COND_V(!comp.has("bounds"), false);
45 ERR_FAIL_COND_V(!comp.has("pages"), false);
46 ERR_FAIL_COND_V(!comp.has("format_version"), false);
47 uint32_t format_version = comp["format_version"];
48 ERR_FAIL_COND_V(format_version > Compression::FORMAT_VERSION, false); // version does not match this supported version
49 compression.fps = comp["fps"];
50 Array bounds = comp["bounds"];
51 compression.bounds.resize(bounds.size());
52 for (int i = 0; i < bounds.size(); i++) {
53 compression.bounds[i] = bounds[i];
54 }
55 Array pages = comp["pages"];
56 compression.pages.resize(pages.size());
57 for (int i = 0; i < pages.size(); i++) {
58 Dictionary page = pages[i];
59 ERR_FAIL_COND_V(!page.has("data"), false);
60 ERR_FAIL_COND_V(!page.has("time_offset"), false);
61 compression.pages[i].data = page["data"];
62 compression.pages[i].time_offset = page["time_offset"];
63 }
64 compression.enabled = true;
65 return true;
66 } else if (prop_name.begins_with("tracks/")) {
67 int track = prop_name.get_slicec('/', 1).to_int();
68 String what = prop_name.get_slicec('/', 2);
69
70 if (tracks.size() == track && what == "type") {
71 String type = p_value;
72
73 if (type == "position_3d") {
74 add_track(TYPE_POSITION_3D);
75 } else if (type == "rotation_3d") {
76 add_track(TYPE_ROTATION_3D);
77 } else if (type == "scale_3d") {
78 add_track(TYPE_SCALE_3D);
79 } else if (type == "blend_shape") {
80 add_track(TYPE_BLEND_SHAPE);
81 } else if (type == "value") {
82 add_track(TYPE_VALUE);
83 } else if (type == "method") {
84 add_track(TYPE_METHOD);
85 } else if (type == "bezier") {
86 add_track(TYPE_BEZIER);
87 } else if (type == "audio") {
88 add_track(TYPE_AUDIO);
89 } else if (type == "animation") {
90 add_track(TYPE_ANIMATION);
91 } else {
92 return false;
93 }
94
95 return true;
96 }
97
98 ERR_FAIL_INDEX_V(track, tracks.size(), false);
99
100 if (what == "path") {
101 track_set_path(track, p_value);
102 } else if (what == "compressed_track") {
103 int index = p_value;
104 ERR_FAIL_COND_V(!compression.enabled, false);
105 ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)index, compression.bounds.size(), false);
106 Track *t = tracks[track];
107 t->interpolation = INTERPOLATION_LINEAR; //only linear supported
108 switch (t->type) {
109 case TYPE_POSITION_3D: {
110 PositionTrack *tt = static_cast<PositionTrack *>(t);
111 tt->compressed_track = index;
112 } break;
113 case TYPE_ROTATION_3D: {
114 RotationTrack *rt = static_cast<RotationTrack *>(t);
115 rt->compressed_track = index;
116 } break;
117 case TYPE_SCALE_3D: {
118 ScaleTrack *st = static_cast<ScaleTrack *>(t);
119 st->compressed_track = index;
120 } break;
121 case TYPE_BLEND_SHAPE: {
122 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
123 bst->compressed_track = index;
124 } break;
125 default: {
126 return false;
127 }
128 }
129 return true;
130 } else if (what == "use_blend") {
131 if (track_get_type(track) == TYPE_AUDIO) {
132 audio_track_set_use_blend(track, p_value);
133 }
134 } else if (what == "interp") {
135 track_set_interpolation_type(track, InterpolationType(p_value.operator int()));
136 } else if (what == "loop_wrap") {
137 track_set_interpolation_loop_wrap(track, p_value);
138 } else if (what == "imported") {
139 track_set_imported(track, p_value);
140 } else if (what == "enabled") {
141 track_set_enabled(track, p_value);
142 } else if (what == "keys" || what == "key_values") {
143 if (track_get_type(track) == TYPE_POSITION_3D) {
144 PositionTrack *tt = static_cast<PositionTrack *>(tracks[track]);
145 Vector<real_t> values = p_value;
146 int vcount = values.size();
147 ERR_FAIL_COND_V(vcount % POSITION_TRACK_SIZE, false);
148
149 const real_t *r = values.ptr();
150
151 int64_t count = vcount / POSITION_TRACK_SIZE;
152 tt->positions.resize(count);
153
154 TKey<Vector3> *tw = tt->positions.ptrw();
155 for (int i = 0; i < count; i++) {
156 TKey<Vector3> &tk = tw[i];
157 const real_t *ofs = &r[i * POSITION_TRACK_SIZE];
158 tk.time = ofs[0];
159 tk.transition = ofs[1];
160
161 tk.value.x = ofs[2];
162 tk.value.y = ofs[3];
163 tk.value.z = ofs[4];
164 }
165 } else if (track_get_type(track) == TYPE_ROTATION_3D) {
166 RotationTrack *rt = static_cast<RotationTrack *>(tracks[track]);
167 Vector<real_t> values = p_value;
168 int vcount = values.size();
169 ERR_FAIL_COND_V(vcount % ROTATION_TRACK_SIZE, false);
170
171 const real_t *r = values.ptr();
172
173 int64_t count = vcount / ROTATION_TRACK_SIZE;
174 rt->rotations.resize(count);
175
176 TKey<Quaternion> *rw = rt->rotations.ptrw();
177 for (int i = 0; i < count; i++) {
178 TKey<Quaternion> &rk = rw[i];
179 const real_t *ofs = &r[i * ROTATION_TRACK_SIZE];
180 rk.time = ofs[0];
181 rk.transition = ofs[1];
182
183 rk.value.x = ofs[2];
184 rk.value.y = ofs[3];
185 rk.value.z = ofs[4];
186 rk.value.w = ofs[5];
187 }
188 } else if (track_get_type(track) == TYPE_SCALE_3D) {
189 ScaleTrack *st = static_cast<ScaleTrack *>(tracks[track]);
190 Vector<real_t> values = p_value;
191 int vcount = values.size();
192 ERR_FAIL_COND_V(vcount % SCALE_TRACK_SIZE, false);
193
194 const real_t *r = values.ptr();
195
196 int64_t count = vcount / SCALE_TRACK_SIZE;
197 st->scales.resize(count);
198
199 TKey<Vector3> *sw = st->scales.ptrw();
200 for (int i = 0; i < count; i++) {
201 TKey<Vector3> &sk = sw[i];
202 const real_t *ofs = &r[i * SCALE_TRACK_SIZE];
203 sk.time = ofs[0];
204 sk.transition = ofs[1];
205
206 sk.value.x = ofs[2];
207 sk.value.y = ofs[3];
208 sk.value.z = ofs[4];
209 }
210 } else if (track_get_type(track) == TYPE_BLEND_SHAPE) {
211 BlendShapeTrack *st = static_cast<BlendShapeTrack *>(tracks[track]);
212 Vector<real_t> values = p_value;
213 int vcount = values.size();
214 ERR_FAIL_COND_V(vcount % BLEND_SHAPE_TRACK_SIZE, false);
215
216 const real_t *r = values.ptr();
217
218 int64_t count = vcount / BLEND_SHAPE_TRACK_SIZE;
219 st->blend_shapes.resize(count);
220
221 TKey<float> *sw = st->blend_shapes.ptrw();
222 for (int i = 0; i < count; i++) {
223 TKey<float> &sk = sw[i];
224 const real_t *ofs = &r[i * BLEND_SHAPE_TRACK_SIZE];
225 sk.time = ofs[0];
226 sk.transition = ofs[1];
227 sk.value = ofs[2];
228 }
229
230 } else if (track_get_type(track) == TYPE_VALUE) {
231 ValueTrack *vt = static_cast<ValueTrack *>(tracks[track]);
232 Dictionary d = p_value;
233 ERR_FAIL_COND_V(!d.has("times"), false);
234 ERR_FAIL_COND_V(!d.has("values"), false);
235 if (d.has("cont")) {
236 bool v = d["cont"];
237 vt->update_mode = v ? UPDATE_CONTINUOUS : UPDATE_DISCRETE;
238 }
239
240 if (d.has("update")) {
241 int um = d["update"];
242 if (um < 0) {
243 um = 0;
244 } else if (um > 3) {
245 um = 3;
246 }
247 vt->update_mode = UpdateMode(um);
248 }
249
250 Vector<real_t> times = d["times"];
251 Array values = d["values"];
252
253 ERR_FAIL_COND_V(times.size() != values.size(), false);
254
255 if (times.size()) {
256 int valcount = times.size();
257
258 const real_t *rt = times.ptr();
259
260 vt->values.resize(valcount);
261
262 for (int i = 0; i < valcount; i++) {
263 vt->values.write[i].time = rt[i];
264 vt->values.write[i].value = values[i];
265 }
266
267 if (d.has("transitions")) {
268 Vector<real_t> transitions = d["transitions"];
269 ERR_FAIL_COND_V(transitions.size() != valcount, false);
270
271 const real_t *rtr = transitions.ptr();
272
273 for (int i = 0; i < valcount; i++) {
274 vt->values.write[i].transition = rtr[i];
275 }
276 }
277 }
278
279 return true;
280
281 } else if (track_get_type(track) == TYPE_METHOD) {
282 while (track_get_key_count(track)) {
283 track_remove_key(track, 0); //well shouldn't be set anyway
284 }
285
286 Dictionary d = p_value;
287 ERR_FAIL_COND_V(!d.has("times"), false);
288 ERR_FAIL_COND_V(!d.has("values"), false);
289
290 Vector<real_t> times = d["times"];
291 Array values = d["values"];
292
293 ERR_FAIL_COND_V(times.size() != values.size(), false);
294
295 if (times.size()) {
296 int valcount = times.size();
297
298 const real_t *rt = times.ptr();
299
300 for (int i = 0; i < valcount; i++) {
301 track_insert_key(track, rt[i], values[i]);
302 }
303
304 if (d.has("transitions")) {
305 Vector<real_t> transitions = d["transitions"];
306 ERR_FAIL_COND_V(transitions.size() != valcount, false);
307
308 const real_t *rtr = transitions.ptr();
309
310 for (int i = 0; i < valcount; i++) {
311 track_set_key_transition(track, i, rtr[i]);
312 }
313 }
314 }
315 } else if (track_get_type(track) == TYPE_BEZIER) {
316 BezierTrack *bt = static_cast<BezierTrack *>(tracks[track]);
317 Dictionary d = p_value;
318 ERR_FAIL_COND_V(!d.has("times"), false);
319 ERR_FAIL_COND_V(!d.has("points"), false);
320 Vector<real_t> times = d["times"];
321 Vector<real_t> values = d["points"];
322#ifdef TOOLS_ENABLED
323 ERR_FAIL_COND_V(!d.has("handle_modes"), false);
324 Vector<int> handle_modes = d["handle_modes"];
325#endif // TOOLS_ENABLED
326
327 ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
328
329 if (times.size()) {
330 int valcount = times.size();
331
332 const real_t *rt = times.ptr();
333 const real_t *rv = values.ptr();
334#ifdef TOOLS_ENABLED
335 const int *rh = handle_modes.ptr();
336#endif // TOOLS_ENABLED
337
338 bt->values.resize(valcount);
339
340 for (int i = 0; i < valcount; i++) {
341 bt->values.write[i].time = rt[i];
342 bt->values.write[i].transition = 0; //unused in bezier
343 bt->values.write[i].value.value = rv[i * 5 + 0];
344 bt->values.write[i].value.in_handle.x = rv[i * 5 + 1];
345 bt->values.write[i].value.in_handle.y = rv[i * 5 + 2];
346 bt->values.write[i].value.out_handle.x = rv[i * 5 + 3];
347 bt->values.write[i].value.out_handle.y = rv[i * 5 + 4];
348#ifdef TOOLS_ENABLED
349 bt->values.write[i].value.handle_mode = static_cast<HandleMode>(rh[i]);
350#endif // TOOLS_ENABLED
351 }
352 }
353
354 return true;
355 } else if (track_get_type(track) == TYPE_AUDIO) {
356 AudioTrack *ad = static_cast<AudioTrack *>(tracks[track]);
357 Dictionary d = p_value;
358 ERR_FAIL_COND_V(!d.has("times"), false);
359 ERR_FAIL_COND_V(!d.has("clips"), false);
360
361 Vector<real_t> times = d["times"];
362 Array clips = d["clips"];
363
364 ERR_FAIL_COND_V(clips.size() != times.size(), false);
365
366 if (times.size()) {
367 int valcount = times.size();
368
369 const real_t *rt = times.ptr();
370
371 ad->values.clear();
372
373 for (int i = 0; i < valcount; i++) {
374 Dictionary d2 = clips[i];
375 if (!d2.has("start_offset")) {
376 continue;
377 }
378 if (!d2.has("end_offset")) {
379 continue;
380 }
381 if (!d2.has("stream")) {
382 continue;
383 }
384
385 TKey<AudioKey> ak;
386 ak.time = rt[i];
387 ak.value.start_offset = d2["start_offset"];
388 ak.value.end_offset = d2["end_offset"];
389 ak.value.stream = d2["stream"];
390
391 ad->values.push_back(ak);
392 }
393 }
394
395 return true;
396 } else if (track_get_type(track) == TYPE_ANIMATION) {
397 AnimationTrack *an = static_cast<AnimationTrack *>(tracks[track]);
398 Dictionary d = p_value;
399 ERR_FAIL_COND_V(!d.has("times"), false);
400 ERR_FAIL_COND_V(!d.has("clips"), false);
401
402 Vector<real_t> times = d["times"];
403 Vector<String> clips = d["clips"];
404
405 ERR_FAIL_COND_V(clips.size() != times.size(), false);
406
407 if (times.size()) {
408 int valcount = times.size();
409
410 const real_t *rt = times.ptr();
411 const String *rc = clips.ptr();
412
413 an->values.resize(valcount);
414
415 for (int i = 0; i < valcount; i++) {
416 TKey<StringName> ak;
417 ak.time = rt[i];
418 ak.value = rc[i];
419 an->values.write[i] = ak;
420 }
421 }
422
423 return true;
424 } else {
425 return false;
426 }
427 } else {
428 return false;
429 }
430#ifndef DISABLE_DEPRECATED
431 } else if (prop_name == "loop" && p_value.operator bool()) { // Compatibility with Godot 3.x.
432 loop_mode = Animation::LoopMode::LOOP_LINEAR;
433 return true;
434#endif // DISABLE_DEPRECATED
435 } else {
436 return false;
437 }
438
439 return true;
440}
441
442bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
443 String prop_name = p_name;
444
445 if (p_name == SNAME("_compression")) {
446 ERR_FAIL_COND_V(!compression.enabled, false);
447 Dictionary comp;
448 comp["fps"] = compression.fps;
449 Array bounds;
450 bounds.resize(compression.bounds.size());
451 for (uint32_t i = 0; i < compression.bounds.size(); i++) {
452 bounds[i] = compression.bounds[i];
453 }
454 comp["bounds"] = bounds;
455 Array pages;
456 pages.resize(compression.pages.size());
457 for (uint32_t i = 0; i < compression.pages.size(); i++) {
458 Dictionary page;
459 page["data"] = compression.pages[i].data;
460 page["time_offset"] = compression.pages[i].time_offset;
461 pages[i] = page;
462 }
463 comp["pages"] = pages;
464 comp["format_version"] = Compression::FORMAT_VERSION;
465
466 r_ret = comp;
467 return true;
468 } else if (prop_name == "length") {
469 r_ret = length;
470 } else if (prop_name == "loop_mode") {
471 r_ret = loop_mode;
472 } else if (prop_name == "step") {
473 r_ret = step;
474 } else if (prop_name.begins_with("tracks/")) {
475 int track = prop_name.get_slicec('/', 1).to_int();
476 String what = prop_name.get_slicec('/', 2);
477 ERR_FAIL_INDEX_V(track, tracks.size(), false);
478 if (what == "type") {
479 switch (track_get_type(track)) {
480 case TYPE_POSITION_3D:
481 r_ret = "position_3d";
482 break;
483 case TYPE_ROTATION_3D:
484 r_ret = "rotation_3d";
485 break;
486 case TYPE_SCALE_3D:
487 r_ret = "scale_3d";
488 break;
489 case TYPE_BLEND_SHAPE:
490 r_ret = "blend_shape";
491 break;
492 case TYPE_VALUE:
493 r_ret = "value";
494 break;
495 case TYPE_METHOD:
496 r_ret = "method";
497 break;
498 case TYPE_BEZIER:
499 r_ret = "bezier";
500 break;
501 case TYPE_AUDIO:
502 r_ret = "audio";
503 break;
504 case TYPE_ANIMATION:
505 r_ret = "animation";
506 break;
507 }
508
509 return true;
510
511 } else if (what == "path") {
512 r_ret = track_get_path(track);
513 } else if (what == "compressed_track") {
514 ERR_FAIL_COND_V(!compression.enabled, false);
515 Track *t = tracks[track];
516 switch (t->type) {
517 case TYPE_POSITION_3D: {
518 PositionTrack *tt = static_cast<PositionTrack *>(t);
519 r_ret = tt->compressed_track;
520 } break;
521 case TYPE_ROTATION_3D: {
522 RotationTrack *rt = static_cast<RotationTrack *>(t);
523 r_ret = rt->compressed_track;
524 } break;
525 case TYPE_SCALE_3D: {
526 ScaleTrack *st = static_cast<ScaleTrack *>(t);
527 r_ret = st->compressed_track;
528 } break;
529 case TYPE_BLEND_SHAPE: {
530 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
531 r_ret = bst->compressed_track;
532 } break;
533 default: {
534 r_ret = Variant();
535 ERR_FAIL_V(false);
536 }
537 }
538
539 return true;
540 } else if (what == "use_blend") {
541 if (track_get_type(track) == TYPE_AUDIO) {
542 r_ret = audio_track_is_use_blend(track);
543 }
544 } else if (what == "interp") {
545 r_ret = track_get_interpolation_type(track);
546 } else if (what == "loop_wrap") {
547 r_ret = track_get_interpolation_loop_wrap(track);
548 } else if (what == "imported") {
549 r_ret = track_is_imported(track);
550 } else if (what == "enabled") {
551 r_ret = track_is_enabled(track);
552 } else if (what == "keys") {
553 if (track_get_type(track) == TYPE_POSITION_3D) {
554 Vector<real_t> keys;
555 int kk = track_get_key_count(track);
556 keys.resize(kk * POSITION_TRACK_SIZE);
557
558 real_t *w = keys.ptrw();
559
560 int idx = 0;
561 for (int i = 0; i < track_get_key_count(track); i++) {
562 Vector3 loc;
563 position_track_get_key(track, i, &loc);
564
565 w[idx++] = track_get_key_time(track, i);
566 w[idx++] = track_get_key_transition(track, i);
567 w[idx++] = loc.x;
568 w[idx++] = loc.y;
569 w[idx++] = loc.z;
570 }
571
572 r_ret = keys;
573 return true;
574 } else if (track_get_type(track) == TYPE_ROTATION_3D) {
575 Vector<real_t> keys;
576 int kk = track_get_key_count(track);
577 keys.resize(kk * ROTATION_TRACK_SIZE);
578
579 real_t *w = keys.ptrw();
580
581 int idx = 0;
582 for (int i = 0; i < track_get_key_count(track); i++) {
583 Quaternion rot;
584 rotation_track_get_key(track, i, &rot);
585
586 w[idx++] = track_get_key_time(track, i);
587 w[idx++] = track_get_key_transition(track, i);
588 w[idx++] = rot.x;
589 w[idx++] = rot.y;
590 w[idx++] = rot.z;
591 w[idx++] = rot.w;
592 }
593
594 r_ret = keys;
595 return true;
596
597 } else if (track_get_type(track) == TYPE_SCALE_3D) {
598 Vector<real_t> keys;
599 int kk = track_get_key_count(track);
600 keys.resize(kk * SCALE_TRACK_SIZE);
601
602 real_t *w = keys.ptrw();
603
604 int idx = 0;
605 for (int i = 0; i < track_get_key_count(track); i++) {
606 Vector3 scale;
607 scale_track_get_key(track, i, &scale);
608
609 w[idx++] = track_get_key_time(track, i);
610 w[idx++] = track_get_key_transition(track, i);
611 w[idx++] = scale.x;
612 w[idx++] = scale.y;
613 w[idx++] = scale.z;
614 }
615
616 r_ret = keys;
617 return true;
618 } else if (track_get_type(track) == TYPE_BLEND_SHAPE) {
619 Vector<real_t> keys;
620 int kk = track_get_key_count(track);
621 keys.resize(kk * BLEND_SHAPE_TRACK_SIZE);
622
623 real_t *w = keys.ptrw();
624
625 int idx = 0;
626 for (int i = 0; i < track_get_key_count(track); i++) {
627 float bs;
628 blend_shape_track_get_key(track, i, &bs);
629
630 w[idx++] = track_get_key_time(track, i);
631 w[idx++] = track_get_key_transition(track, i);
632 w[idx++] = bs;
633 }
634
635 r_ret = keys;
636 return true;
637 } else if (track_get_type(track) == TYPE_VALUE) {
638 const ValueTrack *vt = static_cast<const ValueTrack *>(tracks[track]);
639
640 Dictionary d;
641
642 Vector<real_t> key_times;
643 Vector<real_t> key_transitions;
644 Array key_values;
645
646 int kk = vt->values.size();
647
648 key_times.resize(kk);
649 key_transitions.resize(kk);
650 key_values.resize(kk);
651
652 real_t *wti = key_times.ptrw();
653 real_t *wtr = key_transitions.ptrw();
654
655 int idx = 0;
656
657 const TKey<Variant> *vls = vt->values.ptr();
658
659 for (int i = 0; i < kk; i++) {
660 wti[idx] = vls[i].time;
661 wtr[idx] = vls[i].transition;
662 key_values[idx] = vls[i].value;
663 idx++;
664 }
665
666 d["times"] = key_times;
667 d["transitions"] = key_transitions;
668 d["values"] = key_values;
669 if (track_get_type(track) == TYPE_VALUE) {
670 d["update"] = value_track_get_update_mode(track);
671 }
672
673 r_ret = d;
674
675 return true;
676
677 } else if (track_get_type(track) == TYPE_METHOD) {
678 Dictionary d;
679
680 Vector<real_t> key_times;
681 Vector<real_t> key_transitions;
682 Array key_values;
683
684 int kk = track_get_key_count(track);
685
686 key_times.resize(kk);
687 key_transitions.resize(kk);
688 key_values.resize(kk);
689
690 real_t *wti = key_times.ptrw();
691 real_t *wtr = key_transitions.ptrw();
692
693 int idx = 0;
694 for (int i = 0; i < track_get_key_count(track); i++) {
695 wti[idx] = track_get_key_time(track, i);
696 wtr[idx] = track_get_key_transition(track, i);
697 key_values[idx] = track_get_key_value(track, i);
698 idx++;
699 }
700
701 d["times"] = key_times;
702 d["transitions"] = key_transitions;
703 d["values"] = key_values;
704 if (track_get_type(track) == TYPE_VALUE) {
705 d["update"] = value_track_get_update_mode(track);
706 }
707
708 r_ret = d;
709
710 return true;
711 } else if (track_get_type(track) == TYPE_BEZIER) {
712 const BezierTrack *bt = static_cast<const BezierTrack *>(tracks[track]);
713
714 Dictionary d;
715
716 Vector<real_t> key_times;
717 Vector<real_t> key_points;
718
719 int kk = bt->values.size();
720
721 key_times.resize(kk);
722 key_points.resize(kk * 5);
723
724 real_t *wti = key_times.ptrw();
725 real_t *wpo = key_points.ptrw();
726
727#ifdef TOOLS_ENABLED
728 Vector<int> handle_modes;
729 handle_modes.resize(kk);
730 int *whm = handle_modes.ptrw();
731#endif // TOOLS_ENABLED
732
733 int idx = 0;
734
735 const TKey<BezierKey> *vls = bt->values.ptr();
736
737 for (int i = 0; i < kk; i++) {
738 wti[idx] = vls[i].time;
739 wpo[idx * 5 + 0] = vls[i].value.value;
740 wpo[idx * 5 + 1] = vls[i].value.in_handle.x;
741 wpo[idx * 5 + 2] = vls[i].value.in_handle.y;
742 wpo[idx * 5 + 3] = vls[i].value.out_handle.x;
743 wpo[idx * 5 + 4] = vls[i].value.out_handle.y;
744#ifdef TOOLS_ENABLED
745 whm[idx] = static_cast<int>(vls[i].value.handle_mode);
746#endif // TOOLS_ENABLED
747 idx++;
748 }
749
750 d["times"] = key_times;
751 d["points"] = key_points;
752#ifdef TOOLS_ENABLED
753 d["handle_modes"] = handle_modes;
754#endif // TOOLS_ENABLED
755
756 r_ret = d;
757
758 return true;
759 } else if (track_get_type(track) == TYPE_AUDIO) {
760 const AudioTrack *ad = static_cast<const AudioTrack *>(tracks[track]);
761
762 Dictionary d;
763
764 Vector<real_t> key_times;
765 Array clips;
766
767 int kk = ad->values.size();
768
769 key_times.resize(kk);
770
771 real_t *wti = key_times.ptrw();
772
773 int idx = 0;
774
775 const TKey<AudioKey> *vls = ad->values.ptr();
776
777 for (int i = 0; i < kk; i++) {
778 wti[idx] = vls[i].time;
779 Dictionary clip;
780 clip["start_offset"] = vls[i].value.start_offset;
781 clip["end_offset"] = vls[i].value.end_offset;
782 clip["stream"] = vls[i].value.stream;
783 clips.push_back(clip);
784 idx++;
785 }
786
787 d["times"] = key_times;
788 d["clips"] = clips;
789
790 r_ret = d;
791
792 return true;
793 } else if (track_get_type(track) == TYPE_ANIMATION) {
794 const AnimationTrack *an = static_cast<const AnimationTrack *>(tracks[track]);
795
796 Dictionary d;
797
798 Vector<real_t> key_times;
799 Vector<String> clips;
800
801 int kk = an->values.size();
802
803 key_times.resize(kk);
804 clips.resize(kk);
805
806 real_t *wti = key_times.ptrw();
807 String *wcl = clips.ptrw();
808
809 const TKey<StringName> *vls = an->values.ptr();
810
811 for (int i = 0; i < kk; i++) {
812 wti[i] = vls[i].time;
813 wcl[i] = vls[i].value;
814 }
815
816 d["times"] = key_times;
817 d["clips"] = clips;
818
819 r_ret = d;
820
821 return true;
822 }
823 } else {
824 return false;
825 }
826 } else {
827 return false;
828 }
829
830 return true;
831}
832
833void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
834 if (compression.enabled) {
835 p_list->push_back(PropertyInfo(Variant::DICTIONARY, "_compression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
836 }
837 for (int i = 0; i < tracks.size(); i++) {
838 p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
839 p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
840 p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
841 p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
842 if (track_is_compressed(i)) {
843 p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/compressed_track", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
844 } else {
845 p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
846 p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
847 p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
848 }
849 if (track_get_type(i) == TYPE_AUDIO) {
850 p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/use_blend", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
851 }
852 }
853}
854
855void Animation::reset_state() {
856 clear();
857}
858
859int Animation::add_track(TrackType p_type, int p_at_pos) {
860 if (p_at_pos < 0 || p_at_pos >= tracks.size()) {
861 p_at_pos = tracks.size();
862 }
863
864 switch (p_type) {
865 case TYPE_POSITION_3D: {
866 PositionTrack *tt = memnew(PositionTrack);
867 tracks.insert(p_at_pos, tt);
868 } break;
869 case TYPE_ROTATION_3D: {
870 RotationTrack *rt = memnew(RotationTrack);
871 tracks.insert(p_at_pos, rt);
872 } break;
873 case TYPE_SCALE_3D: {
874 ScaleTrack *st = memnew(ScaleTrack);
875 tracks.insert(p_at_pos, st);
876 } break;
877 case TYPE_BLEND_SHAPE: {
878 BlendShapeTrack *bst = memnew(BlendShapeTrack);
879 tracks.insert(p_at_pos, bst);
880 } break;
881 case TYPE_VALUE: {
882 tracks.insert(p_at_pos, memnew(ValueTrack));
883
884 } break;
885 case TYPE_METHOD: {
886 tracks.insert(p_at_pos, memnew(MethodTrack));
887
888 } break;
889 case TYPE_BEZIER: {
890 tracks.insert(p_at_pos, memnew(BezierTrack));
891
892 } break;
893 case TYPE_AUDIO: {
894 tracks.insert(p_at_pos, memnew(AudioTrack));
895
896 } break;
897 case TYPE_ANIMATION: {
898 tracks.insert(p_at_pos, memnew(AnimationTrack));
899
900 } break;
901 default: {
902 ERR_PRINT("Unknown track type");
903 }
904 }
905 emit_changed();
906 return p_at_pos;
907}
908
909void Animation::remove_track(int p_track) {
910 ERR_FAIL_INDEX(p_track, tracks.size());
911 Track *t = tracks[p_track];
912
913 switch (t->type) {
914 case TYPE_POSITION_3D: {
915 PositionTrack *tt = static_cast<PositionTrack *>(t);
916 ERR_FAIL_COND_MSG(tt->compressed_track >= 0, "Compressed tracks can't be manually removed. Call clear() to get rid of compression first.");
917 _clear(tt->positions);
918
919 } break;
920 case TYPE_ROTATION_3D: {
921 RotationTrack *rt = static_cast<RotationTrack *>(t);
922 ERR_FAIL_COND_MSG(rt->compressed_track >= 0, "Compressed tracks can't be manually removed. Call clear() to get rid of compression first.");
923 _clear(rt->rotations);
924
925 } break;
926 case TYPE_SCALE_3D: {
927 ScaleTrack *st = static_cast<ScaleTrack *>(t);
928 ERR_FAIL_COND_MSG(st->compressed_track >= 0, "Compressed tracks can't be manually removed. Call clear() to get rid of compression first.");
929 _clear(st->scales);
930
931 } break;
932 case TYPE_BLEND_SHAPE: {
933 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
934 ERR_FAIL_COND_MSG(bst->compressed_track >= 0, "Compressed tracks can't be manually removed. Call clear() to get rid of compression first.");
935 _clear(bst->blend_shapes);
936
937 } break;
938 case TYPE_VALUE: {
939 ValueTrack *vt = static_cast<ValueTrack *>(t);
940 _clear(vt->values);
941
942 } break;
943 case TYPE_METHOD: {
944 MethodTrack *mt = static_cast<MethodTrack *>(t);
945 _clear(mt->methods);
946
947 } break;
948 case TYPE_BEZIER: {
949 BezierTrack *bz = static_cast<BezierTrack *>(t);
950 _clear(bz->values);
951
952 } break;
953 case TYPE_AUDIO: {
954 AudioTrack *ad = static_cast<AudioTrack *>(t);
955 _clear(ad->values);
956
957 } break;
958 case TYPE_ANIMATION: {
959 AnimationTrack *an = static_cast<AnimationTrack *>(t);
960 _clear(an->values);
961
962 } break;
963 }
964
965 memdelete(t);
966 tracks.remove_at(p_track);
967 emit_changed();
968}
969
970int Animation::get_track_count() const {
971 return tracks.size();
972}
973
974Animation::TrackType Animation::track_get_type(int p_track) const {
975 ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_VALUE);
976 return tracks[p_track]->type;
977}
978
979void Animation::track_set_path(int p_track, const NodePath &p_path) {
980 ERR_FAIL_INDEX(p_track, tracks.size());
981 tracks[p_track]->path = p_path;
982 emit_changed();
983}
984
985NodePath Animation::track_get_path(int p_track) const {
986 ERR_FAIL_INDEX_V(p_track, tracks.size(), NodePath());
987 return tracks[p_track]->path;
988}
989
990int Animation::find_track(const NodePath &p_path, const TrackType p_type) const {
991 for (int i = 0; i < tracks.size(); i++) {
992 if (tracks[i]->path == p_path && tracks[i]->type == p_type) {
993 return i;
994 }
995 };
996 return -1;
997};
998
999void Animation::track_set_interpolation_type(int p_track, InterpolationType p_interp) {
1000 ERR_FAIL_INDEX(p_track, tracks.size());
1001 tracks[p_track]->interpolation = p_interp;
1002 emit_changed();
1003}
1004
1005Animation::InterpolationType Animation::track_get_interpolation_type(int p_track) const {
1006 ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
1007 return tracks[p_track]->interpolation;
1008}
1009
1010void Animation::track_set_interpolation_loop_wrap(int p_track, bool p_enable) {
1011 ERR_FAIL_INDEX(p_track, tracks.size());
1012 tracks[p_track]->loop_wrap = p_enable;
1013 emit_changed();
1014}
1015
1016bool Animation::track_get_interpolation_loop_wrap(int p_track) const {
1017 ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
1018 return tracks[p_track]->loop_wrap;
1019}
1020
1021template <class T, class V>
1022int Animation::_insert(double p_time, T &p_keys, const V &p_value) {
1023 int idx = p_keys.size();
1024
1025 while (true) {
1026 // Condition for replacement.
1027 if (idx > 0 && Math::is_equal_approx((double)p_keys[idx - 1].time, p_time)) {
1028 float transition = p_keys[idx - 1].transition;
1029 p_keys.write[idx - 1] = p_value;
1030 p_keys.write[idx - 1].transition = transition;
1031 return idx - 1;
1032
1033 // Condition for insert.
1034 } else if (idx == 0 || p_keys[idx - 1].time < p_time) {
1035 p_keys.insert(idx, p_value);
1036 return idx;
1037 }
1038
1039 idx--;
1040 }
1041
1042 return -1;
1043}
1044
1045template <class T>
1046void Animation::_clear(T &p_keys) {
1047 p_keys.clear();
1048}
1049
1050////
1051
1052int Animation::position_track_insert_key(int p_track, double p_time, const Vector3 &p_position) {
1053 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1054 Track *t = tracks[p_track];
1055 ERR_FAIL_COND_V(t->type != TYPE_POSITION_3D, -1);
1056
1057 PositionTrack *tt = static_cast<PositionTrack *>(t);
1058
1059 ERR_FAIL_COND_V(tt->compressed_track >= 0, -1);
1060
1061 TKey<Vector3> tkey;
1062 tkey.time = p_time;
1063 tkey.value = p_position;
1064
1065 int ret = _insert(p_time, tt->positions, tkey);
1066 emit_changed();
1067 return ret;
1068}
1069
1070Error Animation::position_track_get_key(int p_track, int p_key, Vector3 *r_position) const {
1071 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1072 Track *t = tracks[p_track];
1073
1074 PositionTrack *tt = static_cast<PositionTrack *>(t);
1075 ERR_FAIL_COND_V(t->type != TYPE_POSITION_3D, ERR_INVALID_PARAMETER);
1076
1077 if (tt->compressed_track >= 0) {
1078 Vector3i key;
1079 double time;
1080 bool fetch_success = _fetch_compressed_by_index<3>(tt->compressed_track, p_key, key, time);
1081 if (!fetch_success) {
1082 return ERR_INVALID_PARAMETER;
1083 }
1084
1085 *r_position = _uncompress_pos_scale(tt->compressed_track, key);
1086 return OK;
1087 }
1088
1089 ERR_FAIL_INDEX_V(p_key, tt->positions.size(), ERR_INVALID_PARAMETER);
1090
1091 *r_position = tt->positions[p_key].value;
1092
1093 return OK;
1094}
1095
1096Error Animation::try_position_track_interpolate(int p_track, double p_time, Vector3 *r_interpolation) const {
1097 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1098 Track *t = tracks[p_track];
1099 ERR_FAIL_COND_V(t->type != TYPE_POSITION_3D, ERR_INVALID_PARAMETER);
1100
1101 PositionTrack *tt = static_cast<PositionTrack *>(t);
1102
1103 if (tt->compressed_track >= 0) {
1104 if (_pos_scale_interpolate_compressed(tt->compressed_track, p_time, *r_interpolation)) {
1105 return OK;
1106 } else {
1107 return ERR_UNAVAILABLE;
1108 }
1109 }
1110
1111 bool ok = false;
1112
1113 Vector3 tk = _interpolate(tt->positions, p_time, tt->interpolation, tt->loop_wrap, &ok);
1114
1115 if (!ok) {
1116 return ERR_UNAVAILABLE;
1117 }
1118 *r_interpolation = tk;
1119 return OK;
1120}
1121
1122Vector3 Animation::position_track_interpolate(int p_track, double p_time) const {
1123 Vector3 ret = Vector3(0, 0, 0);
1124 ERR_FAIL_INDEX_V(p_track, tracks.size(), ret);
1125 bool err = try_position_track_interpolate(p_track, p_time, &ret);
1126 ERR_FAIL_COND_V_MSG(err, ret, "3D Position Track: '" + tracks[p_track]->path + "' is unavailable.");
1127 return ret;
1128}
1129
1130////
1131
1132int Animation::rotation_track_insert_key(int p_track, double p_time, const Quaternion &p_rotation) {
1133 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1134 Track *t = tracks[p_track];
1135 ERR_FAIL_COND_V(t->type != TYPE_ROTATION_3D, -1);
1136
1137 RotationTrack *rt = static_cast<RotationTrack *>(t);
1138
1139 ERR_FAIL_COND_V(rt->compressed_track >= 0, -1);
1140
1141 TKey<Quaternion> tkey;
1142 tkey.time = p_time;
1143 tkey.value = p_rotation;
1144
1145 int ret = _insert(p_time, rt->rotations, tkey);
1146 emit_changed();
1147 return ret;
1148}
1149
1150Error Animation::rotation_track_get_key(int p_track, int p_key, Quaternion *r_rotation) const {
1151 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1152 Track *t = tracks[p_track];
1153
1154 RotationTrack *rt = static_cast<RotationTrack *>(t);
1155 ERR_FAIL_COND_V(t->type != TYPE_ROTATION_3D, ERR_INVALID_PARAMETER);
1156
1157 if (rt->compressed_track >= 0) {
1158 Vector3i key;
1159 double time;
1160 bool fetch_success = _fetch_compressed_by_index<3>(rt->compressed_track, p_key, key, time);
1161 if (!fetch_success) {
1162 return ERR_INVALID_PARAMETER;
1163 }
1164
1165 *r_rotation = _uncompress_quaternion(key);
1166 return OK;
1167 }
1168
1169 ERR_FAIL_INDEX_V(p_key, rt->rotations.size(), ERR_INVALID_PARAMETER);
1170
1171 *r_rotation = rt->rotations[p_key].value;
1172
1173 return OK;
1174}
1175
1176Error Animation::try_rotation_track_interpolate(int p_track, double p_time, Quaternion *r_interpolation) const {
1177 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1178 Track *t = tracks[p_track];
1179 ERR_FAIL_COND_V(t->type != TYPE_ROTATION_3D, ERR_INVALID_PARAMETER);
1180
1181 RotationTrack *rt = static_cast<RotationTrack *>(t);
1182
1183 if (rt->compressed_track >= 0) {
1184 if (_rotation_interpolate_compressed(rt->compressed_track, p_time, *r_interpolation)) {
1185 return OK;
1186 } else {
1187 return ERR_UNAVAILABLE;
1188 }
1189 }
1190
1191 bool ok = false;
1192
1193 Quaternion tk = _interpolate(rt->rotations, p_time, rt->interpolation, rt->loop_wrap, &ok);
1194
1195 if (!ok) {
1196 return ERR_UNAVAILABLE;
1197 }
1198 *r_interpolation = tk;
1199 return OK;
1200}
1201
1202Quaternion Animation::rotation_track_interpolate(int p_track, double p_time) const {
1203 Quaternion ret = Quaternion(0, 0, 0, 1);
1204 ERR_FAIL_INDEX_V(p_track, tracks.size(), ret);
1205 bool err = try_rotation_track_interpolate(p_track, p_time, &ret);
1206 ERR_FAIL_COND_V_MSG(err, ret, "3D Rotation Track: '" + tracks[p_track]->path + "' is unavailable.");
1207 return ret;
1208}
1209
1210////
1211
1212int Animation::scale_track_insert_key(int p_track, double p_time, const Vector3 &p_scale) {
1213 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1214 Track *t = tracks[p_track];
1215 ERR_FAIL_COND_V(t->type != TYPE_SCALE_3D, -1);
1216
1217 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1218
1219 ERR_FAIL_COND_V(st->compressed_track >= 0, -1);
1220
1221 TKey<Vector3> tkey;
1222 tkey.time = p_time;
1223 tkey.value = p_scale;
1224
1225 int ret = _insert(p_time, st->scales, tkey);
1226 emit_changed();
1227 return ret;
1228}
1229
1230Error Animation::scale_track_get_key(int p_track, int p_key, Vector3 *r_scale) const {
1231 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1232 Track *t = tracks[p_track];
1233
1234 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1235 ERR_FAIL_COND_V(t->type != TYPE_SCALE_3D, ERR_INVALID_PARAMETER);
1236
1237 if (st->compressed_track >= 0) {
1238 Vector3i key;
1239 double time;
1240 bool fetch_success = _fetch_compressed_by_index<3>(st->compressed_track, p_key, key, time);
1241 if (!fetch_success) {
1242 return ERR_INVALID_PARAMETER;
1243 }
1244
1245 *r_scale = _uncompress_pos_scale(st->compressed_track, key);
1246 return OK;
1247 }
1248
1249 ERR_FAIL_INDEX_V(p_key, st->scales.size(), ERR_INVALID_PARAMETER);
1250
1251 *r_scale = st->scales[p_key].value;
1252
1253 return OK;
1254}
1255
1256Error Animation::try_scale_track_interpolate(int p_track, double p_time, Vector3 *r_interpolation) const {
1257 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1258 Track *t = tracks[p_track];
1259 ERR_FAIL_COND_V(t->type != TYPE_SCALE_3D, ERR_INVALID_PARAMETER);
1260
1261 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1262
1263 if (st->compressed_track >= 0) {
1264 if (_pos_scale_interpolate_compressed(st->compressed_track, p_time, *r_interpolation)) {
1265 return OK;
1266 } else {
1267 return ERR_UNAVAILABLE;
1268 }
1269 }
1270
1271 bool ok = false;
1272
1273 Vector3 tk = _interpolate(st->scales, p_time, st->interpolation, st->loop_wrap, &ok);
1274
1275 if (!ok) {
1276 return ERR_UNAVAILABLE;
1277 }
1278 *r_interpolation = tk;
1279 return OK;
1280}
1281
1282Vector3 Animation::scale_track_interpolate(int p_track, double p_time) const {
1283 Vector3 ret = Vector3(1, 1, 1);
1284 ERR_FAIL_INDEX_V(p_track, tracks.size(), ret);
1285 bool err = try_scale_track_interpolate(p_track, p_time, &ret);
1286 ERR_FAIL_COND_V_MSG(err, ret, "3D Scale Track: '" + tracks[p_track]->path + "' is unavailable.");
1287 return ret;
1288}
1289
1290////
1291
1292int Animation::blend_shape_track_insert_key(int p_track, double p_time, float p_blend_shape) {
1293 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1294 Track *t = tracks[p_track];
1295 ERR_FAIL_COND_V(t->type != TYPE_BLEND_SHAPE, -1);
1296
1297 BlendShapeTrack *st = static_cast<BlendShapeTrack *>(t);
1298
1299 ERR_FAIL_COND_V(st->compressed_track >= 0, -1);
1300
1301 TKey<float> tkey;
1302 tkey.time = p_time;
1303 tkey.value = p_blend_shape;
1304
1305 int ret = _insert(p_time, st->blend_shapes, tkey);
1306 emit_changed();
1307 return ret;
1308}
1309
1310Error Animation::blend_shape_track_get_key(int p_track, int p_key, float *r_blend_shape) const {
1311 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1312 Track *t = tracks[p_track];
1313
1314 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1315 ERR_FAIL_COND_V(t->type != TYPE_BLEND_SHAPE, ERR_INVALID_PARAMETER);
1316
1317 if (bst->compressed_track >= 0) {
1318 Vector3i key;
1319 double time;
1320 bool fetch_success = _fetch_compressed_by_index<1>(bst->compressed_track, p_key, key, time);
1321 if (!fetch_success) {
1322 return ERR_INVALID_PARAMETER;
1323 }
1324
1325 *r_blend_shape = _uncompress_blend_shape(key);
1326 return OK;
1327 }
1328
1329 ERR_FAIL_INDEX_V(p_key, bst->blend_shapes.size(), ERR_INVALID_PARAMETER);
1330
1331 *r_blend_shape = bst->blend_shapes[p_key].value;
1332
1333 return OK;
1334}
1335
1336Error Animation::try_blend_shape_track_interpolate(int p_track, double p_time, float *r_interpolation) const {
1337 ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
1338 Track *t = tracks[p_track];
1339 ERR_FAIL_COND_V(t->type != TYPE_BLEND_SHAPE, ERR_INVALID_PARAMETER);
1340
1341 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1342
1343 if (bst->compressed_track >= 0) {
1344 if (_blend_shape_interpolate_compressed(bst->compressed_track, p_time, *r_interpolation)) {
1345 return OK;
1346 } else {
1347 return ERR_UNAVAILABLE;
1348 }
1349 }
1350
1351 bool ok = false;
1352
1353 float tk = _interpolate(bst->blend_shapes, p_time, bst->interpolation, bst->loop_wrap, &ok);
1354
1355 if (!ok) {
1356 return ERR_UNAVAILABLE;
1357 }
1358 *r_interpolation = tk;
1359 return OK;
1360}
1361
1362float Animation::blend_shape_track_interpolate(int p_track, double p_time) const {
1363 float ret = 0;
1364 ERR_FAIL_INDEX_V(p_track, tracks.size(), ret);
1365 bool err = try_blend_shape_track_interpolate(p_track, p_time, &ret);
1366 ERR_FAIL_COND_V_MSG(err, ret, "Blend Shape Track: '" + tracks[p_track]->path + "' is unavailable.");
1367 return ret;
1368}
1369
1370////
1371
1372void Animation::track_remove_key_at_time(int p_track, double p_time) {
1373 int idx = track_find_key(p_track, p_time, FIND_MODE_APPROX);
1374 ERR_FAIL_COND(idx < 0);
1375 track_remove_key(p_track, idx);
1376}
1377
1378void Animation::track_remove_key(int p_track, int p_idx) {
1379 ERR_FAIL_INDEX(p_track, tracks.size());
1380 Track *t = tracks[p_track];
1381
1382 switch (t->type) {
1383 case TYPE_POSITION_3D: {
1384 PositionTrack *tt = static_cast<PositionTrack *>(t);
1385
1386 ERR_FAIL_COND(tt->compressed_track >= 0);
1387
1388 ERR_FAIL_INDEX(p_idx, tt->positions.size());
1389 tt->positions.remove_at(p_idx);
1390
1391 } break;
1392 case TYPE_ROTATION_3D: {
1393 RotationTrack *rt = static_cast<RotationTrack *>(t);
1394
1395 ERR_FAIL_COND(rt->compressed_track >= 0);
1396
1397 ERR_FAIL_INDEX(p_idx, rt->rotations.size());
1398 rt->rotations.remove_at(p_idx);
1399
1400 } break;
1401 case TYPE_SCALE_3D: {
1402 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1403
1404 ERR_FAIL_COND(st->compressed_track >= 0);
1405
1406 ERR_FAIL_INDEX(p_idx, st->scales.size());
1407 st->scales.remove_at(p_idx);
1408
1409 } break;
1410 case TYPE_BLEND_SHAPE: {
1411 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1412
1413 ERR_FAIL_COND(bst->compressed_track >= 0);
1414
1415 ERR_FAIL_INDEX(p_idx, bst->blend_shapes.size());
1416 bst->blend_shapes.remove_at(p_idx);
1417
1418 } break;
1419 case TYPE_VALUE: {
1420 ValueTrack *vt = static_cast<ValueTrack *>(t);
1421 ERR_FAIL_INDEX(p_idx, vt->values.size());
1422 vt->values.remove_at(p_idx);
1423
1424 } break;
1425 case TYPE_METHOD: {
1426 MethodTrack *mt = static_cast<MethodTrack *>(t);
1427 ERR_FAIL_INDEX(p_idx, mt->methods.size());
1428 mt->methods.remove_at(p_idx);
1429
1430 } break;
1431 case TYPE_BEZIER: {
1432 BezierTrack *bz = static_cast<BezierTrack *>(t);
1433 ERR_FAIL_INDEX(p_idx, bz->values.size());
1434 bz->values.remove_at(p_idx);
1435
1436 } break;
1437 case TYPE_AUDIO: {
1438 AudioTrack *ad = static_cast<AudioTrack *>(t);
1439 ERR_FAIL_INDEX(p_idx, ad->values.size());
1440 ad->values.remove_at(p_idx);
1441
1442 } break;
1443 case TYPE_ANIMATION: {
1444 AnimationTrack *an = static_cast<AnimationTrack *>(t);
1445 ERR_FAIL_INDEX(p_idx, an->values.size());
1446 an->values.remove_at(p_idx);
1447
1448 } break;
1449 }
1450
1451 emit_changed();
1452}
1453
1454int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode) const {
1455 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1456 Track *t = tracks[p_track];
1457
1458 switch (t->type) {
1459 case TYPE_POSITION_3D: {
1460 PositionTrack *tt = static_cast<PositionTrack *>(t);
1461
1462 if (tt->compressed_track >= 0) {
1463 double time;
1464 double time_next;
1465 Vector3i key;
1466 Vector3i key_next;
1467 uint32_t key_index;
1468 bool fetch_compressed_success = _fetch_compressed<3>(tt->compressed_track, p_time, key, time, key_next, time_next, &key_index);
1469 ERR_FAIL_COND_V(!fetch_compressed_success, -1);
1470 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
1471 return -1;
1472 }
1473 return key_index;
1474 }
1475
1476 int k = _find(tt->positions, p_time);
1477 if (k < 0 || k >= tt->positions.size()) {
1478 return -1;
1479 }
1480 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(tt->positions[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && tt->positions[k].time != p_time)) {
1481 return -1;
1482 }
1483 return k;
1484
1485 } break;
1486 case TYPE_ROTATION_3D: {
1487 RotationTrack *rt = static_cast<RotationTrack *>(t);
1488
1489 if (rt->compressed_track >= 0) {
1490 double time;
1491 double time_next;
1492 Vector3i key;
1493 Vector3i key_next;
1494 uint32_t key_index;
1495 bool fetch_compressed_success = _fetch_compressed<3>(rt->compressed_track, p_time, key, time, key_next, time_next, &key_index);
1496 ERR_FAIL_COND_V(!fetch_compressed_success, -1);
1497 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
1498 return -1;
1499 }
1500 return key_index;
1501 }
1502
1503 int k = _find(rt->rotations, p_time);
1504 if (k < 0 || k >= rt->rotations.size()) {
1505 return -1;
1506 }
1507 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(rt->rotations[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && rt->rotations[k].time != p_time)) {
1508 return -1;
1509 }
1510 return k;
1511
1512 } break;
1513 case TYPE_SCALE_3D: {
1514 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1515
1516 if (st->compressed_track >= 0) {
1517 double time;
1518 double time_next;
1519 Vector3i key;
1520 Vector3i key_next;
1521 uint32_t key_index;
1522 bool fetch_compressed_success = _fetch_compressed<3>(st->compressed_track, p_time, key, time, key_next, time_next, &key_index);
1523 ERR_FAIL_COND_V(!fetch_compressed_success, -1);
1524 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
1525 return -1;
1526 }
1527 return key_index;
1528 }
1529
1530 int k = _find(st->scales, p_time);
1531 if (k < 0 || k >= st->scales.size()) {
1532 return -1;
1533 }
1534 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(st->scales[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && st->scales[k].time != p_time)) {
1535 return -1;
1536 }
1537 return k;
1538
1539 } break;
1540 case TYPE_BLEND_SHAPE: {
1541 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1542
1543 if (bst->compressed_track >= 0) {
1544 double time;
1545 double time_next;
1546 Vector3i key;
1547 Vector3i key_next;
1548 uint32_t key_index;
1549 bool fetch_compressed_success = _fetch_compressed<1>(bst->compressed_track, p_time, key, time, key_next, time_next, &key_index);
1550 ERR_FAIL_COND_V(!fetch_compressed_success, -1);
1551 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
1552 return -1;
1553 }
1554 return key_index;
1555 }
1556
1557 int k = _find(bst->blend_shapes, p_time);
1558 if (k < 0 || k >= bst->blend_shapes.size()) {
1559 return -1;
1560 }
1561 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(bst->blend_shapes[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && bst->blend_shapes[k].time != p_time)) {
1562 return -1;
1563 }
1564 return k;
1565
1566 } break;
1567 case TYPE_VALUE: {
1568 ValueTrack *vt = static_cast<ValueTrack *>(t);
1569 int k = _find(vt->values, p_time);
1570 if (k < 0 || k >= vt->values.size()) {
1571 return -1;
1572 }
1573 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(vt->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && vt->values[k].time != p_time)) {
1574 return -1;
1575 }
1576 return k;
1577
1578 } break;
1579 case TYPE_METHOD: {
1580 MethodTrack *mt = static_cast<MethodTrack *>(t);
1581 int k = _find(mt->methods, p_time);
1582 if (k < 0 || k >= mt->methods.size()) {
1583 return -1;
1584 }
1585 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(mt->methods[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && mt->methods[k].time != p_time)) {
1586 return -1;
1587 }
1588 return k;
1589
1590 } break;
1591 case TYPE_BEZIER: {
1592 BezierTrack *bt = static_cast<BezierTrack *>(t);
1593 int k = _find(bt->values, p_time);
1594 if (k < 0 || k >= bt->values.size()) {
1595 return -1;
1596 }
1597 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(bt->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && bt->values[k].time != p_time)) {
1598 return -1;
1599 }
1600 return k;
1601
1602 } break;
1603 case TYPE_AUDIO: {
1604 AudioTrack *at = static_cast<AudioTrack *>(t);
1605 int k = _find(at->values, p_time);
1606 if (k < 0 || k >= at->values.size()) {
1607 return -1;
1608 }
1609 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(at->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && at->values[k].time != p_time)) {
1610 return -1;
1611 }
1612 return k;
1613
1614 } break;
1615 case TYPE_ANIMATION: {
1616 AnimationTrack *at = static_cast<AnimationTrack *>(t);
1617 int k = _find(at->values, p_time);
1618 if (k < 0 || k >= at->values.size()) {
1619 return -1;
1620 }
1621 if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(at->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && at->values[k].time != p_time)) {
1622 return -1;
1623 }
1624 return k;
1625
1626 } break;
1627 }
1628
1629 return -1;
1630}
1631
1632int Animation::track_insert_key(int p_track, double p_time, const Variant &p_key, real_t p_transition) {
1633 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1634 Track *t = tracks[p_track];
1635
1636 int ret = -1;
1637
1638 switch (t->type) {
1639 case TYPE_POSITION_3D: {
1640 ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1);
1641 ret = position_track_insert_key(p_track, p_time, p_key);
1642 track_set_key_transition(p_track, ret, p_transition);
1643
1644 } break;
1645 case TYPE_ROTATION_3D: {
1646 ERR_FAIL_COND_V((p_key.get_type() != Variant::QUATERNION) && (p_key.get_type() != Variant::BASIS), -1);
1647 ret = rotation_track_insert_key(p_track, p_time, p_key);
1648 track_set_key_transition(p_track, ret, p_transition);
1649
1650 } break;
1651 case TYPE_SCALE_3D: {
1652 ERR_FAIL_COND_V((p_key.get_type() != Variant::VECTOR3) && (p_key.get_type() != Variant::VECTOR3I), -1);
1653 ret = scale_track_insert_key(p_track, p_time, p_key);
1654 track_set_key_transition(p_track, ret, p_transition);
1655
1656 } break;
1657 case TYPE_BLEND_SHAPE: {
1658 ERR_FAIL_COND_V((p_key.get_type() != Variant::FLOAT) && (p_key.get_type() != Variant::INT), -1);
1659 ret = blend_shape_track_insert_key(p_track, p_time, p_key);
1660 track_set_key_transition(p_track, ret, p_transition);
1661
1662 } break;
1663 case TYPE_VALUE: {
1664 ValueTrack *vt = static_cast<ValueTrack *>(t);
1665
1666 TKey<Variant> k;
1667 k.time = p_time;
1668 k.transition = p_transition;
1669 k.value = p_key;
1670 ret = _insert(p_time, vt->values, k);
1671
1672 } break;
1673 case TYPE_METHOD: {
1674 MethodTrack *mt = static_cast<MethodTrack *>(t);
1675
1676 ERR_FAIL_COND_V(p_key.get_type() != Variant::DICTIONARY, -1);
1677
1678 Dictionary d = p_key;
1679 ERR_FAIL_COND_V(!d.has("method") || (d["method"].get_type() != Variant::STRING_NAME && d["method"].get_type() != Variant::STRING), -1);
1680 ERR_FAIL_COND_V(!d.has("args") || !d["args"].is_array(), -1);
1681
1682 MethodKey k;
1683
1684 k.time = p_time;
1685 k.transition = p_transition;
1686 k.method = d["method"];
1687 k.params = d["args"];
1688
1689 ret = _insert(p_time, mt->methods, k);
1690
1691 } break;
1692 case TYPE_BEZIER: {
1693 BezierTrack *bt = static_cast<BezierTrack *>(t);
1694
1695 Array arr = p_key;
1696 ERR_FAIL_COND_V(arr.size() != 5, -1);
1697
1698 TKey<BezierKey> k;
1699 k.time = p_time;
1700 k.value.value = arr[0];
1701 k.value.in_handle.x = arr[1];
1702 k.value.in_handle.y = arr[2];
1703 k.value.out_handle.x = arr[3];
1704 k.value.out_handle.y = arr[4];
1705 ret = _insert(p_time, bt->values, k);
1706
1707 Vector<int> key_neighborhood;
1708 key_neighborhood.push_back(ret);
1709 if (ret > 0) {
1710 key_neighborhood.push_back(ret - 1);
1711 }
1712 if (ret < track_get_key_count(p_track) - 1) {
1713 key_neighborhood.push_back(ret + 1);
1714 }
1715 } break;
1716 case TYPE_AUDIO: {
1717 AudioTrack *at = static_cast<AudioTrack *>(t);
1718
1719 Dictionary k = p_key;
1720 ERR_FAIL_COND_V(!k.has("start_offset"), -1);
1721 ERR_FAIL_COND_V(!k.has("end_offset"), -1);
1722 ERR_FAIL_COND_V(!k.has("stream"), -1);
1723
1724 TKey<AudioKey> ak;
1725 ak.time = p_time;
1726 ak.value.start_offset = k["start_offset"];
1727 ak.value.end_offset = k["end_offset"];
1728 ak.value.stream = k["stream"];
1729 ret = _insert(p_time, at->values, ak);
1730
1731 } break;
1732 case TYPE_ANIMATION: {
1733 AnimationTrack *at = static_cast<AnimationTrack *>(t);
1734
1735 TKey<StringName> ak;
1736 ak.time = p_time;
1737 ak.value = p_key;
1738
1739 ret = _insert(p_time, at->values, ak);
1740
1741 } break;
1742 }
1743
1744 emit_changed();
1745
1746 return ret;
1747}
1748
1749int Animation::track_get_key_count(int p_track) const {
1750 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1751 Track *t = tracks[p_track];
1752
1753 switch (t->type) {
1754 case TYPE_POSITION_3D: {
1755 PositionTrack *tt = static_cast<PositionTrack *>(t);
1756 if (tt->compressed_track >= 0) {
1757 return _get_compressed_key_count(tt->compressed_track);
1758 }
1759 return tt->positions.size();
1760 } break;
1761 case TYPE_ROTATION_3D: {
1762 RotationTrack *rt = static_cast<RotationTrack *>(t);
1763 if (rt->compressed_track >= 0) {
1764 return _get_compressed_key_count(rt->compressed_track);
1765 }
1766 return rt->rotations.size();
1767 } break;
1768 case TYPE_SCALE_3D: {
1769 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1770 if (st->compressed_track >= 0) {
1771 return _get_compressed_key_count(st->compressed_track);
1772 }
1773 return st->scales.size();
1774 } break;
1775 case TYPE_BLEND_SHAPE: {
1776 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1777 if (bst->compressed_track >= 0) {
1778 return _get_compressed_key_count(bst->compressed_track);
1779 }
1780 return bst->blend_shapes.size();
1781 } break;
1782 case TYPE_VALUE: {
1783 ValueTrack *vt = static_cast<ValueTrack *>(t);
1784 return vt->values.size();
1785
1786 } break;
1787 case TYPE_METHOD: {
1788 MethodTrack *mt = static_cast<MethodTrack *>(t);
1789 return mt->methods.size();
1790 } break;
1791 case TYPE_BEZIER: {
1792 BezierTrack *bt = static_cast<BezierTrack *>(t);
1793 return bt->values.size();
1794 } break;
1795 case TYPE_AUDIO: {
1796 AudioTrack *at = static_cast<AudioTrack *>(t);
1797 return at->values.size();
1798 } break;
1799 case TYPE_ANIMATION: {
1800 AnimationTrack *at = static_cast<AnimationTrack *>(t);
1801 return at->values.size();
1802 } break;
1803 }
1804
1805 ERR_FAIL_V(-1);
1806}
1807
1808Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
1809 ERR_FAIL_INDEX_V(p_track, tracks.size(), Variant());
1810 Track *t = tracks[p_track];
1811
1812 switch (t->type) {
1813 case TYPE_POSITION_3D: {
1814 Vector3 value;
1815 position_track_get_key(p_track, p_key_idx, &value);
1816 return value;
1817 } break;
1818 case TYPE_ROTATION_3D: {
1819 Quaternion value;
1820 rotation_track_get_key(p_track, p_key_idx, &value);
1821 return value;
1822 } break;
1823 case TYPE_SCALE_3D: {
1824 Vector3 value;
1825 scale_track_get_key(p_track, p_key_idx, &value);
1826 return value;
1827 } break;
1828 case TYPE_BLEND_SHAPE: {
1829 float value;
1830 blend_shape_track_get_key(p_track, p_key_idx, &value);
1831 return value;
1832 } break;
1833 case TYPE_VALUE: {
1834 ValueTrack *vt = static_cast<ValueTrack *>(t);
1835 ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), Variant());
1836 return vt->values[p_key_idx].value;
1837
1838 } break;
1839 case TYPE_METHOD: {
1840 MethodTrack *mt = static_cast<MethodTrack *>(t);
1841 ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), Variant());
1842 Dictionary d;
1843 d["method"] = mt->methods[p_key_idx].method;
1844 d["args"] = mt->methods[p_key_idx].params;
1845 return d;
1846
1847 } break;
1848 case TYPE_BEZIER: {
1849 BezierTrack *bt = static_cast<BezierTrack *>(t);
1850 ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant());
1851
1852 Array arr;
1853 arr.resize(5);
1854 arr[0] = bt->values[p_key_idx].value.value;
1855 arr[1] = bt->values[p_key_idx].value.in_handle.x;
1856 arr[2] = bt->values[p_key_idx].value.in_handle.y;
1857 arr[3] = bt->values[p_key_idx].value.out_handle.x;
1858 arr[4] = bt->values[p_key_idx].value.out_handle.y;
1859 return arr;
1860
1861 } break;
1862 case TYPE_AUDIO: {
1863 AudioTrack *at = static_cast<AudioTrack *>(t);
1864 ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
1865
1866 Dictionary k;
1867 k["start_offset"] = at->values[p_key_idx].value.start_offset;
1868 k["end_offset"] = at->values[p_key_idx].value.end_offset;
1869 k["stream"] = at->values[p_key_idx].value.stream;
1870 return k;
1871
1872 } break;
1873 case TYPE_ANIMATION: {
1874 AnimationTrack *at = static_cast<AnimationTrack *>(t);
1875 ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
1876
1877 return at->values[p_key_idx].value;
1878
1879 } break;
1880 }
1881
1882 ERR_FAIL_V(Variant());
1883}
1884
1885double Animation::track_get_key_time(int p_track, int p_key_idx) const {
1886 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
1887 Track *t = tracks[p_track];
1888
1889 switch (t->type) {
1890 case TYPE_POSITION_3D: {
1891 PositionTrack *tt = static_cast<PositionTrack *>(t);
1892 if (tt->compressed_track >= 0) {
1893 Vector3i value;
1894 double time;
1895 bool fetch_compressed_success = _fetch_compressed_by_index<3>(tt->compressed_track, p_key_idx, value, time);
1896 ERR_FAIL_COND_V(!fetch_compressed_success, false);
1897 return time;
1898 }
1899 ERR_FAIL_INDEX_V(p_key_idx, tt->positions.size(), -1);
1900 return tt->positions[p_key_idx].time;
1901 } break;
1902 case TYPE_ROTATION_3D: {
1903 RotationTrack *rt = static_cast<RotationTrack *>(t);
1904 if (rt->compressed_track >= 0) {
1905 Vector3i value;
1906 double time;
1907 bool fetch_compressed_success = _fetch_compressed_by_index<3>(rt->compressed_track, p_key_idx, value, time);
1908 ERR_FAIL_COND_V(!fetch_compressed_success, false);
1909 return time;
1910 }
1911 ERR_FAIL_INDEX_V(p_key_idx, rt->rotations.size(), -1);
1912 return rt->rotations[p_key_idx].time;
1913 } break;
1914 case TYPE_SCALE_3D: {
1915 ScaleTrack *st = static_cast<ScaleTrack *>(t);
1916 if (st->compressed_track >= 0) {
1917 Vector3i value;
1918 double time;
1919 bool fetch_compressed_success = _fetch_compressed_by_index<3>(st->compressed_track, p_key_idx, value, time);
1920 ERR_FAIL_COND_V(!fetch_compressed_success, false);
1921 return time;
1922 }
1923 ERR_FAIL_INDEX_V(p_key_idx, st->scales.size(), -1);
1924 return st->scales[p_key_idx].time;
1925 } break;
1926 case TYPE_BLEND_SHAPE: {
1927 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
1928 if (bst->compressed_track >= 0) {
1929 Vector3i value;
1930 double time;
1931 bool fetch_compressed_success = _fetch_compressed_by_index<1>(bst->compressed_track, p_key_idx, value, time);
1932 ERR_FAIL_COND_V(!fetch_compressed_success, false);
1933 return time;
1934 }
1935 ERR_FAIL_INDEX_V(p_key_idx, bst->blend_shapes.size(), -1);
1936 return bst->blend_shapes[p_key_idx].time;
1937 } break;
1938 case TYPE_VALUE: {
1939 ValueTrack *vt = static_cast<ValueTrack *>(t);
1940 ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
1941 return vt->values[p_key_idx].time;
1942
1943 } break;
1944 case TYPE_METHOD: {
1945 MethodTrack *mt = static_cast<MethodTrack *>(t);
1946 ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
1947 return mt->methods[p_key_idx].time;
1948
1949 } break;
1950 case TYPE_BEZIER: {
1951 BezierTrack *bt = static_cast<BezierTrack *>(t);
1952 ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), -1);
1953 return bt->values[p_key_idx].time;
1954
1955 } break;
1956 case TYPE_AUDIO: {
1957 AudioTrack *at = static_cast<AudioTrack *>(t);
1958 ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
1959 return at->values[p_key_idx].time;
1960
1961 } break;
1962 case TYPE_ANIMATION: {
1963 AnimationTrack *at = static_cast<AnimationTrack *>(t);
1964 ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
1965 return at->values[p_key_idx].time;
1966
1967 } break;
1968 }
1969
1970 ERR_FAIL_V(-1);
1971}
1972
1973void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) {
1974 ERR_FAIL_INDEX(p_track, tracks.size());
1975 Track *t = tracks[p_track];
1976
1977 switch (t->type) {
1978 case TYPE_POSITION_3D: {
1979 PositionTrack *tt = static_cast<PositionTrack *>(t);
1980 ERR_FAIL_COND(tt->compressed_track >= 0);
1981 ERR_FAIL_INDEX(p_key_idx, tt->positions.size());
1982 TKey<Vector3> key = tt->positions[p_key_idx];
1983 key.time = p_time;
1984 tt->positions.remove_at(p_key_idx);
1985 _insert(p_time, tt->positions, key);
1986 return;
1987 }
1988 case TYPE_ROTATION_3D: {
1989 RotationTrack *tt = static_cast<RotationTrack *>(t);
1990 ERR_FAIL_COND(tt->compressed_track >= 0);
1991 ERR_FAIL_INDEX(p_key_idx, tt->rotations.size());
1992 TKey<Quaternion> key = tt->rotations[p_key_idx];
1993 key.time = p_time;
1994 tt->rotations.remove_at(p_key_idx);
1995 _insert(p_time, tt->rotations, key);
1996 return;
1997 }
1998 case TYPE_SCALE_3D: {
1999 ScaleTrack *tt = static_cast<ScaleTrack *>(t);
2000 ERR_FAIL_COND(tt->compressed_track >= 0);
2001 ERR_FAIL_INDEX(p_key_idx, tt->scales.size());
2002 TKey<Vector3> key = tt->scales[p_key_idx];
2003 key.time = p_time;
2004 tt->scales.remove_at(p_key_idx);
2005 _insert(p_time, tt->scales, key);
2006 return;
2007 }
2008 case TYPE_BLEND_SHAPE: {
2009 BlendShapeTrack *tt = static_cast<BlendShapeTrack *>(t);
2010 ERR_FAIL_COND(tt->compressed_track >= 0);
2011 ERR_FAIL_INDEX(p_key_idx, tt->blend_shapes.size());
2012 TKey<float> key = tt->blend_shapes[p_key_idx];
2013 key.time = p_time;
2014 tt->blend_shapes.remove_at(p_key_idx);
2015 _insert(p_time, tt->blend_shapes, key);
2016 return;
2017 }
2018 case TYPE_VALUE: {
2019 ValueTrack *vt = static_cast<ValueTrack *>(t);
2020 ERR_FAIL_INDEX(p_key_idx, vt->values.size());
2021 TKey<Variant> key = vt->values[p_key_idx];
2022 key.time = p_time;
2023 vt->values.remove_at(p_key_idx);
2024 _insert(p_time, vt->values, key);
2025 return;
2026 }
2027 case TYPE_METHOD: {
2028 MethodTrack *mt = static_cast<MethodTrack *>(t);
2029 ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
2030 MethodKey key = mt->methods[p_key_idx];
2031 key.time = p_time;
2032 mt->methods.remove_at(p_key_idx);
2033 _insert(p_time, mt->methods, key);
2034 return;
2035 }
2036 case TYPE_BEZIER: {
2037 BezierTrack *bt = static_cast<BezierTrack *>(t);
2038 ERR_FAIL_INDEX(p_key_idx, bt->values.size());
2039 TKey<BezierKey> key = bt->values[p_key_idx];
2040 key.time = p_time;
2041 bt->values.remove_at(p_key_idx);
2042 _insert(p_time, bt->values, key);
2043 return;
2044 }
2045 case TYPE_AUDIO: {
2046 AudioTrack *at = static_cast<AudioTrack *>(t);
2047 ERR_FAIL_INDEX(p_key_idx, at->values.size());
2048 TKey<AudioKey> key = at->values[p_key_idx];
2049 key.time = p_time;
2050 at->values.remove_at(p_key_idx);
2051 _insert(p_time, at->values, key);
2052 return;
2053 }
2054 case TYPE_ANIMATION: {
2055 AnimationTrack *at = static_cast<AnimationTrack *>(t);
2056 ERR_FAIL_INDEX(p_key_idx, at->values.size());
2057 TKey<StringName> key = at->values[p_key_idx];
2058 key.time = p_time;
2059 at->values.remove_at(p_key_idx);
2060 _insert(p_time, at->values, key);
2061 return;
2062 }
2063 }
2064
2065 ERR_FAIL();
2066}
2067
2068real_t Animation::track_get_key_transition(int p_track, int p_key_idx) const {
2069 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
2070 Track *t = tracks[p_track];
2071
2072 switch (t->type) {
2073 case TYPE_POSITION_3D: {
2074 PositionTrack *tt = static_cast<PositionTrack *>(t);
2075 if (tt->compressed_track >= 0) {
2076 return 1.0;
2077 }
2078 ERR_FAIL_INDEX_V(p_key_idx, tt->positions.size(), -1);
2079 return tt->positions[p_key_idx].transition;
2080 } break;
2081 case TYPE_ROTATION_3D: {
2082 RotationTrack *rt = static_cast<RotationTrack *>(t);
2083 if (rt->compressed_track >= 0) {
2084 return 1.0;
2085 }
2086 ERR_FAIL_INDEX_V(p_key_idx, rt->rotations.size(), -1);
2087 return rt->rotations[p_key_idx].transition;
2088 } break;
2089 case TYPE_SCALE_3D: {
2090 ScaleTrack *st = static_cast<ScaleTrack *>(t);
2091 if (st->compressed_track >= 0) {
2092 return 1.0;
2093 }
2094 ERR_FAIL_INDEX_V(p_key_idx, st->scales.size(), -1);
2095 return st->scales[p_key_idx].transition;
2096 } break;
2097 case TYPE_BLEND_SHAPE: {
2098 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
2099 if (bst->compressed_track >= 0) {
2100 return 1.0;
2101 }
2102 ERR_FAIL_INDEX_V(p_key_idx, bst->blend_shapes.size(), -1);
2103 return bst->blend_shapes[p_key_idx].transition;
2104 } break;
2105 case TYPE_VALUE: {
2106 ValueTrack *vt = static_cast<ValueTrack *>(t);
2107 ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
2108 return vt->values[p_key_idx].transition;
2109
2110 } break;
2111 case TYPE_METHOD: {
2112 MethodTrack *mt = static_cast<MethodTrack *>(t);
2113 ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
2114 return mt->methods[p_key_idx].transition;
2115
2116 } break;
2117 case TYPE_BEZIER: {
2118 return 1; //bezier does not really use transitions
2119 } break;
2120 case TYPE_AUDIO: {
2121 return 1; //audio does not really use transitions
2122 } break;
2123 case TYPE_ANIMATION: {
2124 return 1; //animation does not really use transitions
2125 } break;
2126 }
2127
2128 ERR_FAIL_V(0);
2129}
2130
2131bool Animation::track_is_compressed(int p_track) const {
2132 ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
2133 Track *t = tracks[p_track];
2134
2135 switch (t->type) {
2136 case TYPE_POSITION_3D: {
2137 PositionTrack *tt = static_cast<PositionTrack *>(t);
2138 return tt->compressed_track >= 0;
2139 } break;
2140 case TYPE_ROTATION_3D: {
2141 RotationTrack *rt = static_cast<RotationTrack *>(t);
2142 return rt->compressed_track >= 0;
2143 } break;
2144 case TYPE_SCALE_3D: {
2145 ScaleTrack *st = static_cast<ScaleTrack *>(t);
2146 return st->compressed_track >= 0;
2147 } break;
2148 case TYPE_BLEND_SHAPE: {
2149 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
2150 return bst->compressed_track >= 0;
2151 } break;
2152 default: {
2153 return false; // Animation does not really use transitions.
2154 } break;
2155 }
2156}
2157
2158void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p_value) {
2159 ERR_FAIL_INDEX(p_track, tracks.size());
2160 Track *t = tracks[p_track];
2161
2162 switch (t->type) {
2163 case TYPE_POSITION_3D: {
2164 ERR_FAIL_COND((p_value.get_type() != Variant::VECTOR3) && (p_value.get_type() != Variant::VECTOR3I));
2165 PositionTrack *tt = static_cast<PositionTrack *>(t);
2166 ERR_FAIL_COND(tt->compressed_track >= 0);
2167 ERR_FAIL_INDEX(p_key_idx, tt->positions.size());
2168
2169 tt->positions.write[p_key_idx].value = p_value;
2170
2171 } break;
2172 case TYPE_ROTATION_3D: {
2173 ERR_FAIL_COND((p_value.get_type() != Variant::QUATERNION) && (p_value.get_type() != Variant::BASIS));
2174 RotationTrack *rt = static_cast<RotationTrack *>(t);
2175 ERR_FAIL_COND(rt->compressed_track >= 0);
2176 ERR_FAIL_INDEX(p_key_idx, rt->rotations.size());
2177
2178 rt->rotations.write[p_key_idx].value = p_value;
2179
2180 } break;
2181 case TYPE_SCALE_3D: {
2182 ERR_FAIL_COND((p_value.get_type() != Variant::VECTOR3) && (p_value.get_type() != Variant::VECTOR3I));
2183 ScaleTrack *st = static_cast<ScaleTrack *>(t);
2184 ERR_FAIL_COND(st->compressed_track >= 0);
2185 ERR_FAIL_INDEX(p_key_idx, st->scales.size());
2186
2187 st->scales.write[p_key_idx].value = p_value;
2188
2189 } break;
2190 case TYPE_BLEND_SHAPE: {
2191 ERR_FAIL_COND((p_value.get_type() != Variant::FLOAT) && (p_value.get_type() != Variant::INT));
2192 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
2193 ERR_FAIL_COND(bst->compressed_track >= 0);
2194 ERR_FAIL_INDEX(p_key_idx, bst->blend_shapes.size());
2195
2196 bst->blend_shapes.write[p_key_idx].value = p_value;
2197
2198 } break;
2199 case TYPE_VALUE: {
2200 ValueTrack *vt = static_cast<ValueTrack *>(t);
2201 ERR_FAIL_INDEX(p_key_idx, vt->values.size());
2202
2203 vt->values.write[p_key_idx].value = p_value;
2204
2205 } break;
2206 case TYPE_METHOD: {
2207 MethodTrack *mt = static_cast<MethodTrack *>(t);
2208 ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
2209
2210 Dictionary d = p_value;
2211
2212 if (d.has("method")) {
2213 mt->methods.write[p_key_idx].method = d["method"];
2214 }
2215 if (d.has("args")) {
2216 mt->methods.write[p_key_idx].params = d["args"];
2217 }
2218
2219 } break;
2220 case TYPE_BEZIER: {
2221 BezierTrack *bt = static_cast<BezierTrack *>(t);
2222 ERR_FAIL_INDEX(p_key_idx, bt->values.size());
2223
2224 Array arr = p_value;
2225 ERR_FAIL_COND(arr.size() != 5);
2226
2227 bt->values.write[p_key_idx].value.value = arr[0];
2228 bt->values.write[p_key_idx].value.in_handle.x = arr[1];
2229 bt->values.write[p_key_idx].value.in_handle.y = arr[2];
2230 bt->values.write[p_key_idx].value.out_handle.x = arr[3];
2231 bt->values.write[p_key_idx].value.out_handle.y = arr[4];
2232
2233 } break;
2234 case TYPE_AUDIO: {
2235 AudioTrack *at = static_cast<AudioTrack *>(t);
2236 ERR_FAIL_INDEX(p_key_idx, at->values.size());
2237
2238 Dictionary k = p_value;
2239 ERR_FAIL_COND(!k.has("start_offset"));
2240 ERR_FAIL_COND(!k.has("end_offset"));
2241 ERR_FAIL_COND(!k.has("stream"));
2242
2243 at->values.write[p_key_idx].value.start_offset = k["start_offset"];
2244 at->values.write[p_key_idx].value.end_offset = k["end_offset"];
2245 at->values.write[p_key_idx].value.stream = k["stream"];
2246
2247 } break;
2248 case TYPE_ANIMATION: {
2249 AnimationTrack *at = static_cast<AnimationTrack *>(t);
2250 ERR_FAIL_INDEX(p_key_idx, at->values.size());
2251
2252 at->values.write[p_key_idx].value = p_value;
2253
2254 } break;
2255 }
2256
2257 emit_changed();
2258}
2259
2260void Animation::track_set_key_transition(int p_track, int p_key_idx, real_t p_transition) {
2261 ERR_FAIL_INDEX(p_track, tracks.size());
2262 Track *t = tracks[p_track];
2263
2264 switch (t->type) {
2265 case TYPE_POSITION_3D: {
2266 PositionTrack *tt = static_cast<PositionTrack *>(t);
2267 ERR_FAIL_COND(tt->compressed_track >= 0);
2268 ERR_FAIL_INDEX(p_key_idx, tt->positions.size());
2269 tt->positions.write[p_key_idx].transition = p_transition;
2270 } break;
2271 case TYPE_ROTATION_3D: {
2272 RotationTrack *rt = static_cast<RotationTrack *>(t);
2273 ERR_FAIL_COND(rt->compressed_track >= 0);
2274 ERR_FAIL_INDEX(p_key_idx, rt->rotations.size());
2275 rt->rotations.write[p_key_idx].transition = p_transition;
2276 } break;
2277 case TYPE_SCALE_3D: {
2278 ScaleTrack *st = static_cast<ScaleTrack *>(t);
2279 ERR_FAIL_COND(st->compressed_track >= 0);
2280 ERR_FAIL_INDEX(p_key_idx, st->scales.size());
2281 st->scales.write[p_key_idx].transition = p_transition;
2282 } break;
2283 case TYPE_BLEND_SHAPE: {
2284 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
2285 ERR_FAIL_COND(bst->compressed_track >= 0);
2286 ERR_FAIL_INDEX(p_key_idx, bst->blend_shapes.size());
2287 bst->blend_shapes.write[p_key_idx].transition = p_transition;
2288 } break;
2289 case TYPE_VALUE: {
2290 ValueTrack *vt = static_cast<ValueTrack *>(t);
2291 ERR_FAIL_INDEX(p_key_idx, vt->values.size());
2292 vt->values.write[p_key_idx].transition = p_transition;
2293
2294 } break;
2295 case TYPE_METHOD: {
2296 MethodTrack *mt = static_cast<MethodTrack *>(t);
2297 ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
2298 mt->methods.write[p_key_idx].transition = p_transition;
2299
2300 } break;
2301 case TYPE_BEZIER:
2302 case TYPE_AUDIO:
2303 case TYPE_ANIMATION: {
2304 // they don't use transition
2305 } break;
2306 }
2307
2308 emit_changed();
2309}
2310
2311template <class K>
2312int Animation::_find(const Vector<K> &p_keys, double p_time, bool p_backward) const {
2313 int len = p_keys.size();
2314 if (len == 0) {
2315 return -2;
2316 }
2317
2318 int low = 0;
2319 int high = len - 1;
2320 int middle = 0;
2321
2322#ifdef DEBUG_ENABLED
2323 if (low > high) {
2324 ERR_PRINT("low > high, this may be a bug");
2325 }
2326#endif
2327
2328 const K *keys = &p_keys[0];
2329
2330 while (low <= high) {
2331 middle = (low + high) / 2;
2332
2333 if (Math::is_equal_approx(p_time, (double)keys[middle].time)) { //match
2334 return middle;
2335 } else if (p_time < keys[middle].time) {
2336 high = middle - 1; //search low end of array
2337 } else {
2338 low = middle + 1; //search high end of array
2339 }
2340 }
2341
2342 if (!p_backward) {
2343 if (keys[middle].time > p_time) {
2344 middle--;
2345 }
2346 } else {
2347 if (keys[middle].time < p_time) {
2348 middle++;
2349 }
2350 }
2351
2352 return middle;
2353}
2354
2355// Linear interpolation for anytype.
2356
2357Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, real_t p_c) const {
2358 return p_a.lerp(p_b, p_c);
2359}
2360
2361Quaternion Animation::_interpolate(const Quaternion &p_a, const Quaternion &p_b, real_t p_c) const {
2362 return p_a.slerp(p_b, p_c);
2363}
2364
2365Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const {
2366 return interpolate_variant(p_a, p_b, p_c);
2367}
2368
2369real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const {
2370 return Math::lerp(p_a, p_b, p_c);
2371}
2372
2373Variant Animation::_interpolate_angle(const Variant &p_a, const Variant &p_b, real_t p_c) const {
2374 Variant::Type type_a = p_a.get_type();
2375 Variant::Type type_b = p_b.get_type();
2376 uint32_t vformat = 1 << type_a;
2377 vformat |= 1 << type_b;
2378 if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) {
2379 real_t a = p_a;
2380 real_t b = p_b;
2381 return Math::fposmod((float)Math::lerp_angle(a, b, p_c), (float)Math_TAU);
2382 }
2383 return _interpolate(p_a, p_b, p_c);
2384}
2385
2386// Cubic interpolation for anytype.
2387
2388Vector3 Animation::_cubic_interpolate_in_time(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const {
2389 return p_a.cubic_interpolate_in_time(p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2390}
2391
2392Quaternion Animation::_cubic_interpolate_in_time(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const {
2393 return p_a.spherical_cubic_interpolate_in_time(p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2394}
2395
2396Variant Animation::_cubic_interpolate_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const {
2397 Variant::Type type_a = p_a.get_type();
2398 Variant::Type type_b = p_b.get_type();
2399 Variant::Type type_pa = p_pre_a.get_type();
2400 Variant::Type type_pb = p_post_b.get_type();
2401
2402 //make int and real play along
2403
2404 uint32_t vformat = 1 << type_a;
2405 vformat |= 1 << type_b;
2406 vformat |= 1 << type_pa;
2407 vformat |= 1 << type_pb;
2408
2409 if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) {
2410 //mix of real and int
2411 real_t a = p_a;
2412 real_t b = p_b;
2413 real_t pa = p_pre_a;
2414 real_t pb = p_post_b;
2415
2416 return Math::cubic_interpolate_in_time(a, b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2417 } else if ((vformat & (vformat - 1))) {
2418 return p_a; //can't interpolate, mix of types
2419 }
2420
2421 switch (type_a) {
2422 case Variant::VECTOR2: {
2423 Vector2 a = p_a;
2424 Vector2 b = p_b;
2425 Vector2 pa = p_pre_a;
2426 Vector2 pb = p_post_b;
2427
2428 return a.cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2429 }
2430 case Variant::RECT2: {
2431 Rect2 a = p_a;
2432 Rect2 b = p_b;
2433 Rect2 pa = p_pre_a;
2434 Rect2 pb = p_post_b;
2435
2436 return Rect2(
2437 a.position.cubic_interpolate_in_time(b.position, pa.position, pb.position, p_c, p_b_t, p_pre_a_t, p_post_b_t),
2438 a.size.cubic_interpolate_in_time(b.size, pa.size, pb.size, p_c, p_b_t, p_pre_a_t, p_post_b_t));
2439 }
2440 case Variant::VECTOR3: {
2441 Vector3 a = p_a;
2442 Vector3 b = p_b;
2443 Vector3 pa = p_pre_a;
2444 Vector3 pb = p_post_b;
2445
2446 return a.cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2447 }
2448 case Variant::QUATERNION: {
2449 Quaternion a = p_a;
2450 Quaternion b = p_b;
2451 Quaternion pa = p_pre_a;
2452 Quaternion pb = p_post_b;
2453
2454 return a.spherical_cubic_interpolate_in_time(b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2455 }
2456 case Variant::AABB: {
2457 AABB a = p_a;
2458 AABB b = p_b;
2459 AABB pa = p_pre_a;
2460 AABB pb = p_post_b;
2461
2462 return AABB(
2463 a.position.cubic_interpolate_in_time(b.position, pa.position, pb.position, p_c, p_b_t, p_pre_a_t, p_post_b_t),
2464 a.size.cubic_interpolate_in_time(b.size, pa.size, pb.size, p_c, p_b_t, p_pre_a_t, p_post_b_t));
2465 }
2466 default: {
2467 return _interpolate(p_a, p_b, p_c);
2468 }
2469 }
2470}
2471
2472real_t Animation::_cubic_interpolate_in_time(const real_t &p_pre_a, const real_t &p_a, const real_t &p_b, const real_t &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const {
2473 return Math::cubic_interpolate_in_time(p_a, p_b, p_pre_a, p_post_b, p_c, p_b_t, p_pre_a_t, p_post_b_t);
2474}
2475
2476Variant Animation::_cubic_interpolate_angle_in_time(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c, real_t p_pre_a_t, real_t p_b_t, real_t p_post_b_t) const {
2477 Variant::Type type_a = p_a.get_type();
2478 Variant::Type type_b = p_b.get_type();
2479 Variant::Type type_pa = p_pre_a.get_type();
2480 Variant::Type type_pb = p_post_b.get_type();
2481 uint32_t vformat = 1 << type_a;
2482 vformat |= 1 << type_b;
2483 vformat |= 1 << type_pa;
2484 vformat |= 1 << type_pb;
2485 if (vformat == ((1 << Variant::INT) | (1 << Variant::FLOAT)) || vformat == (1 << Variant::FLOAT)) {
2486 real_t a = p_a;
2487 real_t b = p_b;
2488 real_t pa = p_pre_a;
2489 real_t pb = p_post_b;
2490 return Math::fposmod((float)Math::cubic_interpolate_angle_in_time(a, b, pa, pb, p_c, p_b_t, p_pre_a_t, p_post_b_t), (float)Math_TAU);
2491 }
2492 return _interpolate(p_a, p_b, p_c);
2493}
2494
2495template <class T>
2496T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok, bool p_backward) const {
2497 int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end)
2498
2499 if (len <= 0) {
2500 // (-1 or -2 returned originally) (plus one above)
2501 // meaning no keys, or only key time is larger than length
2502 if (p_ok) {
2503 *p_ok = false;
2504 }
2505 return T();
2506 } else if (len == 1) { // one key found (0+1), return it
2507
2508 if (p_ok) {
2509 *p_ok = true;
2510 }
2511 return p_keys[0].value;
2512 }
2513
2514 int idx = _find(p_keys, p_time, p_backward);
2515
2516 ERR_FAIL_COND_V(idx == -2, T());
2517 int maxi = len - 1;
2518 bool is_start_edge = idx == -1;
2519 bool is_end_edge = p_backward ? idx == 0 : idx >= maxi;
2520
2521 real_t c = 0.0;
2522 // Prepare for all cases of interpolation.
2523 real_t delta = 0.0;
2524 real_t from = 0.0;
2525
2526 int pre = -1;
2527 int next = -1;
2528 int post = -1;
2529 real_t pre_t = 0.0;
2530 real_t to_t = 0.0;
2531 real_t post_t = 0.0;
2532
2533 bool use_cubic = p_interp == INTERPOLATION_CUBIC || p_interp == INTERPOLATION_CUBIC_ANGLE;
2534
2535 if (!p_loop_wrap || loop_mode == LOOP_NONE) {
2536 if (is_start_edge) {
2537 idx = p_backward ? maxi : 0;
2538 }
2539 next = CLAMP(idx + (p_backward ? -1 : 1), 0, maxi);
2540 if (use_cubic) {
2541 pre = CLAMP(idx + (p_backward ? 1 : -1), 0, maxi);
2542 post = CLAMP(idx + (p_backward ? -2 : 2), 0, maxi);
2543 }
2544 } else if (loop_mode == LOOP_LINEAR) {
2545 if (is_start_edge) {
2546 idx = p_backward ? 0 : maxi;
2547 }
2548 next = Math::posmod(idx + (p_backward ? -1 : 1), len);
2549 if (use_cubic) {
2550 pre = Math::posmod(idx + (p_backward ? 1 : -1), len);
2551 post = Math::posmod(idx + (p_backward ? -2 : 2), len);
2552 }
2553 if (is_start_edge) {
2554 if (!p_backward) {
2555 real_t endtime = (length - p_keys[idx].time);
2556 if (endtime < 0) { // may be keys past the end
2557 endtime = 0;
2558 }
2559 delta = endtime + p_keys[next].time;
2560 from = endtime + p_time;
2561 } else {
2562 real_t endtime = p_keys[idx].time;
2563 if (endtime > length) { // may be keys past the end
2564 endtime = length;
2565 }
2566 delta = endtime + length - p_keys[next].time;
2567 from = endtime + length - p_time;
2568 }
2569 } else if (is_end_edge) {
2570 if (!p_backward) {
2571 delta = (length - p_keys[idx].time) + p_keys[next].time;
2572 from = p_time - p_keys[idx].time;
2573 } else {
2574 delta = p_keys[idx].time + (length - p_keys[next].time);
2575 from = (length - p_time) - (length - p_keys[idx].time);
2576 }
2577 }
2578 } else {
2579 if (is_start_edge) {
2580 idx = p_backward ? len : -1;
2581 }
2582 next = (int)Math::round(Math::pingpong((float)(idx + (p_backward ? -1 : 1)) + 0.5f, (float)len) - 0.5f);
2583 if (use_cubic) {
2584 pre = (int)Math::round(Math::pingpong((float)(idx + (p_backward ? 1 : -1)) + 0.5f, (float)len) - 0.5f);
2585 post = (int)Math::round(Math::pingpong((float)(idx + (p_backward ? -2 : 2)) + 0.5f, (float)len) - 0.5f);
2586 }
2587 idx = (int)Math::round(Math::pingpong((float)idx + 0.5f, (float)len) - 0.5f);
2588 if (is_start_edge) {
2589 if (!p_backward) {
2590 real_t endtime = p_keys[idx].time;
2591 if (endtime < 0) { // may be keys past the end
2592 endtime = 0;
2593 }
2594 delta = endtime + p_keys[next].time;
2595 from = endtime + p_time;
2596 } else {
2597 real_t endtime = length - p_keys[idx].time;
2598 if (endtime > length) { // may be keys past the end
2599 endtime = length;
2600 }
2601 delta = endtime + length - p_keys[next].time;
2602 from = endtime + length - p_time;
2603 }
2604 } else if (is_end_edge) {
2605 if (!p_backward) {
2606 delta = length * 2.0 - p_keys[idx].time - p_keys[next].time;
2607 from = p_time - p_keys[idx].time;
2608 } else {
2609 delta = p_keys[idx].time + p_keys[next].time;
2610 from = (length - p_time) - (length - p_keys[idx].time);
2611 }
2612 }
2613 }
2614
2615 if (!is_start_edge && !is_end_edge) {
2616 if (!p_backward) {
2617 delta = p_keys[next].time - p_keys[idx].time;
2618 from = p_time - p_keys[idx].time;
2619 } else {
2620 delta = (length - p_keys[next].time) - (length - p_keys[idx].time);
2621 from = (length - p_time) - (length - p_keys[idx].time);
2622 }
2623 }
2624
2625 if (Math::is_zero_approx(delta)) {
2626 c = 0;
2627 } else {
2628 c = from / delta;
2629 }
2630
2631 if (p_ok) {
2632 *p_ok = true;
2633 }
2634
2635 real_t tr = p_keys[idx].transition;
2636 if (tr == 0) {
2637 // Don't interpolate if not needed.
2638 return p_keys[idx].value;
2639 }
2640
2641 if (tr != 1.0) {
2642 c = Math::ease(c, tr);
2643 }
2644
2645 switch (p_interp) {
2646 case INTERPOLATION_NEAREST: {
2647 return p_keys[idx].value;
2648 } break;
2649 case INTERPOLATION_LINEAR: {
2650 return _interpolate(p_keys[idx].value, p_keys[next].value, c);
2651 } break;
2652 case INTERPOLATION_LINEAR_ANGLE: {
2653 return _interpolate_angle(p_keys[idx].value, p_keys[next].value, c);
2654 } break;
2655 case INTERPOLATION_CUBIC:
2656 case INTERPOLATION_CUBIC_ANGLE: {
2657 if (!p_loop_wrap || loop_mode == LOOP_NONE) {
2658 pre_t = p_keys[pre].time - p_keys[idx].time;
2659 to_t = p_keys[next].time - p_keys[idx].time;
2660 post_t = p_keys[post].time - p_keys[idx].time;
2661 } else if (loop_mode == LOOP_LINEAR) {
2662 pre_t = pre > idx ? -length + p_keys[pre].time - p_keys[idx].time : p_keys[pre].time - p_keys[idx].time;
2663 to_t = next < idx ? length + p_keys[next].time - p_keys[idx].time : p_keys[next].time - p_keys[idx].time;
2664 post_t = next < idx || post <= idx ? length + p_keys[post].time - p_keys[idx].time : p_keys[post].time - p_keys[idx].time;
2665 } else {
2666 pre_t = p_keys[pre].time - p_keys[idx].time;
2667 to_t = p_keys[next].time - p_keys[idx].time;
2668 post_t = p_keys[post].time - p_keys[idx].time;
2669
2670 if ((pre > idx && idx == next && post < next) || (pre < idx && idx == next && post > next)) {
2671 pre_t = p_keys[idx].time - p_keys[pre].time;
2672 } else if (pre == idx) {
2673 pre_t = idx < next ? -p_keys[idx].time * 2.0 : (length - p_keys[idx].time) * 2.0;
2674 }
2675
2676 if (idx == next) {
2677 to_t = pre < idx ? (length - p_keys[idx].time) * 2.0 : -p_keys[idx].time * 2.0;
2678 post_t = p_keys[next].time - p_keys[post].time + to_t;
2679 } else if (next == post) {
2680 post_t = idx < next ? (length - p_keys[next].time) * 2.0 + to_t : -p_keys[next].time * 2.0 + to_t;
2681 }
2682 }
2683
2684 if (p_interp == INTERPOLATION_CUBIC_ANGLE) {
2685 return _cubic_interpolate_angle_in_time(
2686 p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c,
2687 pre_t, to_t, post_t);
2688 }
2689 return _cubic_interpolate_in_time(
2690 p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c,
2691 pre_t, to_t, post_t);
2692 } break;
2693 default:
2694 return p_keys[idx].value;
2695 }
2696
2697 // do a barrel roll
2698}
2699
2700Variant Animation::value_track_interpolate(int p_track, double p_time) const {
2701 ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
2702 Track *t = tracks[p_track];
2703 ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant());
2704 ValueTrack *vt = static_cast<ValueTrack *>(t);
2705
2706 bool ok = false;
2707
2708 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);
2709
2710 if (ok) {
2711 return res;
2712 }
2713
2714 return Variant();
2715}
2716
2717void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
2718 ERR_FAIL_INDEX(p_track, tracks.size());
2719 Track *t = tracks[p_track];
2720 ERR_FAIL_COND(t->type != TYPE_VALUE);
2721 ERR_FAIL_INDEX((int)p_mode, 3);
2722
2723 ValueTrack *vt = static_cast<ValueTrack *>(t);
2724 vt->update_mode = p_mode;
2725 emit_changed();
2726}
2727
2728Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
2729 ERR_FAIL_INDEX_V(p_track, tracks.size(), UPDATE_CONTINUOUS);
2730 Track *t = tracks[p_track];
2731 ERR_FAIL_COND_V(t->type != TYPE_VALUE, UPDATE_CONTINUOUS);
2732
2733 ValueTrack *vt = static_cast<ValueTrack *>(t);
2734 return vt->update_mode;
2735}
2736
2737template <class T>
2738void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices, bool p_is_backward) const {
2739 int len = p_array.size();
2740 if (len == 0) {
2741 return;
2742 }
2743
2744 int from = 0;
2745 int to = len - 1;
2746
2747 if (!p_is_backward) {
2748 while (p_array[from].time < from_time || Math::is_equal_approx(p_array[from].time, from_time)) {
2749 from++;
2750 if (to < from) {
2751 return;
2752 }
2753 }
2754 while (p_array[to].time > to_time && !Math::is_equal_approx(p_array[to].time, to_time)) {
2755 to--;
2756 if (to < from) {
2757 return;
2758 }
2759 }
2760 } else {
2761 while (p_array[from].time < from_time && !Math::is_equal_approx(p_array[from].time, from_time)) {
2762 from++;
2763 if (to < from) {
2764 return;
2765 }
2766 }
2767 while (p_array[to].time > to_time || Math::is_equal_approx(p_array[to].time, to_time)) {
2768 to--;
2769 if (to < from) {
2770 return;
2771 }
2772 }
2773 }
2774
2775 if (from == to) {
2776 p_indices->push_back(from);
2777 return;
2778 }
2779
2780 if (!p_is_backward) {
2781 for (int i = from; i <= to; i++) {
2782 p_indices->push_back(i);
2783 }
2784 } else {
2785 for (int i = to; i >= from; i--) {
2786 p_indices->push_back(i);
2787 }
2788 }
2789}
2790
2791void Animation::track_get_key_indices_in_range(int p_track, double p_time, double p_delta, List<int> *p_indices, Animation::LoopedFlag p_looped_flag) const {
2792 ERR_FAIL_INDEX(p_track, tracks.size());
2793
2794 if (p_delta == 0) {
2795 return; // Prevent to get key continuously.
2796 }
2797
2798 const Track *t = tracks[p_track];
2799
2800 double from_time = p_time - p_delta;
2801 double to_time = p_time;
2802
2803 bool is_backward = false;
2804 if (from_time > to_time) {
2805 is_backward = true;
2806 SWAP(from_time, to_time);
2807 }
2808
2809 switch (loop_mode) {
2810 case LOOP_NONE: {
2811 if (from_time < 0) {
2812 from_time = 0;
2813 }
2814 if (from_time > length) {
2815 from_time = length;
2816 }
2817
2818 if (to_time < 0) {
2819 to_time = 0;
2820 }
2821 if (to_time > length) {
2822 to_time = length;
2823 }
2824 } break;
2825 case LOOP_LINEAR: {
2826 if (from_time > length || from_time < 0) {
2827 from_time = Math::fposmod(from_time, length);
2828 }
2829 if (to_time > length || to_time < 0) {
2830 to_time = Math::fposmod(to_time, length);
2831 }
2832
2833 if (from_time > to_time) {
2834 // Handle loop by splitting.
2835 double anim_end = length + CMP_EPSILON;
2836 double anim_start = -CMP_EPSILON;
2837
2838 switch (t->type) {
2839 case TYPE_POSITION_3D: {
2840 const PositionTrack *tt = static_cast<const PositionTrack *>(t);
2841 if (tt->compressed_track >= 0) {
2842 _get_compressed_key_indices_in_range<3>(tt->compressed_track, from_time, length, p_indices);
2843 _get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, to_time, p_indices);
2844 } else {
2845 if (!is_backward) {
2846 _track_get_key_indices_in_range(tt->positions, from_time, anim_end, p_indices, is_backward);
2847 _track_get_key_indices_in_range(tt->positions, anim_start, to_time, p_indices, is_backward);
2848 } else {
2849 _track_get_key_indices_in_range(tt->positions, anim_start, to_time, p_indices, is_backward);
2850 _track_get_key_indices_in_range(tt->positions, from_time, anim_end, p_indices, is_backward);
2851 }
2852 }
2853 } break;
2854 case TYPE_ROTATION_3D: {
2855 const RotationTrack *rt = static_cast<const RotationTrack *>(t);
2856 if (rt->compressed_track >= 0) {
2857 _get_compressed_key_indices_in_range<3>(rt->compressed_track, from_time, length, p_indices);
2858 _get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, to_time, p_indices);
2859 } else {
2860 if (!is_backward) {
2861 _track_get_key_indices_in_range(rt->rotations, from_time, anim_end, p_indices, is_backward);
2862 _track_get_key_indices_in_range(rt->rotations, anim_start, to_time, p_indices, is_backward);
2863 } else {
2864 _track_get_key_indices_in_range(rt->rotations, anim_start, to_time, p_indices, is_backward);
2865 _track_get_key_indices_in_range(rt->rotations, from_time, anim_end, p_indices, is_backward);
2866 }
2867 }
2868 } break;
2869 case TYPE_SCALE_3D: {
2870 const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
2871 if (st->compressed_track >= 0) {
2872 _get_compressed_key_indices_in_range<3>(st->compressed_track, from_time, length, p_indices);
2873 _get_compressed_key_indices_in_range<3>(st->compressed_track, 0, to_time, p_indices);
2874 } else {
2875 if (!is_backward) {
2876 _track_get_key_indices_in_range(st->scales, from_time, anim_end, p_indices, is_backward);
2877 _track_get_key_indices_in_range(st->scales, anim_start, to_time, p_indices, is_backward);
2878 } else {
2879 _track_get_key_indices_in_range(st->scales, anim_start, to_time, p_indices, is_backward);
2880 _track_get_key_indices_in_range(st->scales, from_time, anim_end, p_indices, is_backward);
2881 }
2882 }
2883 } break;
2884 case TYPE_BLEND_SHAPE: {
2885 const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
2886 if (bst->compressed_track >= 0) {
2887 _get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, length, p_indices);
2888 _get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, to_time, p_indices);
2889 } else {
2890 if (!is_backward) {
2891 _track_get_key_indices_in_range(bst->blend_shapes, from_time, anim_end, p_indices, is_backward);
2892 _track_get_key_indices_in_range(bst->blend_shapes, anim_start, to_time, p_indices, is_backward);
2893 } else {
2894 _track_get_key_indices_in_range(bst->blend_shapes, anim_start, to_time, p_indices, is_backward);
2895 _track_get_key_indices_in_range(bst->blend_shapes, from_time, anim_end, p_indices, is_backward);
2896 }
2897 }
2898 } break;
2899 case TYPE_VALUE: {
2900 const ValueTrack *vt = static_cast<const ValueTrack *>(t);
2901 if (!is_backward) {
2902 _track_get_key_indices_in_range(vt->values, from_time, anim_end, p_indices, is_backward);
2903 _track_get_key_indices_in_range(vt->values, anim_start, to_time, p_indices, is_backward);
2904 } else {
2905 _track_get_key_indices_in_range(vt->values, anim_start, to_time, p_indices, is_backward);
2906 _track_get_key_indices_in_range(vt->values, from_time, anim_end, p_indices, is_backward);
2907 }
2908 } break;
2909 case TYPE_METHOD: {
2910 const MethodTrack *mt = static_cast<const MethodTrack *>(t);
2911 if (!is_backward) {
2912 _track_get_key_indices_in_range(mt->methods, from_time, anim_end, p_indices, is_backward);
2913 _track_get_key_indices_in_range(mt->methods, anim_start, to_time, p_indices, is_backward);
2914 } else {
2915 _track_get_key_indices_in_range(mt->methods, anim_start, to_time, p_indices, is_backward);
2916 _track_get_key_indices_in_range(mt->methods, from_time, anim_end, p_indices, is_backward);
2917 }
2918 } break;
2919 case TYPE_BEZIER: {
2920 const BezierTrack *bz = static_cast<const BezierTrack *>(t);
2921 if (!is_backward) {
2922 _track_get_key_indices_in_range(bz->values, from_time, anim_end, p_indices, is_backward);
2923 _track_get_key_indices_in_range(bz->values, anim_start, to_time, p_indices, is_backward);
2924 } else {
2925 _track_get_key_indices_in_range(bz->values, anim_start, to_time, p_indices, is_backward);
2926 _track_get_key_indices_in_range(bz->values, from_time, anim_end, p_indices, is_backward);
2927 }
2928 } break;
2929 case TYPE_AUDIO: {
2930 const AudioTrack *ad = static_cast<const AudioTrack *>(t);
2931 if (!is_backward) {
2932 _track_get_key_indices_in_range(ad->values, from_time, anim_end, p_indices, is_backward);
2933 _track_get_key_indices_in_range(ad->values, anim_start, to_time, p_indices, is_backward);
2934 } else {
2935 _track_get_key_indices_in_range(ad->values, anim_start, to_time, p_indices, is_backward);
2936 _track_get_key_indices_in_range(ad->values, from_time, anim_end, p_indices, is_backward);
2937 }
2938 } break;
2939 case TYPE_ANIMATION: {
2940 const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
2941 if (!is_backward) {
2942 _track_get_key_indices_in_range(an->values, from_time, anim_end, p_indices, is_backward);
2943 _track_get_key_indices_in_range(an->values, anim_start, to_time, p_indices, is_backward);
2944 } else {
2945 _track_get_key_indices_in_range(an->values, anim_start, to_time, p_indices, is_backward);
2946 _track_get_key_indices_in_range(an->values, from_time, anim_end, p_indices, is_backward);
2947 }
2948 } break;
2949 }
2950 return;
2951 }
2952
2953 // Not from_time > to_time but most recent of looping...
2954 if (p_looped_flag != Animation::LOOPED_FLAG_NONE) {
2955 if (!is_backward && Math::is_equal_approx(from_time, 0)) {
2956 int edge = track_find_key(p_track, 0, FIND_MODE_EXACT);
2957 if (edge >= 0) {
2958 p_indices->push_back(edge);
2959 }
2960 } else if (is_backward && Math::is_equal_approx(to_time, length)) {
2961 int edge = track_find_key(p_track, length, FIND_MODE_EXACT);
2962 if (edge >= 0) {
2963 p_indices->push_back(edge);
2964 }
2965 }
2966 }
2967 } break;
2968 case LOOP_PINGPONG: {
2969 if (from_time > length || from_time < 0) {
2970 from_time = Math::pingpong(from_time, length);
2971 }
2972 if (to_time > length || to_time < 0) {
2973 to_time = Math::pingpong(to_time, length);
2974 }
2975
2976 if (p_looped_flag == Animation::LOOPED_FLAG_START) {
2977 // Handle loop by splitting.
2978 switch (t->type) {
2979 case TYPE_POSITION_3D: {
2980 const PositionTrack *tt = static_cast<const PositionTrack *>(t);
2981 if (tt->compressed_track >= 0) {
2982 _get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, from_time, p_indices);
2983 _get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, to_time, p_indices);
2984 } else {
2985 _track_get_key_indices_in_range(tt->positions, 0, from_time, p_indices, true);
2986 _track_get_key_indices_in_range(tt->positions, 0, to_time, p_indices, false);
2987 }
2988 } break;
2989 case TYPE_ROTATION_3D: {
2990 const RotationTrack *rt = static_cast<const RotationTrack *>(t);
2991 if (rt->compressed_track >= 0) {
2992 _get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, from_time, p_indices);
2993 _get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, to_time, p_indices);
2994 } else {
2995 _track_get_key_indices_in_range(rt->rotations, 0, from_time, p_indices, true);
2996 _track_get_key_indices_in_range(rt->rotations, 0, to_time, p_indices, false);
2997 }
2998 } break;
2999 case TYPE_SCALE_3D: {
3000 const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
3001 if (st->compressed_track >= 0) {
3002 _get_compressed_key_indices_in_range<3>(st->compressed_track, 0, from_time, p_indices);
3003 _get_compressed_key_indices_in_range<3>(st->compressed_track, 0, to_time, p_indices);
3004 } else {
3005 _track_get_key_indices_in_range(st->scales, 0, from_time, p_indices, true);
3006 _track_get_key_indices_in_range(st->scales, 0, to_time, p_indices, false);
3007 }
3008 } break;
3009 case TYPE_BLEND_SHAPE: {
3010 const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
3011 if (bst->compressed_track >= 0) {
3012 _get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, from_time, p_indices);
3013 _get_compressed_key_indices_in_range<1>(bst->compressed_track, 0, to_time, p_indices);
3014 } else {
3015 _track_get_key_indices_in_range(bst->blend_shapes, 0, from_time, p_indices, true);
3016 _track_get_key_indices_in_range(bst->blend_shapes, 0, to_time, p_indices, false);
3017 }
3018 } break;
3019 case TYPE_VALUE: {
3020 const ValueTrack *vt = static_cast<const ValueTrack *>(t);
3021 _track_get_key_indices_in_range(vt->values, 0, from_time, p_indices, true);
3022 _track_get_key_indices_in_range(vt->values, 0, to_time, p_indices, false);
3023 } break;
3024 case TYPE_METHOD: {
3025 const MethodTrack *mt = static_cast<const MethodTrack *>(t);
3026 _track_get_key_indices_in_range(mt->methods, 0, from_time, p_indices, true);
3027 _track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices, false);
3028 } break;
3029 case TYPE_BEZIER: {
3030 const BezierTrack *bz = static_cast<const BezierTrack *>(t);
3031 _track_get_key_indices_in_range(bz->values, 0, from_time, p_indices, true);
3032 _track_get_key_indices_in_range(bz->values, 0, to_time, p_indices, false);
3033 } break;
3034 case TYPE_AUDIO: {
3035 const AudioTrack *ad = static_cast<const AudioTrack *>(t);
3036 _track_get_key_indices_in_range(ad->values, 0, from_time, p_indices, true);
3037 _track_get_key_indices_in_range(ad->values, 0, to_time, p_indices, false);
3038 } break;
3039 case TYPE_ANIMATION: {
3040 const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
3041 _track_get_key_indices_in_range(an->values, 0, from_time, p_indices, true);
3042 _track_get_key_indices_in_range(an->values, 0, to_time, p_indices, false);
3043 } break;
3044 }
3045 return;
3046 }
3047 if (p_looped_flag == Animation::LOOPED_FLAG_END) {
3048 // Handle loop by splitting.
3049 switch (t->type) {
3050 case TYPE_POSITION_3D: {
3051 const PositionTrack *tt = static_cast<const PositionTrack *>(t);
3052 if (tt->compressed_track >= 0) {
3053 _get_compressed_key_indices_in_range<3>(tt->compressed_track, from_time, length, p_indices);
3054 _get_compressed_key_indices_in_range<3>(tt->compressed_track, to_time, length, p_indices);
3055 } else {
3056 _track_get_key_indices_in_range(tt->positions, from_time, length, p_indices, false);
3057 _track_get_key_indices_in_range(tt->positions, to_time, length, p_indices, true);
3058 }
3059 } break;
3060 case TYPE_ROTATION_3D: {
3061 const RotationTrack *rt = static_cast<const RotationTrack *>(t);
3062 if (rt->compressed_track >= 0) {
3063 _get_compressed_key_indices_in_range<3>(rt->compressed_track, from_time, length, p_indices);
3064 _get_compressed_key_indices_in_range<3>(rt->compressed_track, to_time, length, p_indices);
3065 } else {
3066 _track_get_key_indices_in_range(rt->rotations, from_time, length, p_indices, false);
3067 _track_get_key_indices_in_range(rt->rotations, to_time, length, p_indices, true);
3068 }
3069 } break;
3070 case TYPE_SCALE_3D: {
3071 const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
3072 if (st->compressed_track >= 0) {
3073 _get_compressed_key_indices_in_range<3>(st->compressed_track, from_time, length, p_indices);
3074 _get_compressed_key_indices_in_range<3>(st->compressed_track, to_time, length, p_indices);
3075 } else {
3076 _track_get_key_indices_in_range(st->scales, from_time, length, p_indices, false);
3077 _track_get_key_indices_in_range(st->scales, to_time, length, p_indices, true);
3078 }
3079 } break;
3080 case TYPE_BLEND_SHAPE: {
3081 const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
3082 if (bst->compressed_track >= 0) {
3083 _get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, length, p_indices);
3084 _get_compressed_key_indices_in_range<1>(bst->compressed_track, to_time, length, p_indices);
3085 } else {
3086 _track_get_key_indices_in_range(bst->blend_shapes, from_time, length, p_indices, false);
3087 _track_get_key_indices_in_range(bst->blend_shapes, to_time, length, p_indices, true);
3088 }
3089 } break;
3090 case TYPE_VALUE: {
3091 const ValueTrack *vt = static_cast<const ValueTrack *>(t);
3092 _track_get_key_indices_in_range(vt->values, from_time, length, p_indices, false);
3093 _track_get_key_indices_in_range(vt->values, to_time, length, p_indices, true);
3094 } break;
3095 case TYPE_METHOD: {
3096 const MethodTrack *mt = static_cast<const MethodTrack *>(t);
3097 _track_get_key_indices_in_range(mt->methods, from_time, length, p_indices, false);
3098 _track_get_key_indices_in_range(mt->methods, to_time, length, p_indices, true);
3099 } break;
3100 case TYPE_BEZIER: {
3101 const BezierTrack *bz = static_cast<const BezierTrack *>(t);
3102 _track_get_key_indices_in_range(bz->values, from_time, length, p_indices, false);
3103 _track_get_key_indices_in_range(bz->values, to_time, length, p_indices, true);
3104 } break;
3105 case TYPE_AUDIO: {
3106 const AudioTrack *ad = static_cast<const AudioTrack *>(t);
3107 _track_get_key_indices_in_range(ad->values, from_time, length, p_indices, false);
3108 _track_get_key_indices_in_range(ad->values, to_time, length, p_indices, true);
3109 } break;
3110 case TYPE_ANIMATION: {
3111 const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
3112 _track_get_key_indices_in_range(an->values, from_time, length, p_indices, false);
3113 _track_get_key_indices_in_range(an->values, to_time, length, p_indices, true);
3114 } break;
3115 }
3116 return;
3117 }
3118
3119 // The edge will be pingponged in the next frame and processed there, so let's ignore it now...
3120 if (!is_backward && Math::is_equal_approx(to_time, length)) {
3121 to_time -= CMP_EPSILON;
3122 } else if (is_backward && Math::is_equal_approx(from_time, 0)) {
3123 from_time += CMP_EPSILON;
3124 }
3125 } break;
3126 }
3127 switch (t->type) {
3128 case TYPE_POSITION_3D: {
3129 const PositionTrack *tt = static_cast<const PositionTrack *>(t);
3130 if (tt->compressed_track >= 0) {
3131 _get_compressed_key_indices_in_range<3>(tt->compressed_track, from_time, to_time - from_time, p_indices);
3132 } else {
3133 _track_get_key_indices_in_range(tt->positions, from_time, to_time, p_indices, is_backward);
3134 }
3135 } break;
3136 case TYPE_ROTATION_3D: {
3137 const RotationTrack *rt = static_cast<const RotationTrack *>(t);
3138 if (rt->compressed_track >= 0) {
3139 _get_compressed_key_indices_in_range<3>(rt->compressed_track, from_time, to_time - from_time, p_indices);
3140 } else {
3141 _track_get_key_indices_in_range(rt->rotations, from_time, to_time, p_indices, is_backward);
3142 }
3143 } break;
3144 case TYPE_SCALE_3D: {
3145 const ScaleTrack *st = static_cast<const ScaleTrack *>(t);
3146 if (st->compressed_track >= 0) {
3147 _get_compressed_key_indices_in_range<3>(st->compressed_track, from_time, to_time - from_time, p_indices);
3148 } else {
3149 _track_get_key_indices_in_range(st->scales, from_time, to_time, p_indices, is_backward);
3150 }
3151 } break;
3152 case TYPE_BLEND_SHAPE: {
3153 const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
3154 if (bst->compressed_track >= 0) {
3155 _get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, to_time - from_time, p_indices);
3156 } else {
3157 _track_get_key_indices_in_range(bst->blend_shapes, from_time, to_time, p_indices, is_backward);
3158 }
3159 } break;
3160 case TYPE_VALUE: {
3161 const ValueTrack *vt = static_cast<const ValueTrack *>(t);
3162 _track_get_key_indices_in_range(vt->values, from_time, to_time, p_indices, is_backward);
3163 } break;
3164 case TYPE_METHOD: {
3165 const MethodTrack *mt = static_cast<const MethodTrack *>(t);
3166 _track_get_key_indices_in_range(mt->methods, from_time, to_time, p_indices, is_backward);
3167 } break;
3168 case TYPE_BEZIER: {
3169 const BezierTrack *bz = static_cast<const BezierTrack *>(t);
3170 _track_get_key_indices_in_range(bz->values, from_time, to_time, p_indices, is_backward);
3171 } break;
3172 case TYPE_AUDIO: {
3173 const AudioTrack *ad = static_cast<const AudioTrack *>(t);
3174 _track_get_key_indices_in_range(ad->values, from_time, to_time, p_indices, is_backward);
3175 } break;
3176 case TYPE_ANIMATION: {
3177 const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
3178 _track_get_key_indices_in_range(an->values, from_time, to_time, p_indices, is_backward);
3179 } break;
3180 }
3181}
3182
3183Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
3184 ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
3185 Track *t = tracks[p_track];
3186 ERR_FAIL_COND_V(t->type != TYPE_METHOD, Vector<Variant>());
3187
3188 MethodTrack *pm = static_cast<MethodTrack *>(t);
3189
3190 ERR_FAIL_INDEX_V(p_key_idx, pm->methods.size(), Vector<Variant>());
3191
3192 const MethodKey &mk = pm->methods[p_key_idx];
3193
3194 return mk.params;
3195}
3196
3197StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
3198 ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
3199 Track *t = tracks[p_track];
3200 ERR_FAIL_COND_V(t->type != TYPE_METHOD, StringName());
3201
3202 MethodTrack *pm = static_cast<MethodTrack *>(t);
3203
3204 ERR_FAIL_INDEX_V(p_key_idx, pm->methods.size(), StringName());
3205
3206 return pm->methods[p_key_idx].method;
3207}
3208
3209int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) {
3210 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
3211 Track *t = tracks[p_track];
3212 ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
3213
3214 BezierTrack *bt = static_cast<BezierTrack *>(t);
3215
3216 TKey<BezierKey> k;
3217 k.time = p_time;
3218 k.value.value = p_value;
3219 k.value.in_handle = p_in_handle;
3220 if (k.value.in_handle.x > 0) {
3221 k.value.in_handle.x = 0;
3222 }
3223 k.value.out_handle = p_out_handle;
3224 if (k.value.out_handle.x < 0) {
3225 k.value.out_handle.x = 0;
3226 }
3227
3228 int key = _insert(p_time, bt->values, k);
3229
3230 emit_changed();
3231
3232 return key;
3233}
3234
3235void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_value) {
3236 ERR_FAIL_INDEX(p_track, tracks.size());
3237 Track *t = tracks[p_track];
3238 ERR_FAIL_COND(t->type != TYPE_BEZIER);
3239
3240 BezierTrack *bt = static_cast<BezierTrack *>(t);
3241
3242 ERR_FAIL_INDEX(p_index, bt->values.size());
3243
3244 bt->values.write[p_index].value.value = p_value;
3245
3246 emit_changed();
3247}
3248
3249void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio) {
3250 ERR_FAIL_INDEX(p_track, tracks.size());
3251 Track *t = tracks[p_track];
3252 ERR_FAIL_COND(t->type != TYPE_BEZIER);
3253
3254 BezierTrack *bt = static_cast<BezierTrack *>(t);
3255
3256 ERR_FAIL_INDEX(p_index, bt->values.size());
3257
3258 Vector2 in_handle = p_handle;
3259 if (in_handle.x > 0) {
3260 in_handle.x = 0;
3261 }
3262 bt->values.write[p_index].value.in_handle = in_handle;
3263
3264#ifdef TOOLS_ENABLED
3265 if (bt->values[p_index].value.handle_mode == HANDLE_MODE_LINEAR) {
3266 bt->values.write[p_index].value.in_handle = Vector2();
3267 bt->values.write[p_index].value.out_handle = Vector2();
3268 } else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
3269 Transform2D xform;
3270 xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio));
3271
3272 Vector2 vec_out = xform.xform(bt->values[p_index].value.out_handle);
3273 Vector2 vec_in = xform.xform(in_handle);
3274
3275 bt->values.write[p_index].value.out_handle = xform.affine_inverse().xform(-vec_in.normalized() * vec_out.length());
3276 } else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_MIRRORED) {
3277 bt->values.write[p_index].value.out_handle = -in_handle;
3278 }
3279#endif // TOOLS_ENABLED
3280
3281 emit_changed();
3282}
3283
3284void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio) {
3285 ERR_FAIL_INDEX(p_track, tracks.size());
3286 Track *t = tracks[p_track];
3287 ERR_FAIL_COND(t->type != TYPE_BEZIER);
3288
3289 BezierTrack *bt = static_cast<BezierTrack *>(t);
3290
3291 ERR_FAIL_INDEX(p_index, bt->values.size());
3292
3293 Vector2 out_handle = p_handle;
3294 if (out_handle.x < 0) {
3295 out_handle.x = 0;
3296 }
3297 bt->values.write[p_index].value.out_handle = out_handle;
3298
3299#ifdef TOOLS_ENABLED
3300 if (bt->values[p_index].value.handle_mode == HANDLE_MODE_LINEAR) {
3301 bt->values.write[p_index].value.in_handle = Vector2();
3302 bt->values.write[p_index].value.out_handle = Vector2();
3303 } else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
3304 Transform2D xform;
3305 xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio));
3306
3307 Vector2 vec_in = xform.xform(bt->values[p_index].value.in_handle);
3308 Vector2 vec_out = xform.xform(out_handle);
3309
3310 bt->values.write[p_index].value.in_handle = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length());
3311 } else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_MIRRORED) {
3312 bt->values.write[p_index].value.in_handle = -out_handle;
3313 }
3314#endif // TOOLS_ENABLED
3315
3316 emit_changed();
3317}
3318
3319real_t Animation::bezier_track_get_key_value(int p_track, int p_index) const {
3320 ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
3321 Track *t = tracks[p_track];
3322 ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0);
3323
3324 BezierTrack *bt = static_cast<BezierTrack *>(t);
3325
3326 ERR_FAIL_INDEX_V(p_index, bt->values.size(), 0);
3327
3328 return bt->values[p_index].value.value;
3329}
3330
3331Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
3332 ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
3333 Track *t = tracks[p_track];
3334 ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
3335
3336 BezierTrack *bt = static_cast<BezierTrack *>(t);
3337
3338 ERR_FAIL_INDEX_V(p_index, bt->values.size(), Vector2());
3339
3340 return bt->values[p_index].value.in_handle;
3341}
3342
3343Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
3344 ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
3345 Track *t = tracks[p_track];
3346 ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
3347
3348 BezierTrack *bt = static_cast<BezierTrack *>(t);
3349
3350 ERR_FAIL_INDEX_V(p_index, bt->values.size(), Vector2());
3351
3352 return bt->values[p_index].value.out_handle;
3353}
3354
3355#ifdef TOOLS_ENABLED
3356void Animation::bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, HandleSetMode p_set_mode) {
3357 ERR_FAIL_INDEX(p_track, tracks.size());
3358 Track *t = tracks[p_track];
3359 ERR_FAIL_COND(t->type != TYPE_BEZIER);
3360
3361 BezierTrack *bt = static_cast<BezierTrack *>(t);
3362
3363 ERR_FAIL_INDEX(p_index, bt->values.size());
3364
3365 bt->values.write[p_index].value.handle_mode = p_mode;
3366
3367 switch (p_mode) {
3368 case HANDLE_MODE_LINEAR: {
3369 bt->values.write[p_index].value.in_handle = Vector2(0, 0);
3370 bt->values.write[p_index].value.out_handle = Vector2(0, 0);
3371 } break;
3372 case HANDLE_MODE_BALANCED:
3373 case HANDLE_MODE_MIRRORED: {
3374 int prev_key = MAX(0, p_index - 1);
3375 int next_key = MIN(bt->values.size() - 1, p_index + 1);
3376 if (prev_key == next_key) {
3377 break; // Exists only one key.
3378 }
3379 real_t in_handle_x = 0;
3380 real_t in_handle_y = 0;
3381 real_t out_handle_x = 0;
3382 real_t out_handle_y = 0;
3383 if (p_mode == HANDLE_MODE_BALANCED) {
3384 // Note:
3385 // If p_set_mode == HANDLE_SET_MODE_NONE, I don't know if it should change the Tangent implicitly.
3386 // At the least, we need to avoid corrupting the handles when loading animation from the resource.
3387 // However, changes made by the Inspector do not go through the BezierEditor,
3388 // so if you change from Free to Balanced or Mirrored in Inspector, there is no guarantee that
3389 // it is Balanced or Mirrored until there is a handle operation.
3390 if (p_set_mode == HANDLE_SET_MODE_RESET) {
3391 real_t handle_length = 1.0 / 3.0;
3392 in_handle_x = (bt->values[prev_key].time - bt->values[p_index].time) * handle_length;
3393 in_handle_y = 0;
3394 out_handle_x = (bt->values[next_key].time - bt->values[p_index].time) * handle_length;
3395 out_handle_y = 0;
3396 bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
3397 bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
3398 } else if (p_set_mode == HANDLE_SET_MODE_AUTO) {
3399 real_t handle_length = 1.0 / 6.0;
3400 real_t tangent = (bt->values[next_key].value.value - bt->values[prev_key].value.value) / (bt->values[next_key].time - bt->values[prev_key].time);
3401 in_handle_x = (bt->values[prev_key].time - bt->values[p_index].time) * handle_length;
3402 in_handle_y = in_handle_x * tangent;
3403 out_handle_x = (bt->values[next_key].time - bt->values[p_index].time) * handle_length;
3404 out_handle_y = out_handle_x * tangent;
3405 bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
3406 bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
3407 }
3408 } else {
3409 real_t handle_length = 1.0 / 4.0;
3410 real_t prev_interval = Math::abs(bt->values[p_index].time - bt->values[prev_key].time);
3411 real_t next_interval = Math::abs(bt->values[p_index].time - bt->values[next_key].time);
3412 real_t min_time = 0;
3413 if (Math::is_zero_approx(prev_interval)) {
3414 min_time = next_interval;
3415 } else if (Math::is_zero_approx(next_interval)) {
3416 min_time = prev_interval;
3417 } else {
3418 min_time = MIN(prev_interval, next_interval);
3419 }
3420 if (p_set_mode == HANDLE_SET_MODE_RESET) {
3421 in_handle_x = -min_time * handle_length;
3422 in_handle_y = 0;
3423 out_handle_x = min_time * handle_length;
3424 out_handle_y = 0;
3425 bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
3426 bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
3427 } else if (p_set_mode == HANDLE_SET_MODE_AUTO) {
3428 real_t tangent = (bt->values[next_key].value.value - bt->values[prev_key].value.value) / min_time;
3429 in_handle_x = -min_time * handle_length;
3430 in_handle_y = in_handle_x * tangent;
3431 out_handle_x = min_time * handle_length;
3432 out_handle_y = out_handle_x * tangent;
3433 bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
3434 bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
3435 }
3436 }
3437 } break;
3438 default: {
3439 } break;
3440 }
3441
3442 emit_changed();
3443}
3444
3445Animation::HandleMode Animation::bezier_track_get_key_handle_mode(int p_track, int p_index) const {
3446 ERR_FAIL_INDEX_V(p_track, tracks.size(), HANDLE_MODE_FREE);
3447 Track *t = tracks[p_track];
3448 ERR_FAIL_COND_V(t->type != TYPE_BEZIER, HANDLE_MODE_FREE);
3449
3450 BezierTrack *bt = static_cast<BezierTrack *>(t);
3451
3452 ERR_FAIL_INDEX_V(p_index, bt->values.size(), HANDLE_MODE_FREE);
3453
3454 return bt->values[p_index].value.handle_mode;
3455}
3456#endif // TOOLS_ENABLED
3457
3458real_t Animation::bezier_track_interpolate(int p_track, double p_time) const {
3459 //this uses a different interpolation scheme
3460 ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
3461 Track *track = tracks[p_track];
3462 ERR_FAIL_COND_V(track->type != TYPE_BEZIER, 0);
3463
3464 BezierTrack *bt = static_cast<BezierTrack *>(track);
3465
3466 int len = _find(bt->values, length) + 1; // try to find last key (there may be more past the end)
3467
3468 if (len <= 0) {
3469 // (-1 or -2 returned originally) (plus one above)
3470 return 0;
3471 } else if (len == 1) { // one key found (0+1), return it
3472 return bt->values[0].value.value;
3473 }
3474
3475 int idx = _find(bt->values, p_time);
3476
3477 ERR_FAIL_COND_V(idx == -2, 0);
3478
3479 //there really is no looping interpolation on bezier
3480
3481 if (idx < 0) {
3482 return bt->values[0].value.value;
3483 }
3484
3485 if (idx >= bt->values.size() - 1) {
3486 return bt->values[bt->values.size() - 1].value.value;
3487 }
3488
3489 double t = p_time - bt->values[idx].time;
3490
3491 int iterations = 10;
3492
3493 real_t duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes
3494 real_t low = 0.0; // 0% of the current animation segment
3495 real_t high = 1.0; // 100% of the current animation segment
3496
3497 Vector2 start(0, bt->values[idx].value.value);
3498 Vector2 start_out = start + bt->values[idx].value.out_handle;
3499 Vector2 end(duration, bt->values[idx + 1].value.value);
3500 Vector2 end_in = end + bt->values[idx + 1].value.in_handle;
3501
3502 //narrow high and low as much as possible
3503 for (int i = 0; i < iterations; i++) {
3504 real_t middle = (low + high) / 2;
3505
3506 Vector2 interp = start.bezier_interpolate(start_out, end_in, end, middle);
3507
3508 if (interp.x < t) {
3509 low = middle;
3510 } else {
3511 high = middle;
3512 }
3513 }
3514
3515 //interpolate the result:
3516 Vector2 low_pos = start.bezier_interpolate(start_out, end_in, end, low);
3517 Vector2 high_pos = start.bezier_interpolate(start_out, end_in, end, high);
3518 real_t c = (t - low_pos.x) / (high_pos.x - low_pos.x);
3519
3520 return low_pos.lerp(high_pos, c).y;
3521}
3522
3523int Animation::audio_track_insert_key(int p_track, double p_time, const Ref<Resource> &p_stream, real_t p_start_offset, real_t p_end_offset) {
3524 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
3525 Track *t = tracks[p_track];
3526 ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1);
3527
3528 AudioTrack *at = static_cast<AudioTrack *>(t);
3529
3530 TKey<AudioKey> k;
3531 k.time = p_time;
3532 k.value.stream = p_stream;
3533 k.value.start_offset = p_start_offset;
3534 if (k.value.start_offset < 0) {
3535 k.value.start_offset = 0;
3536 }
3537 k.value.end_offset = p_end_offset;
3538 if (k.value.end_offset < 0) {
3539 k.value.end_offset = 0;
3540 }
3541
3542 int key = _insert(p_time, at->values, k);
3543
3544 emit_changed();
3545
3546 return key;
3547}
3548
3549void Animation::audio_track_set_key_stream(int p_track, int p_key, const Ref<Resource> &p_stream) {
3550 ERR_FAIL_INDEX(p_track, tracks.size());
3551 Track *t = tracks[p_track];
3552 ERR_FAIL_COND(t->type != TYPE_AUDIO);
3553
3554 AudioTrack *at = static_cast<AudioTrack *>(t);
3555
3556 ERR_FAIL_INDEX(p_key, at->values.size());
3557
3558 at->values.write[p_key].value.stream = p_stream;
3559
3560 emit_changed();
3561}
3562
3563void Animation::audio_track_set_key_start_offset(int p_track, int p_key, real_t p_offset) {
3564 ERR_FAIL_INDEX(p_track, tracks.size());
3565 Track *t = tracks[p_track];
3566 ERR_FAIL_COND(t->type != TYPE_AUDIO);
3567
3568 AudioTrack *at = static_cast<AudioTrack *>(t);
3569
3570 ERR_FAIL_INDEX(p_key, at->values.size());
3571
3572 if (p_offset < 0) {
3573 p_offset = 0;
3574 }
3575
3576 at->values.write[p_key].value.start_offset = p_offset;
3577
3578 emit_changed();
3579}
3580
3581void Animation::audio_track_set_key_end_offset(int p_track, int p_key, real_t p_offset) {
3582 ERR_FAIL_INDEX(p_track, tracks.size());
3583 Track *t = tracks[p_track];
3584 ERR_FAIL_COND(t->type != TYPE_AUDIO);
3585
3586 AudioTrack *at = static_cast<AudioTrack *>(t);
3587
3588 ERR_FAIL_INDEX(p_key, at->values.size());
3589
3590 if (p_offset < 0) {
3591 p_offset = 0;
3592 }
3593
3594 at->values.write[p_key].value.end_offset = p_offset;
3595
3596 emit_changed();
3597}
3598
3599Ref<Resource> Animation::audio_track_get_key_stream(int p_track, int p_key) const {
3600 ERR_FAIL_INDEX_V(p_track, tracks.size(), Ref<Resource>());
3601 const Track *t = tracks[p_track];
3602 ERR_FAIL_COND_V(t->type != TYPE_AUDIO, Ref<Resource>());
3603
3604 const AudioTrack *at = static_cast<const AudioTrack *>(t);
3605
3606 ERR_FAIL_INDEX_V(p_key, at->values.size(), Ref<Resource>());
3607
3608 return at->values[p_key].value.stream;
3609}
3610
3611real_t Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
3612 ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
3613 const Track *t = tracks[p_track];
3614 ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
3615
3616 const AudioTrack *at = static_cast<const AudioTrack *>(t);
3617
3618 ERR_FAIL_INDEX_V(p_key, at->values.size(), 0);
3619
3620 return at->values[p_key].value.start_offset;
3621}
3622
3623real_t Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
3624 ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
3625 const Track *t = tracks[p_track];
3626 ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
3627
3628 const AudioTrack *at = static_cast<const AudioTrack *>(t);
3629
3630 ERR_FAIL_INDEX_V(p_key, at->values.size(), 0);
3631
3632 return at->values[p_key].value.end_offset;
3633}
3634
3635void Animation::audio_track_set_use_blend(int p_track, bool p_enable) {
3636 ERR_FAIL_INDEX(p_track, tracks.size());
3637 Track *t = tracks[p_track];
3638 ERR_FAIL_COND(t->type != TYPE_AUDIO);
3639
3640 AudioTrack *at = static_cast<AudioTrack *>(t);
3641
3642 at->use_blend = p_enable;
3643 emit_changed();
3644}
3645
3646bool Animation::audio_track_is_use_blend(int p_track) const {
3647 ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
3648 Track *t = tracks[p_track];
3649 ERR_FAIL_COND_V(t->type != TYPE_AUDIO, false);
3650
3651 AudioTrack *at = static_cast<AudioTrack *>(t);
3652
3653 return at->use_blend;
3654}
3655
3656//
3657
3658int Animation::animation_track_insert_key(int p_track, double p_time, const StringName &p_animation) {
3659 ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
3660 Track *t = tracks[p_track];
3661 ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, -1);
3662
3663 AnimationTrack *at = static_cast<AnimationTrack *>(t);
3664
3665 TKey<StringName> k;
3666 k.time = p_time;
3667 k.value = p_animation;
3668
3669 int key = _insert(p_time, at->values, k);
3670
3671 emit_changed();
3672
3673 return key;
3674}
3675
3676void Animation::animation_track_set_key_animation(int p_track, int p_key, const StringName &p_animation) {
3677 ERR_FAIL_INDEX(p_track, tracks.size());
3678 Track *t = tracks[p_track];
3679 ERR_FAIL_COND(t->type != TYPE_ANIMATION);
3680
3681 AnimationTrack *at = static_cast<AnimationTrack *>(t);
3682
3683 ERR_FAIL_INDEX(p_key, at->values.size());
3684
3685 at->values.write[p_key].value = p_animation;
3686
3687 emit_changed();
3688}
3689
3690StringName Animation::animation_track_get_key_animation(int p_track, int p_key) const {
3691 ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
3692 const Track *t = tracks[p_track];
3693 ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, StringName());
3694
3695 const AnimationTrack *at = static_cast<const AnimationTrack *>(t);
3696
3697 ERR_FAIL_INDEX_V(p_key, at->values.size(), StringName());
3698
3699 return at->values[p_key].value;
3700}
3701
3702void Animation::set_length(real_t p_length) {
3703 if (p_length < ANIM_MIN_LENGTH) {
3704 p_length = ANIM_MIN_LENGTH;
3705 }
3706 length = p_length;
3707 emit_changed();
3708}
3709
3710real_t Animation::get_length() const {
3711 return length;
3712}
3713
3714void Animation::set_loop_mode(Animation::LoopMode p_loop_mode) {
3715 loop_mode = p_loop_mode;
3716 emit_changed();
3717}
3718
3719Animation::LoopMode Animation::get_loop_mode() const {
3720 return loop_mode;
3721}
3722
3723void Animation::track_set_imported(int p_track, bool p_imported) {
3724 ERR_FAIL_INDEX(p_track, tracks.size());
3725 tracks[p_track]->imported = p_imported;
3726}
3727
3728bool Animation::track_is_imported(int p_track) const {
3729 ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
3730 return tracks[p_track]->imported;
3731}
3732
3733void Animation::track_set_enabled(int p_track, bool p_enabled) {
3734 ERR_FAIL_INDEX(p_track, tracks.size());
3735 tracks[p_track]->enabled = p_enabled;
3736 emit_changed();
3737}
3738
3739bool Animation::track_is_enabled(int p_track) const {
3740 ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
3741 return tracks[p_track]->enabled;
3742}
3743
3744void Animation::track_move_up(int p_track) {
3745 if (p_track >= 0 && p_track < (tracks.size() - 1)) {
3746 SWAP(tracks.write[p_track], tracks.write[p_track + 1]);
3747 }
3748
3749 emit_changed();
3750}
3751
3752void Animation::track_move_down(int p_track) {
3753 if (p_track > 0 && p_track < tracks.size()) {
3754 SWAP(tracks.write[p_track], tracks.write[p_track - 1]);
3755 }
3756
3757 emit_changed();
3758}
3759
3760void Animation::track_move_to(int p_track, int p_to_index) {
3761 ERR_FAIL_INDEX(p_track, tracks.size());
3762 ERR_FAIL_INDEX(p_to_index, tracks.size() + 1);
3763 if (p_track == p_to_index || p_track == p_to_index - 1) {
3764 return;
3765 }
3766
3767 Track *track = tracks.get(p_track);
3768 tracks.remove_at(p_track);
3769 // Take into account that the position of the tracks that come after the one removed will change.
3770 tracks.insert(p_to_index > p_track ? p_to_index - 1 : p_to_index, track);
3771
3772 emit_changed();
3773}
3774
3775void Animation::track_swap(int p_track, int p_with_track) {
3776 ERR_FAIL_INDEX(p_track, tracks.size());
3777 ERR_FAIL_INDEX(p_with_track, tracks.size());
3778 if (p_track == p_with_track) {
3779 return;
3780 }
3781 SWAP(tracks.write[p_track], tracks.write[p_with_track]);
3782
3783 emit_changed();
3784}
3785
3786void Animation::set_step(real_t p_step) {
3787 step = p_step;
3788 emit_changed();
3789}
3790
3791real_t Animation::get_step() const {
3792 return step;
3793}
3794
3795void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
3796 ERR_FAIL_COND(p_to_animation.is_null());
3797 ERR_FAIL_INDEX(p_track, get_track_count());
3798 int dst_track = p_to_animation->get_track_count();
3799 p_to_animation->add_track(track_get_type(p_track));
3800
3801 p_to_animation->track_set_path(dst_track, track_get_path(p_track));
3802 p_to_animation->track_set_imported(dst_track, track_is_imported(p_track));
3803 p_to_animation->track_set_enabled(dst_track, track_is_enabled(p_track));
3804 p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_track));
3805 p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_track));
3806 if (track_get_type(p_track) == TYPE_VALUE) {
3807 p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
3808 }
3809
3810 for (int i = 0; i < track_get_key_count(p_track); i++) {
3811 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));
3812 }
3813}
3814
3815void Animation::_bind_methods() {
3816 ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
3817 ClassDB::bind_method(D_METHOD("remove_track", "track_idx"), &Animation::remove_track);
3818 ClassDB::bind_method(D_METHOD("get_track_count"), &Animation::get_track_count);
3819 ClassDB::bind_method(D_METHOD("track_get_type", "track_idx"), &Animation::track_get_type);
3820 ClassDB::bind_method(D_METHOD("track_get_path", "track_idx"), &Animation::track_get_path);
3821 ClassDB::bind_method(D_METHOD("track_set_path", "track_idx", "path"), &Animation::track_set_path);
3822 ClassDB::bind_method(D_METHOD("find_track", "path", "type"), &Animation::find_track);
3823
3824 ClassDB::bind_method(D_METHOD("track_move_up", "track_idx"), &Animation::track_move_up);
3825 ClassDB::bind_method(D_METHOD("track_move_down", "track_idx"), &Animation::track_move_down);
3826 ClassDB::bind_method(D_METHOD("track_move_to", "track_idx", "to_idx"), &Animation::track_move_to);
3827 ClassDB::bind_method(D_METHOD("track_swap", "track_idx", "with_idx"), &Animation::track_swap);
3828
3829 ClassDB::bind_method(D_METHOD("track_set_imported", "track_idx", "imported"), &Animation::track_set_imported);
3830 ClassDB::bind_method(D_METHOD("track_is_imported", "track_idx"), &Animation::track_is_imported);
3831
3832 ClassDB::bind_method(D_METHOD("track_set_enabled", "track_idx", "enabled"), &Animation::track_set_enabled);
3833 ClassDB::bind_method(D_METHOD("track_is_enabled", "track_idx"), &Animation::track_is_enabled);
3834
3835 ClassDB::bind_method(D_METHOD("position_track_insert_key", "track_idx", "time", "position"), &Animation::position_track_insert_key);
3836 ClassDB::bind_method(D_METHOD("rotation_track_insert_key", "track_idx", "time", "rotation"), &Animation::rotation_track_insert_key);
3837 ClassDB::bind_method(D_METHOD("scale_track_insert_key", "track_idx", "time", "scale"), &Animation::scale_track_insert_key);
3838 ClassDB::bind_method(D_METHOD("blend_shape_track_insert_key", "track_idx", "time", "amount"), &Animation::blend_shape_track_insert_key);
3839
3840 ClassDB::bind_method(D_METHOD("position_track_interpolate", "track_idx", "time_sec"), &Animation::position_track_interpolate);
3841 ClassDB::bind_method(D_METHOD("rotation_track_interpolate", "track_idx", "time_sec"), &Animation::rotation_track_interpolate);
3842 ClassDB::bind_method(D_METHOD("scale_track_interpolate", "track_idx", "time_sec"), &Animation::scale_track_interpolate);
3843 ClassDB::bind_method(D_METHOD("blend_shape_track_interpolate", "track_idx", "time_sec"), &Animation::blend_shape_track_interpolate);
3844
3845 ClassDB::bind_method(D_METHOD("track_insert_key", "track_idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
3846 ClassDB::bind_method(D_METHOD("track_remove_key", "track_idx", "key_idx"), &Animation::track_remove_key);
3847 ClassDB::bind_method(D_METHOD("track_remove_key_at_time", "track_idx", "time"), &Animation::track_remove_key_at_time);
3848 ClassDB::bind_method(D_METHOD("track_set_key_value", "track_idx", "key", "value"), &Animation::track_set_key_value);
3849 ClassDB::bind_method(D_METHOD("track_set_key_transition", "track_idx", "key_idx", "transition"), &Animation::track_set_key_transition);
3850 ClassDB::bind_method(D_METHOD("track_set_key_time", "track_idx", "key_idx", "time"), &Animation::track_set_key_time);
3851 ClassDB::bind_method(D_METHOD("track_get_key_transition", "track_idx", "key_idx"), &Animation::track_get_key_transition);
3852
3853 ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
3854 ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
3855 ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
3856 ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode"), &Animation::track_find_key, DEFVAL(FIND_MODE_NEAREST));
3857
3858 ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
3859 ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
3860
3861 ClassDB::bind_method(D_METHOD("track_set_interpolation_loop_wrap", "track_idx", "interpolation"), &Animation::track_set_interpolation_loop_wrap);
3862 ClassDB::bind_method(D_METHOD("track_get_interpolation_loop_wrap", "track_idx"), &Animation::track_get_interpolation_loop_wrap);
3863
3864 ClassDB::bind_method(D_METHOD("track_is_compressed", "track_idx"), &Animation::track_is_compressed);
3865
3866 ClassDB::bind_method(D_METHOD("value_track_set_update_mode", "track_idx", "mode"), &Animation::value_track_set_update_mode);
3867 ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode);
3868
3869 ClassDB::bind_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::value_track_interpolate);
3870
3871 ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name);
3872 ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params);
3873
3874 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()));
3875
3876 ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "track_idx", "key_idx", "value"), &Animation::bezier_track_set_key_value);
3877 ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_in_handle, DEFVAL(1.0));
3878 ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_out_handle, DEFVAL(1.0));
3879
3880 ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "track_idx", "key_idx"), &Animation::bezier_track_get_key_value);
3881 ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_in_handle);
3882 ClassDB::bind_method(D_METHOD("bezier_track_get_key_out_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_out_handle);
3883
3884 ClassDB::bind_method(D_METHOD("bezier_track_interpolate", "track_idx", "time"), &Animation::bezier_track_interpolate);
3885
3886 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));
3887 ClassDB::bind_method(D_METHOD("audio_track_set_key_stream", "track_idx", "key_idx", "stream"), &Animation::audio_track_set_key_stream);
3888 ClassDB::bind_method(D_METHOD("audio_track_set_key_start_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_start_offset);
3889 ClassDB::bind_method(D_METHOD("audio_track_set_key_end_offset", "track_idx", "key_idx", "offset"), &Animation::audio_track_set_key_end_offset);
3890 ClassDB::bind_method(D_METHOD("audio_track_get_key_stream", "track_idx", "key_idx"), &Animation::audio_track_get_key_stream);
3891 ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
3892 ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
3893 ClassDB::bind_method(D_METHOD("audio_track_set_use_blend", "track_idx", "enable"), &Animation::audio_track_set_use_blend);
3894 ClassDB::bind_method(D_METHOD("audio_track_is_use_blend", "track_idx"), &Animation::audio_track_is_use_blend);
3895
3896 ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key);
3897 ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
3898 ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "track_idx", "key_idx"), &Animation::animation_track_get_key_animation);
3899
3900 ClassDB::bind_method(D_METHOD("set_length", "time_sec"), &Animation::set_length);
3901 ClassDB::bind_method(D_METHOD("get_length"), &Animation::get_length);
3902
3903 ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &Animation::set_loop_mode);
3904 ClassDB::bind_method(D_METHOD("get_loop_mode"), &Animation::get_loop_mode);
3905
3906 ClassDB::bind_method(D_METHOD("set_step", "size_sec"), &Animation::set_step);
3907 ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
3908
3909 ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
3910 ClassDB::bind_method(D_METHOD("copy_track", "track_idx", "to_animation"), &Animation::copy_track);
3911
3912 ClassDB::bind_method(D_METHOD("compress", "page_size", "fps", "split_tolerance"), &Animation::compress, DEFVAL(8192), DEFVAL(120), DEFVAL(4.0));
3913
3914 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length", PROPERTY_HINT_RANGE, "0.001,99999,0.001,suffix:s"), "set_length", "get_length");
3915 ADD_PROPERTY(PropertyInfo(Variant::INT, "loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Ping-Pong"), "set_loop_mode", "get_loop_mode");
3916 ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step", PROPERTY_HINT_RANGE, "0,4096,0.001,suffix:s"), "set_step", "get_step");
3917
3918 BIND_ENUM_CONSTANT(TYPE_VALUE);
3919 BIND_ENUM_CONSTANT(TYPE_POSITION_3D);
3920 BIND_ENUM_CONSTANT(TYPE_ROTATION_3D);
3921 BIND_ENUM_CONSTANT(TYPE_SCALE_3D);
3922 BIND_ENUM_CONSTANT(TYPE_BLEND_SHAPE);
3923 BIND_ENUM_CONSTANT(TYPE_METHOD);
3924 BIND_ENUM_CONSTANT(TYPE_BEZIER);
3925 BIND_ENUM_CONSTANT(TYPE_AUDIO);
3926 BIND_ENUM_CONSTANT(TYPE_ANIMATION);
3927
3928 BIND_ENUM_CONSTANT(INTERPOLATION_NEAREST);
3929 BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR);
3930 BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC);
3931 BIND_ENUM_CONSTANT(INTERPOLATION_LINEAR_ANGLE);
3932 BIND_ENUM_CONSTANT(INTERPOLATION_CUBIC_ANGLE);
3933
3934 BIND_ENUM_CONSTANT(UPDATE_CONTINUOUS);
3935 BIND_ENUM_CONSTANT(UPDATE_DISCRETE);
3936 BIND_ENUM_CONSTANT(UPDATE_CAPTURE);
3937
3938 BIND_ENUM_CONSTANT(LOOP_NONE);
3939 BIND_ENUM_CONSTANT(LOOP_LINEAR);
3940 BIND_ENUM_CONSTANT(LOOP_PINGPONG);
3941
3942 BIND_ENUM_CONSTANT(LOOPED_FLAG_NONE);
3943 BIND_ENUM_CONSTANT(LOOPED_FLAG_END);
3944 BIND_ENUM_CONSTANT(LOOPED_FLAG_START);
3945
3946 BIND_ENUM_CONSTANT(FIND_MODE_NEAREST);
3947 BIND_ENUM_CONSTANT(FIND_MODE_APPROX);
3948 BIND_ENUM_CONSTANT(FIND_MODE_EXACT);
3949}
3950
3951void Animation::clear() {
3952 for (int i = 0; i < tracks.size(); i++) {
3953 memdelete(tracks[i]);
3954 }
3955 tracks.clear();
3956 loop_mode = LOOP_NONE;
3957 length = 1;
3958 compression.enabled = false;
3959 compression.bounds.clear();
3960 compression.pages.clear();
3961 compression.fps = 120;
3962 emit_changed();
3963}
3964
3965bool Animation::_float_track_optimize_key(const TKey<float> t0, const TKey<float> t1, const TKey<float> t2, real_t p_allowed_velocity_err, real_t p_allowed_precision_error) {
3966 // Remove overlapping keys.
3967 if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) {
3968 return true;
3969 }
3970 if (abs(t0.value - t1.value) < p_allowed_precision_error && abs(t1.value - t2.value) < p_allowed_precision_error) {
3971 return true;
3972 }
3973 // Calc velocities.
3974 double v0 = (t1.value - t0.value) / (t1.time - t0.time);
3975 double v1 = (t2.value - t1.value) / (t2.time - t1.time);
3976 // Avoid zero div but check equality.
3977 if (abs(v0 - v1) < p_allowed_precision_error) {
3978 return true;
3979 } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) {
3980 return false;
3981 }
3982 if (!signbit(v0 * v1)) {
3983 v0 = abs(v0);
3984 v1 = abs(v1);
3985 double ratio = v0 < v1 ? v0 / v1 : v1 / v0;
3986 if (ratio >= 1.0 - p_allowed_velocity_err) {
3987 return true;
3988 }
3989 }
3990 return false;
3991}
3992
3993bool Animation::_vector2_track_optimize_key(const TKey<Vector2> t0, const TKey<Vector2> t1, const TKey<Vector2> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) {
3994 // Remove overlapping keys.
3995 if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) {
3996 return true;
3997 }
3998 if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) {
3999 return true;
4000 }
4001 // Calc velocities.
4002 Vector2 vc0 = (t1.value - t0.value) / (t1.time - t0.time);
4003 Vector2 vc1 = (t2.value - t1.value) / (t2.time - t1.time);
4004 double v0 = vc0.length();
4005 double v1 = vc1.length();
4006 // Avoid zero div but check equality.
4007 if (abs(v0 - v1) < p_allowed_precision_error) {
4008 return true;
4009 } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) {
4010 return false;
4011 }
4012 // Check axis.
4013 if (vc0.normalized().dot(vc1.normalized()) >= 1.0 - p_allowed_angular_error * 2.0) {
4014 v0 = abs(v0);
4015 v1 = abs(v1);
4016 double ratio = v0 < v1 ? v0 / v1 : v1 / v0;
4017 if (ratio >= 1.0 - p_allowed_velocity_err) {
4018 return true;
4019 }
4020 }
4021 return false;
4022}
4023
4024bool Animation::_vector3_track_optimize_key(const TKey<Vector3> t0, const TKey<Vector3> t1, const TKey<Vector3> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) {
4025 // Remove overlapping keys.
4026 if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) {
4027 return true;
4028 }
4029 if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) {
4030 return true;
4031 }
4032 // Calc velocities.
4033 Vector3 vc0 = (t1.value - t0.value) / (t1.time - t0.time);
4034 Vector3 vc1 = (t2.value - t1.value) / (t2.time - t1.time);
4035 double v0 = vc0.length();
4036 double v1 = vc1.length();
4037 // Avoid zero div but check equality.
4038 if (abs(v0 - v1) < p_allowed_precision_error) {
4039 return true;
4040 } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) {
4041 return false;
4042 }
4043 // Check axis.
4044 if (vc0.normalized().dot(vc1.normalized()) >= 1.0 - p_allowed_angular_error * 2.0) {
4045 v0 = abs(v0);
4046 v1 = abs(v1);
4047 double ratio = v0 < v1 ? v0 / v1 : v1 / v0;
4048 if (ratio >= 1.0 - p_allowed_velocity_err) {
4049 return true;
4050 }
4051 }
4052 return false;
4053}
4054
4055bool Animation::_quaternion_track_optimize_key(const TKey<Quaternion> t0, const TKey<Quaternion> t1, const TKey<Quaternion> t2, real_t p_allowed_velocity_err, real_t p_allowed_angular_error, real_t p_allowed_precision_error) {
4056 // Remove overlapping keys.
4057 if (Math::is_equal_approx(t0.time, t1.time) || Math::is_equal_approx(t1.time, t2.time)) {
4058 return true;
4059 }
4060 if ((t0.value - t1.value).length() < p_allowed_precision_error && (t1.value - t2.value).length() < p_allowed_precision_error) {
4061 return true;
4062 }
4063 // Check axis.
4064 Quaternion q0 = t0.value * t1.value * t0.value.inverse();
4065 Quaternion q1 = t1.value * t2.value * t1.value.inverse();
4066 if (q0.get_axis().dot(q1.get_axis()) >= 1.0 - p_allowed_angular_error * 2.0) {
4067 double a0 = Math::acos(t0.value.dot(t1.value));
4068 double a1 = Math::acos(t1.value.dot(t2.value));
4069 if (a0 + a1 >= Math_PI) {
4070 return false; // Rotation is more than 180 deg, keep key.
4071 }
4072 // Calc velocities.
4073 double v0 = a0 / (t1.time - t0.time);
4074 double v1 = a1 / (t2.time - t1.time);
4075 // Avoid zero div but check equality.
4076 if (abs(v0 - v1) < p_allowed_precision_error) {
4077 return true;
4078 } else if (abs(v0) < p_allowed_precision_error || abs(v1) < p_allowed_precision_error) {
4079 return false;
4080 }
4081 double ratio = v0 < v1 ? v0 / v1 : v1 / v0;
4082 if (ratio >= 1.0 - p_allowed_velocity_err) {
4083 return true;
4084 }
4085 }
4086 return false;
4087}
4088
4089void Animation::_position_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) {
4090 ERR_FAIL_INDEX(p_idx, tracks.size());
4091 ERR_FAIL_COND(tracks[p_idx]->type != TYPE_POSITION_3D);
4092 PositionTrack *tt = static_cast<PositionTrack *>(tracks[p_idx]);
4093
4094 int i = 0;
4095 while (i < tt->positions.size() - 2) {
4096 TKey<Vector3> t0 = tt->positions[i];
4097 TKey<Vector3> t1 = tt->positions[i + 1];
4098 TKey<Vector3> t2 = tt->positions[i + 2];
4099
4100 bool erase = _vector3_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4101 if (erase) {
4102 tt->positions.remove_at(i + 1);
4103 } else {
4104 i++;
4105 }
4106 }
4107
4108 if (tt->positions.size() == 2) {
4109 if ((tt->positions[0].value - tt->positions[1].value).length() < p_allowed_precision_error) {
4110 tt->positions.remove_at(1);
4111 }
4112 }
4113}
4114
4115void Animation::_rotation_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) {
4116 ERR_FAIL_INDEX(p_idx, tracks.size());
4117 ERR_FAIL_COND(tracks[p_idx]->type != TYPE_ROTATION_3D);
4118 RotationTrack *rt = static_cast<RotationTrack *>(tracks[p_idx]);
4119
4120 int i = 0;
4121 while (i < rt->rotations.size() - 2) {
4122 TKey<Quaternion> t0 = rt->rotations[i];
4123 TKey<Quaternion> t1 = rt->rotations[i + 1];
4124 TKey<Quaternion> t2 = rt->rotations[i + 2];
4125
4126 bool erase = _quaternion_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4127 if (erase) {
4128 rt->rotations.remove_at(i + 1);
4129 } else {
4130 i++;
4131 }
4132 }
4133
4134 if (rt->rotations.size() == 2) {
4135 if ((rt->rotations[0].value - rt->rotations[1].value).length() < p_allowed_precision_error) {
4136 rt->rotations.remove_at(1);
4137 }
4138 }
4139}
4140
4141void Animation::_scale_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) {
4142 ERR_FAIL_INDEX(p_idx, tracks.size());
4143 ERR_FAIL_COND(tracks[p_idx]->type != TYPE_SCALE_3D);
4144 ScaleTrack *st = static_cast<ScaleTrack *>(tracks[p_idx]);
4145
4146 int i = 0;
4147 while (i < st->scales.size() - 2) {
4148 TKey<Vector3> t0 = st->scales[i];
4149 TKey<Vector3> t1 = st->scales[i + 1];
4150 TKey<Vector3> t2 = st->scales[i + 2];
4151
4152 bool erase = _vector3_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4153 if (erase) {
4154 st->scales.remove_at(i + 1);
4155 } else {
4156 i++;
4157 }
4158 }
4159
4160 if (st->scales.size() == 2) {
4161 if ((st->scales[0].value - st->scales[1].value).length() < p_allowed_precision_error) {
4162 st->scales.remove_at(1);
4163 }
4164 }
4165}
4166
4167void Animation::_blend_shape_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_precision_error) {
4168 ERR_FAIL_INDEX(p_idx, tracks.size());
4169 ERR_FAIL_COND(tracks[p_idx]->type != TYPE_BLEND_SHAPE);
4170 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(tracks[p_idx]);
4171
4172 int i = 0;
4173 while (i < bst->blend_shapes.size() - 2) {
4174 TKey<float> t0 = bst->blend_shapes[i];
4175 TKey<float> t1 = bst->blend_shapes[i + 1];
4176 TKey<float> t2 = bst->blend_shapes[i + 2];
4177
4178 bool erase = _float_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_precision_error);
4179 if (erase) {
4180 bst->blend_shapes.remove_at(i + 1);
4181 } else {
4182 i++;
4183 }
4184 }
4185
4186 if (bst->blend_shapes.size() == 2) {
4187 if (abs(bst->blend_shapes[0].value - bst->blend_shapes[1].value) < p_allowed_precision_error) {
4188 bst->blend_shapes.remove_at(1);
4189 }
4190 }
4191}
4192
4193void Animation::_value_track_optimize(int p_idx, real_t p_allowed_velocity_err, real_t p_allowed_angular_err, real_t p_allowed_precision_error) {
4194 ERR_FAIL_INDEX(p_idx, tracks.size());
4195 ERR_FAIL_COND(tracks[p_idx]->type != TYPE_VALUE);
4196 ValueTrack *vt = static_cast<ValueTrack *>(tracks[p_idx]);
4197 if (vt->values.size() == 0) {
4198 return;
4199 }
4200 Variant::Type type = vt->values[0].value.get_type();
4201
4202 // Special case for angle interpolation.
4203 bool is_using_angle = vt->interpolation == Animation::INTERPOLATION_LINEAR_ANGLE || vt->interpolation == Animation::INTERPOLATION_CUBIC_ANGLE;
4204 int i = 0;
4205 while (i < vt->values.size() - 2) {
4206 bool erase = false;
4207 switch (type) {
4208 case Variant::FLOAT: {
4209 TKey<float> t0;
4210 TKey<float> t1;
4211 TKey<float> t2;
4212 t0.time = vt->values[i].time;
4213 t1.time = vt->values[i + 1].time;
4214 t2.time = vt->values[i + 2].time;
4215 t0.value = vt->values[i].value;
4216 t1.value = vt->values[i + 1].value;
4217 t2.value = vt->values[i + 2].value;
4218 if (is_using_angle) {
4219 float diff1 = fmod(t1.value - t0.value, Math_TAU);
4220 t1.value = t0.value + fmod(2.0 * diff1, Math_TAU) - diff1;
4221 float diff2 = fmod(t2.value - t1.value, Math_TAU);
4222 t2.value = t1.value + fmod(2.0 * diff2, Math_TAU) - diff2;
4223 if (abs(abs(diff1) + abs(diff2)) >= Math_PI) {
4224 break; // Rotation is more than 180 deg, keep key.
4225 }
4226 }
4227 erase = _float_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_precision_error);
4228 } break;
4229 case Variant::VECTOR2: {
4230 TKey<Vector2> t0;
4231 TKey<Vector2> t1;
4232 TKey<Vector2> t2;
4233 t0.time = vt->values[i].time;
4234 t1.time = vt->values[i + 1].time;
4235 t2.time = vt->values[i + 2].time;
4236 t0.value = vt->values[i].value;
4237 t1.value = vt->values[i + 1].value;
4238 t2.value = vt->values[i + 2].value;
4239 erase = _vector2_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4240 } break;
4241 case Variant::VECTOR3: {
4242 TKey<Vector3> t0;
4243 TKey<Vector3> t1;
4244 TKey<Vector3> t2;
4245 t0.time = vt->values[i].time;
4246 t1.time = vt->values[i + 1].time;
4247 t2.time = vt->values[i + 2].time;
4248 t0.value = vt->values[i].value;
4249 t1.value = vt->values[i + 1].value;
4250 t2.value = vt->values[i + 2].value;
4251 erase = _vector3_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4252 } break;
4253 case Variant::QUATERNION: {
4254 TKey<Quaternion> t0;
4255 TKey<Quaternion> t1;
4256 TKey<Quaternion> t2;
4257 t0.time = vt->values[i].time;
4258 t1.time = vt->values[i + 1].time;
4259 t2.time = vt->values[i + 2].time;
4260 t0.value = vt->values[i].value;
4261 t1.value = vt->values[i + 1].value;
4262 t2.value = vt->values[i + 2].value;
4263 erase = _quaternion_track_optimize_key(t0, t1, t2, p_allowed_velocity_err, p_allowed_angular_err, p_allowed_precision_error);
4264 } break;
4265 default: {
4266 } break;
4267 }
4268
4269 if (erase) {
4270 vt->values.remove_at(i + 1);
4271 } else {
4272 i++;
4273 }
4274 }
4275
4276 if (vt->values.size() == 2) {
4277 bool single_key = false;
4278 switch (type) {
4279 case Variant::FLOAT: {
4280 float val_0 = vt->values[0].value;
4281 float val_1 = vt->values[1].value;
4282 if (is_using_angle) {
4283 float diff1 = fmod(val_1 - val_0, Math_TAU);
4284 val_1 = val_0 + fmod(2.0 * diff1, Math_TAU) - diff1;
4285 }
4286 single_key = abs(val_0 - val_1) < p_allowed_precision_error;
4287 } break;
4288 case Variant::VECTOR2: {
4289 Vector2 val_0 = vt->values[0].value;
4290 Vector2 val_1 = vt->values[1].value;
4291 single_key = (val_0 - val_1).length() < p_allowed_precision_error;
4292 } break;
4293 case Variant::VECTOR3: {
4294 Vector3 val_0 = vt->values[0].value;
4295 Vector3 val_1 = vt->values[1].value;
4296 single_key = (val_0 - val_1).length() < p_allowed_precision_error;
4297 } break;
4298 case Variant::QUATERNION: {
4299 Quaternion val_0 = vt->values[0].value;
4300 Quaternion val_1 = vt->values[1].value;
4301 single_key = (val_0 - val_1).length() < p_allowed_precision_error;
4302 } break;
4303 default: {
4304 } break;
4305 }
4306 if (single_key) {
4307 vt->values.remove_at(1);
4308 }
4309 }
4310}
4311
4312void Animation::optimize(real_t p_allowed_velocity_err, real_t p_allowed_angular_err, int p_precision) {
4313 real_t precision = Math::pow(0.1, p_precision);
4314 for (int i = 0; i < tracks.size(); i++) {
4315 if (track_is_compressed(i)) {
4316 continue; //not possible to optimize compressed track
4317 }
4318 if (tracks[i]->type == TYPE_POSITION_3D) {
4319 _position_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision);
4320 } else if (tracks[i]->type == TYPE_ROTATION_3D) {
4321 _rotation_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision);
4322 } else if (tracks[i]->type == TYPE_SCALE_3D) {
4323 _scale_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision);
4324 } else if (tracks[i]->type == TYPE_BLEND_SHAPE) {
4325 _blend_shape_track_optimize(i, p_allowed_velocity_err, precision);
4326 } else if (tracks[i]->type == TYPE_VALUE) {
4327 _value_track_optimize(i, p_allowed_velocity_err, p_allowed_angular_err, precision);
4328 }
4329 }
4330}
4331
4332#define print_animc(m_str)
4333//#define print_animc(m_str) print_line(m_str);
4334
4335struct AnimationCompressionDataState {
4336 enum {
4337 MIN_OPTIMIZE_PACKETS = 5,
4338 MAX_PACKETS = 16
4339 };
4340
4341 uint32_t components = 3;
4342 LocalVector<uint8_t> data; // Committed packets.
4343 struct PacketData {
4344 int32_t data[3] = { 0, 0, 0 };
4345 uint32_t frame = 0;
4346 };
4347
4348 float split_tolerance = 1.5;
4349
4350 LocalVector<PacketData> temp_packets;
4351
4352 //used for rollback if the new frame does not fit
4353 int32_t validated_packet_count = -1;
4354
4355 static int32_t _compute_delta16_signed(int32_t p_from, int32_t p_to) {
4356 int32_t delta = p_to - p_from;
4357 if (delta > 32767) {
4358 return delta - 65536; // use wrap around
4359 } else if (delta < -32768) {
4360 return 65536 + delta; // use wrap around
4361 }
4362 return delta;
4363 }
4364
4365 static uint32_t _compute_shift_bits_signed(int32_t p_delta) {
4366 if (p_delta == 0) {
4367 return 0;
4368 } else if (p_delta < 0) {
4369 p_delta = ABS(p_delta) - 1;
4370 if (p_delta == 0) {
4371 return 1;
4372 }
4373 }
4374 return nearest_shift(p_delta);
4375 }
4376
4377 void _compute_max_shifts(uint32_t p_from, uint32_t p_to, uint32_t *max_shifts, uint32_t &max_frame_delta_shift) const {
4378 for (uint32_t j = 0; j < components; j++) {
4379 max_shifts[j] = 0;
4380 }
4381 max_frame_delta_shift = 0;
4382
4383 for (uint32_t i = p_from + 1; i <= p_to; i++) {
4384 int32_t frame_delta = temp_packets[i].frame - temp_packets[i - 1].frame;
4385 max_frame_delta_shift = MAX(max_frame_delta_shift, nearest_shift(frame_delta));
4386 for (uint32_t j = 0; j < components; j++) {
4387 int32_t diff = _compute_delta16_signed(temp_packets[i - 1].data[j], temp_packets[i].data[j]);
4388 uint32_t shift = _compute_shift_bits_signed(diff);
4389 max_shifts[j] = MAX(shift, max_shifts[j]);
4390 }
4391 }
4392 }
4393
4394 bool insert_key(uint32_t p_frame, const Vector3i &p_key) {
4395 if (temp_packets.size() == MAX_PACKETS) {
4396 commit_temp_packets();
4397 }
4398 PacketData packet;
4399 packet.frame = p_frame;
4400 for (int i = 0; i < 3; i++) {
4401 ERR_FAIL_COND_V(p_key[i] > 65535, false); // Sanity check
4402 packet.data[i] = p_key[i];
4403 }
4404
4405 temp_packets.push_back(packet);
4406
4407 if (temp_packets.size() >= MIN_OPTIMIZE_PACKETS) {
4408 uint32_t max_shifts[3] = { 0, 0, 0 }; // Base sizes, 16 bit
4409 uint32_t max_frame_delta_shift = 0;
4410 // Compute the average shift before the packet was added
4411 _compute_max_shifts(0, temp_packets.size() - 2, max_shifts, max_frame_delta_shift);
4412
4413 float prev_packet_size_avg = 0;
4414 prev_packet_size_avg = float(1 << max_frame_delta_shift);
4415 for (uint32_t i = 0; i < components; i++) {
4416 prev_packet_size_avg += float(1 << max_shifts[i]);
4417 }
4418 prev_packet_size_avg /= float(1 + components);
4419
4420 _compute_max_shifts(temp_packets.size() - 2, temp_packets.size() - 1, max_shifts, max_frame_delta_shift);
4421
4422 float new_packet_size_avg = 0;
4423 new_packet_size_avg = float(1 << max_frame_delta_shift);
4424 for (uint32_t i = 0; i < components; i++) {
4425 new_packet_size_avg += float(1 << max_shifts[i]);
4426 }
4427 new_packet_size_avg /= float(1 + components);
4428
4429 print_animc("packet count: " + rtos(temp_packets.size() - 1) + " size avg " + rtos(prev_packet_size_avg) + " new avg " + rtos(new_packet_size_avg));
4430 float ratio = (prev_packet_size_avg < new_packet_size_avg) ? (new_packet_size_avg / prev_packet_size_avg) : (prev_packet_size_avg / new_packet_size_avg);
4431
4432 if (ratio > split_tolerance) {
4433 print_animc("split!");
4434 temp_packets.resize(temp_packets.size() - 1);
4435 commit_temp_packets();
4436 temp_packets.push_back(packet);
4437 }
4438 }
4439
4440 return temp_packets.size() == 1; // First key
4441 }
4442
4443 uint32_t get_temp_packet_size() const {
4444 if (temp_packets.size() == 0) {
4445 return 0;
4446 } else if (temp_packets.size() == 1) {
4447 return components == 1 ? 4 : 8; // 1 component packet is 16 bits and 16 bits unused. 3 component packets is 48 bits and 16 bits unused
4448 }
4449 uint32_t max_shifts[3] = { 0, 0, 0 }; //base sizes, 16 bit
4450 uint32_t max_frame_delta_shift = 0;
4451
4452 _compute_max_shifts(0, temp_packets.size() - 1, max_shifts, max_frame_delta_shift);
4453
4454 uint32_t size_bits = 16; //base value (all 4 bits of shift sizes for x,y,z,time)
4455 size_bits += max_frame_delta_shift * (temp_packets.size() - 1); //times
4456 for (uint32_t j = 0; j < components; j++) {
4457 size_bits += 16; //base value
4458 uint32_t shift = max_shifts[j];
4459 if (shift > 0) {
4460 shift += 1; //if not zero, add sign bit
4461 }
4462 size_bits += shift * (temp_packets.size() - 1);
4463 }
4464 if (size_bits % 8 != 0) { //wrap to 8 bits
4465 size_bits += 8 - (size_bits % 8);
4466 }
4467 uint32_t size_bytes = size_bits / 8; //wrap to words
4468 if (size_bytes % 4 != 0) {
4469 size_bytes += 4 - (size_bytes % 4);
4470 }
4471 return size_bytes;
4472 }
4473
4474 static void _push_bits(LocalVector<uint8_t> &data, uint32_t &r_buffer, uint32_t &r_bits_used, uint32_t p_value, uint32_t p_bits) {
4475 r_buffer |= p_value << r_bits_used;
4476 r_bits_used += p_bits;
4477 while (r_bits_used >= 8) {
4478 uint8_t byte = r_buffer & 0xFF;
4479 data.push_back(byte);
4480 r_buffer >>= 8;
4481 r_bits_used -= 8;
4482 }
4483 }
4484
4485 void commit_temp_packets() {
4486 if (temp_packets.size() == 0) {
4487 return; // Nothing to do.
4488 }
4489//#define DEBUG_PACKET_PUSH
4490#ifdef DEBUG_PACKET_PUSH
4491#ifndef _MSC_VER
4492#warning Debugging packet push, disable this code in production to gain a bit more import performance.
4493#endif
4494 uint32_t debug_packet_push = get_temp_packet_size();
4495 uint32_t debug_data_size = data.size();
4496#endif
4497 // Store header
4498
4499 uint8_t header[8];
4500 uint32_t header_bytes = 0;
4501 for (uint32_t i = 0; i < components; i++) {
4502 encode_uint16(temp_packets[0].data[i], &header[header_bytes]);
4503 header_bytes += 2;
4504 }
4505
4506 uint32_t max_shifts[3] = { 0, 0, 0 }; //base sizes, 16 bit
4507 uint32_t max_frame_delta_shift = 0;
4508
4509 if (temp_packets.size() > 1) {
4510 _compute_max_shifts(0, temp_packets.size() - 1, max_shifts, max_frame_delta_shift);
4511 uint16_t shift_header = (max_frame_delta_shift - 1) << 12;
4512 for (uint32_t i = 0; i < components; i++) {
4513 shift_header |= max_shifts[i] << (4 * i);
4514 }
4515
4516 encode_uint16(shift_header, &header[header_bytes]);
4517 header_bytes += 2;
4518 }
4519
4520 while (header_bytes < 8 && header_bytes % 4 != 0) { // First cond needed to silence wrong GCC warning.
4521 header[header_bytes++] = 0;
4522 }
4523
4524 for (uint32_t i = 0; i < header_bytes; i++) {
4525 data.push_back(header[i]);
4526 }
4527
4528 if (temp_packets.size() == 1) {
4529 temp_packets.clear();
4530 validated_packet_count = 0;
4531 return; //only header stored, nothing else to do
4532 }
4533
4534 uint32_t bit_buffer = 0;
4535 uint32_t bits_used = 0;
4536
4537 for (uint32_t i = 1; i < temp_packets.size(); i++) {
4538 uint32_t frame_delta = temp_packets[i].frame - temp_packets[i - 1].frame;
4539 _push_bits(data, bit_buffer, bits_used, frame_delta, max_frame_delta_shift);
4540
4541 for (uint32_t j = 0; j < components; j++) {
4542 if (max_shifts[j] == 0) {
4543 continue; // Zero delta, do not store
4544 }
4545 int32_t delta = _compute_delta16_signed(temp_packets[i - 1].data[j], temp_packets[i].data[j]);
4546
4547 ERR_FAIL_COND(delta < -32768 || delta > 32767); //sanity check
4548
4549 uint16_t deltau;
4550 if (delta < 0) {
4551 deltau = (ABS(delta) - 1) | (1 << max_shifts[j]);
4552 } else {
4553 deltau = delta;
4554 }
4555 _push_bits(data, bit_buffer, bits_used, deltau, max_shifts[j] + 1); // Include sign bit
4556 }
4557 }
4558 if (bits_used != 0) {
4559 ERR_FAIL_COND(bit_buffer > 0xFF); // Sanity check
4560 data.push_back(bit_buffer);
4561 }
4562
4563 while (data.size() % 4 != 0) {
4564 data.push_back(0); //pad to align with 4
4565 }
4566
4567 temp_packets.clear();
4568 validated_packet_count = 0;
4569
4570#ifdef DEBUG_PACKET_PUSH
4571 ERR_FAIL_COND((data.size() - debug_data_size) != debug_packet_push);
4572#endif
4573 }
4574};
4575
4576struct AnimationCompressionTimeState {
4577 struct Packet {
4578 uint32_t frame;
4579 uint32_t offset;
4580 uint32_t count;
4581 };
4582
4583 LocalVector<Packet> packets;
4584 //used for rollback
4585 int32_t key_index = 0;
4586 int32_t validated_packet_count = 0;
4587 int32_t validated_key_index = -1;
4588 bool needs_start_frame = false;
4589};
4590
4591Vector3i Animation::_compress_key(uint32_t p_track, const AABB &p_bounds, int32_t p_key, float p_time) {
4592 Vector3i values;
4593 TrackType tt = track_get_type(p_track);
4594 switch (tt) {
4595 case TYPE_POSITION_3D: {
4596 Vector3 pos;
4597 if (p_key >= 0) {
4598 position_track_get_key(p_track, p_key, &pos);
4599 } else {
4600 try_position_track_interpolate(p_track, p_time, &pos);
4601 }
4602 pos = (pos - p_bounds.position) / p_bounds.size;
4603 for (int j = 0; j < 3; j++) {
4604 values[j] = CLAMP(int32_t(pos[j] * 65535.0), 0, 65535);
4605 }
4606 } break;
4607 case TYPE_ROTATION_3D: {
4608 Quaternion rot;
4609 if (p_key >= 0) {
4610 rotation_track_get_key(p_track, p_key, &rot);
4611 } else {
4612 try_rotation_track_interpolate(p_track, p_time, &rot);
4613 }
4614 Vector3 axis = rot.get_axis();
4615 float angle = rot.get_angle();
4616 angle = Math::fposmod(double(angle), double(Math_PI * 2.0));
4617 Vector2 oct = axis.octahedron_encode();
4618 Vector3 rot_norm(oct.x, oct.y, angle / (Math_PI * 2.0)); // high resolution rotation in 0-1 angle.
4619
4620 for (int j = 0; j < 3; j++) {
4621 values[j] = CLAMP(int32_t(rot_norm[j] * 65535.0), 0, 65535);
4622 }
4623 } break;
4624 case TYPE_SCALE_3D: {
4625 Vector3 scale;
4626 if (p_key >= 0) {
4627 scale_track_get_key(p_track, p_key, &scale);
4628 } else {
4629 try_scale_track_interpolate(p_track, p_time, &scale);
4630 }
4631 scale = (scale - p_bounds.position) / p_bounds.size;
4632 for (int j = 0; j < 3; j++) {
4633 values[j] = CLAMP(int32_t(scale[j] * 65535.0), 0, 65535);
4634 }
4635 } break;
4636 case TYPE_BLEND_SHAPE: {
4637 float blend;
4638 if (p_key >= 0) {
4639 blend_shape_track_get_key(p_track, p_key, &blend);
4640 } else {
4641 try_blend_shape_track_interpolate(p_track, p_time, &blend);
4642 }
4643
4644 blend = (blend / float(Compression::BLEND_SHAPE_RANGE)) * 0.5 + 0.5;
4645 values[0] = CLAMP(int32_t(blend * 65535.0), 0, 65535);
4646 } break;
4647 default: {
4648 ERR_FAIL_V(Vector3i()); //sanity check
4649 } break;
4650 }
4651
4652 return values;
4653}
4654
4655struct AnimationCompressionBufferBitsRead {
4656 uint32_t buffer = 0;
4657 uint32_t used = 0;
4658 const uint8_t *src_data = nullptr;
4659
4660 _FORCE_INLINE_ uint32_t read(uint32_t p_bits) {
4661 uint32_t output = 0;
4662 uint32_t written = 0;
4663 while (p_bits > 0) {
4664 if (used == 0) {
4665 used = 8;
4666 buffer = *src_data;
4667 src_data++;
4668 }
4669 uint32_t to_write = MIN(used, p_bits);
4670 output |= (buffer & ((1 << to_write) - 1)) << written;
4671 buffer >>= to_write;
4672 used -= to_write;
4673 p_bits -= to_write;
4674 written += to_write;
4675 }
4676 return output;
4677 }
4678};
4679
4680void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tolerance) {
4681 ERR_FAIL_COND_MSG(compression.enabled, "This animation is already compressed");
4682
4683 p_split_tolerance = CLAMP(p_split_tolerance, 1.1, 8.0);
4684 compression.pages.clear();
4685
4686 uint32_t base_page_size = 0; // Before compressing pages, compute how large the "end page" datablock is.
4687 LocalVector<uint32_t> tracks_to_compress;
4688 LocalVector<AABB> track_bounds;
4689 const uint32_t time_packet_size = 4;
4690
4691 const uint32_t track_header_size = 4 + 4 + 4; // pointer to time (4 bytes), amount of time keys (4 bytes) pointer to track data (4 bytes)
4692
4693 for (int i = 0; i < get_track_count(); i++) {
4694 TrackType type = track_get_type(i);
4695 if (type != TYPE_POSITION_3D && type != TYPE_ROTATION_3D && type != TYPE_SCALE_3D && type != TYPE_BLEND_SHAPE) {
4696 continue;
4697 }
4698 if (track_get_key_count(i) == 0) {
4699 continue; //do not compress, no keys
4700 }
4701 base_page_size += track_header_size; //pointer to beginning of each track timeline and amount of time keys
4702 base_page_size += time_packet_size; //for end of track time marker
4703 base_page_size += (type == TYPE_BLEND_SHAPE) ? 4 : 8; // at least the end of track packet (at much 8 bytes). This could be less, but have to be pessimistic.
4704 tracks_to_compress.push_back(i);
4705
4706 AABB bounds;
4707
4708 if (type == TYPE_POSITION_3D) {
4709 AABB aabb;
4710 int kcount = track_get_key_count(i);
4711 for (int j = 0; j < kcount; j++) {
4712 Vector3 pos;
4713 position_track_get_key(i, j, &pos);
4714 if (j == 0) {
4715 aabb.position = pos;
4716 } else {
4717 aabb.expand_to(pos);
4718 }
4719 }
4720 for (int j = 0; j < 3; j++) {
4721 // Can't have zero.
4722 if (aabb.size[j] < CMP_EPSILON) {
4723 aabb.size[j] = CMP_EPSILON;
4724 }
4725 }
4726 bounds = aabb;
4727 }
4728 if (type == TYPE_SCALE_3D) {
4729 AABB aabb;
4730 int kcount = track_get_key_count(i);
4731 for (int j = 0; j < kcount; j++) {
4732 Vector3 scale;
4733 scale_track_get_key(i, j, &scale);
4734 if (j == 0) {
4735 aabb.position = scale;
4736 } else {
4737 aabb.expand_to(scale);
4738 }
4739 }
4740 for (int j = 0; j < 3; j++) {
4741 // Can't have zero.
4742 if (aabb.size[j] < CMP_EPSILON) {
4743 aabb.size[j] = CMP_EPSILON;
4744 }
4745 }
4746 bounds = aabb;
4747 }
4748
4749 track_bounds.push_back(bounds);
4750 }
4751
4752 if (tracks_to_compress.size() == 0) {
4753 return; //nothing to compress
4754 }
4755
4756 print_animc("Anim Compression:");
4757 print_animc("-----------------");
4758 print_animc("Tracks to compress: " + itos(tracks_to_compress.size()));
4759
4760 uint32_t current_frame = 0;
4761 uint32_t base_page_frame = 0;
4762 double frame_len = 1.0 / double(p_fps);
4763 const uint32_t max_frames_per_page = 65536;
4764
4765 print_animc("Frame Len: " + rtos(frame_len));
4766
4767 LocalVector<AnimationCompressionDataState> data_tracks;
4768 LocalVector<AnimationCompressionTimeState> time_tracks;
4769
4770 data_tracks.resize(tracks_to_compress.size());
4771 time_tracks.resize(tracks_to_compress.size());
4772
4773 uint32_t needed_min_page_size = base_page_size;
4774 for (uint32_t i = 0; i < data_tracks.size(); i++) {
4775 data_tracks[i].split_tolerance = p_split_tolerance;
4776 if (track_get_type(tracks_to_compress[i]) == TYPE_BLEND_SHAPE) {
4777 data_tracks[i].components = 1;
4778 } else {
4779 data_tracks[i].components = 3;
4780 }
4781 needed_min_page_size += data_tracks[i].data.size() + data_tracks[i].get_temp_packet_size();
4782 }
4783 for (uint32_t i = 0; i < time_tracks.size(); i++) {
4784 needed_min_page_size += time_tracks[i].packets.size() * 4; // time packet is 32 bits
4785 }
4786 ERR_FAIL_COND_MSG(p_page_size < needed_min_page_size, "Cannot compress with the given page size");
4787
4788 while (true) {
4789 // Begin by finding the keyframe in all tracks with the time closest to the current time
4790 const uint32_t FRAME_MAX = 0xFFFFFFFF;
4791 const int32_t NO_TRACK_FOUND = -1;
4792 uint32_t best_frame = FRAME_MAX;
4793 uint32_t best_invalid_frame = FRAME_MAX;
4794 int32_t best_frame_track = NO_TRACK_FOUND; // Default is -1, which means all keyframes for this page are exhausted.
4795 bool start_frame = false;
4796
4797 for (uint32_t i = 0; i < tracks_to_compress.size(); i++) {
4798 uint32_t uncomp_track = tracks_to_compress[i];
4799
4800 if (time_tracks[i].key_index == track_get_key_count(uncomp_track)) {
4801 if (time_tracks[i].needs_start_frame) {
4802 start_frame = true;
4803 best_frame = base_page_frame;
4804 best_frame_track = i;
4805 time_tracks[i].needs_start_frame = false;
4806 break;
4807 } else {
4808 continue; // This track is exhausted (all keys were added already), don't consider.
4809 }
4810 }
4811
4812 uint32_t key_frame = double(track_get_key_time(uncomp_track, time_tracks[i].key_index)) / frame_len;
4813
4814 if (time_tracks[i].needs_start_frame && key_frame > base_page_frame) {
4815 start_frame = true;
4816 best_frame = base_page_frame;
4817 best_frame_track = i;
4818 time_tracks[i].needs_start_frame = false;
4819 break;
4820 }
4821
4822 ERR_FAIL_COND(key_frame < base_page_frame); // Sanity check, should never happen
4823
4824 if (key_frame - base_page_frame >= max_frames_per_page) {
4825 // Invalid because beyond the max frames allowed per page
4826 best_invalid_frame = MIN(best_invalid_frame, key_frame);
4827 } else if (key_frame < best_frame) {
4828 best_frame = key_frame;
4829 best_frame_track = i;
4830 }
4831 }
4832
4833 print_animc("*KEY*: Current Frame: " + itos(current_frame) + " Best Frame: " + rtos(best_frame) + " Best Track: " + itos(best_frame_track) + " Start: " + String(start_frame ? "true" : "false"));
4834
4835 if (!start_frame && best_frame > current_frame) {
4836 // Any case where the current frame advanced, either because nothing was found or because something was found greater than the current one.
4837 print_animc("\tAdvance Condition.");
4838 bool rollback = false;
4839
4840 // The frame has advanced, time to validate the previous frame
4841 uint32_t current_page_size = base_page_size;
4842 for (const AnimationCompressionDataState &state : data_tracks) {
4843 uint32_t track_size = state.data.size(); // track size
4844 track_size += state.get_temp_packet_size(); // Add the temporary data
4845 if (track_size > Compression::MAX_DATA_TRACK_SIZE) {
4846 rollback = true; //track to large, time track can't point to keys any longer, because key offset is 12 bits
4847 break;
4848 }
4849 current_page_size += track_size;
4850 }
4851 for (const AnimationCompressionTimeState &state : time_tracks) {
4852 current_page_size += state.packets.size() * 4; // time packet is 32 bits
4853 }
4854
4855 if (!rollback && current_page_size > p_page_size) {
4856 rollback = true;
4857 }
4858
4859 print_animc("\tCurrent Page Size: " + itos(current_page_size) + "/" + itos(p_page_size) + " Rollback? " + String(rollback ? "YES!" : "no"));
4860
4861 if (rollback) {
4862 // Not valid any longer, so rollback and commit page
4863
4864 for (AnimationCompressionDataState &state : data_tracks) {
4865 state.temp_packets.resize(state.validated_packet_count);
4866 }
4867 for (AnimationCompressionTimeState &state : time_tracks) {
4868 state.key_index = state.validated_key_index; //rollback key
4869 state.packets.resize(state.validated_packet_count);
4870 }
4871
4872 } else {
4873 // All valid, so save rollback information
4874 for (AnimationCompressionDataState &state : data_tracks) {
4875 state.validated_packet_count = state.temp_packets.size();
4876 }
4877 for (AnimationCompressionTimeState &state : time_tracks) {
4878 state.validated_key_index = state.key_index;
4879 state.validated_packet_count = state.packets.size();
4880 }
4881
4882 // Accept this frame as the frame being processed (as long as it exists)
4883 if (best_frame != FRAME_MAX) {
4884 current_frame = best_frame;
4885 print_animc("\tValidated, New Current Frame: " + itos(current_frame));
4886 }
4887 }
4888
4889 if (rollback || best_frame == FRAME_MAX) {
4890 // Commit the page if had to rollback or if no track was found
4891 print_animc("\tCommiting page...");
4892
4893 // The end frame for the page depends entirely on whether its valid or
4894 // no more keys were found.
4895 // If not valid, then the end frame is the current frame (as this means the current frame is being rolled back
4896 // If valid, then the end frame is the next invalid one (in case more frames exist), or the current frame in case no more frames exist.
4897 uint32_t page_end_frame = (rollback || best_frame == FRAME_MAX) ? current_frame : best_invalid_frame;
4898
4899 print_animc("\tEnd Frame: " + itos(page_end_frame) + ", " + rtos(page_end_frame * frame_len) + "s");
4900
4901 // Add finalizer frames and commit pending tracks
4902 uint32_t finalizer_local_frame = page_end_frame - base_page_frame;
4903
4904 uint32_t total_page_size = 0;
4905
4906 for (uint32_t i = 0; i < data_tracks.size(); i++) {
4907 if (data_tracks[i].temp_packets.size() == 0 || (data_tracks[i].temp_packets[data_tracks[i].temp_packets.size() - 1].frame) < finalizer_local_frame) {
4908 // Add finalizer frame if it makes sense
4909 Vector3i values = _compress_key(tracks_to_compress[i], track_bounds[i], -1, page_end_frame * frame_len);
4910
4911 bool first_key = data_tracks[i].insert_key(finalizer_local_frame, values);
4912 if (first_key) {
4913 AnimationCompressionTimeState::Packet p;
4914 p.count = 1;
4915 p.frame = finalizer_local_frame;
4916 p.offset = data_tracks[i].data.size();
4917 time_tracks[i].packets.push_back(p);
4918 } else {
4919 ERR_FAIL_COND(time_tracks[i].packets.size() == 0);
4920 time_tracks[i].packets[time_tracks[i].packets.size() - 1].count++;
4921 }
4922 }
4923
4924 data_tracks[i].commit_temp_packets();
4925 total_page_size += data_tracks[i].data.size();
4926 total_page_size += time_tracks[i].packets.size() * 4;
4927 total_page_size += track_header_size;
4928
4929 print_animc("\tTrack " + itos(i) + " time packets: " + itos(time_tracks[i].packets.size()) + " Packet data: " + itos(data_tracks[i].data.size()));
4930 }
4931
4932 print_animc("\tTotal page Size: " + itos(total_page_size) + "/" + itos(p_page_size));
4933
4934 // Create Page
4935 Vector<uint8_t> page_data;
4936 page_data.resize(total_page_size);
4937 {
4938 uint8_t *page_ptr = page_data.ptrw();
4939 uint32_t base_offset = data_tracks.size() * track_header_size;
4940
4941 for (uint32_t i = 0; i < data_tracks.size(); i++) {
4942 encode_uint32(base_offset, page_ptr + (track_header_size * i + 0));
4943 uint16_t *key_time_ptr = (uint16_t *)(page_ptr + base_offset);
4944 for (uint32_t j = 0; j < time_tracks[i].packets.size(); j++) {
4945 key_time_ptr[j * 2 + 0] = uint16_t(time_tracks[i].packets[j].frame);
4946 uint16_t ptr = time_tracks[i].packets[j].offset / 4;
4947 ptr |= (time_tracks[i].packets[j].count - 1) << 12;
4948 key_time_ptr[j * 2 + 1] = ptr;
4949 base_offset += 4;
4950 }
4951 encode_uint32(time_tracks[i].packets.size(), page_ptr + (track_header_size * i + 4));
4952 encode_uint32(base_offset, page_ptr + (track_header_size * i + 8));
4953 memcpy(page_ptr + base_offset, data_tracks[i].data.ptr(), data_tracks[i].data.size());
4954 base_offset += data_tracks[i].data.size();
4955
4956 //reset track
4957 data_tracks[i].data.clear();
4958 data_tracks[i].temp_packets.clear();
4959 data_tracks[i].validated_packet_count = -1;
4960
4961 time_tracks[i].needs_start_frame = true; //Not required the first time, but from now on it is.
4962 time_tracks[i].packets.clear();
4963 time_tracks[i].validated_key_index = -1;
4964 time_tracks[i].validated_packet_count = 0;
4965 }
4966 }
4967
4968 Compression::Page page;
4969 page.data = page_data;
4970 page.time_offset = base_page_frame * frame_len;
4971 compression.pages.push_back(page);
4972
4973 if (!rollback && best_invalid_frame == FRAME_MAX) {
4974 break; // No more pages to add.
4975 }
4976
4977 current_frame = page_end_frame;
4978 base_page_frame = page_end_frame;
4979
4980 continue; // Start over
4981 }
4982 }
4983
4984 // A key was found for the current frame and all is ok
4985
4986 uint32_t comp_track = best_frame_track;
4987 Vector3i values;
4988
4989 if (start_frame) {
4990 // Interpolate
4991 values = _compress_key(tracks_to_compress[comp_track], track_bounds[comp_track], -1, base_page_frame * frame_len);
4992 } else {
4993 uint32_t key = time_tracks[comp_track].key_index;
4994 values = _compress_key(tracks_to_compress[comp_track], track_bounds[comp_track], key);
4995 time_tracks[comp_track].key_index++; //goto next key (but could be rolled back if beyond page size).
4996 }
4997
4998 bool first_key = data_tracks[comp_track].insert_key(best_frame - base_page_frame, values);
4999 if (first_key) {
5000 AnimationCompressionTimeState::Packet p;
5001 p.count = 1;
5002 p.frame = best_frame - base_page_frame;
5003 p.offset = data_tracks[comp_track].data.size();
5004 time_tracks[comp_track].packets.push_back(p);
5005 } else {
5006 ERR_CONTINUE(time_tracks[comp_track].packets.size() == 0);
5007 time_tracks[comp_track].packets[time_tracks[comp_track].packets.size() - 1].count++;
5008 }
5009 }
5010
5011 compression.bounds = track_bounds;
5012 compression.fps = p_fps;
5013 compression.enabled = true;
5014
5015 for (uint32_t i = 0; i < tracks_to_compress.size(); i++) {
5016 Track *t = tracks[tracks_to_compress[i]];
5017 t->interpolation = INTERPOLATION_LINEAR; //only linear supported
5018 switch (t->type) {
5019 case TYPE_POSITION_3D: {
5020 PositionTrack *tt = static_cast<PositionTrack *>(t);
5021 tt->positions.clear();
5022 tt->compressed_track = i;
5023 } break;
5024 case TYPE_ROTATION_3D: {
5025 RotationTrack *rt = static_cast<RotationTrack *>(t);
5026 rt->rotations.clear();
5027 rt->compressed_track = i;
5028 } break;
5029 case TYPE_SCALE_3D: {
5030 ScaleTrack *st = static_cast<ScaleTrack *>(t);
5031 st->scales.clear();
5032 st->compressed_track = i;
5033 print_line("Scale Bounds " + itos(i) + ": " + track_bounds[i]);
5034 } break;
5035 case TYPE_BLEND_SHAPE: {
5036 BlendShapeTrack *bst = static_cast<BlendShapeTrack *>(t);
5037 bst->blend_shapes.clear();
5038 bst->compressed_track = i;
5039 } break;
5040 default: {
5041 }
5042 }
5043 }
5044#if 1
5045 uint32_t orig_size = 0;
5046 for (int i = 0; i < get_track_count(); i++) {
5047 switch (track_get_type(i)) {
5048 case TYPE_SCALE_3D:
5049 case TYPE_POSITION_3D: {
5050 orig_size += sizeof(TKey<Vector3>) * track_get_key_count(i);
5051 } break;
5052 case TYPE_ROTATION_3D: {
5053 orig_size += sizeof(TKey<Quaternion>) * track_get_key_count(i);
5054 } break;
5055 case TYPE_BLEND_SHAPE: {
5056 orig_size += sizeof(TKey<float>) * track_get_key_count(i);
5057 } break;
5058 default: {
5059 }
5060 }
5061 }
5062
5063 uint32_t new_size = 0;
5064 for (const Compression::Page &page : compression.pages) {
5065 new_size += page.data.size();
5066 }
5067
5068 print_line("Original size: " + itos(orig_size) + " - Compressed size: " + itos(new_size) + " " + String::num(float(new_size) / float(orig_size) * 100, 2) + "% pages: " + itos(compression.pages.size()));
5069#endif
5070}
5071
5072bool Animation::_rotation_interpolate_compressed(uint32_t p_compressed_track, double p_time, Quaternion &r_ret) const {
5073 Vector3i current;
5074 Vector3i next;
5075 double time_current;
5076 double time_next;
5077
5078 if (!_fetch_compressed<3>(p_compressed_track, p_time, current, time_current, next, time_next)) {
5079 return false; //some sort of problem
5080 }
5081
5082 if (time_current >= p_time || time_current == time_next) {
5083 r_ret = _uncompress_quaternion(current);
5084 } else if (p_time >= time_next) {
5085 r_ret = _uncompress_quaternion(next);
5086 } else {
5087 double c = (p_time - time_current) / (time_next - time_current);
5088 Quaternion from = _uncompress_quaternion(current);
5089 Quaternion to = _uncompress_quaternion(next);
5090 r_ret = from.slerp(to, c);
5091 }
5092
5093 return true;
5094}
5095
5096bool Animation::_pos_scale_interpolate_compressed(uint32_t p_compressed_track, double p_time, Vector3 &r_ret) const {
5097 Vector3i current;
5098 Vector3i next;
5099 double time_current;
5100 double time_next;
5101
5102 if (!_fetch_compressed<3>(p_compressed_track, p_time, current, time_current, next, time_next)) {
5103 return false; //some sort of problem
5104 }
5105
5106 if (time_current >= p_time || time_current == time_next) {
5107 r_ret = _uncompress_pos_scale(p_compressed_track, current);
5108 } else if (p_time >= time_next) {
5109 r_ret = _uncompress_pos_scale(p_compressed_track, next);
5110 } else {
5111 double c = (p_time - time_current) / (time_next - time_current);
5112 Vector3 from = _uncompress_pos_scale(p_compressed_track, current);
5113 Vector3 to = _uncompress_pos_scale(p_compressed_track, next);
5114 r_ret = from.lerp(to, c);
5115 }
5116
5117 return true;
5118}
5119bool Animation::_blend_shape_interpolate_compressed(uint32_t p_compressed_track, double p_time, float &r_ret) const {
5120 Vector3i current;
5121 Vector3i next;
5122 double time_current;
5123 double time_next;
5124
5125 if (!_fetch_compressed<1>(p_compressed_track, p_time, current, time_current, next, time_next)) {
5126 return false; //some sort of problem
5127 }
5128
5129 if (time_current >= p_time || time_current == time_next) {
5130 r_ret = _uncompress_blend_shape(current);
5131 } else if (p_time >= time_next) {
5132 r_ret = _uncompress_blend_shape(next);
5133 } else {
5134 float c = (p_time - time_current) / (time_next - time_current);
5135 float from = _uncompress_blend_shape(current);
5136 float to = _uncompress_blend_shape(next);
5137 r_ret = Math::lerp(from, to, c);
5138 }
5139
5140 return true;
5141}
5142
5143template <uint32_t COMPONENTS>
5144bool Animation::_fetch_compressed(uint32_t p_compressed_track, double p_time, Vector3i &r_current_value, double &r_current_time, Vector3i &r_next_value, double &r_next_time, uint32_t *key_index) const {
5145 ERR_FAIL_COND_V(!compression.enabled, false);
5146 ERR_FAIL_UNSIGNED_INDEX_V(p_compressed_track, compression.bounds.size(), false);
5147 p_time = CLAMP(p_time, 0, length);
5148 if (key_index) {
5149 *key_index = 0;
5150 }
5151
5152 double frame_to_sec = 1.0 / double(compression.fps);
5153
5154 int32_t page_index = -1;
5155 for (uint32_t i = 0; i < compression.pages.size(); i++) {
5156 if (compression.pages[i].time_offset > p_time) {
5157 break;
5158 }
5159 page_index = i;
5160 }
5161
5162 ERR_FAIL_COND_V(page_index == -1, false); //should not happen
5163
5164 double page_base_time = compression.pages[page_index].time_offset;
5165 const uint8_t *page_data = compression.pages[page_index].data.ptr();
5166 // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
5167 const uint32_t *indices = (const uint32_t *)page_data;
5168 const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
5169 uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
5170
5171 int32_t packet_idx = 0;
5172 double packet_time = double(time_keys[0]) * frame_to_sec + page_base_time;
5173 uint32_t base_frame = time_keys[0];
5174
5175 for (uint32_t i = 1; i < time_key_count; i++) {
5176 uint32_t f = time_keys[i * 2 + 0];
5177 double frame_time = double(f) * frame_to_sec + page_base_time;
5178
5179 if (frame_time > p_time) {
5180 break;
5181 }
5182
5183 if (key_index) {
5184 (*key_index) += (time_keys[(i - 1) * 2 + 1] >> 12) + 1;
5185 }
5186
5187 packet_idx = i;
5188 packet_time = frame_time;
5189 base_frame = f;
5190 }
5191
5192 const uint8_t *data_keys_base = (const uint8_t *)&page_data[indices[p_compressed_track * 3 + 2]];
5193
5194 uint16_t time_key_data = time_keys[packet_idx * 2 + 1];
5195 uint32_t data_offset = (time_key_data & 0xFFF) * 4; // lower 12 bits
5196 uint32_t data_count = (time_key_data >> 12) + 1;
5197
5198 const uint16_t *data_key = (const uint16_t *)(data_keys_base + data_offset);
5199
5200 uint16_t decode[COMPONENTS];
5201 uint16_t decode_next[COMPONENTS];
5202
5203 for (uint32_t i = 0; i < COMPONENTS; i++) {
5204 decode[i] = data_key[i];
5205 decode_next[i] = data_key[i];
5206 }
5207
5208 double next_time = packet_time;
5209
5210 if (p_time > packet_time) { // If its equal or less, then don't bother
5211 if (data_count > 1) {
5212 //decode forward
5213 uint32_t bit_width[COMPONENTS];
5214 for (uint32_t i = 0; i < COMPONENTS; i++) {
5215 bit_width[i] = (data_key[COMPONENTS] >> (i * 4)) & 0xF;
5216 }
5217
5218 uint32_t frame_bit_width = (data_key[COMPONENTS] >> 12) + 1;
5219
5220 AnimationCompressionBufferBitsRead buffer;
5221
5222 buffer.src_data = (const uint8_t *)&data_key[COMPONENTS + 1];
5223
5224 for (uint32_t i = 1; i < data_count; i++) {
5225 uint32_t frame_delta = buffer.read(frame_bit_width);
5226 base_frame += frame_delta;
5227
5228 for (uint32_t j = 0; j < COMPONENTS; j++) {
5229 if (bit_width[j] == 0) {
5230 continue; // do none
5231 }
5232 uint32_t valueu = buffer.read(bit_width[j] + 1);
5233 bool sign = valueu & (1 << bit_width[j]);
5234 int16_t value = valueu & ((1 << bit_width[j]) - 1);
5235 if (sign) {
5236 value = -value - 1;
5237 }
5238
5239 decode_next[j] += value;
5240 }
5241
5242 next_time = double(base_frame) * frame_to_sec + page_base_time;
5243 if (p_time < next_time) {
5244 break;
5245 }
5246
5247 packet_time = next_time;
5248
5249 for (uint32_t j = 0; j < COMPONENTS; j++) {
5250 decode[j] = decode_next[j];
5251 }
5252
5253 if (key_index) {
5254 (*key_index)++;
5255 }
5256 }
5257 }
5258
5259 if (p_time > next_time) { // > instead of >= because if its equal, then it will be properly interpolated anyway
5260 // So, the last frame found still has a time that is less than the required frame,
5261 // will have to interpolate with the first frame of the next timekey.
5262
5263 if ((uint32_t)packet_idx < time_key_count - 1) { // Sanity check but should not matter much, otherwise current next packet is last packet
5264
5265 uint16_t time_key_data_next = time_keys[(packet_idx + 1) * 2 + 1];
5266 uint32_t data_offset_next = (time_key_data_next & 0xFFF) * 4; // Lower 12 bits
5267
5268 const uint16_t *data_key_next = (const uint16_t *)(data_keys_base + data_offset_next);
5269 base_frame = time_keys[(packet_idx + 1) * 2 + 0];
5270 next_time = double(base_frame) * frame_to_sec + page_base_time;
5271 for (uint32_t i = 0; i < COMPONENTS; i++) {
5272 decode_next[i] = data_key_next[i];
5273 }
5274 }
5275 }
5276 }
5277
5278 r_current_time = packet_time;
5279 r_next_time = next_time;
5280
5281 for (uint32_t i = 0; i < COMPONENTS; i++) {
5282 r_current_value[i] = decode[i];
5283 r_next_value[i] = decode_next[i];
5284 }
5285
5286 return true;
5287}
5288
5289template <uint32_t COMPONENTS>
5290void Animation::_get_compressed_key_indices_in_range(uint32_t p_compressed_track, double p_time, double p_delta, List<int> *r_indices) const {
5291 ERR_FAIL_COND(!compression.enabled);
5292 ERR_FAIL_UNSIGNED_INDEX(p_compressed_track, compression.bounds.size());
5293
5294 double frame_to_sec = 1.0 / double(compression.fps);
5295 uint32_t key_index = 0;
5296
5297 for (uint32_t p = 0; p < compression.pages.size(); p++) {
5298 if (compression.pages[p].time_offset >= p_time + p_delta) {
5299 // Page beyond range
5300 return;
5301 }
5302
5303 // Page within range
5304
5305 uint32_t page_index = p;
5306
5307 double page_base_time = compression.pages[page_index].time_offset;
5308 const uint8_t *page_data = compression.pages[page_index].data.ptr();
5309 // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
5310 const uint32_t *indices = (const uint32_t *)page_data;
5311 const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
5312 uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
5313
5314 for (uint32_t i = 0; i < time_key_count; i++) {
5315 uint32_t f = time_keys[i * 2 + 0];
5316 double frame_time = f * frame_to_sec + page_base_time;
5317 if (frame_time >= p_time + p_delta) {
5318 return;
5319 } else if (frame_time >= p_time) {
5320 r_indices->push_back(key_index);
5321 }
5322
5323 key_index++;
5324
5325 const uint8_t *data_keys_base = (const uint8_t *)&page_data[indices[p_compressed_track * 3 + 2]];
5326
5327 uint16_t time_key_data = time_keys[i * 2 + 1];
5328 uint32_t data_offset = (time_key_data & 0xFFF) * 4; // lower 12 bits
5329 uint32_t data_count = (time_key_data >> 12) + 1;
5330
5331 const uint16_t *data_key = (const uint16_t *)(data_keys_base + data_offset);
5332
5333 if (data_count > 1) {
5334 //decode forward
5335 uint32_t bit_width[COMPONENTS];
5336 for (uint32_t j = 0; j < COMPONENTS; j++) {
5337 bit_width[j] = (data_key[COMPONENTS] >> (j * 4)) & 0xF;
5338 }
5339
5340 uint32_t frame_bit_width = (data_key[COMPONENTS] >> 12) + 1;
5341
5342 AnimationCompressionBufferBitsRead buffer;
5343
5344 buffer.src_data = (const uint8_t *)&data_key[COMPONENTS + 1];
5345
5346 for (uint32_t j = 1; j < data_count; j++) {
5347 uint32_t frame_delta = buffer.read(frame_bit_width);
5348 f += frame_delta;
5349
5350 frame_time = f * frame_to_sec + page_base_time;
5351 if (frame_time >= p_time + p_delta) {
5352 return;
5353 } else if (frame_time >= p_time) {
5354 r_indices->push_back(key_index);
5355 }
5356
5357 for (uint32_t k = 0; k < COMPONENTS; k++) {
5358 if (bit_width[k] == 0) {
5359 continue; // do none
5360 }
5361 buffer.read(bit_width[k] + 1); // skip
5362 }
5363
5364 key_index++;
5365 }
5366 }
5367 }
5368 }
5369}
5370
5371int Animation::_get_compressed_key_count(uint32_t p_compressed_track) const {
5372 ERR_FAIL_COND_V(!compression.enabled, -1);
5373 ERR_FAIL_UNSIGNED_INDEX_V(p_compressed_track, compression.bounds.size(), -1);
5374
5375 int key_count = 0;
5376
5377 for (const Compression::Page &page : compression.pages) {
5378 const uint8_t *page_data = page.data.ptr();
5379 // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
5380 const uint32_t *indices = (const uint32_t *)page_data;
5381 const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
5382 uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
5383
5384 for (uint32_t j = 0; j < time_key_count; j++) {
5385 key_count += (time_keys[j * 2 + 1] >> 12) + 1;
5386 }
5387 }
5388
5389 return key_count;
5390}
5391
5392Quaternion Animation::_uncompress_quaternion(const Vector3i &p_value) const {
5393 Vector3 axis = Vector3::octahedron_decode(Vector2(float(p_value.x) / 65535.0, float(p_value.y) / 65535.0));
5394 float angle = (float(p_value.z) / 65535.0) * 2.0 * Math_PI;
5395 return Quaternion(axis, angle);
5396}
5397Vector3 Animation::_uncompress_pos_scale(uint32_t p_compressed_track, const Vector3i &p_value) const {
5398 Vector3 pos_norm(float(p_value.x) / 65535.0, float(p_value.y) / 65535.0, float(p_value.z) / 65535.0);
5399 return compression.bounds[p_compressed_track].position + pos_norm * compression.bounds[p_compressed_track].size;
5400}
5401float Animation::_uncompress_blend_shape(const Vector3i &p_value) const {
5402 float bsn = float(p_value.x) / 65535.0;
5403 return (bsn * 2.0 - 1.0) * float(Compression::BLEND_SHAPE_RANGE);
5404}
5405
5406template <uint32_t COMPONENTS>
5407bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_index, Vector3i &r_value, double &r_time) const {
5408 ERR_FAIL_COND_V(!compression.enabled, false);
5409 ERR_FAIL_UNSIGNED_INDEX_V(p_compressed_track, compression.bounds.size(), false);
5410
5411 for (const Compression::Page &page : compression.pages) {
5412 const uint8_t *page_data = page.data.ptr();
5413 // Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
5414 const uint32_t *indices = (const uint32_t *)page_data;
5415 const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
5416 uint32_t time_key_count = indices[p_compressed_track * 3 + 1];
5417 const uint8_t *data_keys_base = (const uint8_t *)&page_data[indices[p_compressed_track * 3 + 2]];
5418
5419 for (uint32_t j = 0; j < time_key_count; j++) {
5420 uint32_t subkeys = (time_keys[j * 2 + 1] >> 12) + 1;
5421 if ((uint32_t)p_index < subkeys) {
5422 uint16_t data_offset = (time_keys[j * 2 + 1] & 0xFFF) * 4;
5423
5424 const uint16_t *data_key = (const uint16_t *)(data_keys_base + data_offset);
5425
5426 uint16_t frame = time_keys[j * 2 + 0];
5427 uint16_t decode[COMPONENTS];
5428
5429 for (uint32_t k = 0; k < COMPONENTS; k++) {
5430 decode[k] = data_key[k];
5431 }
5432
5433 if (p_index > 0) {
5434 uint32_t bit_width[COMPONENTS];
5435 for (uint32_t k = 0; k < COMPONENTS; k++) {
5436 bit_width[k] = (data_key[COMPONENTS] >> (k * 4)) & 0xF;
5437 }
5438 uint32_t frame_bit_width = (data_key[COMPONENTS] >> 12) + 1;
5439
5440 AnimationCompressionBufferBitsRead buffer;
5441 buffer.src_data = (const uint8_t *)&data_key[COMPONENTS + 1];
5442
5443 for (int k = 0; k < p_index; k++) {
5444 uint32_t frame_delta = buffer.read(frame_bit_width);
5445 frame += frame_delta;
5446 for (uint32_t l = 0; l < COMPONENTS; l++) {
5447 if (bit_width[l] == 0) {
5448 continue; // do none
5449 }
5450 uint32_t valueu = buffer.read(bit_width[l] + 1);
5451 bool sign = valueu & (1 << bit_width[l]);
5452 int16_t value = valueu & ((1 << bit_width[l]) - 1);
5453 if (sign) {
5454 value = -value - 1;
5455 }
5456
5457 decode[l] += value;
5458 }
5459 }
5460 }
5461
5462 r_time = page.time_offset + double(frame) / double(compression.fps);
5463 for (uint32_t l = 0; l < COMPONENTS; l++) {
5464 r_value[l] = decode[l];
5465 }
5466
5467 return true;
5468
5469 } else {
5470 p_index -= subkeys;
5471 }
5472 }
5473 }
5474
5475 return false;
5476}
5477
5478// Helper math functions for Variant.
5479Variant Animation::add_variant(const Variant &a, const Variant &b) {
5480 if (a.get_type() != b.get_type()) {
5481 return a;
5482 }
5483
5484 switch (a.get_type()) {
5485 case Variant::NIL: {
5486 return Variant();
5487 }
5488 case Variant::BOOL: {
5489 return (a.operator real_t()) + (b.operator real_t()); // It is cast for interpolation.
5490 }
5491 case Variant::RECT2: {
5492 const Rect2 ra = a.operator Rect2();
5493 const Rect2 rb = b.operator Rect2();
5494 return Rect2(ra.position + rb.position, ra.size + rb.size);
5495 }
5496 case Variant::RECT2I: {
5497 const Rect2i ra = a.operator Rect2i();
5498 const Rect2i rb = b.operator Rect2i();
5499 return Rect2i(ra.position + rb.position, ra.size + rb.size);
5500 }
5501 case Variant::PLANE: {
5502 const Plane pa = a.operator Plane();
5503 const Plane pb = b.operator Plane();
5504 return Plane(pa.normal + pb.normal, pa.d + pb.d);
5505 }
5506 case Variant::AABB: {
5507 const ::AABB aa = a.operator ::AABB();
5508 const ::AABB ab = b.operator ::AABB();
5509 return ::AABB(aa.position + ab.position, aa.size + ab.size);
5510 }
5511 case Variant::BASIS: {
5512 return (a.operator Basis()) * (b.operator Basis());
5513 }
5514 case Variant::QUATERNION: {
5515 return (a.operator Quaternion()) * (b.operator Quaternion());
5516 }
5517 case Variant::TRANSFORM2D: {
5518 return (a.operator Transform2D()) * (b.operator Transform2D());
5519 }
5520 case Variant::TRANSFORM3D: {
5521 return (a.operator Transform3D()) * (b.operator Transform3D());
5522 }
5523 default: {
5524 return Variant::evaluate(Variant::OP_ADD, a, b);
5525 }
5526 }
5527}
5528
5529Variant Animation::subtract_variant(const Variant &a, const Variant &b) {
5530 if (a.get_type() != b.get_type()) {
5531 return a;
5532 }
5533
5534 switch (a.get_type()) {
5535 case Variant::NIL: {
5536 return Variant();
5537 }
5538 case Variant::BOOL: {
5539 return (a.operator real_t()) - (b.operator real_t()); // It is cast for interpolation.
5540 }
5541 case Variant::RECT2: {
5542 const Rect2 ra = a.operator Rect2();
5543 const Rect2 rb = b.operator Rect2();
5544 return Rect2(ra.position - rb.position, ra.size - rb.size);
5545 }
5546 case Variant::RECT2I: {
5547 const Rect2i ra = a.operator Rect2i();
5548 const Rect2i rb = b.operator Rect2i();
5549 return Rect2i(ra.position - rb.position, ra.size - rb.size);
5550 }
5551 case Variant::PLANE: {
5552 const Plane pa = a.operator Plane();
5553 const Plane pb = b.operator Plane();
5554 return Plane(pa.normal - pb.normal, pa.d - pb.d);
5555 }
5556 case Variant::AABB: {
5557 const ::AABB aa = a.operator ::AABB();
5558 const ::AABB ab = b.operator ::AABB();
5559 return ::AABB(aa.position - ab.position, aa.size - ab.size);
5560 }
5561 case Variant::BASIS: {
5562 return (b.operator Basis()).inverse() * (a.operator Basis());
5563 }
5564 case Variant::QUATERNION: {
5565 return (b.operator Quaternion()).inverse() * (a.operator Quaternion());
5566 }
5567 case Variant::TRANSFORM2D: {
5568 return (b.operator Transform2D()).affine_inverse() * (a.operator Transform2D());
5569 }
5570 case Variant::TRANSFORM3D: {
5571 return (b.operator Transform3D()).affine_inverse() * (a.operator Transform3D());
5572 }
5573 default: {
5574 return Variant::evaluate(Variant::OP_SUBTRACT, a, b);
5575 }
5576 }
5577}
5578
5579Variant Animation::blend_variant(const Variant &a, const Variant &b, float c) {
5580 if (a.get_type() != b.get_type()) {
5581 if (a.is_num() && b.is_num()) {
5582 double va = a;
5583 double vb = b;
5584 return va + vb * c;
5585 }
5586 return a;
5587 }
5588
5589 switch (a.get_type()) {
5590 case Variant::NIL: {
5591 return Variant();
5592 }
5593 case Variant::INT: {
5594 return int64_t((a.operator int64_t()) + (b.operator int64_t()) * c + 0.5);
5595 }
5596 case Variant::FLOAT: {
5597 return (a.operator double()) + (b.operator double()) * c;
5598 }
5599 case Variant::VECTOR2: {
5600 return (a.operator Vector2()) + (b.operator Vector2()) * c;
5601 }
5602 case Variant::VECTOR2I: {
5603 const Vector2i va = a.operator Vector2i();
5604 const Vector2i vb = b.operator Vector2i();
5605 return Vector2i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5));
5606 }
5607 case Variant::RECT2: {
5608 const Rect2 ra = a.operator Rect2();
5609 const Rect2 rb = b.operator Rect2();
5610 return Rect2(ra.position + rb.position * c, ra.size + rb.size * c);
5611 }
5612 case Variant::RECT2I: {
5613 const Rect2i ra = a.operator Rect2i();
5614 const Rect2i rb = b.operator Rect2i();
5615 return Rect2i(int32_t(ra.position.x + rb.position.x * c + 0.5), int32_t(ra.position.y + rb.position.y * c + 0.5), int32_t(ra.size.x + rb.size.x * c + 0.5), int32_t(ra.size.y + rb.size.y * c + 0.5));
5616 }
5617 case Variant::VECTOR3: {
5618 return (a.operator Vector3()) + (b.operator Vector3()) * c;
5619 }
5620 case Variant::VECTOR3I: {
5621 const Vector3i va = a.operator Vector3i();
5622 const Vector3i vb = b.operator Vector3i();
5623 return Vector3i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5), int32_t(va.z + vb.z * c + 0.5));
5624 }
5625 case Variant::VECTOR4: {
5626 return (a.operator Vector4()) + (b.operator Vector4()) * c;
5627 }
5628 case Variant::VECTOR4I: {
5629 const Vector4i va = a.operator Vector4i();
5630 const Vector4i vb = b.operator Vector4i();
5631 return Vector4i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5), int32_t(va.z + vb.z * c + 0.5), int32_t(va.w + vb.w * c + 0.5));
5632 }
5633 case Variant::PLANE: {
5634 const Plane pa = a.operator Plane();
5635 const Plane pb = b.operator Plane();
5636 return Plane(pa.normal + pb.normal * c, pa.d + pb.d * c);
5637 }
5638 case Variant::COLOR: {
5639 return (a.operator Color()) + (b.operator Color()) * c;
5640 }
5641 case Variant::AABB: {
5642 const ::AABB aa = a.operator ::AABB();
5643 const ::AABB ab = b.operator ::AABB();
5644 return ::AABB(aa.position + ab.position * c, aa.size + ab.size * c);
5645 }
5646 case Variant::BASIS: {
5647 return (a.operator Basis()) + (b.operator Basis()) * c;
5648 }
5649 case Variant::QUATERNION: {
5650 return (a.operator Quaternion()) * Quaternion().slerp((b.operator Quaternion()), c);
5651 }
5652 case Variant::TRANSFORM2D: {
5653 return (a.operator Transform2D()) * Transform2D().interpolate_with((b.operator Transform2D()), c);
5654 }
5655 case Variant::TRANSFORM3D: {
5656 return (a.operator Transform3D()) * Transform3D().interpolate_with((b.operator Transform3D()), c);
5657 }
5658 default: {
5659 return c < 0.5 ? a : b;
5660 }
5661 }
5662}
5663
5664Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float c) {
5665 if (a.get_type() != b.get_type()) {
5666 if (a.is_num() && b.is_num()) {
5667 double va = a;
5668 double vb = b;
5669 return va + (vb - va) * c;
5670 }
5671 return a;
5672 }
5673
5674 switch (a.get_type()) {
5675 case Variant::NIL: {
5676 return Variant();
5677 }
5678 case Variant::INT: {
5679 const int64_t va = a.operator int64_t();
5680 return int64_t(va + ((b.operator int64_t()) - va) * c);
5681 }
5682 case Variant::FLOAT: {
5683 const double va = a.operator double();
5684 return va + ((b.operator double()) - va) * c;
5685 }
5686 case Variant::VECTOR2: {
5687 return (a.operator Vector2()).lerp(b.operator Vector2(), c);
5688 }
5689 case Variant::VECTOR2I: {
5690 const Vector2i va = a.operator Vector2i();
5691 const Vector2i vb = b.operator Vector2i();
5692 return Vector2i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c));
5693 }
5694 case Variant::RECT2: {
5695 const Rect2 ra = a.operator Rect2();
5696 const Rect2 rb = b.operator Rect2();
5697 return Rect2(ra.position.lerp(rb.position, c), ra.size.lerp(rb.size, c));
5698 }
5699 case Variant::RECT2I: {
5700 const Rect2i ra = a.operator Rect2i();
5701 const Rect2i rb = b.operator Rect2i();
5702 return Rect2i(int32_t(ra.position.x + (rb.position.x - ra.position.x) * c), int32_t(ra.position.y + (rb.position.y - ra.position.y) * c), int32_t(ra.size.x + (rb.size.x - ra.size.x) * c), int32_t(ra.size.y + (rb.size.y - ra.size.y) * c));
5703 }
5704 case Variant::VECTOR3: {
5705 return (a.operator Vector3()).lerp(b.operator Vector3(), c);
5706 }
5707 case Variant::VECTOR3I: {
5708 const Vector3i va = a.operator Vector3i();
5709 const Vector3i vb = b.operator Vector3i();
5710 return Vector3i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c), int32_t(va.z + (vb.z - va.z) * c));
5711 }
5712 case Variant::VECTOR4: {
5713 return (a.operator Vector4()).lerp(b.operator Vector4(), c);
5714 }
5715 case Variant::VECTOR4I: {
5716 const Vector4i va = a.operator Vector4i();
5717 const Vector4i vb = b.operator Vector4i();
5718 return Vector4i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c), int32_t(va.z + (vb.z - va.z) * c), int32_t(va.w + (vb.w - va.w) * c));
5719 }
5720 case Variant::PLANE: {
5721 const Plane pa = a.operator Plane();
5722 const Plane pb = b.operator Plane();
5723 return Plane(pa.normal.lerp(pb.normal, c), pa.d + (pb.d - pa.d) * c);
5724 }
5725 case Variant::COLOR: {
5726 return (a.operator Color()).lerp(b.operator Color(), c);
5727 }
5728 case Variant::AABB: {
5729 const ::AABB aa = a.operator ::AABB();
5730 const ::AABB ab = b.operator ::AABB();
5731 return ::AABB(aa.position.lerp(ab.position, c), aa.size.lerp(ab.size, c));
5732 }
5733 case Variant::BASIS: {
5734 return (a.operator Basis()).lerp(b.operator Basis(), c);
5735 }
5736 case Variant::QUATERNION: {
5737 return (a.operator Quaternion()).slerp(b.operator Quaternion(), c);
5738 }
5739 case Variant::TRANSFORM2D: {
5740 return (a.operator Transform2D()).interpolate_with(b.operator Transform2D(), c);
5741 }
5742 case Variant::TRANSFORM3D: {
5743 return (a.operator Transform3D()).interpolate_with(b.operator Transform3D(), c);
5744 }
5745 case Variant::STRING: {
5746 // This is pretty funny and bizarre, but artists like to use it for typewriter effects.
5747 const String sa = a.operator String();
5748 const String sb = b.operator String();
5749 String dst;
5750 int sa_len = sa.length();
5751 int sb_len = sb.length();
5752 int csize = sa_len + (sb_len - sa_len) * c;
5753 if (csize == 0) {
5754 return "";
5755 }
5756 dst.resize(csize + 1);
5757 dst[csize] = 0;
5758 int split = csize / 2;
5759
5760 for (int i = 0; i < csize; i++) {
5761 char32_t chr = ' ';
5762
5763 if (i < split) {
5764 if (i < sa.length()) {
5765 chr = sa[i];
5766 } else if (i < sb.length()) {
5767 chr = sb[i];
5768 }
5769
5770 } else {
5771 if (i < sb.length()) {
5772 chr = sb[i];
5773 } else if (i < sa.length()) {
5774 chr = sa[i];
5775 }
5776 }
5777
5778 dst[i] = chr;
5779 }
5780
5781 return dst;
5782 }
5783 case Variant::PACKED_INT32_ARRAY: {
5784 const Vector<int32_t> arr_a = a;
5785 const Vector<int32_t> arr_b = b;
5786 int sz = arr_a.size();
5787 if (sz == 0 || arr_b.size() != sz) {
5788 return a;
5789 } else {
5790 Vector<int32_t> v;
5791 v.resize(sz);
5792 {
5793 int32_t *vw = v.ptrw();
5794 const int32_t *ar = arr_a.ptr();
5795 const int32_t *br = arr_b.ptr();
5796
5797 Variant va;
5798 for (int i = 0; i < sz; i++) {
5799 va = interpolate_variant(ar[i], br[i], c);
5800 vw[i] = va;
5801 }
5802 }
5803 return v;
5804 }
5805 }
5806 case Variant::PACKED_INT64_ARRAY: {
5807 const Vector<int64_t> arr_a = a;
5808 const Vector<int64_t> arr_b = b;
5809 int sz = arr_a.size();
5810 if (sz == 0 || arr_b.size() != sz) {
5811 return a;
5812 } else {
5813 Vector<int64_t> v;
5814 v.resize(sz);
5815 {
5816 int64_t *vw = v.ptrw();
5817 const int64_t *ar = arr_a.ptr();
5818 const int64_t *br = arr_b.ptr();
5819
5820 Variant va;
5821 for (int i = 0; i < sz; i++) {
5822 va = interpolate_variant(ar[i], br[i], c);
5823 vw[i] = va;
5824 }
5825 }
5826 return v;
5827 }
5828 }
5829 case Variant::PACKED_FLOAT32_ARRAY: {
5830 const Vector<float> arr_a = a;
5831 const Vector<float> arr_b = b;
5832 int sz = arr_a.size();
5833 if (sz == 0 || arr_b.size() != sz) {
5834 return a;
5835 } else {
5836 Vector<float> v;
5837 v.resize(sz);
5838 {
5839 float *vw = v.ptrw();
5840 const float *ar = arr_a.ptr();
5841 const float *br = arr_b.ptr();
5842
5843 Variant va;
5844 for (int i = 0; i < sz; i++) {
5845 va = interpolate_variant(ar[i], br[i], c);
5846 vw[i] = va;
5847 }
5848 }
5849 return v;
5850 }
5851 }
5852 case Variant::PACKED_FLOAT64_ARRAY: {
5853 const Vector<double> arr_a = a;
5854 const Vector<double> arr_b = b;
5855 int sz = arr_a.size();
5856 if (sz == 0 || arr_b.size() != sz) {
5857 return a;
5858 } else {
5859 Vector<double> v;
5860 v.resize(sz);
5861 {
5862 double *vw = v.ptrw();
5863 const double *ar = arr_a.ptr();
5864 const double *br = arr_b.ptr();
5865
5866 Variant va;
5867 for (int i = 0; i < sz; i++) {
5868 va = interpolate_variant(ar[i], br[i], c);
5869 vw[i] = va;
5870 }
5871 }
5872 return v;
5873 }
5874 }
5875 case Variant::PACKED_VECTOR2_ARRAY: {
5876 const Vector<Vector2> arr_a = a;
5877 const Vector<Vector2> arr_b = b;
5878 int sz = arr_a.size();
5879 if (sz == 0 || arr_b.size() != sz) {
5880 return a;
5881 } else {
5882 Vector<Vector2> v;
5883 v.resize(sz);
5884 {
5885 Vector2 *vw = v.ptrw();
5886 const Vector2 *ar = arr_a.ptr();
5887 const Vector2 *br = arr_b.ptr();
5888
5889 for (int i = 0; i < sz; i++) {
5890 vw[i] = ar[i].lerp(br[i], c);
5891 }
5892 }
5893 return v;
5894 }
5895 }
5896 case Variant::PACKED_VECTOR3_ARRAY: {
5897 const Vector<Vector3> arr_a = a;
5898 const Vector<Vector3> arr_b = b;
5899 int sz = arr_a.size();
5900 if (sz == 0 || arr_b.size() != sz) {
5901 return a;
5902 } else {
5903 Vector<Vector3> v;
5904 v.resize(sz);
5905 {
5906 Vector3 *vw = v.ptrw();
5907 const Vector3 *ar = arr_a.ptr();
5908 const Vector3 *br = arr_b.ptr();
5909
5910 for (int i = 0; i < sz; i++) {
5911 vw[i] = ar[i].lerp(br[i], c);
5912 }
5913 }
5914 return v;
5915 }
5916 }
5917 case Variant::PACKED_COLOR_ARRAY: {
5918 const Vector<Color> arr_a = a;
5919 const Vector<Color> arr_b = b;
5920 int sz = arr_a.size();
5921 if (sz == 0 || arr_b.size() != sz) {
5922 return a;
5923 } else {
5924 Vector<Color> v;
5925 v.resize(sz);
5926 {
5927 Color *vw = v.ptrw();
5928 const Color *ar = arr_a.ptr();
5929 const Color *br = arr_b.ptr();
5930
5931 for (int i = 0; i < sz; i++) {
5932 vw[i] = ar[i].lerp(br[i], c);
5933 }
5934 }
5935 return v;
5936 }
5937 }
5938 default: {
5939 return c < 0.5 ? a : b;
5940 }
5941 }
5942}
5943
5944Animation::Animation() {
5945}
5946
5947Animation::~Animation() {
5948 for (int i = 0; i < tracks.size(); i++) {
5949 memdelete(tracks[i]);
5950 }
5951}
5952