commit 6968a6efb2ebd5123dba8e93b762e061dd6bac97
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed May 12 00:22:36 2021 +0200

    Progress with RubikControl - finger movements during all 13 sub-stages of the 'whole' stage finished.
    Next: actually move the cube.

diff --git a/src/main/java/org/distorted/control/RubikControlWhole.java b/src/main/java/org/distorted/control/RubikControlWhole.java
index 57921a68..1a5cf5e6 100644
--- a/src/main/java/org/distorted/control/RubikControlWhole.java
+++ b/src/main/java/org/distorted/control/RubikControlWhole.java
@@ -46,6 +46,14 @@ class RubikControlWhole implements EffectListener
   private static final int NUM_NODE = 4;
   private static final int NUM_EFFE = 4;
 
+  private static final int D1 = 2600; // time it takes for the finger to appear
+  private static final int D2 =  250; // finger press
+  private static final int D3 =10000; // finger triangle
+  private static final int D4 = 3000; // fingers approach
+  private static final int D5 =10000; // fingers circle
+
+  private static final int[] DUR = { D1, D2, D3, D2, D1/4, 3*D1/4, D1/4, D2, D4, D5, D4, D2, D1 };
+
   private final RubikControl mControl;
   private DistortedEffects[] mEffects;
   private DistortedNode[] mNodes;
@@ -53,13 +61,18 @@ class RubikControlWhole implements EffectListener
   private int mStageFinished, mWidth, mHeight;
 
   private MeshQuad mQuad;
-  private DistortedTexture mTextureHand, mTextureShad, mTextureCirc;
+  private DistortedTexture mTextureShad, mTextureCirc;
 
   private Dynamic3D mDynMoveHand1, mDynMoveShad1;
   private Dynamic3D mDynScaleHand1, mDynScaleShad1;
   private MatrixEffectMove mMoveHand1, mMoveShad1;
   private MatrixEffectScale mScaleHand1, mScaleShad1;
 
+  private Dynamic3D mDynMoveHand2, mDynMoveShad2;
+  private Dynamic3D mDynScaleHand2, mDynScaleShad2;
+  private MatrixEffectMove mMoveHand2, mMoveShad2;
+  private MatrixEffectScale mScaleHand2, mScaleShad2;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    private Bitmap openBitmap(RubikActivity act, int resource)
@@ -78,8 +91,56 @@ class RubikControlWhole implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void createEffectsStage1()
+  private void resetDynamics1(int stage)
+    {
+    int dur = DUR[stage-1];
+
+    mDynMoveHand1.removeAll();
+    mDynMoveShad1.removeAll();
+    mDynScaleHand1.removeAll();
+    mDynScaleShad1.removeAll();
+
+    mDynMoveHand1.setDuration(dur);
+    mDynMoveShad1.setDuration(dur);
+    mDynScaleHand1.setDuration(dur);
+    mDynScaleShad1.setDuration(dur);
+    mDynMoveHand1.resetToBeginning();
+    mDynMoveShad1.resetToBeginning();
+    mDynScaleHand1.resetToBeginning();
+    mDynScaleShad1.resetToBeginning();
+
+    mStageFinished = stage;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void resetDynamics2(int stage)
+    {
+    int dur = DUR[stage-1];
+
+    mDynMoveHand2.removeAll();
+    mDynMoveShad2.removeAll();
+    mDynScaleHand2.removeAll();
+    mDynScaleShad2.removeAll();
+
+    mDynMoveHand2.setDuration(dur);
+    mDynMoveShad2.setDuration(dur);
+    mDynScaleHand2.setDuration(dur);
+    mDynScaleShad2.setDuration(dur);
+    mDynMoveHand2.resetToBeginning();
+    mDynMoveShad2.resetToBeginning();
+    mDynScaleHand2.resetToBeginning();
+    mDynScaleShad2.resetToBeginning();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// first finger appears and approaches the screen
+
+  private void setEffectsStage1()
     {
+    resetDynamics1(1);
+    resetDynamics2(1);
+
     float x0 = mWidth*0.55f;
     float x1 = mWidth*0.45f;
     float x2 = mWidth*0.35f;
@@ -112,90 +173,596 @@ class RubikControlWhole implements EffectListener
     mDynScaleHand1.add(pointSc);
     mDynScaleShad1.add(pointSc);
 
-    mStageFinished = 1;
+    mMoveHand1.notifyWhenFinished(this);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// first finger touches the screen
 
-  private void createEffectsStage2()
+  private void setEffectsStage2()
     {
+    resetDynamics1(2);
+
     float x2 = mWidth*0.35f;
     float y1 = mHeight*0.28f;
     float z  = 0;
     float d  = mWidth*0.01f;
     float sS = mWidth*0.0001f;
-    float sF = mWidth*0.16f;
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
 
     Static3D point3h = new Static3D(-x2  +d,-y1  +d, z);
     Static3D scaleS  = new Static3D(sS,sS,sS);
     Static3D scaleF  = new Static3D(sF,sF,sF);
+    Static3D pointH  = new Static3D(sH,sH,sH);
 
-    mDynMoveHand1.removeAll();
     mDynMoveHand1.add(point3h);
-    mDynMoveShad1.removeAll();
     mDynMoveShad1.add(point3h);
-    mDynScaleShad1.removeAll();
+    mDynScaleHand1.add(pointH);
     mDynScaleShad1.add(scaleS);
     mDynScaleShad1.add(scaleF);
-    mDynScaleShad1.resetToBeginning();
 
-    mNodes[0].changeInputSurface(mTextureCirc);
+    mScaleShad1.notifyWhenFinished(this);
 
-    mStageFinished = 2;
+    mNodes[0].changeInputSurface(mTextureCirc);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// first finger moves across the screen in a triangular fashion
 
-  private void reloadEffectsStage1()
+  private void setEffectsStage3()
     {
-    mDynMoveHand1.resetToBeginning();
-    mDynMoveShad1.resetToBeginning();
+    resetDynamics1(3);
+
+    float x2 = mWidth*0.35f;
+
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float sH = mWidth*0.33f;
+    float sF = mWidth*0.14f;
+
+    Static3D scaleS = new Static3D(sF,sF,sF);
+    Static3D pointH = new Static3D(sH,sH,sH);
+    Static3D point1 = new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point2 = new Static3D(     +d,-y1  +d, z);
+    Static3D point3 = new Static3D(+x2  +d,-y1  +d, z);
+    Static3D point4 = new Static3D(+x2  +d,     +d, z);
+    Static3D point5 = new Static3D(+x2  +d,+y1  +d, z);
+    Static3D point6 = new Static3D(     +d,     +d, z);
+
+    mDynScaleHand1.add(pointH);
+    mDynScaleShad1.add(scaleS);
+
+    mDynMoveHand1.add(point1);
+    mDynMoveHand1.add(point1);
+    mDynMoveHand1.add(point2);
+    mDynMoveHand1.add(point3);
+    mDynMoveHand1.add(point3);
+    mDynMoveHand1.add(point4);
+    mDynMoveHand1.add(point5);
+    mDynMoveHand1.add(point5);
+    mDynMoveHand1.add(point6);
+    mDynMoveHand1.add(point1);
+    mDynMoveHand1.add(point1);
+
+    mDynMoveShad1.add(point1);
+    mDynMoveShad1.add(point1);
+    mDynMoveShad1.add(point2);
+    mDynMoveShad1.add(point3);
+    mDynMoveShad1.add(point3);
+    mDynMoveShad1.add(point4);
+    mDynMoveShad1.add(point5);
+    mDynMoveShad1.add(point5);
+    mDynMoveShad1.add(point6);
+    mDynMoveShad1.add(point1);
+    mDynMoveShad1.add(point1);
+
     mMoveHand1.notifyWhenFinished(this);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// first finger un-touches the screen
+
+  private void setEffectsStage4()
+    {
+    resetDynamics1(4);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float sF = mWidth*0.0001f;
+    float sS = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+
+    Static3D point3h = new Static3D(-x2  +d,-y1  +d, z);
+    Static3D scaleS  = new Static3D(sS,sS,sS);
+    Static3D scaleF  = new Static3D(sF,sF,sF);
+    Static3D pointH  = new Static3D(sH,sH,sH);
+
+    mDynMoveHand1.add(point3h);
+    mDynMoveShad1.add(point3h);
+    mDynScaleHand1.add(pointH);
+    mDynScaleShad1.add(scaleS);
+    mDynScaleShad1.add(scaleF);
+
+    mScaleShad1.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// first finger un-touches the screen (part2)
+
+  private void setEffectsStage5()
+    {
+    resetDynamics1(5);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float s  = mWidth*0.33f;
+
+    Static3D pointH = new Static3D(-x2    ,-y1    , z);
+    Static3D point0 = new Static3D(-x2  +d,-y1  +d, z);
+    Static3D pointS = new Static3D(-x2+2*d,-y1+2*d, z);
+    Static3D pointSc = new Static3D(s,s,s);
+
+    mDynScaleHand1.add(pointSc);
+    mDynScaleShad1.add(pointSc);
+    mDynMoveHand1.add(point0);
+    mDynMoveHand1.add(pointH);
+    mDynMoveShad1.add(point0);
+    mDynMoveShad1.add(pointS);
+
+    mMoveShad1.notifyWhenFinished(this);
+    mNodes[0].changeInputSurface(mTextureShad);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// second finger appears
+
+  private void setEffectsStage6()
+    {
+    resetDynamics1(6);
+    resetDynamics2(6);
+
+    float x0 = mWidth*0.55f;
+    float x1 = mWidth*0.45f;
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float s  = mWidth*0.33f;
+
+    Static3D pointH = new Static3D(-x2    ,-y1    , z);
+    Static3D pointS = new Static3D(-x2+2*d,-y1+2*d, z);
+    Static3D pointSc= new Static3D(s,s,s);
+
+    mDynScaleHand1.add(pointSc);
+    mDynScaleShad1.add(pointSc);
+    mDynMoveHand1.add(pointH);
+    mDynMoveShad1.add(pointS);
+
+    Static3D point0h = new Static3D( x0    , y1    , z);
+    Static3D point1h = new Static3D( x1    , y1    , z);
+    Static3D point2h = new Static3D( x2    , y1    , z);
+    Static3D point0s = new Static3D( x0+2*d, y1+2*d, z);
+    Static3D point1s = new Static3D( x1+2*d, y1+2*d, z);
+    Static3D point2s = new Static3D( x2+2*d, y1+2*d, z);
+    Static3D pointSm= new Static3D(-s,s,s);
+
+    mDynMoveHand2.add(point0h);
+    mDynMoveHand2.add(point1h);
+    mDynMoveHand2.add(point2h);
+    mDynMoveHand2.add(point2h);
+    mDynMoveShad2.add(point0s);
+    mDynMoveShad2.add(point1s);
+    mDynMoveShad2.add(point2s);
+    mDynMoveShad2.add(point2s);
+    mDynScaleHand2.add(pointSm);
+    mDynScaleShad2.add(pointSm);
+
+    mMoveHand2.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers touch the screen (part1)
+
+  private void setEffectsStage7()
+    {
+    resetDynamics1(7);
+    resetDynamics2(7);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float s  = mWidth*0.33f;
+
+    Static3D point1H = new Static3D(-x2    ,-y1    , z);
+    Static3D point1F = new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point1S = new Static3D(-x2+2*d,-y1+2*d, z);
+    Static3D point1Sc= new Static3D(s,s,s);
+
+    mDynScaleHand1.add(point1Sc);
+    mDynScaleShad1.add(point1Sc);
+    mDynMoveHand1.add(point1H);
+    mDynMoveHand1.add(point1F);
+    mDynMoveShad1.add(point1S);
+    mDynMoveShad1.add(point1F);
+
+    Static3D point2H = new Static3D( x2    , y1    , z);
+    Static3D point2F = new Static3D( x2  +d, y1  +d, z);
+    Static3D point2S = new Static3D( x2+2*d, y1+2*d, z);
+    Static3D point2Sc= new Static3D(-s,s,s);
+
+    mDynScaleHand2.add(point2Sc);
+    mDynScaleShad2.add(point2Sc);
+    mDynMoveHand2.add(point2H);
+    mDynMoveHand2.add(point2F);
+    mDynMoveShad2.add(point2S);
+    mDynMoveShad2.add(point2F);
+
+    mMoveHand2.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers touch the screen (part2)
+
+  private void setEffectsStage8()
+    {
+    resetDynamics1(8);
+    resetDynamics2(8);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float sS = mWidth*0.0001f;
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+
+    Static3D point1h= new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point2h= new Static3D( x2  +d, y1  +d, z);
+    Static3D scale1S = new Static3D( sS,sS,sS);
+    Static3D scale1F = new Static3D( sF,sF,sF);
+    Static3D point1H = new Static3D( sH,sH,sH);
+    Static3D scale2S = new Static3D(-sS,sS,sS);
+    Static3D scale2F = new Static3D(-sF,sF,sF);
+    Static3D point2H = new Static3D(-sH,sH,sH);
+
+    mDynMoveHand1.add(point1h);
+    mDynMoveShad1.add(point1h);
+    mDynScaleHand1.add(point1H);
+    mDynScaleShad1.add(scale1S);
+    mDynScaleShad1.add(scale1F);
+
+    mDynMoveHand2.add(point2h);
+    mDynMoveShad2.add(point2h);
+    mDynScaleHand2.add(point2H);
+    mDynScaleShad2.add(scale2S);
+    mDynScaleShad2.add(scale2F);
+
+    mScaleShad1.notifyWhenFinished(this);
+
+    mNodes[0].changeInputSurface(mTextureCirc);
+    mNodes[1].changeInputSurface(mTextureCirc);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers approach each other
+
+  private void setEffectsStage9()
+    {
+    resetDynamics1(9);
+    resetDynamics2(9);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float f  = 0.60f;
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+
+    Static3D point1s= new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point2s= new Static3D( x2  +d, y1  +d, z);
+    Static3D point1f= new Static3D((-x2  +d)*f,(-y1  +d)*f, z);
+    Static3D point2f= new Static3D(( x2  +d)*f,( y1  +d)*f, z);
+    Static3D scale1F = new Static3D( sF,sF,sF);
+    Static3D point1H = new Static3D( sH,sH,sH);
+    Static3D scale2F = new Static3D(-sF,sF,sF);
+    Static3D point2H = new Static3D(-sH,sH,sH);
+
+    mDynMoveHand1.add(point1s);
+    mDynMoveHand1.add(point1f);
+    mDynMoveShad1.add(point1s);
+    mDynMoveShad1.add(point1f);
+    mDynScaleHand1.add(point1H);
+    mDynScaleShad1.add(scale1F);
+
+    mDynMoveHand2.add(point2s);
+    mDynMoveHand2.add(point2f);
+    mDynMoveShad2.add(point2s);
+    mDynMoveShad2.add(point2f);
+    mDynScaleHand2.add(point2H);
+    mDynScaleShad2.add(scale2F);
+
+    mMoveShad1.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers go around
+
+  private void setEffectsStage10()
+    {
+    resetDynamics1(10);
+    resetDynamics2(10);
+
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float f  = 0.60f;
+
+    Static3D scale1F = new Static3D( sF,sF,sF);
+    Static3D point1H = new Static3D( sH,sH,sH);
+    Static3D scale2F = new Static3D(-sF,sF,sF);
+    Static3D point2H = new Static3D(-sH,sH,sH);
+
+    Static3D point0= new Static3D((-x2  +d)*f,(-y1  +d)*f, z);
+    Static3D point1= new Static3D((-x2  +d)*f,( y1  +d)*f, z);
+    Static3D point2= new Static3D(( x2  +d)*f,( y1  +d)*f, z);
+    Static3D point3= new Static3D(( x2  +d)*f,(-y1  +d)*f, z);
+
+    mDynMoveHand1.add(point0);
+    mDynMoveHand1.add(point1);
+    mDynMoveHand1.add(point2);
+    mDynMoveHand1.add(point3);
+    mDynMoveHand1.add(point0);
+    mDynMoveShad1.add(point0);
+    mDynMoveShad1.add(point1);
+    mDynMoveShad1.add(point2);
+    mDynMoveShad1.add(point3);
+    mDynMoveShad1.add(point0);
+    mDynScaleHand1.add(point1H);
+    mDynScaleShad1.add(scale1F);
+
+    mDynMoveHand2.add(point2);
+    mDynMoveHand2.add(point3);
+    mDynMoveHand2.add(point0);
+    mDynMoveHand2.add(point1);
+    mDynMoveHand2.add(point2);
+    mDynMoveShad2.add(point2);
+    mDynMoveShad2.add(point3);
+    mDynMoveShad2.add(point0);
+    mDynMoveShad2.add(point1);
+    mDynMoveShad2.add(point2);
+    mDynScaleHand2.add(point2H);
+    mDynScaleShad2.add(scale2F);
+
+    mDynMoveHand1.setConvexity(1.0f);
+    mDynMoveHand2.setConvexity(1.0f);
+    mDynMoveShad1.setConvexity(1.0f);
+    mDynMoveShad2.setConvexity(1.0f);
+
+    mMoveShad1.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers move away from each other
+
+  private void setEffectsStage11()
+    {
+    resetDynamics1(11);
+    resetDynamics2(11);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float f  = 0.60f;
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+
+    Static3D point1s= new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point2s= new Static3D( x2  +d, y1  +d, z);
+    Static3D point1f= new Static3D((-x2  +d)*f,(-y1  +d)*f, z);
+    Static3D point2f= new Static3D(( x2  +d)*f,( y1  +d)*f, z);
+    Static3D scale1F= new Static3D( sF,sF,sF);
+    Static3D point1H= new Static3D( sH,sH,sH);
+    Static3D scale2F= new Static3D(-sF,sF,sF);
+    Static3D point2H= new Static3D(-sH,sH,sH);
+
+    mDynMoveHand1.add(point1f);
+    mDynMoveHand1.add(point1s);
+    mDynMoveShad1.add(point1f);
+    mDynMoveShad1.add(point1s);
+    mDynScaleHand1.add(point1H);
+    mDynScaleShad1.add(scale1F);
+
+    mDynMoveHand2.add(point2f);
+    mDynMoveHand2.add(point2s);
+    mDynMoveShad2.add(point2f);
+    mDynMoveShad2.add(point2s);
+    mDynScaleHand2.add(point2H);
+    mDynScaleShad2.add(scale2F);
+
+    mDynMoveHand1.setConvexity(0.0f);
+    mDynMoveHand2.setConvexity(0.0f);
+    mDynMoveShad1.setConvexity(0.0f);
+    mDynMoveShad2.setConvexity(0.0f);
+
+    mMoveShad1.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers un-touch the screen (part1)
+
+  private void setEffectsStage12()
+    {
+    resetDynamics1(12);
+    resetDynamics2(12);
+
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float sS = mWidth*0.0001f;
+    float sF = mWidth*0.14f;
+    float sH = mWidth*0.33f;
+
+    Static3D point1h= new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point2h= new Static3D( x2  +d, y1  +d, z);
+    Static3D scale1S = new Static3D( sS,sS,sS);
+    Static3D scale1F = new Static3D( sF,sF,sF);
+    Static3D point1H = new Static3D( sH,sH,sH);
+    Static3D scale2S = new Static3D(-sS,sS,sS);
+    Static3D scale2F = new Static3D(-sF,sF,sF);
+    Static3D point2H = new Static3D(-sH,sH,sH);
+
+    mDynMoveHand1.add(point1h);
+    mDynMoveShad1.add(point1h);
+    mDynScaleHand1.add(point1H);
+    mDynScaleShad1.add(scale1F);
+    mDynScaleShad1.add(scale1S);
+
+    mDynMoveHand2.add(point2h);
+    mDynMoveShad2.add(point2h);
+    mDynScaleHand2.add(point2H);
+    mDynScaleShad2.add(scale2F);
+    mDynScaleShad2.add(scale2S);
+
+    mScaleShad1.notifyWhenFinished(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// both fingers un-touch the screen (part2)
+
+  private void setEffectsStage13()
+    {
+    resetDynamics1(13);
+    resetDynamics2(13);
+
+    float x0 = mWidth*0.55f;
+    float x1 = mWidth*0.45f;
+    float x2 = mWidth*0.35f;
+    float y1 = mHeight*0.28f;
+    float z  = 0;
+    float d  = mWidth*0.01f;
+    float s  = mWidth*0.33f;
+
+    Static3D point1_0 = new Static3D(-x2  +d,-y1  +d, z);
+    Static3D point11H = new Static3D(-x2    ,-y1    , z);
+    Static3D point12H = new Static3D(-x1    ,-y1    , z);
+    Static3D point13H = new Static3D(-x0    ,-y1    , z);
+    Static3D point11S = new Static3D(-x2+2*d,-y1+2*d, z);
+    Static3D point12S = new Static3D(-x1+2*d,-y1+2*d, z);
+    Static3D point13S = new Static3D(-x0+2*d,-y1+2*d, z);
+    Static3D point1Sc = new Static3D( s,s,s);
+
+    mDynScaleHand1.add(point1Sc);
+    mDynScaleShad1.add(point1Sc);
+    mDynMoveHand1.add(point1_0);
+    mDynMoveHand1.add(point11H);
+    mDynMoveHand1.add(point11H);
+    mDynMoveHand1.add(point12H);
+    mDynMoveHand1.add(point13H);
+    mDynMoveShad1.add(point1_0);
+    mDynMoveShad1.add(point11S);
+    mDynMoveShad1.add(point11S);
+    mDynMoveShad1.add(point12S);
+    mDynMoveShad1.add(point13S);
+
+    Static3D point2_0 = new Static3D( x2  +d, y1  +d, z);
+    Static3D point21H = new Static3D( x2    , y1    , z);
+    Static3D point22H = new Static3D( x1    , y1    , z);
+    Static3D point23H = new Static3D( x0    , y1    , z);
+    Static3D point21S = new Static3D( x2+2*d, y1+2*d, z);
+    Static3D point22S = new Static3D( x1+2*d, y1+2*d, z);
+    Static3D point23S = new Static3D( x0+2*d, y1+2*d, z);
+    Static3D point2Sc= new Static3D(-s,s,s);
+
+    mDynScaleHand2.add(point2Sc);
+    mDynScaleShad2.add(point2Sc);
+    mDynMoveHand2.add(point2_0);
+    mDynMoveHand2.add(point21H);
+    mDynMoveHand2.add(point21H);
+    mDynMoveHand2.add(point22H);
+    mDynMoveHand2.add(point23H);
+    mDynMoveShad2.add(point2_0);
+    mDynMoveShad2.add(point21S);
+    mDynMoveShad2.add(point21S);
+    mDynMoveShad2.add(point22S);
+    mDynMoveShad2.add(point23S);
+
+    mMoveHand2.notifyWhenFinished(this);
+
+    mNodes[0].changeInputSurface(mTextureShad);
+    mNodes[1].changeInputSurface(mTextureShad);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void createEffects()
     {
-    if( mEffects==null )
-      {
-      mEffects = new DistortedEffects[NUM_EFFE];
-      for(int i=0; i<NUM_EFFE; i++) mEffects[i]= new DistortedEffects();
-
-      int time = 3000;
-
-      mDynMoveHand1 = new Dynamic3D(time,0.5f);
-      mDynMoveHand1.setMode(Dynamic.MODE_PATH);
-      mDynMoveHand1.setConvexity(0.0f);
-      mDynMoveShad1 = new Dynamic3D(time,0.5f);
-      mDynMoveShad1.setMode(Dynamic.MODE_PATH);
-      mDynMoveShad1.setConvexity(0.0f);
-      mDynScaleHand1 = new Dynamic3D(time,0.5f);
-      mDynScaleHand1.setMode(Dynamic.MODE_PATH);
-      mDynScaleHand1.setConvexity(0.0f);
-      mDynScaleShad1 = new Dynamic3D(time,0.5f);
-      mDynScaleShad1.setMode(Dynamic.MODE_PATH);
-      mDynScaleShad1.setConvexity(0.0f);
-
-      mMoveHand1 = new MatrixEffectMove(mDynMoveHand1);
-      mMoveShad1 = new MatrixEffectMove(mDynMoveShad1);
-      mScaleHand1= new MatrixEffectScale(mDynScaleHand1);
-      mScaleShad1= new MatrixEffectScale(mDynScaleShad1);
-
-      mMoveHand1.notifyWhenFinished(this);
-
-      mEffects[0].apply(mScaleShad1);
-      mEffects[0].apply(mMoveShad1);
-      mEffects[2].apply(mScaleHand1);
-      mEffects[2].apply(mMoveHand1);
-
-      DistortedScreen screen = mControl.getScreen();
-      mWidth = screen.getWidth();
-      mHeight= screen.getHeight();
-
-      createEffectsStage1();
-      }
-    else reloadEffectsStage1();
+    mEffects = new DistortedEffects[NUM_EFFE];
+    for(int i=0; i<NUM_EFFE; i++) mEffects[i]= new DistortedEffects();
+
+    int time = DUR[0];
+
+    mDynMoveHand1 = new Dynamic3D(time,0.5f);
+    mDynMoveHand1.setMode(Dynamic.MODE_PATH);
+    mDynMoveHand1.setConvexity(0.0f);
+    mDynMoveShad1 = new Dynamic3D(time,0.5f);
+    mDynMoveShad1.setMode(Dynamic.MODE_PATH);
+    mDynMoveShad1.setConvexity(0.0f);
+    mDynScaleHand1 = new Dynamic3D(time,0.5f);
+    mDynScaleHand1.setMode(Dynamic.MODE_PATH);
+    mDynScaleHand1.setConvexity(0.0f);
+    mDynScaleShad1 = new Dynamic3D(time,0.5f);
+    mDynScaleShad1.setMode(Dynamic.MODE_PATH);
+    mDynScaleShad1.setConvexity(0.0f);
+
+    mMoveHand1 = new MatrixEffectMove(mDynMoveHand1);
+    mMoveShad1 = new MatrixEffectMove(mDynMoveShad1);
+    mScaleHand1= new MatrixEffectScale(mDynScaleHand1);
+    mScaleShad1= new MatrixEffectScale(mDynScaleShad1);
+
+    mEffects[0].apply(mScaleShad1);
+    mEffects[0].apply(mMoveShad1);
+    mEffects[2].apply(mScaleHand1);
+    mEffects[2].apply(mMoveHand1);
+
+    mDynMoveHand2 = new Dynamic3D(time,0.5f);
+    mDynMoveHand2.setMode(Dynamic.MODE_PATH);
+    mDynMoveHand2.setConvexity(0.0f);
+    mDynMoveShad2 = new Dynamic3D(time,0.5f);
+    mDynMoveShad2.setMode(Dynamic.MODE_PATH);
+    mDynMoveShad2.setConvexity(0.0f);
+    mDynScaleHand2 = new Dynamic3D(time,0.5f);
+    mDynScaleHand2.setMode(Dynamic.MODE_PATH);
+    mDynScaleHand2.setConvexity(0.0f);
+    mDynScaleShad2 = new Dynamic3D(time,0.5f);
+    mDynScaleShad2.setMode(Dynamic.MODE_PATH);
+    mDynScaleShad2.setConvexity(0.0f);
+
+    mMoveHand2 = new MatrixEffectMove(mDynMoveHand2);
+    mMoveShad2 = new MatrixEffectMove(mDynMoveShad2);
+    mScaleHand2= new MatrixEffectScale(mDynScaleHand2);
+    mScaleShad2= new MatrixEffectScale(mDynScaleShad2);
+
+    mEffects[1].apply(mScaleShad2);
+    mEffects[1].apply(mMoveShad2);
+    mEffects[3].apply(mScaleHand2);
+    mEffects[3].apply(mMoveHand2);
+
+    DistortedScreen screen = mControl.getScreen();
+    mWidth = screen.getWidth();
+    mHeight= screen.getHeight();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -220,13 +787,13 @@ class RubikControlWhole implements EffectListener
       mTextureCirc.setTexture(bmpCirc);
       mTextureShad = new DistortedTexture();
       mTextureShad.setTexture(bmpShad);
-      mTextureHand = new DistortedTexture();
-      mTextureHand.setTexture(bmpHand);
+      DistortedTexture textureHand = new DistortedTexture();
+      textureHand.setTexture(bmpHand);
 
       mNodes[0]= new DistortedNode(mTextureShad,mEffects[0],mQuad);
       mNodes[1]= new DistortedNode(mTextureShad,mEffects[1],mQuad);
-      mNodes[2]= new DistortedNode(mTextureHand,mEffects[2],mQuad);
-      mNodes[3]= new DistortedNode(mTextureHand,mEffects[3],mQuad);
+      mNodes[2]= new DistortedNode( textureHand,mEffects[2],mQuad);
+      mNodes[3]= new DistortedNode( textureHand,mEffects[3],mQuad);
       }
     else
       {
@@ -245,8 +812,9 @@ class RubikControlWhole implements EffectListener
 
   DistortedNode[] getNodes()
     {
-    createEffects();
+    if( mEffects==null ) createEffects();
     createNodes();
+    setEffectsStage1();
 
     return mNodes;
     }
@@ -272,11 +840,21 @@ class RubikControlWhole implements EffectListener
     {
     switch( mStageFinished )
       {
-      case 1: createEffectsStage2();
-              break;
-      case 2: mEffectID = -1;
-              mControl.effectFinished(mEffectID);
-              break;
+      case  1: setEffectsStage2(); break;
+      case  2: setEffectsStage3(); break;
+      case  3: setEffectsStage4(); break;
+      case  4: setEffectsStage5(); break;
+      case  5: setEffectsStage6(); break;
+      case  6: setEffectsStage7(); break;
+      case  7: setEffectsStage8(); break;
+      case  8: setEffectsStage9(); break;
+      case  9: setEffectsStage10();break;
+      case 10: setEffectsStage11();break;
+      case 11: setEffectsStage12();break;
+      case 12: setEffectsStage13();break;
+      default: mEffectID = -1;
+               mControl.effectFinished(mEffectID);
+               break;
       }
     }
   }
