commit 50be8733ec7e5cbe172ce67951911fcad73fe4f2
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Jan 12 16:24:38 2019 +0000

    Correct Distort.

diff --git a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
index fd7cb9f..e32616c 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
@@ -144,8 +144,9 @@ public class VertexEffectDistort extends VertexEffect
       + "  float cp =(ps.x*n.y - ps.y*n.x)*tr;                         \n"   //
       + "  vec3 psRot = vec3( ap+n.y*cp , bp-n.x*cp , dot(ps,n) );     \n"   //
 
-      + "  psRot = normalize(psRot);                                   \n"
-      + "  vec3 N = vec3( -dot(force,n)*psRot.xy, region.w );          \n"   // modified rotated normal
+      + "  float len = length(psRot);                                  \n"
+      + "  float corr= sign(len)-1.0;                                  \n"   // make N (0,0,1) if ps=(0,0,0)
+      + "  vec3 N = vec3( -dot(force,n)*psRot.xy, region.w*len-corr ); \n"   // modified rotated normal
                                                                              // dot(force,n) is rotated force.z
       + "  float an = N.x*n.z + N.z*n.x;                               \n"   // now create the normal vector
       + "  float bn = N.y*n.z + N.z*n.y;                               \n"   // back from our modified normal
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 4211d36..b3f3f91 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -72,14 +72,15 @@ float degree_object(in vec3 S, in vec3 PS)
   vec3 signA = sign(A);                      //
   vec3 signA_SQ = signA*signA;               // div = PS/A if A!=0, 0 otherwise.
   vec3 div = signA_SQ*PS/(A-(ONE-signA_SQ)); //
+  vec3 ret = sign(u_objD)-div;
 
-  float d1= div.x-div.y;
-  float d2= div.y-div.z;
-  float d3= div.x-div.z;
+  float d1= ret.x-ret.y;
+  float d2= ret.y-ret.z;
+  float d3= ret.x-ret.z;
 
-  if( d1*d2>0.0 ) return 1.0-div.y;          //
-  if( d1*d3>0.0 ) return 1.0-div.z;          // return 1-middle(div.x,div.y,div.z)
-  return 1.0-div.x;                          //
+  if( d1*d2>0.0 ) return ret.y;             //
+  if( d1*d3>0.0 ) return ret.z;             // return 1-middle(div.x,div.y,div.z)
+  return ret.x;                             // (unless size of object is 0 then 0-middle)
   }
 
 //////////////////////////////////////////////////////////////////////////////////////////////
@@ -93,7 +94,7 @@ float degree_object(in vec3 S, in vec3 PS)
 // Then, the degree of a point with respect to a given (spherical!) Region is defined by:
 //
 // If P is outside the sphere, return 0.
-// Otherwise, let X be the point where the halfline SP meets the sphere - then return |PX|/||SX|,
+// Otherwise, let X be the point where the halfline SP meets the sphere - then return |PX|/|SX|,
 // aka the 'degree' of point P.
 //
 // We solve the triangle OPX.
@@ -134,25 +135,27 @@ float degree(in vec4 region, in vec3 S, in vec3 PS)
 
   if( D<=0.0 ) return 0.0;
 
-  vec3 A = sign(PS)*u_objD.xyz + S;
+  vec3 A = sign(PS)*u_objD + S;
   vec3 signA = sign(A);
   vec3 signA_SQ = signA*signA;
   vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ));
+  vec3 ret = sign(u_objD)-div;                // if object is flat, make ret.z 0
 
-  float d1= div.x-div.y;
-  float d2= div.y-div.z;
-  float d3= div.x-div.z;
-  float E;
+  float d1= ret.x-ret.y;
+  float d2= ret.y-ret.z;
+  float d3= ret.x-ret.z;
+  float degree_object;
 
-       if( d1*d2>0.0 ) E= 1.0-div.y;
-  else if( d1*d3>0.0 ) E= 1.0-div.z;
-  else                 E= 1.0-div.x;
+       if( d1*d2>0.0 ) degree_object= ret.y;  //
+  else if( d1*d3>0.0 ) degree_object= ret.z;  // middle of the ret.{x,y,z} triple
+  else                 degree_object= ret.x;  //
 
   float ps_sq = dot(PS,PS);
   float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0));  // return 1.0 if ps_sq = 0.0
   float DOT  = dot(PS,PO)*one_over_ps_sq;
+  float degree_region = 1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT));
 
-  return min(1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)),E);
+  return min(degree_region,degree_object);
   }
 
 #endif  // NUM_VERTEX>0
