Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/animation/animation_mixer.h
9896 views
1
/**************************************************************************/
2
/* animation_mixer.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/templates/a_hash_map.h"
34
#include "scene/animation/tween.h"
35
#include "scene/main/node.h"
36
#include "scene/resources/animation.h"
37
#include "scene/resources/animation_library.h"
38
#include "scene/resources/audio_stream_polyphonic.h"
39
40
class AnimatedValuesBackup;
41
42
class AnimationMixer : public Node {
43
GDCLASS(AnimationMixer, Node);
44
friend AnimatedValuesBackup;
45
#ifdef TOOLS_ENABLED
46
bool editing = false;
47
bool dummy = false;
48
#endif // TOOLS_ENABLED
49
50
bool reset_on_save = true;
51
bool is_GDVIRTUAL_CALL_post_process_key_value = true;
52
53
public:
54
enum AnimationCallbackModeProcess {
55
ANIMATION_CALLBACK_MODE_PROCESS_PHYSICS,
56
ANIMATION_CALLBACK_MODE_PROCESS_IDLE,
57
ANIMATION_CALLBACK_MODE_PROCESS_MANUAL,
58
};
59
60
enum AnimationCallbackModeMethod {
61
ANIMATION_CALLBACK_MODE_METHOD_DEFERRED,
62
ANIMATION_CALLBACK_MODE_METHOD_IMMEDIATE,
63
};
64
65
enum AnimationCallbackModeDiscrete {
66
ANIMATION_CALLBACK_MODE_DISCRETE_DOMINANT,
67
ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE,
68
ANIMATION_CALLBACK_MODE_DISCRETE_FORCE_CONTINUOUS,
69
};
70
71
/* ---- Data ---- */
72
struct AnimationLibraryData {
73
StringName name;
74
Ref<AnimationLibrary> library;
75
bool operator<(const AnimationLibraryData &p_data) const { return name.operator String() < p_data.name.operator String(); }
76
};
77
78
struct AnimationData {
79
String name;
80
Ref<Animation> animation;
81
StringName animation_library;
82
uint64_t last_update = 0;
83
};
84
85
struct PlaybackInfo {
86
double time = 0.0;
87
double delta = 0.0;
88
double start = 0.0;
89
double end = 0.0;
90
bool seeked = false;
91
bool is_external_seeking = false;
92
Animation::LoopedFlag looped_flag = Animation::LOOPED_FLAG_NONE;
93
real_t weight = 0.0;
94
Vector<real_t> track_weights;
95
};
96
97
struct AnimationInstance {
98
AnimationData animation_data;
99
PlaybackInfo playback_info;
100
};
101
102
protected:
103
/* ---- Data lists ---- */
104
LocalVector<AnimationLibraryData> animation_libraries;
105
AHashMap<StringName, AnimationData> animation_set; // HashMap<Library name + Animation name, AnimationData>
106
107
TypedArray<StringName> _get_animation_library_list() const;
108
Vector<String> _get_animation_list() const {
109
List<StringName> animations;
110
get_animation_list(&animations);
111
Vector<String> ret;
112
while (animations.size()) {
113
ret.push_back(animations.front()->get());
114
animations.pop_front();
115
}
116
return ret;
117
}
118
119
// For caches.
120
uint64_t animation_set_update_pass = 1;
121
void _animation_set_cache_update();
122
123
// Signals.
124
virtual void _animation_added(const StringName &p_name, const StringName &p_library);
125
virtual void _animation_removed(const StringName &p_name, const StringName &p_library);
126
virtual void _animation_renamed(const StringName &p_name, const StringName &p_to_name, const StringName &p_library);
127
virtual void _animation_changed(const StringName &p_name);
128
129
/* ---- General settings for animation ---- */
130
AnimationCallbackModeProcess callback_mode_process = ANIMATION_CALLBACK_MODE_PROCESS_IDLE;
131
AnimationCallbackModeMethod callback_mode_method = ANIMATION_CALLBACK_MODE_METHOD_DEFERRED;
132
AnimationCallbackModeDiscrete callback_mode_discrete = ANIMATION_CALLBACK_MODE_DISCRETE_RECESSIVE;
133
int audio_max_polyphony = 32;
134
NodePath root_node;
135
136
bool processing = false;
137
bool active = true;
138
139
void _set_process(bool p_process, bool p_force = false);
140
141
/* ---- Caches for blending ---- */
142
bool cache_valid = false;
143
uint64_t setup_pass = 1;
144
uint64_t process_pass = 1;
145
146
struct TrackCache {
147
bool root_motion = false;
148
uint64_t setup_pass = 0;
149
Animation::TrackType type = Animation::TrackType::TYPE_ANIMATION;
150
NodePath path;
151
int blend_idx = -1;
152
ObjectID object_id;
153
real_t total_weight = 0.0;
154
155
TrackCache() = default;
156
TrackCache(const TrackCache &p_other) :
157
root_motion(p_other.root_motion),
158
setup_pass(p_other.setup_pass),
159
type(p_other.type),
160
object_id(p_other.object_id),
161
total_weight(p_other.total_weight) {}
162
163
virtual ~TrackCache() {}
164
};
165
166
struct TrackCacheTransform : public TrackCache {
167
#ifndef _3D_DISABLED
168
ObjectID skeleton_id;
169
#endif // _3D_DISABLED
170
int bone_idx = -1;
171
bool loc_used = false;
172
bool rot_used = false;
173
bool scale_used = false;
174
Vector3 init_loc = Vector3(0, 0, 0);
175
Quaternion init_rot = Quaternion(0, 0, 0, 1);
176
Vector3 init_scale = Vector3(1, 1, 1);
177
Vector3 loc;
178
Quaternion rot;
179
Vector3 scale;
180
181
TrackCacheTransform(const TrackCacheTransform &p_other) :
182
TrackCache(p_other),
183
#ifndef _3D_DISABLED
184
skeleton_id(p_other.skeleton_id),
185
#endif
186
bone_idx(p_other.bone_idx),
187
loc_used(p_other.loc_used),
188
rot_used(p_other.rot_used),
189
scale_used(p_other.scale_used),
190
init_loc(p_other.init_loc),
191
init_rot(p_other.init_rot),
192
init_scale(p_other.init_scale),
193
loc(p_other.loc),
194
rot(p_other.rot),
195
scale(p_other.scale) {
196
}
197
198
TrackCacheTransform() {
199
type = Animation::TYPE_POSITION_3D;
200
}
201
};
202
203
struct RootMotionCache {
204
Vector3 loc = Vector3(0, 0, 0);
205
Quaternion rot = Quaternion(0, 0, 0, 1);
206
Vector3 scale = Vector3(1, 1, 1);
207
};
208
209
struct TrackCacheBlendShape : public TrackCache {
210
float init_value = 0;
211
float value = 0;
212
int shape_index = -1;
213
214
TrackCacheBlendShape(const TrackCacheBlendShape &p_other) :
215
TrackCache(p_other),
216
init_value(p_other.init_value),
217
value(p_other.value),
218
shape_index(p_other.shape_index) {}
219
220
TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
221
};
222
223
struct TrackCacheValue : public TrackCache {
224
Variant init_value;
225
Variant value;
226
Vector<StringName> subpath;
227
228
// TODO: There are many boolean, can be packed into one integer.
229
bool is_init = false;
230
bool use_continuous = false;
231
bool use_discrete = false;
232
bool is_using_angle = false;
233
bool is_variant_interpolatable = true;
234
235
Variant element_size;
236
237
TrackCacheValue(const TrackCacheValue &p_other) :
238
TrackCache(p_other),
239
init_value(p_other.init_value),
240
value(p_other.value),
241
subpath(p_other.subpath),
242
is_init(p_other.is_init),
243
use_continuous(p_other.use_continuous),
244
use_discrete(p_other.use_discrete),
245
is_using_angle(p_other.is_using_angle),
246
is_variant_interpolatable(p_other.is_variant_interpolatable),
247
element_size(p_other.element_size) {}
248
249
TrackCacheValue() { type = Animation::TYPE_VALUE; }
250
~TrackCacheValue() {
251
// Clear ref to avoid leaking.
252
init_value = Variant();
253
value = Variant();
254
}
255
};
256
257
struct TrackCacheMethod : public TrackCache {
258
TrackCacheMethod() { type = Animation::TYPE_METHOD; }
259
};
260
261
// Audio stream information for each audio stream placed on the track.
262
struct PlayingAudioStreamInfo {
263
AudioStreamPlaybackPolyphonic::ID index = -1; // ID retrieved from AudioStreamPlaybackPolyphonic.
264
double start = 0.0;
265
double len = 0.0;
266
};
267
268
// Audio track information for mixng and ending.
269
struct PlayingAudioTrackInfo {
270
AHashMap<int, PlayingAudioStreamInfo> stream_info;
271
double length = 0.0;
272
double time = 0.0;
273
real_t volume = 0.0;
274
bool loop = false;
275
bool backward = false;
276
bool use_blend = false;
277
};
278
279
struct TrackCacheAudio : public TrackCache {
280
Ref<AudioStreamPolyphonic> audio_stream;
281
Ref<AudioStreamPlaybackPolyphonic> audio_stream_playback;
282
HashMap<ObjectID, PlayingAudioTrackInfo> playing_streams; // Key is Animation resource ObjectID.
283
AudioServer::PlaybackType playback_type;
284
StringName bus;
285
286
TrackCacheAudio(const TrackCacheAudio &p_other) :
287
TrackCache(p_other),
288
audio_stream(p_other.audio_stream),
289
audio_stream_playback(p_other.audio_stream_playback),
290
playing_streams(p_other.playing_streams),
291
playback_type(p_other.playback_type) {}
292
293
TrackCacheAudio() {
294
type = Animation::TYPE_AUDIO;
295
}
296
};
297
298
struct TrackCacheAnimation : public TrackCache {
299
bool playing = false;
300
301
TrackCacheAnimation() {
302
type = Animation::TYPE_ANIMATION;
303
}
304
};
305
306
RootMotionCache root_motion_cache;
307
AHashMap<Animation::TypeHash, TrackCache *, HashHasher> track_cache;
308
AHashMap<Ref<Animation>, LocalVector<TrackCache *>> animation_track_num_to_track_cache;
309
HashSet<TrackCache *> playing_caches;
310
Vector<Node *> playing_audio_stream_players;
311
312
// Helpers.
313
void _clear_caches();
314
void _clear_audio_streams();
315
void _clear_playing_caches();
316
void _init_root_motion_cache();
317
bool _update_caches();
318
void _create_track_num_to_track_cache_for_animation(Ref<Animation> &p_animation);
319
320
/* ---- Audio ---- */
321
AudioServer::PlaybackType playback_type;
322
323
/* ---- Blending processor ---- */
324
LocalVector<AnimationInstance> animation_instances;
325
AHashMap<NodePath, int> track_map;
326
int track_count = 0;
327
bool deterministic = false;
328
329
/* ---- Root motion accumulator for Skeleton3D ---- */
330
NodePath root_motion_track;
331
bool root_motion_local = false;
332
Vector3 root_motion_position = Vector3(0, 0, 0);
333
Quaternion root_motion_rotation = Quaternion(0, 0, 0, 1);
334
Vector3 root_motion_scale = Vector3(0, 0, 0);
335
Vector3 root_motion_position_accumulator = Vector3(0, 0, 0);
336
Quaternion root_motion_rotation_accumulator = Quaternion(0, 0, 0, 1);
337
Vector3 root_motion_scale_accumulator = Vector3(1, 1, 1);
338
339
bool _set(const StringName &p_name, const Variant &p_value);
340
bool _get(const StringName &p_name, Variant &r_ret) const;
341
void _get_property_list(List<PropertyInfo> *p_list) const;
342
void _notification(int p_what);
343
virtual void _validate_property(PropertyInfo &p_property) const;
344
345
#ifdef TOOLS_ENABLED
346
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
347
#endif
348
349
static void _bind_methods();
350
void _node_removed(Node *p_node);
351
352
// Helper for extended class.
353
virtual void _set_active(bool p_active);
354
virtual void _remove_animation(const StringName &p_name);
355
virtual void _rename_animation(const StringName &p_from_name, const StringName &p_to_name);
356
357
/* ---- Blending processor ---- */
358
virtual void _process_animation(double p_delta, bool p_update_only = false);
359
360
// For post process with retrieved key value during blending.
361
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);
362
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);
363
GDVIRTUAL5RC(Variant, _post_process_key_value, Ref<Animation>, int, Variant, ObjectID, int);
364
365
void _blend_init();
366
virtual bool _blend_pre_process(double p_delta, int p_track_count, const AHashMap<NodePath, int> &p_track_map);
367
virtual void _blend_capture(double p_delta);
368
void _blend_calc_total_weight(); // For indeterministic blending.
369
void _blend_process(double p_delta, bool p_update_only = false);
370
void _blend_apply();
371
virtual void _blend_post_process();
372
void _call_object(ObjectID p_object_id, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);
373
374
/* ---- Capture feature ---- */
375
struct CaptureCache {
376
Ref<Animation> animation;
377
double remain = 0.0;
378
double step = 0.0;
379
Tween::TransitionType trans_type = Tween::TRANS_LINEAR;
380
Tween::EaseType ease_type = Tween::EASE_IN;
381
382
void clear() {
383
animation.unref();
384
remain = 0.0;
385
step = 0.0;
386
}
387
388
~CaptureCache() {
389
clear();
390
}
391
} capture_cache;
392
void blend_capture(double p_delta); // To blend capture track with all other animations.
393
394
#ifndef DISABLE_DEPRECATED
395
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);
396
static void _bind_compatibility_methods();
397
#endif // DISABLE_DEPRECATED
398
399
public:
400
/* ---- Data lists ---- */
401
Dictionary *get_animation_libraries();
402
403
void get_animation_library_list(List<StringName> *p_animations) const;
404
Ref<AnimationLibrary> get_animation_library(const StringName &p_name) const;
405
bool has_animation_library(const StringName &p_name) const;
406
StringName get_animation_library_name(const Ref<AnimationLibrary> &p_animation_library) const;
407
StringName find_animation_library(const Ref<Animation> &p_animation) const;
408
Error add_animation_library(const StringName &p_name, const Ref<AnimationLibrary> &p_animation_library);
409
void remove_animation_library(const StringName &p_name);
410
void rename_animation_library(const StringName &p_name, const StringName &p_new_name);
411
412
void get_animation_list(List<StringName> *p_animations) const;
413
Ref<Animation> get_animation(const StringName &p_name) const;
414
bool has_animation(const StringName &p_name) const;
415
StringName find_animation(const Ref<Animation> &p_animation) const;
416
417
/* ---- General settings for animation ---- */
418
void set_active(bool p_active);
419
bool is_active() const;
420
421
void set_deterministic(bool p_deterministic);
422
bool is_deterministic() const;
423
424
void set_root_node(const NodePath &p_path);
425
NodePath get_root_node() const;
426
427
void set_callback_mode_process(AnimationCallbackModeProcess p_mode);
428
AnimationCallbackModeProcess get_callback_mode_process() const;
429
430
void set_callback_mode_method(AnimationCallbackModeMethod p_mode);
431
AnimationCallbackModeMethod get_callback_mode_method() const;
432
433
void set_callback_mode_discrete(AnimationCallbackModeDiscrete p_mode);
434
AnimationCallbackModeDiscrete get_callback_mode_discrete() const;
435
436
/* ---- Audio ---- */
437
void set_audio_max_polyphony(int p_audio_max_polyphony);
438
int get_audio_max_polyphony() const;
439
440
/* ---- Root motion accumulator for Skeleton3D ---- */
441
void set_root_motion_track(const NodePath &p_track);
442
NodePath get_root_motion_track() const;
443
444
void set_root_motion_local(bool p_enabled);
445
bool is_root_motion_local() const;
446
447
Vector3 get_root_motion_position() const;
448
Quaternion get_root_motion_rotation() const;
449
Vector3 get_root_motion_scale() const;
450
451
Vector3 get_root_motion_position_accumulator() const;
452
Quaternion get_root_motion_rotation_accumulator() const;
453
Vector3 get_root_motion_scale_accumulator() const;
454
455
/* ---- Blending processor ---- */
456
void make_animation_instance(const StringName &p_name, const PlaybackInfo p_playback_info);
457
void clear_animation_instances();
458
virtual void advance(double p_time);
459
virtual void clear_caches(); // Must be called by hand if an animation was modified after added.
460
461
/* ---- Capture feature ---- */
462
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);
463
464
/* ---- Reset on save ---- */
465
void set_reset_on_save_enabled(bool p_enabled);
466
bool is_reset_on_save_enabled() const;
467
bool can_apply_reset() const;
468
void _build_backup_track_cache();
469
Ref<AnimatedValuesBackup> make_backup();
470
void restore(const Ref<AnimatedValuesBackup> &p_backup);
471
void reset();
472
473
#ifdef TOOLS_ENABLED
474
Ref<AnimatedValuesBackup> apply_reset(bool p_user_initiated = false);
475
476
void set_editing(bool p_editing);
477
bool is_editing() const;
478
479
void set_dummy(bool p_dummy);
480
bool is_dummy() const;
481
#endif // TOOLS_ENABLED
482
483
AnimationMixer();
484
~AnimationMixer();
485
};
486
487
class AnimatedValuesBackup : public RefCounted {
488
GDCLASS(AnimatedValuesBackup, RefCounted);
489
490
AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> data;
491
492
public:
493
void set_data(const AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> p_data);
494
AHashMap<Animation::TypeHash, AnimationMixer::TrackCache *, HashHasher> get_data() const;
495
void clear_data();
496
497
AnimationMixer::TrackCache *get_cache_copy(AnimationMixer::TrackCache *p_cache) const;
498
499
~AnimatedValuesBackup() { clear_data(); }
500
};
501
502
VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeProcess);
503
VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeMethod);
504
VARIANT_ENUM_CAST(AnimationMixer::AnimationCallbackModeDiscrete);
505
506