commit a31d25de2562cc844da922af6c635529cd593238
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Mar 31 12:03:37 2020 +0100

    Major progress with Prretty Patterns.
    
    Two things remain:
    
    1) looks like sometimes making/backing Moves in a Pattern gets stuck. ( Pattern.mCanRotate! )
    2) we need to add RubikPatternList!

diff --git a/src/main/java/org/distorted/dialog/RubikDialogPatternView.java b/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
index 62072455..dc181a39 100644
--- a/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialog/RubikDialogPatternView.java
@@ -153,7 +153,7 @@ public class RubikDialogPatternView extends FrameLayout implements AdapterView.O
           state.setPattern(act, mTab, category, ii);
           int[] sizes = RubikObjectList.CUBE.getSizes();
           RubikPattern pattern = RubikPattern.getInstance();
-          String moves = pattern.getMoves(mTab, category, ii);
+          int[][] moves = pattern.getMoves(mTab, category, ii);
           act.changeObject(RubikObjectList.CUBE,sizes[mTab],moves);
           mDialog.rememberCategories();
           mDialog.dismiss();
diff --git a/src/main/java/org/distorted/magic/RubikActivity.java b/src/main/java/org/distorted/magic/RubikActivity.java
index 88dde7cf..82ccf93d 100644
--- a/src/main/java/org/distorted/magic/RubikActivity.java
+++ b/src/main/java/org/distorted/magic/RubikActivity.java
@@ -193,7 +193,7 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeObject(RubikObjectList object, int size, String moves)
+    public void changeObject(RubikObjectList object, int size, int[][] moves)
       {
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       RubikPostRender post = view.getPostRender();
diff --git a/src/main/java/org/distorted/magic/RubikPostRender.java b/src/main/java/org/distorted/magic/RubikPostRender.java
index bb108826..065ac1fa 100644
--- a/src/main/java/org/distorted/magic/RubikPostRender.java
+++ b/src/main/java/org/distorted/magic/RubikPostRender.java
@@ -54,7 +54,7 @@ public class RubikPostRender implements EffectListener
   private long mNewRecord;
   private int mScreenWidth, mScreenHeight;
   private SharedPreferences mPreferences;
-  private String mNextMoves;
+  private int[][] mNextMoves;
   private RubikObject mOldObject, mNewObject;
   private int mScrambleObjectNum;
   private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
@@ -92,7 +92,7 @@ public class RubikPostRender implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void createObjectNow(RubikObjectList object, int size, String moves)
+  private void createObjectNow(RubikObjectList object, int size, int[][] moves)
     {
     boolean firstTime = (mNewObject==null);
 
@@ -161,8 +161,6 @@ public class RubikPostRender implements EffectListener
           }
         }
 
-android.util.Log.e("post", "1 canDrag true");
-
       mCanDrag   = true;
       mCanRotate = false;
       mCanUI     = false;
@@ -312,7 +310,7 @@ android.util.Log.e("post", "1 canDrag true");
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void changeObject(RubikObjectList object, int size, String moves)
+  void changeObject(RubikObjectList object, int size, int[][] moves)
     {
     if( size>0 )
       {
diff --git a/src/main/java/org/distorted/object/RubikCube.java b/src/main/java/org/distorted/object/RubikCube.java
index 40451737..7cc63a79 100644
--- a/src/main/java/org/distorted/object/RubikCube.java
+++ b/src/main/java/org/distorted/object/RubikCube.java
@@ -78,7 +78,7 @@ class RubikCube extends RubikObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, String moves)
+  RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, int[][] moves)
     {
     super(size, 60, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.CUBE);
     }
diff --git a/src/main/java/org/distorted/object/RubikObject.java b/src/main/java/org/distorted/object/RubikObject.java
index cc175166..a6ee5768 100644
--- a/src/main/java/org/distorted/object/RubikObject.java
+++ b/src/main/java/org/distorted/object/RubikObject.java
@@ -75,7 +75,7 @@ public abstract class RubikObject extends DistortedNode
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   RubikObject(int size, int fov, Static4D quatCur, Static4D quatAcc, DistortedTexture nodeTexture,
-              MeshRectangles nodeMesh, DistortedEffects nodeEffects, String moves, RubikObjectList list)
+              MeshRectangles nodeMesh, DistortedEffects nodeEffects, int[][] moves, RubikObjectList list)
     {
     super(nodeTexture,nodeEffects,nodeMesh);
 
@@ -221,57 +221,46 @@ public abstract class RubikObject extends DistortedNode
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
+// note the minus in front of the sin() - we rotate counterclockwise
+// when looking towards the direction where the axis increases in values.
 
-  private void setupPosition(String moves)
+  private Static4D makeQuaternion(int axisIndex, int angleInDegrees)
     {
-    android.util.Log.e("object", "initializing: "+moves);
-/*
-    int index,tmp, a1,a2,a3, rv, rc, ra;
-
-		numRotations=0;
-		initializeVertices(mSize);
-
-		int len=moves.length()/4;
-
-		for(int i=0; i<len; i++)
-		  {
-			a1=moves.charAt(4*i+1)-'0';
-			a2=moves.charAt(4*i+2)-'0';
-			a3=moves.charAt(4*i+3)-'0';
-
-			rv = (10*a1+a2)/32;
-			rc = (10*a1+a2)%32;
-			ra = 2-a3;
-
-			rotVector = rv;
-
-			tmp=rc;
-			index=0;
-
-			while( tmp!=0 )
-			  {
-				if( (tmp&0x1)==1 )
-				  {
-					rotAngle[index] = ra*90;
-					RubikWorld.setIdentity(rotMat[index]);
-
-					switch(rotVector)
-					  {
-					  case VECTX: RubikWorld.postRotate( rotMat[index], (float)((ra*90)%360), 1f,0f,0f); break;
-					  case VECTY: RubikWorld.postRotate( rotMat[index], (float)((ra*90)%360), 0f,1f,0f); break;
-					  case VECTZ: RubikWorld.postRotate( rotMat[index], (float)((ra*90)%360), 0f,0f,1f); break;
-					  }
-
-					transposeTiles(index);
-					rotAngle[index]=0;
-				  }
-
-				tmp/=2;
-				index++;
-			  }
-	  	}
- */
+    Static3D axis = ROTATION_AXIS[axisIndex];
+
+    while( angleInDegrees<0 ) angleInDegrees += 360;
+    angleInDegrees %= 360;
+    
+    float cosA = (float)Math.cos(Math.PI*angleInDegrees/360);
+    float sinA =-(float)Math.sqrt(1-cosA*cosA);
+
+    return new Static4D(axis.get0()*sinA, axis.get1()*sinA, axis.get2()*sinA, cosA);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void setupPosition(int[][] moves)
+    {
+    if( moves!=null )
+      {
+      Static4D quat;
+      int axis, rowBitmap, angle;
+      int corr = (360/getBasicAngle());
+
+      for(int[] move: moves)
+        {
+        axis     = move[0];
+        rowBitmap= move[1];
+        angle    = move[2]*corr;
+        quat     = makeQuaternion(axis,angle);
+
+        for(int j=0; j<NUM_CUBITS; j++)
+          if( belongsToRotation(j,axis,rowBitmap) )
+            {
+            mCubits[j].removeRotationNow(quat);
+            }
+        }
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -523,7 +512,7 @@ public abstract class RubikObject extends DistortedNode
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void initializeObject(String moves)
+  public void initializeObject(int[][] moves)
     {
     solve();
     setupPosition(moves);
diff --git a/src/main/java/org/distorted/object/RubikObjectList.java b/src/main/java/org/distorted/object/RubikObjectList.java
index 588aa3f6..cba72e19 100644
--- a/src/main/java/org/distorted/object/RubikObjectList.java
+++ b/src/main/java/org/distorted/object/RubikObjectList.java
@@ -245,7 +245,7 @@ public enum RubikObjectList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public RubikObject create(int size, Static4D quatCur, Static4D quatAcc, String moves)
+  public RubikObject create(int size, Static4D quatCur, Static4D quatAcc, int[][] moves)
     {
     DistortedTexture texture = new DistortedTexture();
     DistortedEffects effects = new DistortedEffects();
diff --git a/src/main/java/org/distorted/object/RubikPyraminx.java b/src/main/java/org/distorted/object/RubikPyraminx.java
index 64395f41..db548334 100644
--- a/src/main/java/org/distorted/object/RubikPyraminx.java
+++ b/src/main/java/org/distorted/object/RubikPyraminx.java
@@ -83,7 +83,7 @@ public class RubikPyraminx extends RubikObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikPyraminx(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, String moves)
+  RubikPyraminx(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, int[][] moves)
     {
     super(size, 30, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.PYRA);
     }
diff --git a/src/main/java/org/distorted/patterns/RubikPattern.java b/src/main/java/org/distorted/patterns/RubikPattern.java
index 3a3979e9..d469af73 100644
--- a/src/main/java/org/distorted/patterns/RubikPattern.java
+++ b/src/main/java/org/distorted/patterns/RubikPattern.java
@@ -138,7 +138,7 @@ public class RubikPattern
 
   /////////////////////////////////////////////////////////////
 
-    String getMoves(int pattern)
+    int[][] getMoves(int pattern)
       {
       if( pattern>=0 && pattern<numPatterns )
         {
@@ -146,7 +146,7 @@ public class RubikPattern
         if( p!=null ) return p.getMoves();
         }
 
-      return "";
+      return null;
       }
     }
 
@@ -155,7 +155,7 @@ public class RubikPattern
   private static class Pattern implements RubikPostRender.ActionFinishedListener
     {
     private String name;
-    private String moves;
+    private int[][] moves;
     private int curMove;
     private int numMove;
 
@@ -167,13 +167,34 @@ public class RubikPattern
     Pattern(String n, String m)
       {
       name=n;
-      moves=m;
-      numMove = moves.length()/4;
+      moves= movesParser(m);
       curMove=numMove;
-
       mCanRotate = true;
       }
 
+  /////////////////////////////////////////////////////////////
+
+    private int[][] movesParser(String moves)
+      {
+      numMove = moves.length()/4;
+
+      int digit0, digit1, digit2;
+      int[][] result = new int[numMove][3];
+
+      for(int i=0; i<numMove; i++)
+        {
+        digit0 = moves.charAt(4*i+1)-'0';
+        digit1 = moves.charAt(4*i+2)-'0';
+        digit2 = moves.charAt(4*i+3)-'0';
+
+        result[i][0] = (10*digit0+digit1)/32;
+        result[i][1] = (10*digit0+digit1)%32;
+        result[i][2] = 2-digit2;
+        }
+
+      return result;
+      }
+
   /////////////////////////////////////////////////////////////
 
     String getName()
@@ -205,7 +226,7 @@ public class RubikPattern
       if( curMove>numMove )
         {
         curMove= 0;
-        object.initializeObject(moves.substring(0,4*curMove));
+        object.initializeObject(null);
         }
       else
         {
@@ -214,15 +235,11 @@ public class RubikPattern
           mCanRotate = false;
           mObject = object;
 
-          String move = moves.substring(4*curMove-4,4*curMove);
-          int a1=move.charAt(1)-'0';
-		      int a2=move.charAt(2)-'0';
-		      int a3=move.charAt(3)-'0';
-
-          int axis      = (10*a1+a2)/32;
-          int rowBitmap = (10*a1+a2)%32;
-          int angle     = (2-a3)*(360/object.getBasicAngle());
-          int numRot    = Math.abs(2-a3);
+          int axis     =moves[curMove-1][0];
+		      int rowBitmap=moves[curMove-1][1];
+		      int bareAngle=moves[curMove-1][2];
+          int angle    = bareAngle*(360/object.getBasicAngle());
+          int numRot   = Math.abs(bareAngle);
 
           post.addRotation(this, axis, rowBitmap, angle, numRot*DURATION_MILLIS);
           }
@@ -245,7 +262,7 @@ public class RubikPattern
       if( curMove<0 )
         {
         curMove=numMove;
-        object.initializeObject(moves.substring(0,4*curMove));
+        object.initializeObject(moves);
         }
       else
         {
@@ -254,15 +271,11 @@ public class RubikPattern
           mCanRotate = false;
           mObject = object;
 
-          String move = moves.substring(4*curMove,4*curMove+4);
-          int a1=move.charAt(1)-'0';
-		      int a2=move.charAt(2)-'0';
-		      int a3=move.charAt(3)-'0';
-
-          int axis      = (10*a1+a2)/32;
-          int rowBitmap = (10*a1+a2)%32;
-          int angle     = (2-a3)*(360/object.getBasicAngle());
-          int numRot    = Math.abs(2-a3);
+          int axis     =moves[curMove][0];
+		      int rowBitmap=moves[curMove][1];
+		      int bareAngle=moves[curMove][2];
+          int angle    = bareAngle*(360/object.getBasicAngle());
+          int numRot   = Math.abs(bareAngle);
 
           post.addRotation(this, axis, rowBitmap, -angle, numRot*DURATION_MILLIS);
           }
@@ -276,9 +289,9 @@ public class RubikPattern
 
   /////////////////////////////////////////////////////////////
 
-    String getMoves()
+    int[][] getMoves()
       {
-      return moves.substring(0,4*curMove);
+      return moves;
       }
 
   /////////////////////////////////////////////////////////////
@@ -461,7 +474,7 @@ public class RubikPattern
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public String getMoves(int size, int cat, int pat)
+  public int[][] getMoves(int size, int cat, int pat)
     {
     if( size>=0 && size<NUM_CUBES && cat>=0 && cat< numCategories[size] )
       {
@@ -469,6 +482,6 @@ public class RubikPattern
       if( c!=null ) return c.getMoves(pat);
       }
 
-    return "";
+    return null;
     }
 }
