Blender  V3.3
anim_sys.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation, Joshua Leung. All rights reserved. */
3 
8 #include <float.h>
9 #include <math.h>
10 #include <stddef.h>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "BLI_alloca.h"
17 #include "BLI_blenlib.h"
18 #include "BLI_dynstr.h"
19 #include "BLI_listbase.h"
20 #include "BLI_math_rotation.h"
21 #include "BLI_math_vector.h"
22 #include "BLI_string_utils.h"
23 #include "BLI_utildefines.h"
24 
25 #include "BLT_translation.h"
26 
27 #include "DNA_anim_types.h"
28 #include "DNA_light_types.h"
29 #include "DNA_material_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_texture_types.h"
35 #include "DNA_world_types.h"
36 
37 #include "BKE_action.h"
38 #include "BKE_anim_data.h"
39 #include "BKE_animsys.h"
40 #include "BKE_context.h"
41 #include "BKE_fcurve.h"
42 #include "BKE_global.h"
43 #include "BKE_lib_id.h"
44 #include "BKE_lib_query.h"
45 #include "BKE_main.h"
46 #include "BKE_material.h"
47 #include "BKE_nla.h"
48 #include "BKE_node.h"
49 #include "BKE_report.h"
50 #include "BKE_texture.h"
51 
52 #include "DEG_depsgraph.h"
53 #include "DEG_depsgraph_query.h"
54 
55 #include "RNA_access.h"
56 #include "RNA_path.h"
57 #include "RNA_prototypes.h"
58 
59 #include "BLO_read_write.h"
60 
61 #include "nla_private.h"
62 
63 #include "atomic_ops.h"
64 
65 #include "CLG_log.h"
66 
67 static CLG_LogRef LOG = {"bke.anim_sys"};
68 
69 /* *********************************** */
70 /* KeyingSet API */
71 
72 /* Finding Tools --------------------------- */
73 
75  ID *id,
76  const char group_name[],
77  const char rna_path[],
78  int array_index,
79  int UNUSED(group_mode))
80 {
81  KS_Path *ksp;
82 
83  /* sanity checks */
84  if (ELEM(NULL, ks, rna_path, id)) {
85  return NULL;
86  }
87 
88  /* loop over paths in the current KeyingSet, finding the first one where all settings match
89  * (i.e. the first one where none of the checks fail and equal 0)
90  */
91  for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
92  short eq_id = 1, eq_path = 1, eq_index = 1, eq_group = 1;
93 
94  /* id */
95  if (id != ksp->id) {
96  eq_id = 0;
97  }
98 
99  /* path */
100  if ((ksp->rna_path == NULL) || !STREQ(rna_path, ksp->rna_path)) {
101  eq_path = 0;
102  }
103 
104  /* index - need to compare whole-array setting too... */
105  if (ksp->array_index != array_index) {
106  eq_index = 0;
107  }
108 
109  /* group */
110  if (group_name) {
111  /* FIXME: these checks need to be coded... for now, it's not too important though */
112  }
113 
114  /* if all aspects are ok, return */
115  if (eq_id && eq_path && eq_index && eq_group) {
116  return ksp;
117  }
118  }
119 
120  /* none found */
121  return NULL;
122 }
123 
124 /* Defining Tools --------------------------- */
125 
127  ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
128 {
129  KeyingSet *ks;
130 
131  /* allocate new KeyingSet */
132  ks = MEM_callocN(sizeof(KeyingSet), "KeyingSet");
133 
134  BLI_strncpy(ks->idname,
135  (idname) ? idname :
136  (name) ? name :
137  DATA_("KeyingSet"),
138  sizeof(ks->idname));
139  BLI_strncpy(ks->name, (name) ? name : (idname) ? idname : DATA_("Keying Set"), sizeof(ks->name));
140 
141  ks->flag = flag;
142  ks->keyingflag = keyingflag;
143  /* NOTE: assume that if one is set one way, the other should be too, so that it'll work */
144  ks->keyingoverride = keyingflag;
145 
146  /* add KeyingSet to list */
147  BLI_addtail(list, ks);
148 
149  /* Make sure KeyingSet has a unique idname */
151  list, ks, DATA_("KeyingSet"), '.', offsetof(KeyingSet, idname), sizeof(ks->idname));
152 
153  /* Make sure KeyingSet has a unique label (this helps with identification) */
154  BLI_uniquename(list, ks, DATA_("Keying Set"), '.', offsetof(KeyingSet, name), sizeof(ks->name));
155 
156  /* return new KeyingSet for further editing */
157  return ks;
158 }
159 
161  ID *id,
162  const char group_name[],
163  const char rna_path[],
164  int array_index,
165  short flag,
166  short groupmode)
167 {
168  KS_Path *ksp;
169 
170  /* sanity checks */
171  if (ELEM(NULL, ks, rna_path)) {
172  CLOG_ERROR(&LOG, "no Keying Set and/or RNA Path to add path with");
173  return NULL;
174  }
175 
176  /* ID is required for all types of KeyingSets */
177  if (id == NULL) {
178  CLOG_ERROR(&LOG, "No ID provided for Keying Set Path");
179  return NULL;
180  }
181 
182  /* don't add if there is already a matching KS_Path in the KeyingSet */
183  if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
184  if (G.debug & G_DEBUG) {
185  CLOG_ERROR(&LOG, "destination already exists in Keying Set");
186  }
187  return NULL;
188  }
189 
190  /* allocate a new KeyingSet Path */
191  ksp = MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
192 
193  /* just store absolute info */
194  ksp->id = id;
195  if (group_name) {
196  BLI_strncpy(ksp->group, group_name, sizeof(ksp->group));
197  }
198  else {
199  ksp->group[0] = '\0';
200  }
201 
202  /* store additional info for relative paths (just in case user makes the set relative) */
203  if (id) {
204  ksp->idtype = GS(id->name);
205  }
206 
207  /* just copy path info */
208  /* TODO: should array index be checked too? */
209  ksp->rna_path = BLI_strdup(rna_path);
210  ksp->array_index = array_index;
211 
212  /* store flags */
213  ksp->flag = flag;
214  ksp->groupmode = groupmode;
215 
216  /* add KeyingSet path to KeyingSet */
217  BLI_addtail(&ks->paths, ksp);
218 
219  /* return this path */
220  return ksp;
221 }
222 
224 {
225  /* sanity check */
226  if (ELEM(NULL, ks, ksp)) {
227  return;
228  }
229 
230  /* free RNA-path info */
231  if (ksp->rna_path) {
232  MEM_freeN(ksp->rna_path);
233  }
234 
235  /* free path itself */
236  BLI_freelinkN(&ks->paths, ksp);
237 }
238 
239 void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
240 {
241  KeyingSet *ksn;
242  KS_Path *kspn;
243 
244  BLI_duplicatelist(newlist, list);
245 
246  for (ksn = newlist->first; ksn; ksn = ksn->next) {
247  BLI_duplicatelist(&ksn->paths, &ksn->paths);
248 
249  for (kspn = ksn->paths.first; kspn; kspn = kspn->next) {
250  kspn->rna_path = MEM_dupallocN(kspn->rna_path);
251  }
252  }
253 }
254 
256 {
257  for (KeyingSet *ksn = keyingsets->first; ksn; ksn = ksn->next) {
258  for (KS_Path *kspn = ksn->paths.first; kspn; kspn = kspn->next) {
260  }
261  }
262 }
263 
264 /* Freeing Tools --------------------------- */
265 
267 {
268  KS_Path *ksp, *kspn;
269 
270  /* sanity check */
271  if (ks == NULL) {
272  return;
273  }
274 
275  /* free each path as we go to avoid looping twice */
276  for (ksp = ks->paths.first; ksp; ksp = kspn) {
277  kspn = ksp->next;
278  BKE_keyingset_free_path(ks, ksp);
279  }
280 }
281 
283 {
284  KeyingSet *ks, *ksn;
285 
286  /* sanity check */
287  if (list == NULL) {
288  return;
289  }
290 
291  /* loop over KeyingSets freeing them
292  * - BKE_keyingset_free() doesn't free the set itself, but it frees its sub-data
293  */
294  for (ks = list->first; ks; ks = ksn) {
295  ksn = ks->next;
296  BKE_keyingset_free(ks);
297  BLI_freelinkN(list, ks);
298  }
299 }
300 
302 {
303  LISTBASE_FOREACH (KeyingSet *, ks, list) {
304  /* KeyingSet */
305  BLO_write_struct(writer, KeyingSet, ks);
306 
307  /* Paths */
308  LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
309  /* Path */
310  BLO_write_struct(writer, KS_Path, ksp);
311 
312  if (ksp->rna_path) {
313  BLO_write_string(writer, ksp->rna_path);
314  }
315  }
316  }
317 }
318 
320 {
321  LISTBASE_FOREACH (KeyingSet *, ks, list) {
322  /* paths */
323  BLO_read_list(reader, &ks->paths);
324 
325  LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
326  /* rna path */
327  BLO_read_data_address(reader, &ksp->rna_path);
328  }
329  }
330 }
331 
333 {
334  LISTBASE_FOREACH (KeyingSet *, ks, list) {
335  LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
336  BLO_read_id_address(reader, id->lib, &ksp->id);
337  }
338  }
339 }
340 
342 {
343  LISTBASE_FOREACH (KeyingSet *, ks, list) {
344  LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
345  BLO_expand(expander, ksp->id);
346  }
347  }
348 }
349 
350 /* ***************************************** */
351 /* Evaluation Data-Setting Backend */
352 
353 static bool is_fcurve_evaluatable(FCurve *fcu)
354 {
355  if (fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) {
356  return false;
357  }
358  if (fcu->grp != NULL && (fcu->grp->flag & AGRP_MUTED)) {
359  return false;
360  }
361  if (BKE_fcurve_is_empty(fcu)) {
362  return false;
363  }
364  return true;
365 }
366 
368  /* typically 'fcu->rna_path', 'fcu->array_index' */
369  const char *rna_path,
370  const int array_index,
371  PathResolvedRNA *r_result)
372 {
373  if (rna_path == NULL) {
374  return false;
375  }
376 
377  const char *path = rna_path;
378  if (!RNA_path_resolve_property(ptr, path, &r_result->ptr, &r_result->prop)) {
379  /* failed to get path */
380  /* XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
381  * where some channels will not exist, but shouldn't lock up Action */
382  if (G.debug & G_DEBUG) {
383  CLOG_WARN(&LOG,
384  "Animato: Invalid path. ID = '%s', '%s[%d]'",
385  (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
386  path,
387  array_index);
388  }
389  return false;
390  }
391 
392  if (ptr->owner_id != NULL && !RNA_property_animateable(&r_result->ptr, r_result->prop)) {
393  return false;
394  }
395 
396  int array_len = RNA_property_array_length(&r_result->ptr, r_result->prop);
397  if (array_len && array_index >= array_len) {
398  if (G.debug & G_DEBUG) {
399  CLOG_WARN(&LOG,
400  "Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d",
401  (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
402  path,
403  array_index,
404  array_len - 1);
405  }
406  return false;
407  }
408 
409  r_result->prop_index = array_len ? array_index : -1;
410  return true;
411 }
412 
413 /* less than 1.0 evaluates to false, use epsilon to avoid float error */
414 #define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > (1.0f - FLT_EPSILON))
415 
416 bool BKE_animsys_read_from_rna_path(PathResolvedRNA *anim_rna, float *r_value)
417 {
418  PropertyRNA *prop = anim_rna->prop;
419  PointerRNA *ptr = &anim_rna->ptr;
420  int array_index = anim_rna->prop_index;
421  float orig_value;
422 
423  /* caller must ensure this is animatable */
425 
426  switch (RNA_property_type(prop)) {
427  case PROP_BOOLEAN: {
428  if (array_index != -1) {
429  const int orig_value_coerce = RNA_property_boolean_get_index(ptr, prop, array_index);
430  orig_value = (float)orig_value_coerce;
431  }
432  else {
433  const int orig_value_coerce = RNA_property_boolean_get(ptr, prop);
434  orig_value = (float)orig_value_coerce;
435  }
436  break;
437  }
438  case PROP_INT: {
439  if (array_index != -1) {
440  const int orig_value_coerce = RNA_property_int_get_index(ptr, prop, array_index);
441  orig_value = (float)orig_value_coerce;
442  }
443  else {
444  const int orig_value_coerce = RNA_property_int_get(ptr, prop);
445  orig_value = (float)orig_value_coerce;
446  }
447  break;
448  }
449  case PROP_FLOAT: {
450  if (array_index != -1) {
451  const float orig_value_coerce = RNA_property_float_get_index(ptr, prop, array_index);
452  orig_value = (float)orig_value_coerce;
453  }
454  else {
455  const float orig_value_coerce = RNA_property_float_get(ptr, prop);
456  orig_value = (float)orig_value_coerce;
457  }
458  break;
459  }
460  case PROP_ENUM: {
461  const int orig_value_coerce = RNA_property_enum_get(ptr, prop);
462  orig_value = (float)orig_value_coerce;
463  break;
464  }
465  default:
466  /* nothing can be done here... so it is unsuccessful? */
467  return false;
468  }
469 
470  if (r_value != NULL) {
471  *r_value = orig_value;
472  }
473 
474  /* successful */
475  return true;
476 }
477 
478 bool BKE_animsys_write_to_rna_path(PathResolvedRNA *anim_rna, const float value)
479 {
480  PropertyRNA *prop = anim_rna->prop;
481  PointerRNA *ptr = &anim_rna->ptr;
482  int array_index = anim_rna->prop_index;
483 
484  /* caller must ensure this is animatable */
486 
487  /* Check whether value is new. Otherwise we skip all the updates. */
488  float old_value;
489  if (!BKE_animsys_read_from_rna_path(anim_rna, &old_value)) {
490  return false;
491  }
492  if (old_value == value) {
493  return true;
494  }
495 
496  switch (RNA_property_type(prop)) {
497  case PROP_BOOLEAN: {
498  const int value_coerce = ANIMSYS_FLOAT_AS_BOOL(value);
499  if (array_index != -1) {
500  RNA_property_boolean_set_index(ptr, prop, array_index, value_coerce);
501  }
502  else {
503  RNA_property_boolean_set(ptr, prop, value_coerce);
504  }
505  break;
506  }
507  case PROP_INT: {
508  int value_coerce = (int)value;
509  RNA_property_int_clamp(ptr, prop, &value_coerce);
510  if (array_index != -1) {
511  RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
512  }
513  else {
514  RNA_property_int_set(ptr, prop, value_coerce);
515  }
516  break;
517  }
518  case PROP_FLOAT: {
519  float value_coerce = value;
520  RNA_property_float_clamp(ptr, prop, &value_coerce);
521  if (array_index != -1) {
522  RNA_property_float_set_index(ptr, prop, array_index, value_coerce);
523  }
524  else {
525  RNA_property_float_set(ptr, prop, value_coerce);
526  }
527  break;
528  }
529  case PROP_ENUM: {
530  const int value_coerce = (int)value;
531  RNA_property_enum_set(ptr, prop, value_coerce);
532  break;
533  }
534  default:
535  /* nothing can be done here... so it is unsuccessful? */
536  return false;
537  }
538 
539  /* successful */
540  return true;
541 }
542 
544 {
545  *ptr_orig = *ptr;
546  /* NOTE: nlastrip_evaluate_controls() creates PointerRNA with ID of NULL. Technically, this is
547  * not a valid pointer, but there are exceptions in various places of this file which handles
548  * such pointers.
549  * We do special trickery here as well, to quickly go from evaluated to original NlaStrip. */
550  if (ptr->owner_id == NULL) {
551  if (ptr->type != &RNA_NlaStrip) {
552  return false;
553  }
554  NlaStrip *strip = ((NlaStrip *)ptr_orig->data);
555  if (strip->orig_strip == NULL) {
556  return false;
557  }
558  ptr_orig->data = strip->orig_strip;
559  }
560  else {
561  ptr_orig->owner_id = ptr_orig->owner_id->orig_id;
562  ptr_orig->data = ptr_orig->owner_id;
563  }
564  return true;
565 }
566 
568  const char *rna_path,
569  int array_index,
570  float value)
571 {
572  PointerRNA ptr_orig;
573  if (!animsys_construct_orig_pointer_rna(ptr, &ptr_orig)) {
574  return;
575  }
576  PathResolvedRNA orig_anim_rna;
577  /* TODO(sergey): Should be possible to cache resolved path in dependency graph somehow. */
578  if (BKE_animsys_rna_path_resolve(&ptr_orig, rna_path, array_index, &orig_anim_rna)) {
579  BKE_animsys_write_to_rna_path(&orig_anim_rna, value);
580  }
581 }
582 
589  ListBase *list,
590  const AnimationEvalContext *anim_eval_context,
591  bool flush_to_original)
592 {
593  /* Calculate then execute each curve. */
594  LISTBASE_FOREACH (FCurve *, fcu, list) {
595 
596  if (!is_fcurve_evaluatable(fcu)) {
597  continue;
598  }
599 
600  PathResolvedRNA anim_rna;
601  if (BKE_animsys_rna_path_resolve(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
602  const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
603  BKE_animsys_write_to_rna_path(&anim_rna, curval);
604  if (flush_to_original) {
605  animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
606  }
607  }
608  }
609 }
610 
620  FCurve *first_fcurve,
621  const AnimationEvalContext *anim_eval_context,
622  float r_quaternion[4])
623 {
624  FCurve *quat_curve_fcu = first_fcurve;
625 
626  /* Initialize r_quaternion to the unit quaternion so that half-keyed quaternions at least have
627  * *some* value in there. */
628  r_quaternion[0] = 1.0f;
629  r_quaternion[1] = 0.0f;
630  r_quaternion[2] = 0.0f;
631  r_quaternion[3] = 0.0f;
632 
633  int fcurve_offset = 0;
634  for (; fcurve_offset < 4 && quat_curve_fcu;
635  ++fcurve_offset, quat_curve_fcu = quat_curve_fcu->next) {
636  if (!STREQ(quat_curve_fcu->rna_path, first_fcurve->rna_path)) {
637  /* This should never happen when the quaternion is fully keyed. Some
638  * people do use half-keyed quaternions, though, so better to check. */
639  break;
640  }
641 
642  const int array_index = quat_curve_fcu->array_index;
643  quat_rna.prop_index = array_index;
644  r_quaternion[array_index] = calculate_fcurve(&quat_rna, quat_curve_fcu, anim_eval_context);
645  }
646 
647  if (fcurve_offset < 4) {
648  /* This quaternion was incompletely keyed, so the result is a mixture of the unit quaterion and
649  * values from FCurves. This means that it's almost certainly no longer of unit length. */
650  normalize_qt(r_quaternion);
651  }
652 
653  return fcurve_offset;
654 }
655 
664  FCurve *first_fcurve,
665  const AnimationEvalContext *anim_eval_context,
666  const float blend_factor)
667 {
668  float current_quat[4];
669  RNA_property_float_get_array(&anim_rna->ptr, anim_rna->prop, current_quat);
670 
671  float target_quat[4];
672  const int num_fcurves_read = animsys_quaternion_evaluate_fcurves(
673  *anim_rna, first_fcurve, anim_eval_context, target_quat);
674 
675  float blended_quat[4];
676  interp_qt_qtqt(blended_quat, current_quat, target_quat, blend_factor);
677 
678  RNA_property_float_set_array(&anim_rna->ptr, anim_rna->prop, blended_quat);
679 
680  return num_fcurves_read;
681 }
682 
683 /* LERP between current value (blend_factor=0.0) and the value from the FCurve (blend_factor=1.0)
684  */
686  ListBase *fcurves,
687  const AnimationEvalContext *anim_eval_context,
688  const float blend_factor)
689 {
690  char *channel_to_skip = NULL;
691  int num_channels_to_skip = 0;
692  LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
693 
694  if (num_channels_to_skip) {
695  /* For skipping already-handled rotation channels. Rotation channels are handled per group,
696  * and not per individual channel. */
697  BLI_assert(channel_to_skip != NULL);
698  if (STREQ(channel_to_skip, fcu->rna_path)) {
699  /* This is indeed the channel we want to skip. */
700  num_channels_to_skip--;
701  continue;
702  }
703  }
704 
705  if (!is_fcurve_evaluatable(fcu)) {
706  continue;
707  }
708 
709  PathResolvedRNA anim_rna;
710  if (!BKE_animsys_rna_path_resolve(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
711  continue;
712  }
713 
714  if (STREQ(RNA_property_identifier(anim_rna.prop), "rotation_quaternion")) {
715  const int num_fcurves_read = animsys_blend_fcurves_quaternion(
716  &anim_rna, fcu, anim_eval_context, blend_factor);
717 
718  /* Skip the next three channels, because those have already been handled here. */
719  MEM_SAFE_FREE(channel_to_skip);
720  channel_to_skip = BLI_strdup(fcu->rna_path);
721  num_channels_to_skip = num_fcurves_read - 1;
722  continue;
723  }
724  /* TODO(Sybren): do something similar as above for Euler and Axis/Angle representations. */
725 
726  const float fcurve_value = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
727 
728  float current_value;
729  float value_to_write;
730  if (BKE_animsys_read_from_rna_path(&anim_rna, &current_value)) {
731  value_to_write = (1 - blend_factor) * current_value + blend_factor * fcurve_value;
732 
733  switch (RNA_property_type(anim_rna.prop)) {
734  case PROP_BOOLEAN:
735  /* Without this, anything less than 1.0 is converted to 'False' by
736  * ANIMSYS_FLOAT_AS_BOOL(). This is probably not desirable for blends, where anything
737  * above a 50% blend should act more like the FCurve than like the current value. */
738  case PROP_INT:
739  case PROP_ENUM:
740  value_to_write = roundf(value_to_write);
741  break;
742  default:
743  /* All other types are just handled as float, and value_to_write is already correct. */
744  break;
745  }
746  }
747  else {
748  /* Unable to read the current value for blending, so just apply the FCurve value instead. */
749  value_to_write = fcurve_value;
750  }
751 
752  BKE_animsys_write_to_rna_path(&anim_rna, value_to_write);
753  }
754 
755  MEM_SAFE_FREE(channel_to_skip);
756 }
757 
758 /* ***************************************** */
759 /* Driver Evaluation */
760 
762  float eval_time)
763 {
764  AnimationEvalContext ctx = {
765  .depsgraph = depsgraph,
766  .eval_time = eval_time,
767  };
768  return ctx;
769 }
770 
772  const AnimationEvalContext *anim_eval_context, float eval_time)
773 {
774  return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time);
775 }
776 
777 /* Evaluate Drivers */
779  AnimData *adt,
780  const AnimationEvalContext *anim_eval_context)
781 {
782  FCurve *fcu;
783 
784  /* drivers are stored as F-Curves, but we cannot use the standard code, as we need to check if
785  * the depsgraph requested that this driver be evaluated...
786  */
787  for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
788  ChannelDriver *driver = fcu->driver;
789  bool ok = false;
790 
791  /* check if this driver's curve should be skipped */
792  if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
793  /* check if driver itself is tagged for recalculation */
794  /* XXX driver recalc flag is not set yet by depsgraph! */
795  if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID)) {
796  /* evaluate this using values set already in other places
797  * NOTE: for 'layering' option later on, we should check if we should remove old value
798  * before adding new to only be done when drivers only changed. */
799  PathResolvedRNA anim_rna;
800  if (BKE_animsys_rna_path_resolve(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
801  const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
802  ok = BKE_animsys_write_to_rna_path(&anim_rna, curval);
803  }
804 
805  /* set error-flag if evaluation failed */
806  if (ok == 0) {
807  driver->flag |= DRIVER_FLAG_INVALID;
808  }
809  }
810  }
811  }
812 }
813 
814 /* ***************************************** */
815 /* Actions Evaluation */
816 
817 /* strictly not necessary for actual "evaluation", but it is a useful safety check
818  * to reduce the amount of times that users end up having to "revive" wrongly-assigned
819  * actions
820  */
821 static void action_idcode_patch_check(ID *id, bAction *act)
822 {
823  int idcode = 0;
824 
825  /* just in case */
826  if (ELEM(NULL, id, act)) {
827  return;
828  }
829 
830  idcode = GS(id->name);
831 
832  /* the actual checks... hopefully not too much of a performance hit in the long run... */
833  if (act->idroot == 0) {
834  /* use the current root if not set already
835  * (i.e. newly created actions and actions from 2.50-2.57 builds).
836  * - this has problems if there are 2 users, and the first one encountered is the invalid one
837  * in which case, the user will need to manually fix this (?)
838  */
839  act->idroot = idcode;
840  }
841  else if (act->idroot != idcode) {
842  /* only report this error if debug mode is enabled (to save performance everywhere else) */
843  if (G.debug & G_DEBUG) {
844  printf(
845  "AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of "
846  "type %d such as '%s'\n",
847  act->id.name + 2,
848  idcode,
849  id->name);
850  }
851  }
852 }
853 
854 /* ----------------------------------------- */
855 
857  bAction *act,
858  bActionGroup *agrp,
859  const AnimationEvalContext *anim_eval_context)
860 {
861  FCurve *fcu;
862 
863  /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
864  if (ELEM(NULL, act, agrp)) {
865  return;
866  }
867 
869 
870  /* if group is muted, don't evaluated any of the F-Curve */
871  if (agrp->flag & AGRP_MUTED) {
872  return;
873  }
874 
875  /* calculate then execute each curve */
876  for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcu->next) {
877  /* check if this curve should be skipped */
878  if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) {
879  PathResolvedRNA anim_rna;
880  if (BKE_animsys_rna_path_resolve(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
881  const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
882  BKE_animsys_write_to_rna_path(&anim_rna, curval);
883  }
884  }
885  }
886 }
887 
889  bAction *act,
890  const AnimationEvalContext *anim_eval_context,
891  const bool flush_to_original)
892 {
893  /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
894  if (act == NULL) {
895  return;
896  }
897 
899 
900  /* calculate then execute each curve */
901  animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
902 }
903 
905  bAction *act,
906  const AnimationEvalContext *anim_eval_context,
907  const float blend_factor)
908 {
910  animsys_blend_in_fcurves(ptr, &act->curves, anim_eval_context, blend_factor);
911 }
912 
913 /* ***************************************** */
914 /* NLA System - Evaluation */
915 
916 /* calculate influence of strip based for given frame based on blendin/out values */
917 static float nlastrip_get_influence(NlaStrip *strip, float cframe)
918 {
919  /* sanity checks - normalize the blendin/out values? */
920  strip->blendin = fabsf(strip->blendin);
921  strip->blendout = fabsf(strip->blendout);
922 
923  /* result depends on where frame is in respect to blendin/out values */
924  if (IS_EQF(strip->blendin, 0.0f) == false && (cframe <= (strip->start + strip->blendin))) {
925  /* there is some blend-in */
926  return fabsf(cframe - strip->start) / (strip->blendin);
927  }
928  if (IS_EQF(strip->blendout, 0.0f) == false && (cframe >= (strip->end - strip->blendout))) {
929  /* there is some blend-out */
930  return fabsf(strip->end - cframe) / (strip->blendout);
931  }
932 
933  /* in the middle of the strip, we should be full strength */
934  return 1.0f;
935 }
936 
937 /* evaluate the evaluation time and influence for the strip, storing the results in the strip */
939  const AnimationEvalContext *anim_eval_context,
940  const bool flush_to_original)
941 {
942  /* now strip's evaluate F-Curves for these settings (if applicable) */
943  if (strip->fcurves.first) {
944  PointerRNA strip_ptr;
945 
946  /* create RNA-pointer needed to set values */
947  RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
948 
949  /* execute these settings as per normal */
950  animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original);
951  }
952 
953  /* analytically generate values for influence and time (if applicable)
954  * - we do this after the F-Curves have been evaluated to override the effects of those
955  * in case the override has been turned off.
956  */
957  if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
958  strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time);
959  }
960 
961  /* Bypass evaluation time computation if time mapping is disabled. */
962  if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
963  strip->strip_time = anim_eval_context->eval_time;
964  return;
965  }
966 
967  if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
969  strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL);
970  }
971 
972  /* if user can control the evaluation time (using F-Curves), consider the option which allows
973  * this time to be clamped to lie within extents of the action-clip, so that a steady changing
974  * rate of progress through several cycles of the clip can be achieved easily.
975  */
976  /* NOTE: if we add any more of these special cases, we better group them up nicely... */
977  if ((strip->flag & NLASTRIP_FLAG_USR_TIME) && (strip->flag & NLASTRIP_FLAG_USR_TIME_CYCLIC)) {
978  strip->strip_time = fmod(strip->strip_time - strip->actstart, strip->actend - strip->actstart);
979  }
980 }
981 
983  ListBase *strips,
984  short index,
985  const AnimationEvalContext *anim_eval_context,
986  const bool flush_to_original)
987 {
988  NlaStrip *strip, *estrip = NULL;
989  NlaEvalStrip *nes;
990  short side = 0;
991  float ctime = anim_eval_context->eval_time;
992 
993  /* loop over strips, checking if they fall within the range */
994  for (strip = strips->first; strip; strip = strip->next) {
995  /* Check if current time occurs within this strip. */
996  if (IN_RANGE_INCL(ctime, strip->start, strip->end) ||
997  (strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
998  /* this strip is active, so try to use it */
999  estrip = strip;
1000  side = NES_TIME_WITHIN;
1001  break;
1002  }
1003 
1004  /* if time occurred before current strip... */
1005  if (ctime < strip->start) {
1006  if (strip == strips->first) {
1007  /* before first strip - only try to use it if it extends backwards in time too */
1008  if (strip->extendmode == NLASTRIP_EXTEND_HOLD) {
1009  estrip = strip;
1010  }
1011 
1012  /* side is 'before' regardless of whether there's a useful strip */
1013  side = NES_TIME_BEFORE;
1014  }
1015  else {
1016  /* before next strip - previous strip has ended, but next hasn't begun,
1017  * so blending mode depends on whether strip is being held or not...
1018  * - only occurs when no transition strip added, otherwise the transition would have
1019  * been picked up above...
1020  */
1021  strip = strip->prev;
1022 
1023  if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
1024  estrip = strip;
1025  }
1026  side = NES_TIME_AFTER;
1027  }
1028  break;
1029  }
1030 
1031  /* if time occurred after current strip... */
1032  if (ctime > strip->end) {
1033  /* only if this is the last strip should we do anything, and only if that is being held */
1034  if (strip == strips->last) {
1035  if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
1036  estrip = strip;
1037  }
1038 
1039  side = NES_TIME_AFTER;
1040  break;
1041  }
1042 
1043  /* otherwise, skip... as the 'before' case will catch it more elegantly! */
1044  }
1045  }
1046 
1047  /* check if a valid strip was found
1048  * - must not be muted (i.e. will have contribution
1049  */
1050  if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED)) {
1051  return NULL;
1052  }
1053 
1054  /* if ctime was not within the boundaries of the strip, clamp! */
1055  switch (side) {
1056  case NES_TIME_BEFORE: /* extend first frame only */
1057  ctime = estrip->start;
1058  break;
1059  case NES_TIME_AFTER: /* extend last frame only */
1060  ctime = estrip->end;
1061  break;
1062  }
1063 
1064  /* evaluate strip's evaluation controls
1065  * - skip if no influence (i.e. same effect as muting the strip)
1066  * - negative influence is not supported yet... how would that be defined?
1067  */
1068  /* TODO: this sounds a bit hacky having a few isolated F-Curves
1069  * stuck on some data it operates on... */
1071  anim_eval_context, ctime);
1072  nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original);
1073  if (estrip->influence <= 0.0f) {
1074  return NULL;
1075  }
1076 
1077  /* check if strip has valid data to evaluate,
1078  * and/or perform any additional type-specific actions
1079  */
1080  switch (estrip->type) {
1081  case NLASTRIP_TYPE_CLIP:
1082  /* clip must have some action to evaluate */
1083  if (estrip->act == NULL) {
1084  return NULL;
1085  }
1086  break;
1088  /* there must be strips to transition from and to (i.e. prev and next required) */
1089  if (ELEM(NULL, estrip->prev, estrip->next)) {
1090  return NULL;
1091  }
1092 
1093  /* evaluate controls for the relevant extents of the bordering strips... */
1095  anim_eval_context, estrip->start);
1097  anim_eval_context, estrip->end);
1098  nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original);
1099  nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original);
1100  break;
1101  }
1102 
1103  /* add to list of strips we need to evaluate */
1104  nes = MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
1105 
1106  nes->strip = estrip;
1107  nes->strip_mode = side;
1108  nes->track_index = index;
1109  nes->strip_time = estrip->strip_time;
1110 
1111  if (list) {
1112  BLI_addtail(list, nes);
1113  }
1114 
1115  return nes;
1116 }
1117 
1119  ListBase *dst_list,
1120  NlaStrip *single_strip,
1121  const AnimationEvalContext *anim_eval_context,
1122  const bool flush_to_original)
1123 {
1124  ListBase single_tracks_list;
1125  single_tracks_list.first = single_tracks_list.last = single_strip;
1126 
1128  dst_list, &single_tracks_list, -1, anim_eval_context, flush_to_original);
1129 }
1130 
1131 /* ---------------------- */
1132 
1133 /* Initialize a valid mask, allocating memory if necessary. */
1134 static void nlavalidmask_init(NlaValidMask *mask, int bits)
1135 {
1136  if (BLI_BITMAP_SIZE(bits) > sizeof(mask->buffer)) {
1137  mask->ptr = BLI_BITMAP_NEW(bits, "NlaValidMask");
1138  }
1139  else {
1140  mask->ptr = mask->buffer;
1141  }
1142 }
1143 
1144 /* Free allocated memory for the mask. */
1146 {
1147  if (mask->ptr != mask->buffer) {
1148  MEM_freeN(mask->ptr);
1149  }
1150 }
1151 
1152 /* ---------------------- */
1153 
1154 /* Hashing functions for NlaEvalChannelKey. */
1155 static uint nlaevalchan_keyhash(const void *ptr)
1156 {
1157  const NlaEvalChannelKey *key = ptr;
1159  return hash ^ BLI_ghashutil_ptrhash(key->prop);
1160 }
1161 
1162 static bool nlaevalchan_keycmp(const void *a, const void *b)
1163 {
1164  const NlaEvalChannelKey *A = a;
1165  const NlaEvalChannelKey *B = b;
1166 
1167  return ((A->ptr.data != B->ptr.data) || (A->prop != B->prop));
1168 }
1169 
1170 /* ---------------------- */
1171 
1172 /* Allocate a new blending value snapshot for the channel. */
1174 {
1175  int length = nec->base_snapshot.length;
1176 
1177  size_t byte_size = sizeof(NlaEvalChannelSnapshot) + sizeof(float) * length;
1178  NlaEvalChannelSnapshot *nec_snapshot = MEM_callocN(byte_size, "NlaEvalChannelSnapshot");
1179 
1180  nec_snapshot->channel = nec;
1181  nec_snapshot->length = length;
1182  nlavalidmask_init(&nec_snapshot->blend_domain, length);
1183  nlavalidmask_init(&nec_snapshot->remap_domain, length);
1184 
1185  return nec_snapshot;
1186 }
1187 
1188 /* Free a channel's blending value snapshot. */
1190 {
1191  BLI_assert(!nec_snapshot->is_base);
1192 
1193  nlavalidmask_free(&nec_snapshot->blend_domain);
1194  nlavalidmask_free(&nec_snapshot->remap_domain);
1195  MEM_freeN(nec_snapshot);
1196 }
1197 
1198 /* Copy all data in the snapshot. */
1200  const NlaEvalChannelSnapshot *src)
1201 {
1202  BLI_assert(dst->channel == src->channel);
1203 
1204  memcpy(dst->values, src->values, sizeof(float) * dst->length);
1205 }
1206 
1207 /* ---------------------- */
1208 
1209 /* Initialize a blending state snapshot structure. */
1211  NlaEvalData *nlaeval,
1212  NlaEvalSnapshot *base)
1213 {
1214  snapshot->base = base;
1215  snapshot->size = MAX2(16, nlaeval->num_channels);
1216  snapshot->channels = MEM_callocN(sizeof(*snapshot->channels) * snapshot->size,
1217  "NlaEvalSnapshot::channels");
1218 }
1219 
1220 /* Retrieve the individual channel snapshot. */
1222 {
1223  return (index < snapshot->size) ? snapshot->channels[index] : NULL;
1224 }
1225 
1226 /* Ensure at least this number of slots exists. */
1228 {
1229  if (size > snapshot->size) {
1230  snapshot->size *= 2;
1231  CLAMP_MIN(snapshot->size, size);
1232  CLAMP_MIN(snapshot->size, 16);
1233 
1234  size_t byte_size = sizeof(*snapshot->channels) * snapshot->size;
1235  snapshot->channels = MEM_recallocN_id(
1236  snapshot->channels, byte_size, "NlaEvalSnapshot::channels");
1237  }
1238 }
1239 
1240 /* Retrieve the address of a slot in the blending state snapshot for this channel (may realloc). */
1242  NlaEvalChannel *nec)
1243 {
1245  return &snapshot->channels[nec->index];
1246 }
1247 
1248 /* Retrieve the blending snapshot for the specified channel, with fallback to base. */
1250  NlaEvalChannel *nec)
1251 {
1252  while (snapshot != NULL) {
1253  NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_get(snapshot, nec->index);
1254  if (nec_snapshot != NULL) {
1255  return nec_snapshot;
1256  }
1257  snapshot = snapshot->base;
1258  }
1259 
1260  return &nec->base_snapshot;
1261 }
1262 
1263 /* Retrieve or create the channel value snapshot, copying from the other snapshot
1264  * (or default values) */
1266  NlaEvalChannel *nec)
1267 {
1268  NlaEvalChannelSnapshot **slot = nlaeval_snapshot_ensure_slot(snapshot, nec);
1269 
1270  if (*slot == NULL) {
1271  NlaEvalChannelSnapshot *base_snapshot, *nec_snapshot;
1272 
1273  nec_snapshot = nlaevalchan_snapshot_new(nec);
1274  base_snapshot = nlaeval_snapshot_find_channel(snapshot->base, nec);
1275 
1276  nlaevalchan_snapshot_copy(nec_snapshot, base_snapshot);
1277 
1278  *slot = nec_snapshot;
1279  }
1280 
1281  return *slot;
1282 }
1283 
1284 /* Free all memory owned by this blending snapshot structure. */
1286 {
1287  if (snapshot->channels != NULL) {
1288  for (int i = 0; i < snapshot->size; i++) {
1289  NlaEvalChannelSnapshot *nec_snapshot = snapshot->channels[i];
1290  if (nec_snapshot != NULL) {
1291  nlaevalchan_snapshot_free(nec_snapshot);
1292  }
1293  }
1294 
1295  MEM_freeN(snapshot->channels);
1296  }
1297 
1298  snapshot->base = NULL;
1299  snapshot->size = 0;
1300  snapshot->channels = NULL;
1301 }
1302 
1303 /* ---------------------- */
1304 
1305 /* Free memory owned by this evaluation channel. */
1307 {
1308  nlavalidmask_free(&nec->domain);
1309 }
1310 
1311 /* Initialize a full NLA evaluation state structure. */
1312 static void nlaeval_init(NlaEvalData *nlaeval)
1313 {
1314  memset(nlaeval, 0, sizeof(*nlaeval));
1315 
1316  nlaeval->path_hash = BLI_ghash_str_new("NlaEvalData::path_hash");
1317  nlaeval->key_hash = BLI_ghash_new(
1318  nlaevalchan_keyhash, nlaevalchan_keycmp, "NlaEvalData::key_hash");
1319 }
1320 
1321 static void nlaeval_free(NlaEvalData *nlaeval)
1322 {
1323  /* Delete base snapshot - its channels are part of NlaEvalChannel and shouldn't be freed. */
1325 
1326  /* Delete result snapshot. */
1328 
1329  /* Delete channels. */
1330  LISTBASE_FOREACH (NlaEvalChannel *, nec, &nlaeval->channels) {
1331  nlaevalchan_free_data(nec);
1332  }
1333 
1334  BLI_freelistN(&nlaeval->channels);
1335  BLI_ghash_free(nlaeval->path_hash, NULL, NULL);
1336  BLI_ghash_free(nlaeval->key_hash, NULL, NULL);
1337 }
1338 
1339 /* ---------------------- */
1340 
1341 static int nlaevalchan_validate_index(const NlaEvalChannel *nec, int index)
1342 {
1343  if (nec->is_array) {
1344  if (index >= 0 && index < nec->base_snapshot.length) {
1345  return index;
1346  }
1347 
1348  return -1;
1349  }
1350  return 0;
1351 }
1352 
1353 static bool nlaevalchan_validate_index_ex(const NlaEvalChannel *nec, const int array_index)
1354 {
1357  const int index = nlaevalchan_validate_index(nec, array_index);
1358 
1359  if (index < 0) {
1360  if (G.debug & G_DEBUG) {
1361  ID *id = nec->key.ptr.owner_id;
1362  CLOG_WARN(&LOG,
1363  "Animation: Invalid array index. ID = '%s', '%s[%d]', array length is %d",
1364  id ? (id->name + 2) : "<No ID>",
1365  nec->rna_path,
1366  array_index,
1367  nec->base_snapshot.length);
1368  }
1369 
1370  return false;
1371  }
1372  return true;
1373 }
1374 
1375 /* Initialize default values for NlaEvalChannel from the property data. */
1376 static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
1377 {
1378  PointerRNA *ptr = &nec->key.ptr;
1379  PropertyRNA *prop = nec->key.prop;
1380  int length = nec->base_snapshot.length;
1381 
1382  /* Use unit quaternion for quaternion properties. */
1383  if (nec->mix_mode == NEC_MIX_QUATERNION) {
1384  unit_qt(r_values);
1385  return;
1386  }
1387  /* Use all zero for Axis-Angle properties. */
1388  if (nec->mix_mode == NEC_MIX_AXIS_ANGLE) {
1389  zero_v4(r_values);
1390  return;
1391  }
1392 
1393  /* NOTE: while this doesn't work for all RNA properties as default values aren't in fact
1394  * set properly for most of them, at least the common ones (which also happen to get used
1395  * in NLA strips a lot, e.g. scale) are set correctly.
1396  */
1397  if (RNA_property_array_check(prop)) {
1399  bool *tmp_bool;
1400  int *tmp_int;
1401 
1402  switch (RNA_property_type(prop)) {
1403  case PROP_BOOLEAN:
1404  tmp_bool = MEM_malloc_arrayN(length, sizeof(*tmp_bool), __func__);
1406  for (int i = 0; i < length; i++) {
1407  r_values[i] = (float)tmp_bool[i];
1408  }
1409  MEM_freeN(tmp_bool);
1410  break;
1411  case PROP_INT:
1412  tmp_int = MEM_malloc_arrayN(length, sizeof(*tmp_int), __func__);
1413  RNA_property_int_get_default_array(ptr, prop, tmp_int);
1414  for (int i = 0; i < length; i++) {
1415  r_values[i] = (float)tmp_int[i];
1416  }
1417  MEM_freeN(tmp_int);
1418  break;
1419  case PROP_FLOAT:
1420  RNA_property_float_get_default_array(ptr, prop, r_values);
1421  break;
1422  default:
1423  memset(r_values, 0, sizeof(float) * length);
1424  }
1425  }
1426  else {
1427  BLI_assert(length == 1);
1428 
1429  switch (RNA_property_type(prop)) {
1430  case PROP_BOOLEAN:
1431  *r_values = (float)RNA_property_boolean_get_default(ptr, prop);
1432  break;
1433  case PROP_INT:
1434  *r_values = (float)RNA_property_int_get_default(ptr, prop);
1435  break;
1436  case PROP_FLOAT:
1437  *r_values = RNA_property_float_get_default(ptr, prop);
1438  break;
1439  case PROP_ENUM:
1440  *r_values = (float)RNA_property_enum_get_default(ptr, prop);
1441  break;
1442  default:
1443  *r_values = 0.0f;
1444  }
1445  }
1446 
1447  /* Ensure multiplicative properties aren't reset to 0. */
1448  if (nec->mix_mode == NEC_MIX_MULTIPLY) {
1449  for (int i = 0; i < length; i++) {
1450  if (r_values[i] == 0.0f) {
1451  r_values[i] = 1.0f;
1452  }
1453  }
1454  }
1455 }
1456 
1458 {
1459  PropertySubType subtype = RNA_property_subtype(key->prop);
1460 
1461  if (subtype == PROP_QUATERNION && length == 4) {
1462  return NEC_MIX_QUATERNION;
1463  }
1464  if (subtype == PROP_AXISANGLE && length == 4) {
1465  return NEC_MIX_AXIS_ANGLE;
1466  }
1468  return NEC_MIX_MULTIPLY;
1469  }
1470  return NEC_MIX_ADD;
1471 }
1472 
1473 /* Verify that an appropriate NlaEvalChannel for this property exists. */
1475  const char *path,
1476  NlaEvalChannelKey *key)
1477 {
1478  /* Look it up in the key hash. */
1479  NlaEvalChannel **p_key_nec;
1480  NlaEvalChannelKey **p_key;
1481  bool found_key = BLI_ghash_ensure_p_ex(
1482  nlaeval->key_hash, key, (void ***)&p_key, (void ***)&p_key_nec);
1483 
1484  if (found_key) {
1485  return *p_key_nec;
1486  }
1487 
1488  /* Create the channel. */
1489  bool is_array = RNA_property_array_check(key->prop);
1490  int length = is_array ? RNA_property_array_length(&key->ptr, key->prop) : 1;
1491 
1492  NlaEvalChannel *nec = MEM_callocN(sizeof(NlaEvalChannel) + sizeof(float) * length,
1493  "NlaEvalChannel");
1494 
1495  /* Initialize the channel. */
1496  nec->rna_path = path;
1497  nec->key = *key;
1498 
1499  nec->owner = nlaeval;
1500  nec->index = nlaeval->num_channels++;
1501  nec->is_array = is_array;
1502 
1504 
1506 
1507  nec->base_snapshot.channel = nec;
1508  nec->base_snapshot.length = length;
1509  nec->base_snapshot.is_base = true;
1510 
1512 
1513  /* Store channel in data structures. */
1514  BLI_addtail(&nlaeval->channels, nec);
1515 
1516  *nlaeval_snapshot_ensure_slot(&nlaeval->base_snapshot, nec) = &nec->base_snapshot;
1517 
1518  *p_key_nec = nec;
1519  *p_key = &nec->key;
1520 
1521  return nec;
1522 }
1523 
1524 /* Verify that an appropriate NlaEvalChannel for this path exists. */
1525 static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval, const char *path)
1526 {
1527  if (path == NULL) {
1528  return NULL;
1529  }
1530 
1531  /* Lookup the path in the path based hash. */
1532  NlaEvalChannel **p_path_nec;
1533  bool found_path = BLI_ghash_ensure_p(nlaeval->path_hash, (void *)path, (void ***)&p_path_nec);
1534 
1535  if (found_path) {
1536  return *p_path_nec;
1537  }
1538 
1539  /* Cache NULL result for now. */
1540  *p_path_nec = NULL;
1541 
1542  /* Resolve the property and look it up in the key hash. */
1543  NlaEvalChannelKey key;
1544 
1545  if (!RNA_path_resolve_property(ptr, path, &key.ptr, &key.prop)) {
1546  /* Report failure to resolve the path. */
1547  if (G.debug & G_DEBUG) {
1548  CLOG_WARN(&LOG,
1549  "Animato: Invalid path. ID = '%s', '%s'",
1550  (ptr->owner_id) ? (ptr->owner_id->name + 2) : "<No ID>",
1551  path);
1552  }
1553 
1554  return NULL;
1555  }
1556 
1557  /* Check that the property can be animated. */
1558  if (ptr->owner_id != NULL && !RNA_property_animateable(&key.ptr, key.prop)) {
1559  return NULL;
1560  }
1561 
1562  NlaEvalChannel *nec = nlaevalchan_verify_key(nlaeval, path, &key);
1563 
1564  if (nec->rna_path == NULL) {
1565  nec->rna_path = path;
1566  }
1567 
1568  return *p_path_nec = nec;
1569 }
1570 
1571 /* ---------------------- */
1572 
1574 static bool nla_blend_get_inverted_lower_value(const int blendmode,
1575  const float strip_value,
1576  const float blended_value,
1577  const float influence,
1578  float *r_lower_value)
1579 {
1580  if (IS_EQF(influence, 0.0f)) {
1581  *r_lower_value = blended_value;
1582  return true;
1583  }
1584 
1585  switch (blendmode) {
1586  case NLASTRIP_MODE_ADD:
1587  /* Simply subtract the scaled value on to the stack. */
1588  *r_lower_value = blended_value - (strip_value * influence);
1589  return true;
1590 
1592  /* Simply add the scaled value from the stack. */
1593  *r_lower_value = blended_value + (strip_value * influence);
1594  return true;
1595 
1596  case NLASTRIP_MODE_MULTIPLY: {
1597  /* Check for division by zero. */
1598  const float denominator = (influence * strip_value + (1.0f - influence));
1599  if (IS_EQF(denominator, 0.0f)) {
1600  /* For 0/0, any r_lower_value is a solution. We'll just choose 1.
1601  *
1602  * Any r_lower_value is a solution. In this case, ideally we would insert redundant
1603  * keyframes, those that don't change the fcurve's shape. Otherwise, we're likely messing
1604  * up interpolation for the animator, requiring further cleanup on their part.
1605  */
1606  if (IS_EQF(blended_value, 0.0f)) {
1607  /* When denominator==0:
1608  *
1609  * denominator = (inf * strip_value + (1.0f - inf))
1610  * 0 = inf * strip_value + (1-inf)
1611  * -inf * strip_value = 1 - inf
1612  * -strip_value = (1 - inf) / inf
1613  * strip_value = (inf - 1) / inf
1614  * strip_value = 1 - (1/inf)
1615  *
1616  * For blending, nla_blend_value(), this results in:
1617  *
1618  * blended_value = inf * (lower_value * strip_value) + (1 - inf) * lower_value;
1619  * = inf * (lower_value * (1 - (1/inf))) + ...
1620  * = inf * (1 - (1/inf)) * lower_value + ...
1621  * = (inf - (inf/inf)) * lower_value + ...
1622  * = -(inf - 1) * lower_value + (1 - inf) * lower_value;
1623  * blended_value = 0
1624  *
1625  * Effectively, blended_value will equal 0 no matter what lower_value is. Put another
1626  * way, when (blended_value==0 and denominator==0), then lower_value can be any value and
1627  * blending will give us back blended_value=0. We have infinite solutions for this case.
1628  */
1629  *r_lower_value = 1;
1630  return true;
1631  }
1632  /* No solution for division by zero. */
1633  return false;
1634  }
1635  /* Math:
1636  * blended_value = inf * (lower_value * strip_value) + (1 - inf) * lower_value
1637  * = lower_value * (inf * strip_value + (1-inf))
1638  * lower_value = blended_value / (inf * strip_value + (1-inf))
1639  * lower_value = blended_value / denominator
1640  */
1641  *r_lower_value = blended_value / denominator;
1642  return true;
1643  }
1644  case NLASTRIP_MODE_COMBINE:
1645  BLI_assert_msg(0, "Use nla_combine_get_inverted_lower_value()");
1646  return false;
1647 
1648  case NLASTRIP_MODE_REPLACE:
1649 
1650  /* No solution if lower strip has 0 influence. */
1651  if (IS_EQF(influence, 1.0f)) {
1652  return false;
1653  }
1654 
1655  /* Math:
1656  *
1657  * blended_value = lower_value * (1.0f - inf) + (strip_value * inf)
1658  * blended_value - (strip_value * inf) = lower_value * (1.0f - inf)
1659  * blended_value - (strip_value * inf) / (1.0f - inf) = lower_value
1660  *
1661  * lower_value = blended_value - (strip_value * inf) / (1.0f - inf)
1662  */
1663  *r_lower_value = (blended_value - (strip_value * influence)) / (1.0f - influence);
1664  return true;
1665  }
1666 
1667  BLI_assert_msg(0, "invalid blend mode");
1668  return false;
1669 }
1670 
1672 static bool nla_combine_get_inverted_lower_value(const int mix_mode,
1673  float base_value,
1674  const float strip_value,
1675  const float blended_value,
1676  const float influence,
1677  float *r_lower_value)
1678 {
1679  if (IS_EQF(influence, 0.0f)) {
1680  *r_lower_value = blended_value;
1681  return true;
1682  }
1683 
1684  /* Perform blending. */
1685  switch (mix_mode) {
1686  case NEC_MIX_ADD:
1687  case NEC_MIX_AXIS_ANGLE:
1688  *r_lower_value = blended_value - (strip_value - base_value) * influence;
1689  return true;
1690  case NEC_MIX_MULTIPLY:
1691  /* Division by zero. */
1692  if (IS_EQF(strip_value, 0.0f)) {
1693  /* Resolve 0/0 to 1.
1694  *
1695  * Any r_lower_value is a solution. In this case, ideally we would insert redundant
1696  * keyframes, those that don't change the fcurve's shape. Otherwise, we're likely messing
1697  * up interpolation for the animator, requiring further cleanup on their part.
1698  */
1699  if (IS_EQF(blended_value, 0.0f)) {
1700  /* For blending, nla_combine_value(), when strip_value==0:
1701  *
1702  * blended_value = lower_value * powf(strip_value / base_value, infl);
1703  * blended_value = lower_value * powf(0, infl);
1704  * blended_value = lower_value * 0;
1705  * blended_value = 0;
1706  *
1707  * Effectively, blended_value will equal 0 no matter what lower_value is. Put another
1708  * way, when (blended_value==0 and strip_value==0), then lower_value can be any value and
1709  * blending will give us back blended_value=0. We have infinite solutions for this case.
1710  */
1711  *r_lower_value = 1.0f;
1712  return true;
1713  }
1714  /* No solution. */
1715  return false;
1716  }
1717 
1718  if (IS_EQF(base_value, 0.0f)) {
1719  base_value = 1.0f;
1720  }
1721 
1722  *r_lower_value = blended_value / powf(strip_value / base_value, influence);
1723  return true;
1724 
1725  case NEC_MIX_QUATERNION:
1726  BLI_assert_msg(0, "Use nla_combine_quaternion_get_inverted_lower_values()");
1727  return false;
1728  }
1729 
1730  BLI_assert_msg(0, "Mixmode not implemented");
1731  return false;
1732 }
1733 
1734 static void nla_combine_quaternion_get_inverted_lower_values(const float strip_values[4],
1735  const float blended_values[4],
1736  const float influence,
1737  float r_lower_value[4])
1738 {
1739  if (IS_EQF(influence, 0.0f)) {
1740  normalize_qt_qt(r_lower_value, blended_values);
1741  return;
1742  }
1743 
1744  /* blended_value = lower_values @ strip_values^infl
1745  * blended_value @ inv(strip_values^inf) = lower_values
1746  *
1747  * Returns: lower_values = blended_value @ inv(strip_values^inf) */
1748  float tmp_strip_values[4], tmp_blended[4];
1749 
1750  normalize_qt_qt(tmp_strip_values, strip_values);
1751  normalize_qt_qt(tmp_blended, blended_values);
1752 
1753  pow_qt_fl_normalized(tmp_strip_values, influence);
1754  invert_qt_normalized(tmp_strip_values);
1755 
1756  mul_qt_qtqt(r_lower_value, tmp_blended, tmp_strip_values);
1757 }
1758 
1759 /* Blend the lower nla stack value and upper strip value of a channel according to mode and
1760  * influence. */
1761 static float nla_blend_value(const int blendmode,
1762  const float lower_value,
1763  const float strip_value,
1764  const float influence)
1765 {
1766  /* Optimization: no need to try applying if there is no influence. */
1767  if (IS_EQF(influence, 0.0f)) {
1768  return lower_value;
1769  }
1770 
1771  /* Perform blending. */
1772  switch (blendmode) {
1773  case NLASTRIP_MODE_ADD:
1774  /* Simply add the scaled value on to the stack. */
1775  return lower_value + (strip_value * influence);
1776 
1778  /* Simply subtract the scaled value from the stack. */
1779  return lower_value - (strip_value * influence);
1780 
1782  /* Multiply the scaled value with the stack. */
1783  return influence * (lower_value * strip_value) + (1 - influence) * lower_value;
1784 
1785  case NLASTRIP_MODE_COMBINE:
1786  BLI_assert_msg(0, "combine mode");
1788 
1789  default:
1790  /* TODO: Do we really want to blend by default? it seems more uses might prefer add... */
1791  /* Do linear interpolation. The influence of the accumulated data (elsewhere, that is called
1792  * dstweight) is 1 - influence, since the strip's influence is srcweight.
1793  */
1794  return lower_value * (1.0f - influence) + (strip_value * influence);
1795  }
1796 }
1797 
1798 /* Blend the lower nla stack value and upper strip value of a channel according to mode and
1799  * influence. */
1800 static float nla_combine_value(const int mix_mode,
1801  float base_value,
1802  const float lower_value,
1803  const float strip_value,
1804  const float influence)
1805 {
1806  /* Optimization: No need to try applying if there is no influence. */
1807  if (IS_EQF(influence, 0.0f)) {
1808  return lower_value;
1809  }
1810 
1811  /* Perform blending */
1812  switch (mix_mode) {
1813  case NEC_MIX_ADD:
1814  case NEC_MIX_AXIS_ANGLE:
1815  return lower_value + (strip_value - base_value) * influence;
1816 
1817  case NEC_MIX_MULTIPLY:
1818  if (IS_EQF(base_value, 0.0f)) {
1819  base_value = 1.0f;
1820  }
1821  return lower_value * powf(strip_value / base_value, influence);
1822 
1823  default:
1824  BLI_assert_msg(0, "invalid mix mode");
1825  return lower_value;
1826  }
1827 }
1828 
1830 static bool nla_blend_get_inverted_strip_value(const int blendmode,
1831  const float lower_value,
1832  const float blended_value,
1833  const float influence,
1834  float *r_strip_value)
1835 {
1837  if (IS_EQF(influence, 0.0f)) {
1838  return false;
1839  }
1840 
1841  switch (blendmode) {
1842  case NLASTRIP_MODE_ADD:
1843  *r_strip_value = (blended_value - lower_value) / influence;
1844  return true;
1845 
1847  *r_strip_value = (lower_value - blended_value) / influence;
1848  return true;
1849 
1851  if (IS_EQF(lower_value, 0.0f)) {
1852  /* Resolve 0/0 to 1. */
1853  if (IS_EQF(blended_value, 0.0f)) {
1854  *r_strip_value = 1.0f;
1855  return true;
1856  }
1857  /* Division by zero. */
1858  return false;
1859  }
1860 
1871  *r_strip_value = ((blended_value - lower_value) / (influence * lower_value)) + 1.0f;
1872  return true;
1873 
1874  case NLASTRIP_MODE_COMBINE:
1875  BLI_assert_msg(0, "combine mode");
1877 
1878  default:
1879 
1888  *r_strip_value = (blended_value - lower_value * (1.0f - influence)) / influence;
1889  return true;
1890  }
1891 }
1892 
1894 static bool nla_combine_get_inverted_strip_value(const int mix_mode,
1895  float base_value,
1896  const float lower_value,
1897  const float blended_value,
1898  const float influence,
1899  float *r_strip_value)
1900 {
1901  /* No solution if strip had no influence. */
1902  if (IS_EQF(influence, 0.0f)) {
1903  return false;
1904  }
1905 
1906  switch (mix_mode) {
1907  case NEC_MIX_ADD:
1908  case NEC_MIX_AXIS_ANGLE:
1909  *r_strip_value = base_value + (blended_value - lower_value) / influence;
1910  return true;
1911 
1912  case NEC_MIX_MULTIPLY:
1913  if (IS_EQF(base_value, 0.0f)) {
1914  base_value = 1.0f;
1915  }
1916  /* Division by zero. */
1917  if (IS_EQF(lower_value, 0.0f)) {
1918  /* Resolve 0/0 to 1. */
1919  if (IS_EQF(blended_value, 0.0f)) {
1920  *r_strip_value = base_value;
1921  return true;
1922  }
1923  /* Division by zero. */
1924  return false;
1925  }
1926 
1927  *r_strip_value = base_value * powf(blended_value / lower_value, 1.0f / influence);
1928  return true;
1929 
1930  default:
1931  BLI_assert_msg(0, "invalid mix mode");
1932  return false;
1933  }
1934 }
1935 
1940 static void nla_combine_quaternion(const float lower_values[4],
1941  const float strip_values[4],
1942  const float influence,
1943  float r_blended_value[4])
1944 {
1945  float tmp_lower[4], tmp_strip_values[4];
1946 
1947  normalize_qt_qt(tmp_lower, lower_values);
1948  normalize_qt_qt(tmp_strip_values, strip_values);
1949 
1950  pow_qt_fl_normalized(tmp_strip_values, influence);
1951  mul_qt_qtqt(r_blended_value, tmp_lower, tmp_strip_values);
1952 }
1953 
1955 static bool nla_combine_quaternion_get_inverted_strip_values(const float lower_values[4],
1956  const float blended_values[4],
1957  const float influence,
1958  float r_strip_values[4])
1959 {
1960  /* blended_value = lower_values @ r_strip_values^infl
1961  * inv(lower_values) @ blended_value = r_strip_values^infl
1962  * (inv(lower_values) @ blended_value) ^ (1/inf) = r_strip_values
1963  *
1964  * Returns: r_strip_values = (inv(lower_values) @ blended_value) ^ (1/inf) */
1965  if (IS_EQF(influence, 0.0f)) {
1966  return false;
1967  }
1968  float tmp_lower[4], tmp_blended[4];
1969 
1970  normalize_qt_qt(tmp_lower, lower_values);
1971  normalize_qt_qt(tmp_blended, blended_values);
1972  invert_qt_normalized(tmp_lower);
1973 
1974  mul_qt_qtqt(r_strip_values, tmp_lower, tmp_blended);
1975  pow_qt_fl_normalized(r_strip_values, 1.0f / influence);
1976 
1977  return true;
1978 }
1979 
1980 /* ---------------------- */
1981 
1982 /* Assert necs and necs->channel is nonNull. */
1984 {
1985  UNUSED_VARS_NDEBUG(necs);
1986  BLI_assert(necs != NULL && necs->channel != NULL);
1987 }
1988 
1989 /* Assert that the channels given can be blended or combined together. */
1991  NlaEvalChannelSnapshot *upper_necs,
1992  NlaEvalChannelSnapshot *blended_necs)
1993 {
1994  UNUSED_VARS_NDEBUG(lower_necs, upper_necs, blended_necs);
1995  BLI_assert(!ELEM(NULL, lower_necs, blended_necs));
1996  BLI_assert(upper_necs == NULL || lower_necs->length == upper_necs->length);
1997  BLI_assert(lower_necs->length == blended_necs->length);
1998 }
1999 
2008  NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_or_lower_necs)
2009 {
2010  for (int j = 0; j < 4; j++) {
2011  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
2012  BLI_bitmap_set_all(upper_or_lower_necs->remap_domain.ptr, false, 4);
2013  return true;
2014  }
2015  }
2016 
2017  return false;
2018 }
2019 
2020 /* Assert that the channels given can be blended or combined together as a quaternion. */
2022  NlaEvalChannelSnapshot *lower_necs,
2023  NlaEvalChannelSnapshot *upper_necs,
2024  NlaEvalChannelSnapshot *blended_necs)
2025 {
2026  nlaevalchan_assert_blendOrcombine_compatible(lower_necs, upper_necs, blended_necs);
2027  BLI_assert(lower_necs->length == 4);
2028 }
2029 
2031 {
2032  memcpy(dst->values, src->values, src->length * sizeof(float));
2033 }
2034 
2040  NlaEvalChannelSnapshot *upper_necs,
2041  const float upper_influence,
2042  NlaEvalChannelSnapshot *r_blended_necs)
2043 {
2044  const bool has_influence = !IS_EQF(upper_influence, 0.0f);
2045  if (upper_necs != NULL && has_influence) {
2046  return false;
2047  }
2048 
2049  nlaevalchan_copy_values(r_blended_necs, lower_necs);
2050  return true;
2051 }
2052 
2062  NlaEvalChannelSnapshot *upper_necs,
2063  const float upper_influence,
2064  NlaEvalChannelSnapshot *r_lower_necs)
2065 {
2066  const bool has_influence = !IS_EQF(upper_influence, 0.0f);
2067  if (upper_necs != NULL && has_influence) {
2068  return false;
2069  }
2070 
2071  nlaevalchan_copy_values(r_lower_necs, blended_necs);
2072 
2073  /* Must copy remap domain to handle case where some blended values are out of domain. */
2075  r_lower_necs->remap_domain.ptr, blended_necs->remap_domain.ptr, r_lower_necs->length);
2076 
2077  return true;
2078 }
2079 
2087  NlaEvalChannelSnapshot *upper_necs,
2088  const int upper_blendmode,
2089  const float upper_influence,
2090  NlaEvalChannelSnapshot *r_blended_necs)
2091 {
2092  nlaevalchan_assert_blendOrcombine_compatible(lower_necs, upper_necs, r_blended_necs);
2094  lower_necs, upper_necs, upper_influence, r_blended_necs)) {
2095  return;
2096  }
2097 
2098  const int length = lower_necs->length;
2099  for (int j = 0; j < length; j++) {
2100  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
2101  r_blended_necs->values[j] = lower_necs->values[j];
2102  continue;
2103  }
2104 
2105  r_blended_necs->values[j] = nla_blend_value(
2106  upper_blendmode, lower_necs->values[j], upper_necs->values[j], upper_influence);
2107  }
2108 }
2109 
2117  NlaEvalChannelSnapshot *upper_necs,
2118  const float upper_influence,
2119  NlaEvalChannelSnapshot *r_blended_necs)
2120 {
2121  nlaevalchan_assert_blendOrcombine_compatible(lower_necs, upper_necs, r_blended_necs);
2123  lower_necs, upper_necs, upper_influence, r_blended_necs)) {
2124  return;
2125  }
2126 
2127  /* Assumes every base is the same. */
2128  float *base_values = lower_necs->channel->base_snapshot.values;
2129  const int length = lower_necs->length;
2130  const char mix_mode = lower_necs->channel->mix_mode;
2131 
2132  for (int j = 0; j < length; j++) {
2133  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
2134  r_blended_necs->values[j] = lower_necs->values[j];
2135  continue;
2136  }
2137 
2138  r_blended_necs->values[j] = nla_combine_value(
2139  mix_mode, base_values[j], lower_necs->values[j], upper_necs->values[j], upper_influence);
2140  }
2141 }
2142 
2150  NlaEvalChannelSnapshot *upper_necs,
2151  const float upper_influence,
2152  NlaEvalChannelSnapshot *r_blended_necs)
2153 {
2154  nlaevalchan_assert_blendOrcombine_compatible_quaternion(lower_necs, upper_necs, r_blended_necs);
2156  lower_necs, upper_necs, upper_influence, r_blended_necs)) {
2157  return;
2158  }
2159 
2161  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, 0)) {
2162  nlaevalchan_copy_values(r_blended_necs, lower_necs);
2163  return;
2164  }
2165 
2167  lower_necs->values, upper_necs->values, upper_influence, r_blended_necs->values);
2168 }
2169 
2183  NlaEvalChannelSnapshot *upper_necs,
2184  const int upper_blendmode,
2185  const float upper_influence,
2186  NlaEvalChannelSnapshot *r_blended_necs)
2187 {
2188  nlaevalchan_assert_nonNull(r_blended_necs);
2189 
2190  switch (upper_blendmode) {
2191  case NLASTRIP_MODE_COMBINE: {
2192  switch (r_blended_necs->channel->mix_mode) {
2193  case NEC_MIX_QUATERNION: {
2194  nlaevalchan_combine_quaternion(lower_necs, upper_necs, upper_influence, r_blended_necs);
2195  return;
2196  }
2197  case NEC_MIX_ADD:
2198  case NEC_MIX_AXIS_ANGLE:
2199  case NEC_MIX_MULTIPLY: {
2200  nlaevalchan_combine_value(lower_necs, upper_necs, upper_influence, r_blended_necs);
2201  return;
2202  }
2203  default:
2204  BLI_assert_msg(0, "Mix mode should've been handled");
2205  }
2206  return;
2207  }
2208  case NLASTRIP_MODE_ADD:
2211  case NLASTRIP_MODE_REPLACE: {
2213  lower_necs, upper_necs, upper_blendmode, upper_influence, r_blended_necs);
2214  return;
2215  }
2216  default:
2217  BLI_assert_msg(0, "Blend mode should've been handled");
2218  }
2219 }
2220 
2229  NlaEvalChannelSnapshot *lower_necs,
2230  NlaEvalChannelSnapshot *blended_necs,
2231  const int upper_blendmode,
2232  const float upper_influence,
2233  NlaEvalChannelSnapshot *r_upper_necs)
2234 {
2235  nlaevalchan_assert_nonNull(r_upper_necs);
2236  nlaevalchan_assert_blendOrcombine_compatible(lower_necs, r_upper_necs, blended_necs);
2237 
2238  const int length = lower_necs->length;
2239  for (int j = 0; j < length; j++) {
2240  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
2241  BLI_BITMAP_DISABLE(r_upper_necs->remap_domain.ptr, j);
2242  continue;
2243  }
2244 
2245  const bool success = nla_blend_get_inverted_strip_value(upper_blendmode,
2246  lower_necs->values[j],
2247  blended_necs->values[j],
2248  upper_influence,
2249  &r_upper_necs->values[j]);
2250  BLI_BITMAP_SET(r_upper_necs->remap_domain.ptr, j, success);
2251  }
2252 }
2253 
2262  NlaEvalChannelSnapshot *lower_necs,
2263  NlaEvalChannelSnapshot *blended_necs,
2264  const float upper_influence,
2265  NlaEvalChannelSnapshot *r_upper_necs)
2266 {
2267  nlaevalchan_assert_nonNull(r_upper_necs);
2268  nlaevalchan_assert_blendOrcombine_compatible(lower_necs, r_upper_necs, blended_necs);
2269 
2270  /* Assumes every channel's base is the same. */
2271  float *base_values = lower_necs->channel->base_snapshot.values;
2272  const int length = lower_necs->length;
2273  const char mix_mode = lower_necs->channel->mix_mode;
2274 
2275  for (int j = 0; j < length; j++) {
2276  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
2277  BLI_BITMAP_DISABLE(r_upper_necs->remap_domain.ptr, j);
2278  continue;
2279  }
2280 
2281  const bool success = nla_combine_get_inverted_strip_value(mix_mode,
2282  base_values[j],
2283  lower_necs->values[j],
2284  blended_necs->values[j],
2285  upper_influence,
2286  &r_upper_necs->values[j]);
2287 
2288  BLI_BITMAP_SET(r_upper_necs->remap_domain.ptr, j, success);
2289  }
2290 }
2291 
2300  NlaEvalChannelSnapshot *lower_necs,
2301  NlaEvalChannelSnapshot *blended_necs,
2302  const float upper_influence,
2303  NlaEvalChannelSnapshot *r_upper_necs)
2304 {
2305  nlaevalchan_assert_nonNull(r_upper_necs);
2306  nlaevalchan_assert_blendOrcombine_compatible_quaternion(lower_necs, r_upper_necs, blended_necs);
2307 
2308  if (nlaevalchan_combine_quaternion_handle_undefined_blend_values(blended_necs, r_upper_necs)) {
2309  return;
2310  }
2311 
2313  lower_necs->values, blended_necs->values, upper_influence, r_upper_necs->values);
2314 
2315  BLI_bitmap_set_all(r_upper_necs->remap_domain.ptr, success, 4);
2316 }
2317 
2332  NlaEvalChannelSnapshot *lower_necs,
2333  NlaEvalChannelSnapshot *blended_necs,
2334  const int upper_blendmode,
2335  const float upper_influence,
2336  NlaEvalChannelSnapshot *r_upper_necs)
2337 {
2338  nlaevalchan_assert_nonNull(r_upper_necs);
2339 
2340  if (IS_EQF(upper_influence, 0.0f)) {
2341  BLI_bitmap_set_all(r_upper_necs->remap_domain.ptr, false, r_upper_necs->length);
2342  return;
2343  }
2344 
2345  switch (upper_blendmode) {
2346  case NLASTRIP_MODE_COMBINE: {
2347  switch (r_upper_necs->channel->mix_mode) {
2348  case NEC_MIX_QUATERNION: {
2350  lower_necs, blended_necs, upper_influence, r_upper_necs);
2351  return;
2352  }
2353  case NEC_MIX_ADD:
2354  case NEC_MIX_AXIS_ANGLE:
2355  case NEC_MIX_MULTIPLY: {
2357  lower_necs, blended_necs, upper_influence, r_upper_necs);
2358  return;
2359  }
2360  default:
2361  BLI_assert_msg(0, "Mix mode should've been handled");
2362  }
2363  return;
2364  }
2365  case NLASTRIP_MODE_ADD:
2368  case NLASTRIP_MODE_REPLACE: {
2370  lower_necs, blended_necs, upper_blendmode, upper_influence, r_upper_necs);
2371  return;
2372  }
2373  default:
2374  BLI_assert_msg(0, "Blend mode should've been handled");
2375  }
2376 }
2377 
2379  NlaEvalChannelSnapshot *blended_necs,
2380  NlaEvalChannelSnapshot *upper_necs,
2381  const int upper_blendmode,
2382  const float upper_influence,
2383  NlaEvalChannelSnapshot *r_lower_necs)
2384 {
2385  nlaevalchan_assert_blendOrcombine_compatible(r_lower_necs, upper_necs, blended_necs);
2386 
2388  blended_necs, upper_necs, upper_influence, r_lower_necs)) {
2389  return;
2390  }
2391 
2392  const int length = r_lower_necs->length;
2393 
2394  for (int j = 0; j < length; j++) {
2395  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
2396  BLI_BITMAP_DISABLE(r_lower_necs->remap_domain.ptr, j);
2397  continue;
2398  }
2399 
2400  /* If upper value was not blended, then the blended value was directly copied from the lower
2401  * value. */
2402  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
2403  r_lower_necs->values[j] = blended_necs->values[j];
2404  BLI_BITMAP_ENABLE(r_lower_necs->remap_domain.ptr, j);
2405  continue;
2406  }
2407 
2408  const bool success = nla_blend_get_inverted_lower_value(upper_blendmode,
2409  upper_necs->values[j],
2410  blended_necs->values[j],
2411  upper_influence,
2412  &r_lower_necs->values[j]);
2413 
2414  BLI_BITMAP_SET(r_lower_necs->remap_domain.ptr, j, success);
2415  }
2416 }
2417 
2419  NlaEvalChannelSnapshot *blended_necs,
2420  NlaEvalChannelSnapshot *upper_necs,
2421  const float upper_influence,
2422  NlaEvalChannelSnapshot *r_lower_necs)
2423 {
2424  nlaevalchan_assert_blendOrcombine_compatible(r_lower_necs, upper_necs, blended_necs);
2425 
2427  blended_necs, upper_necs, upper_influence, r_lower_necs)) {
2428  return;
2429  }
2430 
2431  float *base_values = r_lower_necs->channel->base_snapshot.values;
2432  const int mix_mode = r_lower_necs->channel->mix_mode;
2433  const int length = r_lower_necs->length;
2434 
2435  for (int j = 0; j < length; j++) {
2436  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, j)) {
2437  BLI_BITMAP_DISABLE(r_lower_necs->remap_domain.ptr, j);
2438  continue;
2439  }
2440 
2441  /* If upper value was not blended, then the blended value was directly copied from the lower
2442  * value. */
2443  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, j)) {
2444  r_lower_necs->values[j] = blended_necs->values[j];
2445  BLI_BITMAP_ENABLE(r_lower_necs->remap_domain.ptr, j);
2446  continue;
2447  }
2448 
2449  const bool success = nla_combine_get_inverted_lower_value(mix_mode,
2450  base_values[j],
2451  upper_necs->values[j],
2452  blended_necs->values[j],
2453  upper_influence,
2454  &r_lower_necs->values[j]);
2455 
2456  BLI_BITMAP_SET(r_lower_necs->remap_domain.ptr, j, success);
2457  }
2458 }
2459 
2461  NlaEvalChannelSnapshot *blended_necs,
2462  NlaEvalChannelSnapshot *upper_necs,
2463  const float upper_influence,
2464  NlaEvalChannelSnapshot *r_lower_necs)
2465 {
2466  nlaevalchan_assert_blendOrcombine_compatible_quaternion(r_lower_necs, upper_necs, blended_necs);
2467 
2468  if (nlaevalchan_combine_quaternion_handle_undefined_blend_values(blended_necs, r_lower_necs)) {
2469  return;
2470  }
2471 
2473  blended_necs, upper_necs, upper_influence, r_lower_necs)) {
2474  return;
2475  }
2476 
2477  /* If upper value was not blended, then the blended value was directly copied from the lower
2478  * value. */
2479  if (!BLI_BITMAP_TEST_BOOL(upper_necs->blend_domain.ptr, 0)) {
2480  memcpy(r_lower_necs->values, blended_necs->values, 4 * sizeof(float));
2481  BLI_bitmap_set_all(r_lower_necs->remap_domain.ptr, true, 4);
2482  return;
2483  }
2484 
2486  upper_necs->values, blended_necs->values, upper_influence, r_lower_necs->values);
2487 
2488  BLI_bitmap_set_all(r_lower_necs->remap_domain.ptr, true, 4);
2489 }
2490 
2504  NlaEvalChannelSnapshot *blended_necs,
2505  NlaEvalChannelSnapshot *upper_necs,
2506  const int upper_blendmode,
2507  const float upper_influence,
2508  NlaEvalChannelSnapshot *r_lower_necs)
2509 
2510 {
2511  nlaevalchan_assert_nonNull(r_lower_necs);
2512 
2513  switch (upper_blendmode) {
2514  case NLASTRIP_MODE_COMBINE: {
2515  switch (r_lower_necs->channel->mix_mode) {
2516  case NEC_MIX_QUATERNION: {
2518  blended_necs, upper_necs, upper_influence, r_lower_necs);
2519  return;
2520  }
2521  case NEC_MIX_ADD:
2522  case NEC_MIX_AXIS_ANGLE:
2523  case NEC_MIX_MULTIPLY: {
2525  blended_necs, upper_necs, upper_influence, r_lower_necs);
2526  return;
2527  }
2528  }
2529  BLI_assert_msg(0, "Mix mode should've been handled");
2530  return;
2531  }
2532  case NLASTRIP_MODE_ADD:
2535  case NLASTRIP_MODE_REPLACE: {
2537  blended_necs, upper_necs, upper_blendmode, upper_influence, r_lower_necs);
2538  return;
2539  }
2540  }
2541 
2542  BLI_assert_msg(0, "Blend mode should've been handled");
2543 }
2544 
2545 /* ---------------------- */
2546 /* F-Modifier stack joining/separation utilities -
2547  * should we generalize these for BLI_listbase.h interface? */
2548 
2549 /* Temporarily join two lists of modifiers together, storing the result in a third list */
2551 {
2552  FModifier *fcm1, *fcm2;
2553 
2554  /* if list1 is invalid... */
2555  if (ELEM(NULL, list1, list1->first)) {
2556  if (list2 && list2->first) {
2557  result->first = list2->first;
2558  result->last = list2->last;
2559  }
2560  }
2561  /* if list 2 is invalid... */
2562  else if (ELEM(NULL, list2, list2->first)) {
2563  result->first = list1->first;
2564  result->last = list1->last;
2565  }
2566  else {
2567  /* list1 should be added first, and list2 second,
2568  * with the endpoints of these being the endpoints for result
2569  * - the original lists must be left unchanged though, as we need that fact for restoring.
2570  */
2571  result->first = list1->first;
2572  result->last = list2->last;
2573 
2574  fcm1 = list1->last;
2575  fcm2 = list2->first;
2576 
2577  fcm1->next = fcm2;
2578  fcm2->prev = fcm1;
2579  }
2580 }
2581 
2582 /* Split two temporary lists of modifiers */
2584 {
2585  FModifier *fcm1, *fcm2;
2586 
2587  /* if list1/2 is invalid... just skip */
2588  if (ELEM(NULL, list1, list2)) {
2589  return;
2590  }
2591  if (ELEM(NULL, list1->first, list2->first)) {
2592  return;
2593  }
2594 
2595  /* get endpoints */
2596  fcm1 = list1->last;
2597  fcm2 = list2->first;
2598 
2599  /* clear their links */
2600  fcm1->next = NULL;
2601  fcm2->prev = NULL;
2602 }
2603 
2604 /* ---------------------- */
2605 
2609  ListBase *modifiers,
2610  bAction *action,
2611  const float evaltime,
2612  NlaEvalSnapshot *r_snapshot)
2613 {
2614  FCurve *fcu;
2615 
2617 
2618  /* Evaluate modifiers which modify time to evaluate the base curves at. */
2619  FModifiersStackStorage storage;
2620  storage.modifier_count = BLI_listbase_count(modifiers);
2622  storage.buffer = alloca(storage.modifier_count * storage.size_per_modifier);
2623 
2624  const float modified_evaltime = evaluate_time_fmodifiers(
2625  &storage, modifiers, NULL, 0.0f, evaltime);
2626 
2627  for (fcu = action->curves.first; fcu; fcu = fcu->next) {
2628  if (!is_fcurve_evaluatable(fcu)) {
2629  continue;
2630  }
2631 
2633 
2634  /* Invalid path or property cannot be animated. */
2635  if (nec == NULL) {
2636  continue;
2637  }
2638 
2639  if (!nlaevalchan_validate_index_ex(nec, fcu->array_index)) {
2640  continue;
2641  }
2642 
2644 
2645  float value = evaluate_fcurve(fcu, modified_evaltime);
2646  evaluate_value_fmodifiers(&storage, modifiers, fcu, &value, evaltime);
2647  necs->values[fcu->array_index] = value;
2648 
2649  if (nec->mix_mode == NEC_MIX_QUATERNION) {
2650  BLI_bitmap_set_all(necs->blend_domain.ptr, true, 4);
2651  }
2652  else {
2654  }
2655  }
2656 }
2657 
2658 /* evaluate action-clip strip */
2659 static void nlastrip_evaluate_actionclip(const int evaluation_mode,
2660  PointerRNA *ptr,
2662  ListBase *modifiers,
2663  NlaEvalStrip *nes,
2664  NlaEvalSnapshot *snapshot)
2665 {
2666 
2667  NlaStrip *strip = nes->strip;
2668 
2669  /* sanity checks for action */
2670  if (strip == NULL) {
2671  return;
2672  }
2673 
2674  if (strip->act == NULL) {
2675  CLOG_ERROR(&LOG, "NLA-Strip Eval Error: Strip '%s' has no Action", strip->name);
2676  return;
2677  }
2678 
2679  ListBase tmp_modifiers = {NULL, NULL};
2680 
2681  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
2682  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
2683 
2684  switch (evaluation_mode) {
2685  case STRIP_EVAL_BLEND: {
2686 
2687  NlaEvalSnapshot strip_snapshot;
2688  nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
2689 
2691  ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
2693  channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
2694 
2695  nlaeval_snapshot_free_data(&strip_snapshot);
2696 
2697  break;
2698  }
2700 
2701  NlaEvalSnapshot strip_snapshot;
2702  nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
2703 
2705  ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
2707  channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
2708 
2709  nlaeval_snapshot_free_data(&strip_snapshot);
2710 
2711  break;
2712  }
2713  case STRIP_EVAL_NOBLEND: {
2715  ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, snapshot);
2716  break;
2717  }
2718  }
2719 
2720  /* unlink this strip's modifiers from the parent's modifiers again */
2721  nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
2722 }
2723 
2724 /* evaluate transition strip */
2725 static void nlastrip_evaluate_transition(const int evaluation_mode,
2726  PointerRNA *ptr,
2728  ListBase *modifiers,
2729  NlaEvalStrip *nes,
2730  NlaEvalSnapshot *snapshot,
2731  const AnimationEvalContext *anim_eval_context,
2732  const bool flush_to_original)
2733 {
2734  ListBase tmp_modifiers = {NULL, NULL};
2735  NlaEvalSnapshot snapshot1, snapshot2;
2736  NlaEvalStrip tmp_nes;
2737  NlaStrip *s1, *s2;
2738 
2739  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
2740  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
2741 
2742  /* get the two strips to operate on
2743  * - we use the endpoints of the strips directly flanking our strip
2744  * using these as the endpoints of the transition (destination and source)
2745  * - these should have already been determined to be valid...
2746  * - if this strip is being played in reverse, we need to swap these endpoints
2747  * otherwise they will be interpolated wrong
2748  */
2749  if (nes->strip->flag & NLASTRIP_FLAG_REVERSE) {
2750  s1 = nes->strip->next;
2751  s2 = nes->strip->prev;
2752  }
2753  else {
2754  s1 = nes->strip->prev;
2755  s2 = nes->strip->next;
2756  }
2757 
2758  switch (evaluation_mode) {
2759  case STRIP_EVAL_BLEND: {
2760 
2761  /* prepare template for 'evaluation strip'
2762  * - based on the transition strip's evaluation strip data
2763  * - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
2764  * - strip_time is the 'normalized' (i.e. in-strip) time for evaluation,
2765  * which doubles up as an additional weighting factor for the strip influences
2766  * which allows us to appear to be 'interpolating' between the two extremes
2767  */
2768  tmp_nes = *nes;
2769 
2770  /* evaluate these strips into a temp-buffer (tmp_channels) */
2771  /* FIXME: modifier evaluation here needs some work... */
2772  /* first strip */
2774  tmp_nes.strip = s1;
2775  tmp_nes.strip_time = s1->strip_time;
2776  nlaeval_snapshot_init(&snapshot1, channels, snapshot);
2778  channels,
2779  &tmp_modifiers,
2780  &tmp_nes,
2781  &snapshot1,
2782  anim_eval_context,
2783  flush_to_original);
2784 
2785  /* second strip */
2787  tmp_nes.strip = s2;
2788  tmp_nes.strip_time = s2->strip_time;
2789  nlaeval_snapshot_init(&snapshot2, channels, snapshot);
2791  channels,
2792  &tmp_modifiers,
2793  &tmp_nes,
2794  &snapshot2,
2795  anim_eval_context,
2796  flush_to_original);
2797 
2803  channels, &snapshot1, &snapshot2, NLASTRIP_MODE_REPLACE, nes->strip_time, snapshot);
2804 
2805  nlaeval_snapshot_free_data(&snapshot1);
2806  nlaeval_snapshot_free_data(&snapshot2);
2807 
2808  break;
2809  }
2811  /* No support for remapping values through a transition. Mark all channel values affected by
2812  * transition as non-remappable. */
2813  tmp_nes = *nes;
2814 
2815  /* Process first strip. */
2816  tmp_nes.strip = s1;
2817  tmp_nes.strip_time = s1->strip_time;
2818  nlaeval_snapshot_init(&snapshot1, channels, snapshot);
2820  ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context);
2821 
2822  /* Remove channel values affected by transition from the remap domain. */
2823  LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
2824  NlaEvalChannelSnapshot *necs = nlaeval_snapshot_get(&snapshot1, nec->index);
2825  if (necs == NULL) {
2826  continue;
2827  }
2828  NlaEvalChannelSnapshot *output_necs = nlaeval_snapshot_ensure_channel(snapshot, nec);
2829  for (int i = 0; i < necs->length; i++) {
2830  if (BLI_BITMAP_TEST_BOOL(necs->blend_domain.ptr, i)) {
2831  BLI_BITMAP_DISABLE(output_necs->remap_domain.ptr, i);
2832  }
2833  }
2834  }
2835 
2836  nlaeval_snapshot_free_data(&snapshot1);
2837 
2838  /* Process second strip. */
2839  tmp_nes.strip = s2;
2840  tmp_nes.strip_time = s2->strip_time;
2841  nlaeval_snapshot_init(&snapshot2, channels, snapshot);
2843  ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context);
2844 
2845  /* Remove channel values affected by transition from the remap domain. */
2846  LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
2847  NlaEvalChannelSnapshot *necs = nlaeval_snapshot_get(&snapshot2, nec->index);
2848  if (necs == NULL) {
2849  continue;
2850  }
2851  NlaEvalChannelSnapshot *output_necs = nlaeval_snapshot_ensure_channel(snapshot, nec);
2852  for (int i = 0; i < necs->length; i++) {
2853  if (BLI_BITMAP_TEST_BOOL(necs->blend_domain.ptr, i)) {
2854  BLI_BITMAP_DISABLE(output_necs->remap_domain.ptr, i);
2855  }
2856  }
2857  }
2858 
2859  nlaeval_snapshot_free_data(&snapshot2);
2860 
2861  break;
2862  }
2863  case STRIP_EVAL_NOBLEND: {
2864  BLI_assert(
2865  !"This case shouldn't occur. Transitions assumed to not reference other "
2866  "transitions. ");
2867  break;
2868  }
2869  }
2870 
2871  /* unlink this strip's modifiers from the parent's modifiers again */
2872  nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
2873 }
2874 
2875 /* evaluate meta-strip */
2876 static void nlastrip_evaluate_meta(const int evaluation_mode,
2877  PointerRNA *ptr,
2879  ListBase *modifiers,
2880  NlaEvalStrip *nes,
2881  NlaEvalSnapshot *snapshot,
2882  const AnimationEvalContext *anim_eval_context,
2883  const bool flush_to_original)
2884 {
2885  ListBase tmp_modifiers = {NULL, NULL};
2886  NlaStrip *strip = nes->strip;
2887  NlaEvalStrip *tmp_nes;
2888  float evaltime;
2889 
2890  /* meta-strip was calculated normally to have some time to be evaluated at
2891  * and here we 'look inside' the meta strip, treating it as a decorated window to
2892  * its child strips, which get evaluated as if they were some tracks on a strip
2893  * (but with some extra modifiers to apply).
2894  *
2895  * NOTE: keep this in sync with animsys_evaluate_nla()
2896  */
2897 
2898  /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
2899  nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
2900 
2901  /* find the child-strip to evaluate */
2902  evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
2903  AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context,
2904  evaltime);
2905  tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original);
2906 
2907  /* Assert currently supported modes. If new mode added, then assertion marks potentially missed
2908  * area.
2909  *
2910  * NOTE: In the future if support is ever added to metastrips to support nested tracks, then
2911  * STRIP_EVAL_BLEND and STRIP_EVAL_BLEND_GET_INVERTED_LOWER_SNAPSHOT cases are no longer
2912  * equivalent. The output of nlastrips_ctime_get_strip() may return a list of strips. The only
2913  * case difference should be the evaluation order.
2914  */
2915  BLI_assert(ELEM(evaluation_mode,
2919 
2920  /* directly evaluate child strip into accumulation buffer...
2921  * - there's no need to use a temporary buffer (as it causes issues [T40082])
2922  */
2923  if (tmp_nes) {
2924  nlastrip_evaluate(evaluation_mode,
2925  ptr,
2926  channels,
2927  &tmp_modifiers,
2928  tmp_nes,
2929  snapshot,
2930  &child_context,
2931  flush_to_original);
2932 
2933  /* free temp eval-strip */
2934  MEM_freeN(tmp_nes);
2935  }
2936 
2937  /* unlink this strip's modifiers from the parent's modifiers again */
2938  nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
2939 }
2940 
2941 void nlastrip_evaluate(const int evaluation_mode,
2942  PointerRNA *ptr,
2944  ListBase *modifiers,
2945  NlaEvalStrip *nes,
2946  NlaEvalSnapshot *snapshot,
2947  const AnimationEvalContext *anim_eval_context,
2948  const bool flush_to_original)
2949 {
2950  NlaStrip *strip = nes->strip;
2951 
2952  /* To prevent potential infinite recursion problems
2953  * (i.e. transition strip, beside meta strip containing a transition
2954  * several levels deep inside it),
2955  * we tag the current strip as being evaluated, and clear this when we leave.
2956  */
2957  /* TODO: be careful with this flag, since some edit tools may be running and have
2958  * set this while animation playback was running. */
2959  if (strip->flag & NLASTRIP_FLAG_EDIT_TOUCHED) {
2960  return;
2961  }
2962  strip->flag |= NLASTRIP_FLAG_EDIT_TOUCHED;
2963 
2964  /* actions to take depend on the type of strip */
2965  switch (strip->type) {
2966  case NLASTRIP_TYPE_CLIP: /* action-clip */
2967  nlastrip_evaluate_actionclip(evaluation_mode, ptr, channels, modifiers, nes, snapshot);
2968  break;
2969  case NLASTRIP_TYPE_TRANSITION: /* transition */
2970  nlastrip_evaluate_transition(evaluation_mode,
2971  ptr,
2972  channels,
2973  modifiers,
2974  nes,
2975  snapshot,
2976  anim_eval_context,
2977  flush_to_original);
2978  break;
2979  case NLASTRIP_TYPE_META: /* meta */
2980  nlastrip_evaluate_meta(evaluation_mode,
2981  ptr,
2982  channels,
2983  modifiers,
2984  nes,
2985  snapshot,
2986  anim_eval_context,
2987  flush_to_original);
2988  break;
2989 
2990  default: /* do nothing */
2991  break;
2992  }
2993 
2994  /* clear temp recursion safe-check */
2995  strip->flag &= ~NLASTRIP_FLAG_EDIT_TOUCHED;
2996 }
2997 
3000  ListBase *modifiers,
3001  NlaEvalStrip *nes,
3002  NlaEvalSnapshot *snapshot,
3003  const struct AnimationEvalContext *anim_eval_context,
3004  const bool flush_to_original)
3005 {
3007  ptr,
3008  channels,
3009  modifiers,
3010  nes,
3011  snapshot,
3012  anim_eval_context,
3013  flush_to_original);
3014 }
3015 
3017  PointerRNA *ptr,
3019  ListBase *modifiers,
3020  NlaEvalStrip *nes,
3021  NlaEvalSnapshot *snapshot,
3022  const struct AnimationEvalContext *anim_eval_context)
3023 {
3025  ptr,
3026  channels,
3027  modifiers,
3028  nes,
3029  snapshot,
3030  anim_eval_context,
3031  false);
3032 }
3033 
3036  ListBase *modifiers,
3037  NlaEvalStrip *nes,
3038  NlaEvalSnapshot *snapshot,
3039  const struct AnimationEvalContext *anim_eval_context)
3040 {
3042  STRIP_EVAL_NOBLEND, ptr, channels, modifiers, nes, snapshot, anim_eval_context, false);
3043 }
3044 
3047  NlaEvalSnapshot *snapshot,
3048  const bool flush_to_original)
3049 {
3050  /* sanity checks */
3051  if (channels == NULL) {
3052  return;
3053  }
3054 
3055  /* for each channel with accumulated values, write its value on the property it affects */
3056  LISTBASE_FOREACH (NlaEvalChannel *, nec, &channels->channels) {
3066  NlaEvalChannelSnapshot *nec_snapshot = nlaeval_snapshot_find_channel(snapshot, nec);
3067 
3068  PathResolvedRNA rna = {nec->key.ptr, nec->key.prop, -1};
3069 
3070  for (int i = 0; i < nec_snapshot->length; i++) {
3071  if (BLI_BITMAP_TEST(nec->domain.ptr, i)) {
3072  float value = nec_snapshot->values[i];
3073  if (nec->is_array) {
3074  rna.prop_index = i;
3075  }
3076  BKE_animsys_write_to_rna_path(&rna, value);
3077  if (flush_to_original) {
3078  animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
3079  }
3080  }
3081  }
3082  }
3083 }
3084 
3085 /* ---------------------- */
3086 
3089  bAction *act,
3090  GSet *touched_actions)
3091 {
3092  if (!BLI_gset_add(touched_actions, act)) {
3093  return;
3094  }
3095 
3096  LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
3097  /* check if this curve should be skipped */
3098  if (!is_fcurve_evaluatable(fcu)) {
3099  continue;
3100  }
3101 
3102  NlaEvalChannel *nec = nlaevalchan_verify(ptr, channels, fcu->rna_path);
3103 
3104  if (nec != NULL) {
3105  /* For quaternion properties, enable all sub-channels. */
3106  if (nec->mix_mode == NEC_MIX_QUATERNION) {
3107  BLI_bitmap_set_all(nec->domain.ptr, true, 4);
3108  continue;
3109  }
3110 
3111  int idx = nlaevalchan_validate_index(nec, fcu->array_index);
3112 
3113  if (idx >= 0) {
3114  BLI_BITMAP_ENABLE(nec->domain.ptr, idx);
3115  }
3116  }
3117  }
3118 }
3119 
3122  ListBase *strips,
3123  GSet *touched_actions)
3124 {
3125  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
3126  /* Check strip's action. */
3127  if (strip->act) {
3128  nla_eval_domain_action(ptr, channels, strip->act, touched_actions);
3129  }
3130 
3131  /* Check sub-strips (if meta-strips). */
3132  nla_eval_domain_strips(ptr, channels, &strip->strips, touched_actions);
3133  }
3134 }
3135 
3141 {
3142  GSet *touched_actions = BLI_gset_ptr_new(__func__);
3143 
3144  /* Include domain of Action Track. */
3145  if ((adt->flag & ADT_NLA_EDIT_ON) == 0) {
3146  if (adt->action) {
3147  nla_eval_domain_action(ptr, channels, adt->action, touched_actions);
3148  }
3149  }
3150  else if (adt->tmpact && (adt->flag & ADT_NLA_EVAL_UPPER_TRACKS)) {
3151  nla_eval_domain_action(ptr, channels, adt->tmpact, touched_actions);
3152  }
3153 
3154  /* NLA Data - Animation Data for Strips */
3155  LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
3156  /* solo and muting are mutually exclusive... */
3157  if (adt->flag & ADT_NLA_SOLO_TRACK) {
3158  /* skip if there is a solo track, but this isn't it */
3159  if ((nlt->flag & NLATRACK_SOLO) == 0) {
3160  continue;
3161  }
3162  /* else - mute doesn't matter */
3163  }
3164  else {
3165  /* no solo tracks - skip track if muted */
3166  if (nlt->flag & NLATRACK_MUTED) {
3167  continue;
3168  }
3169  }
3170 
3171  nla_eval_domain_strips(ptr, channels, &nlt->strips, touched_actions);
3172  }
3173 
3174  BLI_gset_free(touched_actions, NULL);
3175 }
3176 
3177 /* ---------------------- */
3178 
3183 static void animsys_create_tweak_strip(const AnimData *adt,
3184  const bool keyframing_to_strip,
3185  NlaStrip *r_tweak_strip)
3186 
3187 {
3188  /* Copy active strip so we can modify how it evaluates without affecting user data. */
3189  memcpy(r_tweak_strip, adt->actstrip, sizeof(NlaStrip));
3190  r_tweak_strip->next = r_tweak_strip->prev = NULL;
3191 
3192  /* If tweaked strip is syncing action length, then evaluate using action length. */
3193  if (r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
3195  }
3196 
3197  /* Strips with a user-defined time curve don't get properly remapped for editing
3198  * at the moment, so mapping them just for display may be confusing. */
3199  const bool is_inplace_tweak = !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
3201 
3202  if (!is_inplace_tweak) {
3203  /* Use Hold due to no proper remapping yet (the note above). */
3204  r_tweak_strip->extendmode = NLASTRIP_EXTEND_HOLD;
3205 
3206  /* Disable range. */
3207  r_tweak_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
3208  }
3209 
3211  if (keyframing_to_strip) {
3212  r_tweak_strip->extendmode = (is_inplace_tweak &&
3213  !(r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
3216  }
3217 }
3218 
3221  const bool keyframing_to_strip,
3222  NlaStrip *r_action_strip)
3223 {
3224  memset(r_action_strip, 0, sizeof(NlaStrip));
3225 
3226  bAction *action = adt->action;
3227 
3228  if (adt->flag & ADT_NLA_EDIT_ON) {
3229  action = adt->tmpact;
3230  }
3231 
3232  /* Set settings of dummy NLA strip from AnimData settings. */
3233  r_action_strip->act = action;
3234 
3235  /* Action range is calculated taking F-Modifiers into account
3236  * (which making new strips doesn't do due to the troublesome nature of that). */
3237  calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
3238  r_action_strip->start = r_action_strip->actstart;
3239  r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
3240  (r_action_strip->actstart + 1.0f) :
3241  (r_action_strip->actend);
3242 
3243  r_action_strip->blendmode = adt->act_blendmode;
3244  r_action_strip->extendmode = adt->act_extendmode;
3245  r_action_strip->influence = adt->act_influence;
3246 
3247  /* NOTE: must set this, or else the default setting overrides,
3248  * and this setting doesn't work. */
3249  r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
3250 
3251  /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range.
3252  * Extendmode Nothing and Hold will behave as normal. Hold Forward will behave just like Hold.
3253  */
3254  if (r_action_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
3255  r_action_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
3256  }
3257 
3258  const bool tweaking = (adt->flag & ADT_NLA_EDIT_ON) != 0;
3259  const bool soloing = (adt->flag & ADT_NLA_SOLO_TRACK) != 0;
3260  const bool eval_upper = !tweaking || (adt->flag & ADT_NLA_EVAL_UPPER_TRACKS) != 0;
3261  const bool actionstrip_evaluated = r_action_strip->act && !soloing && eval_upper;
3262  if (!actionstrip_evaluated) {
3263  r_action_strip->flag |= NLASTRIP_FLAG_MUTED;
3264  }
3265 
3267  if (keyframing_to_strip) {
3268  r_action_strip->extendmode = NLASTRIP_EXTEND_HOLD;
3269  }
3270 }
3271 
3272 static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
3273 {
3274  /* Skip disabled tracks unless it contains the tweaked strip. */
3275  const bool contains_tweak_strip = (adt->flag & ADT_NLA_EDIT_ON) && adt->act_track &&
3276  (nlt->index == adt->act_track->index);
3277  if ((nlt->flag & NLATRACK_DISABLED) && !contains_tweak_strip) {
3278  return false;
3279  }
3280 
3281  /* Solo and muting are mutually exclusive. */
3282  if (adt->flag & ADT_NLA_SOLO_TRACK) {
3283  /* Skip if there is a solo track, but this isn't it. */
3284  if ((nlt->flag & NLATRACK_SOLO) == 0) {
3285  return false;
3286  }
3287  }
3288  else {
3289  /* Skip track if muted. */
3290  if (nlt->flag & NLATRACK_MUTED) {
3291  return false;
3292  }
3293  }
3294 
3295  return true;
3296 }
3297 
3303  const bool any_strip_evaluated)
3304 {
3305  if (adt->action == NULL) {
3306  return false;
3307  }
3308 
3309  if (any_strip_evaluated) {
3310  return false;
3311  }
3312 
3314  if ((adt->flag & (ADT_NLA_SOLO_TRACK | ADT_NLA_EDIT_ON)) != 0) {
3315  return false;
3316  }
3317 
3319  return true;
3320 }
3321 
3331 {
3332  NlaTrack *nlt;
3333 
3334  if (adt == NULL) {
3335  return NULL;
3336  }
3337 
3338  /* Since the track itself gets disabled, we want the first disabled. */
3339  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
3340  if (nlt->flag & NLATRACK_DISABLED) {
3341  return nlt;
3342  }
3343  }
3344 
3345  return NULL;
3346 }
3347 
3353  PointerRNA *ptr,
3354  const AnimData *adt,
3355  const AnimationEvalContext *anim_eval_context,
3356  const bool flush_to_original)
3357 {
3358  NlaTrack *nlt;
3359  short track_index = 0;
3360  bool has_strips = false;
3361  ListBase estrips = {NULL, NULL};
3362  NlaEvalStrip *nes;
3363 
3364  NlaStrip tweak_strip;
3365 
3366  NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
3367 
3368  /* Get the stack of strips to evaluate at current time (influence calculated here). */
3369  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
3370 
3371  if (!is_nlatrack_evaluatable(adt, nlt)) {
3372  continue;
3373  }
3374 
3375  if (nlt->strips.first) {
3376  has_strips = true;
3377  }
3378 
3380  if (nlt == tweaked_track) {
3382  animsys_create_tweak_strip(adt, false, &tweak_strip);
3384  &estrips, &tweak_strip, anim_eval_context, flush_to_original);
3385  }
3386  else {
3388  &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
3389  }
3390  if (nes) {
3391  nes->track = nlt;
3392  }
3393  }
3394 
3395  if (is_action_track_evaluated_without_nla(adt, has_strips)) {
3396  BLI_freelistN(&estrips);
3397  return false;
3398  }
3399 
3400  NlaStrip action_strip = {0};
3401  animsys_create_action_track_strip(adt, false, &action_strip);
3402  nlastrips_ctime_get_strip_single(&estrips, &action_strip, anim_eval_context, flush_to_original);
3403 
3404  /* Per strip, evaluate and accumulate on top of existing channels. */
3405  for (nes = estrips.first; nes; nes = nes->next) {
3407  echannels,
3408  NULL,
3409  nes,
3410  &echannels->eval_snapshot,
3411  anim_eval_context,
3412  flush_to_original);
3413  }
3414 
3415  /* Free temporary evaluation data that's not used elsewhere. */
3416  BLI_freelistN(&estrips);
3417  return true;
3418 }
3419 
3422  const AnimData *adt,
3423  const AnimationEvalContext *anim_eval_context,
3424  NlaKeyframingContext *r_context)
3425 {
3426  if (!r_context) {
3427  return;
3428  }
3429 
3430  /* Early out. If NLA track is soloing and tweaked action isn't it, then don't allow keyframe
3431  * insertion. */
3432  if (adt->flag & ADT_NLA_SOLO_TRACK) {
3433  if (!(adt->act_track && (adt->act_track->flag & NLATRACK_SOLO))) {
3434  r_context->eval_strip = NULL;
3435  return;
3436  }
3437  }
3438 
3439  NlaTrack *nlt;
3440  short track_index = 0;
3441  bool has_strips = false;
3442 
3443  ListBase *upper_estrips = &r_context->upper_estrips;
3444  ListBase lower_estrips = {NULL, NULL};
3445  NlaEvalStrip *nes;
3446 
3447  NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
3448 
3449  /* Get the lower stack of strips to evaluate at current time (influence calculated here). */
3450  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
3451 
3452  if (!is_nlatrack_evaluatable(adt, nlt)) {
3453  continue;
3454  }
3455 
3456  /* Tweaked strip effect should not be stored in any snapshot. */
3457  if (nlt == tweaked_track) {
3458  break;
3459  }
3460 
3461  if (nlt->strips.first) {
3462  has_strips = true;
3463  }
3464 
3465  /* Get strip to evaluate for this channel. */
3467  &lower_estrips, &nlt->strips, track_index, anim_eval_context, false);
3468  if (nes) {
3469  nes->track = nlt;
3470  }
3471  }
3472 
3473  /* Get the upper stack of strips to evaluate at current time (influence calculated here).
3474  * Var nlt exists only if tweak strip exists. */
3475  if (nlt) {
3476 
3477  /* Skip tweaked strip. */
3478  nlt = nlt->next;
3479  track_index++;
3480 
3481  for (; nlt; nlt = nlt->next, track_index++) {
3482 
3483  if (!is_nlatrack_evaluatable(adt, nlt)) {
3484  continue;
3485  }
3486 
3487  if (nlt->strips.first) {
3488  has_strips = true;
3489  }
3490 
3491  /* Get strip to evaluate for this channel. */
3493  upper_estrips, &nlt->strips, track_index, anim_eval_context, false);
3494  }
3495  }
3496 
3501  if (is_action_track_evaluated_without_nla(adt, has_strips)) {
3502  BLI_freelistN(&lower_estrips);
3503  return;
3504  }
3505 
3506  /* Write r_context->eval_strip. */
3507  if (adt->flag & ADT_NLA_EDIT_ON) {
3508  /* Append action_track_strip to upper estrips. */
3509  NlaStrip *action_strip = &r_context->action_track_strip;
3510  animsys_create_action_track_strip(adt, false, action_strip);
3511  nlastrips_ctime_get_strip_single(upper_estrips, action_strip, anim_eval_context, false);
3512 
3513  NlaStrip *tweak_strip = &r_context->strip;
3514  animsys_create_tweak_strip(adt, true, tweak_strip);
3516  NULL, tweak_strip, anim_eval_context, false);
3517  }
3518  else {
3519 
3520  NlaStrip *action_strip = &r_context->strip;
3521  animsys_create_action_track_strip(adt, true, action_strip);
3523  NULL, action_strip, anim_eval_context, false);
3524  }
3525 
3526  /* If NULL, then keyframing will fail. No need to do any more processing. */
3527  if (!r_context->eval_strip) {
3528  BLI_freelistN(&lower_estrips);
3529  return;
3530  }
3531 
3532  /* If tweak strip is full REPLACE, then lower strips not needed. */
3533  if (r_context->strip.blendmode == NLASTRIP_MODE_REPLACE &&
3534  IS_EQF(r_context->strip.influence, 1.0f)) {
3535  BLI_freelistN(&lower_estrips);
3536  return;
3537  }
3538 
3539  /* For each strip, evaluate then accumulate on top of existing channels. */
3540  for (nes = lower_estrips.first; nes; nes = nes->next) {
3542  &r_context->lower_eval_data,
3543  NULL,
3544  nes,
3545  &r_context->lower_eval_data.eval_snapshot,
3546  anim_eval_context,
3547  false);
3548  }
3549 
3550  /* Free temporary evaluation data that's not used elsewhere. */
3551  BLI_freelistN(&lower_estrips);
3552 }
3553 
3554 /* NLA Evaluation function (mostly for use through do_animdata)
3555  * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into
3556  * some temp channels, where values can be accumulated in one go.
3557  */
3559  AnimData *adt,
3560  const AnimationEvalContext *anim_eval_context,
3561  const bool flush_to_original)
3562 {
3563  NlaEvalData echannels;
3564 
3565  nlaeval_init(&echannels);
3566 
3567  /* evaluate the NLA stack, obtaining a set of values to flush */
3568  if (animsys_evaluate_nla_for_flush(&echannels, ptr, adt, anim_eval_context, flush_to_original)) {
3569  /* reset any channels touched by currently inactive actions to default value */
3570  animsys_evaluate_nla_domain(ptr, &echannels, adt);
3571 
3572  /* flush effects of accumulating channels in NLA to the actual data they affect */
3573  nladata_flush_channels(ptr, &echannels, &echannels.eval_snapshot, flush_to_original);
3574  }
3575  else {
3576  /* special case - evaluate as if there isn't any NLA data */
3577  /* TODO: this is really just a stop-gap measure... */
3578  if (G.debug & G_DEBUG) {
3579  CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
3580  }
3581 
3582  animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original);
3583  }
3584 
3585  /* free temp data */
3586  nlaeval_free(&echannels);
3587 }
3588 
3589 /* ---------------------- */
3590 
3592 {
3593  for (int i = 0; i < snapshot->size; i++) {
3594  NlaEvalChannelSnapshot *necs = nlaeval_snapshot_get(snapshot, i);
3595  if (necs == NULL) {
3596  continue;
3597  }
3598 
3599  BLI_bitmap_set_all(necs->blend_domain.ptr, true, necs->length);
3600  }
3601 }
3602 
3604 {
3605  LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
3606  nlaeval_snapshot_ensure_channel(snapshot, nec);
3607  }
3608 }
3609 
3611  NlaEvalSnapshot *lower_snapshot,
3612  NlaEvalSnapshot *upper_snapshot,
3613  const short upper_blendmode,
3614  const float upper_influence,
3615  NlaEvalSnapshot *r_blended_snapshot)
3616 {
3617  nlaeval_snapshot_ensure_size(r_blended_snapshot, eval_data->num_channels);
3618 
3619  LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
3620  NlaEvalChannelSnapshot *upper_necs = nlaeval_snapshot_get(upper_snapshot, nec->index);
3621  NlaEvalChannelSnapshot *lower_necs = nlaeval_snapshot_get(lower_snapshot, nec->index);
3622  if (upper_necs == NULL && lower_necs == NULL) {
3623  continue;
3624  }
3625 
3627  if (lower_necs == NULL) {
3628  lower_necs = nlaeval_snapshot_find_channel(lower_snapshot->base, nec);
3629  }
3630 
3631  NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_blended_snapshot, nec);
3633  lower_necs, upper_necs, upper_blendmode, upper_influence, result_necs);
3634  }
3635 }
3636 
3638  NlaEvalSnapshot *lower_snapshot,
3639  NlaEvalSnapshot *blended_snapshot,
3640  const short upper_blendmode,
3641  const float upper_influence,
3642  NlaEvalSnapshot *r_upper_snapshot)
3643 {
3644  nlaeval_snapshot_ensure_size(r_upper_snapshot, eval_data->num_channels);
3645 
3646  LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
3647  NlaEvalChannelSnapshot *blended_necs = nlaeval_snapshot_get(blended_snapshot, nec->index);
3648  if (blended_necs == NULL) {
3651  continue;
3652  }
3653 
3654  NlaEvalChannelSnapshot *lower_necs = nlaeval_snapshot_get(lower_snapshot, nec->index);
3655  if (lower_necs == NULL) {
3656  lower_necs = nlaeval_snapshot_find_channel(lower_snapshot->base, nec);
3657  }
3658 
3659  NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_upper_snapshot, nec);
3661  lower_necs, blended_necs, upper_blendmode, upper_influence, result_necs);
3662  }
3663 }
3664 
3676  NlaEvalSnapshot *blended_snapshot,
3677  NlaEvalSnapshot *upper_snapshot,
3678  const short upper_blendmode,
3679  const float upper_influence,
3680  NlaEvalSnapshot *r_lower_snapshot)
3681 {
3682  nlaeval_snapshot_ensure_size(r_lower_snapshot, eval_data->num_channels);
3683 
3684  LISTBASE_FOREACH (NlaEvalChannel *, nec, &eval_data->channels) {
3685  NlaEvalChannelSnapshot *blended_necs = nlaeval_snapshot_get(blended_snapshot, nec->index);
3686  if (blended_necs == NULL) {
3687  /* We assume the caller only wants a subset of channels to be inverted, those that exist
3688  * within \a blended_snapshot. */
3689  continue;
3690  }
3691 
3692  NlaEvalChannelSnapshot *upper_necs = nlaeval_snapshot_get(upper_snapshot, nec->index);
3693  NlaEvalChannelSnapshot *result_necs = nlaeval_snapshot_ensure_channel(r_lower_snapshot, nec);
3694 
3696  blended_necs, upper_necs, upper_blendmode, upper_influence, result_necs);
3697  }
3698 }
3699 
3700 /* ---------------------- */
3701 
3703  struct ListBase *cache,
3704  struct PointerRNA *ptr,
3705  struct AnimData *adt,
3706  const AnimationEvalContext *anim_eval_context)
3707 {
3708  /* No remapping needed if NLA is off or no action. */
3709  if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
3710  (adt->flag & ADT_NLA_EVAL_OFF)) {
3711  return NULL;
3712  }
3713 
3714  /* No remapping if editing an ordinary Replace action with full influence and upper tracks not
3715  * evaluated. */
3716  if (!(adt->flag & ADT_NLA_EDIT_ON) &&
3717  (adt->act_blendmode == NLASTRIP_MODE_REPLACE && adt->act_influence == 1.0f) &&
3718  (adt->flag & ADT_NLA_EVAL_UPPER_TRACKS) == 0) {
3719  return NULL;
3720  }
3721 
3722  /* Try to find a cached context. */
3723  NlaKeyframingContext *ctx = BLI_findptr(cache, adt, offsetof(NlaKeyframingContext, adt));
3724 
3725  if (ctx == NULL) {
3726  /* Allocate and evaluate a new context. */
3727  ctx = MEM_callocN(sizeof(*ctx), "NlaKeyframingContext");
3728  ctx->adt = adt;
3729 
3731  animsys_evaluate_nla_for_keyframing(ptr, adt, anim_eval_context, ctx);
3732 
3733  BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
3734  BLI_addtail(cache, ctx);
3735  }
3736 
3737  return ctx;
3738 }
3739 
3741  struct PointerRNA *prop_ptr,
3742  struct PropertyRNA *prop,
3743  float *values,
3744  int count,
3745  int index,
3746  const struct AnimationEvalContext *anim_eval_context,
3747  bool *r_force_all,
3748  BLI_bitmap *r_successful_remaps)
3749 {
3750  BLI_bitmap_set_all(r_successful_remaps, false, count);
3751 
3752  if (r_force_all != NULL) {
3753  *r_force_all = false;
3754  }
3755 
3756  BLI_bitmap *remap_domain = BLI_BITMAP_NEW(count, __func__);
3757  for (int i = 0; i < count; i++) {
3758  if (!ELEM(index, i, -1)) {
3759  continue;
3760  }
3761 
3762  BLI_BITMAP_ENABLE(remap_domain, i);
3763  }
3764 
3765  /* No context means no correction. */
3766  if (context == NULL || context->strip.act == NULL) {
3767  BLI_bitmap_copy_all(r_successful_remaps, remap_domain, count);
3768  MEM_freeN(remap_domain);
3769  return;
3770  }
3771 
3772  /* If the strip is not evaluated, it is the same as zero influence. */
3773  if (context->eval_strip == NULL) {
3774  MEM_freeN(remap_domain);
3775  return;
3776  }
3777 
3778  /* Full influence Replace strips also require no correction if there are no upper tracks
3779  * evaluating. */
3780  int blend_mode = context->strip.blendmode;
3781  float influence = context->strip.influence;
3782 
3783  if (blend_mode == NLASTRIP_MODE_REPLACE && influence == 1.0f &&
3784  BLI_listbase_is_empty(&context->upper_estrips)) {
3785  BLI_bitmap_copy_all(r_successful_remaps, remap_domain, count);
3786  MEM_freeN(remap_domain);
3787  return;
3788  }
3789 
3790  /* Zero influence is division by zero. */
3791  if (influence <= 0.0f) {
3792  MEM_freeN(remap_domain);
3793  return;
3794  }
3795 
3797  NlaEvalData *eval_data = &context->lower_eval_data;
3798  NlaEvalSnapshot blended_snapshot;
3799  nlaeval_snapshot_init(&blended_snapshot, eval_data, NULL);
3800 
3801  NlaEvalChannelKey key = {
3802  .ptr = *prop_ptr,
3803  .prop = prop,
3804  };
3805 
3806  NlaEvalChannel *nec = nlaevalchan_verify_key(eval_data, NULL, &key);
3807  BLI_assert(nec);
3808  if (nec->base_snapshot.length != count) {
3809  BLI_assert_msg(0, "invalid value count");
3810  nlaeval_snapshot_free_data(&blended_snapshot);
3811  MEM_freeN(remap_domain);
3812  return;
3813  }
3814 
3815  NlaEvalChannelSnapshot *blended_necs = nlaeval_snapshot_ensure_channel(&blended_snapshot, nec);
3816  memcpy(blended_necs->values, values, sizeof(float) * count);
3817 
3818  /* Force all channels to be remapped for quaternions in a Combine strip, otherwise it will
3819  * always fail. See nlaevalchan_combine_quaternion_handle_undefined_blend_values().
3820  */
3821  const bool can_force_all = r_force_all != NULL;
3822  if (blended_necs->channel->mix_mode == NEC_MIX_QUATERNION &&
3823  blend_mode == NLASTRIP_MODE_COMBINE && can_force_all) {
3824 
3825  *r_force_all = true;
3826  index = -1;
3827  BLI_bitmap_set_all(remap_domain, true, 4);
3828  }
3829 
3830  BLI_bitmap_copy_all(blended_necs->remap_domain.ptr, remap_domain, count);
3831 
3832  /* Need to send id_ptr instead of prop_ptr so fcurve RNA paths resolve properly. */
3833  PointerRNA id_ptr;
3834  RNA_id_pointer_create(prop_ptr->owner_id, &id_ptr);
3835 
3836  /* Per iteration, remove effect of upper strip which gives output of nla stack below it. */
3837  LISTBASE_FOREACH_BACKWARD (NlaEvalStrip *, nes, &context->upper_estrips) {
3838  /* This will disable blended_necs->remap_domain bits if an upper strip is not invertible
3839  * (full replace, multiply zero, or transition). Then there is no remap solution. */
3841  &id_ptr, eval_data, NULL, nes, &blended_snapshot, anim_eval_context);
3842  }
3843 
3846  &context->lower_eval_data.eval_snapshot,
3847  &blended_snapshot,
3848  blend_mode,
3849  influence,
3850  &blended_snapshot);
3851 
3852  /* Write results into \a values for successfully remapped values. */
3853  for (int i = 0; i < count; i++) {
3854  if (!BLI_BITMAP_TEST_BOOL(blended_necs->remap_domain.ptr, i)) {
3855  continue;
3856  }
3857  values[i] = blended_necs->values[i];
3858  }
3859 
3860  BLI_bitmap_copy_all(r_successful_remaps, blended_necs->remap_domain.ptr, blended_necs->length);
3861 
3862  nlaeval_snapshot_free_data(&blended_snapshot);
3863  MEM_freeN(remap_domain);
3864 }
3865 
3867 {
3868  LISTBASE_FOREACH (NlaKeyframingContext *, ctx, cache) {
3869  MEM_SAFE_FREE(ctx->eval_strip);
3870  BLI_freelistN(&ctx->upper_estrips);
3871  nlaeval_free(&ctx->lower_eval_data);
3872  }
3873 
3874  BLI_freelistN(cache);
3875 }
3876 
3877 /* ***************************************** */
3878 /* Overrides System - Public API */
3879 
3880 /* Evaluate Overrides */
3882 {
3883  AnimOverride *aor;
3884 
3885  /* for each override, simply execute... */
3886  for (aor = adt->overrides.first; aor; aor = aor->next) {
3887  PathResolvedRNA anim_rna;
3888  if (BKE_animsys_rna_path_resolve(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
3889  BKE_animsys_write_to_rna_path(&anim_rna, aor->value);
3890  }
3891  }
3892 }
3893 
3894 /* ***************************************** */
3895 /* Evaluation System - Public API */
3896 
3897 /* Overview of how this system works:
3898  * 1) Depsgraph sorts data as necessary, so that data is in an order that means
3899  * that all dependencies are resolved before dependents.
3900  * 2) All normal animation is evaluated, so that drivers have some basis values to
3901  * work with
3902  * a. NLA stacks are done first, as the Active Actions act as 'tweaking' tracks
3903  * which modify the effects of the NLA-stacks
3904  * b. Active Action is evaluated as per normal, on top of the results of the NLA tracks
3905  *
3906  * --------------< often in a separate phase... >------------------
3907  *
3908  * 3) Drivers/expressions are evaluated on top of this, in an order where dependencies are
3909  * resolved nicely.
3910  * NOTE: it may be necessary to have some tools to handle the cases where some higher-level
3911  * drivers are added and cause some problematic dependencies that
3912  * didn't exist in the local levels...
3913  *
3914  * --------------< always executed >------------------
3915  *
3916  * Maintenance of editability of settings (XXX):
3917  * - In order to ensure that settings that are animated can still be manipulated in the UI without
3918  * requiring that keyframes are added to prevent these values from being overwritten,
3919  * we use 'overrides'.
3920  *
3921  * Unresolved things:
3922  * - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids
3923  * or nodal system? but stored where?
3924  * - Multiple-block dependencies
3925  * (i.e. drivers for settings are in both local and higher levels) -> split into separate lists?
3926  *
3927  * Current Status:
3928  * - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides.
3929  * However, the code for this is relatively harmless, so is left in the code for now.
3930  */
3931 
3933  AnimData *adt,
3934  const AnimationEvalContext *anim_eval_context,
3935  eAnimData_Recalc recalc,
3936  const bool flush_to_original)
3937 {
3938  PointerRNA id_ptr;
3939 
3940  /* sanity checks */
3941  if (ELEM(NULL, id, adt)) {
3942  return;
3943  }
3944 
3945  /* get pointer to ID-block for RNA to use */
3946  RNA_id_pointer_create(id, &id_ptr);
3947 
3948  /* recalculate keyframe data:
3949  * - NLA before Active Action, as Active Action behaves as 'tweaking track'
3950  * that overrides 'rough' work in NLA
3951  */
3952  /* TODO: need to double check that this all works correctly */
3953  if (recalc & ADT_RECALC_ANIM) {
3954  /* evaluate NLA data */
3955  if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF)) {
3956  /* evaluate NLA-stack
3957  * - active action is evaluated as part of the NLA stack as the last item
3958  */
3959  animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original);
3960  }
3961  /* evaluate Active Action only */
3962  else if (adt->action) {
3963  animsys_evaluate_action(&id_ptr, adt->action, anim_eval_context, flush_to_original);
3964  }
3965  }
3966 
3967  /* recalculate drivers
3968  * - Drivers need to be evaluated afterwards, as they can either override
3969  * or be layered on top of existing animation data.
3970  * - Drivers should be in the appropriate order to be evaluated without problems...
3971  */
3972  if (recalc & ADT_RECALC_DRIVERS) {
3973  animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context);
3974  }
3975 
3976  /* always execute 'overrides'
3977  * - Overrides allow editing, by overwriting the value(s) set from animation-data, with the
3978  * value last set by the user (and not keyframed yet).
3979  * - Overrides are cleared upon frame change and/or keyframing
3980  * - It is best that we execute this every time, so that no errors are likely to occur.
3981  */
3982  animsys_evaluate_overrides(&id_ptr, adt);
3983 }
3984 
3986 {
3987  ID *id;
3988 
3989  if (G.debug & G_DEBUG) {
3990  printf("Evaluate all animation - %f\n", ctime);
3991  }
3992 
3993  const bool flush_to_original = DEG_is_active(depsgraph);
3995  ctime);
3996 
3997  /* macros for less typing
3998  * - only evaluate animation data for id if it has users (and not just fake ones)
3999  * - whether animdata exists is checked for by the evaluation function, though taking
4000  * this outside of the function may make things slightly faster?
4001  */
4002 #define EVAL_ANIM_IDS(first, aflag) \
4003  for (id = first; id; id = id->next) { \
4004  if (ID_REAL_USERS(id) > 0) { \
4005  AnimData *adt = BKE_animdata_from_id(id); \
4006  BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
4007  } \
4008  } \
4009  (void)0
4010 
4011  /* another macro for the "embedded" nodetree cases
4012  * - this is like EVAL_ANIM_IDS, but this handles the case "embedded nodetrees"
4013  * (i.e. scene/material/texture->nodetree) which we need a special exception
4014  * for, otherwise they'd get skipped
4015  * - 'ntp' stands for "node tree parent" = data-block where node tree stuff resides
4016  */
4017 #define EVAL_ANIM_NODETREE_IDS(first, NtId_Type, aflag) \
4018  for (id = first; id; id = id->next) { \
4019  if (ID_REAL_USERS(id) > 0) { \
4020  AnimData *adt = BKE_animdata_from_id(id); \
4021  NtId_Type *ntp = (NtId_Type *)id; \
4022  if (ntp->nodetree) { \
4023  AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
4024  BKE_animsys_evaluate_animdata( \
4025  &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \
4026  } \
4027  BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
4028  } \
4029  } \
4030  (void)0
4031 
4032  /* optimization:
4033  * when there are no actions, don't go over database and loop over heaps of data-blocks,
4034  * which should ultimately be empty, since it is not possible for now to have any animation
4035  * without some actions, and drivers wouldn't get affected by any state changes
4036  *
4037  * however, if there are some curves, we will need to make sure that their 'ctime' property gets
4038  * set correctly, so this optimization must be skipped in that case...
4039  */
4040  if (BLI_listbase_is_empty(&main->actions) && BLI_listbase_is_empty(&main->curves)) {
4041  if (G.debug & G_DEBUG) {
4042  printf("\tNo Actions, so no animation needs to be evaluated...\n");
4043  }
4044 
4045  return;
4046  }
4047 
4048  /* nodes */
4049  EVAL_ANIM_IDS(main->nodetrees.first, ADT_RECALC_ANIM);
4050 
4051  /* textures */
4052  EVAL_ANIM_NODETREE_IDS(main->textures.first, Tex, ADT_RECALC_ANIM);
4053 
4054  /* lights */
4056 
4057  /* materials */
4059 
4060  /* cameras */
4061  EVAL_ANIM_IDS(main->cameras.first, ADT_RECALC_ANIM);
4062 
4063  /* shapekeys */
4064  EVAL_ANIM_IDS(main->shapekeys.first, ADT_RECALC_ANIM);
4065 
4066  /* metaballs */
4067  EVAL_ANIM_IDS(main->metaballs.first, ADT_RECALC_ANIM);
4068 
4069  /* curves */
4070  EVAL_ANIM_IDS(main->curves.first, ADT_RECALC_ANIM);
4071 
4072  /* armatures */
4073  EVAL_ANIM_IDS(main->armatures.first, ADT_RECALC_ANIM);
4074 
4075  /* lattices */
4076  EVAL_ANIM_IDS(main->lattices.first, ADT_RECALC_ANIM);
4077 
4078  /* meshes */
4079  EVAL_ANIM_IDS(main->meshes.first, ADT_RECALC_ANIM);
4080 
4081  /* particles */
4082  EVAL_ANIM_IDS(main->particles.first, ADT_RECALC_ANIM);
4083 
4084  /* speakers */
4085  EVAL_ANIM_IDS(main->speakers.first, ADT_RECALC_ANIM);
4086 
4087  /* movie clips */
4088  EVAL_ANIM_IDS(main->movieclips.first, ADT_RECALC_ANIM);
4089 
4090  /* linestyles */
4091  EVAL_ANIM_IDS(main->linestyles.first, ADT_RECALC_ANIM);
4092 
4093  /* grease pencil */
4094  EVAL_ANIM_IDS(main->gpencils.first, ADT_RECALC_ANIM);
4095 
4096  /* palettes */
4097  EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
4098 
4099  /* cache files */
4100  EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
4101 
4102  /* Hair Curves. */
4103  EVAL_ANIM_IDS(main->hair_curves.first, ADT_RECALC_ANIM);
4104 
4105  /* pointclouds */
4106  EVAL_ANIM_IDS(main->pointclouds.first, ADT_RECALC_ANIM);
4107 
4108  /* volumes */
4109  EVAL_ANIM_IDS(main->volumes.first, ADT_RECALC_ANIM);
4110 
4111  /* simulations */
4112  EVAL_ANIM_IDS(main->simulations.first, ADT_RECALC_ANIM);
4113 
4114  /* objects */
4115  /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
4116  * this tagged by Depsgraph on frame-change. This optimization means that objects
4117  * linked from other (not-visible) scenes will not need their data calculated.
4118  */
4119  EVAL_ANIM_IDS(main->objects.first, 0);
4120 
4121  /* masks */
4122  EVAL_ANIM_IDS(main->masks.first, ADT_RECALC_ANIM);
4123 
4124  /* worlds */
4126 
4127  /* scenes */
4129 }
4130 
4131 /* ***************************************** */
4132 
4133 /* ************** */
4134 /* Evaluation API */
4135 
4137 {
4138  float ctime = DEG_get_ctime(depsgraph);
4139  AnimData *adt = BKE_animdata_from_id(id);
4140  /* XXX: this is only needed for flushing RNA updates,
4141  * which should get handled as part of the dependency graph instead. */
4142  DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
4143  const bool flush_to_original = DEG_is_active(depsgraph);
4144 
4146  ctime);
4147  BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
4148 }
4149 
4151 {
4152  AnimData *adt = BKE_animdata_from_id(id);
4153 
4154  /* Runtime driver map to avoid O(n^2) lookups in BKE_animsys_eval_driver.
4155  * Ideally the depsgraph could pass a pointer to the COW driver directly,
4156  * but this is difficult in the current design. */
4157  if (adt && adt->drivers.first) {
4158  BLI_assert(!adt->driver_array);
4159 
4160  int num_drivers = BLI_listbase_count(&adt->drivers);
4161  adt->driver_array = MEM_mallocN(sizeof(FCurve *) * num_drivers, "adt->driver_array");
4162 
4163  int driver_index = 0;
4164  LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
4165  adt->driver_array[driver_index++] = fcu;
4166  }
4167  }
4168 }
4169 
4170 void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCurve *fcu_orig)
4171 {
4172  BLI_assert(fcu_orig != NULL);
4173 
4174  /* TODO(sergey): De-duplicate with BKE animsys. */
4175  PointerRNA id_ptr;
4176  bool ok = false;
4177 
4178  /* Lookup driver, accelerated with driver array map. */
4179  const AnimData *adt = BKE_animdata_from_id(id);
4180  FCurve *fcu;
4181 
4182  if (adt->driver_array) {
4183  fcu = adt->driver_array[driver_index];
4184  }
4185  else {
4186  fcu = BLI_findlink(&adt->drivers, driver_index);
4187  }
4188 
4190  depsgraph, __func__, id->name, id, "fcu", fcu->rna_path, fcu, fcu->array_index);
4191 
4192  RNA_id_pointer_create(id, &id_ptr);
4193 
4194  /* check if this driver's curve should be skipped */
4195  if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0) {
4196  /* check if driver itself is tagged for recalculation */
4197  /* XXX driver recalc flag is not set yet by depsgraph! */
4198  ChannelDriver *driver_orig = fcu_orig->driver;
4199  if ((driver_orig) && !(driver_orig->flag & DRIVER_FLAG_INVALID)) {
4200  /* evaluate this using values set already in other places
4201  * NOTE: for 'layering' option later on, we should check if we should remove old value before
4202  * adding new to only be done when drivers only changed */
4203  // printf("\told val = %f\n", fcu->curval);
4204 
4205  PathResolvedRNA anim_rna;
4206  if (BKE_animsys_rna_path_resolve(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
4207  /* Evaluate driver, and write results to COW-domain destination */
4208  const float ctime = DEG_get_ctime(depsgraph);
4209  const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
4210  depsgraph, ctime);
4211  const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context);
4212  ok = BKE_animsys_write_to_rna_path(&anim_rna, curval);
4213 
4214  /* Flush results & status codes to original data for UI (T59984) */
4215  if (ok && DEG_is_active(depsgraph)) {
4216  animsys_write_orig_anim_rna(&id_ptr, fcu->rna_path, fcu->array_index, curval);
4217 
4218  /* curval is displayed in the UI, and flag contains error-status codes */
4219  fcu_orig->curval = fcu->curval;
4220  driver_orig->curval = fcu->driver->curval;
4221  driver_orig->flag = fcu->driver->flag;
4222 
4223  DriverVar *dvar_orig = driver_orig->variables.first;
4224  DriverVar *dvar = fcu->driver->variables.first;
4225  for (; dvar_orig && dvar; dvar_orig = dvar_orig->next, dvar = dvar->next) {
4226  DriverTarget *dtar_orig = &dvar_orig->targets[0];
4227  DriverTarget *dtar = &dvar->targets[0];
4228  for (int i = 0; i < MAX_DRIVER_TARGETS; i++, dtar_orig++, dtar++) {
4229  dtar_orig->flag = dtar->flag;
4230  }
4231 
4232  dvar_orig->curval = dvar->curval;
4233  dvar_orig->flag = dvar->flag;
4234  }
4235  }
4236  }
4237 
4238  /* set error-flag if evaluation failed */
4239  if (ok == 0) {
4240  CLOG_WARN(&LOG, "invalid driver - %s[%d]", fcu->rna_path, fcu->array_index);
4241  driver_orig->flag |= DRIVER_FLAG_INVALID;
4242  }
4243  }
4244  }
4245 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers)
struct AnimData * BKE_animdata_from_id(const struct ID *id)
eAnimData_Recalc
Definition: BKE_animsys.h:288
@ ADT_RECALC_ANIM
Definition: BKE_animsys.h:290
@ ADT_RECALC_DRIVERS
Definition: BKE_animsys.h:289
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2135
float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, const struct AnimationEvalContext *anim_eval_context)
bool BKE_fcurve_is_empty(struct FCurve *fcu)
Definition: fcurve.c:2198
void evaluate_value_fmodifiers(FModifiersStackStorage *storage, ListBase *modifiers, struct FCurve *fcu, float *cvalue, float evaltime)
Definition: fmodifier.c:1452
float evaluate_time_fmodifiers(FModifiersStackStorage *storage, ListBase *modifiers, struct FCurve *fcu, float cvalue, float evaltime)
Definition: fmodifier.c:1395
uint evaluate_fmodifiers_storage_size_per_modifier(ListBase *modifiers)
Definition: fmodifier.c:1325
@ G_DEBUG
Definition: BKE_global.h:174
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag)
General operations, lookup, etc. for materials.
@ NLATIME_CONVERT_EVAL
Definition: BKE_nla.h:354
void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip)
Definition: nla.c:1435
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
#define BLI_BITMAP_DISABLE(_bitmap, _index)
Definition: BLI_bitmap.h:88
#define BLI_BITMAP_SIZE(_num)
Definition: BLI_bitmap.h:35
void BLI_bitmap_copy_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits)
Definition: bitmap.c:30
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition: BLI_bitmap.h:74
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
Definition: bitmap.c:17
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition: BLI_bitmap.h:102
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
#define ATTR_FALLTHROUGH
A dynamically sized string ADT.
struct GSet GSet
Definition: BLI_ghash.h:340
unsigned int BLI_ghashutil_ptrhash(const void *key)
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
GSet * BLI_gset_ptr_new(const char *info)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:689
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:771
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
Definition: BLI_listbase.h:348
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void pow_qt_fl_normalized(float q[4], float f)
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void invert_qt_normalized(float q[4])
float normalize_qt(float q[4])
void unit_qt(float q[4])
Definition: math_rotation.c:27
float normalize_qt_qt(float r[4], const float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
MINLINE void zero_v4(float r[4])
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define IS_EQF(a, b)
#define IN_RANGE_INCL(a, b, c)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1601
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
void DEG_debug_print_eval_subdata_index(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address, int subdata_index)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
void DEG_debug_print_eval_time(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, float time)
float DEG_get_ctime(const Depsgraph *graph)
@ AGRP_MUTED
#define MAX_DRIVER_TARGETS
@ NLASTRIP_FLAG_USR_INFLUENCE
@ NLASTRIP_FLAG_USR_TIME
@ NLASTRIP_FLAG_REVERSE
@ NLASTRIP_FLAG_MUTED
@ NLASTRIP_FLAG_USR_TIME_CYCLIC
@ NLASTRIP_FLAG_NO_TIME_MAP
@ NLASTRIP_FLAG_EDIT_TOUCHED
@ NLASTRIP_FLAG_SYNC_LENGTH
@ ADT_NLA_SOLO_TRACK
@ ADT_NLA_EVAL_OFF
@ ADT_NLA_EDIT_NOMAP
@ ADT_NLA_EVAL_UPPER_TRACKS
@ ADT_NLA_EDIT_ON
@ NLASTRIP_EXTEND_NOTHING
@ NLASTRIP_EXTEND_HOLD
@ NLASTRIP_MODE_REPLACE
@ NLASTRIP_MODE_ADD
@ NLASTRIP_MODE_SUBTRACT
@ NLASTRIP_MODE_COMBINE
@ NLASTRIP_MODE_MULTIPLY
@ DRIVER_FLAG_INVALID
@ NLASTRIP_TYPE_META
@ NLASTRIP_TYPE_TRANSITION
@ NLASTRIP_TYPE_CLIP
@ FCURVE_DISABLED
@ FCURVE_MUTED
@ NLATRACK_SOLO
@ NLATRACK_MUTED
@ NLATRACK_DISABLED
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_BOOLEAN
Definition: RNA_types.h:59
@ PROP_ENUM
Definition: RNA_types.h:63
@ PROP_INT
Definition: RNA_types.h:60
@ PROP_PROPORTIONAL
Definition: RNA_types.h:223
PropertySubType
Definition: RNA_types.h:125
@ PROP_AXISANGLE
Definition: RNA_types.h:161
@ PROP_QUATERNION
Definition: RNA_types.h:160
static void nlaeval_init(NlaEvalData *nlaeval)
Definition: anim_sys.c:1312
void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
Definition: anim_sys.c:3866
static float nla_combine_value(const int mix_mode, float base_value, const float lower_value, const float strip_value, const float influence)
Definition: anim_sys.c:1800
static bool nla_combine_get_inverted_lower_value(const int mix_mode, float base_value, const float strip_value, const float blended_value, const float influence, float *r_lower_value)
Definition: anim_sys.c:1672
static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, const AnimationEvalContext *anim_eval_context, bool flush_to_original)
Definition: anim_sys.c:588
void nlasnapshot_enable_all_blend_domain(NlaEvalSnapshot *snapshot)
Definition: anim_sys.c:3591
void BKE_animsys_evaluate_animdata(ID *id, AnimData *adt, const AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, const bool flush_to_original)
Definition: anim_sys.c:3932
static void animsys_write_orig_anim_rna(PointerRNA *ptr, const char *rna_path, int array_index, float value)
Definition: anim_sys.c:567
static void nlastrip_evaluate_meta(const int evaluation_mode, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:2876
static void nlaevalchan_assert_blendOrcombine_compatible(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, NlaEvalChannelSnapshot *blended_necs)
Definition: anim_sys.c:1990
static bool is_action_track_evaluated_without_nla(const AnimData *adt, const bool any_strip_evaluated)
Definition: anim_sys.c:3302
static NlaEvalChannelSnapshot * nlaeval_snapshot_find_channel(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
Definition: anim_sys.c:1249
static NlaTrack * nlatrack_find_tweaked(const AnimData *adt)
Definition: anim_sys.c:3330
void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float ctime)
Definition: anim_sys.c:3985
void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
Definition: anim_sys.c:239
static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
Definition: anim_sys.c:3272
static void nlaevalchan_free_data(NlaEvalChannel *nec)
Definition: anim_sys.c:1306
static void nlavalidmask_free(NlaValidMask *mask)
Definition: anim_sys.c:1145
static void nlastrip_evaluate_transition(const int evaluation_mode, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:2725
void nlasnapshot_ensure_channels(NlaEvalData *eval_data, NlaEvalSnapshot *snapshot)
Definition: anim_sys.c:3603
static void animsys_create_action_track_strip(const AnimData *adt, const bool keyframing_to_strip, NlaStrip *r_action_strip)
Definition: anim_sys.c:3220
static void nlavalidmask_init(NlaValidMask *mask, int bits)
Definition: anim_sys.c:1134
static float nla_blend_value(const int blendmode, const float lower_value, const float strip_value, const float influence)
Definition: anim_sys.c:1761
static void nlaevalchan_combine_value_get_inverted_upper_evalchan(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *blended_necs, const float upper_influence, NlaEvalChannelSnapshot *r_upper_necs)
Definition: anim_sys.c:2261
bool BKE_animsys_rna_path_resolve(PointerRNA *ptr, const char *rna_path, const int array_index, PathResolvedRNA *r_result)
Definition: anim_sys.c:367
static NlaEvalChannelSnapshot * nlaeval_snapshot_get(NlaEvalSnapshot *snapshot, int index)
Definition: anim_sys.c:1221
static NlaEvalChannel * nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval, const char *path)
Definition: anim_sys.c:1525
void nlasnapshot_blend_strip_get_inverted_lower_snapshot(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const struct AnimationEvalContext *anim_eval_context)
Definition: anim_sys.c:3016
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:761
static NlaEvalStrip * nlastrips_ctime_get_strip_single(ListBase *dst_list, NlaStrip *single_strip, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:1118
static void nlaeval_fmodifiers_join_stacks(ListBase *result, ListBase *list1, ListBase *list2)
Definition: anim_sys.c:2550
void BKE_keyingset_free_path(KeyingSet *ks, KS_Path *ksp)
Definition: anim_sys.c:223
void nlasnapshot_blend(NlaEvalData *eval_data, NlaEvalSnapshot *lower_snapshot, NlaEvalSnapshot *upper_snapshot, const short upper_blendmode, const float upper_influence, NlaEvalSnapshot *r_blended_snapshot)
Definition: anim_sys.c:3610
static uint nlaevalchan_keyhash(const void *ptr)
Definition: anim_sys.c:1155
void nlasnapshot_blend_get_inverted_upper_snapshot(NlaEvalData *eval_data, NlaEvalSnapshot *lower_snapshot, NlaEvalSnapshot *blended_snapshot, const short upper_blendmode, const float upper_influence, NlaEvalSnapshot *r_upper_snapshot)
Definition: anim_sys.c:3637
void BKE_keyingsets_blend_read_expand(BlendExpander *expander, ListBase *list)
Definition: anim_sys.c:341
static void animsys_blend_in_fcurves(PointerRNA *ptr, ListBase *fcurves, const AnimationEvalContext *anim_eval_context, const float blend_factor)
Definition: anim_sys.c:685
static void nlaevalchan_combine_quaternion_get_inverted_upper_evalchan(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *blended_necs, const float upper_influence, NlaEvalChannelSnapshot *r_upper_necs)
Definition: anim_sys.c:2299
static void nlaevalchan_blendOrcombine_get_inverted_upper_evalchan(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *blended_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_upper_necs)
Definition: anim_sys.c:2331
void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
Definition: anim_sys.c:4136
static bool nla_combine_get_inverted_strip_value(const int mix_mode, float base_value, const float lower_value, const float blended_value, const float influence, float *r_strip_value)
Definition: anim_sys.c:1894
static void nlaevalchan_blend_value_get_inverted_upper_evalchan(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *blended_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_upper_necs)
Definition: anim_sys.c:2228
static NlaEvalChannel * nlaevalchan_verify_key(NlaEvalData *nlaeval, const char *path, NlaEvalChannelKey *key)
Definition: anim_sys.c:1474
static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
Definition: anim_sys.c:1376
static bool nlaevalchan_blendOrcombine_try_copy_to_lower(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_lower_necs)
Definition: anim_sys.c:2061
static void nlaevalchan_combine_value_get_inverted_lower_evalchan(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_lower_necs)
Definition: anim_sys.c:2418
static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_blended_necs)
Definition: anim_sys.c:2182
#define EVAL_ANIM_IDS(first, aflag)
static bool nlaevalchan_validate_index_ex(const NlaEvalChannel *nec, const int array_index)
Definition: anim_sys.c:1353
static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
Definition: anim_sys.c:3881
static int animsys_blend_fcurves_quaternion(PathResolvedRNA *anim_rna, FCurve *first_fcurve, const AnimationEvalContext *anim_eval_context, const float blend_factor)
Definition: anim_sys.c:663
static void nlaevalchan_blend_value(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_blended_necs)
Definition: anim_sys.c:2086
static void nlaevalchan_snapshot_copy(NlaEvalChannelSnapshot *dst, const NlaEvalChannelSnapshot *src)
Definition: anim_sys.c:1199
KS_Path * BKE_keyingset_find_path(KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int UNUSED(group_mode))
Definition: anim_sys.c:74
void BKE_keyingsets_blend_write(BlendWriter *writer, ListBase *list)
Definition: anim_sys.c:301
static void animsys_calculate_nla(PointerRNA *ptr, AnimData *adt, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:3558
bool BKE_animsys_read_from_rna_path(PathResolvedRNA *anim_rna, float *r_value)
Definition: anim_sys.c:416
void nlasnapshot_blend_get_inverted_lower_snapshot(NlaEvalData *eval_data, NlaEvalSnapshot *blended_snapshot, NlaEvalSnapshot *upper_snapshot, const short upper_blendmode, const float upper_influence, NlaEvalSnapshot *r_lower_snapshot)
Definition: anim_sys.c:3675
static bool is_fcurve_evaluatable(FCurve *fcu)
Definition: anim_sys.c:353
static bool nla_blend_get_inverted_lower_value(const int blendmode, const float strip_value, const float blended_value, const float influence, float *r_lower_value)
Definition: anim_sys.c:1574
static void nlaevalchan_blend_value_get_inverted_lower_evalchan(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_lower_necs)
Definition: anim_sys.c:2378
void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, const AnimationEvalContext *anim_eval_context)
Definition: anim_sys.c:856
NlaKeyframingContext * BKE_animsys_get_nla_keyframing_context(struct ListBase *cache, struct PointerRNA *ptr, struct AnimData *adt, const AnimationEvalContext *anim_eval_context)
Definition: anim_sys.c:3702
void animsys_evaluate_action(PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:888
static int nlaevalchan_validate_index(const NlaEvalChannel *nec, int index)
Definition: anim_sys.c:1341
static void nla_eval_domain_action(PointerRNA *ptr, NlaEvalData *channels, bAction *act, GSet *touched_actions)
Definition: anim_sys.c:3087
static bool nla_blend_get_inverted_strip_value(const int blendmode, const float lower_value, const float blended_value, const float influence, float *r_strip_value)
Definition: anim_sys.c:1830
NlaEvalStrip * nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short index, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:982
static void nlaeval_snapshot_ensure_size(NlaEvalSnapshot *snapshot, int size)
Definition: anim_sys.c:1227
void BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, float *values, int count, int index, const struct AnimationEvalContext *anim_eval_context, bool *r_force_all, BLI_bitmap *r_successful_remaps)
Definition: anim_sys.c:3740
void BKE_keyingsets_blend_read_data(BlendDataReader *reader, ListBase *list)
Definition: anim_sys.c:319
#define ANIMSYS_FLOAT_AS_BOOL(value)
Definition: anim_sys.c:414
void BKE_keyingset_free(KeyingSet *ks)
Definition: anim_sys.c:266
#define EVAL_ANIM_NODETREE_IDS(first, NtId_Type, aflag)
static void nlaevalchan_combine_quaternion_get_inverted_lower_evalchan(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_lower_necs)
Definition: anim_sys.c:2460
static void nla_combine_quaternion(const float lower_values[4], const float strip_values[4], const float influence, float r_blended_value[4])
Definition: anim_sys.c:1940
void BKE_animsys_update_driver_array(ID *id)
Definition: anim_sys.c:4150
void animsys_blend_in_action(PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context, const float blend_factor)
Definition: anim_sys.c:904
KeyingSet * BKE_keyingset_add(ListBase *list, const char idname[], const char name[], short flag, short keyingflag)
Definition: anim_sys.c:126
static NlaEvalChannelSnapshot * nlaeval_snapshot_ensure_channel(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
Definition: anim_sys.c:1265
static bool nla_combine_quaternion_get_inverted_strip_values(const float lower_values[4], const float blended_values[4], const float influence, float r_strip_values[4])
Definition: anim_sys.c:1955
static void nlaevalchan_combine_quaternion(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_blended_necs)
Definition: anim_sys.c:2149
static void nlaeval_snapshot_init(NlaEvalSnapshot *snapshot, NlaEvalData *nlaeval, NlaEvalSnapshot *base)
Definition: anim_sys.c:1210
static void nlaeval_snapshot_free_data(NlaEvalSnapshot *snapshot)
Definition: anim_sys.c:1285
static void nla_combine_quaternion_get_inverted_lower_values(const float strip_values[4], const float blended_values[4], const float influence, float r_lower_value[4])
Definition: anim_sys.c:1734
static void nlaevalchan_assert_nonNull(NlaEvalChannelSnapshot *necs)
Definition: anim_sys.c:1983
static void nlaeval_free(NlaEvalData *nlaeval)
Definition: anim_sys.c:1321
KS_Path * BKE_keyingset_add_path(KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
Definition: anim_sys.c:160
void nlastrip_evaluate(const int evaluation_mode, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:2941
static void nlaevalchan_assert_blendOrcombine_compatible_quaternion(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, NlaEvalChannelSnapshot *blended_necs)
Definition: anim_sys.c:2021
static NlaEvalChannelSnapshot ** nlaeval_snapshot_ensure_slot(NlaEvalSnapshot *snapshot, NlaEvalChannel *nec)
Definition: anim_sys.c:1241
static CLG_LogRef LOG
Definition: anim_sys.c:67
static float nlastrip_get_influence(NlaStrip *strip, float cframe)
Definition: anim_sys.c:917
static bool nlaevalchan_blendOrcombine_try_copy_from_lower(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_blended_necs)
Definition: anim_sys.c:2039
static int animsys_quaternion_evaluate_fcurves(PathResolvedRNA quat_rna, FCurve *first_fcurve, const AnimationEvalContext *anim_eval_context, float r_quaternion[4])
Definition: anim_sys.c:619
static bool animsys_evaluate_nla_for_flush(NlaEvalData *echannels, PointerRNA *ptr, const AnimData *adt, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:3352
static bool nlaevalchan_keycmp(const void *a, const void *b)
Definition: anim_sys.c:1162
static void nlasnapshot_from_action(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, bAction *action, const float evaltime, NlaEvalSnapshot *r_snapshot)
Definition: anim_sys.c:2607
void nlasnapshot_blend_strip_no_blend(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const struct AnimationEvalContext *anim_eval_context)
Definition: anim_sys.c:3034
void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCurve *fcu_orig)
Definition: anim_sys.c:4170
static bool nlaevalchan_combine_quaternion_handle_undefined_blend_values(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_or_lower_necs)
Definition: anim_sys.c:2007
void BKE_keyingsets_foreach_id(LibraryForeachIDData *data, const ListBase *keyingsets)
Definition: anim_sys.c:255
static void animsys_create_tweak_strip(const AnimData *adt, const bool keyframing_to_strip, NlaStrip *r_tweak_strip)
Definition: anim_sys.c:3183
static void nlaevalchan_snapshot_free(NlaEvalChannelSnapshot *nec_snapshot)
Definition: anim_sys.c:1189
void nladata_flush_channels(PointerRNA *ptr, NlaEvalData *channels, NlaEvalSnapshot *snapshot, const bool flush_to_original)
Definition: anim_sys.c:3045
static void action_idcode_patch_check(ID *id, bAction *act)
Definition: anim_sys.c:821
static void nlaeval_fmodifiers_split_stacks(ListBase *list1, ListBase *list2)
Definition: anim_sys.c:2583
static char nlaevalchan_detect_mix_mode(NlaEvalChannelKey *key, int length)
Definition: anim_sys.c:1457
static NlaEvalChannelSnapshot * nlaevalchan_snapshot_new(NlaEvalChannel *nec)
Definition: anim_sys.c:1173
static bool animsys_construct_orig_pointer_rna(const PointerRNA *ptr, PointerRNA *ptr_orig)
Definition: anim_sys.c:543
static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, const AnimationEvalContext *anim_eval_context)
Definition: anim_sys.c:778
static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels, AnimData *adt)
Definition: anim_sys.c:3140
static void animsys_evaluate_nla_for_keyframing(PointerRNA *ptr, const AnimData *adt, const AnimationEvalContext *anim_eval_context, NlaKeyframingContext *r_context)
Definition: anim_sys.c:3421
void nlasnapshot_blend_strip(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const struct AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:2998
static void nlaevalchan_combine_value(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, NlaEvalChannelSnapshot *r_blended_necs)
Definition: anim_sys.c:2116
static void nla_eval_domain_strips(PointerRNA *ptr, NlaEvalData *channels, ListBase *strips, GSet *touched_actions)
Definition: anim_sys.c:3120
static void nlastrip_evaluate_actionclip(const int evaluation_mode, PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot)
Definition: anim_sys.c:2659
static void nlaevalchan_blendOrCombine_get_inverted_lower_evalchan(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const int upper_blendmode, const float upper_influence, NlaEvalChannelSnapshot *r_lower_necs)
Definition: anim_sys.c:2503
static void nlastrip_evaluate_controls(NlaStrip *strip, const AnimationEvalContext *anim_eval_context, const bool flush_to_original)
Definition: anim_sys.c:938
AnimationEvalContext BKE_animsys_eval_context_construct_at(const AnimationEvalContext *anim_eval_context, float eval_time)
Definition: anim_sys.c:771
bool BKE_animsys_write_to_rna_path(PathResolvedRNA *anim_rna, const float value)
Definition: anim_sys.c:478
void BKE_keyingsets_free(ListBase *list)
Definition: anim_sys.c:282
void BKE_keyingsets_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *list)
Definition: anim_sys.c:332
static void nlaevalchan_copy_values(NlaEvalChannelSnapshot *dst, NlaEvalChannelSnapshot *src)
Definition: anim_sys.c:2030
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
int main(int argc, char *argv[])
#define A
float evaltime
Definition: bpy_driver.c:161
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define powf(x, y)
Definition: cuda/compat.h:103
const Depsgraph * depsgraph
SyclQueue void void * src
int count
#define GS(x)
Definition: iris.c:225
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:30
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define B
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned a[3]
Definition: RandGen.cpp:78
T length(const vec_base< T, Size > &a)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode)
Definition: nla.c:628
@ STRIP_EVAL_NOBLEND
Definition: nla_private.h:191
@ STRIP_EVAL_BLEND_GET_INVERTED_LOWER_SNAPSHOT
Definition: nla_private.h:185
@ STRIP_EVAL_BLEND
Definition: nla_private.h:183
struct NlaEvalChannelSnapshot NlaEvalChannelSnapshot
@ NEC_MIX_AXIS_ANGLE
Definition: nla_private.h:85
@ NEC_MIX_ADD
Definition: nla_private.h:82
@ NEC_MIX_MULTIPLY
Definition: nla_private.h:83
@ NEC_MIX_QUATERNION
Definition: nla_private.h:84
@ NES_TIME_TRANSITION_END
Definition: nla_private.h:44
@ NES_TIME_TRANSITION_START
Definition: nla_private.h:43
@ NES_TIME_AFTER
Definition: nla_private.h:40
@ NES_TIME_BEFORE
Definition: nla_private.h:38
@ NES_TIME_WITHIN
Definition: nla_private.h:39
#define hash
Definition: noise.c:153
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:3095
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
Definition: rna_access.c:2352
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2449
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
Definition: rna_access.c:1382
int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
Definition: rna_access.c:1365
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2581
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
Definition: rna_access.c:3036
bool RNA_property_animateable(const PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1993
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2954
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3421
bool RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
Definition: rna_access.c:2379
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, bool *values)
Definition: rna_access.c:2390
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
Definition: rna_access.c:2652
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
Definition: rna_access.c:3451
int RNA_property_flag(PropertyRNA *prop)
Definition: rna_access.c:1055
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2180
int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
Definition: rna_access.c:2678
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1075
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
Definition: rna_access.c:2707
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
PropertySubType RNA_property_subtype(PropertyRNA *prop)
Definition: rna_access.c:1015
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2275
float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
Definition: rna_access.c:3062
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_path.cc:531
bAction * action
short act_blendmode
NlaStrip * actstrip
ListBase overrides
float act_influence
FCurve ** driver_array
NlaTrack * act_track
bAction * tmpact
short act_extendmode
ListBase drivers
ListBase nla_tracks
struct AnimOverride * next
struct Depsgraph * depsgraph
Definition: BKE_animsys.h:42
ListBase variables
struct DriverVar * next
DriverTarget targets[8]
struct FCurve * next
bActionGroup * grp
float curval
char * rna_path
ChannelDriver * driver
int array_index
short flag
struct FModifier * next
struct FModifier * prev
Definition: DNA_ID.h:368
struct Library * lib
Definition: DNA_ID.h:372
struct ID * orig_id
Definition: DNA_ID.h:419
char name[66]
Definition: DNA_ID.h:378
struct KS_Path * next
short flag
char group[64]
int array_index
short groupmode
char * rna_path
char name[64]
char idname[64]
struct KeyingSet * next
ListBase paths
short keyingflag
short keyingoverride
ID id
Definition: DNA_ID.h:458
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
struct PropertyRNA * prop
Definition: nla_private.h:53
struct PointerRNA ptr
Definition: nla_private.h:52
NlaValidMask remap_domain
Definition: nla_private.h:71
NlaValidMask blend_domain
Definition: nla_private.h:67
struct NlaEvalChannel * channel
Definition: nla_private.h:64
struct NlaEvalData * owner
Definition: nla_private.h:92
NlaEvalChannelSnapshot base_snapshot
Definition: nla_private.h:106
const char * rna_path
Definition: nla_private.h:95
NlaEvalChannelKey key
Definition: nla_private.h:96
NlaValidMask domain
Definition: nla_private.h:103
NlaEvalSnapshot eval_snapshot
Definition: nla_private.h:132
GHash * path_hash
Definition: nla_private.h:124
NlaEvalSnapshot base_snapshot
Definition: nla_private.h:129
ListBase channels
Definition: nla_private.h:121
GHash * key_hash
Definition: nla_private.h:125
int num_channels
Definition: nla_private.h:128
struct NlaEvalSnapshot * base
Definition: nla_private.h:113
NlaEvalChannelSnapshot ** channels
Definition: nla_private.h:116
struct NlaEvalStrip * next
Definition: nla_private.h:24
NlaStrip * strip
Definition: nla_private.h:27
short track_index
Definition: nla_private.h:29
NlaTrack * track
Definition: nla_private.h:26
short strip_mode
Definition: nla_private.h:30
float strip_time
Definition: nla_private.h:32
NlaStrip action_track_strip
Definition: nla_private.h:146
struct AnimData * adt
Definition: nla_private.h:140
NlaEvalData lower_eval_data
Definition: nla_private.h:151
NlaEvalStrip * eval_strip
Definition: nla_private.h:144
float actstart
struct NlaStrip * next
short blendmode
float blendout
ListBase fcurves
char name[64]
float influence
ListBase strips
float actend
ListBase modifiers
struct NlaStrip * prev
float blendin
struct NlaStrip * orig_strip
short extendmode
bAction * act
float strip_time
ListBase strips
struct NlaTrack * next
BLI_bitmap * ptr
Definition: nla_private.h:58
struct PropertyRNA * prop
Definition: RNA_types.h:51
struct PointerRNA ptr
Definition: RNA_types.h:50
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
ListBase curves
PointerRNA * ptr
Definition: wm_files.c:3480