diff options
Diffstat (limited to 'scene/resources/animation.cpp')
-rw-r--r-- | scene/resources/animation.cpp | 174 |
1 files changed, 123 insertions, 51 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 3700e87839..e3cf9183a0 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -317,7 +317,7 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { Vector<real_t> times = d["times"]; Vector<real_t> values = d["points"]; - ERR_FAIL_COND_V(times.size() * 5 != values.size(), false); + ERR_FAIL_COND_V(times.size() * 6 != values.size(), false); if (times.size()) { int valcount = times.size(); @@ -330,11 +330,12 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { for (int i = 0; i < valcount; i++) { bt->values.write[i].time = rt[i]; bt->values.write[i].transition = 0; //unused in bezier - bt->values.write[i].value.value = rv[i * 5 + 0]; - bt->values.write[i].value.in_handle.x = rv[i * 5 + 1]; - bt->values.write[i].value.in_handle.y = rv[i * 5 + 2]; - bt->values.write[i].value.out_handle.x = rv[i * 5 + 3]; - bt->values.write[i].value.out_handle.y = rv[i * 5 + 4]; + bt->values.write[i].value.value = rv[i * 6 + 0]; + bt->values.write[i].value.in_handle.x = rv[i * 6 + 1]; + bt->values.write[i].value.in_handle.y = rv[i * 6 + 2]; + bt->values.write[i].value.out_handle.x = rv[i * 6 + 3]; + bt->values.write[i].value.out_handle.y = rv[i * 6 + 4]; + bt->values.write[i].value.handle_mode = static_cast<HandleMode>((int)rv[i * 6 + 5]); } } @@ -698,7 +699,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { int kk = bt->values.size(); key_times.resize(kk); - key_points.resize(kk * 5); + key_points.resize(kk * 6); real_t *wti = key_times.ptrw(); real_t *wpo = key_points.ptrw(); @@ -709,11 +710,12 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { for (int i = 0; i < kk; i++) { wti[idx] = vls[i].time; - wpo[idx * 5 + 0] = vls[i].value.value; - wpo[idx * 5 + 1] = vls[i].value.in_handle.x; - wpo[idx * 5 + 2] = vls[i].value.in_handle.y; - wpo[idx * 5 + 3] = vls[i].value.out_handle.x; - wpo[idx * 5 + 4] = vls[i].value.out_handle.y; + wpo[idx * 6 + 0] = vls[i].value.value; + wpo[idx * 6 + 1] = vls[i].value.in_handle.x; + wpo[idx * 6 + 2] = vls[i].value.in_handle.y; + wpo[idx * 6 + 3] = vls[i].value.out_handle.x; + wpo[idx * 6 + 4] = vls[i].value.out_handle.y; + wpo[idx * 6 + 5] = (double)vls[i].value.handle_mode; idx++; } @@ -928,7 +930,7 @@ void Animation::remove_track(int p_track) { } memdelete(t); - tracks.remove(p_track); + tracks.remove_at(p_track); emit_changed(); emit_signal(SceneStringNames::get_singleton()->tracks_changed); } @@ -1318,7 +1320,7 @@ void Animation::track_remove_key(int p_track, int p_idx) { ERR_FAIL_COND(tt->compressed_track >= 0); ERR_FAIL_INDEX(p_idx, tt->positions.size()); - tt->positions.remove(p_idx); + tt->positions.remove_at(p_idx); } break; case TYPE_ROTATION_3D: { @@ -1327,7 +1329,7 @@ void Animation::track_remove_key(int p_track, int p_idx) { ERR_FAIL_COND(rt->compressed_track >= 0); ERR_FAIL_INDEX(p_idx, rt->rotations.size()); - rt->rotations.remove(p_idx); + rt->rotations.remove_at(p_idx); } break; case TYPE_SCALE_3D: { @@ -1336,7 +1338,7 @@ void Animation::track_remove_key(int p_track, int p_idx) { ERR_FAIL_COND(st->compressed_track >= 0); ERR_FAIL_INDEX(p_idx, st->scales.size()); - st->scales.remove(p_idx); + st->scales.remove_at(p_idx); } break; case TYPE_BLEND_SHAPE: { @@ -1345,37 +1347,37 @@ void Animation::track_remove_key(int p_track, int p_idx) { ERR_FAIL_COND(bst->compressed_track >= 0); ERR_FAIL_INDEX(p_idx, bst->blend_shapes.size()); - bst->blend_shapes.remove(p_idx); + bst->blend_shapes.remove_at(p_idx); } break; case TYPE_VALUE: { ValueTrack *vt = static_cast<ValueTrack *>(t); ERR_FAIL_INDEX(p_idx, vt->values.size()); - vt->values.remove(p_idx); + vt->values.remove_at(p_idx); } break; case TYPE_METHOD: { MethodTrack *mt = static_cast<MethodTrack *>(t); ERR_FAIL_INDEX(p_idx, mt->methods.size()); - mt->methods.remove(p_idx); + mt->methods.remove_at(p_idx); } break; case TYPE_BEZIER: { BezierTrack *bz = static_cast<BezierTrack *>(t); ERR_FAIL_INDEX(p_idx, bz->values.size()); - bz->values.remove(p_idx); + bz->values.remove_at(p_idx); } break; case TYPE_AUDIO: { AudioTrack *ad = static_cast<AudioTrack *>(t); ERR_FAIL_INDEX(p_idx, ad->values.size()); - ad->values.remove(p_idx); + ad->values.remove_at(p_idx); } break; case TYPE_ANIMATION: { AnimationTrack *an = static_cast<AnimationTrack *>(t); ERR_FAIL_INDEX(p_idx, an->values.size()); - an->values.remove(p_idx); + an->values.remove_at(p_idx); } break; } @@ -1623,7 +1625,7 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke BezierTrack *bt = static_cast<BezierTrack *>(t); Array arr = p_key; - ERR_FAIL_COND(arr.size() != 5); + ERR_FAIL_COND(arr.size() != 6); TKey<BezierKey> k; k.time = p_time; @@ -1632,6 +1634,7 @@ void Animation::track_insert_key(int p_track, double p_time, const Variant &p_ke k.value.in_handle.y = arr[2]; k.value.out_handle.x = arr[3]; k.value.out_handle.y = arr[4]; + k.value.handle_mode = static_cast<HandleMode>((int)arr[5]); _insert(p_time, bt->values, k); } break; @@ -1770,12 +1773,13 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const { ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant()); Array arr; - arr.resize(5); + arr.resize(6); arr[0] = bt->values[p_key_idx].value.value; arr[1] = bt->values[p_key_idx].value.in_handle.x; arr[2] = bt->values[p_key_idx].value.in_handle.y; arr[3] = bt->values[p_key_idx].value.out_handle.x; arr[4] = bt->values[p_key_idx].value.out_handle.y; + arr[5] = (double)bt->values[p_key_idx].value.handle_mode; return arr; } break; @@ -1901,7 +1905,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, tt->positions.size()); TKey<Vector3> key = tt->positions[p_key_idx]; key.time = p_time; - tt->positions.remove(p_key_idx); + tt->positions.remove_at(p_key_idx); _insert(p_time, tt->positions, key); return; } @@ -1911,7 +1915,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, tt->rotations.size()); TKey<Quaternion> key = tt->rotations[p_key_idx]; key.time = p_time; - tt->rotations.remove(p_key_idx); + tt->rotations.remove_at(p_key_idx); _insert(p_time, tt->rotations, key); return; } @@ -1921,7 +1925,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, tt->scales.size()); TKey<Vector3> key = tt->scales[p_key_idx]; key.time = p_time; - tt->scales.remove(p_key_idx); + tt->scales.remove_at(p_key_idx); _insert(p_time, tt->scales, key); return; } @@ -1931,7 +1935,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, tt->blend_shapes.size()); TKey<float> key = tt->blend_shapes[p_key_idx]; key.time = p_time; - tt->blend_shapes.remove(p_key_idx); + tt->blend_shapes.remove_at(p_key_idx); _insert(p_time, tt->blend_shapes, key); return; } @@ -1940,7 +1944,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, vt->values.size()); TKey<Variant> key = vt->values[p_key_idx]; key.time = p_time; - vt->values.remove(p_key_idx); + vt->values.remove_at(p_key_idx); _insert(p_time, vt->values, key); return; } @@ -1949,7 +1953,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, mt->methods.size()); MethodKey key = mt->methods[p_key_idx]; key.time = p_time; - mt->methods.remove(p_key_idx); + mt->methods.remove_at(p_key_idx); _insert(p_time, mt->methods, key); return; } @@ -1958,7 +1962,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, bt->values.size()); TKey<BezierKey> key = bt->values[p_key_idx]; key.time = p_time; - bt->values.remove(p_key_idx); + bt->values.remove_at(p_key_idx); _insert(p_time, bt->values, key); return; } @@ -1967,7 +1971,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, at->values.size()); TKey<AudioKey> key = at->values[p_key_idx]; key.time = p_time; - at->values.remove(p_key_idx); + at->values.remove_at(p_key_idx); _insert(p_time, at->values, key); return; } @@ -1976,7 +1980,7 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, double p_time) { ERR_FAIL_INDEX(p_key_idx, at->values.size()); TKey<StringName> key = at->values[p_key_idx]; key.time = p_time; - at->values.remove(p_key_idx); + at->values.remove_at(p_key_idx); _insert(p_time, at->values, key); return; } @@ -2144,13 +2148,14 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p ERR_FAIL_INDEX(p_key_idx, bt->values.size()); Array arr = p_value; - ERR_FAIL_COND(arr.size() != 5); + ERR_FAIL_COND(arr.size() != 6); bt->values.write[p_key_idx].value.value = arr[0]; bt->values.write[p_key_idx].value.in_handle.x = arr[1]; bt->values.write[p_key_idx].value.in_handle.y = arr[2]; bt->values.write[p_key_idx].value.out_handle.x = arr[3]; bt->values.write[p_key_idx].value.out_handle.y = arr[4]; + bt->values.write[p_key_idx].value.handle_mode = static_cast<HandleMode>((int)arr[5]); } break; case TYPE_AUDIO: { @@ -3203,7 +3208,7 @@ StringName Animation::method_track_get_name(int p_track, int p_key_idx) const { return pm->methods[p_key_idx].method; } -int 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) { +int 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, const HandleMode p_handle_mode) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1); @@ -3221,6 +3226,7 @@ int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_valu if (k.value.out_handle.x < 0) { k.value.out_handle.x = 0; } + k.value.handle_mode = p_handle_mode; int key = _insert(p_time, bt->values, k); @@ -3229,6 +3235,30 @@ int Animation::bezier_track_insert_key(int p_track, double p_time, real_t p_valu return key; } +void Animation::bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, double p_balanced_value_time_ratio) { + ERR_FAIL_INDEX(p_track, tracks.size()); + Track *t = tracks[p_track]; + ERR_FAIL_COND(t->type != TYPE_BEZIER); + + BezierTrack *bt = static_cast<BezierTrack *>(t); + + ERR_FAIL_INDEX(p_index, bt->values.size()); + + bt->values.write[p_index].value.handle_mode = p_mode; + + if (p_mode == HANDLE_MODE_BALANCED) { + Transform2D xform; + xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio)); + + Vector2 vec_in = xform.xform(bt->values[p_index].value.in_handle); + Vector2 vec_out = xform.xform(bt->values[p_index].value.out_handle); + + bt->values.write[p_index].value.in_handle = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length()); + } + + emit_changed(); +} + void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_value) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; @@ -3242,7 +3272,7 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_va emit_changed(); } -void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle) { +void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_BEZIER); @@ -3251,14 +3281,26 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V ERR_FAIL_INDEX(p_index, bt->values.size()); - bt->values.write[p_index].value.in_handle = p_handle; - if (bt->values[p_index].value.in_handle.x > 0) { - bt->values.write[p_index].value.in_handle.x = 0; + Vector2 in_handle = p_handle; + if (in_handle.x > 0) { + in_handle.x = 0; + } + bt->values.write[p_index].value.in_handle = in_handle; + + if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) { + Transform2D xform; + xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio)); + + Vector2 vec_out = xform.xform(bt->values[p_index].value.out_handle); + Vector2 vec_in = xform.xform(in_handle); + + bt->values.write[p_index].value.out_handle = xform.affine_inverse().xform(-vec_in.normalized() * vec_out.length()); } + emit_changed(); } -void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) { +void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) { ERR_FAIL_INDEX(p_track, tracks.size()); Track *t = tracks[p_track]; ERR_FAIL_COND(t->type != TYPE_BEZIER); @@ -3267,10 +3309,22 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const ERR_FAIL_INDEX(p_index, bt->values.size()); - bt->values.write[p_index].value.out_handle = p_handle; - if (bt->values[p_index].value.out_handle.x < 0) { - bt->values.write[p_index].value.out_handle.x = 0; + Vector2 out_handle = p_handle; + if (out_handle.x < 0) { + out_handle.x = 0; + } + bt->values.write[p_index].value.out_handle = out_handle; + + if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) { + Transform2D xform; + xform.set_scale(Vector2(1.0, 1.0 / p_balanced_value_time_ratio)); + + Vector2 vec_in = xform.xform(bt->values[p_index].value.in_handle); + Vector2 vec_out = xform.xform(out_handle); + + bt->values.write[p_index].value.in_handle = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length()); } + emit_changed(); } @@ -3286,6 +3340,18 @@ real_t Animation::bezier_track_get_key_value(int p_track, int p_index) const { return bt->values[p_index].value.value; } +int Animation::bezier_track_get_key_handle_mode(int p_track, int p_index) const { + ERR_FAIL_INDEX_V(p_track, tracks.size(), 0); + Track *t = tracks[p_track]; + ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0); + + BezierTrack *bt = static_cast<BezierTrack *>(t); + + ERR_FAIL_INDEX_V(p_index, bt->values.size(), 0); + + return bt->values[p_index].value.handle_mode; +} + Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const { ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2()); Track *t = tracks[p_track]; @@ -3613,7 +3679,7 @@ void Animation::track_move_to(int p_track, int p_to_index) { } Track *track = tracks.get(p_track); - tracks.remove(p_track); + tracks.remove_at(p_track); // Take into account that the position of the tracks that come after the one removed will change. tracks.insert(p_to_index > p_track ? p_to_index - 1 : p_to_index, track); @@ -3718,11 +3784,11 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name); ClassDB::bind_method(D_METHOD("method_track_get_params", "track_idx", "key_idx"), &Animation::method_track_get_params); - 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())); + ClassDB::bind_method(D_METHOD("bezier_track_insert_key", "track_idx", "time", "value", "in_handle", "out_handle", "handle_mode"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(Animation::HandleMode::HANDLE_MODE_BALANCED)); ClassDB::bind_method(D_METHOD("bezier_track_set_key_value", "track_idx", "key_idx", "value"), &Animation::bezier_track_set_key_value); - ClassDB::bind_method(D_METHOD("bezier_track_set_key_in_handle", "track_idx", "key_idx", "in_handle"), &Animation::bezier_track_set_key_in_handle); - ClassDB::bind_method(D_METHOD("bezier_track_set_key_out_handle", "track_idx", "key_idx", "out_handle"), &Animation::bezier_track_set_key_out_handle); + 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)); + 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)); ClassDB::bind_method(D_METHOD("bezier_track_get_key_value", "track_idx", "key_idx"), &Animation::bezier_track_get_key_value); ClassDB::bind_method(D_METHOD("bezier_track_get_key_in_handle", "track_idx", "key_idx"), &Animation::bezier_track_get_key_in_handle); @@ -3738,6 +3804,9 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset); ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset); + ClassDB::bind_method(D_METHOD("bezier_track_set_key_handle_mode", "track_idx", "key_idx", "key_handle_mode", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_handle_mode, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("bezier_track_get_key_handle_mode", "track_idx", "key_idx"), &Animation::bezier_track_get_key_handle_mode); + ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key); ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation); ClassDB::bind_method(D_METHOD("animation_track_get_key_animation", "track_idx", "key_idx"), &Animation::animation_track_get_key_animation); @@ -3784,6 +3853,9 @@ void Animation::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_NONE); BIND_ENUM_CONSTANT(LOOP_LINEAR); BIND_ENUM_CONSTANT(LOOP_PINGPONG); + + BIND_ENUM_CONSTANT(HANDLE_MODE_FREE); + BIND_ENUM_CONSTANT(HANDLE_MODE_BALANCED); } void Animation::clear() { @@ -3986,7 +4058,7 @@ void Animation::_position_track_optimize(int p_idx, real_t p_allowed_linear_err, prev_erased = true; } - tt->positions.remove(i); + tt->positions.remove_at(i); i--; } else { @@ -4021,7 +4093,7 @@ void Animation::_rotation_track_optimize(int p_idx, real_t p_allowed_angular_err prev_erased = true; } - tt->rotations.remove(i); + tt->rotations.remove_at(i); i--; } else { @@ -4055,7 +4127,7 @@ void Animation::_scale_track_optimize(int p_idx, real_t p_allowed_linear_err) { prev_erased = true; } - tt->scales.remove(i); + tt->scales.remove_at(i); i--; } else { @@ -4090,7 +4162,7 @@ void Animation::_blend_shape_track_optimize(int p_idx, real_t p_allowed_linear_e prev_erased = true; } - tt->blend_shapes.remove(i); + tt->blend_shapes.remove_at(i); i--; } else { |