diff options
Diffstat (limited to 'scene/animation/animation_player.cpp')
| -rw-r--r-- | scene/animation/animation_player.cpp | 76 | 
1 files changed, 70 insertions, 6 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 010f5a586f..ea445b1573 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -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);  |