summaryrefslogtreecommitdiff
path: root/scene/animation
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation')
-rw-r--r--scene/animation/animation_player.cpp87
-rw-r--r--scene/animation/animation_player.h26
2 files changed, 106 insertions, 7 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 010f5a586f..206f3ccca2 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -33,6 +33,17 @@
#include "message_queue.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
+void AnimatedValuesBackup::update_skeletons() {
+
+ for (int i = 0; i < entries.size(); i++) {
+ if (entries[i].bone_idx != -1) {
+ Object::cast_to<Skeleton>(entries[i].object)->notification(Skeleton::NOTIFICATION_UPDATE_SKELETON);
+ }
+ }
+}
+#endif
+
bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
@@ -228,7 +239,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 +351,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 +1216,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);
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index e4e021c7fe..e39afcf199 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -38,6 +38,24 @@
@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;
+
+public:
+ void update_skeletons();
+};
+#endif
+
class AnimationPlayer : public Node {
GDCLASS(AnimationPlayer, Node);
OBJ_CATEGORY("Animation Nodes");
@@ -198,7 +216,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 +309,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();
};