commit cd174a6431cef4d9d78f720bc26112df1d4be36e
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Tue Jun 28 14:01:10 2016 +0100

    Make the 'deform' effect continuous when 'center' point passes through (0,0) i.e. middle of the Object.

diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 9797719..90d46ac 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -146,13 +146,13 @@ void restrict(inout float v)
 //////////////////////////////////////////////////////////////////////////////////////////////
 // DEFORM EFFECT
 //
-// Deform the whole shape of the bitmap by force V
+// Deform the whole shape of the Object by force V
 // 
-// If the point of application (Sx,Sy) is on the edge of the bitmap, then:
+// If the point of application (Sx,Sy) is on the edge of the Object, then:
 // a) ignore Vz
-// b) change shape of the whole bitmap in the following way:
-//    Suppose the upper-left corner of the bitmap rectangle is point L, upper-right - R, force vector V is applied to point M on the upper edge,
-//    length of the bitmap = w, height = h, |LM| = Wl, |MR| = Wr, force vector V=(Vx,Vy). Also let H = h/(h+Vy)
+// b) change shape of the whole Object in the following way:
+//    Suppose the upper-left corner of the Object rectangle is point L, upper-right - R, force vector V is applied to point M on the upper edge,
+//    width of the Object = w, height = h, |LM| = Wl, |MR| = Wr, force vector V=(Vx,Vy). Also let H = h/(h+Vy)
 //
 //    Let now L' and R' be points such that vec(LL') = Wr/w * vec(V) and vec(RR') = Wl/w * vec(V)
 //    now let Vl be a point on the line segment L --> M+vec(V) such that Vl(y) = L'(y)
@@ -165,7 +165,7 @@ void restrict(inout float v)
 //    vec(Fl) = (Wr/w) * [ (Vx+Wl)-Wl*H, Vy ] = (Wr/w) * [ Wl*Vy / (h+Vy) + Vx, Vy ]
 //    vec(Fr) = (Wl/w) * [ (Vx-Wr)+Wr*H, Vy ] = (Wl/w) * [-Wr*Vy / (h+Vy) + Vx, Vy ]
 //
-//    Lets now denote M+vec(v) = M'. The line segment LMR gets distorted to the curve Fl-M'-Fr. Let's now arbitrarilly decide that:
+//    Lets now denote M+vec(V) = M'. The line segment LMR gets distorted to the curve Fl-M'-Fr. Let's now arbitrarilly decide that:
 //    a) at point Fl the curve has to be parallel to line LM'
 //    b) at point M' - to line LR
 //    c) at point Fr - to line M'R
@@ -188,29 +188,30 @@ void restrict(inout float v)
 //    If we are dragging the top edge:    
 //
 //    Now point (x,u_objD.x) on the top edge will move by vector (X(t),Y(t)) where those functions are given by (*) and
-//    t =  x < dSx ? (u_objD.x+x)/(u_objD.x+dSx) : (u_objD.x-x)/(u_objD.x-dSx)
+//    t =  x < dSx ? (u_objD.x+x)/(u_objD.x+dSx) : (u_objD.x-x)/(u_objD.x-dSx)    (this is 'vec2 time' below in the code)
 //    Any point (x,y) will move by vector (a*X(t),a*Y(t)) where a is (y+u_objD.y)/(2*u_objD.y)
   
 void deform(in int effect, inout vec4 v)
   {
-  vec2 p = vUniforms[effect+2].yz;  
-  vec2 w = vUniforms[effect].xy;    // w = vec(MM')
+  vec2 center = vUniforms[effect+2].yz;
+  vec2 force = vUniforms[effect].xy;    // force = vec(MM')
   vec2 vert_vec, horz_vec; 
-  vec2 signXY = sign(p-v.xy);  
-  vec2 time = (u_objD.xy+signXY*v.xy)/(u_objD.xy+signXY*p);
-  vec2 factorV = vec2(0.5,0.5) + sign(p)*v.xy/(4.0*u_objD.xy);
-  vec2 factorD = (u_objD.xy-signXY*p)/(2.0*u_objD.xy);
-  vec2 vert_d = factorD.x*w;
-  vec2 horz_d = factorD.y*w;
-  vec2 corr = 0.33 / ( 1.0 + (4.0*u_objD.x*u_objD.x)/dot(w,w) ) * (p+w+signXY*u_objD.xy); // .x = the vector tangent to X(t) at Fl = 0.3*vec(LM')  (or vec(RM') if signXY.x=-1).
-                                                                                          // .y = the vector tangent to X(t) at Fb = 0.3*vec(BM')  (or vec(TM') if signXY.y=-1)
-                                                                                          // the scalar: make the length of the speed vectors at Fl and Fr be 0 when force vector 'w' is zero
-  vert_vec.x = ( w.x-vert_d.x-corr.x )*time.x*time.x + corr.x*time.x + vert_d.x;
-  horz_vec.y = (-w.y+horz_d.y+corr.y )*time.y*time.y - corr.y*time.y - horz_d.y;
-  vert_vec.y = (-3.0*vert_d.y+2.0*w.y )*time.x*time.x*time.x + (-3.0*w.y+5.0*vert_d.y )*time.x*time.x - vert_d.y*time.x - vert_d.y;
-  horz_vec.x = ( 3.0*horz_d.x-2.0*w.x )*time.y*time.y*time.y + ( 3.0*w.x-5.0*horz_d.x )*time.y*time.y + horz_d.x*time.y + horz_d.x;  
+  vec2 signXY = sign(center-v.xy);
+  vec2 time = (u_objD.xy+signXY*v.xy)/(u_objD.xy+signXY*center);
+  vec2 factorV = vec2(0.5,0.5) + (center*v.xy)/(4.0*u_objD.xy*u_objD.xy);
+  vec2 factorD = (u_objD.xy-signXY*center)/(2.0*u_objD.xy);
+  vec2 vert_d = factorD.x*force;
+  vec2 horz_d = factorD.y*force;
+  float dot = dot(force,force);
+  vec2 corr = 0.33 * (center+force+signXY*u_objD.xy) * dot / ( dot + (4.0*u_objD.x*u_objD.x) ); // .x = the vector tangent to X(t) at Fl = 0.3*vec(LM')  (or vec(RM') if signXY.x=-1).
+                                                                                                // .y = the vector tangent to X(t) at Fb = 0.3*vec(BM')  (or vec(TM') if signXY.y=-1)
+                                                                                                // the scalar: make the length of the speed vectors at Fl and Fr be 0 when force vector 'force' is zero
+  vert_vec.x = ( force.x-vert_d.x-corr.x )*time.x*time.x + corr.x*time.x + vert_d.x;
+  horz_vec.y = (-force.y+horz_d.y+corr.y )*time.y*time.y - corr.y*time.y - horz_d.y;
+  vert_vec.y = (-3.0*vert_d.y+2.0*force.y )*time.x*time.x*time.x + (-3.0*force.y+5.0*vert_d.y )*time.x*time.x - vert_d.y*time.x - vert_d.y;
+  horz_vec.x = ( 3.0*horz_d.x-2.0*force.x )*time.y*time.y*time.y + ( 3.0*force.x-5.0*horz_d.x )*time.y*time.y + horz_d.x*time.y + horz_d.x;
   
-  v.xy += (factorV.y*vert_vec + factorV.x*horz_vec);  
+  v.xy += (factorV.y*vert_vec + factorV.x*horz_vec);
   }
 
 //////////////////////////////////////////////////////////////////////////////////////////////
