Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-08 20:28:55 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-08 20:28:55 +0400
commit61bbccaee7ed33d8c9ee22efd6a0aeea59d51a01 (patch)
tree66d428e197c98f552609cc3ce4ce4484323966aa /source
parentfa5d0309b2b9f8d62f1ccd3666cad3a793c9d920 (diff)
Optimization for the sequencer wipe effect, was doing a lot of unnecessary
computations for each pixel making it quite slow.
Diffstat (limited to 'source')
-rw-r--r--source/blender/src/seqeffects.c209
1 files changed, 132 insertions, 77 deletions
diff --git a/source/blender/src/seqeffects.c b/source/blender/src/seqeffects.c
index 4a9e934a691..e59df25115d 100644
--- a/source/blender/src/seqeffects.c
+++ b/source/blender/src/seqeffects.c
@@ -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
-
- 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;
+ if(!wipe->forward)
+ facf0 = 1.0f-facf0; // Go the other direction
+
+ 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(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;
- 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*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/2)-xo*facf0/2;
- temp2 = yo*(1-facf0/2)-yo*facf0/2;
+ 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);