Implement backup/restore for animated values
This commit is contained in:
parent
3f31925b18
commit
ff03a0bc7b
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
if (p_anim->node_cache.size() != p_anim->animation->get_track_count()) {
|
||||
// animation hasn't been "node-cached"
|
||||
_generate_node_caches(p_anim);
|
||||
}
|
||||
|
||||
_ensure_node_caches(p_anim);
|
||||
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#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() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationPlayer::_node_removed);
|
||||
|
@ -38,6 +38,21 @@
|
||||
@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 {
|
||||
GDCLASS(AnimationPlayer, Node);
|
||||
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 _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_process2(float p_delta);
|
||||
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;
|
||||
|
||||
#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();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user