Merge pull request #64647 from TokageItLab/auto-tangent
This commit is contained in:
commit
6277448f42
11 changed files with 468 additions and 271 deletions
|
|
@ -313,29 +313,37 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
|
|||
Dictionary d = p_value;
|
||||
ERR_FAIL_COND_V(!d.has("times"), false);
|
||||
ERR_FAIL_COND_V(!d.has("points"), false);
|
||||
|
||||
Vector<real_t> times = d["times"];
|
||||
Vector<real_t> values = d["points"];
|
||||
#ifdef TOOLS_ENABLED
|
||||
ERR_FAIL_COND_V(!d.has("handle_modes"), false);
|
||||
Vector<int> handle_modes = d["handle_modes"];
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
ERR_FAIL_COND_V(times.size() * 6 != values.size(), false);
|
||||
ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
|
||||
|
||||
if (times.size()) {
|
||||
int valcount = times.size();
|
||||
|
||||
const real_t *rt = times.ptr();
|
||||
const real_t *rv = values.ptr();
|
||||
#ifdef TOOLS_ENABLED
|
||||
const int *rh = handle_modes.ptr();
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
bt->values.resize(valcount);
|
||||
|
||||
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 * 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]);
|
||||
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];
|
||||
#ifdef TOOLS_ENABLED
|
||||
bt->values.write[i].value.handle_mode = static_cast<HandleMode>(rh[i]);
|
||||
#endif // TOOLS_ENABLED
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -699,28 +707,39 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
|
|||
int kk = bt->values.size();
|
||||
|
||||
key_times.resize(kk);
|
||||
key_points.resize(kk * 6);
|
||||
key_points.resize(kk * 5);
|
||||
|
||||
real_t *wti = key_times.ptrw();
|
||||
real_t *wpo = key_points.ptrw();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Vector<int> handle_modes;
|
||||
handle_modes.resize(kk);
|
||||
int *whm = handle_modes.ptrw();
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
int idx = 0;
|
||||
|
||||
const TKey<BezierKey> *vls = bt->values.ptr();
|
||||
|
||||
for (int i = 0; i < kk; i++) {
|
||||
wti[idx] = vls[i].time;
|
||||
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;
|
||||
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;
|
||||
#ifdef TOOLS_ENABLED
|
||||
whm[idx] = static_cast<int>(vls[i].value.handle_mode);
|
||||
#endif // TOOLS_ENABLED
|
||||
idx++;
|
||||
}
|
||||
|
||||
d["times"] = key_times;
|
||||
d["points"] = key_points;
|
||||
#ifdef TOOLS_ENABLED
|
||||
d["handle_modes"] = handle_modes;
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
r_ret = d;
|
||||
|
||||
|
|
@ -1626,7 +1645,7 @@ int Animation::track_insert_key(int p_track, double p_time, const Variant &p_key
|
|||
BezierTrack *bt = static_cast<BezierTrack *>(t);
|
||||
|
||||
Array arr = p_key;
|
||||
ERR_FAIL_COND_V(arr.size() != 6, -1);
|
||||
ERR_FAIL_COND_V(arr.size() != 5, -1);
|
||||
|
||||
TKey<BezierKey> k;
|
||||
k.time = p_time;
|
||||
|
|
@ -1635,9 +1654,16 @@ int Animation::track_insert_key(int p_track, double p_time, const Variant &p_key
|
|||
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]);
|
||||
ret = _insert(p_time, bt->values, k);
|
||||
|
||||
Vector<int> key_neighborhood;
|
||||
key_neighborhood.push_back(ret);
|
||||
if (ret > 0) {
|
||||
key_neighborhood.push_back(ret - 1);
|
||||
}
|
||||
if (ret < track_get_key_count(p_track) - 1) {
|
||||
key_neighborhood.push_back(ret + 1);
|
||||
}
|
||||
} break;
|
||||
case TYPE_AUDIO: {
|
||||
AudioTrack *at = static_cast<AudioTrack *>(t);
|
||||
|
|
@ -1776,13 +1802,12 @@ 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(6);
|
||||
arr.resize(5);
|
||||
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;
|
||||
|
|
@ -2151,14 +2176,13 @@ 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() != 6);
|
||||
ERR_FAIL_COND(arr.size() != 5);
|
||||
|
||||
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: {
|
||||
|
|
@ -3347,7 +3371,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, const HandleMode p_handle_mode) {
|
||||
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) {
|
||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
|
||||
Track *t = tracks[p_track];
|
||||
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
|
||||
|
|
@ -3365,7 +3389,6 @@ 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);
|
||||
|
||||
|
|
@ -3374,30 +3397,6 @@ 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];
|
||||
|
|
@ -3408,10 +3407,11 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, real_t p_va
|
|||
ERR_FAIL_INDEX(p_index, bt->values.size());
|
||||
|
||||
bt->values.write[p_index].value.value = p_value;
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) {
|
||||
void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio) {
|
||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
||||
Track *t = tracks[p_track];
|
||||
ERR_FAIL_COND(t->type != TYPE_BEZIER);
|
||||
|
|
@ -3426,7 +3426,11 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
|
|||
}
|
||||
bt->values.write[p_index].value.in_handle = in_handle;
|
||||
|
||||
if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (bt->values[p_index].value.handle_mode == HANDLE_MODE_LINEAR) {
|
||||
bt->values.write[p_index].value.in_handle = Vector2();
|
||||
bt->values.write[p_index].value.out_handle = Vector2();
|
||||
} else 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));
|
||||
|
||||
|
|
@ -3434,12 +3438,15 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
|
|||
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());
|
||||
} else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_MIRRORED) {
|
||||
bt->values.write[p_index].value.out_handle = -in_handle;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio) {
|
||||
void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio) {
|
||||
ERR_FAIL_INDEX(p_track, tracks.size());
|
||||
Track *t = tracks[p_track];
|
||||
ERR_FAIL_COND(t->type != TYPE_BEZIER);
|
||||
|
|
@ -3454,7 +3461,11 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
|
|||
}
|
||||
bt->values.write[p_index].value.out_handle = out_handle;
|
||||
|
||||
if (bt->values[p_index].value.handle_mode == HANDLE_MODE_BALANCED) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (bt->values[p_index].value.handle_mode == HANDLE_MODE_LINEAR) {
|
||||
bt->values.write[p_index].value.in_handle = Vector2();
|
||||
bt->values.write[p_index].value.out_handle = Vector2();
|
||||
} else 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));
|
||||
|
||||
|
|
@ -3462,7 +3473,10 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
|
|||
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());
|
||||
} else if (bt->values[p_index].value.handle_mode == HANDLE_MODE_MIRRORED) {
|
||||
bt->values.write[p_index].value.in_handle = -out_handle;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
|
@ -3479,18 +3493,6 @@ 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];
|
||||
|
|
@ -3515,6 +3517,109 @@ Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) con
|
|||
return bt->values[p_index].value.out_handle;
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void Animation::bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, HandleSetMode p_set_mode) {
|
||||
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;
|
||||
|
||||
switch (p_mode) {
|
||||
case HANDLE_MODE_LINEAR: {
|
||||
bt->values.write[p_index].value.in_handle = Vector2(0, 0);
|
||||
bt->values.write[p_index].value.out_handle = Vector2(0, 0);
|
||||
} break;
|
||||
case HANDLE_MODE_BALANCED:
|
||||
case HANDLE_MODE_MIRRORED: {
|
||||
int prev_key = MAX(0, p_index - 1);
|
||||
int next_key = MIN(bt->values.size() - 1, p_index + 1);
|
||||
if (prev_key == next_key) {
|
||||
break; // Exists only one key.
|
||||
}
|
||||
real_t in_handle_x = 0;
|
||||
real_t in_handle_y = 0;
|
||||
real_t out_handle_x = 0;
|
||||
real_t out_handle_y = 0;
|
||||
if (p_mode == HANDLE_MODE_BALANCED) {
|
||||
// Note:
|
||||
// If p_set_mode == HANDLE_SET_MODE_NONE, I don't know if it should change the Tangent implicitly.
|
||||
// At the least, we need to avoid corrupting the handles when loading animation from the resource.
|
||||
// However, changes made by the Inspector do not go through the BezierEditor,
|
||||
// so if you change from Free to Balanced or Mirrored in Inspector, there is no guarantee that
|
||||
// it is Balanced or Mirrored until there is a handle operation.
|
||||
if (p_set_mode == HANDLE_SET_MODE_RESET) {
|
||||
real_t handle_length = 1.0 / 3.0;
|
||||
in_handle_x = (bt->values[prev_key].time - bt->values[p_index].time) * handle_length;
|
||||
in_handle_y = 0;
|
||||
out_handle_x = (bt->values[next_key].time - bt->values[p_index].time) * handle_length;
|
||||
out_handle_y = 0;
|
||||
bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
|
||||
bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
|
||||
} else if (p_set_mode == HANDLE_SET_MODE_AUTO) {
|
||||
real_t handle_length = 1.0 / 6.0;
|
||||
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);
|
||||
in_handle_x = (bt->values[prev_key].time - bt->values[p_index].time) * handle_length;
|
||||
in_handle_y = in_handle_x * tangent;
|
||||
out_handle_x = (bt->values[next_key].time - bt->values[p_index].time) * handle_length;
|
||||
out_handle_y = out_handle_x * tangent;
|
||||
bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
|
||||
bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
|
||||
}
|
||||
} else {
|
||||
real_t handle_length = 1.0 / 4.0;
|
||||
real_t prev_interval = Math::abs(bt->values[p_index].time - bt->values[prev_key].time);
|
||||
real_t next_interval = Math::abs(bt->values[p_index].time - bt->values[next_key].time);
|
||||
real_t min_time = 0;
|
||||
if (Math::is_zero_approx(prev_interval)) {
|
||||
min_time = next_interval;
|
||||
} else if (Math::is_zero_approx(next_interval)) {
|
||||
min_time = prev_interval;
|
||||
} else {
|
||||
min_time = MIN(prev_interval, next_interval);
|
||||
}
|
||||
if (p_set_mode == HANDLE_SET_MODE_RESET) {
|
||||
in_handle_x = -min_time * handle_length;
|
||||
in_handle_y = 0;
|
||||
out_handle_x = min_time * handle_length;
|
||||
out_handle_y = 0;
|
||||
bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
|
||||
bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
|
||||
} else if (p_set_mode == HANDLE_SET_MODE_AUTO) {
|
||||
real_t tangent = (bt->values[next_key].value.value - bt->values[prev_key].value.value) / min_time;
|
||||
in_handle_x = -min_time * handle_length;
|
||||
in_handle_y = in_handle_x * tangent;
|
||||
out_handle_x = min_time * handle_length;
|
||||
out_handle_y = out_handle_x * tangent;
|
||||
bt->values.write[p_index].value.in_handle = Vector2(in_handle_x, in_handle_y);
|
||||
bt->values.write[p_index].value.out_handle = Vector2(out_handle_x, out_handle_y);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Animation::HandleMode Animation::bezier_track_get_key_handle_mode(int p_track, int p_index) const {
|
||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), HANDLE_MODE_FREE);
|
||||
Track *t = tracks[p_track];
|
||||
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, HANDLE_MODE_FREE);
|
||||
|
||||
BezierTrack *bt = static_cast<BezierTrack *>(t);
|
||||
|
||||
ERR_FAIL_INDEX_V(p_index, bt->values.size(), HANDLE_MODE_FREE);
|
||||
|
||||
return bt->values[p_index].value.handle_mode;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
real_t Animation::bezier_track_interpolate(int p_track, double p_time) const {
|
||||
//this uses a different interpolation scheme
|
||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
|
||||
|
|
@ -3911,7 +4016,7 @@ 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", "handle_mode"), &Animation::bezier_track_insert_key, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(Animation::HandleMode::HANDLE_MODE_BALANCED));
|
||||
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_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", "balanced_value_time_ratio"), &Animation::bezier_track_set_key_in_handle, DEFVAL(1.0));
|
||||
|
|
@ -3931,9 +4036,6 @@ 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);
|
||||
|
|
@ -3981,9 +4083,6 @@ 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() {
|
||||
|
|
|
|||
|
|
@ -73,10 +73,19 @@ public:
|
|||
LOOP_PINGPONG,
|
||||
};
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
enum HandleMode {
|
||||
HANDLE_MODE_FREE,
|
||||
HANDLE_MODE_LINEAR,
|
||||
HANDLE_MODE_BALANCED,
|
||||
HANDLE_MODE_MIRRORED,
|
||||
};
|
||||
enum HandleSetMode {
|
||||
HANDLE_SET_MODE_NONE,
|
||||
HANDLE_SET_MODE_RESET,
|
||||
HANDLE_SET_MODE_AUTO,
|
||||
};
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
private:
|
||||
struct Track {
|
||||
|
|
@ -166,8 +175,10 @@ private:
|
|||
struct BezierKey {
|
||||
Vector2 in_handle; //relative (x always <0)
|
||||
Vector2 out_handle; //relative (x always >0)
|
||||
HandleMode handle_mode = HANDLE_MODE_BALANCED;
|
||||
real_t value = 0.0;
|
||||
#ifdef TOOLS_ENABLED
|
||||
HandleMode handle_mode = HANDLE_MODE_FREE;
|
||||
#endif // TOOLS_ENABLED
|
||||
};
|
||||
|
||||
struct BezierTrack : public Track {
|
||||
|
|
@ -429,15 +440,17 @@ public:
|
|||
void track_set_interpolation_type(int p_track, InterpolationType p_interp);
|
||||
InterpolationType track_get_interpolation_type(int p_track) const;
|
||||
|
||||
int 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 = HandleMode::HANDLE_MODE_BALANCED);
|
||||
void bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, double p_balanced_value_time_ratio = 1.0);
|
||||
int bezier_track_insert_key(int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle);
|
||||
void bezier_track_set_key_value(int p_track, int p_index, real_t p_value);
|
||||
void bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio = 1.0);
|
||||
void bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, double p_balanced_value_time_ratio = 1.0);
|
||||
void bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio = 1.0);
|
||||
void bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle, real_t p_balanced_value_time_ratio = 1.0);
|
||||
real_t bezier_track_get_key_value(int p_track, int p_index) const;
|
||||
int bezier_track_get_key_handle_mode(int p_track, int p_index) const;
|
||||
Vector2 bezier_track_get_key_in_handle(int p_track, int p_index) const;
|
||||
Vector2 bezier_track_get_key_out_handle(int p_track, int p_index) const;
|
||||
#ifdef TOOLS_ENABLED
|
||||
void bezier_track_set_key_handle_mode(int p_track, int p_index, HandleMode p_mode, HandleSetMode p_set_mode = HANDLE_SET_MODE_NONE);
|
||||
HandleMode bezier_track_get_key_handle_mode(int p_track, int p_index) const;
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
real_t bezier_track_interpolate(int p_track, double p_time) const;
|
||||
|
||||
|
|
@ -490,7 +503,10 @@ public:
|
|||
VARIANT_ENUM_CAST(Animation::TrackType);
|
||||
VARIANT_ENUM_CAST(Animation::InterpolationType);
|
||||
VARIANT_ENUM_CAST(Animation::UpdateMode);
|
||||
VARIANT_ENUM_CAST(Animation::HandleMode);
|
||||
VARIANT_ENUM_CAST(Animation::LoopMode);
|
||||
#ifdef TOOLS_ENABLED
|
||||
VARIANT_ENUM_CAST(Animation::HandleMode);
|
||||
VARIANT_ENUM_CAST(Animation::HandleSetMode);
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
#endif // ANIMATION_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue