1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup bke
22 */
23
24 #include <float.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_alloca.h"
33 #include "BLI_blenlib.h"
34 #include "BLI_dynstr.h"
35 #include "BLI_listbase.h"
36 #include "BLI_math_rotation.h"
37 #include "BLI_math_vector.h"
38 #include "BLI_string_utils.h"
39 #include "BLI_utildefines.h"
40
41 #include "BLT_translation.h"
42
43 #include "DNA_anim_types.h"
44 #include "DNA_light_types.h"
45 #include "DNA_material_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_space_types.h"
50 #include "DNA_texture_types.h"
51 #include "DNA_world_types.h"
52
53 #include "BKE_action.h"
54 #include "BKE_anim_data.h"
55 #include "BKE_animsys.h"
56 #include "BKE_context.h"
57 #include "BKE_fcurve.h"
58 #include "BKE_global.h"
59 #include "BKE_lib_id.h"
60 #include "BKE_main.h"
61 #include "BKE_material.h"
62 #include "BKE_nla.h"
63 #include "BKE_node.h"
64 #include "BKE_report.h"
65 #include "BKE_texture.h"
66
67 #include "DEG_depsgraph.h"
68 #include "DEG_depsgraph_query.h"
69
70 #include "RNA_access.h"
71
72 #include "BLO_read_write.h"
73
74 #include "nla_private.h"
75
76 #include "atomic_ops.h"
77
78 #include "CLG_log.h"
79
80 static CLG_LogRef LOG = {"bke.anim_sys"};
81
82 /* *********************************** */
83 /* KeyingSet API */
84
85 /* Finding Tools --------------------------- */
86
87 /* Find the first path that matches the given criteria */
88 /* TODO: do we want some method to perform partial matches too? */
BKE_keyingset_find_path(KeyingSet * ks,ID * id,const char group_name[],const char rna_path[],int array_index,int UNUSED (group_mode))89 KS_Path *BKE_keyingset_find_path(KeyingSet *ks,
90 ID *id,
91 const char group_name[],
92 const char rna_path[],
93 int array_index,
94 int UNUSED(group_mode))
95 {
96 KS_Path *ksp;
97
98 /* sanity checks */
99 if (ELEM(NULL, ks, rna_path, id)) {
100 return NULL;
101 }
102
103 /* loop over paths in the current KeyingSet, finding the first one where all settings match
104 * (i.e. the first one where none of the checks fail and equal 0)
105 */
106 for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
107 short eq_id = 1, eq_path = 1, eq_index = 1, eq_group = 1;
108
109 /* id */
110 if (id != ksp->id) {
111 eq_id = 0;
112 }
113
114 /* path */
115 if ((ksp->rna_path == NULL) || !STREQ(rna_path, ksp->rna_path)) {
116 eq_path = 0;
117 }
118
119 /* index - need to compare whole-array setting too... */
120 if (ksp->array_index != array_index) {
121 eq_index = 0;
122 }
123
124 /* group */
125 if (group_name) {
126 /* FIXME: these checks need to be coded... for now, it's not too important though */
127 }
128
129 /* if all aspects are ok, return */
130 if (eq_id && eq_path && eq_index && eq_group) {
131 return ksp;
132 }
133 }
134
135 /* none found */
136 return NULL;
137 }
138
139 /* Defining Tools --------------------------- */
140
141 /* Used to create a new 'custom' KeyingSet for the user,
142 * that will be automatically added to the stack */
BKE_keyingset_add(ListBase * list,const char idname[],const char name[],short flag,short keyingflag)143 KeyingSet *BKE_keyingset_add(
144 ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
145 {
146 KeyingSet *ks;
147
148 /* allocate new KeyingSet */
149 ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet");
150
151 BLI_strncpy(
152 ks->idname, (idname) ? idname : (name) ? name : DATA_("KeyingSet"), sizeof(ks->idname));
153 BLI_strncpy(ks->name, (name) ? name : (idname) ? idname : DATA_("Keying Set"), sizeof(ks->name));
154
155 ks->flag = flag;
156 ks->keyingflag = keyingflag;
157 /* NOTE: assume that if one is set one way, the other should be too, so that it'll work */
158 ks->keyingoverride = keyingflag;
159
160 /* add KeyingSet to list */
161 BLI_addtail(list, ks);
162
163 /* Make sure KeyingSet has a unique idname */
164 BLI_uniquename(
165 list, ks, DATA_("KeyingSet"), '.', offsetof(KeyingSet, idname), sizeof(ks->idname));
166
167 /* Make sure KeyingSet has a unique label (this helps with identification) */
168 BLI_uniquename(list, ks, DATA_("Keying Set"), '.', offsetof(KeyingSet, name), sizeof(ks->name));
169
170 /* return new KeyingSet for further editing */
171 return ks;
172 }
173
174 /* Add a path to a KeyingSet. Nothing is returned for now...
175 * Checks are performed to ensure that destination is appropriate for the KeyingSet in question
176 */
BKE_keyingset_add_path(KeyingSet * ks,ID * id,const char group_name[],const char rna_path[],int array_index,short flag,short groupmode)177 KS_Path *BKE_keyingset_add_path(KeyingSet *ks,
178 ID *id,
179 const char group_name[],
180 const char rna_path[],
181 int array_index,
182 short flag,
183 short groupmode)
184 {
185 KS_Path *ksp;
186
187 /* sanity checks */
188 if (ELEM(NULL, ks, rna_path)) {
189 CLOG_ERROR(&LOG, "no Keying Set and/or RNA Path to add path with");
190 return NULL;
191 }
192
193 /* ID is required for all types of KeyingSets */
194 if (id == NULL) {
195 CLOG_ERROR(&LOG, "No ID provided for Keying Set Path");
196 return NULL;
197 }
198
199 /* don't add if there is already a matching KS_Path in the KeyingSet */
200 if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
201 if (G.debug & G_DEBUG) {
202 CLOG_ERROR(&LOG, "destination already exists in Keying Set");
203 }
204 return NULL;
205 }
206
207 /* allocate a new KeyingSet Path */
208 ksp = MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
209
210 /* just store absolute info */
211 ksp->id = id;
212 if (group_name) {
213 BLI_strncpy(ksp->group, group_name, sizeof(ksp->group));
214 }
215 else {
216 ksp->group[0] = '\0';
217 }
218
219 /* store additional info for relative paths (just in case user makes the set relative) */
220 if (id) {
221 ksp->idtype = GS(id->name);
222 }
223
224 /* just copy path info */
225 /* TODO: should array index be checked too? */
226 ksp->rna_path = BLI_strdup(rna_path);
227 ksp->array_index = array_index;
228
229 /* store flags */
230 ksp->flag = flag;
231 ksp->groupmode = groupmode;
232
233 /* add KeyingSet path to KeyingSet */
234 BLI_addtail(&ks->paths, ksp);
235
236 /* return this path */
237 return ksp;
238 }
239
240 /* Free the given Keying Set path */
BKE_keyingset_free_path(KeyingSet * ks,KS_Path * ksp)241 void BKE_keyingset_free_path(KeyingSet *ks, KS_Path *ksp)
242 {
243 /* sanity check */
244 if (ELEM(NULL, ks, ksp)) {
245 return;
246 }
247
248 /* free RNA-path info */
249 if (ksp->rna_path) {
250 MEM_freeN(ksp->rna_path);
251 }
252
253 /* free path itself */
254 BLI_freelinkN(&ks->paths, ksp);
255 }
256
257 /* Copy all KeyingSets in the given list */
BKE_keyingsets_copy(ListBase * newlist,const ListBase * list)258 void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
259 {
260 KeyingSet *ksn;
261 KS_Path *kspn;
262
263 BLI_duplicatelist(newlist, list);
264
265 for (ksn = newlist->first; ksn; ksn = ksn->next) {
266 BLI_duplicatelist(&ksn->paths, &ksn->paths);
267
268 for (kspn = ksn->paths.first; kspn; kspn = kspn->next) {
269 kspn->rna_path = MEM_dupallocN(kspn->rna_path);
270 }
271 }
272 }
273
274 /* Freeing Tools --------------------------- */
275
276 /* Free data for KeyingSet but not set itself */
BKE_keyingset_free(KeyingSet * ks)277 void BKE_keyingset_free(KeyingSet *ks)
278 {
279 KS_Path *ksp, *kspn;
280
281 /* sanity check */
282 if (ks == NULL) {
283 return;
284 }
285
286 /* free each path as we go to avoid looping twice */
287 for (ksp = ks->paths.first; ksp; ksp = kspn) {
288 kspn = ksp->next;
289 BKE_keyingset_free_path(ks, ksp);
290 }
291 }
292
293 /* Free all the KeyingSets in the given list */
BKE_keyingsets_free(ListBase * list)294 void BKE_keyingsets_free(ListBase *list)
295 {
296 KeyingSet *ks, *ksn;
297
298 /* sanity check */
299 if (list == NULL) {
300 return;
301 }
302
303 /* loop over KeyingSets freeing them
304 * - BKE_keyingset_free() doesn't free the set itself, but it frees its sub-data
305 */
306 for (ks = list->first; ks; ks = ksn) {
307 ksn = ks->next;
308 BKE_keyingset_free(ks);
309 BLI_freelinkN(list, ks);
310 }
311 }
312
BKE_keyingsets_blend_write(BlendWriter * writer,ListBase * list)313 void BKE_keyingsets_blend_write(BlendWriter *writer, ListBase *list)
314 {
315 LISTBASE_FOREACH (KeyingSet *, ks, list) {
316 /* KeyingSet */
317 BLO_write_struct(writer, KeyingSet, ks);
318
319 /* Paths */
320 LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
321 /* Path */
322 BLO_write_struct(writer, KS_Path, ksp);
323
324 if (ksp->rna_path) {
325 BLO_write_string(writer, ksp->rna_path);
326 }
327 }
328 }
329 }
330
BKE_keyingsets_blend_read_data(BlendDataReader * reader,ListBase * list)331 void BKE_keyingsets_blend_read_data(BlendDataReader *reader, ListBase *list)
332 {
333 LISTBASE_FOREACH (KeyingSet *, ks, list) {
334 /* paths */
335 BLO_read_list(reader, &ks->paths);
336
337 LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
338 /* rna path */
339 BLO_read_data_address(reader, &ksp->rna_path);
340 }
341 }
342 }
343
BKE_keyingsets_blend_read_lib(BlendLibReader * reader,ID * id,ListBase * list)344 void BKE_keyingsets_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *list)
345 {
346 LISTBASE_FOREACH (KeyingSet *, ks, list) {
347 LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
348 BLO_read_id_address(reader, id->lib, &ksp->id);
349 }
350 }
351 }
352
BKE_keyingsets_blend_read_expand(BlendExpander * expander,ListBase * list)353 void BKE_keyingsets_blend_read_expand(BlendExpander *expander, ListBase *list)
354 {
355 LISTBASE_FOREACH (KeyingSet *, ks, list) {
356 LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
357 BLO_expand(expander, ksp->id);
358 }
359 }
360 }
361
362 /* ***************************************** */
363 /* Evaluation Data-Setting Backend */
364
BKE_animsys_store_rna_setting(PointerRNA * ptr,const char * rna_path,const int array_index,PathResolvedRNA * r_result)365 bool BKE_animsys_store_rna_setting(PointerRNA *ptr,
366 /* typically 'fcu->rna_path', 'fcu->array_index' */
367 const char *rna_path,
368 const int array_index,
369 PathResolvedRNA *r_result)
370 {
371 bool success = false;
372 const char *path = rna_path;
373
374 /* write value to setting */
375 if (path) {
376 /* get property to write to */
377 if (RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
378 if ((ptr->owner_id == NULL) || RNA_property_animateable(&r_result->ptr, r_result->prop)) {
379 int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
380
381 if (array_len && array_index >= array_len) {
382 if (G.debug & G_DEBUG) {
383 CLOG_WARN(&LOG,
384 "Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d",
385 (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
386 path,
387 array_index,
388 array_len - 1);
389 }
390 }
391 else {
392 r_result->prop_index = array_len ? array_index : -1;
393 success = true;
394 }
395 }
396 }
397 else {
398 /* failed to get path */
399 /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
400 * where some channels will not exist, but shouldn't lock up Action */
401 if (G.debug & G_DEBUG) {
402 CLOG_WARN(&LOG,
403 "Animato: Invalid path. ID = '%s', '%s[%d]'",
404 (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
405 path,
406 array_index);
407 }
408 }
409 }
410
411 return success;
412 }
413
414 /* less than 1.0 evaluates to false, use epsilon to avoid float error */
415 #define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
416
BKE_animsys_read_rna_setting(PathResolvedRNA * anim_rna,float * r_value)417 bool BKE_animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
418 {
419 PropertyRNA *prop = anim_rna->prop;
420 PointerRNA *ptr = &anim_rna->ptr;
421 int array_index = anim_rna->prop_index;
422 float orig_value;
423
424 /* caller must ensure this is animatable */
425 BLI_assert(RNA_property_animateable(ptr, prop) || ptr->owner_id == NULL);
426
427 switch (RNA_property_type(prop)) {
428 case PROP_BOOLEAN: {
429 if (array_index != -1) {
430 const int orig_value_coerce = RNA_property_boolean_get_index(ptr, prop, array_index);
431 orig_value = (float)orig_value_coerce;
432 }
433 else {
434 const int orig_value_coerce = RNA_property_boolean_get(ptr, prop);
435 orig_value = (float)orig_value_coerce;
436 }
437 break;
438 }
439 case PROP_INT: {
440 if (array_index != -1) {
441 const int orig_value_coerce = RNA_property_int_get_index(ptr, prop, array_index);
442 orig_value = (float)orig_value_coerce;
443 }
444 else {
445 const int orig_value_coerce = RNA_property_int_get(ptr, prop);
446 orig_value = (float)orig_value_coerce;
447 }
448 break;
449 }
450 case PROP_FLOAT: {
451 if (array_index != -1) {
452 const float orig_value_coerce = RNA_property_float_get_index(ptr, prop, array_index);
453 orig_value = (float)orig_value_coerce;
454 }
455 else {
456 const float orig_value_coerce = RNA_property_float_get(ptr, prop);
457 orig_value = (float)orig_value_coerce;
458 }
459 break;
460 }
461 case PROP_ENUM: {
462 const int orig_value_coerce = RNA_property_enum_get(ptr, prop);
463 orig_value = (float)orig_value_coerce;
464 break;
465 }
466 default:
467 /* nothing can be done here... so it is unsuccessful? */
468 return false;
469 }
470
471 if (r_value != NULL) {
472 *r_value = orig_value;
473 }
474
475 /* successful */
476 return true;
477 }
478
479 /* Write the given value to a setting using RNA, and return success */
BKE_animsys_write_rna_setting(PathResolvedRNA * anim_rna,const float value)480 bool BKE_animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
481 {
482 PropertyRNA *prop = anim_rna->prop;
483 PointerRNA *ptr = &anim_rna->ptr;
484 int array_index = anim_rna->prop_index;
485
486 /* caller must ensure this is animatable */
487 BLI_assert(RNA_property_animateable(ptr, prop) || ptr->owner_id == NULL);
488
489 /* Check whether value is new. Otherwise we skip all the updates. */
490 float old_value;
491 if (!BKE_animsys_read_rna_setting(anim_rna, &old_value)) {
492 return false;
493 }
494 if (old_value == value) {
495 return true;
496 }
497
498 switch (RNA_property_type(prop)) {
499 case PROP_BOOLEAN: {
500 const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
501 if (array_index != -1) {
502 RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
503 }
504 else {
505 RNA_property_boolean_set(ptr, prop, value_coerce);
506 }
507 break;
508 }
509 case PROP_INT: {
510 int value_coerce = (int)value;
511 RNA_property_int_clamp(ptr, prop, &value_coerce);
512 if (array_index != -1) {
513 RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
514 }
515 else {
516 RNA_property_int_set(ptr, prop, value_coerce);
517 }
518 break;
519 }
520 case PROP_FLOAT: {
521 float value_coerce = value;
522 RNA_property_float_clamp(ptr, prop, &value_coerce);
523 if (array_index != -1) {
524 RNA_property_float_set_index(ptr, prop, array_index, value_coerce);
525 }
526 else {
527 RNA_property_float_set(ptr, prop, value_coerce);
528 }
529 break;
530 }
531 case PROP_ENUM: {
532 const int value_coerce = (int)value;
533 RNA_property_enum_set(ptr, prop, value_coerce);
534 break;
535 }
536 default:
537 /* nothing can be done here... so it is unsuccessful? */
538 return false;
539 }
540
541 /* successful */
542 return true;
543 }
544
animsys_construct_orig_pointer_rna(const PointerRNA * ptr,PointerRNA * ptr_orig)545 static bool animsys_construct_orig_pointer_rna(const PointerRNA *ptr, PointerRNA *ptr_orig)
546 {
547 *ptr_orig = *ptr;
548 /* NOTE: nlastrip_evaluate_controls() creates PointerRNA with ID of NULL. Technically, this is
549 * not a valid pointer, but there are exceptions in various places of this file which handles
550 * such pointers.
551 * We do special trickery here as well, to quickly go from evaluated to original NlaStrip. */
552 if (ptr->owner_id == NULL) {
553 if (ptr->type != &RNA_NlaStrip) {
554 return false;
555 }
556 NlaStrip *strip = ((NlaStrip *)ptr_orig->data);
557 if (strip->orig_strip == NULL) {
558 return false;
559 }
560 ptr_orig->data = strip->orig_strip;
561 }
562 else {
563 ptr_orig->owner_id = ptr_orig->owner_id->orig_id;
564 ptr_orig->data = ptr_orig->owner_id;
565 }
566 return true;
567 }
568
animsys_write_orig_anim_rna(PointerRNA * ptr,const char * rna_path,int array_index,float value)569 static void animsys_write_orig_anim_rna(PointerRNA *ptr,
570 const char *rna_path,
571 int array_index,
572 float value)
573 {
574 PointerRNA ptr_orig;
575 if (!animsys_construct_orig_pointer_rna(ptr, &ptr_orig)) {
576 return;
577 }
578 PathResolvedRNA orig_anim_rna;
579 /* TODO(sergey): Should be possible to cache resolved path in dependency graph somehow. */
580 if (BKE_animsys_store_rna_setting(&ptr_orig, rna_path, array_index, &orig_anim_rna)) {
581 BKE_animsys_write_rna_setting(&orig_anim_rna, value);
582 }
583 }
584
585 /**
586 * Evaluate all the F-Curves in the given list
587 * This performs a set of standard checks. If extra checks are required,
588 * separate code should be used.
589 */
animsys_evaluate_fcurves(PointerRNA * ptr,ListBase * list,const AnimationEvalContext * anim_eval_context,bool flush_to_original)590 static void animsys_evaluate_fcurves(PointerRNA *ptr,
591 ListBase *list,
592 const AnimationEvalContext *anim_eval_context,
593 bool flush_to_original)
594 {
595 /* Calculate then execute each curve. */
596 LISTBASE_FOREACH (FCurve *, fcu, list) {
597 /* Check if this F-Curve doesn't belong to a muted group. */
598 if ((fcu->grp != NULL) && (fcu->grp->flag & AGRP_MUTED)) {
599 continue;
600 }
601 /* Check if this curve should be skipped. */
602 if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED))) {
603 continue;
604 }
605 /* Skip empty curves, as if muted. */
606 if (BKE_fcurve_is_empty(fcu)) {
607 continue;
608 }
609 PathResolvedRNA anim_rna;
610 if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
611 const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
612 BKE_animsys_write_rna_setting(&anim_rna, curval);
613 if (flush_to_original) {
614 animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
615 }
616 }
617 }
618 }
619
620 /* ***************************************** */
621 /* Driver Evaluation */
622
BKE_animsys_eval_context_construct(struct Depsgraph * depsgraph,float eval_time)623 AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
624 float eval_time)
625 {
626 AnimationEvalContext ctx = {
627 .depsgraph = depsgraph,
628 .eval_time = eval_time,
629 };
630 return ctx;
631 }
632
BKE_animsys_eval_context_construct_at(const AnimationEvalContext * anim_eval_context,float eval_time)633 AnimationEvalContext BKE_animsys_eval_context_construct_at(
634 const AnimationEvalContext *anim_eval_context, float eval_time)
635 {
636 return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time);
637 }
638
639 /* Evaluate Drivers */
animsys_evaluate_drivers(PointerRNA * ptr,AnimData * adt,const AnimationEvalContext * anim_eval_context)640 static void animsys_evaluate_drivers(PointerRNA *ptr,
641 AnimData *adt,
642 const AnimationEvalContext *anim_eval_context)
643 {
644 FCurve *fcu;
645
646 /* drivers are stored as F-Curves, but we cannot use the standard code, as we need to check if
647 * the depsgraph requested that this driver be evaluated...
648 */
649 for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
650 ChannelDriver *driver = fcu->driver;
651 bool ok = false;
652
653 /* check if this driver's curve should be skipped */
654 if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
655 /* check if driver itself is tagged for recalculation */
656 /* XXX driver recalc flag is not set yet by depsgraph! */
657 if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID)) {
658 /* evaluate this using values set already in other places
659 * NOTE: for 'layering' option later on, we should check if we should remove old value
660 * before adding new to only be done when drivers only changed. */
661 PathResolvedRNA anim_rna;
662 if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
663 const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
664 ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
665 }
666
667 /* set error-flag if evaluation failed */
668 if (ok == 0) {
669 driver->flag |= DRIVER_FLAG_INVALID;
670 }
671 }
672 }
673 }
674 }
675
676 /* ***************************************** */
677 /* Actions Evaluation */
678
679 /* strictly not necessary for actual "evaluation", but it is a useful safety check
680 * to reduce the amount of times that users end up having to "revive" wrongly-assigned
681 * actions
682 */
action_idcode_patch_check(ID * id,bAction * act)683 static void action_idcode_patch_check(ID *id, bAction *act)
684 {
685 int idcode = 0;
686
687 /* just in case */
688 if (ELEM(NULL, id, act)) {
689 return;
690 }
691
692 idcode = GS(id->name);
693
694 /* the actual checks... hopefully not too much of a performance hit in the long run... */
695 if (act->idroot == 0) {
696 /* use the current root if not set already
697 * (i.e. newly created actions and actions from 2.50-2.57 builds).
698 * - this has problems if there are 2 users, and the first one encountered is the invalid one
699 * in which case, the user will need to manually fix this (?)
700 */
701 act->idroot = idcode;
702 }
703 else if (act->idroot != idcode) {
704 /* only report this error if debug mode is enabled (to save performance everywhere else) */
705 if (G.debug & G_DEBUG) {
706 printf(
707 "AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of "
708 "type %d such as '%s'\n",
709 act->id.name + 2,
710 idcode,
711 id->name);
712 }
713 }
714 }
715
716 /* ----------------------------------------- */
717
718 /* Evaluate Action Group */
animsys_evaluate_action_group(PointerRNA * ptr,bAction * act,bActionGroup * agrp,const AnimationEvalContext * anim_eval_context)719 void animsys_evaluate_action_group(PointerRNA *ptr,
720 bAction *act,
721 bActionGroup *agrp,
722 const AnimationEvalContext *anim_eval_context)
723 {
724 FCurve *fcu;
725
726 /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
727 if (ELEM(NULL, act, agrp)) {
728 return;
729 }
730
731 action_idcode_patch_check(ptr->owner_id, act);
732
733 /* if group is muted, don't evaluated any of the F-Curve */
734 if (agrp->flag & AGRP_MUTED) {
735 return;
736 }
737
738 /* calculate then execute each curve */
739 for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
740 /* check if this curve should be skipped */
741 if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) {
742 PathResolvedRNA anim_rna;
743 if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
744 const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
745 BKE_animsys_write_rna_setting(&anim_rna, curval);
746 }
747 }
748 }
749 }
750
751 /* Evaluate Action (F-Curve Bag) */
animsys_evaluate_action_ex(PointerRNA * ptr,bAction * act,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)752 static void animsys_evaluate_action_ex(PointerRNA *ptr,
753 bAction *act,
754 const AnimationEvalContext *anim_eval_context,
755 const bool flush_to_original)
756 {
757 /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
758 if (act == NULL) {
759 return;
760 }
761
762 action_idcode_patch_check(ptr->owner_id, act);
763
764 /* calculate then execute each curve */
765 animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
766 }
767
animsys_evaluate_action(PointerRNA * ptr,bAction * act,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)768 void animsys_evaluate_action(PointerRNA *ptr,
769 bAction *act,
770 const AnimationEvalContext *anim_eval_context,
771 const bool flush_to_original)
772 {
773 animsys_evaluate_action_ex(ptr, act, anim_eval_context, flush_to_original);
774 }
775
776 /* ***************************************** */
777 /* NLA System - Evaluation */
778
779 /* calculate influence of strip based for given frame based on blendin/out values */
nlastrip_get_influence(NlaStrip * strip,float cframe)780 static float nlastrip_get_influence(NlaStrip *strip, float cframe)
781 {
782 /* sanity checks - normalize the blendin/out values? */
783 strip->blendin = fabsf(strip->blendin);
784 strip->blendout = fabsf(strip->blendout);
785
786 /* result depends on where frame is in respect to blendin/out values */
787 if (IS_EQF(strip->blendin, 0.0f) == false && (cframe <= (strip->start + strip->blendin))) {
788 /* there is some blend-in */
789 return fabsf(cframe - strip->start) / (strip->blendin);
790 }
791 if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
792 /* there is some blend-out */
793 return fabsf(strip->end - cframe) / (strip->blendout);
794 }
795
796 /* in the middle of the strip, we should be full strength */
797 return 1.0f;
798 }
799
800 /* evaluate the evaluation time and influence for the strip, storing the results in the strip */
nlastrip_evaluate_controls(NlaStrip * strip,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)801 static void nlastrip_evaluate_controls(NlaStrip *strip,
802 const AnimationEvalContext *anim_eval_context,
803 const bool flush_to_original)
804 {
805 /* now strip's evaluate F-Curves for these settings (if applicable) */
806 if (strip->fcurves.first) {
807 PointerRNA strip_ptr;
808
809 /* create RNA-pointer needed to set values */
810 RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
811
812 /* execute these settings as per normal */
813 animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original);
814 }
815
816 /* analytically generate values for influence and time (if applicable)
817 * - we do this after the F-Curves have been evaluated to override the effects of those
818 * in case the override has been turned off.
819 */
820 if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
821 strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time);
822 }
823
824 /* Bypass evaluation time computation if time mapping is disabled. */
825 if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
826 strip->strip_time = anim_eval_context->eval_time;
827 return;
828 }
829
830 if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
831 strip->strip_time = nlastrip_get_frame(
832 strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL);
833 }
834
835 /* if user can control the evaluation time (using F-Curves), consider the option which allows
836 * this time to be clamped to lie within extents of the action-clip, so that a steady changing
837 * rate of progress through several cycles of the clip can be achieved easily.
838 */
839 /* NOTE: if we add any more of these special cases, we better group them up nicely... */
840 if ((strip->flag & NLASTRIP_FLAG_USR_TIME) && (strip->flag & NLASTRIP_FLAG_USR_TIME_CYCLIC)) {
841 strip->strip_time = fmod(strip->strip_time - strip->actstart, strip->actend - strip->actstart);
842 }
843 }
844
845 /* gets the strip active at the current time for a list of strips for evaluation purposes */
nlastrips_ctime_get_strip(ListBase * list,ListBase * strips,short index,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)846 NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
847 ListBase *strips,
848 short index,
849 const AnimationEvalContext *anim_eval_context,
850 const bool flush_to_original)
851 {
852 NlaStrip *strip, *estrip = NULL;
853 NlaEvalStrip *nes;
854 short side = 0;
855 float ctime = anim_eval_context->eval_time;
856
857 /* loop over strips, checking if they fall within the range */
858 for (strip = strips->first; strip; strip = strip->next) {
859 /* check if current time occurs within this strip */
860 if (IN_RANGE_INCL(ctime, strip->start, strip->end) ||
861 (strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
862 /* this strip is active, so try to use it */
863 estrip = strip;
864 side = NES_TIME_WITHIN;
865 break;
866 }
867
868 /* if time occurred before current strip... */
869 if (ctime < strip->start) {
870 if (strip == strips->first) {
871 /* before first strip - only try to use it if it extends backwards in time too */
872 if (strip->extendmode == NLASTRIP_EXTEND_HOLD) {
873 estrip = strip;
874 }
875
876 /* side is 'before' regardless of whether there's a useful strip */
877 side = NES_TIME_BEFORE;
878 }
879 else {
880 /* before next strip - previous strip has ended, but next hasn't begun,
881 * so blending mode depends on whether strip is being held or not...
882 * - only occurs when no transition strip added, otherwise the transition would have
883 * been picked up above...
884 */
885 strip = strip->prev;
886
887 if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
888 estrip = strip;
889 }
890 side = NES_TIME_AFTER;
891 }
892 break;
893 }
894
895 /* if time occurred after current strip... */
896 if (ctime > strip->end) {
897 /* only if this is the last strip should we do anything, and only if that is being held */
898 if (strip == strips->last) {
899 if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
900 estrip = strip;
901 }
902
903 side = NES_TIME_AFTER;
904 break;
905 }
906
907 /* otherwise, skip... as the 'before' case will catch it more elegantly! */
908 }
909 }
910
911 /* check if a valid strip was found
912 * - must not be muted (i.e. will have contribution
913 */
914 if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED)) {
915 return NULL;
916 }
917
918 /* if ctime was not within the boundaries of the strip, clamp! */
919 switch (side) {
920 case NES_TIME_BEFORE: /* extend first frame only */
921 ctime = estrip->start;
922 break;
923 case NES_TIME_AFTER: /* extend last frame only */
924 ctime = estrip->end;
925 break;
926 }
927
928 /* evaluate strip's evaluation controls
929 * - skip if no influence (i.e. same effect as muting the strip)
930 * - negative influence is not supported yet... how would that be defined?
931 */
932 /* TODO: this sounds a bit hacky having a few isolated F-Curves
933 * stuck on some data it operates on... */
934 AnimationEvalContext clamped_eval_context = BKE_animsys_eval_context_construct_at(
935 anim_eval_context, ctime);
936 nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original);
937 if (estrip->influence <= 0.0f) {
938 return NULL;
939 }
940
941 /* check if strip has valid data to evaluate,
942 * and/or perform any additional type-specific actions
943 */
944 switch (estrip->type) {
945 case NLASTRIP_TYPE_CLIP:
946 /* clip must have some action to evaluate */
947 if (estrip->act == NULL) {
948 return NULL;
949 }
950 break;
951 case NLASTRIP_TYPE_TRANSITION:
952 /* there must be strips to transition from and to (i.e. prev and next required) */
953 if (ELEM(NULL, estrip->prev, estrip->next)) {
954 return NULL;
955 }
956
957 /* evaluate controls for the relevant extents of the bordering strips... */
958 AnimationEvalContext start_eval_context = BKE_animsys_eval_context_construct_at(
959 anim_eval_context, estrip->start);
960 AnimationEvalContext end_eval_context = BKE_animsys_eval_context_construct_at(
961 anim_eval_context, estrip->end);
962 nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original);
963 nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original);
964 break;
965 }
966
967 /* add to list of strips we need to evaluate */
968 nes = MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
969
970 nes->strip = estrip;
971 nes->strip_mode = side;
972 nes->track_index = index;
973 nes->strip_time = estrip->strip_time;
974
975 if (list) {
976 BLI_addtail(list, nes);
977 }
978
979 return nes;
980 }
981
982 /* ---------------------- */
983
984 /* Initialize a valid mask, allocating memory if necessary. */
nlavalidmask_init(NlaValidMask * mask,int bits)985 static void nlavalidmask_init(NlaValidMask *mask, int bits)
986 {
987 if (BLI_BITMAP_SIZE(bits) > sizeof(mask->buffer)) {
988 mask->ptr = BLI_BITMAP_NEW(bits, "NlaValidMask");
989 }
990 else {
991 mask->ptr = mask->buffer;
992 }
993 }
994
995 /* Free allocated memory for the mask. */
nlavalidmask_free(NlaValidMask * mask)996 static void nlavalidmask_free(NlaValidMask *mask)
997 {
998 if (mask->ptr != mask->buffer) {
999 MEM_freeN(mask->ptr);
1000 }
1001 }
1002
1003 /* ---------------------- */
1004
1005 /* Hashing functions for NlaEvalChannelKey. */
nlaevalchan_keyhash(const void * ptr)1006 static uint nlaevalchan_keyhash(const void *ptr)
1007 {
1008 const NlaEvalChannelKey *key = ptr;
1009 uint hash = BLI_ghashutil_ptrhash(key->ptr.data);
1010 return hash ^ BLI_ghashutil_ptrhash(key->prop);
1011 }
1012
nlaevalchan_keycmp(const void * a,const void * b)1013 static bool nlaevalchan_keycmp(const void *a, const void *b)
1014 {
1015 const NlaEvalChannelKey *A = a;
1016 const NlaEvalChannelKey *B = b;
1017
1018 return ((A->ptr.data != B->ptr.data) || (A->prop != B->prop));
1019 }
1020
1021 /* ---------------------- */
1022
1023 /* Allocate a new blending value snapshot for the channel. */
nlaevalchan_snapshot_new(NlaEvalChannel * nec)1024 static NlaEvalChannelSnapshot *nlaevalchan_snapshot_new(NlaEvalChannel *nec)
1025 {
1026 int length = nec->base_snapshot.length;
1027
1028 size_t byte_size = sizeof(NlaEvalChannelSnapshot) + sizeof(float) * length;
1029 NlaEvalChannelSnapshot *nec_snapshot = MEM_callocN(byte_size, "NlaEvalChannelSnapshot");
1030
1031 nec_snapshot->channel = nec;
1032 nec_snapshot->length = length;
1033
1034 return nec_snapshot;
1035 }
1036
1037 /* Free a channel's blending value snapshot. */
nlaevalchan_snapshot_free(NlaEvalChannelSnapshot * nec_snapshot)1038 static void nlaevalchan_snapshot_free(NlaEvalChannelSnapshot *nec_snapshot)
1039 {
1040 BLI_assert(!nec_snapshot->is_base);
1041
1042 MEM_freeN(nec_snapshot);
1043 }
1044
1045 /* Copy all data in the snapshot. */
nlaevalchan_snapshot_copy(NlaEvalChannelSnapshot * dst,const NlaEvalChannelSnapshot * src)1046 static void nlaevalchan_snapshot_copy(NlaEvalChannelSnapshot *dst,
1047 const NlaEvalChannelSnapshot *src)
1048 {
1049 BLI_assert(dst->channel == src->channel);
1050
1051 memcpy(dst->values, src->values, sizeof(float) * dst->length);
1052 }
1053
1054 /* ---------------------- */
1055
1056 /* Initialize a blending state snapshot structure. */
nlaeval_snapshot_init(NlaEvalSnapshot * snapshot,NlaEvalData * nlaeval,NlaEvalSnapshot * base)1057 static void nlaeval_snapshot_init(NlaEvalSnapshot *snapshot,
1058 NlaEvalData *nlaeval,
1059 NlaEvalSnapshot *base)
1060 {
1061 snapshot->base = base;
1062 snapshot->size = MAX2(16, nlaeval->num_channels);
1063 snapshot->channels = MEM_callocN(sizeof(*snapshot->channels) * snapshot->size,
1064 "NlaEvalSnapshot::channels");
1065 }
1066
1067 /* Retrieve the individual channel snapshot. */
nlaeval_snapshot_get(NlaEvalSnapshot * snapshot,int index)1068 static NlaEvalChannelSnapshot *nlaeval_snapshot_get(NlaEvalSnapshot *snapshot, int index)
1069 {
1070 return (index < snapshot->size) ? snapshot->channels[index] : NULL;
1071 }
1072
1073 /* Ensure at least this number of slots exists. */
nlaeval_snapshot_ensure_size(NlaEvalSnapshot * snapshot,int size)1074 static void nlaeval_snapshot_ensure_size(NlaEvalSnapshot *snapshot, int size)
1075 {
1076 if (size > snapshot->size) {
1077 snapshot->size *= 2;
1078 CLAMP_MIN(snapshot->size, size);
1079 CLAMP_MIN(snapshot->size, 16);
1080
1081 size_t byte_size = sizeof(*snapshot->channels) * snapshot->size;
1082 snapshot->channels = MEM_recallocN_id(
1083 snapshot->channels, byte_size, "NlaEvalSnapshot::channels");
1084 }
1085 }
1086
1087 /* Retrieve the address of a slot in the blending state snapshot for this channel (may realloc). */
nlaeval_snapshot_ensure_slot(NlaEvalSnapshot * snapshot,NlaEvalChannel * nec)1088 static NlaEvalChannelSnapshot **nlaeval_snapshot_ensure_slot(NlaEvalSnapshot *snapshot,
1089 NlaEvalChannel *nec)
1090 {
1091 nlaeval_snapshot_ensure_size(snapshot, nec->owner->num_channels);
1092 return &snapshot->channels[nec->index];
1093 }
1094
1095 /* Retrieve the blending snapshot for the specified channel, with fallback to base. */
nlaeval_snapshot_find_channel(NlaEvalSnapshot * snapshot,NlaEvalChannel * nec)1096 static NlaEvalChannelSnapshot *nlaeval_snapshot_find_channel(NlaEvalSnapshot *snapshot,
1097 NlaEvalChannel *nec)
1098 {
1099 while (snapshot != NULL) {
1100 NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_get(snapshot, nec->index);
1101 if (nec_snapshot != NULL) {
1102 return nec_snapshot;
1103 }
1104 snapshot = snapshot->base;
1105 }
1106
1107 return &nec->base_snapshot;
1108 }
1109
1110 /* Retrieve or create the channel value snapshot, copying from the other snapshot
1111 * (or default values) */
nlaeval_snapshot_ensure_channel(NlaEvalSnapshot * snapshot,NlaEvalChannel * nec)1112 static NlaEvalChannelSnapshot *nlaeval_snapshot_ensure_channel(NlaEvalSnapshot *snapshot,
1113 NlaEvalChannel *nec)
1114 {
1115 NlaEvalChannelSnapshot **slot = nlaeval_snapshot_ensure_slot(snapshot, nec);
1116
1117 if (*slot == NULL) {
1118 NlaEvalChannelSnapshot *base_snapshot, *nec_snapshot;
1119
1120 nec_snapshot = nlaevalchan_snapshot_new(nec);
1121 base_snapshot = nlaeval_snapshot_find_channel(snapshot->base, nec);
1122
1123 nlaevalchan_snapshot_copy(nec_snapshot, base_snapshot);
1124
1125 *slot = nec_snapshot;
1126 }
1127
1128 return *slot;
1129 }
1130
1131 /* Free all memory owned by this blending snapshot structure. */
nlaeval_snapshot_free_data(NlaEvalSnapshot * snapshot)1132 static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
1133 {
1134 if (snapshot->channels != NULL) {
1135 for (int i = 0; i < snapshot->size; i++) {
1136 NlaEvalChannelSnapshot *nec_snapshot = snapshot->channels[i];
1137 if (nec_snapshot != NULL) {
1138 nlaevalchan_snapshot_free(nec_snapshot);
1139 }
1140 }
1141
1142 MEM_freeN(snapshot->channels);
1143 }
1144
1145 snapshot->base = NULL;
1146 snapshot->size = 0;
1147 snapshot->channels = NULL;
1148 }
1149
1150 /* ---------------------- */
1151
1152 /* Free memory owned by this evaluation channel. */
nlaevalchan_free_data(NlaEvalChannel * nec)1153 static void nlaevalchan_free_data(NlaEvalChannel *nec)
1154 {
1155 nlavalidmask_free(&nec->valid);
1156
1157 if (nec->blend_snapshot != NULL) {
1158 nlaevalchan_snapshot_free(nec->blend_snapshot);
1159 }
1160 }
1161
1162 /* Initialize a full NLA evaluation state structure. */
nlaeval_init(NlaEvalData * nlaeval)1163 static void nlaeval_init(NlaEvalData *nlaeval)
1164 {
1165 memset(nlaeval, 0, sizeof(*nlaeval));
1166
1167 nlaeval->path_hash = BLI_ghash_str_new("NlaEvalData::path_hash");
1168 nlaeval->key_hash = BLI_ghash_new(
1169 nlaevalchan_keyhash, nlaevalchan_keycmp, "NlaEvalData::key_hash");
1170 }
1171
nlaeval_free(NlaEvalData * nlaeval)1172 static void nlaeval_free(NlaEvalData *nlaeval)
1173 {
1174 /* Delete base snapshot - its channels are part of NlaEvalChannel and shouldn't be freed. */
1175 MEM_SAFE_FREE(nlaeval->base_snapshot.channels);
1176
1177 /* Delete result snapshot. */
1178 nlaeval_snapshot_free_data(&nlaeval->eval_snapshot);
1179
1180 /* Delete channels. */
1181 LISTBASE_FOREACH (NlaEvalChannel *, nec, &nlaeval->channels) {
1182 nlaevalchan_free_data(nec);
1183 }
1184
1185 BLI_freelistN(&nlaeval->channels);
1186 BLI_ghash_free(nlaeval->path_hash, NULL, NULL);
1187 BLI_ghash_free(nlaeval->key_hash, NULL, NULL);
1188 }
1189
1190 /* ---------------------- */
1191
nlaevalchan_validate_index(NlaEvalChannel * nec,int index)1192 static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index)
1193 {
1194 if (nec->is_array) {
1195 if (index >= 0 && index < nec->base_snapshot.length) {
1196 return index;
1197 }
1198
1199 return -1;
1200 }
1201 return 0;
1202 }
1203
1204 /* Initialize default values for NlaEvalChannel from the property data. */
nlaevalchan_get_default_values(NlaEvalChannel * nec,float * r_values)1205 static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
1206 {
1207 PointerRNA *ptr = &nec->key.ptr;
1208 PropertyRNA *prop = nec->key.prop;
1209 int length = nec->base_snapshot.length;
1210
1211 /* Use unit quaternion for quaternion properties. */
1212 if (nec->mix_mode == NEC_MIX_QUATERNION) {
1213 unit_qt(r_values);
1214 return;
1215 }
1216 /* Use all zero for Axis-Angle properties. */
1217 if (nec->mix_mode == NEC_MIX_AXIS_ANGLE) {
1218 zero_v4(r_values);
1219 return;
1220 }
1221
1222 /* NOTE: while this doesn't work for all RNA properties as default values aren't in fact
1223 * set properly for most of them, at least the common ones (which also happen to get used
1224 * in NLA strips a lot, e.g. scale) are set correctly.
1225 */
1226 if (RNA_property_array_check(prop)) {
1227 BLI_assert(length == RNA_property_array_length(ptr, prop));
1228 bool *tmp_bool;
1229 int *tmp_int;
1230
1231 switch (RNA_property_type(prop)) {
1232 case PROP_BOOLEAN:
1233 tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
1234 RNA_property_boolean_get_default_array(ptr, prop, tmp_bool);
1235 for (int i = 0; i < length; i++) {
1236 r_values[i] = (float)tmp_bool[i];
1237 }
1238 MEM_freeN(tmp_bool);
1239 break;
1240 case PROP_INT:
1241 tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
1242 RNA_property_int_get_default_array(ptr, prop, tmp_int);
1243 for (int i = 0; i < length; i++) {
1244 r_values[i] = (float)tmp_int[i];
1245 }
1246 MEM_freeN(tmp_int);
1247 break;
1248 case PROP_FLOAT:
1249 RNA_property_float_get_default_array(ptr, prop, r_values);
1250 break;
1251 default:
1252 memset(r_values, 0, sizeof(float) * length);
1253 }
1254 }
1255 else {
1256 BLI_assert(length == 1);
1257
1258 switch (RNA_property_type(prop)) {
1259 case PROP_BOOLEAN:
1260 *r_values = (float)RNA_property_boolean_get_default(ptr, prop);
1261 break;
1262 case PROP_INT:
1263 *r_values = (float)RNA_property_int_get_default(ptr, prop);
1264 break;
1265 case PROP_FLOAT:
1266 *r_values = RNA_property_float_get_default(ptr, prop);
1267 break;
1268 case PROP_ENUM:
1269 *r_values = (float)RNA_property_enum_get_default(ptr, prop);
1270 break;
1271 default:
1272 *r_values = 0.0f;
1273 }
1274 }
1275
1276 /* Ensure multiplicative properties aren't reset to 0. */
1277 if (nec->mix_mode == NEC_MIX_MULTIPLY) {
1278 for (int i = 0; i < length; i++) {
1279 if (r_values[i] == 0.0f) {
1280 r_values[i] = 1.0f;
1281 }
1282 }
1283 }
1284 }
1285
nlaevalchan_detect_mix_mode(NlaEvalChannelKey * key,int length)1286 static char nlaevalchan_detect_mix_mode(NlaEvalChannelKey *key, int length)
1287 {
1288 PropertySubType subtype = RNA_property_subtype(key->prop);
1289
1290 if (subtype == PROP_QUATERNION && length == 4) {
1291 return NEC_MIX_QUATERNION;
1292 }
1293 if (subtype == PROP_AXISANGLE && length == 4) {
1294 return NEC_MIX_AXIS_ANGLE;
1295 }
1296 if (RNA_property_flag(key->prop) & PROP_PROPORTIONAL) {
1297 return NEC_MIX_MULTIPLY;
1298 }
1299 return NEC_MIX_ADD;
1300 }
1301
1302 /* Verify that an appropriate NlaEvalChannel for this property exists. */
nlaevalchan_verify_key(NlaEvalData * nlaeval,const char * path,NlaEvalChannelKey * key)1303 static NlaEvalChannel *nlaevalchan_verify_key(NlaEvalData *nlaeval,
1304 const char *path,
1305 NlaEvalChannelKey *key)
1306 {
1307 /* Look it up in the key hash. */
1308 NlaEvalChannel **p_key_nec;
1309 NlaEvalChannelKey **p_key;
1310 bool found_key = BLI_ghash_ensure_p_ex(
1311 nlaeval->key_hash, key, (void ***)&p_key, (void ***)&p_key_nec);
1312
1313 if (found_key) {
1314 return *p_key_nec;
1315 }
1316
1317 /* Create the channel. */
1318 bool is_array = RNA_property_array_check(key->prop);
1319 int length = is_array ? RNA_property_array_length(&key->ptr, key->prop) : 1;
1320
1321 NlaEvalChannel *nec = MEM_callocN(sizeof(NlaEvalChannel) + sizeof(float) * length,
1322 "NlaEvalChannel");
1323
1324 /* Initialize the channel. */
1325 nec->rna_path = path;
1326 nec->key = *key;
1327
1328 nec->owner = nlaeval;
1329 nec->index = nlaeval->num_channels++;
1330 nec->is_array = is_array;
1331
1332 nec->mix_mode = nlaevalchan_detect_mix_mode(key, length);
1333
1334 nlavalidmask_init(&nec->valid, length);
1335
1336 nec->base_snapshot.channel = nec;
1337 nec->base_snapshot.length = length;
1338 nec->base_snapshot.is_base = true;
1339
1340 nlaevalchan_get_default_values(nec, nec->base_snapshot.values);
1341
1342 /* Store channel in data structures. */
1343 BLI_addtail(&nlaeval->channels, nec);
1344
1345 *nlaeval_snapshot_ensure_slot(&nlaeval->base_snapshot, nec) = &nec->base_snapshot;
1346
1347 *p_key_nec = nec;
1348 *p_key = &nec->key;
1349
1350 return nec;
1351 }
1352
1353 /* Verify that an appropriate NlaEvalChannel for this path exists. */
nlaevalchan_verify(PointerRNA * ptr,NlaEvalData * nlaeval,const char * path)1354 static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval, const char *path)
1355 {
1356 if (path == NULL) {
1357 return NULL;
1358 }
1359
1360 /* Lookup the path in the path based hash. */
1361 NlaEvalChannel **p_path_nec;
1362 bool found_path = BLI_ghash_ensure_p(nlaeval->path_hash, (void *)path, (void ***)&p_path_nec);
1363
1364 if (found_path) {
1365 return *p_path_nec;
1366 }
1367
1368 /* Cache NULL result for now. */
1369 *p_path_nec = NULL;
1370
1371 /* Resolve the property and look it up in the key hash. */
1372 NlaEvalChannelKey key;
1373
1374 if (!RNA_path_resolve_property(ptr, path, &key.ptr, &key.prop)) {
1375 /* Report failure to resolve the path. */
1376 if (G.debug & G_DEBUG) {
1377 CLOG_WARN(&LOG,
1378 "Animato: Invalid path. ID = '%s', '%s'",
1379 (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
1380 path);
1381 }
1382
1383 return NULL;
1384 }
1385
1386 /* Check that the property can be animated. */
1387 if (ptr->owner_id != NULL && !RNA_property_animateable(&key.ptr, key.prop)) {
1388 return NULL;
1389 }
1390
1391 NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, path, &key);
1392
1393 if (nec->rna_path == NULL) {
1394 nec->rna_path = path;
1395 }
1396
1397 return *p_path_nec = nec;
1398 }
1399
1400 /* ---------------------- */
1401
1402 /* accumulate the old and new values of a channel according to mode and influence */
nla_blend_value(int blendmode,float old_value,float value,float inf)1403 static float nla_blend_value(int blendmode, float old_value, float value, float inf)
1404 {
1405 /* Optimization: no need to try applying if there is no influence. */
1406 if (IS_EQF(inf, 0.0f)) {
1407 return old_value;
1408 }
1409
1410 /* perform blending */
1411 switch (blendmode) {
1412 case NLASTRIP_MODE_ADD:
1413 /* simply add the scaled value on to the stack */
1414 return old_value + (value * inf);
1415
1416 case NLASTRIP_MODE_SUBTRACT:
1417 /* simply subtract the scaled value from the stack */
1418 return old_value - (value * inf);
1419
1420 case NLASTRIP_MODE_MULTIPLY:
1421 /* multiply the scaled value with the stack */
1422 /* Formula Used:
1423 * result = fac * (a * b) + (1 - fac) * a
1424 */
1425 return inf * (old_value * value) + (1 - inf) * old_value;
1426
1427 case NLASTRIP_MODE_COMBINE:
1428 BLI_assert(!"combine mode");
1429 ATTR_FALLTHROUGH;
1430
1431 case NLASTRIP_MODE_REPLACE:
1432 default
1433 : /* TODO: do we really want to blend by default? it seems more uses might prefer add... */
1434 /* do linear interpolation
1435 * - the influence of the accumulated data (elsewhere, that is called dstweight)
1436 * is 1 - influence, since the strip's influence is srcweight
1437 */
1438 return old_value * (1.0f - inf) + (value * inf);
1439 }
1440 }
1441
1442 /* accumulate the old and new values of a channel according to mode and influence */
nla_combine_value(int mix_mode,float base_value,float old_value,float value,float inf)1443 static float nla_combine_value(
1444 int mix_mode, float base_value, float old_value, float value, float inf)
1445 {
1446 /* Optimization: no need to try applying if there is no influence. */
1447 if (IS_EQF(inf, 0.0f)) {
1448 return old_value;
1449 }
1450
1451 /* perform blending */
1452 switch (mix_mode) {
1453 case NEC_MIX_ADD:
1454 case NEC_MIX_AXIS_ANGLE:
1455 return old_value + (value - base_value) * inf;
1456
1457 case NEC_MIX_MULTIPLY:
1458 if (base_value == 0.0f) {
1459 base_value = 1.0f;
1460 }
1461 return old_value * powf(value / base_value, inf);
1462
1463 case NEC_MIX_QUATERNION:
1464 default:
1465 BLI_assert(!"invalid mix mode");
1466 return old_value;
1467 }
1468 }
1469
1470 /* compute the value that would blend to the desired target value using nla_blend_value */
nla_invert_blend_value(int blend_mode,float old_value,float target_value,float influence,float * r_value)1471 static bool nla_invert_blend_value(
1472 int blend_mode, float old_value, float target_value, float influence, float *r_value)
1473 {
1474 switch (blend_mode) {
1475 case NLASTRIP_MODE_ADD:
1476 *r_value = (target_value - old_value) / influence;
1477 return true;
1478
1479 case NLASTRIP_MODE_SUBTRACT:
1480 *r_value = (old_value - target_value) / influence;
1481 return true;
1482
1483 case NLASTRIP_MODE_MULTIPLY:
1484 if (old_value == 0.0f) {
1485 /* Resolve 0/0 to 1. */
1486 if (target_value == 0.0f) {
1487 *r_value = 1.0f;
1488 return true;
1489 }
1490 /* Division by zero. */
1491 return false;
1492 }
1493 else {
1494 *r_value = (target_value - old_value) / influence / old_value + 1.0f;
1495 return true;
1496 }
1497
1498 case NLASTRIP_MODE_COMBINE:
1499 BLI_assert(!"combine mode");
1500 ATTR_FALLTHROUGH;
1501
1502 case NLASTRIP_MODE_REPLACE:
1503 default:
1504 *r_value = (target_value - old_value) / influence + old_value;
1505 return true;
1506 }
1507 }
1508
1509 /* compute the value that would blend to the desired target value using nla_combine_value */
nla_invert_combine_value(int mix_mode,float base_value,float old_value,float target_value,float influence,float * r_value)1510 static bool nla_invert_combine_value(int mix_mode,
1511 float base_value,
1512 float old_value,
1513 float target_value,
1514 float influence,
1515 float *r_value)
1516 {
1517 switch (mix_mode) {
1518 case NEC_MIX_ADD:
1519 case NEC_MIX_AXIS_ANGLE:
1520 *r_value = base_value + (target_value - old_value) / influence;
1521 return true;
1522
1523 case NEC_MIX_MULTIPLY:
1524 if (base_value == 0.0f) {
1525 base_value = 1.0f;
1526 }
1527 if (old_value == 0.0f) {
1528 /* Resolve 0/0 to 1. */
1529 if (target_value == 0.0f) {
1530 *r_value = base_value;
1531 return true;
1532 }
1533 /* Division by zero. */
1534 return false;
1535 }
1536
1537 *r_value = base_value * powf(target_value / old_value, 1.0f / influence);
1538 return true;
1539
1540 case NEC_MIX_QUATERNION:
1541 default:
1542 BLI_assert(!"invalid mix mode");
1543 return false;
1544 }
1545 }
1546
1547 /* accumulate quaternion channels for Combine mode according to influence */
nla_combine_quaternion(const float old_values[4],const float values[4],float influence,float result[4])1548 static void nla_combine_quaternion(const float old_values[4],
1549 const float values[4],
1550 float influence,
1551 float result[4])
1552 {
1553 float tmp_old[4], tmp_new[4];
1554
1555 normalize_qt_qt(tmp_old, old_values);
1556 normalize_qt_qt(tmp_new, values);
1557
1558 pow_qt_fl_normalized(tmp_new, influence);
1559 mul_qt_qtqt(result, tmp_old, tmp_new);
1560 }
1561
1562 /* invert accumulation of quaternion channels for Combine mode according to influence */
nla_invert_combine_quaternion(const float old_values[4],const float values[4],float influence,float result[4])1563 static void nla_invert_combine_quaternion(const float old_values[4],
1564 const float values[4],
1565 float influence,
1566 float result[4])
1567 {
1568 float tmp_old[4], tmp_new[4];
1569
1570 normalize_qt_qt(tmp_old, old_values);
1571 normalize_qt_qt(tmp_new, values);
1572 invert_qt_normalized(tmp_old);
1573
1574 mul_qt_qtqt(result, tmp_old, tmp_new);
1575 pow_qt_fl_normalized(result, 1.0f / influence);
1576 }
1577
1578 /* Data about the current blend mode. */
1579 typedef struct NlaBlendData {
1580 NlaEvalSnapshot *snapshot;
1581 int mode;
1582 float influence;
1583
1584 NlaEvalChannel *blend_queue;
1585 } NlaBlendData;
1586
1587 /* Queue the channel for deferred blending. */
nlaevalchan_queue_blend(NlaBlendData * blend,NlaEvalChannel * nec)1588 static NlaEvalChannelSnapshot *nlaevalchan_queue_blend(NlaBlendData *blend, NlaEvalChannel *nec)
1589 {
1590 if (!nec->in_blend) {
1591 if (nec->blend_snapshot == NULL) {
1592 nec->blend_snapshot = nlaevalchan_snapshot_new(nec);
1593 }
1594
1595 nec->in_blend = true;
1596 nlaevalchan_snapshot_copy(nec->blend_snapshot, &nec->base_snapshot);
1597
1598 nec->next_blend = blend->blend_queue;
1599 blend->blend_queue = nec;
1600 }
1601
1602 return nec->blend_snapshot;
1603 }
1604
1605 /* Accumulate (i.e. blend) the given value on to the channel it affects. */
nlaeval_blend_value(NlaBlendData * blend,NlaEvalChannel * nec,int array_index,float value)1606 static bool nlaeval_blend_value(NlaBlendData *blend,
1607 NlaEvalChannel *nec,
1608 int array_index,
1609 float value)
1610 {
1611 if (nec == NULL) {
1612 return false;
1613 }
1614
1615 int index = nlaevalchan_validate_index(nec, array_index);
1616
1617 if (index < 0) {
1618 if (G.debug & G_DEBUG) {
1619 ID *id = nec->key.ptr.owner_id;
1620 CLOG_WARN(&LOG,
1621 "Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d",
1622 id ? (id->name + 2) : "<No ID>",
1623 nec->rna_path,
1624 array_index,
1625 nec->base_snapshot.length);
1626 }
1627
1628 return false;
1629 }
1630
1631 if (nec->mix_mode == NEC_MIX_QUATERNION) {
1632 /* For quaternion properties, always output all sub-channels. */
1633 BLI_bitmap_set_all(nec->valid.ptr, true, 4);
1634 }
1635 else {
1636 BLI_BITMAP_ENABLE(nec->valid.ptr, index);
1637 }
1638
1639 NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
1640 float *p_value = &nec_snapshot->values[index];
1641
1642 if (blend->mode == NLASTRIP_MODE_COMBINE) {
1643 /* Quaternion blending is deferred until all sub-channel values are known. */
1644 if (nec->mix_mode == NEC_MIX_QUATERNION) {
1645 NlaEvalChannelSnapshot *blend_snapshot = nlaevalchan_queue_blend(blend, nec);
1646
1647 blend_snapshot->values[index] = value;
1648 }
1649 else {
1650 float base_value = nec->base_snapshot.values[index];
1651
1652 *p_value = nla_combine_value(nec->mix_mode, base_value, *p_value, value, blend->influence);
1653 }
1654 }
1655 else {
1656 *p_value = nla_blend_value(blend->mode, *p_value, value, blend->influence);
1657 }
1658
1659 return true;
1660 }
1661
1662 /* Finish deferred quaternion blending. */
nlaeval_blend_flush(NlaBlendData * blend)1663 static void nlaeval_blend_flush(NlaBlendData *blend)
1664 {
1665 NlaEvalChannel *nec;
1666
1667 while ((nec = blend->blend_queue)) {
1668 blend->blend_queue = nec->next_blend;
1669 nec->in_blend = false;
1670
1671 NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_ensure_channel(blend->snapshot, nec);
1672 NlaEvalChannelSnapshot *blend_snapshot = nec->blend_snapshot;
1673
1674 if (nec->mix_mode == NEC_MIX_QUATERNION) {
1675 nla_combine_quaternion(
1676 nec_snapshot->values, blend_snapshot->values, blend->influence, nec_snapshot->values);
1677 }
1678 else {
1679 BLI_assert(!"mix quaternion");
1680 }
1681 }
1682 }
1683
1684 /* Blend the specified snapshots into the target, and free the input snapshots. */
nlaeval_snapshot_mix_and_free(NlaEvalData * nlaeval,NlaEvalSnapshot * out,NlaEvalSnapshot * in1,NlaEvalSnapshot * in2,float alpha)1685 static void nlaeval_snapshot_mix_and_free(NlaEvalData *nlaeval,
1686 NlaEvalSnapshot *out,
1687 NlaEvalSnapshot *in1,
1688 NlaEvalSnapshot *in2,
1689 float alpha)
1690 {
1691 BLI_assert(in1->base == out && in2->base == out);
1692
1693 nlaeval_snapshot_ensure_size(out, nlaeval->num_channels);
1694
1695 for (int i = 0; i < nlaeval->num_channels; i++) {
1696 NlaEvalChannelSnapshot *c_in1 = nlaeval_snapshot_get(in1, i);
1697 NlaEvalChannelSnapshot *c_in2 = nlaeval_snapshot_get(in2, i);
1698
1699 if (c_in1 || c_in2) {
1700 NlaEvalChannelSnapshot *c_out = out->channels[i];
1701
1702 /* Steal the entry from one of the input snapshots. */
1703 if (c_out == NULL) {
1704 if (c_in1 != NULL) {
1705 c_out = c_in1;
1706 in1->channels[i] = NULL;
1707 }
1708 else {
1709 c_out = c_in2;
1710 in2->channels[i] = NULL;
1711 }
1712 }
1713
1714 if (c_in1 == NULL) {
1715 c_in1 = nlaeval_snapshot_find_channel(in1->base, c_out->channel);
1716 }
1717 if (c_in2 == NULL) {
1718 c_in2 = nlaeval_snapshot_find_channel(in2->base, c_out->channel);
1719 }
1720
1721 out->channels[i] = c_out;
1722
1723 for (int j = 0; j < c_out->length; j++) {
1724 c_out->values[j] = c_in1->values[j] * (1.0f - alpha) + c_in2->values[j] * alpha;
1725 }
1726 }
1727 }
1728
1729 nlaeval_snapshot_free_data(in1);
1730 nlaeval_snapshot_free_data(in2);
1731 }
1732
1733 /* ---------------------- */
1734 /* F-Modifier stack joining/separation utilities -
1735 * should we generalize these for BLI_listbase.h interface? */
1736
1737 /* Temporarily join two lists of modifiers together, storing the result in a third list */
nlaeval_fmodifiers_join_stacks(ListBase * result,ListBase * list1,ListBase * list2)1738 static void nlaeval_fmodifiers_join_stacks(ListBase *result, ListBase *list1, ListBase *list2)
1739 {
1740 FModifier *fcm1, *fcm2;
1741
1742 /* if list1 is invalid... */
1743 if (ELEM(NULL, list1, list1->first)) {
1744 if (list2 && list2->first) {
1745 result->first = list2->first;
1746 result->last = list2->last;
1747 }
1748 }
1749 /* if list 2 is invalid... */
1750 else if (ELEM(NULL, list2, list2->first)) {
1751 result->first = list1->first;
1752 result->last = list1->last;
1753 }
1754 else {
1755 /* list1 should be added first, and list2 second,
1756 * with the endpoints of these being the endpoints for result
1757 * - the original lists must be left unchanged though, as we need that fact for restoring.
1758 */
1759 result->first = list1->first;
1760 result->last = list2->last;
1761
1762 fcm1 = list1->last;
1763 fcm2 = list2->first;
1764
1765 fcm1->next = fcm2;
1766 fcm2->prev = fcm1;
1767 }
1768 }
1769
1770 /* Split two temporary lists of modifiers */
nlaeval_fmodifiers_split_stacks(ListBase * list1,ListBase * list2)1771 static void nlaeval_fmodifiers_split_stacks(ListBase *list1, ListBase *list2)
1772 {
1773 FModifier *fcm1, *fcm2;
1774
1775 /* if list1/2 is invalid... just skip */
1776 if (ELEM(NULL, list1, list2)) {
1777 return;
1778 }
1779 if (ELEM(NULL, list1->first, list2->first)) {
1780 return;
1781 }
1782
1783 /* get endpoints */
1784 fcm1 = list1->last;
1785 fcm2 = list2->first;
1786
1787 /* clear their links */
1788 fcm1->next = NULL;
1789 fcm2->prev = NULL;
1790 }
1791
1792 /* ---------------------- */
1793
1794 /* evaluate action-clip strip */
nlastrip_evaluate_actionclip(PointerRNA * ptr,NlaEvalData * channels,ListBase * modifiers,NlaEvalStrip * nes,NlaEvalSnapshot * snapshot)1795 static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
1796 NlaEvalData *channels,
1797 ListBase *modifiers,
1798 NlaEvalStrip *nes,
1799 NlaEvalSnapshot *snapshot)
1800 {
1801 ListBase tmp_modifiers = {NULL, NULL};
1802 NlaStrip *strip = nes->strip;
1803 FCurve *fcu;
1804 float evaltime;
1805
1806 /* sanity checks for action */
1807 if (strip == NULL) {
1808 return;
1809 }
1810
1811 if (strip->act == NULL) {
1812 CLOG_ERROR(&LOG, "NLA-Strip Eval Error: Strip '%s' has no Action", strip->name);
1813 return;
1814 }
1815
1816 action_idcode_patch_check(ptr->owner_id, strip->act);
1817
1818 /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
1819 nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
1820
1821 /* evaluate strip's modifiers which modify time to evaluate the base curves at */
1822 FModifiersStackStorage storage;
1823 storage.modifier_count = BLI_listbase_count(&tmp_modifiers);
1824 storage.size_per_modifier = evaluate_fmodifiers_storage_size_per_modifier(&tmp_modifiers);
1825 storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
1826
1827 evaltime = evaluate_time_fmodifiers(&storage, &tmp_modifiers, NULL, 0.0f, strip->strip_time);
1828
1829 NlaBlendData blend = {
1830 .snapshot = snapshot,
1831 .mode = strip->blendmode,
1832 .influence = strip->influence,
1833 };
1834
1835 /* Evaluate all the F-Curves in the action,
1836 * saving the relevant pointers to data that will need to be used. */
1837 for (fcu = strip->act->curves.first; fcu; fcu = fcu->next) {
1838 float value = 0.0f;
1839
1840 /* check if this curve should be skipped */
1841 if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
1842 continue;
1843 }
1844 if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
1845 continue;
1846 }
1847 if (BKE_fcurve_is_empty(fcu)) {
1848 continue;
1849 }
1850
1851 /* evaluate the F-Curve's value for the time given in the strip
1852 * NOTE: we use the modified time here, since strip's F-Curve Modifiers
1853 * are applied on top of this.
1854 */
1855 value = evaluate_fcurve(fcu, evaltime);
1856
1857 /* apply strip's F-Curve Modifiers on this value
1858 * NOTE: we apply the strip's original evaluation time not the modified one
1859 * (as per standard F-Curve eval)
1860 */
1861 evaluate_value_fmodifiers(&storage, &tmp_modifiers, fcu, &value, strip->strip_time);
1862
1863 /* Get an NLA evaluation channel to work with,
1864 * and accumulate the evaluated value with the value(s)
1865 * stored in this channel if it has been used already. */
1866 NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
1867
1868 nlaeval_blend_value(&blend, nec, fcu->array_index, value);
1869 }
1870
1871 nlaeval_blend_flush(&blend);
1872
1873 /* unlink this strip's modifiers from the parent's modifiers again */
1874 nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
1875 }
1876
1877 /* evaluate transition strip */
nlastrip_evaluate_transition(PointerRNA * ptr,NlaEvalData * channels,ListBase * modifiers,NlaEvalStrip * nes,NlaEvalSnapshot * snapshot,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)1878 static void nlastrip_evaluate_transition(PointerRNA *ptr,
1879 NlaEvalData *channels,
1880 ListBase *modifiers,
1881 NlaEvalStrip *nes,
1882 NlaEvalSnapshot *snapshot,
1883 const AnimationEvalContext *anim_eval_context,
1884 const bool flush_to_original)
1885 {
1886 ListBase tmp_modifiers = {NULL, NULL};
1887 NlaEvalSnapshot snapshot1, snapshot2;
1888 NlaEvalStrip tmp_nes;
1889 NlaStrip *s1, *s2;
1890
1891 /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
1892 nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
1893
1894 /* get the two strips to operate on
1895 * - we use the endpoints of the strips directly flanking our strip
1896 * using these as the endpoints of the transition (destination and source)
1897 * - these should have already been determined to be valid...
1898 * - if this strip is being played in reverse, we need to swap these endpoints
1899 * otherwise they will be interpolated wrong
1900 */
1901 if (nes->strip->flag & NLASTRIP_FLAG_REVERSE) {
1902 s1 = nes->strip->next;
1903 s2 = nes->strip->prev;
1904 }
1905 else {
1906 s1 = nes->strip->prev;
1907 s2 = nes->strip->next;
1908 }
1909
1910 /* prepare template for 'evaluation strip'
1911 * - based on the transition strip's evaluation strip data
1912 * - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
1913 * - strip_time is the 'normalized' (i.e. in-strip) time for evaluation,
1914 * which doubles up as an additional weighting factor for the strip influences
1915 * which allows us to appear to be 'interpolating' between the two extremes
1916 */
1917 tmp_nes = *nes;
1918
1919 /* evaluate these strips into a temp-buffer (tmp_channels) */
1920 /* FIXME: modifier evaluation here needs some work... */
1921 /* first strip */
1922 tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
1923 tmp_nes.strip = s1;
1924 tmp_nes.strip_time = s1->strip_time;
1925 nlaeval_snapshot_init(&snapshot1, channels, snapshot);
1926 nlastrip_evaluate(
1927 ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original);
1928
1929 /* second strip */
1930 tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
1931 tmp_nes.strip = s2;
1932 tmp_nes.strip_time = s2->strip_time;
1933 nlaeval_snapshot_init(&snapshot2, channels, snapshot);
1934 nlastrip_evaluate(
1935 ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original);
1936
1937 /* accumulate temp-buffer and full-buffer, using the 'real' strip */
1938 nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
1939
1940 /* unlink this strip's modifiers from the parent's modifiers again */
1941 nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
1942 }
1943
1944 /* evaluate meta-strip */
nlastrip_evaluate_meta(PointerRNA * ptr,NlaEvalData * channels,ListBase * modifiers,NlaEvalStrip * nes,NlaEvalSnapshot * snapshot,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)1945 static void nlastrip_evaluate_meta(PointerRNA *ptr,
1946 NlaEvalData *channels,
1947 ListBase *modifiers,
1948 NlaEvalStrip *nes,
1949 NlaEvalSnapshot *snapshot,
1950 const AnimationEvalContext *anim_eval_context,
1951 const bool flush_to_original)
1952 {
1953 ListBase tmp_modifiers = {NULL, NULL};
1954 NlaStrip *strip = nes->strip;
1955 NlaEvalStrip *tmp_nes;
1956 float evaltime;
1957
1958 /* meta-strip was calculated normally to have some time to be evaluated at
1959 * and here we 'look inside' the meta strip, treating it as a decorated window to
1960 * its child strips, which get evaluated as if they were some tracks on a strip
1961 * (but with some extra modifiers to apply).
1962 *
1963 * NOTE: keep this in sync with animsys_evaluate_nla()
1964 */
1965
1966 /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
1967 nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
1968
1969 /* find the child-strip to evaluate */
1970 evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
1971 AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context,
1972 evaltime);
1973 tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original);
1974
1975 /* directly evaluate child strip into accumulation buffer...
1976 * - there's no need to use a temporary buffer (as it causes issues [T40082])
1977 */
1978 if (tmp_nes) {
1979 nlastrip_evaluate(
1980 ptr, channels, &tmp_modifiers, tmp_nes, snapshot, &child_context, flush_to_original);
1981
1982 /* free temp eval-strip */
1983 MEM_freeN(tmp_nes);
1984 }
1985
1986 /* unlink this strip's modifiers from the parent's modifiers again */
1987 nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
1988 }
1989
1990 /* evaluates the given evaluation strip */
nlastrip_evaluate(PointerRNA * ptr,NlaEvalData * channels,ListBase * modifiers,NlaEvalStrip * nes,NlaEvalSnapshot * snapshot,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)1991 void nlastrip_evaluate(PointerRNA *ptr,
1992 NlaEvalData *channels,
1993 ListBase *modifiers,
1994 NlaEvalStrip *nes,
1995 NlaEvalSnapshot *snapshot,
1996 const AnimationEvalContext *anim_eval_context,
1997 const bool flush_to_original)
1998 {
1999 NlaStrip *strip = nes->strip;
2000
2001 /* To prevent potential infinite recursion problems
2002 * (i.e. transition strip, beside meta strip containing a transition
2003 * several levels deep inside it),
2004 * we tag the current strip as being evaluated, and clear this when we leave.
2005 */
2006 /* TODO: be careful with this flag, since some edit tools may be running and have
2007 * set this while animation playback was running. */
2008 if (strip->flag & NLASTRIP_FLAG_EDIT_TOUCHED) {
2009 return;
2010 }
2011 strip->flag |= NLASTRIP_FLAG_EDIT_TOUCHED;
2012
2013 /* actions to take depend on the type of strip */
2014 switch (strip->type) {
2015 case NLASTRIP_TYPE_CLIP: /* action-clip */
2016 nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
2017 break;
2018 case NLASTRIP_TYPE_TRANSITION: /* transition */
2019 nlastrip_evaluate_transition(
2020 ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
2021 break;
2022 case NLASTRIP_TYPE_META: /* meta */
2023 nlastrip_evaluate_meta(
2024 ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
2025 break;
2026
2027 default: /* do nothing */
2028 break;
2029 }
2030
2031 /* clear temp recursion safe-check */
2032 strip->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
2033 }
2034
2035 /* write the accumulated settings to */
nladata_flush_channels(PointerRNA * ptr,NlaEvalData * channels,NlaEvalSnapshot * snapshot,const bool flush_to_original)2036 void nladata_flush_channels(PointerRNA *ptr,
2037 NlaEvalData *channels,
2038 NlaEvalSnapshot *snapshot,
2039 const bool flush_to_original)
2040 {
2041 /* sanity checks */
2042 if (channels == NULL) {
2043 return;
2044 }
2045
2046 /* for each channel with accumulated values, write its value on the property it affects */
2047 LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
2048 NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
2049
2050 PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1};
2051
2052 for (int i = 0; i < nec_snapshot->length; i++) {
2053 if (BLI_BITMAP_TEST(nec->valid.ptr, i)) {
2054 float value = nec_snapshot->values[i];
2055 if (nec->is_array) {
2056 rna.prop_index = i;
2057 }
2058 BKE_animsys_write_rna_setting(&rna, value);
2059 if (flush_to_original) {
2060 animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
2061 }
2062 }
2063 }
2064 }
2065 }
2066
2067 /* ---------------------- */
2068
nla_eval_domain_action(PointerRNA * ptr,NlaEvalData * channels,bAction * act,GSet * touched_actions)2069 static void nla_eval_domain_action(PointerRNA *ptr,
2070 NlaEvalData *channels,
2071 bAction *act,
2072 GSet *touched_actions)
2073 {
2074 if (!BLI_gset_add(touched_actions, act)) {
2075 return;
2076 }
2077
2078 LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
2079 /* check if this curve should be skipped */
2080 if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
2081 continue;
2082 }
2083 if ((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) {
2084 continue;
2085 }
2086 if (BKE_fcurve_is_empty(fcu)) {
2087 continue;
2088 }
2089
2090 NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
2091
2092 if (nec != NULL) {
2093 /* For quaternion properties, enable all sub-channels. */
2094 if (nec->mix_mode == NEC_MIX_QUATERNION) {
2095 BLI_bitmap_set_all(nec->valid.ptr, true, 4);
2096 continue;
2097 }
2098
2099 int idx = nlaevalchan_validate_index(nec, fcu->array_index);
2100
2101 if (idx >= 0) {
2102 BLI_BITMAP_ENABLE(nec->valid.ptr, idx);
2103 }
2104 }
2105 }
2106 }
2107
nla_eval_domain_strips(PointerRNA * ptr,NlaEvalData * channels,ListBase * strips,GSet * touched_actions)2108 static void nla_eval_domain_strips(PointerRNA *ptr,
2109 NlaEvalData *channels,
2110 ListBase *strips,
2111 GSet *touched_actions)
2112 {
2113 LISTBASE_FOREACH (NlaStrip *, strip, strips) {
2114 /* check strip's action */
2115 if (strip->act) {
2116 nla_eval_domain_action(ptr, channels, strip->act, touched_actions);
2117 }
2118
2119 /* check sub-strips (if metas) */
2120 nla_eval_domain_strips(ptr, channels, &strip->strips, touched_actions);
2121 }
2122 }
2123
2124 /**
2125 * Ensure that all channels touched by any of the actions in enabled tracks exist.
2126 * This is necessary to ensure that evaluation result depends only on current frame.
2127 */
animsys_evaluate_nla_domain(PointerRNA * ptr,NlaEvalData * channels,AnimData * adt)2128 static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels, AnimData *adt)
2129 {
2130 GSet *touched_actions = BLI_gset_ptr_new(__func__);
2131
2132 if (adt->action) {
2133 nla_eval_domain_action(ptr, channels, adt->action, touched_actions);
2134 }
2135
2136 /* NLA Data - Animation Data for Strips */
2137 LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
2138 /* solo and muting are mutually exclusive... */
2139 if (adt->flag & ADT_NLA_SOLO_TRACK) {
2140 /* skip if there is a solo track, but this isn't it */
2141 if ((nlt->flag & NLATRACK_SOLO) == 0) {
2142 continue;
2143 }
2144 /* else - mute doesn't matter */
2145 }
2146 else {
2147 /* no solo tracks - skip track if muted */
2148 if (nlt->flag & NLATRACK_MUTED) {
2149 continue;
2150 }
2151 }
2152
2153 nla_eval_domain_strips(ptr, channels, &nlt->strips, touched_actions);
2154 }
2155
2156 BLI_gset_free(touched_actions, NULL);
2157 }
2158
2159 /* ---------------------- */
2160
2161 /**
2162 * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
2163 *
2164 * \param[out] echannels: Evaluation channels with calculated values
2165 * \param[out] r_context: If not NULL,
2166 * data about the currently edited strip is stored here and excluded from value calculation.
2167 * \return false if NLA evaluation isn't actually applicable.
2168 */
animsys_evaluate_nla(NlaEvalData * echannels,PointerRNA * ptr,AnimData * adt,const AnimationEvalContext * anim_eval_context,const bool flush_to_original,NlaKeyframingContext * r_context)2169 static bool animsys_evaluate_nla(NlaEvalData *echannels,
2170 PointerRNA *ptr,
2171 AnimData *adt,
2172 const AnimationEvalContext *anim_eval_context,
2173 const bool flush_to_original,
2174 NlaKeyframingContext *r_context)
2175 {
2176 NlaTrack *nlt;
2177 short track_index = 0;
2178 bool has_strips = false;
2179
2180 ListBase estrips = {NULL, NULL};
2181 NlaEvalStrip *nes;
2182 NlaStrip dummy_strip_buf;
2183
2184 /* dummy strip for active action */
2185 NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
2186
2187 memset(dummy_strip, 0, sizeof(*dummy_strip));
2188
2189 /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
2190 for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
2191 /* stop here if tweaking is on and this strip is the tweaking track
2192 * (it will be the first one that's 'disabled')... */
2193 if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED)) {
2194 break;
2195 }
2196
2197 /* solo and muting are mutually exclusive... */
2198 if (adt->flag & ADT_NLA_SOLO_TRACK) {
2199 /* skip if there is a solo track, but this isn't it */
2200 if ((nlt->flag & NLATRACK_SOLO) == 0) {
2201 continue;
2202 }
2203 /* else - mute doesn't matter */
2204 }
2205 else {
2206 /* no solo tracks - skip track if muted */
2207 if (nlt->flag & NLATRACK_MUTED) {
2208 continue;
2209 }
2210 }
2211
2212 /* if this track has strips (but maybe they won't be suitable), set has_strips
2213 * - used for mainly for still allowing normal action evaluation...
2214 */
2215 if (nlt->strips.first) {
2216 has_strips = true;
2217 }
2218
2219 /* otherwise, get strip to evaluate for this channel */
2220 nes = nlastrips_ctime_get_strip(
2221 &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
2222 if (nes) {
2223 nes->track = nlt;
2224 }
2225 }
2226
2227 /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack
2228 * - only do this if we're not exclusively evaluating the 'solo' NLA-track
2229 * - however, if the 'solo' track houses the current 'tweaking' strip,
2230 * then we should allow this to play, otherwise nothing happens
2231 */
2232 if ((adt->action) && ((adt->flag & ADT_NLA_SOLO_TRACK) == 0 || (adt->flag & ADT_NLA_EDIT_ON))) {
2233 /* if there are strips, evaluate action as per NLA rules */
2234 if ((has_strips) || (adt->actstrip)) {
2235 /* make dummy NLA strip, and add that to the stack */
2236 ListBase dummy_trackslist;
2237
2238 dummy_trackslist.first = dummy_trackslist.last = dummy_strip;
2239
2240 /* Strips with a user-defined time curve don't get properly remapped for editing
2241 * at the moment, so mapping them just for display may be confusing. */
2242 bool is_inplace_tweak = (nlt) && !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
2243 !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
2244
2245 if (is_inplace_tweak) {
2246 /* edit active action in-place according to its active strip, so copy the data */
2247 memcpy(dummy_strip, adt->actstrip, sizeof(NlaStrip));
2248 /* Prevents nla eval from considering active strip's adj strips.
2249 * For user, this means entering tweak mode on a strip ignores evaluating adjacent strips
2250 * in the same track. */
2251 dummy_strip->next = dummy_strip->prev = NULL;
2252
2253 /* If tweaked strip is syncing action length, then evaluate using action length. */
2254 if (dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
2255 BKE_nlastrip_recalculate_bounds_sync_action(dummy_strip);
2256 }
2257 }
2258 else {
2259 /* set settings of dummy NLA strip from AnimData settings */
2260 dummy_strip->act = adt->action;
2261
2262 /* action range is calculated taking F-Modifiers into account
2263 * (which making new strips doesn't do due to the troublesome nature of that) */
2264 calc_action_range(dummy_strip->act, &dummy_strip->actstart, &dummy_strip->actend, 1);
2265 dummy_strip->start = dummy_strip->actstart;
2266 dummy_strip->end = (IS_EQF(dummy_strip->actstart, dummy_strip->actend)) ?
2267 (dummy_strip->actstart + 1.0f) :
2268 (dummy_strip->actend);
2269
2270 /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
2271 if (nlt && adt->actstrip) {
2272 dummy_strip->blendmode = adt->actstrip->blendmode;
2273 dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
2274 }
2275 else {
2276 dummy_strip->blendmode = adt->act_blendmode;
2277 dummy_strip->extendmode = adt->act_extendmode;
2278 }
2279
2280 /* Unless extend-mode is Nothing (might be useful for flattening NLA evaluation),
2281 * disable range. */
2282 if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
2283 dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
2284 }
2285
2286 dummy_strip->influence = adt->act_influence;
2287
2288 /* NOTE: must set this, or else the default setting overrides,
2289 * and this setting doesn't work. */
2290 dummy_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
2291 }
2292
2293 /* add this to our list of evaluation strips */
2294 if (r_context == NULL) {
2295 nlastrips_ctime_get_strip(
2296 &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
2297 }
2298 /* If computing the context for keyframing, store data there instead of the list. */
2299 else {
2300 /* The extend mode here effectively controls
2301 * whether it is possible to key-frame beyond the ends.*/
2302 dummy_strip->extendmode = (is_inplace_tweak &&
2303 !(dummy_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
2304 NLASTRIP_EXTEND_NOTHING :
2305 NLASTRIP_EXTEND_HOLD;
2306
2307 r_context->eval_strip = nes = nlastrips_ctime_get_strip(
2308 NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
2309
2310 /* These setting combinations require no data from strips below, so exit immediately. */
2311 if ((nes == NULL) ||
2312 (dummy_strip->blendmode == NLASTRIP_MODE_REPLACE && dummy_strip->influence == 1.0f)) {
2313 BLI_freelistN(&estrips);
2314 return true;
2315 }
2316 }
2317 }
2318 else {
2319 /* special case - evaluate as if there isn't any NLA data */
2320 BLI_freelistN(&estrips);
2321 return false;
2322 }
2323 }
2324
2325 /* only continue if there are strips to evaluate */
2326 if (BLI_listbase_is_empty(&estrips)) {
2327 return true;
2328 }
2329
2330 /* 2. for each strip, evaluate then accumulate on top of existing channels,
2331 * but don't set values yet. */
2332 for (nes = estrips.first; nes; nes = nes->next) {
2333 nlastrip_evaluate(ptr,
2334 echannels,
2335 NULL,
2336 nes,
2337 &echannels->eval_snapshot,
2338 anim_eval_context,
2339 flush_to_original);
2340 }
2341
2342 /* 3. free temporary evaluation data that's not used elsewhere */
2343 BLI_freelistN(&estrips);
2344 return true;
2345 }
2346
2347 /* NLA Evaluation function (mostly for use through do_animdata)
2348 * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into
2349 * some temp channels, where values can be accumulated in one go.
2350 */
animsys_calculate_nla(PointerRNA * ptr,AnimData * adt,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)2351 static void animsys_calculate_nla(PointerRNA *ptr,
2352 AnimData *adt,
2353 const AnimationEvalContext *anim_eval_context,
2354 const bool flush_to_original)
2355 {
2356 NlaEvalData echannels;
2357
2358 nlaeval_init(&echannels);
2359
2360 /* evaluate the NLA stack, obtaining a set of values to flush */
2361 if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
2362 /* reset any channels touched by currently inactive actions to default value */
2363 animsys_evaluate_nla_domain(ptr, &echannels, adt);
2364
2365 /* flush effects of accumulating channels in NLA to the actual data they affect */
2366 nladata_flush_channels(ptr, &echannels, &echannels.eval_snapshot, flush_to_original);
2367 }
2368 else {
2369 /* special case - evaluate as if there isn't any NLA data */
2370 /* TODO: this is really just a stop-gap measure... */
2371 if (G.debug & G_DEBUG) {
2372 CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
2373 }
2374
2375 animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original);
2376 }
2377
2378 /* free temp data */
2379 nlaeval_free(&echannels);
2380 }
2381
2382 /* ---------------------- */
2383
2384 /**
2385 * Prepare data necessary to compute correct keyframe values for NLA strips
2386 * with non-Replace mode or influence different from 1.
2387 *
2388 * \param cache: List used to cache contexts for reuse when keying
2389 * multiple channels in one operation.
2390 * \param ptr: RNA pointer to the Object with the animation.
2391 * \return Keyframing context, or NULL if not necessary.
2392 */
BKE_animsys_get_nla_keyframing_context(struct ListBase * cache,struct PointerRNA * ptr,struct AnimData * adt,const AnimationEvalContext * anim_eval_context,const bool flush_to_original)2393 NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
2394 struct ListBase *cache,
2395 struct PointerRNA *ptr,
2396 struct AnimData *adt,
2397 const AnimationEvalContext *anim_eval_context,
2398 const bool flush_to_original)
2399 {
2400 /* No remapping needed if NLA is off or no action. */
2401 if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
2402 (adt->flag & ADT_NLA_EVAL_OFF)) {
2403 return NULL;
2404 }
2405
2406 /* No remapping if editing an ordinary Replace action with full influence. */
2407 if (!(adt->flag & ADT_NLA_EDIT_ON) &&
2408 (adt->act_blendmode == NLASTRIP_MODE_REPLACE && adt->act_influence == 1.0f)) {
2409 return NULL;
2410 }
2411
2412 /* Try to find a cached context. */
2413 NlaKeyframingContext *ctx = BLI_findptr(cache, adt, offsetof(NlaKeyframingContext, adt));
2414
2415 if (ctx == NULL) {
2416 /* Allocate and evaluate a new context. */
2417 ctx = MEM_callocN(sizeof(*ctx), "NlaKeyframingContext");
2418 ctx->adt = adt;
2419
2420 nlaeval_init(&ctx->nla_channels);
2421 animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, anim_eval_context, flush_to_original, ctx);
2422
2423 BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
2424 BLI_addtail(cache, ctx);
2425 }
2426
2427 return ctx;
2428 }
2429
2430 /**
2431 * Apply correction from the NLA context to the values about to be keyframed.
2432 *
2433 * \param context: Context to use (may be NULL).
2434 * \param prop_ptr: Property about to be keyframed.
2435 * \param[in,out] values: Array of property values to adjust.
2436 * \param count: Number of values in the array.
2437 * \param index: Index of the element about to be updated, or -1.
2438 * \param[out] r_force_all: Set to true if all channels must be inserted. May be NULL.
2439 * \return False if correction fails due to a division by zero,
2440 * or null r_force_all when all channels are required.
2441 */
BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext * context,struct PointerRNA * prop_ptr,struct PropertyRNA * prop,float * values,int count,int index,bool * r_force_all)2442 bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
2443 struct PointerRNA *prop_ptr,
2444 struct PropertyRNA *prop,
2445 float *values,
2446 int count,
2447 int index,
2448 bool *r_force_all)
2449 {
2450 if (r_force_all != NULL) {
2451 *r_force_all = false;
2452 }
2453
2454 /* No context means no correction. */
2455 if (context == NULL || context->strip.act == NULL) {
2456 return true;
2457 }
2458
2459 /* If the strip is not evaluated, it is the same as zero influence. */
2460 if (context->eval_strip == NULL) {
2461 return false;
2462 }
2463
2464 /* Full influence Replace strips also require no correction. */
2465 int blend_mode = context->strip.blendmode;
2466 float influence = context->strip.influence;
2467
2468 if (blend_mode == NLASTRIP_MODE_REPLACE && influence == 1.0f) {
2469 return true;
2470 }
2471
2472 /* Zero influence is division by zero. */
2473 if (influence <= 0.0f) {
2474 return false;
2475 }
2476
2477 /* Find the evaluation channel for the NLA stack below current strip. */
2478 NlaEvalChannelKey key = {
2479 .ptr = *prop_ptr,
2480 .prop = prop,
2481 };
2482 NlaEvalData *nlaeval = &context->nla_channels;
2483 NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, NULL, &key);
2484
2485 if (nec->base_snapshot.length != count) {
2486 BLI_assert(!"invalid value count");
2487 return false;
2488 }
2489
2490 /* Invert the blending operation to compute the desired key values. */
2491 NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(&nlaeval->eval_snapshot,
2492 nec);
2493
2494 float *old_values = nec_snapshot->values;
2495
2496 if (blend_mode == NLASTRIP_MODE_COMBINE) {
2497 /* Quaternion combine handles all sub-channels as a unit. */
2498 if (nec->mix_mode == NEC_MIX_QUATERNION) {
2499 if (r_force_all == NULL) {
2500 return false;
2501 }
2502
2503 *r_force_all = true;
2504
2505 nla_invert_combine_quaternion(old_values, values, influence, values);
2506 }
2507 else {
2508 float *base_values = nec->base_snapshot.values;
2509
2510 for (int i = 0; i < count; i++) {
2511 if (ELEM(index, i, -1)) {
2512 if (!nla_invert_combine_value(nec->mix_mode,
2513 base_values[i],
2514 old_values[i],
2515 values[i],
2516 influence,
2517 &values[i])) {
2518 return false;
2519 }
2520 }
2521 }
2522 }
2523 }
2524 else {
2525 for (int i = 0; i < count; i++) {
2526 if (ELEM(index, i, -1)) {
2527 if (!nla_invert_blend_value(blend_mode, old_values[i], values[i], influence, &values[i])) {
2528 return false;
2529 }
2530 }
2531 }
2532 }
2533
2534 return true;
2535 }
2536
2537 /**
2538 * Free all cached contexts from the list.
2539 */
BKE_animsys_free_nla_keyframing_context_cache(struct ListBase * cache)2540 void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
2541 {
2542 LISTBASE_FOREACH (NlaKeyframingContext *, ctx, cache) {
2543 MEM_SAFE_FREE(ctx->eval_strip);
2544 nlaeval_free(&ctx->nla_channels);
2545 }
2546
2547 BLI_freelistN(cache);
2548 }
2549
2550 /* ***************************************** */
2551 /* Overrides System - Public API */
2552
2553 /* Evaluate Overrides */
animsys_evaluate_overrides(PointerRNA * ptr,AnimData * adt)2554 static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
2555 {
2556 AnimOverride *aor;
2557
2558 /* for each override, simply execute... */
2559 for (aor = adt->overrides.first; aor; aor = aor->next) {
2560 PathResolvedRNA anim_rna;
2561 if (BKE_animsys_store_rna_setting(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
2562 BKE_animsys_write_rna_setting(&anim_rna, aor->value);
2563 }
2564 }
2565 }
2566
2567 /* ***************************************** */
2568 /* Evaluation System - Public API */
2569
2570 /* Overview of how this system works:
2571 * 1) Depsgraph sorts data as necessary, so that data is in an order that means
2572 * that all dependencies are resolved before dependents.
2573 * 2) All normal animation is evaluated, so that drivers have some basis values to
2574 * work with
2575 * a. NLA stacks are done first, as the Active Actions act as 'tweaking' tracks
2576 * which modify the effects of the NLA-stacks
2577 * b. Active Action is evaluated as per normal, on top of the results of the NLA tracks
2578 *
2579 * --------------< often in a separate phase... >------------------
2580 *
2581 * 3) Drivers/expressions are evaluated on top of this, in an order where dependencies are
2582 * resolved nicely.
2583 * Note: it may be necessary to have some tools to handle the cases where some higher-level
2584 * drivers are added and cause some problematic dependencies that
2585 * didn't exist in the local levels...
2586 *
2587 * --------------< always executed >------------------
2588 *
2589 * Maintenance of editability of settings (XXX):
2590 * - In order to ensure that settings that are animated can still be manipulated in the UI without
2591 * requiring that keyframes are added to prevent these values from being overwritten,
2592 * we use 'overrides'.
2593 *
2594 * Unresolved things:
2595 * - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids
2596 * or nodal system? but stored where?
2597 * - Multiple-block dependencies
2598 * (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
2599 *
2600 * Current Status:
2601 * - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides.
2602 * However, the code for this is relatively harmless, so is left in the code for now.
2603 */
2604
2605 /* Evaluation loop for evaluation animation data
2606 *
2607 * This assumes that the animation-data provided belongs to the ID block in question,
2608 * and that the flags for which parts of the anim-data settings need to be recalculated
2609 * have been set already by the depsgraph. Now, we use the recalc
2610 */
BKE_animsys_evaluate_animdata(ID * id,AnimData * adt,const AnimationEvalContext * anim_eval_context,eAnimData_Recalc recalc,const bool flush_to_original)2611 void BKE_animsys_evaluate_animdata(ID *id,
2612 AnimData *adt,
2613 const AnimationEvalContext *anim_eval_context,
2614 eAnimData_Recalc recalc,
2615 const bool flush_to_original)
2616 {
2617 PointerRNA id_ptr;
2618
2619 /* sanity checks */
2620 if (ELEM(NULL, id, adt)) {
2621 return;
2622 }
2623
2624 /* get pointer to ID-block for RNA to use */
2625 RNA_id_pointer_create(id, &id_ptr);
2626
2627 /* recalculate keyframe data:
2628 * - NLA before Active Action, as Active Action behaves as 'tweaking track'
2629 * that overrides 'rough' work in NLA
2630 */
2631 /* TODO: need to double check that this all works correctly */
2632 if (recalc & ADT_RECALC_ANIM) {
2633 /* evaluate NLA data */
2634 if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF)) {
2635 /* evaluate NLA-stack
2636 * - active action is evaluated as part of the NLA stack as the last item
2637 */
2638 animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original);
2639 }
2640 /* evaluate Active Action only */
2641 else if (adt->action) {
2642 animsys_evaluate_action_ex(&id_ptr, adt->action, anim_eval_context, flush_to_original);
2643 }
2644 }
2645
2646 /* recalculate drivers
2647 * - Drivers need to be evaluated afterwards, as they can either override
2648 * or be layered on top of existing animation data.
2649 * - Drivers should be in the appropriate order to be evaluated without problems...
2650 */
2651 if (recalc & ADT_RECALC_DRIVERS) {
2652 animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context);
2653 }
2654
2655 /* always execute 'overrides'
2656 * - Overrides allow editing, by overwriting the value(s) set from animation-data, with the
2657 * value last set by the user (and not keyframed yet).
2658 * - Overrides are cleared upon frame change and/or keyframing
2659 * - It is best that we execute this every time, so that no errors are likely to occur.
2660 */
2661 animsys_evaluate_overrides(&id_ptr, adt);
2662 }
2663
2664 /* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only
2665 *
2666 * This will evaluate only the animation info available in the animation data-blocks
2667 * encountered. In order to enforce the system by which some settings controlled by a
2668 * 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a
2669 * standard 'root') block are overridden by a larger 'user'
2670 */
BKE_animsys_evaluate_all_animation(Main * main,Depsgraph * depsgraph,float ctime)2671 void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float ctime)
2672 {
2673 ID *id;
2674
2675 if (G.debug & G_DEBUG) {
2676 printf("Evaluate all animation - %f\n", ctime);
2677 }
2678
2679 const bool flush_to_original = DEG_is_active(depsgraph);
2680 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
2681 ctime);
2682
2683 /* macros for less typing
2684 * - only evaluate animation data for id if it has users (and not just fake ones)
2685 * - whether animdata exists is checked for by the evaluation function, though taking
2686 * this outside of the function may make things slightly faster?
2687 */
2688 #define EVAL_ANIM_IDS(first, aflag) \
2689 for (id = first; id; id = id->next) { \
2690 if (ID_REAL_USERS(id) > 0) { \
2691 AnimData *adt = BKE_animdata_from_id(id); \
2692 BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
2693 } \
2694 } \
2695 (void)0
2696
2697 /* another macro for the "embedded" nodetree cases
2698 * - this is like EVAL_ANIM_IDS, but this handles the case "embedded nodetrees"
2699 * (i.e. scene/material/texture->nodetree) which we need a special exception
2700 * for, otherwise they'd get skipped
2701 * - 'ntp' stands for "node tree parent" = data-block where node tree stuff resides
2702 */
2703 #define EVAL_ANIM_NODETREE_IDS(first, NtId_Type, aflag) \
2704 for (id = first; id; id = id->next) { \
2705 if (ID_REAL_USERS(id) > 0) { \
2706 AnimData *adt = BKE_animdata_from_id(id); \
2707 NtId_Type *ntp = (NtId_Type *)id; \
2708 if (ntp->nodetree) { \
2709 AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
2710 BKE_animsys_evaluate_animdata( \
2711 &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \
2712 } \
2713 BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
2714 } \
2715 } \
2716 (void)0
2717
2718 /* optimization:
2719 * when there are no actions, don't go over database and loop over heaps of data-blocks,
2720 * which should ultimately be empty, since it is not possible for now to have any animation
2721 * without some actions, and drivers wouldn't get affected by any state changes
2722 *
2723 * however, if there are some curves, we will need to make sure that their 'ctime' property gets
2724 * set correctly, so this optimization must be skipped in that case...
2725 */
2726 if (BLI_listbase_is_empty(&main->actions) && BLI_listbase_is_empty(&main->curves)) {
2727 if (G.debug & G_DEBUG) {
2728 printf("\tNo Actions, so no animation needs to be evaluated...\n");
2729 }
2730
2731 return;
2732 }
2733
2734 /* nodes */
2735 EVAL_ANIM_IDS(main->nodetrees.first, ADT_RECALC_ANIM);
2736
2737 /* textures */
2738 EVAL_ANIM_NODETREE_IDS(main->textures.first, Tex, ADT_RECALC_ANIM);
2739
2740 /* lights */
2741 EVAL_ANIM_NODETREE_IDS(main->lights.first, Light, ADT_RECALC_ANIM);
2742
2743 /* materials */
2744 EVAL_ANIM_NODETREE_IDS(main->materials.first, Material, ADT_RECALC_ANIM);
2745
2746 /* cameras */
2747 EVAL_ANIM_IDS(main->cameras.first, ADT_RECALC_ANIM);
2748
2749 /* shapekeys */
2750 EVAL_ANIM_IDS(main->shapekeys.first, ADT_RECALC_ANIM);
2751
2752 /* metaballs */
2753 EVAL_ANIM_IDS(main->metaballs.first, ADT_RECALC_ANIM);
2754
2755 /* curves */
2756 EVAL_ANIM_IDS(main->curves.first, ADT_RECALC_ANIM);
2757
2758 /* armatures */
2759 EVAL_ANIM_IDS(main->armatures.first, ADT_RECALC_ANIM);
2760
2761 /* lattices */
2762 EVAL_ANIM_IDS(main->lattices.first, ADT_RECALC_ANIM);
2763
2764 /* meshes */
2765 EVAL_ANIM_IDS(main->meshes.first, ADT_RECALC_ANIM);
2766
2767 /* particles */
2768 EVAL_ANIM_IDS(main->particles.first, ADT_RECALC_ANIM);
2769
2770 /* speakers */
2771 EVAL_ANIM_IDS(main->speakers.first, ADT_RECALC_ANIM);
2772
2773 /* movie clips */
2774 EVAL_ANIM_IDS(main->movieclips.first, ADT_RECALC_ANIM);
2775
2776 /* linestyles */
2777 EVAL_ANIM_IDS(main->linestyles.first, ADT_RECALC_ANIM);
2778
2779 /* grease pencil */
2780 EVAL_ANIM_IDS(main->gpencils.first, ADT_RECALC_ANIM);
2781
2782 /* palettes */
2783 EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
2784
2785 /* cache files */
2786 EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
2787
2788 /* hairs */
2789 EVAL_ANIM_IDS(main->hairs.first, ADT_RECALC_ANIM);
2790
2791 /* pointclouds */
2792 EVAL_ANIM_IDS(main->pointclouds.first, ADT_RECALC_ANIM);
2793
2794 /* volumes */
2795 EVAL_ANIM_IDS(main->volumes.first, ADT_RECALC_ANIM);
2796
2797 /* simulations */
2798 EVAL_ANIM_IDS(main->simulations.first, ADT_RECALC_ANIM);
2799
2800 /* objects */
2801 /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
2802 * this tagged by Depsgraph on framechange. This optimization means that objects
2803 * linked from other (not-visible) scenes will not need their data calculated.
2804 */
2805 EVAL_ANIM_IDS(main->objects.first, 0);
2806
2807 /* masks */
2808 EVAL_ANIM_IDS(main->masks.first, ADT_RECALC_ANIM);
2809
2810 /* worlds */
2811 EVAL_ANIM_NODETREE_IDS(main->worlds.first, World, ADT_RECALC_ANIM);
2812
2813 /* scenes */
2814 EVAL_ANIM_NODETREE_IDS(main->scenes.first, Scene, ADT_RECALC_ANIM);
2815 }
2816
2817 /* ***************************************** */
2818
2819 /* ************** */
2820 /* Evaluation API */
2821
BKE_animsys_eval_animdata(Depsgraph * depsgraph,ID * id)2822 void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
2823 {
2824 float ctime = DEG_get_ctime(depsgraph);
2825 AnimData *adt = BKE_animdata_from_id(id);
2826 /* XXX: this is only needed for flushing RNA updates,
2827 * which should get handled as part of the dependency graph instead. */
2828 DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
2829 const bool flush_to_original = DEG_is_active(depsgraph);
2830
2831 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
2832 ctime);
2833 BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
2834 }
2835
BKE_animsys_update_driver_array(ID * id)2836 void BKE_animsys_update_driver_array(ID *id)
2837 {
2838 AnimData *adt = BKE_animdata_from_id(id);
2839
2840 /* Runtime driver map to avoid O(n^2) lookups in BKE_animsys_eval_driver.
2841 * Ideally the depsgraph could pass a pointer to the COW driver directly,
2842 * but this is difficult in the current design. */
2843 if (adt && adt->drivers.first) {
2844 BLI_assert(!adt->driver_array);
2845
2846 int num_drivers = BLI_listbase_count(&adt->drivers);
2847 adt->driver_array = MEM_mallocN(sizeof(FCurve *) * num_drivers, "adt->driver_array");
2848
2849 int driver_index = 0;
2850 LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
2851 adt->driver_array[driver_index++] = fcu;
2852 }
2853 }
2854 }
2855
BKE_animsys_eval_driver(Depsgraph * depsgraph,ID * id,int driver_index,FCurve * fcu_orig)2856 void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCurve *fcu_orig)
2857 {
2858 BLI_assert(fcu_orig != NULL);
2859
2860 /* TODO(sergey): De-duplicate with BKE animsys. */
2861 PointerRNA id_ptr;
2862 bool ok = false;
2863
2864 /* Lookup driver, accelerated with driver array map. */
2865 const AnimData *adt = BKE_animdata_from_id(id);
2866 FCurve *fcu;
2867
2868 if (adt->driver_array) {
2869 fcu = adt->driver_array[driver_index];
2870 }
2871 else {
2872 fcu = BLI_findlink(&adt->drivers, driver_index);
2873 }
2874
2875 DEG_debug_print_eval_subdata_index(
2876 depsgraph, __func__, id->name, id, "fcu", fcu->rna_path, fcu, fcu->array_index);
2877
2878 RNA_id_pointer_create(id, &id_ptr);
2879
2880 /* check if this driver's curve should be skipped */
2881 if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
2882 /* check if driver itself is tagged for recalculation */
2883 /* XXX driver recalc flag is not set yet by depsgraph! */
2884 ChannelDriver *driver_orig = fcu_orig->driver;
2885 if ((driver_orig) && !(driver_orig->flag & DRIVER_FLAG_INVALID)) {
2886 /* evaluate this using values set already in other places
2887 * NOTE: for 'layering' option later on, we should check if we should remove old value before
2888 * adding new to only be done when drivers only changed */
2889 // printf("\told val = %f\n", fcu->curval);
2890
2891 PathResolvedRNA anim_rna;
2892 if (BKE_animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
2893 /* Evaluate driver, and write results to COW-domain destination */
2894 const float ctime = DEG_get_ctime(depsgraph);
2895 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
2896 depsgraph, ctime);
2897 const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context);
2898 ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
2899
2900 /* Flush results & status codes to original data for UI (T59984) */
2901 if (ok && DEG_is_active(depsgraph)) {
2902 animsys_write_orig_anim_rna(&id_ptr, fcu->rna_path, fcu->array_index, curval);
2903
2904 /* curval is displayed in the UI, and flag contains error-status codes */
2905 fcu_orig->curval = fcu->curval;
2906 driver_orig->curval = fcu->driver->curval;
2907 driver_orig->flag = fcu->driver->flag;
2908
2909 DriverVar *dvar_orig = driver_orig->variables.first;
2910 DriverVar *dvar = fcu->driver->variables.first;
2911 for (; dvar_orig && dvar; dvar_orig = dvar_orig->next, dvar = dvar->next) {
2912 DriverTarget *dtar_orig = &dvar_orig->targets[0];
2913 DriverTarget *dtar = &dvar->targets[0];
2914 for (int i = 0; i < MAX_DRIVER_TARGETS; i++, dtar_orig++, dtar++) {
2915 dtar_orig->flag = dtar->flag;
2916 }
2917
2918 dvar_orig->curval = dvar->curval;
2919 dvar_orig->flag = dvar->flag;
2920 }
2921 }
2922 }
2923
2924 /* set error-flag if evaluation failed */
2925 if (ok == 0) {
2926 CLOG_WARN(&LOG, "invalid driver - %s[%d]", fcu->rna_path, fcu->array_index);
2927 driver_orig->flag |= DRIVER_FLAG_INVALID;
2928 }
2929 }
2930 }
2931 }
2932