4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): Joshua Leung (full recode)
27 * ***** END GPL LICENSE BLOCK *****
30 /** \file blender/blenkernel/intern/fcurve.c
42 #include "MEM_guardedalloc.h"
44 #include "DNA_anim_types.h"
45 #include "DNA_constraint_types.h"
46 #include "DNA_object_types.h"
48 #include "BLI_blenlib.h"
50 #include "BLI_utildefines.h"
52 #include "BKE_fcurve.h"
53 #include "BKE_animsys.h"
54 #include "BKE_action.h"
55 #include "BKE_armature.h"
56 #include "BKE_constraint.h"
57 #include "BKE_curve.h"
58 #include "BKE_global.h"
59 #include "BKE_object.h"
60 #include "BKE_utildefines.h"
62 #include "RNA_access.h"
65 #include "BPY_extern.h"
68 #define SMALL -1.0e-10
71 /* ************************** Data-Level Functions ************************* */
73 /* ---------------------- Freeing --------------------------- */
75 /* Frees the F-Curve itself too, so make sure BLI_remlink is called before calling this... */
76 void free_fcurve (FCurve *fcu)
83 if (fcu->bezt) MEM_freeN(fcu->bezt);
84 if (fcu->fpt) MEM_freeN(fcu->fpt);
87 /* free RNA-path, as this were allocated when getting the path string */
89 MEM_freeN(fcu->rna_path);
91 /* free extra data - i.e. modifiers, and driver */
92 fcurve_free_driver(fcu);
93 free_fmodifiers(&fcu->modifiers);
95 /* free f-curve itself */
99 /* Frees a list of F-Curves */
100 void free_fcurves (ListBase *list)
108 /* free data - no need to call remlink before freeing each curve,
109 * as we store reference to next, and freeing only touches the curve
112 for (fcu= list->first; fcu; fcu= fcn) {
117 /* clear pointers just in case */
118 list->first= list->last= NULL;
121 /* ---------------------- Copy --------------------------- */
123 /* duplicate an F-Curve */
124 FCurve *copy_fcurve (FCurve *fcu)
133 fcu_d= MEM_dupallocN(fcu);
135 fcu_d->next= fcu_d->prev= NULL;
138 /* copy curve data */
139 fcu_d->bezt= MEM_dupallocN(fcu_d->bezt);
140 fcu_d->fpt= MEM_dupallocN(fcu_d->fpt);
143 fcu_d->rna_path= MEM_dupallocN(fcu_d->rna_path);
146 fcu_d->driver= fcurve_copy_driver(fcu_d->driver);
149 copy_fmodifiers(&fcu_d->modifiers, &fcu->modifiers);
151 /* return new data */
155 /* duplicate a list of F-Curves */
156 void copy_fcurves (ListBase *dst, ListBase *src)
161 if ELEM(NULL, dst, src)
164 /* clear destination list first */
165 dst->first= dst->last= NULL;
167 /* copy one-by-one */
168 for (sfcu= src->first; sfcu; sfcu= sfcu->next) {
169 dfcu= copy_fcurve(sfcu);
170 BLI_addtail(dst, dfcu);
174 /* ----------------- Finding F-Curves -------------------------- */
176 /* high level function to get an fcurve from C without having the rna */
177 FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *prop_name, int index, char *driven)
180 AnimData *adt= BKE_animdata_from_id(id);
191 /* only use the current action ??? */
192 if (ELEM(NULL, adt, adt->action))
195 RNA_pointer_create(id, type, data, &ptr);
196 prop = RNA_struct_find_property(&ptr, prop_name);
199 path= RNA_path_from_ID_to_property(&ptr, prop);
202 /* animation takes priority over drivers */
203 if ((adt->action) && (adt->action->curves.first))
204 fcu= list_find_fcurve(&adt->action->curves, path, index);
206 /* if not animated, check if driven */
207 if ((fcu == NULL) && (adt->drivers.first)) {
208 fcu= list_find_fcurve(&adt->drivers, path, index);
222 /* Find the F-Curve affecting the given RNA-access path + index, in the list of F-Curves provided */
223 FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array_index)
228 if ( ELEM(NULL, list, rna_path) || (array_index < 0) )
231 /* check paths of curves, then array indices... */
232 for (fcu= list->first; fcu; fcu= fcu->next) {
233 /* simple string-compare (this assumes that they have the same root...) */
234 if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
235 /* now check indices */
236 if (fcu->array_index == array_index)
245 /* quick way to loop over all fcurves of a given 'path' */
246 FCurve *iter_step_fcurve (FCurve *fcu_iter, const char rna_path[])
251 if (ELEM(NULL, fcu_iter, rna_path))
254 /* check paths of curves, then array indices... */
255 for (fcu= fcu_iter; fcu; fcu= fcu->next) {
256 /* simple string-compare (this assumes that they have the same root...) */
257 if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
266 /* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated
268 * - dst: list of LinkData's matching the criteria returned.
269 * List must be freed after use, and is assumed to be empty when passed.
270 * - src: list of F-Curves to search through
272 * - dataPrefix: i.e. 'pose.bones[' or 'nodes['
273 * - dataName: name of entity within "" immediately following the prefix
275 int list_find_data_fcurves (ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName)
281 if (ELEM4(NULL, dst, src, dataPrefix, dataName))
283 else if ((dataPrefix[0] == 0) || (dataName[0] == 0))
286 /* search each F-Curve one by one */
287 for (fcu= src->first; fcu; fcu= fcu->next) {
288 /* check if quoted string matches the path */
289 if ((fcu->rna_path) && strstr(fcu->rna_path, dataPrefix)) {
290 char *quotedName= BLI_getQuotedStr(fcu->rna_path, dataPrefix);
293 /* check if the quoted name matches the required name */
294 if (strcmp(quotedName, dataName) == 0) {
295 LinkData *ld= MEM_callocN(sizeof(LinkData), "list_find_data_fcurves");
298 BLI_addtail(dst, ld);
303 /* always free the quoted string, since it needs freeing */
304 MEM_freeN(quotedName);
309 /* return the number of matches */
313 FCurve *rna_get_fcurve (PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, int *driven)
319 /* there must be some RNA-pointer + property combon */
320 if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
321 AnimData *adt= BKE_animdata_from_id(ptr->id.data);
325 if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
326 /* XXX this function call can become a performance bottleneck */
327 path= RNA_path_from_ID_to_property(ptr, prop);
330 /* animation takes priority over drivers */
331 if (adt->action && adt->action->curves.first)
332 fcu= list_find_fcurve(&adt->action->curves, path, rnaindex);
334 /* if not animated, check if driven */
335 if (!fcu && (adt->drivers.first)) {
336 fcu= list_find_fcurve(&adt->drivers, path, rnaindex);
343 *action= adt->action;
354 /* ----------------- Finding Keyframes/Extents -------------------------- */
356 /* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
357 #define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
359 /* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
360 * Returns the index to insert at (data already at that index will be offset if replace is 0)
362 int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
364 int start=0, end=arraylen;
365 int loopbreaker= 0, maxloop= arraylen * 2;
367 /* initialise replace-flag first */
370 /* sneaky optimisations (don't go through searching process if...):
371 * - keyframe to be added is to be added out of current bounds
372 * - keyframe to be added would replace one of the existing ones on bounds
374 if ((arraylen <= 0) || (array == NULL)) {
375 printf("Warning: binarysearch_bezt_index() encountered invalid array \n");
379 /* check whether to add before/after/on */
382 /* 'First' Keyframe (when only one keyframe, this case is used) */
383 framenum= array[0].vec[1][0];
384 if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
388 else if (frame < framenum)
391 /* 'Last' Keyframe */
392 framenum= array[(arraylen-1)].vec[1][0];
393 if (IS_EQT(frame, framenum, BEZT_BINARYSEARCH_THRESH)) {
395 return (arraylen - 1);
397 else if (frame > framenum)
402 /* most of the time, this loop is just to find where to put it
403 * 'loopbreaker' is just here to prevent infinite loops
405 for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
406 /* compute and get midpoint */
407 int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
408 float midfra= array[mid].vec[1][0];
410 /* check if exactly equal to midpoint */
411 if (IS_EQT(frame, midfra, BEZT_BINARYSEARCH_THRESH)) {
416 /* repeat in upper/lower half */
419 else if (frame < midfra)
423 /* print error if loop-limit exceeded */
424 if (loopbreaker == (maxloop-1)) {
425 printf("Error: binarysearch_bezt_index() was taking too long \n");
427 // include debug info
428 printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
431 /* not found, so return where to place it */
435 /* ...................................... */
437 /* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
438 static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last, const short selOnly)
445 if (fcu->bezt == NULL)
448 /* only include selected items? */
453 /* find first selected */
455 for (i=0; i < fcu->totvert; bezt++, i++) {
456 if (BEZSELECTED(bezt)) {
462 /* find last selected */
463 bezt = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, sizeof(BezTriple), fcu->totvert);
464 for (i=0; i < fcu->totvert; bezt--, i++) {
465 if (BEZSELECTED(bezt)) {
472 /* just full array */
474 *last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, sizeof(BezTriple), fcu->totvert);
479 /* Calculate the extents of F-Curve's data */
480 void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly)
482 float xminv=999999999.0f, xmaxv=-999999999.0f;
483 float yminv=999999999.0f, ymaxv=-999999999.0f;
489 BezTriple *bezt_first= NULL, *bezt_last= NULL;
492 /* get endpoint keyframes */
493 get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
496 BLI_assert(bezt_last != NULL);
498 xminv= MIN2(xminv, bezt_first->vec[1][0]);
499 xmaxv= MAX2(xmaxv, bezt_last->vec[1][0]);
503 /* only loop over keyframes to find extents for values if needed */
507 for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
508 if ((selOnly == 0) || BEZSELECTED(bezt)) {
509 if (bezt->vec[1][1] < yminv)
510 yminv= bezt->vec[1][1];
511 if (bezt->vec[1][1] > ymaxv)
512 ymaxv= bezt->vec[1][1];
518 /* frame range can be directly calculated from end verts */
520 xminv= MIN2(xminv, fcu->fpt[0].vec[0]);
521 xmaxv= MAX2(xmaxv, fcu->fpt[fcu->totvert-1].vec[0]);
524 /* only loop over keyframes to find extents for values if needed */
528 for (fpt=fcu->fpt, i=0; i < fcu->totvert; fpt++, i++) {
529 if (fpt->vec[1] < yminv)
531 if (fpt->vec[1] > ymaxv)
541 if (xmin) *xmin= xminv;
542 if (xmax) *xmax= xmaxv;
544 if (ymin) *ymin= yminv;
545 if (ymax) *ymax= ymaxv;
549 printf("F-Curve calc bounds didn't find anything, so assuming minimum bounds of 1.0\n");
551 if (xmin) *xmin= 0.0f;
552 if (xmax) *xmax= 1.0f;
554 if (ymin) *ymin= 0.0f;
555 if (ymax) *ymax= 1.0f;
559 /* Calculate the extents of F-Curve's keyframes */
560 void calc_fcurve_range (FCurve *fcu, float *start, float *end, const short selOnly)
562 float min=999999999.0f, max=-999999999.0f;
567 BezTriple *bezt_first= NULL, *bezt_last= NULL;
569 /* get endpoint keyframes */
570 get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
573 BLI_assert(bezt_last != NULL);
575 min= MIN2(min, bezt_first->vec[1][0]);
576 max= MAX2(max, bezt_last->vec[1][0]);
580 min= MIN2(min, fcu->fpt[0].vec[0]);
581 max= MAX2(max, fcu->fpt[fcu->totvert-1].vec[0]);
587 /* minimum length is 1 frame */
589 if (min == max) max += 1.0f;
599 /* ----------------- Status Checks -------------------------- */
601 /* Are keyframes on F-Curve of any use?
602 * Usability of keyframes refers to whether they should be displayed,
603 * and also whether they will have any influence on the final result.
605 short fcurve_are_keyframes_usable (FCurve *fcu)
607 /* F-Curve must exist */
611 /* F-Curve must not have samples - samples are mutually exclusive of keyframes */
615 /* if it has modifiers, none of these should "drastically" alter the curve */
616 if (fcu->modifiers.first) {
619 /* check modifiers from last to first, as last will be more influential */
620 // TODO: optionally, only check modifier if it is the active one...
621 for (fcm = fcu->modifiers.last; fcm; fcm = fcm->prev) {
622 /* ignore if muted/disabled */
623 if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
628 /* clearly harmless - do nothing */
629 case FMODIFIER_TYPE_CYCLES:
630 case FMODIFIER_TYPE_STEPPED:
631 case FMODIFIER_TYPE_NOISE:
634 /* sometimes harmful - depending on whether they're "additive" or not */
635 case FMODIFIER_TYPE_GENERATOR:
637 FMod_Generator *data = (FMod_Generator *)fcm->data;
639 if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
643 case FMODIFIER_TYPE_FN_GENERATOR:
645 FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
647 if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
652 /* always harmful - cannot allow */
659 /* keyframes are usable */
663 /* Can keyframes be added to F-Curve?
664 * Keyframes can only be added if they are already visible
666 short fcurve_is_keyframable (FCurve *fcu)
668 /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */
669 if (fcurve_are_keyframes_usable(fcu) == 0)
672 /* F-Curve must currently be editable too */
673 if ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) )
676 /* F-Curve is keyframable */
680 /* ***************************** Keyframe Column Tools ********************************* */
682 /* add a BezTriple to a column */
683 void bezt_add_to_cfra_elem (ListBase *lb, BezTriple *bezt)
687 for (ce= lb->first; ce; ce= ce->next) {
689 if (ce->cfra == bezt->vec[1][0]) {
690 if (bezt->f2 & SELECT) ce->sel= bezt->f2;
693 /* should key be inserted before this column? */
694 else if (ce->cfra > bezt->vec[1][0]) break;
697 /* create a new column */
698 cen= MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
699 if (ce) BLI_insertlinkbefore(lb, ce, cen);
700 else BLI_addtail(lb, cen);
702 cen->cfra= bezt->vec[1][0];
706 /* ***************************** Samples Utilities ******************************* */
707 /* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as
708 * data imported from BVH/Mocap files), which are specialised for use with high density datasets,
709 * which BezTriples/Keyframe data are ill equipped to do.
713 /* Basic sampling callback which acts as a wrapper for evaluate_fcurve()
714 * 'data' arg here is unneeded here...
716 float fcurve_samplingcb_evalcurve (FCurve *fcu, void *UNUSED(data), float evaltime)
718 /* assume any interference from drivers on the curve is intended... */
719 return evaluate_fcurve(fcu, evaltime);
723 /* Main API function for creating a set of sampled curve data, given some callback function
724 * used to retrieve the values to store.
726 void fcurve_store_samples (FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb)
728 FPoint *fpt, *new_fpt;
732 // TODO: make these tests report errors using reports not printf's
733 if ELEM(NULL, fcu, sample_cb) {
734 printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
738 printf("Error: Frame range for Sampled F-Curve creation is inappropriate \n");
742 /* set up sample data */
743 fpt= new_fpt= MEM_callocN(sizeof(FPoint)*(end-start+1), "FPoint Samples");
745 /* use the sampling callback at 1-frame intervals from start to end frames */
746 for (cfra= start; cfra <= end; cfra++, fpt++) {
747 fpt->vec[0]= (float)cfra;
748 fpt->vec[1]= sample_cb(fcu, data, (float)cfra);
751 /* free any existing sample/keyframe data on curve */
752 if (fcu->bezt) MEM_freeN(fcu->bezt);
753 if (fcu->fpt) MEM_freeN(fcu->fpt);
755 /* store the samples */
758 fcu->totvert= end - start + 1;
761 /* ***************************** F-Curve Sanity ********************************* */
762 /* The functions here are used in various parts of Blender, usually after some editing
763 * of keyframe data has occurred. They ensure that keyframe data is properly ordered and
764 * that the handles are correctly
767 /* This function recalculates the handles of an F-Curve
768 * If the BezTriples have been rearranged, sort them first before using this.
770 void calchandles_fcurve (FCurve *fcu)
772 BezTriple *bezt, *prev, *next;
776 * - need at least two points
778 * - only bezier-interpolation has handles (for now)
780 if (ELEM(NULL, fcu, fcu->bezt) || (a < 2) /*|| ELEM(fcu->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN)*/)
783 /* get initial pointers */
788 /* loop over all beztriples, adjusting handles */
790 /* clamp timing of handles to be on either side of beztriple */
791 if (bezt->vec[0][0] > bezt->vec[1][0]) bezt->vec[0][0]= bezt->vec[1][0];
792 if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
794 /* calculate auto-handles */
795 if (fcu->flag & FCURVE_AUTO_HANDLES)
796 calchandleNurb(bezt, prev, next, 2); /* 2==special autohandle && keep extrema horizontal */
798 calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
800 /* for automatic ease in and out */
801 if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
802 /* only do this on first or last beztriple */
803 if ((a == 0) || (a == fcu->totvert-1)) {
804 /* set both handles to have same horizontal value as keyframe */
805 if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
806 bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
811 /* advance pointers for next iteration */
813 if (a == 1) next= NULL;
819 /* Use when F-Curve with handles has changed
820 * It treats all BezTriples with the following rules:
821 * - PHASE 1: do types have to be altered?
822 * -> Auto handles: become aligned when selection status is NOT(000 || 111)
823 * -> Vector handles: become 'nothing' when (one half selected AND other not)
824 * - PHASE 2: recalculate handles
826 void testhandles_fcurve (FCurve *fcu)
831 /* only beztriples have handles (bpoints don't though) */
832 if ELEM(NULL, fcu, fcu->bezt)
835 /* loop over beztriples */
836 for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
839 /* flag is initialised as selection status
840 * of beztriple control-points (labelled 0,1,2)
842 if (bezt->f1 & SELECT) flag |= (1<<0); // == 1
843 if (bezt->f2 & SELECT) flag |= (1<<1); // == 2
844 if (bezt->f3 & SELECT) flag |= (1<<2); // == 4
846 /* one or two handles selected only */
847 if (ELEM(flag, 0, 7)==0) {
848 /* auto handles become aligned */
849 if (bezt->h1==HD_AUTO)
851 if (bezt->h2==HD_AUTO)
854 /* vector handles become 'free' when only one half selected */
855 if (bezt->h1==HD_VECT) {
856 /* only left half (1 or 2 or 1+2) */
860 if (bezt->h2==HD_VECT) {
861 /* only right half (4 or 2+4) */
868 /* recalculate handles */
869 calchandles_fcurve(fcu);
872 /* This function sorts BezTriples so that they are arranged in chronological order,
873 * as tools working on F-Curves expect that the BezTriples are in order.
875 void sort_time_fcurve (FCurve *fcu)
879 /* keep adjusting order of beztriples until nothing moves (bubble-sort) */
883 /* currently, will only be needed when there are beztriples */
888 /* loop over ALL points to adjust position in array and recalculate handles */
889 for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
890 /* check if thee's a next beztriple which we could try to swap with current */
891 if (a < (fcu->totvert-1)) {
892 /* swap if one is after the other (and indicate that order has changed) */
893 if (bezt->vec[1][0] > (bezt+1)->vec[1][0]) {
894 SWAP(BezTriple, *bezt, *(bezt+1));
898 /* if either one of both of the points exceeds crosses over the keyframe time... */
899 if ( (bezt->vec[0][0] > bezt->vec[1][0]) && (bezt->vec[2][0] < bezt->vec[1][0]) ) {
900 /* swap handles if they have switched sides for some reason */
901 SWAP(float, bezt->vec[0][0], bezt->vec[2][0]);
902 SWAP(float, bezt->vec[0][1], bezt->vec[2][1]);
906 if (bezt->vec[0][0] > bezt->vec[1][0])
907 bezt->vec[0][0]= bezt->vec[1][0];
908 if (bezt->vec[2][0] < bezt->vec[1][0])
909 bezt->vec[2][0]= bezt->vec[1][0];
917 /* This function tests if any BezTriples are out of order, thus requiring a sort */
918 short test_time_fcurve (FCurve *fcu)
926 /* currently, only need to test beztriples */
930 /* loop through all BezTriples, stopping when one exceeds the one after it */
931 for (a=0, bezt= fcu->bezt; a < (fcu->totvert - 1); a++, bezt++) {
932 if (bezt->vec[1][0] > (bezt+1)->vec[1][0])
939 /* loop through all FPoints, stopping when one exceeds the one after it */
940 for (a=0, fpt= fcu->fpt; a < (fcu->totvert - 1); a++, fpt++) {
941 if (fpt->vec[0] > (fpt+1)->vec[0])
946 /* none need any swapping */
950 /* ***************************** Drivers ********************************* */
952 /* Driver Variables --------------------------- */
954 /* TypeInfo for Driver Variables (dvti) */
955 typedef struct DriverVarTypeInfo {
956 /* evaluation callback */
957 float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
959 /* allocation of target slots */
960 int num_targets; /* number of target slots required */
961 const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */
962 int target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */
965 /* Macro to begin definitions */
966 #define BEGIN_DVAR_TYPEDEF(type) \
969 /* Macro to end definitions */
970 #define END_DVAR_TYPEDEF \
975 static ID *dtar_id_ensure_proxy_from(ID *id)
977 if (id && GS(id->name)==ID_OB && ((Object *)id)->proxy_from)
978 return (ID *)(((Object *)id)->proxy_from);
982 /* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
983 static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
985 PointerRNA id_ptr, ptr;
992 if ELEM(NULL, driver, dtar)
995 id= dtar_id_ensure_proxy_from(dtar->id);
997 /* error check for missing pointer... */
998 // TODO: tag the specific target too as having issues
1000 printf("Error: driver has an invalid target to use \n");
1001 if (G.f & G_DEBUG) printf("\tpath = %s\n", dtar->rna_path);
1002 driver->flag |= DRIVER_FLAG_INVALID;
1006 /* get RNA-pointer for the ID-block given in target */
1007 RNA_id_pointer_create(id, &id_ptr);
1009 /* get property to read from, and get value as appropriate */
1010 if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
1011 if(RNA_property_array_check(&ptr, prop)) {
1013 if (index < RNA_property_array_length(&ptr, prop)) {
1014 switch (RNA_property_type(prop)) {
1016 value= (float)RNA_property_boolean_get_index(&ptr, prop, index);
1019 value= (float)RNA_property_int_get_index(&ptr, prop, index);
1022 value= RNA_property_float_get_index(&ptr, prop, index);
1031 switch (RNA_property_type(prop)) {
1033 value= (float)RNA_property_boolean_get(&ptr, prop);
1036 value= (float)RNA_property_int_get(&ptr, prop);
1039 value= RNA_property_float_get(&ptr, prop);
1042 value= (float)RNA_property_enum_get(&ptr, prop);
1052 printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, dtar->rna_path);
1054 driver->flag |= DRIVER_FLAG_INVALID;
1061 /* Helper function to obtain a pointer to a Pose Channel (for evaluating drivers) */
1062 static bPoseChannel *dtar_get_pchan_ptr (ChannelDriver *driver, DriverTarget *dtar)
1066 if ELEM(NULL, driver, dtar)
1069 id= dtar_id_ensure_proxy_from(dtar->id);
1071 /* check if the ID here is a valid object */
1072 if (id && GS(id->name)) {
1073 Object *ob= (Object *)id;
1075 /* get pose, and subsequently, posechannel */
1076 return get_pose_channel(ob->pose, dtar->pchan_name);
1079 /* cannot find a posechannel this way */
1086 /* evaluate 'single prop' driver variable */
1087 static float dvar_eval_singleProp (ChannelDriver *driver, DriverVar *dvar)
1089 /* just evaluate the first target slot */
1090 return dtar_get_prop_val(driver, &dvar->targets[0]);
1093 /* evaluate 'rotation difference' driver variable */
1094 static float dvar_eval_rotDiff (ChannelDriver *driver, DriverVar *dvar)
1096 bPoseChannel *pchan, *pchan2;
1097 float q1[4], q2[4], quat[4], angle;
1099 /* get pose channels, and check if we've got two */
1100 pchan= dtar_get_pchan_ptr(driver, &dvar->targets[0]);
1101 pchan2= dtar_get_pchan_ptr(driver, &dvar->targets[1]);
1103 if (ELEM(NULL, pchan, pchan2)) {
1104 /* disable this driver, since it doesn't work correctly... */
1105 driver->flag |= DRIVER_FLAG_INVALID;
1107 /* check what the error was */
1108 if ((pchan == NULL) && (pchan2 == NULL))
1109 printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid \n");
1110 else if (pchan == NULL)
1111 printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel \n");
1112 else if (pchan2 == NULL)
1113 printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel \n");
1119 /* use the final posed locations */
1120 mat4_to_quat(q1, pchan->pose_mat);
1121 mat4_to_quat(q2, pchan2->pose_mat);
1124 mul_qt_qtqt(quat, q1, q2);
1125 angle = 2.0f * (saacos(quat[0]));
1128 return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
1131 /* evaluate 'location difference' driver variable */
1132 // TODO: this needs to take into account space conversions...
1133 static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
1135 float loc1[3] = {0.0f,0.0f,0.0f};
1136 float loc2[3] = {0.0f,0.0f,0.0f};
1138 /* get two location values */
1139 // NOTE: for now, these are all just worldspace
1140 DRIVER_TARGETS_USED_LOOPER(dvar)
1142 /* get pointer to loc values to store in */
1143 Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
1144 bPoseChannel *pchan;
1147 /* check if this target has valid data */
1148 if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
1149 /* invalid target, so will not have enough targets */
1150 driver->flag |= DRIVER_FLAG_INVALID;
1154 /* try to get posechannel */
1155 pchan= get_pose_channel(ob->pose, dtar->pchan_name);
1157 /* check if object or bone */
1160 if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
1161 if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
1164 /* extract transform just like how the constraints do it! */
1165 copy_m4_m4(mat, pchan->pose_mat);
1166 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
1168 /* ... and from that, we get our transform */
1169 VECCOPY(tmp_loc, mat[3]);
1172 /* transform space (use transform values directly) */
1173 VECCOPY(tmp_loc, pchan->loc);
1177 /* convert to worldspace */
1178 VECCOPY(tmp_loc, pchan->pose_head);
1179 mul_m4_v3(ob->obmat, tmp_loc);
1184 if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
1185 if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
1186 // XXX: this should practically be the same as transform space...
1189 /* extract transform just like how the constraints do it! */
1190 copy_m4_m4(mat, ob->obmat);
1191 constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
1193 /* ... and from that, we get our transform */
1194 VECCOPY(tmp_loc, mat[3]);
1197 /* transform space (use transform values directly) */
1198 VECCOPY(tmp_loc, ob->loc);
1203 VECCOPY(tmp_loc, ob->obmat[3]);
1207 /* copy the location to the right place */
1209 VECCOPY(loc2, tmp_loc);
1212 VECCOPY(loc1, tmp_loc);
1215 DRIVER_TARGETS_LOOPER_END
1218 /* if we're still here, there should now be two targets to use,
1219 * so just take the length of the vector between these points
1221 return len_v3v3(loc1, loc2);
1224 /* evaluate 'transform channel' driver variable */
1225 static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
1227 DriverTarget *dtar= &dvar->targets[0];
1228 Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
1229 bPoseChannel *pchan;
1231 float oldEul[3] = {0.0f,0.0f,0.0f};
1232 short useEulers=0, rotOrder=ROT_MODE_EUL;
1234 /* check if this target has valid data */
1235 if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
1236 /* invalid target, so will not have enough targets */
1237 driver->flag |= DRIVER_FLAG_INVALID;
1241 /* try to get posechannel */
1242 pchan= get_pose_channel(ob->pose, dtar->pchan_name);
1244 /* check if object or bone, and get transform matrix accordingly
1245 * - "useEulers" code is used to prevent the problems associated with non-uniqueness
1246 * of euler decomposition from matrices [#20870]
1247 * - localspace is for [#21384], where parent results are not wanted
1248 * but local-consts is for all the common "corrective-shapes-for-limbs" situations
1252 if (pchan->rotmode > 0) {
1253 VECCOPY(oldEul, pchan->eul);
1254 rotOrder= pchan->rotmode;
1258 if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
1259 if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
1260 /* just like how the constraints do it! */
1261 copy_m4_m4(mat, pchan->pose_mat);
1262 constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
1265 /* specially calculate local matrix, since chan_mat is not valid
1266 * since it stores delta transform of pose_mat so that deforms work
1267 * so it cannot be used here for "transform" space
1269 pchan_to_mat4(pchan, mat);
1273 /* worldspace matrix */
1274 mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
1279 if (ob->rotmode > 0) {
1280 VECCOPY(oldEul, ob->rot);
1281 rotOrder= ob->rotmode;
1285 if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
1286 if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
1287 /* just like how the constraints do it! */
1288 copy_m4_m4(mat, ob->obmat);
1289 constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
1292 /* transforms to matrix */
1293 object_to_mat4(ob, mat);
1297 /* worldspace matrix - just the good-old one */
1298 copy_m4_m4(mat, ob->obmat);
1302 /* check which transform */
1303 if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
1304 /* not valid channel */
1307 else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) {
1308 /* extract scale, and choose the right axis */
1311 mat4_to_size(scale, mat);
1312 return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX];
1314 else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
1315 /* extract rotation as eulers (if needed)
1316 * - definitely if rotation order isn't eulers already
1317 * - if eulers, then we have 2 options:
1318 * a) decompose transform matrix as required, then try to make eulers from
1319 * there compatible with original values
1320 * b) [NOT USED] directly use the original values (no decomposition)
1321 * - only an option for "transform space", if quality is really bad with a)
1325 mat4_to_eulO(eul, rotOrder, mat);
1328 compatible_eul(eul, oldEul);
1331 return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
1334 /* extract location and choose right axis */
1335 return mat[3][dtar->transChan];
1341 /* Table of Driver Varaiable Type Info Data */
1342 static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
1343 BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP)
1344 dvar_eval_singleProp, /* eval callback */
1345 1, /* number of targets used */
1346 {"Property"}, /* UI names for targets */
1350 BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF)
1351 dvar_eval_rotDiff, /* eval callback */
1352 2, /* number of targets used */
1353 {"Bone 1", "Bone 2"}, /* UI names for targets */
1354 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1357 BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF)
1358 dvar_eval_locDiff, /* eval callback */
1359 2, /* number of targets used */
1360 {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
1361 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1364 BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN)
1365 dvar_eval_transChan, /* eval callback */
1366 1, /* number of targets used */
1367 {"Object/Bone"}, /* UI names for targets */
1368 {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */
1372 /* Get driver variable typeinfo */
1373 static DriverVarTypeInfo *get_dvar_typeinfo (int type)
1375 /* check if valid type */
1376 if ((type >= 0) && (type < MAX_DVAR_TYPES))
1377 return &dvar_types[type];
1382 /* Driver API --------------------------------- */
1384 /* This frees the driver variable itself */
1385 void driver_free_variable (ChannelDriver *driver, DriverVar *dvar)
1392 * - need to go over all of them, not just up to the ones that are used
1393 * currently, since there may be some lingering RNA paths from
1394 * previous users needing freeing
1396 DRIVER_TARGETS_LOOPER(dvar)
1398 /* free RNA path if applicable */
1400 MEM_freeN(dtar->rna_path);
1402 DRIVER_TARGETS_LOOPER_END
1404 /* remove the variable from the driver */
1406 BLI_freelinkN(&driver->variables, dvar);
1411 /* since driver variables are cached, the expression needs re-compiling too */
1412 if(driver->type==DRIVER_TYPE_PYTHON)
1413 driver->flag |= DRIVER_FLAG_RENAMEVAR;
1417 /* Change the type of driver variable */
1418 void driver_change_variable_type (DriverVar *dvar, int type)
1420 DriverVarTypeInfo *dvti= get_dvar_typeinfo(type);
1423 if (ELEM(NULL, dvar, dvti))
1426 /* set the new settings */
1428 dvar->num_targets= dvti->num_targets;
1430 /* make changes to the targets based on the defines for these types
1431 * NOTE: only need to make sure the ones we're using here are valid...
1433 DRIVER_TARGETS_USED_LOOPER(dvar)
1435 int flags = dvti->target_flags[tarIndex];
1437 /* store the flags */
1440 /* object ID types only, or idtype not yet initialised*/
1441 if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0))
1442 dtar->idtype= ID_OB;
1444 DRIVER_TARGETS_LOOPER_END
1447 /* Add a new driver variable */
1448 DriverVar *driver_add_new_variable (ChannelDriver *driver)
1456 /* make a new variable */
1457 dvar= MEM_callocN(sizeof(DriverVar), "DriverVar");
1458 BLI_addtail(&driver->variables, dvar);
1460 /* give the variable a 'unique' name */
1461 strcpy(dvar->name, "var");
1462 BLI_uniquename(&driver->variables, dvar, "var", '_', offsetof(DriverVar, name), sizeof(dvar->name));
1464 /* set the default type to 'single prop' */
1465 driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
1468 /* since driver variables are cached, the expression needs re-compiling too */
1469 if (driver->type==DRIVER_TYPE_PYTHON)
1470 driver->flag |= DRIVER_FLAG_RENAMEVAR;
1473 /* return the target */
1477 /* This frees the driver itself */
1478 void fcurve_free_driver(FCurve *fcu)
1480 ChannelDriver *driver;
1481 DriverVar *dvar, *dvarn;
1484 if ELEM(NULL, fcu, fcu->driver)
1486 driver= fcu->driver;
1488 /* free driver targets */
1489 for (dvar= driver->variables.first; dvar; dvar= dvarn) {
1491 driver_free_variable(driver, dvar);
1495 /* free compiled driver expression */
1496 if (driver->expr_comp)
1497 BPY_DECREF(driver->expr_comp);
1500 /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
1505 /* This makes a copy of the given driver */
1506 ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
1508 ChannelDriver *ndriver;
1516 ndriver= MEM_dupallocN(driver);
1517 ndriver->expr_comp= NULL;
1519 /* copy variables */
1520 ndriver->variables.first= ndriver->variables.last= NULL;
1521 BLI_duplicatelist(&ndriver->variables, &driver->variables);
1523 for (dvar= ndriver->variables.first; dvar; dvar= dvar->next) {
1524 /* need to go over all targets so that we don't leave any dangling paths */
1525 DRIVER_TARGETS_LOOPER(dvar)
1527 /* make a copy of target's rna path if available */
1529 dtar->rna_path = MEM_dupallocN(dtar->rna_path);
1531 DRIVER_TARGETS_LOOPER_END
1534 /* return the new driver */
1538 /* Driver Evaluation -------------------------- */
1540 /* Evaluate a Driver Variable to get a value that contributes to the final */
1541 float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
1543 DriverVarTypeInfo *dvti;
1546 if (ELEM(NULL, driver, dvar))
1549 /* call the relevant callbacks to get the variable value
1550 * using the variable type info, storing the obtained value
1551 * in dvar->curval so that drivers can be debugged
1553 dvti= get_dvar_typeinfo(dvar->type);
1555 if (dvti && dvti->get_value)
1556 dvar->curval= dvti->get_value(driver, dvar);
1560 return dvar->curval;
1563 /* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
1564 * - "evaltime" is the frame at which F-Curve is being evaluated
1565 * - has to return a float value
1567 static float evaluate_driver (ChannelDriver *driver, float UNUSED(evaltime))
1571 /* check if driver can be evaluated */
1572 if (driver->flag & DRIVER_FLAG_INVALID)
1575 switch (driver->type) {
1576 case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
1577 case DRIVER_TYPE_SUM: /* sum values of driver targets */
1579 /* check how many variables there are first (i.e. just one?) */
1580 if (driver->variables.first == driver->variables.last) {
1581 /* just one target, so just use that */
1582 dvar= driver->variables.first;
1583 driver->curval= driver_get_variable_value(driver, dvar);
1586 /* more than one target, so average the values of the targets */
1590 /* loop through targets, adding (hopefully we don't get any overflow!) */
1591 for (dvar= driver->variables.first; dvar; dvar=dvar->next) {
1592 value += driver_get_variable_value(driver, dvar);
1596 /* perform operations on the total if appropriate */
1597 if (driver->type == DRIVER_TYPE_AVERAGE)
1598 driver->curval= (value / (float)tot);
1600 driver->curval= value;
1605 case DRIVER_TYPE_MIN: /* smallest value */
1606 case DRIVER_TYPE_MAX: /* largest value */
1610 /* loop through the variables, getting the values and comparing them to existing ones */
1611 for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
1613 float tmp_val= driver_get_variable_value(driver, dvar);
1615 /* store this value if appropriate */
1617 /* check if greater/smaller than the baseline */
1618 if (driver->type == DRIVER_TYPE_MAX) {
1620 if (tmp_val > value)
1625 if (tmp_val < value)
1630 /* first item - make this the baseline for comparisons */
1635 /* store value in driver */
1636 driver->curval= value;
1640 case DRIVER_TYPE_PYTHON: /* expression */
1643 /* check for empty or invalid expression */
1644 if ( (driver->expression[0] == '\0') ||
1645 (driver->flag & DRIVER_FLAG_INVALID) )
1647 driver->curval= 0.0f;
1651 /* this evaluates the expression using Python,and returns its result:
1652 * - on errors it reports, then returns 0.0f
1654 driver->curval= BPY_driver_exec(driver);
1656 #endif /* WITH_PYTHON*/
1662 /* special 'hack' - just use stored value
1663 * This is currently used as the mechanism which allows animated settings to be able
1664 * to be changed via the UI.
1669 /* return value for driver */
1670 return driver->curval;
1673 /* ***************************** Curve Calculations ********************************* */
1675 /* The total length of the handles is not allowed to be more
1676 * than the horizontal distance between (v1-v4).
1677 * This is to prevent curve loops.
1679 void correct_bezpart (float *v1, float *v2, float *v3, float *v4)
1681 float h1[2], h2[2], len1, len2, len, fac;
1683 /* calculate handle deltas */
1684 h1[0]= v1[0] - v2[0];
1685 h1[1]= v1[1] - v2[1];
1687 h2[0]= v4[0] - v3[0];
1688 h2[1]= v4[1] - v3[1];
1690 /* calculate distances:
1691 * - len = span of time between keyframes
1692 * - len1 = length of handle of start key
1693 * - len2 = length of handle of end key
1696 len1= (float)fabs(h1[0]);
1697 len2= (float)fabs(h2[0]);
1699 /* if the handles have no length, no need to do any corrections */
1700 if ((len1+len2) == 0.0f)
1703 /* the two handles cross over each other, so force them
1704 * apart using the proportion they overlap
1706 if ((len1+len2) > len) {
1707 fac= len / (len1+len2);
1709 v2[0]= (v1[0] - fac*h1[0]);
1710 v2[1]= (v1[1] - fac*h1[1]);
1712 v3[0]= (v4[0] - fac*h2[0]);
1713 v3[1]= (v4[1] - fac*h2[1]);
1717 /* find root ('zero') */
1718 static int findzero (float x, float q0, float q1, float q2, float q3, float *o)
1720 double c0, c1, c2, c3, a, b, c, p, q, d, t, phi;
1724 c1= 3.0f * (q1 - q0);
1725 c2= 3.0f * (q0 - 2.0f*q1 + q2);
1726 c3= q3 - q0 + 3.0f * (q1 - q2);
1735 q= (2*a*a*a - a*b + c) / 2;
1740 o[0]= (float)(sqrt3d(-q+t) + sqrt3d(-q-t) - a);
1742 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) return 1;
1745 else if (d == 0.0) {
1747 o[0]= (float)(2*t - a);
1749 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) nr++;
1750 o[nr]= (float)(-t-a);
1752 if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) return nr+1;
1756 phi= acos(-q / sqrt(-(p*p*p)));
1760 o[0]= (float)(2*t*p - a);
1762 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) nr++;
1763 o[nr]= (float)(-t * (p + q) - a);
1765 if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) nr++;
1766 o[nr]= (float)(-t * (p - q) - a);
1768 if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) return nr+1;
1783 o[0]= (float)((-b-p) / (2 * a));
1785 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) nr++;
1786 o[nr]= (float)((-b+p)/(2*a));
1788 if ((o[nr] >= (float)SMALL) && (o[nr] <= 1.000001f)) return nr+1;
1792 o[0]= (float)(-b / (2 * a));
1793 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) return 1;
1797 else if (b != 0.0) {
1798 o[0]= (float)(-c/b);
1800 if ((o[0] >= (float)SMALL) && (o[0] <= 1.000001f)) return 1;
1803 else if (c == 0.0) {
1812 static void berekeny (float f1, float f2, float f3, float f4, float *o, int b)
1814 float t, c0, c1, c2, c3;
1818 c1= 3.0f * (f2 - f1);
1819 c2= 3.0f * (f1 - 2.0f*f2 + f3);
1820 c3= f4 - f1 + 3.0f * (f2 - f3);
1822 for (a=0; a < b; a++) {
1824 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
1829 static void berekenx (float *f, float *o, int b)
1831 float t, c0, c1, c2, c3;
1835 c1= 3.0f * (f[3] - f[0]);
1836 c2= 3.0f * (f[0] - 2.0f*f[3] + f[6]);
1837 c3= f[9] - f[0] + 3.0f * (f[3] - f[6]);
1839 for (a=0; a < b; a++) {
1841 o[a]= c0 + t*c1 + t*t*c2 + t*t*t*c3;
1847 /* -------------------------- */
1849 /* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
1850 static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltime)
1852 BezTriple *bezt, *prevbezt, *lastbezt;
1853 float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
1856 float cvalue = 0.0f;
1862 lastbezt= prevbezt + a;
1864 /* evaluation time at or past endpoints? */
1865 if (prevbezt->vec[1][0] >= evaltime)
1867 /* before or on first keyframe */
1868 if ( (fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST) &&
1869 !(fcu->flag & FCURVE_DISCRETE_VALUES) )
1871 /* linear or bezier interpolation */
1872 if (prevbezt->ipo==BEZT_IPO_LIN)
1874 /* Use the next center point instead of our own handle for
1875 * linear interpolated extrapolate
1877 if (fcu->totvert == 1)
1878 cvalue= prevbezt->vec[1][1];
1882 dx= prevbezt->vec[1][0] - evaltime;
1883 fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1885 /* prevent division by zero */
1887 fac= (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1888 cvalue= prevbezt->vec[1][1] - (fac * dx);
1891 cvalue= prevbezt->vec[1][1];
1896 /* Use the first handle (earlier) of first BezTriple to calculate the
1897 * gradient and thus the value of the curve at evaltime
1899 dx= prevbezt->vec[1][0] - evaltime;
1900 fac= prevbezt->vec[1][0] - prevbezt->vec[0][0];
1902 /* prevent division by zero */
1904 fac= (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
1905 cvalue= prevbezt->vec[1][1] - (fac * dx);
1908 cvalue= prevbezt->vec[1][1];
1913 /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
1914 * so just extend first keyframe's value
1916 cvalue= prevbezt->vec[1][1];
1919 else if (lastbezt->vec[1][0] <= evaltime)
1921 /* after or on last keyframe */
1922 if ( (fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST) &&
1923 !(fcu->flag & FCURVE_DISCRETE_VALUES) )
1925 /* linear or bezier interpolation */
1926 if (lastbezt->ipo==BEZT_IPO_LIN)
1928 /* Use the next center point instead of our own handle for
1929 * linear interpolated extrapolate
1931 if (fcu->totvert == 1)
1932 cvalue= lastbezt->vec[1][1];
1935 prevbezt = lastbezt - 1;
1936 dx= evaltime - lastbezt->vec[1][0];
1937 fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
1939 /* prevent division by zero */
1941 fac= (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
1942 cvalue= lastbezt->vec[1][1] + (fac * dx);
1945 cvalue= lastbezt->vec[1][1];
1950 /* Use the gradient of the second handle (later) of last BezTriple to calculate the
1951 * gradient and thus the value of the curve at evaltime
1953 dx= evaltime - lastbezt->vec[1][0];
1954 fac= lastbezt->vec[2][0] - lastbezt->vec[1][0];
1956 /* prevent division by zero */
1958 fac= (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
1959 cvalue= lastbezt->vec[1][1] + (fac * dx);
1962 cvalue= lastbezt->vec[1][1];
1967 /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
1968 * so just extend last keyframe's value
1970 cvalue= lastbezt->vec[1][1];
1975 /* evaltime occurs somewhere in the middle of the curve */
1976 for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++)
1978 /* use if the key is directly on the frame, rare cases this is needed else we get 0.0 instead. */
1979 if(fabs(bezt->vec[1][0] - evaltime) < SMALL_NUMBER) {
1980 cvalue= bezt->vec[1][1];
1982 /* evaltime occurs within the interval defined by these two keyframes */
1983 else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime))
1985 /* value depends on interpolation mode */
1986 if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES))
1988 /* constant (evaltime not relevant, so no interpolation needed) */
1989 cvalue= prevbezt->vec[1][1];
1991 else if (prevbezt->ipo == BEZT_IPO_LIN)
1993 /* linear - interpolate between values of the two keyframes */
1994 fac= bezt->vec[1][0] - prevbezt->vec[1][0];
1996 /* prevent division by zero */
1998 fac= (evaltime - prevbezt->vec[1][0]) / fac;
1999 cvalue= prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
2002 cvalue= prevbezt->vec[1][1];
2006 /* bezier interpolation */
2007 /* v1,v2 are the first keyframe and its 2nd handle */
2008 v1[0]= prevbezt->vec[1][0];
2009 v1[1]= prevbezt->vec[1][1];
2010 v2[0]= prevbezt->vec[2][0];
2011 v2[1]= prevbezt->vec[2][1];
2012 /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
2013 v3[0]= bezt->vec[0][0];
2014 v3[1]= bezt->vec[0][1];
2015 v4[0]= bezt->vec[1][0];
2016 v4[1]= bezt->vec[1][1];
2018 /* adjust handles so that they don't overlap (forming a loop) */
2019 correct_bezpart(v1, v2, v3, v4);
2021 /* try to get a value for this position - if failure, try another set of points */
2022 b= findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
2024 berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
2037 /* Calculate F-Curve value for 'evaltime' using FPoint samples */
2038 static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
2040 FPoint *prevfpt, *lastfpt, *fpt;
2045 lastfpt= prevfpt + fcu->totvert-1;
2047 /* evaluation time at or past endpoints? */
2048 if (prevfpt->vec[0] >= evaltime) {
2049 /* before or on first sample, so just extend value */
2050 cvalue= prevfpt->vec[1];
2052 else if (lastfpt->vec[0] <= evaltime) {
2053 /* after or on last sample, so just extend value */
2054 cvalue= lastfpt->vec[1];
2057 float t= (float)abs(evaltime - (int)evaltime);
2059 /* find the one on the right frame (assume that these are spaced on 1-frame intervals) */
2060 fpt= prevfpt + (int)(evaltime - prevfpt->vec[0]);
2062 /* if not exactly on the frame, perform linear interpolation with the next one */
2064 cvalue= interpf(fpt->vec[1], (fpt+1)->vec[1], t);
2066 cvalue= fpt->vec[1];
2073 /* ***************************** F-Curve - Evaluation ********************************* */
2075 /* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
2076 * Note: this is also used for drivers
2078 float evaluate_fcurve (FCurve *fcu, float evaltime)
2083 /* if there is a driver (only if this F-Curve is acting as 'driver'), evaluate it to find value to use as "evaltime"
2084 * since drivers essentially act as alternative input (i.e. in place of 'time') for F-Curves
2085 * - this value will also be returned as the value of the 'curve', if there are no keyframes
2088 /* evaltime now serves as input for the curve */
2089 evaltime= cvalue= evaluate_driver(fcu->driver, evaltime);
2092 /* evaluate modifiers which modify time to evaluate the base curve at */
2093 devaltime= evaluate_time_fmodifiers(&fcu->modifiers, fcu, cvalue, evaltime);
2095 /* evaluate curve-data
2096 * - 'devaltime' instead of 'evaltime', as this is the time that the last time-modifying
2097 * F-Curve modifier on the stack requested the curve to be evaluated at
2100 cvalue= fcurve_eval_keyframes(fcu, fcu->bezt, devaltime);
2102 cvalue= fcurve_eval_samples(fcu, fcu->fpt, devaltime);
2104 /* evaluate modifiers */
2105 evaluate_value_fmodifiers(&fcu->modifiers, fcu, &cvalue, evaltime);
2107 /* if curve can only have integral values, perform truncation (i.e. drop the decimal part)
2108 * here so that the curve can be sampled correctly
2110 if (fcu->flag & FCURVE_INT_VALUES)
2111 cvalue= floorf(cvalue + 0.5f);
2113 /* return evaluated value */
2117 /* Calculate the value of the given F-Curve at the given frame, and set its curval */
2118 void calculate_fcurve (FCurve *fcu, float ctime)
2120 /* only calculate + set curval (overriding the existing value) if curve has
2121 * any data which warrants this...
2123 if ( (fcu->totvert) || (fcu->driver && !(fcu->driver->flag & DRIVER_FLAG_INVALID)) ||
2124 list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) )
2126 /* calculate and set curval (evaluates driver too if necessary) */
2127 fcu->curval= evaluate_fcurve(fcu, ctime);