commit e979d28512f0787dd06afa557453fbfb405d6638
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Apr 25 01:18:36 2020 +0100

    Add the first two VERTEX 'pseudo-matrix' effects: VERTEX_MOVE & VERTEX_QUATERNION i.e. implementations of those two MATRIX effects in VERTEX queue.
    
    The point(s):
    
    1) preparation for the upcoming MeshBase.preApply(VertexEffect effect) API that's going to supersede the current much more limited MeshBase.apply(MatrixEffect effect)
    2) those can be put in any position in the VERTEX queue, whereas the Matrix effects always have to come last

diff --git a/src/main/java/org/distorted/library/effect/EffectName.java b/src/main/java/org/distorted/library/effect/EffectName.java
index cea4786..862a69f 100644
--- a/src/main/java/org/distorted/library/effect/EffectName.java
+++ b/src/main/java/org/distorted/library/effect/EffectName.java
@@ -55,6 +55,8 @@ public enum EffectName
   PINCH            ( EffectType.VERTEX  ,   new float[] {1.0f}           , 3, 4,     3    , VertexEffectPinch.class        ),
   SWIRL            ( EffectType.VERTEX  ,   new float[] {0.0f}           , 1, 4,     3    , VertexEffectSwirl.class        ),
   WAVE             ( EffectType.VERTEX  ,   new float[] {0.0f}           , 5, 4,     3    , VertexEffectWave.class         ),
+  VERTEX_MOVE      ( EffectType.VERTEX  ,   new float[] {0.0f,0.0f,0.0f} , 3, 0,     0    , VertexEffectMove.class         ),
+  VERTEX_QUATERNION( EffectType.VERTEX  ,   new float[] {0.0f,0.0f,0.0f} , 4, 0,     3    , VertexEffectQuaternion.class   ),
 
   ALPHA            ( EffectType.FRAGMENT,   new float[] {1.0f}           , 1, 3,     3    , FragmentEffectAlpha.class      ),
   SMOOTH_ALPHA     ( EffectType.FRAGMENT,   new float[] {1.0f}           , 1, 3,     3    , FragmentEffectAlpha.class      ),
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffect.java b/src/main/java/org/distorted/library/effect/MatrixEffect.java
index 125f532..bd3b250 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffect.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffect.java
@@ -29,6 +29,7 @@ public abstract class MatrixEffect extends Effect
  * 7: 4 per-effect interpolated values + 3 dimensional center.
  */
   public static final int NUM_UNIFORMS = 7;
+  static final int CENTER_OFFSET = 4;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
index 3c59bb5..5483326 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
@@ -44,7 +44,7 @@ public class MatrixEffectQuaternion extends MatrixEffect
  */
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
-    mCenter.get(uniforms,index+4,currentDuration,step);
+    mCenter.get(uniforms,index+CENTER_OFFSET,currentDuration,step);
     return mQuaternion.get(uniforms,index,currentDuration,step);
     }
 
@@ -61,9 +61,9 @@ public class MatrixEffectQuaternion extends MatrixEffect
     float qZ = uniforms[NUM_UNIFORMS*index+2];
     float qW = uniforms[NUM_UNIFORMS*index+3];
 
-    float x = uniforms[NUM_UNIFORMS*index+4];
-    float y = uniforms[NUM_UNIFORMS*index+5];
-    float z = uniforms[NUM_UNIFORMS*index+6];
+    float x = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET  ];
+    float y = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+1];
+    float z = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+2];
 
     Matrix.translateM(matrix, 0, x, y, z);
     multiplyByQuat( matrix, qX, qY, qZ, qW);
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
index 14c33b0..e2932f2 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
@@ -41,7 +41,7 @@ public class MatrixEffectRotate extends MatrixEffect
  */
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
-    mCenter.get(uniforms,index+4,currentDuration,step);
+    mCenter.get(uniforms,index+CENTER_OFFSET,currentDuration,step);
     mAxis.get(uniforms,index+1,currentDuration,step);
     return mAngle.get(uniforms,index,currentDuration,step);
     }
@@ -59,9 +59,9 @@ public class MatrixEffectRotate extends MatrixEffect
     float axisY = uniforms[NUM_UNIFORMS*index+2];
     float axisZ = uniforms[NUM_UNIFORMS*index+3];
 
-    float x = uniforms[NUM_UNIFORMS*index+4];
-    float y = uniforms[NUM_UNIFORMS*index+5];
-    float z = uniforms[NUM_UNIFORMS*index+6];
+    float x = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET  ];
+    float y = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+1];
+    float z = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+2];
 
     Matrix.translateM(matrix, 0, x, y, z);
     Matrix.rotateM( matrix, 0, alpha, axisX, axisY, axisZ);
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
index 6ec7c27..93e83ff 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
@@ -39,7 +39,7 @@ public class MatrixEffectShear extends MatrixEffect
  */
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
-    mCenter.get(uniforms,index+4,currentDuration,step);
+    mCenter.get(uniforms,index+CENTER_OFFSET,currentDuration,step);
     return mShear.get(uniforms,index,currentDuration,step);
     }
 
@@ -55,9 +55,9 @@ public class MatrixEffectShear extends MatrixEffect
     float sy = uniforms[NUM_UNIFORMS*index+1];
     float sz = uniforms[NUM_UNIFORMS*index+2];
 
-    float x  = uniforms[NUM_UNIFORMS*index+4];
-    float y  = uniforms[NUM_UNIFORMS*index+5];
-    float z  = uniforms[NUM_UNIFORMS*index+6];
+    float x  = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET  ];
+    float y  = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+1];
+    float z  = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+2];
 
     Matrix.translateM(matrix, 0, x, y, z);
 
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectMove.java b/src/main/java/org/distorted/library/effect/VertexEffectMove.java
new file mode 100644
index 0000000..d4d5b17
--- /dev/null
+++ b/src/main/java/org/distorted/library/effect/VertexEffectMove.java
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.effect;
+
+import org.distorted.library.type.Data3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Deform the Mesh by applying a 3D vector of force.
+ */
+public class VertexEffectMove extends VertexEffect
+  {
+  private Data3D mVector;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public boolean compute(float[] uniforms, int index, long currentDuration, long step )
+    {
+    return mVector.get(uniforms,index,currentDuration,step);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
+ */
+  public static void enable()
+    {
+    addEffect( EffectName.VERTEX_MOVE, "v += vUniforms[effect].xyz;" );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Move the whole Mesh with a (possibly changing in time) vector.
+ *
+ * @param vector Vector by which to move the Mesh.
+ */
+  public VertexEffectMove(Data3D vector)
+    {
+    super(EffectName.VERTEX_MOVE);
+    mVector = vector;
+    }
+  }
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java b/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java
new file mode 100644
index 0000000..4dd8ab4
--- /dev/null
+++ b/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2020 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.effect;
+
+import org.distorted.library.type.Data3D;
+import org.distorted.library.type.Data4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Deform the Mesh by applying a 3D vector of force.
+ */
+public class VertexEffectQuaternion extends VertexEffect
+  {
+  private Data4D mQuaternion;
+  private Data3D mCenter;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public boolean compute(float[] uniforms, int index, long currentDuration, long step )
+    {
+    mCenter.get(uniforms,index+CENTER_OFFSET,currentDuration,step);
+    return mQuaternion.get(uniforms,index,currentDuration,step);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
+ */
+  public static void enable()
+    {
+    addEffect( EffectName.VERTEX_QUATERNION,
+               "float qx = vUniforms[effect].x;               \n"
+             + "float qy = vUniforms[effect].y;               \n"
+             + "float qz = vUniforms[effect].z;               \n"
+             + "float qw = vUniforms[effect].w;               \n"
+
+             + "float tx = qx - v.z*qy + v.y*qz + v.x*qw;     \n"
+             + "float ty = qy + v.z*qx + v.y*qw - v.x*qz;     \n"
+             + "float tz = qz + v.z*qw - v.y*qx + v.x*qy;     \n"
+             + "float tw = qw - v.z*qz - v.y*qy - v.x*qx;     \n"
+
+             + "v.x = qw*tx + qz*ty - qy*tz - qx*tw;          \n"
+             + "v.y = qw*ty - qz*tx - qy*tw + qx*tz;          \n"
+             + "v.z = qw*tz - qz*tw + qy*tx - qx*ty;          \n"
+
+             + "float nx =  - n.z*qy + n.y*qz + n.x*qw;       \n"
+             + "float ny =  + n.z*qx + n.y*qw - n.x*qz;       \n"
+             + "float nz =  + n.z*qw - n.y*qx + n.x*qy;       \n"
+             + "float nw =  - n.z*qz - n.y*qy - n.x*qx;       \n"
+
+             + "n.x = qw*nx + qz*ny - qy*nz - qx*nw;          \n"
+             + "n.y = qw*ny - qz*nx - qy*nw + qx*nz;          \n"
+             + "n.z = qw*nz - qz*nw + qy*nx - qx*ny;          \n"
+             );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Rotate the Mesh by a (possibly changing in time) quaternion.
+ *
+ * @param quaternion Quaternion describing the rotation.
+ * @param center     Coordinates of the Point we are rotating around.
+ */
+  public VertexEffectQuaternion(Data4D quaternion, Data3D center )
+    {
+    super(EffectName.VERTEX_QUATERNION);
+    mQuaternion = quaternion;
+    mCenter = center;
+    }
+  }
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 4490ff9..683be1c 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -181,7 +181,7 @@ void main()
 #endif
    
   v_Position      = v;
-  v_endPosition   = v + 0.2*u_Stretch*n;
+  v_endPosition   = v + (0.2*u_Stretch.x)*n;
   v_TexCoordinate = a_TexCoordinate;
   v_Normal        = normalize(vec3(u_MVMatrix*vec4(n,0.0)));
   gl_Position     = u_MVPMatrix*vec4(v,1.0);
