commit b2dc3c19955695952e095a683fd28329d6895cd9
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Fri Feb 3 21:45:28 2017 +0000

    Back out the last change.

diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 005498f..dcebb81 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -214,7 +214,7 @@ void restrictZ(inout float v)
 //        along the force line is.
 //        0<=C<1 looks completely ridiculous and C<0 destroys the system.
 
-void deform(in int effect, inout vec3 v)
+void deform(in int effect, inout vec3 v, inout vec3 n)
   {
   const vec2 ONE = vec2(1.0,1.0);
 
@@ -247,25 +247,29 @@ void deform(in int effect, inout vec3 v)
 
   v.x -= (mvXvert+mvXhorz);
   v.y -= (mvYvert+mvYhorz);
+
   v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0);                          // thick bubble
+  float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom;//
+
+  n.xy += n.z*b*ps;
   }
 
 //////////////////////////////////////////////////////////////////////////////////////////////
 // DISTORT EFFECT
 //
-// Point (Px,Py) gets moved by vector (Wx,Wy,Wz) where Wx/Wy = Vx/Vy i.e. Wx=aVx and Wy=aVy where 
-// a=Py/Sy (N --> when (Px,Py) is above (Sx,Sy)) or a=Px/Sx (W) or a=(w-Px)/(w-Sx) (E) or a=(h-Py)/(h-Sy) (S) 
+// Point (Px,Py) gets moved by vector (Wx,Wy,Wz) where Wx/Wy = Vx/Vy i.e. Wx=aVx and Wy=aVy where
+// a=Py/Sy (N --> when (Px,Py) is above (Sx,Sy)) or a=Px/Sx (W) or a=(w-Px)/(w-Sx) (E) or a=(h-Py)/(h-Sy) (S)
 // It remains to be computed which of the N,W,E or S case we have: answer: a = min[ Px/Sx , Py/Sy , (w-Px)/(w-Sx) , (h-Py)/(h-Sy) ]
 // Computations above are valid for screen (0,0)x(w,h) but here we have (-w/2,-h/2)x(w/2,h/2)
-//  
+//
 // the vertical part
 // Let |(v.x,v.y),(ux,uy)| = |PS|, ux-v.x=dx,uy-v.y=dy, f(x) (0<=x<=|SX|) be the shape of the side of the bubble.
 // H(v.x,v.y) = |PS|>|SX| ? 0 : f(|PX|)
-// N(v.x,v.y) = |PS|>|SX| ? (0,0,1) : ( -(dx/|PS|)sin(beta), -(dy/|PS|)sin(beta), cos(beta) ) where tan(beta) is f'(|PX|) 
-// ( i.e. normalize( dx, dy, -|PS|/f'(|PX|))         
+// N(v.x,v.y) = |PS|>|SX| ? (0,0,1) : ( -(dx/|PS|)sin(beta), -(dy/|PS|)sin(beta), cos(beta) ) where tan(beta) is f'(|PX|)
+// ( i.e. normalize( dx, dy, -|PS|/f'(|PX|))
 //
 // Now we also have to take into account the effect horizontal move by V=(u_dVx[i],u_dVy[i]) will have on the normal vector.
-// Solution: 
+// Solution:
 // 1. Decompose the V into two subcomponents, one parallel to SX and another perpendicular.
 // 2. Convince yourself (draw!) that the perpendicular component has no effect on normals.
 // 3. The parallel component changes the length of |SX| by the factor of a=(|SX|-|Vpar|)/|SX| (where the length
@@ -273,66 +277,74 @@ void deform(in int effect, inout vec3 v)
 // 4. that in turn leaves the x and y parts of the normal unchanged and multiplies the z component by a!
 //
 // |Vpar| = (u_dVx[i]*dx - u_dVy[i]*dy) / sqrt(ps_sq) = (Vx*dx-Vy*dy)/ sqrt(ps_sq)  (-Vy because y is inverted)
-// a =  (|SX| - |Vpar|)/|SX| = 1 - |Vpar|/((sqrt(ps_sq)/(1-d)) = 1 - (1-d)*|Vpar|/sqrt(ps_sq) = 1-(1-d)*(Vx*dx-Vy*dy)/ps_sq 
+// a =  (|SX| - |Vpar|)/|SX| = 1 - |Vpar|/((sqrt(ps_sq)/(1-d)) = 1 - (1-d)*|Vpar|/sqrt(ps_sq) = 1-(1-d)*(Vx*dx-Vy*dy)/ps_sq
 //
 // Side of the bubble
-// 
-// choose from one of the three bubble shapes: the cone, the thin bubble and the thick bubble          
-// Case 1: 
+//
+// choose from one of the three bubble shapes: the cone, the thin bubble and the thick bubble
+// Case 1:
 // f(t) = t, i.e. f(x) = uz * x/|SX|   (a cone)
 // -|PS|/f'(|PX|) = -|PS|*|SX|/uz but since ps_sq=|PS|^2 and d=|PX|/|SX| then |PS|*|SX| = ps_sq/(1-d)
 // so finally -|PS|/f'(|PX|) = -ps_sq/(uz*(1-d))
-//                    
-// Case 2: 
+//
+// Case 2:
 // f(t) = 3t^2 - 2t^3 --> f(0)=0, f'(0)=0, f'(1)=0, f(1)=1 (the bell curve)
 // here we have t = x/|SX| which makes f'(|PX|) = 6*uz*|PS|*|PX|/|SX|^3.
 // so -|PS|/f'(|PX|) = (-|SX|^3)/(6uz|PX|) =  (-|SX|^2) / (6*uz*d) but
 // d = |PX|/|SX| and ps_sq = |PS|^2 so |SX|^2 = ps_sq/(1-d)^2
 // so finally -|PS|/f'(|PX|) = -ps_sq/ (6uz*d*(1-d)^2)
-//                  
+//
 // Case 3:
 // f(t) = 3t^4-8t^3+6t^2 would be better as this satisfies f(0)=0, f'(0)=0, f'(1)=0, f(1)=1,
 // f(0.5)=0.7 and f'(t)= t(t-1)^2 >=0 for t>=0 so this produces a fuller, thicker bubble!
-// then -|PS|/f'(|PX|) = (-|PS|*|SX)) / (12uz*d*(d-1)^2) but |PS|*|SX| = ps_sq/(1-d) (see above!) 
-// so finally -|PS|/f'(|PX|) = -ps_sq/ (12uz*d*(1-d)^3)  
+// then -|PS|/f'(|PX|) = (-|PS|*|SX)) / (12uz*d*(d-1)^2) but |PS|*|SX| = ps_sq/(1-d) (see above!)
+// so finally -|PS|/f'(|PX|) = -ps_sq/ (12uz*d*(1-d)^3)
 //
 // Now, new requirement: we have to be able to add up normal vectors, i.e. distort already distorted surfaces.
 // If a surface is given by z = f(x,y), then the normal vector at (x0,y0) is given by (-df/dx (x0,y0), -df/dy (x0,y0), 1 ).
-// so if we have two surfaces defined by f1(x,y) and f2(x,y) with their normals expressed as (f1x,f1y,1) and (f2x,f2y,1) 
+// so if we have two surfaces defined by f1(x,y) and f2(x,y) with their normals expressed as (f1x,f1y,1) and (f2x,f2y,1)
 // then the normal to g = f1+f2 is simply given by (f1x+f2x,f1y+f2y,1), i.e. if the third components are equal, then we
 // can simply add up the first and second components.
 //
 // Thus we actually want to compute N(v.x,v.y) = a*(-(dx/|PS|)*f'(|PX|), -(dy/|PS|)*f'(|PX|), 1) and keep adding
 // the first two components. (a is the horizontal part)
-        
-void distort(in int effect, inout vec3 v)
+
+void distort(in int effect, inout vec3 v, inout vec3 n)
   {
   vec2 center = vUniforms[effect+1].yz;
   vec2 ps = center-v.xy;
   vec3 force = vUniforms[effect].xyz;
   float d = degree(vUniforms[effect+2],center,ps);
+  float denom = dot(ps+(1.0-d)*force.xy,ps);
+  float one_over_denom = 1.0/(denom-0.001*(sign(denom)-1.0));          // = denom==0 ? 1000:1/denom;
+
+  //v.z += force.z*d;                                                  // cone
+  //b = -(force.z*(1.0-d))*one_over_denom;                             //
 
-  //v.z += force.z*d;                       // cone
-  //v.z += force.z*d*d*(3.0-2.0*d);         // thin bubble
-  v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0); // thick bubble
+  //v.z += force.z*d*d*(3.0-2.0*d);                                    // thin bubble
+  //b = -(6.0*force.z*d*(1.0-d)*(1.0-d))*one_over_denom;               //
+
+  v.z += force.z*d*d*(3.0*d*d -8.0*d +6.0);                            // thick bubble
+  float b = -(12.0*force.z*d*(1.0-d)*(1.0-d)*(1.0-d))*one_over_denom;  //
 
   v.xy += d*force.xy;
+  n.xy += n.z*b*ps;
   }
- 
+
 //////////////////////////////////////////////////////////////////////////////////////////////
 // SINK EFFECT
 //
 // Pull P=(v.x,v.y) towards center of the effect with P' = P + (1-h)*dist(S-P)
 // when h>1 we are pushing points away from S: P' = P + (1/h-1)*dist(S-P)
- 
+
 void sink(in int effect,inout vec3 v)
   {
   vec2 center = vUniforms[effect+1].yz;
   vec2 ps = center-v.xy;
   float h = vUniforms[effect].x;
   float t = degree(vUniforms[effect+2],center,ps) * (1.0-h)/max(1.0,h);
-  
-  v.xy += t*ps;           
+
+  v.xy += t*ps;
   }
 
 //////////////////////////////////////////////////////////////////////////////////////////////
@@ -360,7 +372,7 @@ void pinch(in int effect,inout vec3 v)
 // SWIRL EFFECT
 //
 // Let d be the degree of the current vertex V with respect to center of the effect S and Region vRegion.
-// This effect rotates the current vertex V by vInterpolated.x radians clockwise around the circle dilated 
+// This effect rotates the current vertex V by vInterpolated.x radians clockwise around the circle dilated
 // by (1-d) around the center of the effect S.
 
 void swirl(in int effect, inout vec3 v)
@@ -448,7 +460,7 @@ void swirl(in int effect, inout vec3 v)
 //
 // Generally speaking I'd keep to amplitude < length, as the opposite case has some other problems as well.
 
-void wave(in int effect, inout vec3 v)
+void wave(in int effect, inout vec3 v, inout vec3 n)
   {
   vec2 center     = vUniforms[effect+1].yz;
   float amplitude = vUniforms[effect  ].x;
@@ -473,84 +485,68 @@ void wave(in int effect, inout vec3 v)
     vec3 dir= vec3(sinB*cosA,cosB*cosA,sinA);
 
     v += sin(angle)*deg*dir;
+
+    if( n.z != 0.0 )
+      {
+      float sqrtX = sqrt(dir.y*dir.y + dir.z*dir.z);
+      float sqrtY = sqrt(dir.x*dir.x + dir.z*dir.z);
+
+      float sinX = ( sqrtY==0.0 ? 0.0 : dir.z / sqrtY);
+      float cosX = ( sqrtY==0.0 ? 1.0 : dir.x / sqrtY);
+      float sinY = ( sqrtX==0.0 ? 0.0 : dir.z / sqrtX);
+      float cosY = ( sqrtX==0.0 ? 1.0 : dir.y / sqrtX);
+
+      float abs_z = dir.z <0.0 ? -(sinX*sinY) : (sinX*sinY);
+
+      float tmp = 1.578*cos(angle)*deg/length;
+
+      float fx =-cosB*tmp;
+      float fy = sinB*tmp;
+
+      vec3 sx = vec3 (1.0+cosX*fx,cosY*sinX*fx,abs_z*fx);
+      vec3 sy = vec3 (cosX*sinY*fy,1.0+cosY*fy,abs_z*fy);
+
+      vec3 normal = cross(sx,sy);
+
+      if( normal.z<=0.0 )                   // Why this bizarre shit rather than the straightforward
+        {                                   //
+        normal.x= 0.0;                      // if( normal.z>0.0 )
+        normal.y= 0.0;                      //   {
+        normal.z= 1.0;                      //   n.x = (n.x*normal.z + n.z*normal.x);
+        }                                   //   n.y = (n.y*normal.z + n.z*normal.y);
+                                            //   n.z = (n.z*normal.z);
+                                            //   }
+      n.x = (n.x*normal.z + n.z*normal.x);  //
+      n.y = (n.y*normal.z + n.z*normal.y);  // ? Because if we do the above, my shitty Nexus4 crashes
+      n.z = (n.z*normal.z);                 // during shader compilation!
+      }
     }
   }
 
 #endif
 
 //////////////////////////////////////////////////////////////////////////////////////////////
-  		  
-void main()                                                 	
-  {              
+
+void main()
+  {
   vec3 v = 2.0*u_objD*a_Position;
   vec3 n = a_Normal;
 
 #if NUM_VERTEX>0
-
-  vec3 b1;
-  float len = n.x*n.x+n.y*n.y;
-  float l = u_objD.x / 2.0;
-
-  if( len>0.0 )
-    {
-    len = sqrt(len);
-    b1 = vec3( n.y/len,-n.x/len,0.0);
-    }
-  else
-    {
-    b1 = vec3(1.0,0.0,0.0);
-    }
-
-  vec3 b2 = cross(n,b1);
-  vec3 v1 = v+b1;
-  vec3 v2 = v+b2;
-
   int j=0;
 
   for(int i=0; i<vNumEffects; i++)
     {
-    if( vType[i]==DISTORT)
-      {
-      distort(j,v);
-      distort(j,v1);
-      distort(j,v2);
-      }
-    else if( vType[i]==DEFORM )
-      {
-      deform (j,v);
-      deform (j,v1);
-      deform (j,v2);
-      }
-    else if( vType[i]==SINK   )
-      {
-      sink   (j,v);
-      sink   (j,v1);
-      sink   (j,v2);
-      }
-    else if( vType[i]==PINCH  )
-      {
-      pinch  (j,v);
-      pinch  (j,v1);
-      pinch  (j,v2);
-      }
-    else if( vType[i]==SWIRL  )
-      {
-      swirl  (j,v);
-      swirl  (j,v1);
-      swirl  (j,v2);
-      }
-    else if( vType[i]==WAVE   )
-      {
-      wave   (j,v);
-      wave   (j,v1);
-      wave   (j,v2);
-      }
+         if( vType[i]==DISTORT) distort(j,v,n);
+    else if( vType[i]==DEFORM ) deform (j,v,n);
+    else if( vType[i]==SINK   ) sink   (j,v);
+    else if( vType[i]==PINCH  ) pinch  (j,v);
+    else if( vType[i]==SWIRL  ) swirl  (j,v);
+    else if( vType[i]==WAVE   ) wave   (j,v,n);
 
     j+=3;
     }
 
-  n = cross(v1-v,v2-v);
-
   restrictZ(v.z);
 #endif
    
