commit af0de0af41c5709a6cb6306b5da6a8a6ba3cd26c
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Sep 7 00:38:00 2021 +0200

    Remove statics from the Minx classes.

diff --git a/src/main/java/org/distorted/objects/TwistyKilominx.java b/src/main/java/org/distorted/objects/TwistyKilominx.java
index 87e3868c..f5284132 100644
--- a/src/main/java/org/distorted/objects/TwistyKilominx.java
+++ b/src/main/java/org/distorted/objects/TwistyKilominx.java
@@ -34,7 +34,21 @@ import org.distorted.main.R;
 
 public class TwistyKilominx extends TwistyMinx
 {
-  private static final int[] mCenterFaceMap = new int[]
+  private int[] mCenterFaceMap;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  TwistyKilominx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
+                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
+    {
+    super(size, size, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void initializeCenterFaceMap()
+    {
+    mCenterFaceMap = new int[]
       {
         0,0,0,0,1,
         1,0,1,1,0,
@@ -49,55 +63,6 @@ public class TwistyKilominx extends TwistyMinx
         2,1,0,1,2,
         2,2,2,2,2
       };
-
-  private static final float CENTER_CORR = 0.87f;
-
-  private static final float[][] STICKERS = new float[][]
-      {
-        { -0.36616942f, -0.36327124f, 0.5f, -0.36327124f, 0.23233888f, 0.4605048f, -0.36616942f, 0.26603764f },
-        { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
-        { -0.3249197f, -0.39442718f, 0.3249197f, -0.39442718f, 0.3249197f, 0.5f, -0.3249197f, 0.2888544f }
-      };
-
-  static
-    {
-    final float C = 1.14f; // make the 'center' sticker artificially larger, so that we paint
-                           // over the area in the center of the face.
-
-    STICKERS[0][0] *= C;
-    STICKERS[0][1] *= C;
-    STICKERS[0][2] *= C;
-    STICKERS[0][3] *= C;
-    STICKERS[0][4] *= C;
-    STICKERS[0][5] *= C;
-    STICKERS[0][6] *= C;
-    STICKERS[0][7] *= C;
-
-    STICKERS[0][2] *= CENTER_CORR;
-    STICKERS[0][3] *= CENTER_CORR;
-    }
-
-  private static final ObjectSticker[] mStickers;
-  static
-    {
-    mStickers = new ObjectSticker[STICKERS.length];
-
-    float R = 0.10f;
-    final float[][] radii = { {R,R,R,R},{R,R,R,R},{R,R,R,R} };
-    final float[] strokes = { 0.20f, 0.11f, 0.10f };
-
-    for(int s=0; s<STICKERS.length; s++)
-      {
-      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyKilominx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -169,7 +134,11 @@ public class TwistyKilominx extends TwistyMinx
 
   private void computeBasicCornerVectors(int corner)
     {
-    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
+    if( mQuatCornerIndices==null ) initializeQuatIndices();
+    if( mQuats==null ) initializeQuats();
+    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
+
+    Static4D quat = mQuats[mQuatCornerIndices[corner]];
 
     mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
     mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
@@ -180,8 +149,11 @@ public class TwistyKilominx extends TwistyMinx
 
   private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
     {
+    if( mCorners==null ) initializeCorners();
+    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
+
     float D = numLayers/3.0f;
-    float[] corn = CORNERS[corner];
+    float[] corn = mCorners[corner];
 
     if( part==0 )
       {
@@ -212,9 +184,13 @@ public class TwistyKilominx extends TwistyMinx
 
   private float[] computeCenter(int numLayers, int center, int part)
     {
+    if( mCenterCoords==null ) initializeCenterCoords();
+    if( mCorners     ==null ) initializeCorners();
+    if( mCenterMap   ==null ) initializeCenterMap();
+
     int corner = mCenterMap[center][part];
     float[] cent = mCenterCoords[center];
-    float[] corn = CORNERS[corner];
+    float[] corn = mCorners[corner];
     float D = numLayers/3.0f;
     float F = 1.0f - (2.0f*numLayers-6.0f)/(numLayers-1)*COS54*COS54;
 
@@ -238,9 +214,13 @@ public class TwistyKilominx extends TwistyMinx
 
   private float[] computeEdge(int numLayers, int edge, int part)
     {
+    if( mCenterCoords==null ) initializeCenterCoords();
+    if( mCorners==null ) initializeCorners();
+    if( mEdgeMap==null ) initializeEdgeMap();
+
     float D = numLayers/3.0f;
-    float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
-    float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
+    float[] c1 = mCorners[ mEdgeMap[edge][0] ];
+    float[] c2 = mCorners[ mEdgeMap[edge][1] ];
 
     int leftRight = 2*(part%2) -1;
     part /= 2;
@@ -284,7 +264,8 @@ public class TwistyKilominx extends TwistyMinx
 
   float[][] getCubitPositions(int numLayers)
     {
-    if( numLayers<5 ) return CORNERS;
+    if( mCorners==null ) initializeCorners();
+    if( numLayers<5 ) return mCorners;
 
     int numCubitsPerCorner = numCubitsPerCorner(numLayers);
     int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
@@ -327,21 +308,24 @@ public class TwistyKilominx extends TwistyMinx
 
   private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
     {
+    if( mQuatCornerIndices==null || mQuatEdgeIndices==null ) initializeQuatIndices();
+    if( mCenterMap==null ) initializeCenterMap();
+
     if( cubit < NUM_CORNERS*numCubitsPerCorner )
       {
       int corner = cubit/numCubitsPerCorner;
-      return QUAT_CORNER_INDICES[corner];
+      return mQuatCornerIndices[corner];
       }
 
     if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
       {
       int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
-      return QUAT_EDGE_INDICES[edge];
+      return mQuatEdgeIndices[edge];
       }
 
     if( numCubitsPerCorner==0 )
       {
-      return QUAT_CORNER_INDICES[cubit];
+      return mQuatCornerIndices[cubit];
       }
     else
       {
@@ -351,7 +335,7 @@ public class TwistyKilominx extends TwistyMinx
       int index= cubit%numCubitsPerCenter;
       int corner=mCenterMap[face][index];
 
-      return QUAT_CORNER_INDICES[corner];
+      return mQuatCornerIndices[corner];
       }
     }
 
@@ -537,10 +521,11 @@ public class TwistyKilominx extends TwistyMinx
 
   Static4D getQuat(int cubit, int numLayers)
     {
+    if( mQuats==null ) initializeQuats();
     int numCubitsPerCorner = numCubitsPerCorner(numLayers);
     int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
 
-    return QUATS[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
+    return mQuats[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -581,6 +566,7 @@ public class TwistyKilominx extends TwistyMinx
 
   int getCornerColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner)
     {
+    if( mCornerFaceMap==null ) initializeCornerFaceMap();
     if( cubitface<0 || cubitface>2 ) return NUM_TEXTURES;
 
     int part  = cubit % numCubitsPerCorner;
@@ -627,6 +613,7 @@ public class TwistyKilominx extends TwistyMinx
 
     int part    = edge % numCubitsPerEdge;
     int variant = edge / numCubitsPerEdge;
+    if( mEdgeMap==null ) initializeEdgeMap();
 
     part /=2;
 
@@ -637,7 +624,10 @@ public class TwistyKilominx extends TwistyMinx
 
   int getCenterColor(int center, int cubitface, int numLayers)
     {
-     if( numLayers==3 )
+    if( mCenterFaceMap==null ) initializeCenterFaceMap();
+    if( mCornerFaceMap==null ) initializeCornerFaceMap();
+
+    if( numLayers==3 )
       {
       return cubitface>=0 && cubitface<3 ? mCornerFaceMap[center][cubitface] : NUM_TEXTURES;
       }
@@ -679,6 +669,42 @@ public class TwistyKilominx extends TwistyMinx
 
   ObjectSticker retSticker(int face)
     {
+    if( mStickers==null )
+      {
+      float[][] STICKERS = new float[][]
+        {
+          { -0.36616942f, -0.36327124f, 0.5f, -0.36327124f, 0.23233888f, 0.4605048f, -0.36616942f, 0.26603764f },
+          { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
+          { -0.3249197f, -0.39442718f, 0.3249197f, -0.39442718f, 0.3249197f, 0.5f, -0.3249197f, 0.2888544f }
+        };
+
+      float CENTER_CORR = 0.87f;
+      float C = 1.14f; // make the 'center' sticker artificially larger, so that we paint over the area in the center of the face.
+
+      STICKERS[0][0] *= C;
+      STICKERS[0][1] *= C;
+      STICKERS[0][2] *= C;
+      STICKERS[0][3] *= C;
+      STICKERS[0][4] *= C;
+      STICKERS[0][5] *= C;
+      STICKERS[0][6] *= C;
+      STICKERS[0][7] *= C;
+
+      STICKERS[0][2] *= CENTER_CORR;
+      STICKERS[0][3] *= CENTER_CORR;
+
+      mStickers = new ObjectSticker[STICKERS.length];
+
+      float R = 0.10f;
+      final float[][] radii = { {R,R,R,R},{R,R,R,R},{R,R,R,R} };
+      final float[] strokes = { 0.20f, 0.11f, 0.10f };
+
+      for(int s=0; s<STICKERS.length; s++)
+        {
+        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+        }
+      }
+
     return mStickers[getStickerIndex(face)];
     }
 
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index f76dc38f..5f248e40 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -35,46 +35,21 @@ import org.distorted.main.R;
 public class TwistyMegaminx extends TwistyMinx
 {
   static final float MEGA_D = 0.04f;
+  private int[] mQuatCenterIndices;
 
-  private static final int[] QUAT_CENTER_INDICES =
-      {
-        16, 18, 22,  1, 20, 13, 14, 15,  0, 12,  2,  3
-      };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private static final float[][] STICKERS = new float[][]
-      {
-        { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
-        { -0.5f, -0.0914315f, 0.5f, -0.4163512f, 0.5f, 0.4163512f, -0.5f, 0.0914315f },
-        { -0.49233657f, -0.18006028f, 0.49233657f, -0.5f, 0.49233657f, 0.5f, -0.49233657f, 0.18006028f },
-        { -0.3002273f, -0.30490047f, 0.3002273f, -0.5f, 0.3002273f, 0.5f, -0.3002273f, 0.30490047f },
-        { -0.29389262f, 0.4045085f, -0.47552824f, -0.1545085f, 0.0f, -0.5f, 0.47552824f, -0.1545085f, 0.29389262f, 0.4045085f }
-      };
-
-  private static final ObjectSticker[] mStickers;
-  static
+  TwistyMegaminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
+                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
     {
-    mStickers = new ObjectSticker[STICKERS.length];
-
-    final float R0 = 0.08f;
-    final float R1 = 0.12f;
-    final float R2 = 0.12f;
-    final float R3 = 0.08f;
-    final float R4 = 0.10f;
-    final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4,R4,R4} };
-    final float[] strokes = { 0.10f,0.12f,0.12f,0.08f,0.07f };
-
-    for(int s=0; s<STICKERS.length; s++)
-      {
-      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-      }
+    super(size, size, quat, texture, mesh, effects, moves, ObjectList.MEGA, res, scrWidth);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  TwistyMegaminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
+  private void initializeCenterIndices()
     {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.MEGA, res, scrWidth);
+    mQuatCenterIndices = new int[] { 16, 18, 22,  1, 20, 13, 14, 15,  0, 12,  2,  3 };
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -144,6 +119,7 @@ public class TwistyMegaminx extends TwistyMinx
 
   private float[] computeCenter(int center, int numLayers)
     {
+    if( mCenterCoords==null ) initializeCenterCoords();
     float[] coords = mCenterCoords[center];
     float A = numLayers/3.0f;
 
@@ -156,7 +132,11 @@ public class TwistyMegaminx extends TwistyMinx
 
   private void computeBasicCornerVectors(int corner)
     {
-    Static4D quat = QUATS[QUAT_CORNER_INDICES[corner]];
+    if( mQuatCornerIndices==null ) initializeQuatIndices();
+    if( mQuats==null ) initializeQuats();
+    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
+
+    Static4D quat = mQuats[mQuatCornerIndices[corner]];
 
     mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
     mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
@@ -167,8 +147,11 @@ public class TwistyMegaminx extends TwistyMinx
 
   private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
     {
+    if( mCorners==null ) initializeCorners();
+    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
+
     float D = numLayers/3.0f;
-    float[] corn = CORNERS[corner];
+    float[] corn = mCorners[corner];
 
     if( part==0 )
       {
@@ -207,10 +190,13 @@ public class TwistyMegaminx extends TwistyMinx
 
   private float[] computeEdge(int numLayers, int edge, int part)
     {
-    float D = numLayers/3.0f;
+    if( mCenterCoords==null ) initializeCenterCoords();
+    if( mCorners==null ) initializeCorners();
+    if( mEdgeMap==null ) initializeEdgeMap();
 
-    float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
-    float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
+    float D = numLayers/3.0f;
+    float[] c1 = mCorners[ mEdgeMap[edge][0] ];
+    float[] c2 = mCorners[ mEdgeMap[edge][1] ];
     float x = D * (c1[0]+c2[0]) / 2;
     float y = D * (c1[1]+c2[1]) / 2;
     float z = D * (c1[2]+c2[2]) / 2;
@@ -277,20 +263,23 @@ public class TwistyMegaminx extends TwistyMinx
 
   private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
     {
+    if( mQuatCornerIndices==null || mQuatEdgeIndices==null ) initializeQuatIndices();
+    if( mQuatCenterIndices==null ) initializeCenterIndices();
+
     if( cubit < NUM_CORNERS*numCubitsPerCorner )
       {
       int corner = cubit/numCubitsPerCorner;
-      return QUAT_CORNER_INDICES[corner];
+      return mQuatCornerIndices[corner];
       }
 
     if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
       {
       int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
-      return QUAT_EDGE_INDICES[edge];
+      return mQuatEdgeIndices[edge];
       }
 
     int center = cubit - NUM_CORNERS*numCubitsPerCorner - NUM_EDGES*numCubitsPerEdge;
-    return QUAT_CENTER_INDICES[center];
+    return mQuatCenterIndices[center];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -443,15 +432,15 @@ public class TwistyMegaminx extends TwistyMinx
       }
     }
 
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   Static4D getQuat(int cubit, int numLayers)
     {
+    if( mQuats==null ) initializeQuats();
     int numCubitsPerCorner = numCubitsPerCorner(numLayers);
     int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
 
-    return QUATS[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
+    return mQuats[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -491,6 +480,7 @@ public class TwistyMegaminx extends TwistyMinx
 
   int getCornerColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner)
     {
+    if( mCornerFaceMap==null ) initializeCornerFaceMap();
     if( cubitface<0 || cubitface>2 ) return NUM_TEXTURES;
 
     int part  = cubit % numCubitsPerCorner;
@@ -537,6 +527,7 @@ public class TwistyMegaminx extends TwistyMinx
 
     int part    = edge % numCubitsPerEdge;
     int variant = edge / numCubitsPerEdge;
+    if( mEdgeMap==null ) initializeEdgeMap();
 
     return (part==0 || cubitface==((part+1)%2)) ? mEdgeMap[variant][cubitface+2] + ((part+3)/2)*NUM_FACES : NUM_TEXTURES;
     }
@@ -582,6 +573,33 @@ public class TwistyMegaminx extends TwistyMinx
 
   ObjectSticker retSticker(int face)
     {
+    if( mStickers==null )
+      {
+      float[][] STICKERS = new float[][]
+        {
+          { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
+          { -0.5f, -0.0914315f, 0.5f, -0.4163512f, 0.5f, 0.4163512f, -0.5f, 0.0914315f },
+          { -0.49233657f, -0.18006028f, 0.49233657f, -0.5f, 0.49233657f, 0.5f, -0.49233657f, 0.18006028f },
+          { -0.3002273f, -0.30490047f, 0.3002273f, -0.5f, 0.3002273f, 0.5f, -0.3002273f, 0.30490047f },
+          { -0.29389262f, 0.4045085f, -0.47552824f, -0.1545085f, 0.0f, -0.5f, 0.47552824f, -0.1545085f, 0.29389262f, 0.4045085f }
+        };
+
+      mStickers = new ObjectSticker[STICKERS.length];
+
+      final float R0 = 0.08f;
+      final float R1 = 0.12f;
+      final float R2 = 0.12f;
+      final float R3 = 0.08f;
+      final float R4 = 0.10f;
+      final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4,R4,R4} };
+      final float[] strokes = { 0.10f,0.12f,0.12f,0.08f,0.07f };
+
+      for(int s=0; s<STICKERS.length; s++)
+        {
+        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+        }
+      }
+
     return mStickers[getStickerIndex(face)];
     }
 
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index ee167917..be9b403c 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -21,6 +21,7 @@ package org.distorted.objects;
 
 import android.content.res.Resources;
 
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.helpers.ScrambleState;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -60,8 +61,6 @@ abstract class TwistyMinx extends TwistyObject
            new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
          };
 
-  private static final int[] BASIC_ANGLE = new int[] { 5,5,5,5,5,5 };
-
   static final int MINX_LGREEN = 0xff53aa00;
   static final int MINX_PINK   = 0xfffd7ab7;
   static final int MINX_SANDY  = 0xffefd48b;
@@ -82,146 +81,78 @@ abstract class TwistyMinx extends TwistyObject
            MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
          };
 
-  private static final int[] mFaceMap = new int[] {8,10,3,7,1,11,9,2,4,0,5,6};
+  private int mCurrState;
+  private int mIndexExcluded;
+  private ScrambleState[] mStates;
+  private int[][] mScrambleTable;
+  private int[] mNumOccurences;
+  private int[] mBasicAngle;
+  private int[] mFaceMap;
+  Static4D[] mQuats;
+  float[][] mCenterCoords;
+  float[][] mCorners;
+  int[][] mCornerFaceMap;
+  int[] mQuatEdgeIndices;
+  int[] mQuatCornerIndices;
+  int[][] mEdgeMap;
+  int[][] mCenterMap;
+  Static4D[] mBasicCornerV, mCurrCornerV;
+  ObjectSticker[] mStickers;
 
-  // All 60 legal rotation quats of a Minx
-  static final Static4D[] QUATS = new Static4D[]
-         {
-           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),  //0
-           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),  //4
-           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-           new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
-           new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
-           new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
-           new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
-
-           new Static4D(  0.5f, SIN54, SIN18,  0.0f ), // 12
-           new Static4D(  0.5f, SIN54,-SIN18,  0.0f ),
-           new Static4D(  0.5f,-SIN54, SIN18,  0.0f ),
-           new Static4D(  0.5f,-SIN54,-SIN18,  0.0f ),
-           new Static4D( SIN18,  0.5f, SIN54,  0.0f ),
-           new Static4D( SIN18,  0.5f,-SIN54,  0.0f ),
-           new Static4D(-SIN18,  0.5f, SIN54,  0.0f ),
-           new Static4D(-SIN18,  0.5f,-SIN54,  0.0f ),
-           new Static4D( SIN54, SIN18,  0.5f,  0.0f ),
-           new Static4D( SIN54,-SIN18,  0.5f,  0.0f ),
-           new Static4D(-SIN54, SIN18,  0.5f,  0.0f ),
-           new Static4D(-SIN54,-SIN18,  0.5f,  0.0f ),
-
-           new Static4D(  0.0f, SIN18, SIN54,  0.5f ), //24
-           new Static4D(  0.0f, SIN18,-SIN54,  0.5f ),
-           new Static4D(  0.0f,-SIN18, SIN54,  0.5f ),
-           new Static4D(  0.0f,-SIN18,-SIN54,  0.5f ),
-           new Static4D( SIN18, SIN54,  0.0f,  0.5f ),
-           new Static4D( SIN18,-SIN54,  0.0f,  0.5f ),
-           new Static4D(-SIN18, SIN54,  0.0f,  0.5f ),
-           new Static4D(-SIN18,-SIN54,  0.0f,  0.5f ),
-           new Static4D( SIN54,  0.0f, SIN18,  0.5f ),
-           new Static4D( SIN54,  0.0f,-SIN18,  0.5f ),
-           new Static4D(-SIN54,  0.0f, SIN18,  0.5f ),
-           new Static4D(-SIN54,  0.0f,-SIN18,  0.5f ),
-
-           new Static4D(  0.0f, SIN54,  0.5f, SIN18 ), //36
-           new Static4D(  0.0f, SIN54, -0.5f, SIN18 ),
-           new Static4D(  0.0f,-SIN54,  0.5f, SIN18 ),
-           new Static4D(  0.0f,-SIN54, -0.5f, SIN18 ),
-           new Static4D(  0.5f,  0.0f, SIN54, SIN18 ),
-           new Static4D(  0.5f,  0.0f,-SIN54, SIN18 ),
-           new Static4D( -0.5f,  0.0f, SIN54, SIN18 ),
-           new Static4D( -0.5f,  0.0f,-SIN54, SIN18 ),
-           new Static4D( SIN54,  0.5f,  0.0f, SIN18 ),
-           new Static4D( SIN54, -0.5f,  0.0f, SIN18 ),
-           new Static4D(-SIN54,  0.5f,  0.0f, SIN18 ),
-           new Static4D(-SIN54, -0.5f,  0.0f, SIN18 ),
-
-           new Static4D(  0.0f,  0.5f, SIN18, SIN54 ), //48
-           new Static4D(  0.0f,  0.5f,-SIN18, SIN54 ),
-           new Static4D(  0.0f, -0.5f, SIN18, SIN54 ),
-           new Static4D(  0.0f, -0.5f,-SIN18, SIN54 ),
-           new Static4D(  0.5f, SIN18,  0.0f, SIN54 ),
-           new Static4D(  0.5f,-SIN18,  0.0f, SIN54 ),
-           new Static4D( -0.5f, SIN18,  0.0f, SIN54 ),
-           new Static4D( -0.5f,-SIN18,  0.0f, SIN54 ),
-           new Static4D( SIN18,  0.0f,  0.5f, SIN54 ),
-           new Static4D( SIN18,  0.0f, -0.5f, SIN54 ),
-           new Static4D(-SIN18,  0.0f,  0.5f, SIN54 ),
-           new Static4D(-SIN18,  0.0f, -0.5f, SIN54 ),
-         };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  // Coordinates of all 20 corners of a Minx
-  static final float[][] CORNERS = new float[][]
-         {
-             {  0.0f,  0.5f,    C2},
-             {  0.0f,  0.5f,   -C2},
-             {  0.0f, -0.5f,    C2},
-             {  0.0f, -0.5f,   -C2},
-             {    C2,  0.0f,  0.5f},
-             {    C2,  0.0f, -0.5f},
-             {   -C2,  0.0f,  0.5f},
-             {   -C2,  0.0f, -0.5f},
-             {  0.5f,    C2,  0.0f},
-             {  0.5f,   -C2,  0.0f},
-             { -0.5f,    C2,  0.0f},
-             { -0.5f,   -C2,  0.0f},
-             { SIN54, SIN54, SIN54},
-             { SIN54, SIN54,-SIN54},
-             { SIN54,-SIN54, SIN54},
-             { SIN54,-SIN54,-SIN54},
-             {-SIN54, SIN54, SIN54},
-             {-SIN54, SIN54,-SIN54},
-             {-SIN54,-SIN54, SIN54},
-             {-SIN54,-SIN54,-SIN54},
-         };
+  TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
+             DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
+    {
+    super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth);
 
-  static final int[][] mCornerFaceMap =
-         {
-           {  0, 1, 8 },
-           {  6, 5,10 },
-           {  1, 0,11 },
-           {  5, 6, 3 },
-           {  0, 9, 4 },
-           {  5, 4, 9 },
-           {  7, 1, 2 },
-           {  2, 6, 7 },
-           { 10, 9, 8 },
-           {  4, 3,11 },
-           {  7,10, 8 },
-           {  3, 2,11 },
-           {  0, 8, 9 },
-           {  9,10, 5 },
-           {  0, 4,11 },
-           {  4, 5, 3 },
-           {  1, 7, 8 },
-           {  7, 6,10 },
-           {  2, 1,11 },
-           {  6, 2, 3 },
-         };
+    initializeScrambleStates(numLayers);
+    }
 
-  static final int[] QUAT_EDGE_INDICES =
-      {
-        56, 40, 43, 59,  0, 19,  9, 54, 58, 49,
-        48, 24, 52,  4, 16, 32, 20, 11, 21, 35 ,
-        37, 30,  8, 28, 36, 44,  1, 46, 12, 47
-      };
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  static final int[] QUAT_CORNER_INDICES =
-      {
-         0,  2,  3,  1, 40, 31, 41, 30, 39, 35,
-        36, 34, 56, 32, 43, 21, 48, 28, 42, 23
-      };
+  void initializeCornerV()
+    {
+    mBasicCornerV = new Static4D[3];
+    mCurrCornerV  = new Static4D[3];
+
+    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
+    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
+    mBasicCornerV[2] = new Static4D(              0,        -0.500f,    0.0f, 0.0f );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// the five vertices that form a given face. Order: the same as colors of the faces in TwistyMinx.
+
+  void initializeCenterMap()
+    {
+    mCenterMap = new int[][]
+         {
+           { 0, 12,  4, 14,  2},
+           { 0,  2, 18,  6, 16},
+           { 6, 18, 11, 19,  7},
+           { 3, 15,  9, 11, 19},
+           { 4,  5, 15,  9, 14},
+           { 1, 13,  5, 15,  3},
+           { 1,  3, 19,  7, 17},
+           {10, 16,  6,  7, 17},
+           { 0, 12,  8, 10, 16},
+           { 8, 13,  5,  4, 12},
+           { 1, 13,  8, 10, 17},
+           { 2, 14,  9, 11, 18},
+         };
+    }
 
-  // the quadruple ( corner1, corner2, face1, face2 ) defining an edge.
-  // In fact the 2 corners already define it, the faces only provide easy
-  // way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
-  // the 'left' or right of vector corner1 --> corner2, according to Quat.
-  static final int[][] mEdgeMap =
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// the quadruple ( corner1, corner2, face1, face2 ) defining an edge.
+// In fact the 2 corners already define it, the faces only provide easy
+// way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
+// the 'left' or right of vector corner1 --> corner2, according to Quat.
+
+  void initializeEdgeMap()
+    {
+    mEdgeMap = new int[][]
          {
            {  0, 12,  0,  8}, //0
            { 12,  4,  0,  9},
@@ -254,83 +185,193 @@ abstract class TwistyMinx extends TwistyObject
            {  1, 13, 10,  5},
            {  3, 15,  5,  3},
          };
+    }
 
-  // the five vertices that form a given face. Order: the same as colors
-  // of the faces in TwistyMinx.
-  static final int[][] mCenterMap =
-         {
-           { 0, 12,  4, 14,  2},
-           { 0,  2, 18,  6, 16},
-           { 6, 18, 11, 19,  7},
-           { 3, 15,  9, 11, 19},
-           { 4,  5, 15,  9, 14},
-           { 1, 13,  5, 15,  3},
-           { 1,  3, 19,  7, 17},
-           {10, 16,  6,  7, 17},
-           { 0, 12,  8, 10, 16},
-           { 8, 13,  5,  4, 12},
-           { 1, 13,  8, 10, 17},
-           { 2, 14,  9, 11, 18},
-         };
-
-  static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  static
+  void initializeQuatIndices()
     {
-    for(int center=0; center<NUM_CENTERS; center++)
+    mQuatEdgeIndices = new int[]
       {
-      int[] map = mCenterMap[center];
+        56, 40, 43, 59,  0, 19,  9, 54, 58, 49,
+        48, 24, 52,  4, 16, 32, 20, 11, 21, 35,
+        37, 30,  8, 28, 36, 44,  1, 46, 12, 47
+      };
+    mQuatCornerIndices = new int[]
+      {
+         0,  2,  3,  1, 40, 31, 41, 30, 39, 35,
+        36, 34, 56, 32, 43, 21, 48, 28, 42, 23
+      };
+    }
 
-      float x = CORNERS[map[0]][0] +
-                CORNERS[map[1]][0] +
-                CORNERS[map[2]][0] +
-                CORNERS[map[3]][0] +
-                CORNERS[map[4]][0] ;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-      float y = CORNERS[map[0]][1] +
-                CORNERS[map[1]][1] +
-                CORNERS[map[2]][1] +
-                CORNERS[map[3]][1] +
-                CORNERS[map[4]][1] ;
+  void initializeCornerFaceMap()
+    {
+    mCornerFaceMap = new int[][]
+         {
+           {  0, 1, 8 },
+           {  6, 5,10 },
+           {  1, 0,11 },
+           {  5, 6, 3 },
+           {  0, 9, 4 },
+           {  5, 4, 9 },
+           {  7, 1, 2 },
+           {  2, 6, 7 },
+           { 10, 9, 8 },
+           {  4, 3,11 },
+           {  7,10, 8 },
+           {  3, 2,11 },
+           {  0, 8, 9 },
+           {  9,10, 5 },
+           {  0, 4,11 },
+           {  4, 5, 3 },
+           {  1, 7, 8 },
+           {  7, 6,10 },
+           {  2, 1,11 },
+           {  6, 2, 3 },
+         };
+    }
 
-      float z = CORNERS[map[0]][2] +
-                CORNERS[map[1]][2] +
-                CORNERS[map[2]][2] +
-                CORNERS[map[3]][2] +
-                CORNERS[map[4]][2] ;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-      mCenterCoords[center][0] = x/5;
-      mCenterCoords[center][1] = y/5;
-      mCenterCoords[center][2] = z/5;
-      }
+  void initializeQuats()
+    {
+    mQuats = new Static4D[]
+         {
+         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),  //0
+         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
+         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
+         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
+
+         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),  //4
+         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
+         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
+         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
+         new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
+         new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
+         new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
+         new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
+
+         new Static4D(  0.5f, SIN54, SIN18,  0.0f ), // 12
+         new Static4D(  0.5f, SIN54,-SIN18,  0.0f ),
+         new Static4D(  0.5f,-SIN54, SIN18,  0.0f ),
+         new Static4D(  0.5f,-SIN54,-SIN18,  0.0f ),
+         new Static4D( SIN18,  0.5f, SIN54,  0.0f ),
+         new Static4D( SIN18,  0.5f,-SIN54,  0.0f ),
+         new Static4D(-SIN18,  0.5f, SIN54,  0.0f ),
+         new Static4D(-SIN18,  0.5f,-SIN54,  0.0f ),
+         new Static4D( SIN54, SIN18,  0.5f,  0.0f ),
+         new Static4D( SIN54,-SIN18,  0.5f,  0.0f ),
+         new Static4D(-SIN54, SIN18,  0.5f,  0.0f ),
+         new Static4D(-SIN54,-SIN18,  0.5f,  0.0f ),
+
+         new Static4D(  0.0f, SIN18, SIN54,  0.5f ), //24
+         new Static4D(  0.0f, SIN18,-SIN54,  0.5f ),
+         new Static4D(  0.0f,-SIN18, SIN54,  0.5f ),
+         new Static4D(  0.0f,-SIN18,-SIN54,  0.5f ),
+         new Static4D( SIN18, SIN54,  0.0f,  0.5f ),
+         new Static4D( SIN18,-SIN54,  0.0f,  0.5f ),
+         new Static4D(-SIN18, SIN54,  0.0f,  0.5f ),
+         new Static4D(-SIN18,-SIN54,  0.0f,  0.5f ),
+         new Static4D( SIN54,  0.0f, SIN18,  0.5f ),
+         new Static4D( SIN54,  0.0f,-SIN18,  0.5f ),
+         new Static4D(-SIN54,  0.0f, SIN18,  0.5f ),
+         new Static4D(-SIN54,  0.0f,-SIN18,  0.5f ),
+
+         new Static4D(  0.0f, SIN54,  0.5f, SIN18 ), //36
+         new Static4D(  0.0f, SIN54, -0.5f, SIN18 ),
+         new Static4D(  0.0f,-SIN54,  0.5f, SIN18 ),
+         new Static4D(  0.0f,-SIN54, -0.5f, SIN18 ),
+         new Static4D(  0.5f,  0.0f, SIN54, SIN18 ),
+         new Static4D(  0.5f,  0.0f,-SIN54, SIN18 ),
+         new Static4D( -0.5f,  0.0f, SIN54, SIN18 ),
+         new Static4D( -0.5f,  0.0f,-SIN54, SIN18 ),
+         new Static4D( SIN54,  0.5f,  0.0f, SIN18 ),
+         new Static4D( SIN54, -0.5f,  0.0f, SIN18 ),
+         new Static4D(-SIN54,  0.5f,  0.0f, SIN18 ),
+         new Static4D(-SIN54, -0.5f,  0.0f, SIN18 ),
+
+         new Static4D(  0.0f,  0.5f, SIN18, SIN54 ), //48
+         new Static4D(  0.0f,  0.5f,-SIN18, SIN54 ),
+         new Static4D(  0.0f, -0.5f, SIN18, SIN54 ),
+         new Static4D(  0.0f, -0.5f,-SIN18, SIN54 ),
+         new Static4D(  0.5f, SIN18,  0.0f, SIN54 ),
+         new Static4D(  0.5f,-SIN18,  0.0f, SIN54 ),
+         new Static4D( -0.5f, SIN18,  0.0f, SIN54 ),
+         new Static4D( -0.5f,-SIN18,  0.0f, SIN54 ),
+         new Static4D( SIN18,  0.0f,  0.5f, SIN54 ),
+         new Static4D( SIN18,  0.0f, -0.5f, SIN54 ),
+         new Static4D(-SIN18,  0.0f,  0.5f, SIN54 ),
+         new Static4D(-SIN18,  0.0f, -0.5f, SIN54 ),
+         };
     }
 
-  static final Static4D[] mBasicCornerV, mCurrCornerV;
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Coordinates of all 20 corners of a Minx
 
-  static
+  void initializeCorners()
     {
-    mBasicCornerV = new Static4D[3];
-    mCurrCornerV  = new Static4D[3];
-
-    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
-    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.125f, (SQ5-1)*0.125f, -0.250f, 0.0f );
-    mBasicCornerV[2] = new Static4D(              0,        -0.500f,    0.0f, 0.0f );
+    mCorners = new float[][]
+         {
+             {  0.0f,  0.5f,    C2},
+             {  0.0f,  0.5f,   -C2},
+             {  0.0f, -0.5f,    C2},
+             {  0.0f, -0.5f,   -C2},
+             {    C2,  0.0f,  0.5f},
+             {    C2,  0.0f, -0.5f},
+             {   -C2,  0.0f,  0.5f},
+             {   -C2,  0.0f, -0.5f},
+             {  0.5f,    C2,  0.0f},
+             {  0.5f,   -C2,  0.0f},
+             { -0.5f,    C2,  0.0f},
+             { -0.5f,   -C2,  0.0f},
+             { SIN54, SIN54, SIN54},
+             { SIN54, SIN54,-SIN54},
+             { SIN54,-SIN54, SIN54},
+             { SIN54,-SIN54,-SIN54},
+             {-SIN54, SIN54, SIN54},
+             {-SIN54, SIN54,-SIN54},
+             {-SIN54,-SIN54, SIN54},
+             {-SIN54,-SIN54,-SIN54},
+         };
     }
 
-  private int mCurrState;
-  private int mIndexExcluded;
-  private ScrambleState[] mStates;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-             DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
+  void initializeCenterCoords()
     {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth);
+    if( mCorners==null ) initializeCorners();
+    if( mCenterMap==null ) initializeCenterMap();
 
-    initializeScrambleStates(numLayers);
+    mCenterCoords = new float[NUM_CENTERS][3];
+
+    for(int center=0; center<NUM_CENTERS; center++)
+      {
+      int[] map = mCenterMap[center];
+
+      float x = mCorners[map[0]][0] +
+                mCorners[map[1]][0] +
+                mCorners[map[2]][0] +
+                mCorners[map[3]][0] +
+                mCorners[map[4]][0] ;
+
+      float y = mCorners[map[0]][1] +
+                mCorners[map[1]][1] +
+                mCorners[map[2]][1] +
+                mCorners[map[3]][1] +
+                mCorners[map[4]][1] ;
+
+      float z = mCorners[map[0]][2] +
+                mCorners[map[1]][2] +
+                mCorners[map[2]][2] +
+                mCorners[map[3]][2] +
+                mCorners[map[4]][2] ;
+
+      mCenterCoords[center][0] = x/5;
+      mCenterCoords[center][1] = y/5;
+      mCenterCoords[center][2] = z/5;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -463,15 +504,18 @@ abstract class TwistyMinx extends TwistyObject
 
   int[] getSolvedQuats(int cubit, int numLayers)
     {
+    if( mQuats==null ) initializeQuats();
+    if( mFaceMap==null ) mFaceMap = new int[] {8,10,3,7,1,11,9,2,4,0,5,6};
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementMinx.FACE_AXIS[mFaceMap[status]],QUATS);
+    return status<0 ? null : buildSolvedQuats(MovementMinx.FACE_AXIS[mFaceMap[status]],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   Static4D[] getQuats()
     {
-    return QUATS;
+    if( mQuats==null ) initializeQuats();
+    return mQuats;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -569,6 +613,7 @@ abstract class TwistyMinx extends TwistyObject
 
   public int[] getBasicAngle()
     {
-    return BASIC_ANGLE;
+    if( mBasicAngle ==null ) mBasicAngle = new int[] { 5,5,5,5,5,5 };
+    return mBasicAngle;
     }
 }
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index 079fc2cd..a8bae7ae 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -271,7 +271,7 @@ public abstract class TwistyObject extends DistortedNode
     int sizeIndex = ObjectList.getSizeIndex(list.ordinal(),mNumLayers);
     int resourceID= list.getResourceIDs()[sizeIndex];
 
-    if( resourceID!=0 )
+    if( false ) // resourceID!=0 )
       {
       InputStream is = res.openRawResource(resourceID);
       DataInputStream dos = new DataInputStream(is);
