commit 833685d05024a3f34f64f172f2423a52e1a922b6
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Thu Jun 23 11:57:32 2016 +0100

    Progress with Vertex3D

diff --git a/src/main/java/org/distorted/examples/cubes/CubesRenderer.java b/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
index 2430e04..410c278 100644
--- a/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
+++ b/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
@@ -70,13 +70,9 @@ class CubesRenderer implements GLSurfaceView.Renderer
       mQuat1 = new Static4D(0,0,0,1);  // unity
       mQuat2 = new Static4D(0,0,0,1);  // quaternions
       
-      mQuatInt1 = new DynamicQuat();
-      mQuatInt2 = new DynamicQuat();
-      mQuatInt1.setDuration(0);
-      mQuatInt2.setDuration(0);
-      mQuatInt1.setCount(0.5f);
-      mQuatInt2.setCount(0.5f);
-      
+      mQuatInt1 = new DynamicQuat(0,0.5f);
+      mQuatInt2 = new DynamicQuat(0,0.5f);
+
       mQuatInt1.add(mQuat1);
       mQuatInt2.add(mQuat2);
       }
diff --git a/src/main/java/org/distorted/examples/cubes/CubesSurfaceView.java b/src/main/java/org/distorted/examples/cubes/CubesSurfaceView.java
index 8942b12..166dc48 100644
--- a/src/main/java/org/distorted/examples/cubes/CubesSurfaceView.java
+++ b/src/main/java/org/distorted/examples/cubes/CubesSurfaceView.java
@@ -32,8 +32,8 @@ import android.widget.Toast;
 
 class CubesSurfaceView extends GLSurfaceView 
 {
-    int mX, mY;
-    CubesRenderer mRenderer;
+    private int mX, mY;
+    private CubesRenderer mRenderer;
 	
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
@@ -109,11 +109,21 @@ class CubesSurfaceView extends GLSurfaceView
                                        float rz = mRenderer.mQuat2.getZ();
                                        float rw = mRenderer.mQuat2.getW();
 
+                                       // This is quaternion multiplication. (tx.ty.tz.tw)
+                                       // is now equal to (qx,qy,qz,qw)*(rx,ry,rz,rw)
                                        float tx = rw*qx - rz*qy + ry*qz + rx*qw;
                                        float ty = rw*qy + rz*qx + ry*qw - rx*qz;
                                        float tz = rw*qz + rz*qw - ry*qx + rx*qy;
                                        float tw = rw*qw - rz*qz - ry*qy - rx*qx;
-                                       
+
+                                       // The point of this is so that there are always
+                                       // exactly 2 quaternions: Quat1 representing the rotation
+                                       // accumulating only since the last screen touch, and Quat2
+                                       // which remembers the combined effect of all previous
+                                       // swipes.
+                                       // We cannot be accumulating an ever-growing list of quaternions
+                                       // and add a new one every time user swipes the screen - there
+                                       // is a limited number of slots in the EffectQueueMatrix!
                                        mRenderer.mQuat1.set(0f, 0f, 0f, 1f);
                                        mRenderer.mQuat2.set(tx, ty, tz, tw);
                                        
diff --git a/src/main/java/org/distorted/examples/vertex3d/Vertex3DRenderer.java b/src/main/java/org/distorted/examples/vertex3d/Vertex3DRenderer.java
index 0312f8f..11bdb9f 100644
--- a/src/main/java/org/distorted/examples/vertex3d/Vertex3DRenderer.java
+++ b/src/main/java/org/distorted/examples/vertex3d/Vertex3DRenderer.java
@@ -32,6 +32,7 @@ import org.distorted.library.EffectTypes;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Dynamic4D;
+import org.distorted.library.type.DynamicQuat;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static2D;
 import org.distorted.library.type.Static3D;
@@ -52,6 +53,7 @@ class Vertex3DRenderer implements GLSurfaceView.Renderer
     private GLSurfaceView mView;
     private static DistortedCubes mCube;
     private int mCols, mRows;
+    private DynamicQuat mQuatInt1, mQuatInt2;
 
     private static EffectNames[] order;
     
@@ -62,6 +64,9 @@ class Vertex3DRenderer implements GLSurfaceView.Renderer
     private static Static3D mDeformPoint, mDistortPoint;
     private static Static1D mSinkPoint, mSwirlPoint;
 
+    Static4D mQuat1, mQuat2;
+    int mScreenMin;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     public static void setDeform(float x, float y, float z)
@@ -144,6 +149,15 @@ class Vertex3DRenderer implements GLSurfaceView.Renderer
       mDistortInter.add(mDistortPoint);
       mSwirlInter.add(mSwirlPoint);
       mSinkInter.add(mSinkPoint);
+
+      mQuat1 = new Static4D(0,0,0,1);  // unity
+      mQuat2 = new Static4D(0,0,0,1);  // quaternions
+
+      mQuatInt1 = new DynamicQuat(0,0.5f);
+      mQuatInt2 = new DynamicQuat(0,0.5f);
+
+      mQuatInt1.add(mQuat1);
+      mQuatInt2.add(mQuat2);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -160,6 +174,8 @@ class Vertex3DRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
+      mScreenMin = width<height ? width:height;
+
       mCube.abortEffects(EffectTypes.MATRIX);
       float factor;
 
@@ -175,6 +191,11 @@ class Vertex3DRenderer implements GLSurfaceView.Renderer
       mCube.scale(factor);
       mCube.move( new Static3D( (width-factor*mCols*SIZE)/2 , (height-factor*mRows*SIZE)/2 , 0) );
 
+      Static3D center = new Static3D(mCols*SIZE/2,mRows*SIZE/2, 0);
+
+      mCube.quaternion(mQuatInt1, center);
+      mCube.quaternion(mQuatInt2, center);
+
       setVertexEffects();
 
       Distorted.onSurfaceChanged(width, height); 
diff --git a/src/main/java/org/distorted/examples/vertex3d/Vertex3DSurfaceView.java b/src/main/java/org/distorted/examples/vertex3d/Vertex3DSurfaceView.java
index 71b88f3..92f053a 100644
--- a/src/main/java/org/distorted/examples/vertex3d/Vertex3DSurfaceView.java
+++ b/src/main/java/org/distorted/examples/vertex3d/Vertex3DSurfaceView.java
@@ -23,28 +23,97 @@ import android.content.Context;
 import android.opengl.GLSurfaceView;
 import android.os.Build;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class Vertex3DSurfaceView extends GLSurfaceView
-{
+  {
+  private int mX, mY;
+  private Vertex3DRenderer mRenderer;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
-    public Vertex3DSurfaceView(Context c, AttributeSet attrs)
-      {
-      super(c, attrs);
+  public Vertex3DSurfaceView(Context c, AttributeSet attrs)
+    {
+    super(c, attrs);
       
-      if(!isInEditMode())
-        {
-        setEGLContextClientVersion(2);
-        
-        if( Build.FINGERPRINT.startsWith("generic") )
-          { 
-          setEGLConfigChooser(8, 8, 8, 8, 16, 0);   
-          }
+    if(!isInEditMode())
+      {
+      setEGLContextClientVersion(2);
         
-        setRenderer(new Vertex3DRenderer(this));
+      if( Build.FINGERPRINT.startsWith("generic") )
+        {
+        setEGLConfigChooser(8, 8, 8, 8, 16, 0);
         }
+
+      mRenderer = new Vertex3DRenderer(this);
+
+      setRenderer(mRenderer);
       }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @Override
+  public boolean onTouchEvent(MotionEvent event)
+    {
+    int action = event.getAction();
+    int x = (int)event.getX();
+    int y = (int)event.getY();
+
+    switch(action)
+      {
+      case MotionEvent.ACTION_DOWN: mX = x;
+                                    mY = y;
+                                    break;
+
+      case MotionEvent.ACTION_MOVE: if( mX>=0 && mY>= 0 )
+                                      {
+                                      float px = mY-y;
+                                      float py = mX-x;
+                                      float pz = 0;
+                                      float plen = (float)Math.sqrt(px*px + py*py + pz*pz);
+
+                                      if( plen>0 )
+                                        {
+                                        px /= plen;
+                                        py /= plen;
+                                        pz /= plen;
+
+                                        float cosA = (float)Math.cos(plen*3.14f/mRenderer.mScreenMin);
+                                        float sinA = (float)Math.sqrt(1-cosA*cosA);
+
+                                        mRenderer.mQuat1.set(px*sinA, py*sinA, pz*sinA, cosA);
+                                        }
+                                      }
+                                    break;
+
+      case MotionEvent.ACTION_UP  : mX = -1;
+                                    mY = -1;
+
+                                    float qx = mRenderer.mQuat1.getX();
+                                    float qy = mRenderer.mQuat1.getY();
+                                    float qz = mRenderer.mQuat1.getZ();
+                                    float qw = mRenderer.mQuat1.getW();
+
+                                    float rx = mRenderer.mQuat2.getX();
+                                    float ry = mRenderer.mQuat2.getY();
+                                    float rz = mRenderer.mQuat2.getZ();
+                                    float rw = mRenderer.mQuat2.getW();
+
+                                    float tx = rw*qx - rz*qy + ry*qz + rx*qw;
+                                    float ty = rw*qy + rz*qx + ry*qw - rx*qz;
+                                    float tz = rw*qz + rz*qw - ry*qx + rx*qy;
+                                    float tw = rw*qw - rz*qz - ry*qy - rx*qx;
+
+                                    mRenderer.mQuat1.set(0f, 0f, 0f, 1f);
+                                    mRenderer.mQuat2.set(tx, ty, tz, tw);
+
+                                    break;
+      }
+
+    return true;
+    }
 }
 
