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