commit e8764a49b7c5d019e44df25280f31dfbe6179ff5
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Jan 19 22:23:09 2020 +0000

    RubikCube: progress with scrambling

diff --git a/src/main/java/org/distorted/effect/ScrambleEffect.java b/src/main/java/org/distorted/effect/ScrambleEffect.java
index 6199f4f7..ea0380be 100644
--- a/src/main/java/org/distorted/effect/ScrambleEffect.java
+++ b/src/main/java/org/distorted/effect/ScrambleEffect.java
@@ -21,11 +21,11 @@ package org.distorted.effect;
 
 import org.distorted.library.effect.Effect;
 import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
 import org.distorted.magic.RubikCube;
 
 import java.lang.reflect.Method;
+import java.util.Random;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -61,32 +61,26 @@ public abstract class ScrambleEffect implements EffectListener
     }
 
   private EffectListener mListener;
-  private int mDuration;
-  private int[] mEffectReturned;
+  private int mEffectReturned;
+  private long mCurrentBaseEffectID;
+  private int mNumDoubleScramblesLeft, mNumScramblesLeft;
+  private int mLastVector;
+  private long mDurationSingleTurn;
+  private Random mRnd;
   private RubikCube mCube;
-  private DistortedScreen mScreen;
 
-  static final int EFFECT_FLAVOUR_BASE  = 0;
-  static final int EFFECT_FLAVOUR_PLUGIN= 1;
-  static final int NUM_EFFECT_FLAVOURS  = 2;
-
-  Effect[][] mNodeEffects;
-  int[][] mNodeEffectPosition;
-  Effect[][] mCubeEffects;
-  int[][] mCubeEffectPosition;
-  int[] mCubeEffectNumber, mNodeEffectNumber;
+  Effect[] mNodeEffects;
+  int[] mNodeEffectPosition;
+  Effect[] mCubeEffects;
+  int[] mCubeEffectPosition;
+  int mCubeEffectNumber, mNodeEffectNumber;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   ScrambleEffect()
     {
-    mEffectReturned     = new int[NUM_EFFECT_FLAVOURS];
-    mCubeEffectNumber   = new int[NUM_EFFECT_FLAVOURS];
-    mNodeEffectNumber   = new int[NUM_EFFECT_FLAVOURS];
-    mCubeEffectPosition = new int[NUM_EFFECT_FLAVOURS][];
-    mNodeEffectPosition = new int[NUM_EFFECT_FLAVOURS][];
-    mCubeEffects        = new Effect[NUM_EFFECT_FLAVOURS][];
-    mNodeEffects        = new Effect[NUM_EFFECT_FLAVOURS][];
+    mRnd = new Random( System.currentTimeMillis() );
+    mLastVector = -1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -123,141 +117,182 @@ public abstract class ScrambleEffect implements EffectListener
   abstract void effectFinishedPlugin(final long effectID);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
+
   private void createBaseEffects(int duration, int numScrambles)
     {
-    mCubeEffectNumber[EFFECT_FLAVOUR_BASE] = 0;
-    mNodeEffectNumber[EFFECT_FLAVOUR_BASE] = 0;
+    mNumScramblesLeft = numScrambles;
+
+    // compute how many out of 'numScrambles' are double turns.
+    mNumDoubleScramblesLeft=0;
+
+    for(int i=0; i<numScrambles; i++)
+      {
+      if( (mRnd.nextInt() % 3) == 0 )
+        {
+        mNumDoubleScramblesLeft++;
+        }
+      }
+
+    mDurationSingleTurn = duration/(mNumScramblesLeft+mNumDoubleScramblesLeft);
+
+    addNewScramble();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
 
-  private void effectFinishedBase(final long effectID)
+  private void addNewScramble()
     {
+    if( mNumScramblesLeft>0 )
+      {
+      if( mLastVector == -1 )
+        {
+        switch(mRnd.nextInt(3))
+          {
+          case 0: mLastVector = RubikCube.VECTX; break;
+          case 1: mLastVector = RubikCube.VECTY; break;
+          case 2: mLastVector = RubikCube.VECTZ; break;
+          }
+        }
+      else
+        {
+        int newVector = mRnd.nextInt(2);
+
+        switch(mLastVector)
+          {
+          case RubikCube.VECTX: mLastVector = (newVector==0 ? RubikCube.VECTY: RubikCube.VECTZ); break;
+          case RubikCube.VECTY: mLastVector = (newVector==0 ? RubikCube.VECTX: RubikCube.VECTZ); break;
+          case RubikCube.VECTZ: mLastVector = (newVector==0 ? RubikCube.VECTX: RubikCube.VECTY); break;
+          }
+        }
+
+      int row  = mRnd.nextInt(mCube.getSize());
+      int angle= randomizeAngle();
+      int absAngle = (angle<0 ? -angle : angle);
+      long durationMillis =  absAngle*mDurationSingleTurn;
+
+      mNumScramblesLeft--;
+      if( absAngle==2 ) mNumDoubleScramblesLeft--;
 
+      mCurrentBaseEffectID = mCube.addNewRotation(mLastVector, row, angle*90, durationMillis, this );
+      }
+    else
+      {
+      mLastVector = -1;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO;
+
+  private int randomizeAngle()
+    {
+    return 1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void effectFinished(final long effectID)
     {
-    for(int flavour=0; flavour<NUM_EFFECT_FLAVOURS; flavour++)
+    if( effectID == mCurrentBaseEffectID )
+      {
+      mCube.removeRotationNow();
+      addNewScramble();
+      return;
+      }
+
+    for(int i=0; i<mCubeEffectNumber; i++)
       {
-      for(int i=0; i<mCubeEffectNumber[flavour]; i++)
+      long id = mCubeEffects[i].getID();
+
+      if( effectID == id )
         {
-        long id = mCubeEffects[flavour][i].getID();
+        mEffectReturned++;
+        effectFinishedPlugin(effectID);
 
-        if( effectID == id )
+        if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
           {
-          mEffectReturned[flavour]++;
+          disassignEffects();
+          }
 
-          switch(flavour)
-            {
-            case EFFECT_FLAVOUR_BASE  : effectFinishedBase(  effectID); break;
-            case EFFECT_FLAVOUR_PLUGIN: effectFinishedPlugin(effectID); break;
-            }
+        return;
+        }
+      }
 
-          if( mEffectReturned[flavour] == mCubeEffectNumber[flavour]+mNodeEffectNumber[flavour] )
-            {
-            disassignEffects(flavour);
-            }
+    for(int i=0; i<mNodeEffectNumber; i++)
+      {
+      long id = mNodeEffects[i].getID();
 
-          return;
-          }
-        }
-      for(int i=0; i<mNodeEffectNumber[flavour]; i++)
+      if( effectID == id )
         {
-        long id = mNodeEffects[flavour][i].getID();
+        mEffectReturned++;
+        effectFinishedPlugin(effectID);
 
-        if( effectID == id )
+        if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
           {
-          mEffectReturned[flavour]++;
-
-          switch(flavour)
-            {
-            case EFFECT_FLAVOUR_BASE  : effectFinishedBase(  effectID); break;
-            case EFFECT_FLAVOUR_PLUGIN: effectFinishedPlugin(effectID); break;
-            }
-
-          if( mEffectReturned[flavour] == mCubeEffectNumber[flavour]+mNodeEffectNumber[flavour] )
-            {
-            disassignEffects(flavour);
-            }
-
-          return;
+          disassignEffects();
           }
+
+        return;
         }
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public long start(int duration, DistortedScreen screen, RubikCube cube, int numScrambles, EffectListener listener)
+  public long start(int duration, RubikCube cube, int numScrambles, EffectListener listener)
     {
-    mScreen   = screen;
     mCube     = cube;
     mListener = listener;
-    mDuration = duration;
-
-    createBaseEffects(mDuration, numScrambles);
-    assignEffects(EFFECT_FLAVOUR_BASE);
 
-    createEffects(mDuration);
+    createBaseEffects(duration, numScrambles);
+    createEffects(duration);
 
-    if( mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN]==0 && mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN]==0 )
+    if( mCubeEffectNumber==0 && mNodeEffectNumber==0 )
       {
       throw new RuntimeException("Cube and Node Plugin Effects not created!");
       }
 
-    assignEffects(EFFECT_FLAVOUR_PLUGIN);
+    assignEffects();
 
     return FAKE_EFFECT_ID;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void assignEffects(int flavour)
+  private void assignEffects()
     {
-    for(int i=0; i<mCubeEffectNumber[flavour]; i++)
+    for(int i=0; i<mCubeEffectNumber; i++)
       {
-      //android.util.Log.e("scramble", "applying cube effect "+mCubeEffects[flavour][i].getName());
-
-      mCube.apply(mCubeEffects[flavour][i],mCubeEffectPosition[flavour][i]);
-      mCubeEffects[flavour][i].notifyWhenFinished(this);
+      mCube.apply(mCubeEffects[i],mCubeEffectPosition[i]);
+      mCubeEffects[i].notifyWhenFinished(this);
       }
 
     DistortedEffects nodeEffects = mCube.getEffects();
 
-    for(int i=0; i<mNodeEffectNumber[flavour]; i++)
+    for(int i=0; i<mNodeEffectNumber; i++)
       {
-      nodeEffects.apply(mNodeEffects[flavour][i],mNodeEffectPosition[flavour][i]);
-      mNodeEffects[flavour][i].notifyWhenFinished(this);
+      nodeEffects.apply(mNodeEffects[i],mNodeEffectPosition[i]);
+      mNodeEffects[i].notifyWhenFinished(this);
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void disassignEffects(int flavour)
+  private void disassignEffects()
     {
-    for(int i=0; i<mCubeEffectNumber[flavour]; i++)
+    for(int i=0; i<mCubeEffectNumber; i++)
       {
-      //android.util.Log.e("scramble", "removing cube effect "+mCubeEffects[flavour][i].getName());
-
-      mCube.remove(mCubeEffects[flavour][i].getID());
+      mCube.remove(mCubeEffects[i].getID());
       }
 
     DistortedEffects nodeEffects = mCube.getEffects();
 
-    for(int i=0; i<mNodeEffectNumber[flavour]; i++)
+    for(int i=0; i<mNodeEffectNumber; i++)
       {
-      nodeEffects.abortById(mNodeEffects[flavour][i].getID());
+      nodeEffects.abortById(mNodeEffects[i].getID());
       }
 
-    if( flavour==EFFECT_FLAVOUR_PLUGIN )
-      {
-      mListener.effectFinished(FAKE_EFFECT_ID);
-      }
+    mListener.effectFinished(FAKE_EFFECT_ID);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/ScrambleEffectNone.java b/src/main/java/org/distorted/effect/ScrambleEffectNone.java
index b78d548f..b8d5bf4f 100644
--- a/src/main/java/org/distorted/effect/ScrambleEffectNone.java
+++ b/src/main/java/org/distorted/effect/ScrambleEffectNone.java
@@ -33,12 +33,12 @@ public class ScrambleEffectNone extends ScrambleEffect
     Dynamic3D d0 = new Dynamic3D(1,0.5f);
     d0.add(new Static3D(0,0,0));
 
-    mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN]   = 1;
-    mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN]   = 0;
+    mCubeEffectNumber   = 1;
+    mNodeEffectNumber   = 0;
 
-    mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN] = new int[] {-1};
-    mCubeEffects[EFFECT_FLAVOUR_PLUGIN]        = new Effect[mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN].length];
-    mCubeEffects[EFFECT_FLAVOUR_PLUGIN][0]     = new MatrixEffectMove(d0);
+    mCubeEffectPosition = new int[] {-1};
+    mCubeEffects        = new Effect[mCubeEffectPosition.length];
+    mCubeEffects[0]     = new MatrixEffectMove(d0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/ScrambleEffectRotations.java b/src/main/java/org/distorted/effect/ScrambleEffectRotations.java
index 252626b7..381a93b3 100644
--- a/src/main/java/org/distorted/effect/ScrambleEffectRotations.java
+++ b/src/main/java/org/distorted/effect/ScrambleEffectRotations.java
@@ -42,10 +42,10 @@ public class ScrambleEffectRotations extends ScrambleEffect
 
   public void createEffects(int duration)
     {
-    mCubeEffectNumber[EFFECT_FLAVOUR_PLUGIN]   = 2;
-    mNodeEffectNumber[EFFECT_FLAVOUR_PLUGIN]   = 0;
-    mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN] = new int[] {6,7};
-    mCubeEffects[EFFECT_FLAVOUR_PLUGIN]        = new Effect[mCubeEffectPosition[EFFECT_FLAVOUR_PLUGIN].length];
+    mCubeEffectNumber   = 2;
+    mNodeEffectNumber   = 0;
+    mCubeEffectPosition = new int[] {6,7};
+    mCubeEffects        = new Effect[mCubeEffectPosition.length];
 
     mRnd.setSeed(System.currentTimeMillis());
 
@@ -57,7 +57,7 @@ public class ScrambleEffectRotations extends ScrambleEffect
     dq.add(generateNewRandomPoint());
     dq.add(new Static4D(0,0,0,1));
 
-    mCubeEffects[EFFECT_FLAVOUR_PLUGIN][0] = new MatrixEffectQuaternion(dq, new Static3D(0,0,0));
+    mCubeEffects[0] = new MatrixEffectQuaternion(dq, new Static3D(0,0,0));
 
     float Z = TEXTURE_SIZE/3;
 
@@ -66,7 +66,7 @@ public class ScrambleEffectRotations extends ScrambleEffect
     d0.add(new Static3D( 0, 0, 0));
     d0.add(new Static3D( 0, 0,-Z));
     d0.add(new Static3D( 0, 0, 0));
-    mCubeEffects[EFFECT_FLAVOUR_PLUGIN][1] = new MatrixEffectMove(d0);
+    mCubeEffects[1] = new MatrixEffectMove(d0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikCube.java b/src/main/java/org/distorted/magic/RubikCube.java
index 50179f8d..d741b527 100644
--- a/src/main/java/org/distorted/magic/RubikCube.java
+++ b/src/main/java/org/distorted/magic/RubikCube.java
@@ -53,6 +53,10 @@ public class RubikCube extends DistortedNode
     private static final Static3D VectY = new Static3D(0,1,0);
     private static final Static3D VectZ = new Static3D(0,0,1);
 
+    public static final int VECTX = 0;  //
+    public static final int VECTY = 1;  // don't change this
+    public static final int VECTZ = 2;  //
+
     private DistortedNode[][][] mNodes;
     private MeshCubes[][][] mCubes;
     private DistortedEffects[][][] mEffects;
@@ -89,7 +93,7 @@ public class RubikCube extends DistortedNode
       mNodeMove = new Static3D(0,0,0);
       mNodeScale= new Static3D(1,1,1);
 
-      mRotAxis= RubikSurfaceView.VECTX;
+      mRotAxis = VECTX;
       mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
 
       mNodes          = new DistortedNode[mSize][mSize][mSize];
@@ -278,6 +282,58 @@ public class RubikCube extends DistortedNode
       return mEffects[0][0][0].getNumEffects(type);
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener )
+      {
+      Static3D axis = VectX;
+      long effectID=0;
+      boolean first = true;
+
+      switch(vector)
+        {
+        case VECTX: axis = VectX; break;
+        case VECTY: axis = VectY; break;
+        case VECTZ: axis = VectZ; break;
+        }
+
+      mRotAxis = vector;
+      mRotRow  = row;
+
+      mRotationAngleStatic.set1(0.0f);
+
+      for(int x=0; x<mSize; x++)
+        for(int y=0; y<mSize; y++)
+          for(int z=0; z<mSize; z++)
+            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
+              {
+              if( belongsToRotation(x,y,z,vector,mRotRow) )
+                {
+                mRotationAxis[x][y][z].set(axis);
+                mRotationAngle[x][y][z].setDuration(durationMillis);
+                mRotationAngle[x][y][z].resetToBeginning();
+                mRotationAngle[x][y][z].add(new Static1D(0));
+                mRotationAngle[x][y][z].add(new Static1D(angle));
+
+                if( first )
+                  {
+                  first = false;
+                  effectID = mRotateEffect[x][y][z].getID();
+                  mRotateEffect[x][y][z].notifyWhenFinished(listener);
+                  }
+                }
+              }
+
+      return effectID;
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public int getSize()
+      {
+      return mSize;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
 // Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
@@ -307,9 +363,9 @@ public class RubikCube extends DistortedNode
 
       switch(vector)
         {
-        case RubikSurfaceView.VECTX: axis = VectX; break;
-        case RubikSurfaceView.VECTY: axis = VectY; break;
-        case RubikSurfaceView.VECTZ: axis = VectZ; break;
+        case VECTX: axis = VectX; break;
+        case VECTY: axis = VectY; break;
+        case VECTZ: axis = VectZ; break;
         }
 
       mRotAxis = vector;
@@ -399,26 +455,19 @@ public class RubikCube extends DistortedNode
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void removeRotationNow()
+    public void removeRotationNow()
       {
-      int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1());
-      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
-      float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
-      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
-
-      mRotationAngleStatic.set1(0);
-
       float qx=0,qy=0,qz=0;
+      boolean first = true;
+      Static4D quat = null;
 
       switch(mRotAxis)
         {
-        case RubikSurfaceView.VECTX: qx=1; break;
-        case RubikSurfaceView.VECTY: qy=1; break;
-        case RubikSurfaceView.VECTZ: qz=1; break;
+        case VECTX: qx=1; break;
+        case VECTY: qy=1; break;
+        case VECTZ: qz=1; break;
         }
 
-      Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
-
       for(int x=0; x<mSize; x++)
         for(int y=0; y<mSize; y++)
           for(int z=0; z<mSize; z++)
@@ -426,11 +475,34 @@ public class RubikCube extends DistortedNode
               {
               if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
                 {
+                if( first )
+                  {
+                  first = false;
+                  int pointNum = mRotationAngle[x][y][z].getNumPoints();
+
+                  if( pointNum>=1 )
+                    {
+                    float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get1();
+                    int nearestAngleInDegrees = computeNearestAngle(startingAngle);
+                    double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
+                    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
+                    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
+                    quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
+                    }
+                  else
+                    {
+                    android.util.Log.e("cube", "ERROR removing rotation!");
+                    return;
+                    }
+                  }
+
                 mRotationAngle[x][y][z].removeAll();
                 mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
                 modifyCurrentPosition(x,y,z,quat);
                 }
               }
+
+      mRotationAngleStatic.set1(0);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -453,9 +525,9 @@ public class RubikCube extends DistortedNode
       {
       switch(vector)
         {
-        case RubikSurfaceView.VECTX: return mCurrentPosition[x][y][z].get1()==row;
-        case RubikSurfaceView.VECTY: return mCurrentPosition[x][y][z].get2()==row;
-        case RubikSurfaceView.VECTZ: return mCurrentPosition[x][y][z].get3()==row;
+        case VECTX: return mCurrentPosition[x][y][z].get1()==row;
+        case VECTY: return mCurrentPosition[x][y][z].get2()==row;
+        case VECTZ: return mCurrentPosition[x][y][z].get3()==row;
         }
 
       return false;
@@ -533,36 +605,29 @@ public class RubikCube extends DistortedNode
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   void recomputeScaleFactor(int screenWidth, int screenHeight, float size)
-     {
-     int texW = mNodeTexture.getWidth();
-     int texH = mNodeTexture.getHeight();
-
-     if( (float)texH/texW > (float)screenHeight/screenWidth )
-       {
-       int w = (screenHeight*texW)/texH;
-       float factor = (float)screenHeight/texH;
-       mNodeMove.set((screenWidth-w)*0.5f ,0, 0);
-       mNodeScale.set(factor,factor,factor);
-       }
-     else
-       {
-       int h = (screenWidth*texH)/texW;
-       float factor = (float)screenWidth/texW;
-       mNodeMove.set(0,(screenHeight-h)*0.5f,0);
-       mNodeScale.set(factor,factor,factor);
-       }
-
-     float scaleFactor = (size/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth);
-
-     mMove.set( texW*0.5f , texH*0.5f , 0.0f );
-     mScale.set(scaleFactor,scaleFactor,scaleFactor);
-     }
+    void recomputeScaleFactor(int screenWidth, int screenHeight, float size)
+      {
+      int texW = mNodeTexture.getWidth();
+      int texH = mNodeTexture.getHeight();
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
+      if( (float)texH/texW > (float)screenHeight/screenWidth )
+        {
+        int w = (screenHeight*texW)/texH;
+        float factor = (float)screenHeight/texH;
+        mNodeMove.set((screenWidth-w)*0.5f ,0, 0);
+        mNodeScale.set(factor,factor,factor);
+        }
+      else
+        {
+        int h = (screenWidth*texH)/texW;
+        float factor = (float)screenWidth/texW;
+        mNodeMove.set(0,(screenHeight-h)*0.5f,0);
+        mNodeScale.set(factor,factor,factor);
+        }
 
-    int getSize()
-      {
-      return mSize;
+      float scaleFactor = (size/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth);
+
+      mMove.set( texW*0.5f , texH*0.5f , 0.0f );
+      mScale.set(scaleFactor,scaleFactor,scaleFactor);
       }
 }
diff --git a/src/main/java/org/distorted/magic/RubikRenderer.java b/src/main/java/org/distorted/magic/RubikRenderer.java
index a440450e..c259b458 100644
--- a/src/main/java/org/distorted/magic/RubikRenderer.java
+++ b/src/main/java/org/distorted/magic/RubikRenderer.java
@@ -210,21 +210,21 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
    public void effectFinished(final long effectID)
      {
-     if(      effectID == mRotationFinishedID)
+     if(      effectID == mRotationFinishedID        )
        {
        mRemoveRotation = true;
        }
-     else if( effectID == mSizeChangeEffectID    )
+     else if( effectID == mSizeChangeEffectID        )
        {
        mCanRotate = true;
        mCanDrag   = true;
        }
-     else if( effectID == mUnscrambleEffectID    )
+     else if( effectID == mUnscrambleEffectID        )
        {
        mCanRotate = true;
        mCanDrag   = true;
        }
-     else if( effectID == mScrambleEffectID    )
+     else if( effectID == mScrambleEffectID          )
        {
        mCanRotate = true;
        mCanDrag   = true;
@@ -368,7 +368,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
      try
        {
        ScrambleEffect effect = ScrambleEffect.create(mScrambleType);
-       mScrambleEffectID = effect.start(mScrambleDuration,mScreen,mNewCube,mScrambleCubeNum,this);
+       mScrambleEffectID = effect.start(mScrambleDuration,mNewCube,mScrambleCubeNum,this);
        }
      catch(Exception ex)
        {
diff --git a/src/main/java/org/distorted/magic/RubikSurfaceView.java b/src/main/java/org/distorted/magic/RubikSurfaceView.java
index c34e2f27..716d0724 100644
--- a/src/main/java/org/distorted/magic/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/magic/RubikSurfaceView.java
@@ -47,11 +47,7 @@ class RubikSurfaceView extends GLSurfaceView
     private final static int TOP    = 4;  //
     private final static int BOTTOM = 5;  //
 
-    static final int VECTX = 0;  //
-    static final int VECTY = 1;  // don't change this
-    static final int VECTZ = 2;  //
-
-    private static final int[] VECT = {VECTX,VECTY,VECTZ};
+    private static final int[] VECT = {RubikCube.VECTX,RubikCube.VECTY,RubikCube.VECTZ};
 
     private boolean mDragging, mBeginningRotation, mContinuingRotation;
     private int mX, mY;
@@ -427,11 +423,11 @@ class RubikSurfaceView extends GLSurfaceView
       switch(face)
         {
         case FRONT :
-        case BACK  : return VECTX;
+        case BACK  : return RubikCube.VECTX;
         case LEFT  :
-        case RIGHT : return VECTZ;
+        case RIGHT : return RubikCube.VECTZ;
         case TOP   :
-        case BOTTOM: return VECTX;
+        case BOTTOM: return RubikCube.VECTX;
         }
 
       return -1;
@@ -444,11 +440,11 @@ class RubikSurfaceView extends GLSurfaceView
       switch(face)
         {
         case FRONT :
-        case BACK  : return VECTY;
+        case BACK  : return RubikCube.VECTY;
         case LEFT  :
-        case RIGHT : return VECTY;
+        case RIGHT : return RubikCube.VECTY;
         case TOP   :
-        case BOTTOM: return VECTZ;
+        case BOTTOM: return RubikCube.VECTZ;
         }
 
       return -1;
@@ -461,11 +457,11 @@ class RubikSurfaceView extends GLSurfaceView
       switch(face)
         {
         case FRONT :
-        case BACK  : return VECTZ;
+        case BACK  : return RubikCube.VECTZ;
         case LEFT  :
-        case RIGHT : return VECTX;
+        case RIGHT : return RubikCube.VECTX;
         case TOP   :
-        case BOTTOM: return VECTY;
+        case BOTTOM: return RubikCube.VECTY;
         }
 
       return -1;
