37
40
#include "DNA_anim_types.h"
42
#include "BLF_translation.h"
39
44
#include "BLI_blenlib.h"
40
45
#include "BLI_math.h" /* windows needs for M_PI */
46
#include "BLI_utildefines.h"
42
48
#include "BKE_fcurve.h"
43
49
#include "BKE_idprop.h"
44
#include "BKE_utildefines.h"
46
#ifndef DISABLE_PYTHON
47
#include "BPY_extern.h" /* for BPY_eval_driver() */
50
52
#define SMALL -1.0e-10
99
101
/* Generators available:
100
102
* 1) simple polynomial generator:
101
103
* - Exanded form - (y = C[0]*(x^(n)) + C[1]*(x^(n-1)) + ... + C[n])
102
* - Factorised form - (y = (C[0][0]*x + C[0][1]) * (C[1][0]*x + C[1][1]) * ... * (C[n][0]*x + C[n][1]))
104
* - Factorized form - (y = (C[0][0]*x + C[0][1]) * (C[1][0]*x + C[1][1]) * ... * (C[n][0]*x + C[n][1]))
105
107
static void fcm_generator_free (FModifier *fcm)
150
152
nc= MEM_callocN(sizeof(float)*(data->poly_order+1), "FMod_Generator_Coefs");
152
154
if (data->coefficients) {
153
if (data->arraysize > (data->poly_order+1))
155
if ((int)data->arraysize > (data->poly_order+1))
154
156
memcpy(nc, data->coefficients, sizeof(float)*(data->poly_order+1));
156
158
memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
176
178
nc= MEM_callocN(sizeof(float)*(data->poly_order*2), "FMod_Generator_Coefs");
178
180
if (data->coefficients) {
179
if (data->arraysize > (data->poly_order * 2))
181
if (data->arraysize > (unsigned int)(data->poly_order * 2))
180
182
memcpy(nc, data->coefficients, sizeof(float)*(data->poly_order * 2));
182
184
memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
197
static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
199
static void fcm_generator_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime)
199
201
FMod_Generator *data= (FMod_Generator *)fcm->data;
201
/* behaviour depends on mode
203
/* behavior depends on mode
202
204
* NOTE: the data in its default state is fine too
204
206
switch (data->mode) {
241
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */
243
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */
243
245
float value= 1.0f, *cp=NULL;
246
248
/* for each coefficient pair, solve for that bracket before accumulating in value by multiplying */
247
for (cp=data->coefficients, i=0; (cp) && (i < data->poly_order); cp+=2, i++)
249
for (cp=data->coefficients, i=0; (cp) && (i < (unsigned int)data->poly_order); cp+=2, i++)
248
250
value *= (cp[0]*evaltime + cp[1]);
250
252
/* only if something changed, write *cvalue in one go */
264
266
sizeof(FMod_Generator), /* size */
265
267
FMI_TYPE_GENERATE_CURVE, /* action type */
266
268
FMI_REQUIRES_NOTHING, /* requirements */
267
"Generator", /* name */
269
N_("Generator"), /* name */
268
270
"FMod_Generator", /* struct name */
269
271
fcm_generator_free, /* free data */
270
272
fcm_generator_copy, /* copy data */
307
309
return sin(M_PI * x) / (M_PI * x);
310
static void fcm_fn_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
312
static void fcm_fn_generator_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime)
312
314
FMod_FunctionGenerator *data= (FMod_FunctionGenerator *)fcm->data;
313
315
double arg= data->phase_multiplier*evaltime + data->phase_offset;
333
335
case FCM_GENERATOR_FN_TAN: /* tangent wave */
335
337
/* check that argument is not on one of the discontinuities (i.e. 90deg, 270 deg, etc) */
336
if IS_EQ(fmod((arg - M_PI_2), M_PI), 0.0) {
338
if (IS_EQ(fmod((arg - M_PI_2), M_PI), 0.0)) {
337
339
if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
338
340
*cvalue = 0.0f; /* no value possible here */
370
printf("Invalid Function-Generator for F-Modifier - %d \n", data->type);
372
printf("Invalid Function-Generator for F-Modifier - %d\n", data->type);
373
375
/* execute function callback to set value if appropriate */
375
float value= (float)(data->amplitude*fn(arg) + data->value_offset);
377
float value= (float)(data->amplitude*(float)fn(arg) + data->value_offset);
377
379
if (data->flag & FCM_GENERATOR_ADDITIVE)
378
380
*cvalue += value;
386
388
sizeof(FMod_FunctionGenerator), /* size */
387
389
FMI_TYPE_GENERATE_CURVE, /* action type */
388
390
FMI_REQUIRES_NOTHING, /* requirements */
389
"Built-In Function", /* name */
391
N_("Built-In Function"), /* name */
390
392
"FMod_FunctionGenerator", /* struct name */
391
393
NULL, /* free data */
392
394
NULL, /* copy data */
439
static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
441
static void fcm_envelope_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime)
441
443
FMod_Envelope *env= (FMod_Envelope *)fcm->data;
442
444
FCM_EnvelopeData *fed, *prevfed, *lastfed;
493
495
sizeof(FMod_Envelope), /* size */
494
496
FMI_TYPE_REPLACE_VALUES, /* action type */
495
497
0, /* requirements */
496
"Envelope", /* name */
498
N_("Envelope"), /* name */
497
499
"FMod_Envelope", /* struct name */
498
500
fcm_envelope_free, /* free data */
499
501
fcm_envelope_copy, /* copy data */
506
508
/* Cycles F-Curve Modifier --------------------------- */
508
510
/* This modifier changes evaltime to something that exists within the curve's frame-range,
509
* then re-evaluates modifier stack up to this point using the new time. This re-entrant behaviour
510
* is very likely to be more time-consuming than the original approach... (which was tighly integrated into
511
* then re-evaluates modifier stack up to this point using the new time. This re-entrant behavior
512
* is very likely to be more time-consuming than the original approach... (which was tightly integrated into
511
513
* the calculation code...).
513
* NOTE: this needs to be at the start of the stack to be of use, as it needs to know the extents of the keyframes/sample-data
514
* Possible TODO - store length of cycle information that can be initialised from the extents of the keyframes/sample-data, and adjusted
515
* NOTE: this needs to be at the start of the stack to be of use, as it needs to know the extents of the
516
* keyframes/sample-data.
518
* Possible TODO - store length of cycle information that can be initialized from the extents of the
519
* keyframes/sample-data, and adjusted as appropriate.
518
522
/* temp data used during evaluation */
528
532
data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
531
static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
535
static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float UNUSED(cvalue), float evaltime)
533
537
FMod_Cycles *data= (FMod_Cycles *)fcm->data;
534
538
float prevkey[2], lastkey[2], cycyofs=0.0f;
535
539
short side=0, mode=0;
538
542
/* check if modifier is first in stack, otherwise disable ourself... */
571
575
* 2) if before first frame or after last frame, make sure some cycling is in use
573
577
if (evaltime < prevkey[0]) {
574
if (data->before_mode) {
578
if (data->before_mode) {
576
580
mode= data->before_mode;
577
581
cycles= data->before_cycles;
580
585
else if (evaltime > lastkey[0]) {
583
588
mode= data->after_mode;
584
589
cycles= data->after_cycles;
587
if ELEM(0, side, mode)
593
if ((ELEM(0, side, mode)))
590
596
/* find relative place within a cycle */
592
float cycdx=0, cycdy=0, ofs=0;
595
/* ofs is start frame of cycle */
598
float cycdx=0, cycdy=0;
599
float cycle= 0, cyct=0;
598
601
/* calculate period and amplitude (total height) of a cycle */
599
602
cycdx= lastkey[0] - prevkey[0];
606
609
/* calculate the 'number' of the cycle */
607
610
cycle= ((float)side * (evaltime - ofs) / cycdx);
612
/* calculate the time inside the cycle */
613
cyct= fmod(evaltime - ofs, cycdx);
609
615
/* check that cyclic is still enabled for the specified time */
610
616
if (cycles == 0) {
611
617
/* catch this case so that we don't exit when we have cycles=0
612
618
* as this indicates infinite cycles...
615
else if (cycle > (cycles+1)) {
621
else if (cycle > cycles) {
616
622
/* we are too far away from range to evaluate
617
623
* TODO: but we should still hold last value...
622
628
/* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */
623
629
if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
624
cycyofs = (float)floor((evaltime - ofs) / cycdx);
631
cycyofs = (float)floor((evaltime - ofs) / cycdx);
633
cycyofs = (float)ceil((evaltime - ofs) / cycdx);
625
634
cycyofs *= cycdy;
637
/* special case for cycle start/end */
639
evaltime = (side == 1 ? lastkey[0] : prevkey[0]);
641
if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2))
642
evaltime = (side == 1 ? prevkey[0] : lastkey[0]);
628
644
/* calculate where in the cycle we are (overwrite evaltime to reflect this) */
629
if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle) % 2)) {
645
else if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle+1) % 2)) {
630
646
/* when 'mirror' option is used and cycle number is odd, this cycle is played in reverse
631
647
* - for 'before' extrapolation, we need to flip in a different way, otherwise values past
632
648
* then end of the curve get referenced (result of fmod will be negative, and with different phase)
635
evaltime= (float)(prevkey[0] - fmod(evaltime-ofs, cycdx));
651
evaltime= prevkey[0] - cyct;
637
evaltime= (float)(lastkey[0] - fmod(evaltime-ofs, cycdx));
653
evaltime= lastkey[0] - cyct;
640
656
/* the cycle is played normally... */
641
evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
657
evaltime= prevkey[0] + cyct;
643
if (evaltime < ofs) evaltime += cycdx;
659
if (evaltime < prevkey[0]) evaltime += cycdx;
646
662
/* store temp data if needed */
659
static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
675
static void fcm_cycles_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float UNUSED(evaltime))
661
677
tFCMED_Cycles *edata= (tFCMED_Cycles *)fcm->edata;
676
692
sizeof(FMod_Cycles), /* size */
677
693
FMI_TYPE_EXTRAPOLATION, /* action type */
678
694
FMI_REQUIRES_ORIGINAL_DATA, /* requirements */
695
N_("Cycles"), /* name */
680
696
"FMod_Cycles", /* struct name */
681
697
NULL, /* free data */
682
698
NULL, /* copy data */
700
716
data->modification = FCM_NOISE_MODIF_REPLACE;
703
static void fcm_noise_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
719
static void fcm_noise_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime)
705
721
FMod_Noise *data= (FMod_Noise *)fcm->data;
734
750
sizeof(FMod_Noise), /* size */
735
751
FMI_TYPE_REPLACE_VALUES, /* action type */
736
752
0, /* requirements */
753
N_("Noise"), /* name */
738
754
"FMod_Noise", /* struct name */
739
755
NULL, /* free data */
740
756
NULL, /* copy data */
752
768
sizeof(FMod_Filter), /* size */
753
769
FMI_TYPE_REPLACE_VALUES, /* action type */
754
770
0, /* requirements */
771
N_("Filter"), /* name */
756
772
"FMod_Filter", /* struct name */
757
773
NULL, /* free data */
758
774
NULL, /* copy data */
792
808
pymod->prop = IDP_CopyProperty(opymod->prop);
795
static void fcm_python_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
811
static void fcm_python_evaluate (FCurve *UNUSED(fcu), FModifier *UNUSED(fcm), float *UNUSED(cvalue), float UNUSED(evaltime))
797
#ifndef DISABLE_PYTHON
798
814
//FMod_Python *data= (FMod_Python *)fcm->data;
800
816
/* FIXME... need to implement this modifier...
801
817
* It will need it execute a script using the custom properties
803
#endif /* DISABLE_PYTHON */
819
#endif /* WITH_PYTHON */
806
822
static FModifierTypeInfo FMI_PYTHON = {
808
824
sizeof(FMod_Python), /* size */
809
825
FMI_TYPE_GENERATE_CURVE, /* action type */
810
826
FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
827
N_("Python"), /* name */
812
828
"FMod_Python", /* struct name */
813
829
fcm_python_free, /* free data */
814
830
fcm_python_copy, /* copy data */
822
838
/* Limits F-Curve Modifier --------------------------- */
824
static float fcm_limits_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
840
static float fcm_limits_time (FCurve *UNUSED(fcu), FModifier *fcm, float UNUSED(cvalue), float evaltime)
826
842
FMod_Limits *data= (FMod_Limits *)fcm->data;
838
static void fcm_limits_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
854
static void fcm_limits_evaluate (FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float UNUSED(evaltime))
840
856
FMod_Limits *data= (FMod_Limits *)fcm->data;
851
867
sizeof(FMod_Limits), /* size */
852
868
FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */
853
869
FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
870
N_("Limits"), /* name */
855
871
"FMod_Limits", /* struct name */
856
872
NULL, /* free data */
857
873
NULL, /* copy data */
872
888
data->step_size = 2.0f;
875
static float fcm_stepped_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
891
static float fcm_stepped_time (FCurve *UNUSED(fcu), FModifier *fcm, float UNUSED(cvalue), float evaltime)
877
893
FMod_Stepped *data= (FMod_Stepped *)fcm->data;
904
920
sizeof(FMod_Limits), /* size */
905
921
FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */
906
922
FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
907
"Stepped", /* name */
923
N_("Stepped"), /* name */
908
924
"FMod_Stepped", /* struct name */
909
925
NULL, /* free data */
910
926
NULL, /* copy data */
924
940
static short FMI_INIT= 1; /* when non-zero, the list needs to be updated */
926
942
/* This function only gets called when FMI_INIT is non-zero */
927
static void fmods_init_typeinfo ()
943
static void fmods_init_typeinfo (void)
929
945
fmodifiersTypeInfo[0]= NULL; /* 'Null' F-Curve Modifier */
930
946
fmodifiersTypeInfo[1]= &FMI_GENERATOR; /* Generator F-Curve Modifier */
986
1002
/* sanity checks */
987
if ELEM(NULL, modifiers, fmi)
1003
if (ELEM(NULL, modifiers, fmi))
990
1006
/* special checks for whether modifier can be added */
991
1007
if ((modifiers->first) && (type == FMODIFIER_TYPE_CYCLES)) {
992
1008
/* cycles modifier must be first in stack, so for now, don't add if it can't be */
993
1009
// TODO: perhaps there is some better way, but for now,
994
printf("Error: Cannot add 'Cycles' modifier to F-Curve, as 'Cycles' modifier can only be first in stack. \n");
1010
printf("Error: Cannot add 'Cycles' modifier to F-Curve, as 'Cycles' modifier can only be first in stack.\n");
999
1015
fcm= MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
1000
1016
fcm->type = type;
1001
1017
fcm->flag = FMODIFIER_FLAG_EXPANDED;
1018
fcm->influence = 1.0f;
1002
1019
BLI_addtail(modifiers, fcm);
1021
/* tag modifier as "active" if no other modifiers exist in the stack yet */
1022
if (modifiers->first == modifiers->last)
1023
fcm->flag |= FMODIFIER_FLAG_ACTIVE;
1004
1025
/* add modifier's data */
1005
1026
fcm->data= MEM_callocN(fmi->size, fmi->structName);
1007
1028
/* init custom settings if necessary */
1008
1029
if (fmi->new_data)
1009
1030
fmi->new_data(fcm->data);
1087
1108
// XXX this case can probably be removed some day, as it shouldn't happen...
1088
printf("remove_fmodifier() - no modifier stack given \n");
1109
printf("remove_fmodifier() - no modifier stack given\n");
1089
1110
MEM_freeN(fcm);
1094
/* Remove and free the nth F-Modifier from the given stack */
1095
int remove_fmodifier_index (ListBase *modifiers, int index)
1097
FModifier *fcm= BLI_findlink(modifiers, index);
1098
return remove_fmodifier(modifiers, fcm);
1101
1115
/* Remove all of a given F-Curve's modifiers */
1102
1116
void free_fmodifiers (ListBase *modifiers)
1120
1134
FModifier *fcm;
1122
1136
/* sanity checks */
1123
if ELEM(NULL, modifiers, modifiers->first)
1137
if (ELEM(NULL, modifiers, modifiers->first))
1126
1140
/* loop over modifiers until 'active' one is found */
1141
1155
/* sanity checks */
1142
if ELEM(NULL, modifiers, modifiers->first)
1156
if (ELEM(NULL, modifiers, modifiers->first))
1145
1159
/* deactivate all, and set current one active */
1164
1178
return (modifiers && modifiers->first);
1166
1180
/* sanity checks */
1167
if ELEM(NULL, modifiers, modifiers->first)
1181
if (ELEM(NULL, modifiers, modifiers->first))
1170
1184
/* find the first mdifier fitting these criteria */
1190
1204
/* Evaluation API --------------------------- */
1206
/* helper function - calculate influence of FModifier */
1207
static float eval_fmodifier_influence (FModifier *fcm, float evaltime)
1215
/* should we use influence stored in modifier or not
1216
* NOTE: this is really just a hack so that we don't need to version patch old files ;)
1218
if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE)
1219
influence = fcm->influence;
1223
/* restricted range or full range? */
1224
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
1225
if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) {
1229
else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
1230
/* blend in range */
1231
float a = fcm->sfra;
1232
float b = fcm->sfra + fcm->blendin;
1233
return influence * (evaltime - a) / (b - a);
1235
else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
1236
/* blend out range */
1237
float a = fcm->efra;
1238
float b = fcm->efra - fcm->blendout;
1239
return influence * (evaltime - a) / (b - a);
1243
/* just return the influence of the modifier */
1192
1247
/* evaluate time modifications imposed by some F-Curve Modifiers
1193
* - this step acts as an optimisation to prevent the F-Curve stack being evaluated
1248
* - this step acts as an optimization to prevent the F-Curve stack being evaluated
1194
1249
* several times by modifiers requesting the time be modified, as the final result
1195
1250
* would have required using the modified time
1196
1251
* - modifiers only ever receive the unmodified time, as subsequent modifiers should be
1203
1258
FModifier *fcm;
1205
1260
/* sanity checks */
1206
if ELEM(NULL, modifiers, modifiers->last)
1261
if (ELEM(NULL, modifiers, modifiers->last))
1207
1262
return evaltime;
1209
1264
/* Starting from the end of the stack, calculate the time effects of various stacked modifiers
1219
1274
for (fcm= modifiers->last; fcm; fcm= fcm->prev) {
1220
1275
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
1222
/* only evaluate if there's a callback for this */
1223
// TODO: implement the 'influence' control feature...
1224
if (fmi && fmi->evaluate_modifier_time) {
1225
if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
1226
evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
1280
/* if modifier cannot be applied on this frame (whatever scale it is on, it won't affect the results)
1281
* hence we shouldn't bother seeing what it would do given the chance
1283
if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
1284
((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
1286
/* only evaluate if there's a callback for this */
1287
if (fmi->evaluate_modifier_time) {
1288
if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
1289
float influence = eval_fmodifier_influence(fcm, evaltime);
1290
float nval = fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
1292
evaltime = interpf(nval, evaltime, influence);
1239
1307
FModifier *fcm;
1241
1309
/* sanity checks */
1242
if ELEM(NULL, modifiers, modifiers->first)
1310
if (ELEM(NULL, modifiers, modifiers->first))
1245
1313
/* evaluate modifiers */
1246
1314
for (fcm= modifiers->first; fcm; fcm= fcm->next) {
1247
1315
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
1249
/* only evaluate if there's a callback for this */
1250
// TODO: implement the 'influence' control feature...
1251
if (fmi && fmi->evaluate_modifier) {
1252
if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
1253
fmi->evaluate_modifier(fcu, fcm, cvalue, evaltime);
1320
/* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */
1321
if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
1322
((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
1324
if (fmi->evaluate_modifier) {
1325
if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
1326
float influence = eval_fmodifier_influence(fcm, evaltime);
1327
float nval = *cvalue;
1329
fmi->evaluate_modifier(fcu, fcm, &nval, evaltime);
1330
*cvalue = interpf(nval, *cvalue, influence);
1267
1346
/* sanity checks */
1268
1347
// TODO: make these tests report errors using reports not printf's
1269
if ELEM(NULL, fcu, fcu->modifiers.first) {
1348
if (ELEM(NULL, fcu, fcu->modifiers.first)) {
1270
1349
printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");