From 57a2f7a5b569d1d0564c45e33eae1ebad3cd560b Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Thu, 9 Nov 2006 22:23:09 +0000 Subject: == Sequencer == 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 | 21 ++-- source/blender/include/BSE_seqeffects.h | 10 +- source/blender/makesdna/DNA_sequence_types.h | 8 ++ source/blender/src/drawseq.c | 24 ++++- source/blender/src/editseq.c | 140 +++++++++++++++++---------- source/blender/src/seqeffects.c | 135 +++++++++++++++++++++++++- source/blender/src/sequence.c | 89 +++++++++++------ 7 files changed, 332 insertions(+), 95 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 0e16706eb74..e92101e10e7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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; } } diff --git a/source/blender/include/BSE_seqeffects.h b/source/blender/include/BSE_seqeffects.h index a7fd56593e0..0c3eab82e0b 100644 --- a/source/blender/include/BSE_seqeffects.h +++ b/source/blender/include/BSE_seqeffects.h @@ -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 diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 84ca1f16006..71908ded6af 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -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 diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index 5597e5f07da..36c58bd8d5c 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -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); } diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index 3fe819dcd98..adfe3205f92 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -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->typestart= 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->typestart= CFRA-seq->startofs+seq->startstill; + if(sequence_is_free_transformable(seq)) seq->start= CFRA-seq->startofs+seq->startstill; calc_sequence(seq); } } diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c index dbef3b61ba5..9196f02c28b 100644 --- a/source/blender/src/seqeffects.c +++ b/source/blender/src/seqeffects.c @@ -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; yy; y++) { + for(x=0; xx; 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; yy; y++) { + for(x=0; xx; 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(); +} diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index f81df5357f9..f34484fea14 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -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); -- cgit v1.2.3