Fix seeking Animation immediate after playback for Discrete track
This commit is contained in:
parent
e96ad5af98
commit
bea47d877b
|
@ -360,9 +360,12 @@
|
||||||
<param index="1" name="time" type="float" />
|
<param index="1" name="time" type="float" />
|
||||||
<param index="2" name="find_mode" type="int" enum="Animation.FindMode" default="0" />
|
<param index="2" name="find_mode" type="int" enum="Animation.FindMode" default="0" />
|
||||||
<param index="3" name="limit" type="bool" default="false" />
|
<param index="3" name="limit" type="bool" default="false" />
|
||||||
|
<param index="4" name="backward" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Finds the key index by time in a given track. Optionally, only find it if the approx/exact time is given.
|
Finds the key index by time in a given track. Optionally, only find it if the approx/exact time is given.
|
||||||
If [param limit] is [code]true[/code], it does not return keys outside the animation range.
|
If [param limit] is [code]true[/code], it does not return keys outside the animation range.
|
||||||
|
If [param backward] is [code]true[/code], the direction is reversed in methods that rely on one directional processing.
|
||||||
|
For example, in case [param find_mode] is [constant FIND_MODE_NEAREST], if there is no key in the current position just after seeked, the first key found is retrieved by searching before the position, but if [param backward] is [code]true[/code], the first key found is retrieved after the position.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="track_get_interpolation_loop_wrap" qualifiers="const">
|
<method name="track_get_interpolation_loop_wrap" qualifiers="const">
|
||||||
|
@ -583,6 +586,7 @@
|
||||||
<param index="2" name="backward" type="bool" default="false" />
|
<param index="2" name="backward" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Returns the interpolated value at the given time (in seconds). The [param track_idx] must be the index of a value track.
|
Returns the interpolated value at the given time (in seconds). The [param track_idx] must be the index of a value track.
|
||||||
|
A [param backward] mainly affects the direction of key retrieval of the track with [constant UPDATE_DISCRETE] converted by [constant AnimationMixer.ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS] to match the result with [method track_find_key].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="value_track_set_update_mode">
|
<method name="value_track_set_update_mode">
|
||||||
|
|
|
@ -243,12 +243,12 @@ void AnimationPlayerEditor::_play_from_pressed() {
|
||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
|
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
float time = player->get_current_animation_position();
|
double time = player->get_current_animation_position();
|
||||||
if (current == player->get_assigned_animation() && player->is_playing()) {
|
if (current == player->get_assigned_animation() && player->is_playing()) {
|
||||||
player->stop(); //so it won't blend with itself
|
player->clear_caches(); //so it won't blend with itself
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
player->seek(time);
|
player->seek(time, true, true);
|
||||||
player->play(current);
|
player->play(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,12 +281,12 @@ void AnimationPlayerEditor::_play_bw_from_pressed() {
|
||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
|
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
float time = player->get_current_animation_position();
|
double time = player->get_current_animation_position();
|
||||||
if (current == player->get_assigned_animation()) {
|
if (current == player->get_assigned_animation() && player->is_playing()) {
|
||||||
player->stop(); //so it won't blend with itself
|
player->clear_caches(); //so it won't blend with itself
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
player->seek(time);
|
player->seek(time, true, true);
|
||||||
player->play_backwards(current);
|
player->play_backwards(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -364,3 +364,9 @@ GH-92322
|
||||||
Validate extension JSON: Error: Field 'classes/EditorInspectorPlugin/methods/add_property_editor/arguments': size changed value in new API, from 3 to 4.
|
Validate extension JSON: Error: Field 'classes/EditorInspectorPlugin/methods/add_property_editor/arguments': size changed value in new API, from 3 to 4.
|
||||||
|
|
||||||
Optional arguments added. Compatibility methods registered.
|
Optional arguments added. Compatibility methods registered.
|
||||||
|
|
||||||
|
GH-86661
|
||||||
|
--------
|
||||||
|
Validate extension JSON: Error: Field 'classes/Animation/methods/track_find_key/arguments': size changed value in new API, from 3 to 5.
|
||||||
|
|
||||||
|
Added optional argument to track_find_key to handle backward seeking. Compatibility method registered.
|
||||||
|
|
|
@ -1109,6 +1109,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
|
||||||
real_t weight = ai.playback_info.weight;
|
real_t weight = ai.playback_info.weight;
|
||||||
Vector<real_t> track_weights = ai.playback_info.track_weights;
|
Vector<real_t> track_weights = ai.playback_info.track_weights;
|
||||||
bool backward = signbit(delta); // This flag is used by the root motion calculates or detecting the end of audio stream.
|
bool backward = signbit(delta); // This flag is used by the root motion calculates or detecting the end of audio stream.
|
||||||
|
bool seeked_backward = signbit(p_delta);
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
bool calc_root = !seeked || is_external_seeking;
|
bool calc_root = !seeked || is_external_seeking;
|
||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
|
@ -1463,7 +1464,7 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (seeked) {
|
if (seeked) {
|
||||||
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT, true);
|
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT, false, seeked_backward);
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1744,8 +1745,10 @@ void AnimationMixer::_blend_apply() {
|
||||||
case Animation::TYPE_VALUE: {
|
case Animation::TYPE_VALUE: {
|
||||||
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
|
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
|
||||||
|
|
||||||
if (t->use_discrete && !t->use_continuous) {
|
if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) {
|
||||||
t->is_init = true; // If only disctere value is applied, no more RESET.
|
t->is_init = false; // Always update in Force Continuous.
|
||||||
|
} else if (!t->use_continuous && (t->use_discrete || !deterministic)) {
|
||||||
|
t->is_init = true; // If there is no continuous value and only disctere value is applied or just started, don't RESET.
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((t->is_init && (is_zero_amount || !t->use_continuous)) ||
|
if ((t->is_init && (is_zero_amount || !t->use_continuous)) ||
|
||||||
|
@ -1756,9 +1759,7 @@ void AnimationMixer::_blend_apply() {
|
||||||
break; // Don't overwrite the value set by UPDATE_DISCRETE.
|
break; // Don't overwrite the value set by UPDATE_DISCRETE.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback_mode_discrete == ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) {
|
if (callback_mode_discrete != ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS) {
|
||||||
t->is_init = false; // Always update in Force Continuous.
|
|
||||||
} else {
|
|
||||||
t->is_init = !t->use_continuous; // If there is no Continuous in non-Force Continuous type, it means RESET.
|
t->is_init = !t->use_continuous; // If there is no Continuous in non-Force Continuous type, it means RESET.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,6 +234,9 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
|
||||||
pi.delta = delta;
|
pi.delta = delta;
|
||||||
pi.seeked = p_seeked;
|
pi.seeked = p_seeked;
|
||||||
}
|
}
|
||||||
|
if (Math::is_zero_approx(pi.delta) && backwards) {
|
||||||
|
pi.delta = -0.0; // Sign is needed to handle converted Continuous track from Discrete track correctly.
|
||||||
|
}
|
||||||
// AnimationPlayer doesn't have internal seeking.
|
// AnimationPlayer doesn't have internal seeking.
|
||||||
// However, immediately after playback, discrete keys should be retrieved with EXACT mode since behind keys must be ignored at that time.
|
// However, immediately after playback, discrete keys should be retrieved with EXACT mode since behind keys must be ignored at that time.
|
||||||
pi.is_external_seeking = !p_started;
|
pi.is_external_seeking = !p_started;
|
||||||
|
@ -257,7 +260,7 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
|
||||||
|
|
||||||
bool seeked = c.seeked; // The animation may be changed during process, so it is safer that the state is changed before process.
|
bool seeked = c.seeked; // The animation may be changed during process, so it is safer that the state is changed before process.
|
||||||
|
|
||||||
if (p_delta != 0) {
|
if (!Math::is_zero_approx(p_delta)) {
|
||||||
c.seeked = false;
|
c.seeked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +584,8 @@ void AnimationPlayer::seek(double p_time, bool p_update, bool p_update_only) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_backward = p_time < playback.current.pos;
|
||||||
|
|
||||||
_check_immediately_after_start();
|
_check_immediately_after_start();
|
||||||
|
|
||||||
playback.current.pos = p_time;
|
playback.current.pos = p_time;
|
||||||
|
@ -596,7 +601,7 @@ void AnimationPlayer::seek(double p_time, bool p_update, bool p_update_only) {
|
||||||
|
|
||||||
playback.seeked = true;
|
playback.seeked = true;
|
||||||
if (p_update) {
|
if (p_update) {
|
||||||
_process_animation(0, p_update_only);
|
_process_animation(is_backward ? -0.0 : 0.0, p_update_only);
|
||||||
playback.seeked = false; // If animation was proceeded here, no more seek in internal process.
|
playback.seeked = false; // If animation was proceeded here, no more seek in internal process.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ Variant Animation::_value_track_interpolate_bind_compat_86629(int p_track, doubl
|
||||||
return value_track_interpolate(p_track, p_time, false);
|
return value_track_interpolate(p_track, p_time, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Animation::_track_find_key_bind_compat_86661(int p_track, double p_time, FindMode p_find_mode) const {
|
int Animation::_track_find_key_bind_compat_92861(int p_track, double p_time, FindMode p_find_mode) const {
|
||||||
return track_find_key(p_track, p_time, p_find_mode, false);
|
return track_find_key(p_track, p_time, p_find_mode, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::_bind_compatibility_methods() {
|
void Animation::_bind_compatibility_methods() {
|
||||||
|
@ -60,7 +60,7 @@ void Animation::_bind_compatibility_methods() {
|
||||||
ClassDB::bind_compatibility_method(D_METHOD("scale_track_interpolate", "track_idx", "time_sec"), &Animation::_scale_track_interpolate_bind_compat_86629);
|
ClassDB::bind_compatibility_method(D_METHOD("scale_track_interpolate", "track_idx", "time_sec"), &Animation::_scale_track_interpolate_bind_compat_86629);
|
||||||
ClassDB::bind_compatibility_method(D_METHOD("blend_shape_track_interpolate", "track_idx", "time_sec"), &Animation::_blend_shape_track_interpolate_bind_compat_86629);
|
ClassDB::bind_compatibility_method(D_METHOD("blend_shape_track_interpolate", "track_idx", "time_sec"), &Animation::_blend_shape_track_interpolate_bind_compat_86629);
|
||||||
ClassDB::bind_compatibility_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::_value_track_interpolate_bind_compat_86629);
|
ClassDB::bind_compatibility_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::_value_track_interpolate_bind_compat_86629);
|
||||||
ClassDB::bind_compatibility_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode"), &Animation::_track_find_key_bind_compat_86661, DEFVAL(FIND_MODE_NEAREST));
|
ClassDB::bind_compatibility_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode"), &Animation::_track_find_key_bind_compat_92861, DEFVAL(FIND_MODE_NEAREST));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DISABLE_DEPRECATED
|
#endif // DISABLE_DEPRECATED
|
||||||
|
|
|
@ -1496,7 +1496,7 @@ void Animation::track_remove_key(int p_track, int p_idx) {
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode, bool p_limit) const {
|
int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode, bool p_limit, bool p_backward) const {
|
||||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
|
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
|
||||||
Track *t = tracks[p_track];
|
Track *t = tracks[p_track];
|
||||||
|
|
||||||
|
@ -1518,7 +1518,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
return key_index;
|
return key_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int k = _find(tt->positions, p_time, false, p_limit);
|
int k = _find(tt->positions, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= tt->positions.size()) {
|
if (k < 0 || k >= tt->positions.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1545,7 +1545,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
return key_index;
|
return key_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int k = _find(rt->rotations, p_time, false, p_limit);
|
int k = _find(rt->rotations, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= rt->rotations.size()) {
|
if (k < 0 || k >= rt->rotations.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1572,7 +1572,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
return key_index;
|
return key_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int k = _find(st->scales, p_time, false, p_limit);
|
int k = _find(st->scales, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= st->scales.size()) {
|
if (k < 0 || k >= st->scales.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1599,7 +1599,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
return key_index;
|
return key_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
int k = _find(bst->blend_shapes, p_time, false, p_limit);
|
int k = _find(bst->blend_shapes, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= bst->blend_shapes.size()) {
|
if (k < 0 || k >= bst->blend_shapes.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1611,7 +1611,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
} break;
|
} break;
|
||||||
case TYPE_VALUE: {
|
case TYPE_VALUE: {
|
||||||
ValueTrack *vt = static_cast<ValueTrack *>(t);
|
ValueTrack *vt = static_cast<ValueTrack *>(t);
|
||||||
int k = _find(vt->values, p_time, false, p_limit);
|
int k = _find(vt->values, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= vt->values.size()) {
|
if (k < 0 || k >= vt->values.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1623,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
} break;
|
} break;
|
||||||
case TYPE_METHOD: {
|
case TYPE_METHOD: {
|
||||||
MethodTrack *mt = static_cast<MethodTrack *>(t);
|
MethodTrack *mt = static_cast<MethodTrack *>(t);
|
||||||
int k = _find(mt->methods, p_time, false, p_limit);
|
int k = _find(mt->methods, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= mt->methods.size()) {
|
if (k < 0 || k >= mt->methods.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1635,7 +1635,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
} break;
|
} break;
|
||||||
case TYPE_BEZIER: {
|
case TYPE_BEZIER: {
|
||||||
BezierTrack *bt = static_cast<BezierTrack *>(t);
|
BezierTrack *bt = static_cast<BezierTrack *>(t);
|
||||||
int k = _find(bt->values, p_time, false, p_limit);
|
int k = _find(bt->values, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= bt->values.size()) {
|
if (k < 0 || k >= bt->values.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1647,7 +1647,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
} break;
|
} break;
|
||||||
case TYPE_AUDIO: {
|
case TYPE_AUDIO: {
|
||||||
AudioTrack *at = static_cast<AudioTrack *>(t);
|
AudioTrack *at = static_cast<AudioTrack *>(t);
|
||||||
int k = _find(at->values, p_time, false, p_limit);
|
int k = _find(at->values, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= at->values.size()) {
|
if (k < 0 || k >= at->values.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1659,7 +1659,7 @@ int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode,
|
||||||
} break;
|
} break;
|
||||||
case TYPE_ANIMATION: {
|
case TYPE_ANIMATION: {
|
||||||
AnimationTrack *at = static_cast<AnimationTrack *>(t);
|
AnimationTrack *at = static_cast<AnimationTrack *>(t);
|
||||||
int k = _find(at->values, p_time, false, p_limit);
|
int k = _find(at->values, p_time, p_backward, p_limit);
|
||||||
if (k < 0 || k >= at->values.size()) {
|
if (k < 0 || k >= at->values.size()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -3836,7 +3836,7 @@ void Animation::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
|
ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
|
||||||
ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
|
ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
|
||||||
ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
|
ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
|
||||||
ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode", "limit"), &Animation::track_find_key, DEFVAL(FIND_MODE_NEAREST), DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode", "limit", "backward"), &Animation::track_find_key, DEFVAL(FIND_MODE_NEAREST), DEFVAL(false), DEFVAL(false));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
|
ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
|
||||||
ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
|
ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
|
||||||
|
|
|
@ -388,7 +388,7 @@ protected:
|
||||||
Vector3 _scale_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
Vector3 _scale_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
||||||
float _blend_shape_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
float _blend_shape_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
||||||
Variant _value_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
Variant _value_track_interpolate_bind_compat_86629(int p_track, double p_time) const;
|
||||||
int _track_find_key_bind_compat_86661(int p_track, double p_time, FindMode p_find_mode = FIND_MODE_NEAREST) const;
|
int _track_find_key_bind_compat_92861(int p_track, double p_time, FindMode p_find_mode = FIND_MODE_NEAREST) const;
|
||||||
static void _bind_compatibility_methods();
|
static void _bind_compatibility_methods();
|
||||||
#endif // DISABLE_DEPRECATED
|
#endif // DISABLE_DEPRECATED
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ public:
|
||||||
void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition);
|
void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition);
|
||||||
void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value);
|
void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value);
|
||||||
void track_set_key_time(int p_track, int p_key_idx, double p_time);
|
void track_set_key_time(int p_track, int p_key_idx, double p_time);
|
||||||
int track_find_key(int p_track, double p_time, FindMode p_find_mode = FIND_MODE_NEAREST, bool p_limit = false) const;
|
int track_find_key(int p_track, double p_time, FindMode p_find_mode = FIND_MODE_NEAREST, bool p_limit = false, bool p_backward = false) const;
|
||||||
void track_remove_key(int p_track, int p_idx);
|
void track_remove_key(int p_track, int p_idx);
|
||||||
void track_remove_key_at_time(int p_track, double p_time);
|
void track_remove_key_at_time(int p_track, double p_time);
|
||||||
int track_get_key_count(int p_track) const;
|
int track_get_key_count(int p_track) const;
|
||||||
|
|
Loading…
Reference in New Issue