commit 9f34a0f64e53472397b6d42aa1e6caa13bcccef1
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Apr 27 16:35:20 2020 +0100

    new VertexEffectRotate

diff --git a/src/main/java/org/distorted/library/effect/EffectName.java b/src/main/java/org/distorted/library/effect/EffectName.java
index 862a69f..2f0398f 100644
--- a/src/main/java/org/distorted/library/effect/EffectName.java
+++ b/src/main/java/org/distorted/library/effect/EffectName.java
@@ -57,6 +57,7 @@ public enum EffectName
   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   ),
+  VERTEX_ROTATE    ( EffectType.VERTEX  ,   new float[] {0.0f}           , 4, 0,     3    , VertexEffectRotate.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/MatrixEffectRotate.java b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
index e2932f2..e75cc36 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
@@ -54,7 +54,7 @@ public class MatrixEffectRotate extends MatrixEffect
  */
   public void apply(float[] matrix, float[] uniforms, int index)
     {
-    float alpha = uniforms[NUM_UNIFORMS*index  ];
+    float angle = uniforms[NUM_UNIFORMS*index  ];
     float axisX = uniforms[NUM_UNIFORMS*index+1];
     float axisY = uniforms[NUM_UNIFORMS*index+2];
     float axisZ = uniforms[NUM_UNIFORMS*index+3];
@@ -64,7 +64,7 @@ public class MatrixEffectRotate extends MatrixEffect
     float z = uniforms[NUM_UNIFORMS*index+CENTER_OFFSET+2];
 
     Matrix.translateM(matrix, 0, x, y, z);
-    Matrix.rotateM( matrix, 0, alpha, axisX, axisY, axisZ);
+    Matrix.rotateM( matrix, 0, angle, axisX, axisY, axisZ);
     Matrix.translateM(matrix, 0,-x,-y,-z);
     }
 
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectRotate.java b/src/main/java/org/distorted/library/effect/VertexEffectRotate.java
new file mode 100644
index 0000000..7f04aba
--- /dev/null
+++ b/src/main/java/org/distorted/library/effect/VertexEffectRotate.java
@@ -0,0 +1,119 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.Data1D;
+import org.distorted.library.type.Data3D;
+import org.distorted.library.type.Data4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Deform the Mesh by applying a 3D vector of force.
+ */
+public class VertexEffectRotate extends VertexEffect
+  {
+  private Data1D mAngle;
+  private Data3D mAxis, 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);
+    mAxis.get(uniforms,index+1,currentDuration,step);
+
+    float len = uniforms[index+1]*uniforms[index+1] + uniforms[index+2]*uniforms[index+2] + uniforms[index+3]*uniforms[index+3];
+    len = (float)Math.sqrt(len);
+
+    if( len!=0 )
+      {
+      uniforms[index+1] /= len;
+      uniforms[index+2] /= len;
+      uniforms[index+3] /= len;
+      }
+
+    return mAngle.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_ROTATE,
+
+               "float angle = vUniforms[effect].x*3.1415/360.0;\n"
+             + "vec3 center = vUniforms[effect+1].yzw;         \n"
+             + "float sinHalf = sin(angle);                    \n"
+             + "float cosHalf = cos(angle);                    \n"
+
+             + "float qx = vUniforms[effect].y * sinHalf;      \n"
+             + "float qy = vUniforms[effect].z * sinHalf;      \n"
+             + "float qz = vUniforms[effect].w * sinHalf;      \n"
+             + "float qw = cosHalf;                            \n"
+
+             + "v += center;                                   \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"
+
+             + "v -= center;                                   \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 'angle' degrees around the center, along an axis.
+ *
+ * @param angle  Angle that we want to rotate the Object to. Unit: degrees
+ * @param axis   Axis of rotation
+ * @param center Coordinates of the Point we are rotating around.
+ */
+  public VertexEffectRotate(Data1D angle, Data3D axis, Data3D center)
+    {
+    super(EffectName.VERTEX_ROTATE);
+    mAngle = angle;
+    mAxis = axis;
+    mCenter = center;
+    }
+  }
