forked from bartvdbraak/blender
Optimization for the sequencer wipe effect, was doing a lot of unnecessary
computations for each pixel making it quite slow.
This commit is contained in:
parent
fa5d0309b2
commit
61bbccaee7
@ -1501,12 +1501,38 @@ static void do_mul_effect(Sequence * seq,int cfra,
|
||||
WIPE
|
||||
********************************************************************** */
|
||||
|
||||
typedef struct WipeZone {
|
||||
float angle;
|
||||
int flip;
|
||||
int xo, yo;
|
||||
int width;
|
||||
float invwidth;
|
||||
float pythangle;
|
||||
} WipeZone;
|
||||
|
||||
static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
|
||||
{
|
||||
wipezone->flip = (wipe->angle < 0);
|
||||
wipezone->angle = pow(fabs(wipe->angle)/45.0f, log(xo)/log(2.0f));
|
||||
wipezone->xo = xo;
|
||||
wipezone->yo = yo;
|
||||
wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
|
||||
wipezone->pythangle = 1.0f/sqrt(wipe->angle*wipe->angle + 1.0f);
|
||||
|
||||
if(wipe->wipetype == DO_SINGLE_WIPE)
|
||||
wipezone->invwidth = 1.0f/wipezone->width;
|
||||
else
|
||||
wipezone->invwidth = 1.0f/(0.5f*wipezone->width);
|
||||
}
|
||||
|
||||
// This function calculates the blur band for the wipe effects
|
||||
static float in_band(float width,float dist, float perc,int side,int dir){
|
||||
|
||||
static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir)
|
||||
{
|
||||
float t1,t2,alpha,percwidth;
|
||||
|
||||
if(width == 0)
|
||||
return (float)side;
|
||||
|
||||
if(side == 1)
|
||||
percwidth = width * perc;
|
||||
else
|
||||
@ -1515,8 +1541,8 @@ static float in_band(float width,float dist, float perc,int side,int dir){
|
||||
if(width < dist)
|
||||
return side;
|
||||
|
||||
t1 = dist / width; //percentange of width that is
|
||||
t2 = 1 / width; //amount of alpha per % point
|
||||
t1 = dist * wipezone->invwidth; //percentange of width that is
|
||||
t2 = wipezone->invwidth; //amount of alpha per % point
|
||||
|
||||
if(side == 1)
|
||||
alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
|
||||
@ -1525,31 +1551,31 @@ static float in_band(float width,float dist, float perc,int side,int dir){
|
||||
|
||||
if(dir == 0)
|
||||
alpha = 1-alpha;
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
static float check_zone(int x, int y, int xo, int yo,
|
||||
Sequence *seq, float facf0)
|
||||
static float check_zone(WipeZone *wipezone, int x, int y,
|
||||
Sequence *seq, float facf0)
|
||||
{
|
||||
float posx, posy,hyp,hyp2,angle,hwidth,b1,b2,b3,pointdist;
|
||||
/*some future stuff
|
||||
float hyp3,hyp4,b4,b5
|
||||
*/
|
||||
float temp1,temp2,temp3,temp4; //some placeholder variables
|
||||
float halfx = xo/2;
|
||||
float halfy = yo/2;
|
||||
int xo = wipezone->xo;
|
||||
int yo = wipezone->yo;
|
||||
float halfx = xo*0.5f;
|
||||
float halfy = yo*0.5f;
|
||||
float widthf,output=0;
|
||||
WipeVars *wipe = (WipeVars *)seq->effectdata;
|
||||
int width;
|
||||
|
||||
angle = wipe->angle;
|
||||
if(angle < 0){
|
||||
x = xo-x;
|
||||
//y = yo-y
|
||||
}
|
||||
angle = pow(fabs(angle)/45,log(xo)/log(2));
|
||||
if(wipezone->flip) x = xo - x;
|
||||
angle = wipezone->angle;
|
||||
|
||||
posy = facf0 * yo;
|
||||
|
||||
if(wipe->forward){
|
||||
posx = facf0 * xo;
|
||||
posy = facf0 * yo;
|
||||
@ -1557,64 +1583,83 @@ float hyp3,hyp4,b4,b5
|
||||
posx = xo - facf0 * xo;
|
||||
posy = yo - facf0 * yo;
|
||||
}
|
||||
|
||||
switch (wipe->wipetype) {
|
||||
case DO_SINGLE_WIPE:
|
||||
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
|
||||
hwidth = (float)width/2.0;
|
||||
width = wipezone->width;
|
||||
hwidth = width*0.5f;
|
||||
|
||||
if (angle == 0.0)angle = 0.000001;
|
||||
b1 = posy - (-angle)*posx;
|
||||
b2 = y - (-angle)*x;
|
||||
hyp = fabs(angle*x+y+(-posy-angle*posx))/sqrt(angle*angle+1);
|
||||
if(angle < 0){
|
||||
if(angle == 0.0f) {
|
||||
b1 = posy;
|
||||
b2 = y;
|
||||
hyp = fabs(y - posy);
|
||||
}
|
||||
else {
|
||||
b1 = posy - (-angle)*posx;
|
||||
b2 = y - (-angle)*x;
|
||||
hyp = fabs(angle*x+y+(-posy-angle*posx))*wipezone->pythangle;
|
||||
}
|
||||
|
||||
if(angle < 0) {
|
||||
temp1 = b1;
|
||||
b1 = b2;
|
||||
b2 = temp1;
|
||||
}
|
||||
if(wipe->forward){
|
||||
|
||||
if(wipe->forward) {
|
||||
if(b1 < b2)
|
||||
output = in_band(width,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,width,hyp,facf0,1,1);
|
||||
else
|
||||
output = in_band(width,hyp,facf0,0,1);
|
||||
} else{
|
||||
output = in_band(wipezone,width,hyp,facf0,0,1);
|
||||
}
|
||||
else {
|
||||
if(b1 < b2)
|
||||
output = in_band(width,hyp,facf0,0,1);
|
||||
output = in_band(wipezone,width,hyp,facf0,0,1);
|
||||
else
|
||||
output = in_band(width,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,width,hyp,facf0,1,1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case DO_DOUBLE_WIPE:
|
||||
if(!wipe->forward)facf0 = 1-facf0; // Go the other direction
|
||||
if(!wipe->forward)
|
||||
facf0 = 1.0f-facf0; // Go the other direction
|
||||
|
||||
width = (int)(wipe->edgeWidth*((xo+yo)/2.0)); // calculate the blur width
|
||||
hwidth = (float)width/2.0;
|
||||
if (angle == 0)angle = 0.000001;
|
||||
b1 = posy/2 - (-angle)*posx/2;
|
||||
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
|
||||
b2 = y - (-angle)*x;
|
||||
width = wipezone->width; // calculate the blur width
|
||||
hwidth = width*0.5f;
|
||||
if (angle == 0) {
|
||||
b1 = posy*0.5f;
|
||||
b3 = yo-posy*0.5f;
|
||||
b2 = y;
|
||||
|
||||
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
|
||||
hyp = abs(y - posy*0.5f);
|
||||
hyp2 = abs(y - (yo-posy*0.5f));
|
||||
}
|
||||
else {
|
||||
b1 = posy*0.5f - (-angle)*posx*0.5f;
|
||||
b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f);
|
||||
b2 = y - (-angle)*x;
|
||||
|
||||
temp1 = xo*(1-facf0/2)-xo*facf0/2;
|
||||
temp2 = yo*(1-facf0/2)-yo*facf0/2;
|
||||
hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
|
||||
}
|
||||
|
||||
temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f;
|
||||
temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f;
|
||||
pointdist = sqrt(temp1*temp1 + temp2*temp2);
|
||||
|
||||
if(b2 < b1 && b2 < b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output = in_band(hwidth,hyp,facf0,0,1);
|
||||
output = in_band(wipezone,hwidth,hyp,facf0,0,1);
|
||||
} else if(b2 > b1 && b2 > b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output = in_band(hwidth,hyp2,facf0,0,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
|
||||
} else {
|
||||
if( hyp < hwidth && hyp2 > hwidth )
|
||||
output = in_band(hwidth,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
else if( hyp > hwidth && hyp2 < hwidth )
|
||||
output = in_band(hwidth,hyp2,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
|
||||
else
|
||||
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
}
|
||||
if(!wipe->forward)output = 1-output;
|
||||
break;
|
||||
@ -1625,31 +1670,31 @@ float hyp3,hyp4,b4,b5
|
||||
temp3: angle of low side of blur
|
||||
temp4: angle of high side of blur
|
||||
*/
|
||||
output = 1-facf0;
|
||||
widthf = wipe->edgeWidth*2*3.14159;
|
||||
temp1 = 2 * 3.14159 * facf0;
|
||||
output = 1.0f - facf0;
|
||||
widthf = wipe->edgeWidth*2.0f*(float)M_PI;
|
||||
temp1 = 2.0f * (float)M_PI * facf0;
|
||||
|
||||
if(wipe->forward){
|
||||
temp1 = 2*3.14159-temp1;
|
||||
temp1 = 2.0f*(float)M_PI - temp1;
|
||||
}
|
||||
|
||||
x = x - halfx;
|
||||
y = y - halfy;
|
||||
|
||||
temp2 = asin(abs(y)/sqrt(x*x + y*y));
|
||||
if(x <= 0 && y >= 0) temp2 = 3.14159 - temp2;
|
||||
else if(x<=0 && y <= 0) temp2 += 3.14159;
|
||||
else if(x >= 0 && y <= 0) temp2 = 2*3.14159 - temp2;
|
||||
if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
|
||||
else if(x<=0 && y <= 0) temp2 += (float)M_PI;
|
||||
else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
|
||||
|
||||
if(wipe->forward){
|
||||
temp3 = temp1-(widthf/2)*facf0;
|
||||
temp4 = temp1+(widthf/2)*(1-facf0);
|
||||
temp3 = temp1-(widthf*0.5f)*facf0;
|
||||
temp4 = temp1+(widthf*0.5f)*(1-facf0);
|
||||
} else{
|
||||
temp3 = temp1-(widthf/2)*(1-facf0);
|
||||
temp4 = temp1+(widthf/2)*facf0;
|
||||
temp3 = temp1-(widthf*0.5f)*(1-facf0);
|
||||
temp4 = temp1+(widthf*0.5f)*facf0;
|
||||
}
|
||||
if (temp3 < 0) temp3 = 0;
|
||||
if (temp4 > 2*3.14159) temp4 = 2*3.14159;
|
||||
if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
|
||||
|
||||
|
||||
if(temp2 < temp3) output = 0;
|
||||
@ -1673,8 +1718,8 @@ float hyp3,hyp4,b4,b5
|
||||
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
|
||||
b2 = y - (-angle)*x;
|
||||
|
||||
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
|
||||
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
|
||||
|
||||
temp1 = xo*(1-facf0/2)-xo*facf0/2;
|
||||
temp2 = yo*(1-facf0/2)-yo*facf0/2;
|
||||
@ -1682,17 +1727,17 @@ float hyp3,hyp4,b4,b5
|
||||
|
||||
if(b2 < b1 && b2 < b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output = in_band(hwidth,hyp,facf0,0,1);
|
||||
output = in_band(wipezone,hwidth,hyp,facf0,0,1);
|
||||
} else if(b2 > b1 && b2 > b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output = in_band(hwidth,hyp2,facf0,0,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
|
||||
} else {
|
||||
if( hyp < hwidth && hyp2 > hwidth )
|
||||
output = in_band(hwidth,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
else if( hyp > hwidth && hyp2 < hwidth )
|
||||
output = in_band(hwidth,hyp2,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
|
||||
else
|
||||
output = in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
|
||||
output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
}
|
||||
|
||||
if(invert)facf0 = 1-facf0;
|
||||
@ -1701,22 +1746,22 @@ float hyp3,hyp4,b4,b5
|
||||
b3 = (yo-posy/2) - (-angle)*(xo-posx/2);
|
||||
b2 = y - (-angle)*x;
|
||||
|
||||
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))/sqrt(angle*angle+1);
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))/sqrt(angle*angle+1);
|
||||
hyp = abs(angle*x+y+(-posy/2-angle*posx/2))*wipezone->pythangle;
|
||||
hyp2 = abs(angle*x+y+(-(yo-posy/2)-angle*(xo-posx/2)))*wipezone->pythangle;
|
||||
|
||||
if(b2 < b1 && b2 < b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output *= in_band(hwidth,hyp,facf0,0,1);
|
||||
output *= in_band(wipezone,hwidth,hyp,facf0,0,1);
|
||||
} else if(b2 > b1 && b2 > b3 ){
|
||||
if(hwidth < pointdist)
|
||||
output *= in_band(hwidth,hyp2,facf0,0,1);
|
||||
output *= in_band(wipezone,hwidth,hyp2,facf0,0,1);
|
||||
} else {
|
||||
if( hyp < hwidth && hyp2 > hwidth )
|
||||
output *= in_band(hwidth,hyp,facf0,1,1);
|
||||
output *= in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
else if( hyp > hwidth && hyp2 < hwidth )
|
||||
output *= in_band(hwidth,hyp2,facf0,1,1);
|
||||
output *= in_band(wipezone,hwidth,hyp2,facf0,1,1);
|
||||
else
|
||||
output *= in_band(hwidth,hyp2,facf0,1,1) * in_band(hwidth,hyp,facf0,1,1);
|
||||
output *= in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1727,15 +1772,15 @@ float hyp3,hyp4,b4,b5
|
||||
|
||||
if(!wipe->forward) facf0 = 1-facf0;
|
||||
|
||||
width = (int)(wipe->edgeWidth*((xo+yo)/2.0));
|
||||
hwidth = (float)width/2.0;
|
||||
width = wipezone->width;
|
||||
hwidth = width*0.5f;
|
||||
|
||||
temp1 = (halfx-(halfx)*facf0);
|
||||
pointdist = sqrt(temp1*temp1 + temp1*temp1);
|
||||
|
||||
temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
|
||||
if(temp2 > pointdist) output = in_band(hwidth,fabs(temp2-pointdist),facf0,0,1);
|
||||
else output = in_band(hwidth,fabs(temp2-pointdist),facf0,1,1);
|
||||
if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
|
||||
else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
|
||||
|
||||
if(!wipe->forward) output = 1-output;
|
||||
|
||||
@ -1773,8 +1818,13 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1,
|
||||
unsigned char *rect1,
|
||||
unsigned char *rect2, unsigned char *out)
|
||||
{
|
||||
WipeZone wipezone;
|
||||
WipeVars *wipe = (WipeVars *)seq->effectdata;
|
||||
int xo, yo;
|
||||
char *rt1, *rt2, *rt;
|
||||
|
||||
precalc_wipe_zone(&wipezone, wipe, x, y);
|
||||
|
||||
rt1 = (char *)rect1;
|
||||
rt2 = (char *)rect2;
|
||||
rt = (char *)out;
|
||||
@ -1783,7 +1833,7 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float facf1,
|
||||
yo = y;
|
||||
for(y=0;y<yo;y++) {
|
||||
for(x=0;x<xo;x++) {
|
||||
float check = check_zone(x,y,xo,yo,seq,facf0);
|
||||
float check = check_zone(&wipezone,x,y,seq,facf0);
|
||||
if (check) {
|
||||
if (rt1) {
|
||||
rt[0] = (int)(rt1[0]*check)+ (int)(rt2[0]*(1-check));
|
||||
@ -1826,8 +1876,13 @@ static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
|
||||
float *rect1,
|
||||
float *rect2, float *out)
|
||||
{
|
||||
WipeZone wipezone;
|
||||
WipeVars *wipe = (WipeVars *)seq->effectdata;
|
||||
int xo, yo;
|
||||
float *rt1, *rt2, *rt;
|
||||
|
||||
precalc_wipe_zone(&wipezone, wipe, x, y);
|
||||
|
||||
rt1 = rect1;
|
||||
rt2 = rect2;
|
||||
rt = out;
|
||||
@ -1836,7 +1891,7 @@ static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
|
||||
yo = y;
|
||||
for(y=0;y<yo;y++) {
|
||||
for(x=0;x<xo;x++) {
|
||||
float check = check_zone(x,y,xo,yo,seq,facf0);
|
||||
float check = check_zone(&wipezone,x,y,seq,facf0);
|
||||
if (check) {
|
||||
if (rt1) {
|
||||
rt[0] = rt1[0]*check+ rt2[0]*(1-check);
|
||||
|
Loading…
Reference in New Issue
Block a user