~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/fmodifier.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: fmodifier.c 30526 2010-07-20 10:41:08Z campbellbarton $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
25
23
 * ***** END GPL LICENSE BLOCK *****
26
24
 */
27
25
 
 
26
/** \file blender/blenkernel/intern/fmodifier.c
 
27
 *  \ingroup bke
 
28
 */
 
29
 
 
30
 
28
31
 
29
32
#include <math.h>
30
33
#include <stdio.h>
36
39
 
37
40
#include "DNA_anim_types.h"
38
41
 
 
42
#include "BLF_translation.h"
 
43
 
39
44
#include "BLI_blenlib.h"
40
45
#include "BLI_math.h" /* windows needs for M_PI */
 
46
#include "BLI_utildefines.h"
41
47
 
42
48
#include "BKE_fcurve.h"
43
49
#include "BKE_idprop.h"
44
 
#include "BKE_utildefines.h"
45
50
 
46
 
#ifndef DISABLE_PYTHON
47
 
#include "BPY_extern.h" /* for BPY_eval_driver() */
48
 
#endif
49
51
 
50
52
#define SMALL -1.0e-10
51
53
#define SELECT 1
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]))
103
105
 */
104
106
 
105
107
static void fcm_generator_free (FModifier *fcm)
150
152
                                nc= MEM_callocN(sizeof(float)*(data->poly_order+1), "FMod_Generator_Coefs");
151
153
                                
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));
155
157
                                        else
156
158
                                                memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
176
178
                                nc= MEM_callocN(sizeof(float)*(data->poly_order*2), "FMod_Generator_Coefs");
177
179
                                
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));
181
183
                                        else
182
184
                                                memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
194
196
        }
195
197
}
196
198
 
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)
198
200
{
199
201
        FMod_Generator *data= (FMod_Generator *)fcm->data;
200
202
        
201
 
        /* behaviour depends on mode 
 
203
        /* behavior depends on mode 
202
204
         * NOTE: the data in its default state is fine too
203
205
         */
204
206
        switch (data->mode) {
238
240
                }
239
241
                        break;
240
242
                        
241
 
                case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */
 
243
                case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */
242
244
                {
243
245
                        float value= 1.0f, *cp=NULL;
244
246
                        unsigned int i;
245
247
                        
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]);
249
251
                                
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);
308
310
}
309
311
 
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)
311
313
{
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 */
334
336
                {
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 */
339
341
                        }
344
346
                case FCM_GENERATOR_FN_LN: /* natural log */
345
347
                {
346
348
                        /* check that value is greater than 1? */
347
 
                        if (arg > 1.0f) {
 
349
                        if (arg > 1.0) {
348
350
                                fn= log;
349
351
                        }
350
352
                        else {
356
358
                case FCM_GENERATOR_FN_SQRT: /* square root */
357
359
                {
358
360
                        /* no negative numbers */
359
 
                        if (arg > 0.0f) {
 
361
                        if (arg > 0.0) {
360
362
                                fn= sqrt;
361
363
                        }
362
364
                        else {
367
369
                        break;
368
370
                
369
371
                default:
370
 
                        printf("Invalid Function-Generator for F-Modifier - %d \n", data->type);
 
372
                        printf("Invalid Function-Generator for F-Modifier - %d\n", data->type);
371
373
        }
372
374
        
373
375
        /* execute function callback to set value if appropriate */
374
376
        if (fn) {
375
 
                float value= (float)(data->amplitude*fn(arg) + data->value_offset);
 
377
                float value= (float)(data->amplitude*(float)fn(arg) + data->value_offset);
376
378
                
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 */
436
438
        }
437
439
}
438
440
 
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)
440
442
{
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  --------------------------- */
507
509
 
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...).
512
514
 *
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
 
 *                              as appropriate
 
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.
 
517
 *
 
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.
516
520
 */
517
521
 
518
522
/* temp data used during evaluation */
528
532
        data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
529
533
}
530
534
 
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)
532
536
{
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;
536
 
        int cycles=0;
 
540
        int cycles=0, ofs=0;
537
541
        
538
542
        /* check if modifier is first in stack, otherwise disable ourself... */
539
543
        // FIXME...
571
575
         *      2) if before first frame or after last frame, make sure some cycling is in use
572
576
         */
573
577
        if (evaltime < prevkey[0]) {
574
 
                if (data->before_mode)  {
 
578
                if (data->before_mode) {
575
579
                        side= -1;
576
580
                        mode= data->before_mode;
577
581
                        cycles= data->before_cycles;
 
582
                        ofs= prevkey[0];
578
583
                }
579
584
        }
580
585
        else if (evaltime > lastkey[0]) {
582
587
                        side= 1;
583
588
                        mode= data->after_mode;
584
589
                        cycles= data->after_cycles;
 
590
                        ofs= lastkey[0];
585
591
                }
586
592
        }
587
 
        if ELEM(0, side, mode)
 
593
        if ((ELEM(0, side, mode)))
588
594
                return evaltime;
589
595
                
590
596
        /* find relative place within a cycle */
591
597
        {
592
 
                float cycdx=0, cycdy=0, ofs=0;
593
 
                float cycle= 0;
594
 
                
595
 
                /* ofs is start frame of cycle */
596
 
                ofs= prevkey[0];
 
598
                float cycdx=0, cycdy=0;
 
599
                float cycle= 0, cyct=0;
597
600
                
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);
608
611
                
 
612
                /* calculate the time inside the cycle */
 
613
                cyct= fmod(evaltime - ofs, cycdx);
 
614
                
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...
613
619
                         */
614
620
                }
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... 
618
624
                         */
621
627
                
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);
 
630
                        if (side < 0)
 
631
                                cycyofs = (float)floor((evaltime - ofs) / cycdx);
 
632
                        else
 
633
                                cycyofs = (float)ceil((evaltime - ofs) / cycdx);
625
634
                        cycyofs *= cycdy;
626
635
                }
627
636
                
 
637
                /* special case for cycle start/end */
 
638
                if (cyct == 0.0f) {
 
639
                        evaltime = (side == 1 ? lastkey[0] : prevkey[0]);
 
640
                        
 
641
                        if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2))
 
642
                                evaltime = (side == 1 ? prevkey[0] : lastkey[0]);
 
643
                }
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)
633
649
                         */
634
650
                        if (side < 0)
635
 
                                evaltime= (float)(prevkey[0] - fmod(evaltime-ofs, cycdx));
 
651
                                evaltime= prevkey[0] - cyct;
636
652
                        else
637
 
                                evaltime= (float)(lastkey[0] - fmod(evaltime-ofs, cycdx));
 
653
                                evaltime= lastkey[0] - cyct;
638
654
                }
639
655
                else {
640
656
                        /* the cycle is played normally... */
641
 
                        evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
 
657
                        evaltime= prevkey[0] + cyct;
642
658
                }
643
 
                if (evaltime < ofs) evaltime += cycdx;
 
659
                if (evaltime < prevkey[0]) evaltime += cycdx;
644
660
        }
645
661
        
646
662
        /* store temp data if needed */
656
672
        return evaltime;
657
673
}
658
674
 
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))
660
676
{
661
677
        tFCMED_Cycles *edata= (tFCMED_Cycles *)fcm->edata;
662
678
        
676
692
        sizeof(FMod_Cycles), /* size */
677
693
        FMI_TYPE_EXTRAPOLATION, /* action type */
678
694
        FMI_REQUIRES_ORIGINAL_DATA, /* requirements */
679
 
        "Cycles", /* name */
 
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;
701
717
}
702
718
 
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)
704
720
{
705
721
        FMod_Noise *data= (FMod_Noise *)fcm->data;
706
722
        float noise;
734
750
        sizeof(FMod_Noise), /* size */
735
751
        FMI_TYPE_REPLACE_VALUES, /* action type */
736
752
        0, /* requirements */
737
 
        "Noise", /* name */
 
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 */
755
 
        "Filter", /* name */
 
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);
793
809
}
794
810
 
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))
796
812
{
797
 
#ifndef DISABLE_PYTHON
 
813
#ifdef WITH_PYTHON
798
814
        //FMod_Python *data= (FMod_Python *)fcm->data;
799
815
        
800
816
        /* FIXME... need to implement this modifier...
801
817
         *      It will need it execute a script using the custom properties 
802
818
         */
803
 
#endif /* DISABLE_PYTHON */
 
819
#endif /* WITH_PYTHON */
804
820
}
805
821
 
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 */
811
 
        "Python", /* name */
 
827
        N_("Python"), /* name */
812
828
        "FMod_Python", /* struct name */
813
829
        fcm_python_free, /* free data */
814
830
        fcm_python_copy, /* copy data */
821
837
 
822
838
/* Limits F-Curve Modifier --------------------------- */
823
839
 
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)
825
841
{
826
842
        FMod_Limits *data= (FMod_Limits *)fcm->data;
827
843
        
835
851
        return evaltime;
836
852
}
837
853
 
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))
839
855
{
840
856
        FMod_Limits *data= (FMod_Limits *)fcm->data;
841
857
        
851
867
        sizeof(FMod_Limits), /* size */
852
868
        FMI_TYPE_GENERATE_CURVE, /* action type */  /* XXX... err... */   
853
869
        FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
854
 
        "Limits", /* name */
 
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;
873
889
}
874
890
 
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)
876
892
{
877
893
        FMod_Stepped *data= (FMod_Stepped *)fcm->data;
878
894
        int snapblock;
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 */
925
941
 
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) 
928
944
{
929
945
        fmodifiersTypeInfo[0]=  NULL;                                   /* 'Null' F-Curve Modifier */
930
946
        fmodifiersTypeInfo[1]=  &FMI_GENERATOR;                 /* Generator F-Curve Modifier */
943
959
 */
944
960
FModifierTypeInfo *get_fmodifier_typeinfo (int type)
945
961
{
946
 
        /* initialise the type-info list? */
 
962
        /* initialize the type-info list? */
947
963
        if (FMI_INIT) {
948
964
                fmods_init_typeinfo();
949
965
                FMI_INIT = 0;
957
973
                return fmodifiersTypeInfo[type];
958
974
        }
959
975
        else {
960
 
                printf("No valid F-Curve Modifier type-info data available. Type = %i \n", type);
 
976
                printf("No valid F-Curve Modifier type-info data available. Type = %i\n", type);
961
977
        }
962
978
        
963
979
        return NULL;
984
1000
        FModifier *fcm;
985
1001
        
986
1002
        /* sanity checks */
987
 
        if ELEM(NULL, modifiers, fmi)
 
1003
        if (ELEM(NULL, modifiers, fmi))
988
1004
                return NULL;
989
1005
        
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");
995
1011
                return NULL;
996
1012
        }
997
1013
        
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);
1003
1020
        
 
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;
 
1024
        
1004
1025
        /* add modifier's data */
1005
1026
        fcm->data= MEM_callocN(fmi->size, fmi->structName);
1006
 
                
 
1027
        
1007
1028
        /* init custom settings if necessary */
1008
1029
        if (fmi->new_data)      
1009
1030
                fmi->new_data(fcm->data);
1042
1063
{
1043
1064
        FModifier *fcm, *srcfcm;
1044
1065
        
1045
 
        if ELEM(NULL, dst, src)
 
1066
        if (ELEM(NULL, dst, src))
1046
1067
                return;
1047
1068
        
1048
1069
        dst->first= dst->last= NULL;
1085
1106
        } 
1086
1107
        else {
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);
1090
1111
                return 0;
1091
1112
        }
1092
1113
}
1093
1114
 
1094
 
/* Remove and free the nth F-Modifier from the given stack */
1095
 
int remove_fmodifier_index (ListBase *modifiers, int index)
1096
 
{
1097
 
        FModifier *fcm= BLI_findlink(modifiers, index);
1098
 
        return remove_fmodifier(modifiers, fcm);
1099
 
}
1100
 
 
1101
1115
/* Remove all of a given F-Curve's modifiers */
1102
1116
void free_fmodifiers (ListBase *modifiers)
1103
1117
{
1120
1134
        FModifier *fcm;
1121
1135
        
1122
1136
        /* sanity checks */
1123
 
        if ELEM(NULL, modifiers, modifiers->first)
 
1137
        if (ELEM(NULL, modifiers, modifiers->first))
1124
1138
                return NULL;
1125
1139
        
1126
1140
        /* loop over modifiers until 'active' one is found */
1139
1153
        FModifier *fm;
1140
1154
        
1141
1155
        /* sanity checks */
1142
 
        if ELEM(NULL, modifiers, modifiers->first)
 
1156
        if (ELEM(NULL, modifiers, modifiers->first))
1143
1157
                return;
1144
1158
        
1145
1159
        /* deactivate all, and set current one active */
1164
1178
                return (modifiers && modifiers->first);
1165
1179
                
1166
1180
        /* sanity checks */
1167
 
        if ELEM(NULL, modifiers, modifiers->first)
 
1181
        if (ELEM(NULL, modifiers, modifiers->first))
1168
1182
                return 0;
1169
1183
                
1170
1184
        /* find the first mdifier fitting these criteria */
1189
1203
 
1190
1204
/* Evaluation API --------------------------- */
1191
1205
 
 
1206
/* helper function - calculate influence of FModifier */
 
1207
static float eval_fmodifier_influence (FModifier *fcm, float evaltime)
 
1208
{
 
1209
        float influence;
 
1210
        
 
1211
        /* sanity check */
 
1212
        if (fcm == NULL) 
 
1213
                return 0.0f;
 
1214
        
 
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 ;)
 
1217
         */
 
1218
        if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE)
 
1219
                influence = fcm->influence;
 
1220
        else
 
1221
                influence = 1.0f;
 
1222
                
 
1223
        /* restricted range or full range? */
 
1224
        if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
 
1225
                if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) {
 
1226
                        /* out of range */
 
1227
                        return 0.0f;
 
1228
                }
 
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);
 
1234
                }
 
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);
 
1240
                }
 
1241
        }
 
1242
        
 
1243
        /* just return the influence of the modifier */
 
1244
        return influence;
 
1245
}
 
1246
 
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;
1204
1259
        
1205
1260
        /* sanity checks */
1206
 
        if ELEM(NULL, modifiers, modifiers->last)
 
1261
        if (ELEM(NULL, modifiers, modifiers->last))
1207
1262
                return evaltime;
1208
1263
                
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);
1221
1276
                
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);
 
1277
                if (fmi == NULL) 
 
1278
                        continue;
 
1279
                
 
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
 
1282
                 */
 
1283
                if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 || 
 
1284
                        ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
 
1285
                {
 
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);
 
1291
                                        
 
1292
                                        evaltime = interpf(nval, evaltime, influence);
 
1293
                                }
 
1294
                        }
1227
1295
                }
1228
1296
        }
1229
1297
        
1239
1307
        FModifier *fcm;
1240
1308
        
1241
1309
        /* sanity checks */
1242
 
        if ELEM(NULL, modifiers, modifiers->first)
 
1310
        if (ELEM(NULL, modifiers, modifiers->first))
1243
1311
                return;
1244
1312
        
1245
1313
        /* evaluate modifiers */
1246
1314
        for (fcm= modifiers->first; fcm; fcm= fcm->next) {
1247
1315
                FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
1248
1316
                
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);
 
1317
                if (fmi == NULL) 
 
1318
                        continue;
 
1319
                
 
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)) )
 
1323
                {
 
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;
 
1328
                                        
 
1329
                                        fmi->evaluate_modifier(fcu, fcm, &nval, evaltime);
 
1330
                                        *cvalue = interpf(nval, *cvalue, influence);
 
1331
                                }
 
1332
                        }
1254
1333
                }
1255
1334
        }
1256
1335
1266
1345
        
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");
1271
1350
                return;
1272
1351
        }