Implement backup/restore for animated values
This commit is contained in:
parent
3f31925b18
commit
ff03a0bc7b
2 changed files with 92 additions and 7 deletions
|
@ -228,7 +228,11 @@ void AnimationPlayer::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationPlayer::_generate_node_caches(AnimationData *p_anim) {
|
void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
|
||||||
|
|
||||||
|
// Already cached?
|
||||||
|
if (p_anim->node_cache.size() == p_anim->animation->get_track_count())
|
||||||
|
return;
|
||||||
|
|
||||||
Node *parent = get_node(root);
|
Node *parent = get_node(root);
|
||||||
|
|
||||||
|
@ -336,11 +340,7 @@ void AnimationPlayer::_generate_node_caches(AnimationData *p_anim) {
|
||||||
|
|
||||||
void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_allow_discrete) {
|
void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_allow_discrete) {
|
||||||
|
|
||||||
if (p_anim->node_cache.size() != p_anim->animation->get_track_count()) {
|
_ensure_node_caches(p_anim);
|
||||||
// animation hasn't been "node-cached"
|
|
||||||
_generate_node_caches(p_anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
|
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
|
||||||
|
|
||||||
Animation *a = p_anim->animation.operator->();
|
Animation *a = p_anim->animation.operator->();
|
||||||
|
@ -1205,6 +1205,70 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
|
||||||
Node::get_argument_options(p_function, p_idx, r_options);
|
Node::get_argument_options(p_function, p_idx, r_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
|
||||||
|
|
||||||
|
if (!playback.current.from)
|
||||||
|
return AnimatedValuesBackup();
|
||||||
|
|
||||||
|
_ensure_node_caches(playback.current.from);
|
||||||
|
|
||||||
|
AnimatedValuesBackup backup;
|
||||||
|
|
||||||
|
for (int i = 0; i < playback.current.from->node_cache.size(); i++) {
|
||||||
|
TrackNodeCache *nc = playback.current.from->node_cache[i];
|
||||||
|
if (!nc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nc->skeleton) {
|
||||||
|
if (nc->bone_idx == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
AnimatedValuesBackup::Entry entry;
|
||||||
|
entry.object = nc->skeleton;
|
||||||
|
entry.bone_idx = nc->bone_idx;
|
||||||
|
entry.value = nc->skeleton->get_bone_pose(nc->bone_idx);
|
||||||
|
backup.entries.push_back(entry);
|
||||||
|
} else {
|
||||||
|
if (nc->spatial) {
|
||||||
|
AnimatedValuesBackup::Entry entry;
|
||||||
|
entry.object = nc->spatial;
|
||||||
|
entry.subpath.push_back("transform");
|
||||||
|
entry.value = nc->spatial->get_transform();
|
||||||
|
entry.bone_idx = -1;
|
||||||
|
backup.entries.push_back(entry);
|
||||||
|
} else {
|
||||||
|
for (Map<StringName, TrackNodeCache::PropertyAnim>::Element *E = nc->property_anim.front(); E; E = E->next()) {
|
||||||
|
AnimatedValuesBackup::Entry entry;
|
||||||
|
entry.object = E->value().object;
|
||||||
|
entry.subpath = E->value().subpath;
|
||||||
|
bool valid;
|
||||||
|
entry.value = E->value().object->get_indexed(E->value().subpath, &valid);
|
||||||
|
entry.bone_idx = -1;
|
||||||
|
if (valid)
|
||||||
|
backup.entries.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationPlayer::restore_animated_values(const AnimatedValuesBackup &p_backup) {
|
||||||
|
|
||||||
|
for (int i = 0; i < p_backup.entries.size(); i++) {
|
||||||
|
|
||||||
|
const AnimatedValuesBackup::Entry *entry = &p_backup.entries[i];
|
||||||
|
if (entry->bone_idx == -1) {
|
||||||
|
entry->object->set_indexed(entry->subpath, entry->value);
|
||||||
|
} else {
|
||||||
|
Object::cast_to<Skeleton>(entry->object)->set_bone_pose(entry->bone_idx, entry->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void AnimationPlayer::_bind_methods() {
|
void AnimationPlayer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayer::_node_removed);
|
ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayer::_node_removed);
|
||||||
|
|
|
@ -38,6 +38,21 @@
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
// To save/restore animated values
|
||||||
|
class AnimatedValuesBackup {
|
||||||
|
struct Entry {
|
||||||
|
Object *object;
|
||||||
|
Vector<StringName> subpath; // Unused if bone
|
||||||
|
int bone_idx; // -1 if not a bone
|
||||||
|
Variant value;
|
||||||
|
};
|
||||||
|
Vector<Entry> entries;
|
||||||
|
|
||||||
|
friend class AnimationPlayer;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class AnimationPlayer : public Node {
|
class AnimationPlayer : public Node {
|
||||||
GDCLASS(AnimationPlayer, Node);
|
GDCLASS(AnimationPlayer, Node);
|
||||||
OBJ_CATEGORY("Animation Nodes");
|
OBJ_CATEGORY("Animation Nodes");
|
||||||
|
@ -198,7 +213,7 @@ private:
|
||||||
|
|
||||||
void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_allow_discrete = true);
|
void _animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_allow_discrete = true);
|
||||||
|
|
||||||
void _generate_node_caches(AnimationData *p_anim);
|
void _ensure_node_caches(AnimationData *p_anim);
|
||||||
void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend);
|
void _animation_process_data(PlaybackData &cd, float p_delta, float p_blend);
|
||||||
void _animation_process2(float p_delta);
|
void _animation_process2(float p_delta);
|
||||||
void _animation_update_transforms();
|
void _animation_update_transforms();
|
||||||
|
@ -291,6 +306,12 @@ public:
|
||||||
|
|
||||||
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
|
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
// These may be interesting for games, but are too dangerous for general use
|
||||||
|
AnimatedValuesBackup backup_animated_values();
|
||||||
|
void restore_animated_values(const AnimatedValuesBackup &p_backup);
|
||||||
|
#endif
|
||||||
|
|
||||||
AnimationPlayer();
|
AnimationPlayer();
|
||||||
~AnimationPlayer();
|
~AnimationPlayer();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue