123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- /**************************************************************************/
- /* animation_mixer.h */
- /**************************************************************************/
- /* This file is part of: */
- /* GODOT ENGINE */
- /* https://godotengine.org */
- /**************************************************************************/
- /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
- /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
- /* */
- /* Permission is hereby granted, free of charge, to any person obtaining */
- /* a copy of this software and associated documentation files (the */
- /* "Software"), to deal in the Software without restriction, including */
- /* without limitation the rights to use, copy, modify, merge, publish, */
- /* distribute, sublicense, and/or sell copies of the Software, and to */
- /* permit persons to whom the Software is furnished to do so, subject to */
- /* the following conditions: */
- /* */
- /* The above copyright notice and this permission notice shall be */
- /* included in all copies or substantial portions of the Software. */
- /* */
- /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
- /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
- /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
- /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
- /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
- /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
- /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
- /**************************************************************************/
- #ifndef ANIMATION_MIXER_H
- #define ANIMATION_MIXER_H
- #include "scene/animation/tween.h"
- #include "scene/main/node.h"
- #include "scene/resources/animation.h"
- #include "scene/resources/animation_library.h"
- #include "scene/resources/audio_stream_polyphonic.h"
- class AnimatedValuesBackup;
- class AnimationMixer : public Node {
- GDCLASS(AnimationMixer, Node);
- friend AnimatedValuesBackup;
- #ifdef TOOLS_ENABLED
- bool editing = false;
- bool dummy = false;
- #endif // TOOLS_ENABLED
- bool reset_on_save = true;
- public:
- enum AnimationCallbackModeProcess {
- ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS,
- ANIMATION_CALLBACK_MODE_PROCESS_IDLE,
- ANIMATION_CALLBACK_MODE_PROCESS_MANUAL,
- };
- enum AnimationCallbackModeMethod {
- ANIMATION_CALLBACK_MODE_METHOD_DEFERRED,
- ANIMATION_CALLBACK_MODE_METHOD_IMMEDIATE,
- };
- enum AnimationCallbackModeDiscrete {
- ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT,
- ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE,
- ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS,
- };
- /* ---- Data ---- */
- struct AnimationLibraryData {
- StringName name;
- Ref<AnimationLibrary> library;
- bool operator<(const AnimationLibraryData &p_data) const { return name.operator String() < p_data.name.operator String(); }
- };
- struct AnimationData {
- String name;
- Ref<Animation> animation;
- StringName animation_library;
- uint64_t last_update = 0;
- };
- struct PlaybackInfo {
- double time = 0.0;
- double delta = 0.0;
- bool seeked = false;
- bool is_external_seeking = false;
- Animation::LoopedFlag looped_flag = Animation::LOOPED_FLAG_NONE;
- real_t weight = 0.0;
- Vector<real_t> track_weights;
- };
- struct AnimationInstance {
- AnimationData animation_data;
- PlaybackInfo playback_info;
- };
- protected:
- /* ---- Data lists ---- */
- LocalVector<AnimationLibraryData> animation_libraries;
- HashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData>
- TypedArray<StringName> _get_animation_library_list() const;
- Vector<String> _get_animation_list() const {
- List<StringName> animations;
- get_animation_list(&animations);
- Vector<String> ret;
- while (animations.size()) {
- ret.push_back(animations.front()->get());
- animations.pop_front();
- }
- return ret;
- }
- // For caches.
- uint64_t animation_set_update_pass = 1;
- void _animation_set_cache_update();
- // Signals.
- virtual void _animation_added(const StringName &p_name, const StringName &p_library);
- virtual void _animation_removed(const StringName &p_name, const StringName &p_library);
- virtual void _animation_renamed(const StringName &p_name, const StringName &p_to_name, const StringName &p_library);
- virtual void _animation_changed(const StringName &p_name);
- /* ---- General settings for animation ---- */
- AnimationCallbackModeProcess callback_mode_process = ANIMATION_CALLBACK_MODE_PROCESS_IDLE;
- AnimationCallbackModeMethod callback_mode_method = ANIMATION_CALLBACK_MODE_METHOD_DEFERRED;
- AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE;
- int audio_max_polyphony = 32;
- NodePath root_node;
- bool processing = false;
- bool active = true;
- void _set_process(bool p_process, bool p_force = false);
- /* ---- Caches for blending ---- */
- bool cache_valid = false;
- uint64_t setup_pass = 1;
- uint64_t process_pass = 1;
- struct TrackCache {
- bool root_motion = false;
- uint64_t setup_pass = 0;
- Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION;
- NodePath path;
- ObjectID object_id;
- real_t total_weight = 0.0;
- TrackCache() = default;
- TrackCache(const TrackCache &p_other) :
- root_motion(p_other.root_motion),
- setup_pass(p_other.setup_pass),
- type(p_other.type),
- object_id(p_other.object_id),
- total_weight(p_other.total_weight) {}
- virtual ~TrackCache() {}
- };
- struct TrackCacheTransform : public TrackCache {
- #ifndef _3D_DISABLED
- ObjectID skeleton_id;
- #endif // _3D_DISABLED
- int bone_idx = -1;
- bool loc_used = false;
- bool rot_used = false;
- bool scale_used = false;
- Vector3 init_loc = Vector3(0, 0, 0);
- Quaternion init_rot = Quaternion(0, 0, 0, 1);
- Vector3 init_scale = Vector3(1, 1, 1);
- Vector3 loc;
- Quaternion rot;
- Vector3 scale;
- TrackCacheTransform(const TrackCacheTransform &p_other) :
- TrackCache(p_other),
- #ifndef _3D_DISABLED
- skeleton_id(p_other.skeleton_id),
- #endif
- bone_idx(p_other.bone_idx),
- loc_used(p_other.loc_used),
- rot_used(p_other.rot_used),
- scale_used(p_other.scale_used),
- init_loc(p_other.init_loc),
- init_rot(p_other.init_rot),
- init_scale(p_other.init_scale),
- loc(p_other.loc),
- rot(p_other.rot),
- scale(p_other.scale) {
- }
- TrackCacheTransform() {
- type = Animation::TYPE_POSITION_3D;
- }
- ~TrackCacheTransform() {}
- };
- struct RootMotionCache {
- Vector3 loc = Vector3(0, 0, 0);
- Quaternion rot = Quaternion(0, 0, 0, 1);
- Vector3 scale = Vector3(1, 1, 1);
- };
- struct TrackCacheBlendShape : public TrackCache {
- float init_value = 0;
- float value = 0;
- int shape_index = -1;
- TrackCacheBlendShape(const TrackCacheBlendShape &p_other) :
- TrackCache(p_other),
- init_value(p_other.init_value),
- value(p_other.value),
- shape_index(p_other.shape_index) {}
- TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
- ~TrackCacheBlendShape() {}
- };
- struct TrackCacheValue : public TrackCache {
- Variant init_value;
- Variant value;
- Vector<StringName> subpath;
- // TODO: There are many boolean, can be packed into one integer.
- bool is_init = false;
- bool use_continuous = false;
- bool use_discrete = false;
- bool is_using_angle = false;
- bool is_variant_interpolatable = true;
- Variant element_size;
- TrackCacheValue(const TrackCacheValue &p_other) :
- TrackCache(p_other),
- init_value(p_other.init_value),
- value(p_other.value),
- subpath(p_other.subpath),
- is_init(p_other.is_init),
- use_continuous(p_other.use_continuous),
- use_discrete(p_other.use_discrete),
- is_using_angle(p_other.is_using_angle),
- is_variant_interpolatable(p_other.is_variant_interpolatable),
- element_size(p_other.element_size) {}
- TrackCacheValue() { type = Animation::TYPE_VALUE; }
- ~TrackCacheValue() {
- // Clear ref to avoid leaking.
- init_value = Variant();
- value = Variant();
- }
- };
- struct TrackCacheMethod : public TrackCache {
- TrackCacheMethod() { type = Animation::TYPE_METHOD; }
- ~TrackCacheMethod() {}
- };
- // Audio stream information for each audio stream placed on the track.
- struct PlayingAudioStreamInfo {
- AudioStreamPlaybackPolyphonic::ID index = -1; // ID retrieved from AudioStreamPlaybackPolyphonic.
- double start = 0.0;
- double len = 0.0;
- };
- // Audio track information for mixng and ending.
- struct PlayingAudioTrackInfo {
- HashMap<int, PlayingAudioStreamInfo> stream_info;
- double length = 0.0;
- double time = 0.0;
- real_t volume = 0.0;
- bool loop = false;
- bool backward = false;
- bool use_blend = false;
- };
- struct TrackCacheAudio : public TrackCache {
- Ref<AudioStreamPolyphonic> audio_stream;
- Ref<AudioStreamPlaybackPolyphonic> audio_stream_playback;
- HashMap<ObjectID, PlayingAudioTrackInfo> playing_streams; // Key is Animation resource ObjectID.
- AudioServer::PlaybackType playback_type;
- StringName bus;
- TrackCacheAudio(const TrackCacheAudio &p_other) :
- TrackCache(p_other),
- audio_stream(p_other.audio_stream),
- audio_stream_playback(p_other.audio_stream_playback),
- playing_streams(p_other.playing_streams),
- playback_type(p_other.playback_type) {}
- TrackCacheAudio() {
- type = Animation::TYPE_AUDIO;
- }
- ~TrackCacheAudio() {}
- };
- struct TrackCacheAnimation : public TrackCache {
- bool playing = false;
- TrackCacheAnimation() {
- type = Animation::TYPE_ANIMATION;
- }
- ~TrackCacheAnimation() {}
- };
- RootMotionCache root_motion_cache;
- HashMap<Animation::TypeHash, TrackCache *> track_cache;
- HashSet<TrackCache *> playing_caches;
- Vector<Node *> playing_audio_stream_players;
- // Helpers.
- void _clear_caches();
- void _clear_audio_streams();
- void _clear_playing_caches();
- void _init_root_motion_cache();
- bool _update_caches();
- /* ---- Audio ---- */
- AudioServer::PlaybackType playback_type;
- /* ---- Blending processor ---- */
- LocalVector<AnimationInstance> animation_instances;
- HashMap<NodePath, int> track_map;
- int track_count = 0;
- bool deterministic = false;
- /* ---- Root motion accumulator for Skeleton3D ---- */
- NodePath root_motion_track;
- Vector3 root_motion_position = Vector3(0, 0, 0);
- Quaternion root_motion_rotation = Quaternion(0, 0, 0, 1);
- Vector3 root_motion_scale = Vector3(0, 0, 0);
- Vector3 root_motion_position_accumulator = Vector3(0, 0, 0);
- Quaternion root_motion_rotation_accumulator = Quaternion(0, 0, 0, 1);
- Vector3 root_motion_scale_accumulator = Vector3(1, 1, 1);
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
- void _notification(int p_what);
- virtual void _validate_property(PropertyInfo &p_property) const;
- #ifdef TOOLS_ENABLED
- virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
- #endif
- static void _bind_methods();
- void _node_removed(Node *p_node);
- // Helper for extended class.
- virtual void _set_active(bool p_active);
- virtual void _remove_animation(const StringName &p_name);
- virtual void _rename_animation(const StringName &p_from_name, const StringName &p_to_name);
- /* ---- Blending processor ---- */
- virtual void _process_animation(double p_delta, bool p_update_only = false);
- // For post process with retrieved key value during blending.
- virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1);
- Variant post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, ObjectID p_object_id, int p_object_sub_idx = -1);
- GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, ObjectID, int);
- void _blend_init();
- virtual bool _blend_pre_process(double p_delta, int p_track_count, const HashMap<NodePath, int> &p_track_map);
- virtual void _blend_capture(double p_delta);
- void _blend_calc_total_weight(); // For undeterministic blending.
- void _blend_process(double p_delta, bool p_update_only = false);
- void _blend_apply();
- virtual void _blend_post_process();
- void _call_object(ObjectID p_object_id, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);
- /* ---- Capture feature ---- */
- struct CaptureCache {
- Ref<Animation> animation;
- double remain = 0.0;
- double step = 0.0;
- Tween::TransitionType trans_type = Tween::TRANS_LINEAR;
- Tween::EaseType ease_type = Tween::EASE_IN;
- void clear() {
- animation.unref();
- remain = 0.0;
- step = 0.0;
- }
- CaptureCache() {}
- ~CaptureCache() {
- clear();
- }
- } capture_cache;
- void blend_capture(double p_delta); // To blend capture track with all other animations.
- #ifndef DISABLE_DEPRECATED
- virtual Variant _post_process_key_value_bind_compat_86687(const Ref<Animation> &p_anim, int p_track, Variant p_value, Object *p_object, int p_object_idx = -1);
- static void _bind_compatibility_methods();
- #endif // DISABLE_DEPRECATED
- public:
- /* ---- Data lists ---- */
- Dictionary *get_animation_libraries();
- void get_animation_library_list(List<StringName> *p_animations) const;
- Ref<AnimationLibrary> get_animation_library(const StringName &p_name) const;
- bool has_animation_library(const StringName &p_name) const;
- StringName find_animation_library(const Ref<Animation> &p_animation) const;
- Error add_animation_library(const StringName &p_name, const Ref<AnimationLibrary> &p_animation_library);
- void remove_animation_library(const StringName &p_name);
- void rename_animation_library(const StringName &p_name, const StringName &p_new_name);
- void get_animation_list(List<StringName> *p_animations) const;
- Ref<Animation> get_animation(const StringName &p_name) const;
- bool has_animation(const StringName &p_name) const;
- StringName find_animation(const Ref<Animation> &p_animation) const;
- /* ---- General settings for animation ---- */
- void set_active(bool p_active);
- bool is_active() const;
- void set_deterministic(bool p_deterministic);
- bool is_deterministic() const;
- void set_root_node(const NodePath &p_path);
- NodePath get_root_node() const;
- void set_callback_mode_process(AnimationCallbackModeProcess p_mode);
- AnimationCallbackModeProcess get_callback_mode_process() const;
- void set_callback_mode_method(AnimationCallbackModeMethod p_mode);
- AnimationCallbackModeMethod get_callback_mode_method() const;
- void set_callback_mode_discrete(AnimationCallbackModeDiscrete p_mode);
- AnimationCallbackModeDiscrete get_callback_mode_discrete() const;
- /* ---- Audio ---- */
- void set_audio_max_polyphony(int p_audio_max_polyphony);
- int get_audio_max_polyphony() const;
- /* ---- Root motion accumulator for Skeleton3D ---- */
- void set_root_motion_track(const NodePath &p_track);
- NodePath get_root_motion_track() const;
- Vector3 get_root_motion_position() const;
- Quaternion get_root_motion_rotation() const;
- Vector3 get_root_motion_scale() const;
- Vector3 get_root_motion_position_accumulator() const;
- Quaternion get_root_motion_rotation_accumulator() const;
- Vector3 get_root_motion_scale_accumulator() const;
- /* ---- Blending processor ---- */
- void make_animation_instance(const StringName &p_name, const PlaybackInfo p_playback_info);
- void clear_animation_instances();
- virtual void advance(double p_time);
- virtual void clear_caches(); // Must be called by hand if an animation was modified after added.
- /* ---- Capture feature ---- */
- void capture(const StringName &p_name, double p_duration, Tween::TransitionType p_trans_type = Tween::TRANS_LINEAR, Tween::EaseType p_ease_type = Tween::EASE_IN);
- /* ---- Reset on save ---- */
- void set_reset_on_save_enabled(bool p_enabled);
- bool is_reset_on_save_enabled() const;
- bool can_apply_reset() const;
- void _build_backup_track_cache();
- Ref<AnimatedValuesBackup> make_backup();
- void restore(const Ref<AnimatedValuesBackup> &p_backup);
- void reset();
- #ifdef TOOLS_ENABLED
- Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false);
- void set_editing(bool p_editing);
- bool is_editing() const;
- void set_dummy(bool p_dummy);
- bool is_dummy() const;
- #endif // TOOLS_ENABLED
- AnimationMixer();
- ~AnimationMixer();
- };
- class AnimatedValuesBackup : public RefCounted {
- GDCLASS(AnimatedValuesBackup, RefCounted);
- HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> data;
- public:
- void set_data(const HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> p_data);
- HashMap<Animation::TypeHash, AnimationMixer::TrackCache *> get_data() const;
- void clear_data();
- AnimationMixer::TrackCache *get_cache_copy(AnimationMixer::TrackCache *p_cache) const;
- ~AnimatedValuesBackup() { clear_data(); }
- };
- VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeProcess);
- VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeMethod);
- VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeDiscrete);
- #endif // ANIMATION_MIXER_H
|