== Sequencer ==
authorPeter Schlaile <peter@schlaile.de>
Thu, 9 Nov 2006 22:23:09 +0000 (22:23 +0000)
committerPeter Schlaile <peter@schlaile.de>
Thu, 9 Nov 2006 22:23:09 +0000 (22:23 +0000)
This adds support for "generator effect strips", which don't need necessarily
an input strip and my version of Matt Ebb's [ #5035 ] 'Solid Color'
sequence strip.

TODO: With a little bit more tweaking it will be possible to make animated
effect plugins and my still unfinished "Bake"-Strip.

For the 'Solid Color'-Effect, to quote Matt:
This is nice and simple, just provides a solid colour that's set in a colour picker in the properties popup. This is something we've needed for a long time, and I got totally sick of having to make 'black.png' and 'white.png' just to do fades, so I coded this.

source/blender/blenloader/intern/writefile.c
source/blender/include/BSE_seqeffects.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/src/drawseq.c
source/blender/src/editseq.c
source/blender/src/seqeffects.c
source/blender/src/sequence.c

index 0e16706eb74a737545ae81f798b2070c72f6de69..e92101e10e7b2fa7d77e60cd9208c3f91b9ad0a8 100644 (file)
@@ -1258,15 +1258,18 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                                        if(seq->plugin) writestruct(wd, DATA, "PluginSeq", 1, seq->plugin);
                                        if(seq->effectdata) {
                                                switch(seq->type){
-                                                       case SEQ_WIPE:
-                                                               writestruct(wd, DATA, "WipeVars", 1, seq->effectdata);
-                                                               break;
-                                                       case SEQ_GLOW:
-                                                               writestruct(wd, DATA, "GlowVars", 1, seq->effectdata);
-                                                               break;
-                                                       case SEQ_TRANSFORM:
-                                                               writestruct(wd, DATA, "TransformVars", 1, seq->effectdata);
-                                                               break;
+                                               case SEQ_COLOR:
+                                                       writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
+                                                       break;
+                                               case SEQ_WIPE:
+                                                       writestruct(wd, DATA, "WipeVars", 1, seq->effectdata);
+                                                       break;
+                                               case SEQ_GLOW:
+                                                       writestruct(wd, DATA, "GlowVars", 1, seq->effectdata);
+                                                       break;
+                                               case SEQ_TRANSFORM:
+                                                       writestruct(wd, DATA, "TransformVars", 1, seq->effectdata);
+                                                       break;
                                                }
                                        }
 
index a7fd56593e0f34b339cb63f13681ee3c4ab52686..0c3eab82e0bf2cc12fb75c64749dbfd01d33b6cc 100644 (file)
@@ -47,6 +47,10 @@ struct SeqEffectHandle {
        void (*init)(struct Sequence *seq);
        void (*init_plugin)(struct Sequence * seq, const char * fname);
 
+       /* number of input strips needed 
+          (called directly after construction) */
+       int (*num_inputs)();
+
         /* load is called first time after readblenfile in
            get_sequence_effect automatically */
        void (*load)(struct Sequence *seq);
@@ -57,7 +61,10 @@ struct SeqEffectHandle {
        /* destruct */
        void (*free)(struct Sequence *seq);
 
-       /* returns: 0: no early out, 1: out = ibuf1, 2: out = ibuf2 */
+       /* returns: -1: no input needed,
+                    0: no early out, 
+                    1: out = ibuf1, 
+                    2: out = ibuf2 */
        int (*early_out)(struct Sequence *seq,
                         float facf0, float facf1); 
 
@@ -78,6 +85,7 @@ struct SeqEffectHandle {
 };
 
 struct SeqEffectHandle get_sequence_effect(struct Sequence * seq);
+int get_sequence_effect_num_inputs(int seq_type);
 
 #endif
 
index 84ca1f16006a7f8066393e5061469d66dc942da5..71908ded6af57663b6906accf6315c615a37a5b0 100644 (file)
@@ -173,6 +173,12 @@ typedef struct TransformVars {
        float rotFin;
 } TransformVars;
 
+typedef struct SolidColorVars {
+       float col[3];
+       float pad;
+} SolidColorVars;
+
+
 /* ***************** SEQUENCE ****************** */
 
 /* seq->flag */
@@ -209,6 +215,8 @@ typedef struct TransformVars {
 #define SEQ_WIPE               25
 #define SEQ_GLOW               26
 #define SEQ_TRANSFORM          27
+#define SEQ_COLOR               28
+
 
 #endif
 
index 5597e5f07da16d4edafd8af36d6ada4d4296efec..36c58bd8d5c9f336db008c89a6bd6d3f4bf6dc75 100644 (file)
@@ -117,6 +117,7 @@ static char *give_seqname(Sequence *seq)
        else if(seq->type==SEQ_WIPE) return "Wipe";
        else if(seq->type==SEQ_GLOW) return "Glow";
        else if(seq->type==SEQ_TRANSFORM) return "Transform";
+       else if(seq->type==SEQ_COLOR) return "Color";
        else if(seq->type==SEQ_PLUGIN) {
                if(!(seq->flag & SEQ_EFFECT_NOT_LOADED) &&
                   seq->plugin && seq->plugin->doit) return seq->plugin->pname;
@@ -140,7 +141,8 @@ static void get_seq_color3ubv(Sequence *seq, char *col)
 {
        char blendcol[3];
        float hsv[3], rgb[3];
-       
+       SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
+
        switch(seq->type) {
        case SEQ_IMAGE:
                BIF_GetThemeColor3ubv(TH_SEQ_IMAGE, col);
@@ -206,7 +208,15 @@ static void get_seq_color3ubv(Sequence *seq, char *col)
                hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
                col[0] = (char)(rgb[0]*255); col[1] = (char)(rgb[1]*255); col[2] = (char)(rgb[2]*255); 
                break;
-               
+       case SEQ_COLOR:
+               if (colvars->col) {
+                       col[0]= (char)(colvars->col[0]*255);
+                       col[1]= (char)(colvars->col[1]*255);
+                       col[2]= (char)(colvars->col[2]*255);
+               } else {
+                       col[0] = col[1] = col[2] = 128;
+               }
+               break;
        case SEQ_PLUGIN:
                BIF_GetThemeColor3ubv(TH_SEQ_PLUGIN, col);
                break;
@@ -404,7 +414,8 @@ static void draw_seq_handle(Sequence *seq, SpaceSeq *sseq, short direction)
        }
        
        /* draw! */
-       if(seq->type < SEQ_EFFECT) {
+       if(seq->type < SEQ_EFFECT || 
+          get_sequence_effect_num_inputs(seq->type) == 0) {
                glEnable( GL_BLEND );
                
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -582,8 +593,10 @@ static void draw_seq_text(Sequence *seq, float x1, float x2, float y1, float y2)
 
                        if(seq->seq3!=seq->seq2 && seq->seq1!=seq->seq3)
                                sprintf(str, "%d | %s: %d>%d (use %d)%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, seq->seq3->machine, can_float ? "" : " No float, upgrade plugin!");
-                       else
+                       else if (seq->seq1 && seq->seq2)
                                sprintf(str, "%d | %s: %d>%d%s", seq->len, give_seqname(seq), seq->seq1->machine, seq->seq2->machine, can_float ? "" : " No float, upgrade plugin!");
+                       else 
+                               sprintf(str, "%d | %s", seq->len, give_seqname(seq));
                }
                else if (seq->type == SEQ_RAM_SOUND) {
                        sprintf(str, "%d | %s", seq->len, seq->strip->stripdata->name);
@@ -1173,6 +1186,9 @@ static void seq_panel_properties(short cntrl)     // SEQ_HANDLER_PROPERTIES
 
                        uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot Start:",10,-10,150,19, &transform->rotIni, 0.0, 360.0, 0, 0, "Rotation Start");
                        uiDefButF(block, NUM, SEQ_BUT_EFFECT, "rot End:",160,-10,150,19, &transform->rotFin, 0.0, 360.0, 0, 0, "Rotation End");
+               } else if(last_seq->type==SEQ_COLOR) {
+                       SolidColorVars *colvars = (SolidColorVars *)last_seq->effectdata;
+                       uiDefButF(block, COL, SEQ_BUT_RELOAD, "",10,90,150,19, colvars->col, 0, 0, 0, 0, "");
                }
                uiBlockEndAlign(block);
        }
index 3fe819dcd98c3e03a2c9ff27001be0815f8fee9c..adfe3205f920423e2a75b05808b6923204d054ac 100644 (file)
@@ -194,6 +194,12 @@ void boundbox_seq(void)
 
 }
 
+int sequence_is_free_transformable(Sequence * seq)
+{
+       return seq->type < SEQ_EFFECT
+               || (get_sequence_effect_num_inputs(seq->type) == 0);
+}
+
 Sequence *find_nearest_seq(int *hand)
 {
        Sequence *seq;
@@ -228,7 +234,7 @@ Sequence *find_nearest_seq(int *hand)
                        if( ((seq->startdisp < seq->enddisp) && (seq->startdisp<=x && seq->enddisp>=x)) ||
                                ((seq->startdisp > seq->enddisp) && (seq->startdisp>=x && seq->enddisp<=x)) )
                        {
-                               if(seq->type < SEQ_EFFECT) {
+                               if(sequence_is_free_transformable(seq)) {
                                        if( handsize+seq->startdisp >=x )
                                                *hand= 1;
                                        else if( -handsize+seq->enddisp <=x )
@@ -1039,6 +1045,7 @@ static int event_to_efftype(int event)
        if(event==13) return SEQ_WIPE;
        if(event==14) return SEQ_GLOW;
        if(event==15) return SEQ_TRANSFORM;
+       if(event==16) return SEQ_COLOR;
        return 0;
 }
 
@@ -1047,6 +1054,11 @@ static int can_insert_seq_between(Sequence *seq1,
 {
        Editing *ed= G.scene->ed;
        Sequence *seq;
+
+       if (seq1 == 0 || seq2 == 0 || seq3 == 0) {
+              return 0;
+       }
+
        /* see if inserting inbetween would create a cycle */
        if(seq_is_predecessor(seq1, seq2) || seq_is_predecessor(seq2, seq1) ||
           seq_is_predecessor(seq2, seq3) || seq_is_predecessor(seq3, seq2) ||
@@ -1101,17 +1113,18 @@ static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type,
        }
        
 
-       if(type==SEQ_PLUGIN || type==SEQ_WIPE || 
-          type==SEQ_GLOW || type==SEQ_TRANSFORM) {
-         /* plugin: minimal 1 select */
+       switch(get_sequence_effect_num_inputs(type)) {
+       case 0:
+               seq1 = seq2 = seq3 = 0;
+               break;
+       case 1:
                if(seq2==0)  {
                        error("Need at least one selected sequence strip");
                        return 0;
                }
                if(seq1==0) seq1= seq2;
                if(seq3==0) seq3= seq2;
-       }
-       else {
+       case 2:
                if(seq1==0 || seq2==0) {
                        error("Need 2 selected sequence strips");
                        return 0;
@@ -1203,6 +1216,13 @@ static int add_seq_effect(int type, char *str)
        newseq->seq3= seq3;
 
        sh.init(newseq);
+
+       if (!seq1) {
+               newseq->len= 1;
+               newseq->startstill= 25;
+               newseq->endstill= 24;
+       }
+
        calc_sequence(newseq);
 
        newseq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
@@ -1212,7 +1232,7 @@ static int add_seq_effect(int type, char *str)
                strip->stripdata= MEM_callocN(newseq->len*sizeof(StripElem), "stripelem");
 
        /* initialize plugin */
-       if(type==10) {
+       if(newseq->type == SEQ_PLUGIN) {
                sh.init_plugin(newseq, str);
 
                if(newseq->plugin==0) {
@@ -1224,8 +1244,11 @@ static int add_seq_effect(int type, char *str)
        }
 
        /* set find a free spot to but the strip */
-       newseq->machine= MAX3(newseq->seq1->machine, newseq->seq2->machine,
-               newseq->seq3->machine);
+       if (newseq->seq1) {
+               newseq->machine= MAX3(newseq->seq1->machine, 
+                                     newseq->seq2->machine,
+                                     newseq->seq3->machine);
+       }
        if(test_overlap_seq(newseq)) shuffle_seq(newseq);
 
        /* set inbetween relation */
@@ -1235,8 +1258,11 @@ static int add_seq_effect(int type, char *str)
        update_changed_seq_and_deps(newseq, 1, 1);
 
        /* push undo and go into grab mode */
-       if(type == 10) BIF_undo_push("Add plugin strip Sequencer");
-       else BIF_undo_push("Add effect strip Sequencer");
+       if(newseq->type == SEQ_PLUGIN) {
+               BIF_undo_push("Add plugin strip Sequencer");
+       } else {
+               BIF_undo_push("Add effect strip Sequencer");
+       }
 
        transform_seq('g', 0);
 
@@ -1316,6 +1342,9 @@ void add_sequence(int type)
                case SEQ_TRANSFORM:
                        event = 15;
                        break;
+               case SEQ_COLOR:
+                       event = 16;
+                       break;
                default:
                        event = 0;
                        break;
@@ -1344,7 +1373,8 @@ void add_sequence(int type)
                               "|Alpha Over Drop%x9"
                               "|Wipe%x13"
                               "|Glow%x14"
-                              "|Transforms%x15");
+                              "|Transforms%x15"
+                              "|Color Generator%x16");
        }
 
        if(event<1) return;
@@ -1423,8 +1453,9 @@ void add_sequence(int type)
        case 13:
        case 14:
        case 15:
-
-               if(get_last_seq()==0)
+       case 16:
+               if(get_last_seq()==0 && 
+                  get_sequence_effect_num_inputs( event_to_efftype(event))> 0)
                        error("Need at least one active sequence strip");
                else if(event==10)
                        activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
@@ -1467,7 +1498,8 @@ void change_sequence(void)
                                "|Alpha Over Drop%x9"
                                "|Wipe%x13"
                                "|Glow%x14"
-                               "|Transform%x15");
+                               "|Transform%x15"
+                               "|Color Generator%x16");
                if(event > 0) {
                        if(event==1) {
                                SWAP(Sequence *,last_seq->seq1,last_seq->seq2);
@@ -1486,13 +1518,22 @@ void change_sequence(void)
                                /* free previous effect and init new effect */
                                struct SeqEffectHandle sh;
 
-                               sh = get_sequence_effect(last_seq);
-                               sh.free(last_seq);
-
-                               last_seq->type = event_to_efftype(event);
-
-                               sh = get_sequence_effect(last_seq);
-                               sh.init(last_seq);
+                               if (get_sequence_effect_num_inputs(
+                                           last_seq->type)
+                                   < get_sequence_effect_num_inputs(
+                                           event_to_efftype(event))) {
+                                       error("New effect needs more "
+                                             "input strips!");
+                               } else {
+                                       sh = get_sequence_effect(last_seq);
+                                       sh.free(last_seq);
+                                       
+                                       last_seq->type 
+                                               = event_to_efftype(event);
+                                       
+                                       sh = get_sequence_effect(last_seq);
+                                       sh.init(last_seq);
+                               }
                        }
 
                        update_changed_seq_and_deps(last_seq, 0, 1);
@@ -1783,33 +1824,30 @@ static void recurs_dupli_seq(ListBase *old, ListBase *new)
                                seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
                        }
                        else {
-                               if(seq->seq1->newseq) {
-
-                                       seqn= MEM_dupallocN(seq);
-                                       seq->newseq= seqn;
-                                       BLI_addtail(new, seqn);
-
-                                       seqn->seq1= seq->seq1->newseq;
-                                       if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
-                                       if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
+                               seqn= MEM_dupallocN(seq);
+                               seq->newseq= seqn;
+                               BLI_addtail(new, seqn);
 
-                                       if(seqn->ipo) seqn->ipo->id.us++;
+                               if(seq->seq1 && seq->seq1->newseq) seqn->seq1= seq->seq1->newseq;
+                               if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
+                               if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
 
-                                       if (seq->type & SEQ_EFFECT) {
-                                               struct SeqEffectHandle sh;
-                                               sh = get_sequence_effect(seq);
-                                               if(sh.copy)
-                                                       sh.copy(seq, seqn);
-                                       }
+                               if(seqn->ipo) seqn->ipo->id.us++;
 
-                                       seqn->strip= MEM_dupallocN(seq->strip);
+                               if (seq->type & SEQ_EFFECT) {
+                                       struct SeqEffectHandle sh;
+                                       sh = get_sequence_effect(seq);
+                                       if(sh.copy)
+                                               sh.copy(seq, seqn);
+                               }
 
-                                       if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+                               seqn->strip= MEM_dupallocN(seq->strip);
 
-                                       seq->flag &= SEQ_DESEL;
+                               if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
 
-                                       seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
-                               }
+                               seq->flag &= SEQ_DESEL;
+                               
+                               seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
                        }
 
                }
@@ -2274,7 +2312,7 @@ void transform_seq(int mode, int context)
                                                        }
                                                }
                                                if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
-                                                       if(seq->type<SEQ_EFFECT) seq->start= ts->start+ ix;
+                                                       if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
 
                                                        if(seq->depth==0) seq->machine= ts->machine+ iy;
 
@@ -2306,9 +2344,9 @@ void transform_seq(int mode, int context)
                                        }
                                }
                                else if(seq->type & SEQ_EFFECT) {
-                                       if(seq->seq1->flag & SELECT) calc_sequence(seq);
-                                       else if(seq->seq2->flag & SELECT) calc_sequence(seq);
-                                       else if(seq->seq3->flag & SELECT) calc_sequence(seq);
+                                       if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
+                                       else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
+                                       else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
                                }
                        }
                        END_SEQ;
@@ -2361,9 +2399,9 @@ void transform_seq(int mode, int context)
 
                                ts++;
                        } else if(seq->type & SEQ_EFFECT) {
-                               if(seq->seq1->flag & SELECT) calc_sequence(seq);
-                               else if(seq->seq2->flag & SELECT) calc_sequence(seq);
-                               else if(seq->seq3->flag & SELECT) calc_sequence(seq);
+                               if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
+                               else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
+                               else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
                        }
 
                }
@@ -2551,7 +2589,7 @@ void seq_snap(short event)
        /* also check metas */
        WHILE_SEQ(ed->seqbasep) {
                if(seq->flag & SELECT) {
-                       if(seq->type<SEQ_EFFECT) seq->start= CFRA-seq->startofs+seq->startstill;
+                       if(sequence_is_free_transformable(seq)) seq->start= CFRA-seq->startofs+seq->startstill;
                        calc_sequence(seq);
                }
        }
index dbef3b61ba50f31b545766ec5c534b8fc176d3ed..9196f02c28bc61defe4c602c7baea5dc58e69b11 100644 (file)
@@ -199,6 +199,14 @@ static void init_plugin(Sequence * seq, const char * fname)
        seq->plugin= (PluginSeq *)add_plugin_seq(fname, seq->name+2);
 }
 
+/* 
+ * FIXME: should query plugin! Could be generator, that needs zero inputs...
+ */
+static int num_inputs_plugin()
+{
+       return 1;
+}
+
 static void load_plugin(Sequence * seq)
 {
        if (seq) {
@@ -1756,6 +1764,11 @@ static void init_wipe_effect(Sequence *seq)
        seq->effectdata = MEM_callocN(sizeof(struct WipeVars), "wipevars");
 }
 
+static int num_inputs_wipe()
+{
+       return 1;
+}
+
 static void free_wipe_effect(Sequence *seq)
 {
        if(seq->effectdata)MEM_freeN(seq->effectdata);
@@ -1891,7 +1904,7 @@ static void do_wipe_effect(Sequence * seq,int cfra,
        }
 }
 /* **********************************************************************
-   transform
+   TRANSFORM
    ********************************************************************** */
 static void init_transform_effect(Sequence *seq)
 {
@@ -1916,6 +1929,11 @@ static void init_transform_effect(Sequence *seq)
        
 }
 
+static int num_inputs_transform()
+{
+       return 1;
+}
+
 static void free_transform_effect(Sequence *seq)
 {
        if(seq->effectdata)MEM_freeN(seq->effectdata);
@@ -2632,6 +2650,11 @@ static void init_glow_effect(Sequence *seq)
        glow->bNoComp = 0;
 }
 
+static int num_inputs_glow()
+{
+       return 1;
+}
+
 static void free_glow_effect(Sequence *seq)
 {
        if(seq->effectdata)MEM_freeN(seq->effectdata);
@@ -2690,6 +2713,78 @@ static void do_glow_effect(Sequence * seq,int cfra,
        }
 }
 
+/* **********************************************************************
+   SOLID COLOR
+   ********************************************************************** */
+
+static void init_solid_color(Sequence *seq)
+{
+       SolidColorVars *cv;
+       
+       if(seq->effectdata)MEM_freeN(seq->effectdata);
+       seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
+       
+       cv = (SolidColorVars *)seq->effectdata;
+       cv->col[0] = cv->col[1] = cv->col[2] = 0.5;
+}
+
+static int num_inputs_color()
+{
+       return 0;
+}
+
+static void free_solid_color(Sequence *seq)
+{
+       if(seq->effectdata)MEM_freeN(seq->effectdata);
+       seq->effectdata = 0;
+}
+
+static void copy_solid_color(Sequence *dst, Sequence *src)
+{
+       dst->effectdata = MEM_dupallocN(src->effectdata);
+}
+
+static int early_out_color(struct Sequence *seq,
+                          float facf0, float facf1)
+{
+       return -1;
+}
+
+static void do_solid_color(Sequence * seq,int cfra,
+                          float facf0, float facf1, int x, int y, 
+                          struct ImBuf *ibuf1, struct ImBuf *ibuf2, 
+                          struct ImBuf *ibuf3, struct ImBuf *out)
+{
+       SolidColorVars *cv = (SolidColorVars *)seq->effectdata;
+
+       unsigned char *rect;
+       float *rect_float;
+
+       if (out->rect) {
+               rect = (unsigned char *)out->rect;
+               
+               for(y=0; y<out->y; y++) {       
+                       for(x=0; x<out->x; x++, rect+=4) {
+                               rect[0]= (char)(cv->col[0]*255);
+                               rect[1]= (char)(cv->col[1]*255);
+                               rect[2]= (char)(cv->col[2]*255);
+                               rect[3]= 255;
+                       }       
+               }
+       } else if (out->rect_float) {
+               rect_float = out->rect_float;
+               
+               for(y=0; y<out->y; y++) {       
+                       for(x=0; x<out->x; x++, rect_float+=4) {
+                               rect_float[0]= cv->col[0];
+                               rect_float[1]= cv->col[1];
+                               rect_float[2]= cv->col[2];
+                               rect_float[3]= 1.0;
+                       }
+               }
+       }
+}
+
 /* **********************************************************************
    sequence effect factory
    ********************************************************************** */
@@ -2715,6 +2810,11 @@ static void free_noop(struct Sequence *seq)
 
 }
 
+static int num_inputs_default()
+{
+       return 2;
+}
+
 static int early_out_noop(struct Sequence *seq,
                          float facf0, float facf1)
 {
@@ -2769,13 +2869,14 @@ static void do_overdrop_effect(struct Sequence * seq, int cfra,
                            ibuf1, ibuf2, ibuf3, out);
 }
 
-struct SeqEffectHandle get_sequence_effect(Sequence * seq)
+static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
 {
        struct SeqEffectHandle rval;
-       int sequence_type = seq->type;
+       int sequence_type = seq_type;
 
        rval.init = init_noop;
        rval.init_plugin = init_plugin_noop;
+       rval.num_inputs = num_inputs_default;
        rval.load = load_noop;
        rval.free = free_noop;
        rval.early_out = early_out_noop;
@@ -2822,6 +2923,7 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq)
                break;
        case SEQ_WIPE:
                rval.init = init_wipe_effect;
+               rval.num_inputs = num_inputs_wipe;
                rval.free = free_wipe_effect;
                rval.copy = copy_wipe_effect;
                rval.early_out = early_out_fade;
@@ -2830,18 +2932,30 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq)
                break;
        case SEQ_GLOW:
                rval.init = init_glow_effect;
+               rval.num_inputs = num_inputs_glow;
                rval.free = free_glow_effect;
                rval.copy = copy_glow_effect;
                rval.execute = do_glow_effect;
                break;
        case SEQ_TRANSFORM:
                rval.init = init_transform_effect;
+               rval.num_inputs = num_inputs_transform;
                rval.free = free_transform_effect;
                rval.copy = copy_transform_effect;
                rval.execute = do_transform_effect;
                break;
+       case SEQ_COLOR:
+               rval.init = init_solid_color;
+               rval.num_inputs = num_inputs_color;
+               rval.early_out = early_out_color;
+               rval.free = free_solid_color;
+               rval.copy = copy_solid_color;
+               rval.execute = do_solid_color;
+               break;
+
        case SEQ_PLUGIN:
                rval.init_plugin = init_plugin;
+               rval.num_inputs = num_inputs_plugin;
                rval.load = load_plugin;
                rval.free = free_plugin;
                rval.copy = copy_plugin;
@@ -2851,6 +2965,14 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq)
                break;
        }
 
+       return rval;
+}
+
+
+struct SeqEffectHandle get_sequence_effect(Sequence * seq)
+{
+       struct SeqEffectHandle rval = get_sequence_effect_impl(seq->type);
+
        if (seq->flag & SEQ_EFFECT_NOT_LOADED) {
                rval.load(seq);
                seq->flag &= ~SEQ_EFFECT_NOT_LOADED;
@@ -2858,3 +2980,10 @@ struct SeqEffectHandle get_sequence_effect(Sequence * seq)
 
        return rval;
 }
+
+int get_sequence_effect_num_inputs(int seq_type)
+{
+       struct SeqEffectHandle rval = get_sequence_effect_impl(seq_type);
+
+       return rval.num_inputs();
+}
index f81df5357f947a33fee72c1b19f7f7b65d3ac7c2..f34484fea14a0d8129451dde0789ffc16bebfe08 100644 (file)
@@ -229,9 +229,25 @@ void calc_sequence(Sequence *seq)
                // seq->start= seq->startdisp= MAX2(seq->seq1->startdisp, seq->seq2->startdisp);
                // seq->enddisp= MIN2(seq->seq1->enddisp, seq->seq2->enddisp);
 
-               seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
-               seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
-               seq->len= seq->enddisp - seq->startdisp;
+               if (seq->seq1) {
+                       seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
+                       seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
+                       seq->len= seq->enddisp - seq->startdisp;
+               } else {
+                       if(seq->startofs && seq->startstill) seq->startstill= 0;
+                       if(seq->endofs && seq->endstill) seq->endstill= 0;
+
+                       seq->startdisp= seq->start + seq->startofs - seq->startstill;
+                       seq->enddisp= seq->start+seq->len - seq->endofs + seq->endstill;
+
+                       seq->handsize= 10.0;    /* 10 frames */
+                       if( seq->enddisp-seq->startdisp < 20 ) {
+                               seq->handsize= (float)(0.5*(seq->enddisp-seq->startdisp));
+                       }
+                       else if(seq->enddisp-seq->startdisp > 250) {
+                               seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
+                       }
+               }
 
                if(seq->strip && seq->len!=seq->strip->len) {
                        new_stripdata(seq);
@@ -414,39 +430,53 @@ void do_effect(int cfra, Sequence *seq, StripElem *se)
        StripElem *se1, *se2, *se3;
        float fac, facf;
        int x, y;
+       int early_out;
        struct SeqEffectHandle sh = get_sequence_effect(seq);
 
-       if(!sh.execute || se->se1==0 || se->se2==0 || se->se3==0) {
+       if (!sh.execute) { /* effect not supported in this version... */
                make_black_ibuf(se->ibuf);
                return;
        }
 
+       if(seq->ipo && seq->ipo->curve.first) {
+               do_seq_ipo(seq);
+               fac= seq->facf0;
+               facf= seq->facf1;
+       } else {
+               sh.get_default_fac(seq, cfra, &fac, &facf);
+       }
+
+       if( !(G.scene->r.mode & R_FIELDS) ) facf = fac;
+
+       early_out = sh.early_out(seq, fac, facf);
+
+       if (early_out == -1) { /* no input needed */
+               sh.execute(seq, cfra, fac, facf, se->ibuf->x, se->ibuf->y, 
+                          0, 0, 0, se->ibuf);
+               return;
+       }
+
+       if(se->se1==0 || se->se2==0 || se->se3==0) {
+               make_black_ibuf(se->ibuf);
+               return;
+       }
+       
        /* if metastrip: other se's */
        if(se->se1->ok==2) se1= se->se1->se1;
        else se1= se->se1;
-
+       
        if(se->se2->ok==2) se2= se->se2->se1;
        else se2= se->se2;
-
+       
        if(se->se3->ok==2) se3= se->se3->se1;
        else se3= se->se3;
-
+       
        if(se1==0 || se2==0 || se3==0) {
                make_black_ibuf(se->ibuf);
                return;
        }
 
-       if(seq->ipo && seq->ipo->curve.first) {
-               do_seq_ipo(seq);
-               fac= seq->facf0;
-               facf= seq->facf1;
-       } else {
-               sh.get_default_fac(seq, cfra, &fac, &facf);
-       }
-
-       if( G.scene->r.mode & R_FIELDS ); else facf= fac;
-
-       switch (sh.early_out(seq, fac, facf)) {
+       switch (early_out) {
        case 0:
                break;
        case 1:
@@ -719,6 +749,9 @@ static void do_effect_depend(int cfra, Sequence * seq, StripElem *se)
        if( G.scene->r.mode & R_FIELDS ); else facf= fac;
        
        switch (sh.early_out(seq, fac, facf)) {
+       case -1:
+               /* no input needed */
+               break;
        case 0:
                do_build_seq_depend(seq->seq1, cfra);
                do_build_seq_depend(seq->seq2, cfra);
@@ -731,7 +764,9 @@ static void do_effect_depend(int cfra, Sequence * seq, StripElem *se)
                break;
        }
 
-       do_build_seq_depend(seq->seq3, cfra);
+       if (seq->seq3) {
+               do_build_seq_depend(seq->seq3, cfra);
+       }
 }
 
 static void do_build_seq_depend(Sequence * seq, int cfra)
@@ -786,17 +821,17 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                        /* should the effect be recalculated? */
                        
                        if(se->ibuf==0 
-                          || (se->se1 != seq->seq1->curelem) 
-                          || (se->se2 != seq->seq2->curelem) 
-                          || (se->se3 != seq->seq3->curelem)) {
-                               se->se1= seq->seq1->curelem;
-                               se->se2= seq->seq2->curelem;
-                               se->se3= seq->seq3->curelem;
+                          || (seq->seq1 && se->se1 != seq->seq1->curelem) 
+                          || (seq->seq2 && se->se2 != seq->seq2->curelem) 
+                          || (seq->seq3 && se->se3 != seq->seq3->curelem)) {
+                               if (seq->seq1) se->se1= seq->seq1->curelem;
+                               if (seq->seq2) se->se2= seq->seq2->curelem;
+                               if (seq->seq3) se->se3= seq->seq3->curelem;
                                
                                if(se->ibuf==NULL) {
                                        /* if one of two first inputs are rectfloat, output is float too */
-                                       if((se->se1->ibuf && se->se1->ibuf->rect_float) ||
-                                          (se->se2->ibuf && se->se2->ibuf->rect_float))
+                                       if((se->se1 && se->se1->ibuf && se->se1->ibuf->rect_float) ||
+                                          (se->se2 && se->se2->ibuf && se->se2->ibuf->rect_float))
                                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
                                        else
                                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);