commit 967c1d17cfd2932b6dbfeb3e1fc818ae3bb114be
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Sep 25 01:30:07 2021 +0200

    Do away with the last method in the object Movement classes. Remove the object Movement classes altogether.
    From now on the implementation of a TwistyPuzzle is 100% data, no code at all.
    Next step: make the implementation a (generated?) (XML?) file.

diff --git a/src/main/java/org/distorted/objects/Movement.java b/src/main/java/org/distorted/objects/Movement.java
index b15a713d..3c2f9a3d 100644
--- a/src/main/java/org/distorted/objects/Movement.java
+++ b/src/main/java/org/distorted/objects/Movement.java
@@ -27,6 +27,13 @@ import org.distorted.library.type.Static4D;
 
 public abstract class Movement
   {
+  // it doesn't matter where we touch a face - the list of enabled rotAxis will always be the same
+  static final int TYPE_NOT_SPLIT    = 0;
+  // each face is split into several parts by lines coming from its center to the midpoints of each edge
+  static final int TYPE_SPLIT_EDGE   = 1;
+  // each face is split into several parts by lines coming from its center to the vertices
+  static final int TYPE_SPLIT_CORNER = 2;
+
   static final float SQ3 = (float)Math.sqrt(3);
   static final float SQ6 = (float)Math.sqrt(6);
 
@@ -42,15 +49,20 @@ public abstract class Movement
   private Static4D[][] mCastedRotAxis4D;
   private float[][] mTouchBorders, mA, mB;
 
+  private final int mType;
+  private final int[] mNumEnabled;
+  private final int[][][] mEnabled;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
+  abstract int returnPart(int type, int face, float[] touchPoint);
   abstract boolean isInsideFace(int face, float[] point);
-  abstract void computeEnabledAxis(int face, float[] touchPoint, int[] enabledAxis);
   public abstract float returnRotationFactor(int numLayers, int row);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable, float distance3D, int size)
+  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable,
+           float distance3D, int size, int type, int[] numEnabled, int[][][] enabled)
     {
     mPoint = new float[3];
     mCamera= new float[3];
@@ -59,6 +71,10 @@ public abstract class Movement
     mPoint2D = new float[2];
     mMove2D  = new float[2];
 
+    mType = type;
+    mNumEnabled = numEnabled;
+    mEnabled = enabled;
+
     mFaceAxis   = faceAxis;
     mNumFaceAxis= mFaceAxis.length;
 
@@ -380,6 +396,17 @@ public abstract class Movement
     return len;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
+    {
+    int part = returnPart(mType,face,touchPoint);
+
+    int num = mNumEnabled[face];
+    enabled[0] = num;
+    System.arraycopy(mEnabled[face][part], 0, enabled, 1, num);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement12.java b/src/main/java/org/distorted/objects/Movement12.java
index 5384b699..f92ffb38 100644
--- a/src/main/java/org/distorted/objects/Movement12.java
+++ b/src/main/java/org/distorted/objects/Movement12.java
@@ -30,7 +30,7 @@ import org.distorted.library.type.Static3D;
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Dodecahedral objects: map the 2D swipes of user's fingers to 3D rotations
 
-abstract class Movement12 extends Movement
+class Movement12 extends Movement
 {
   static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5);
   static final float DIST2D = (SIN54/COS54)/2;
@@ -53,9 +53,9 @@ abstract class Movement12 extends Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
+  Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size, int type, int[] numEnabled, int[][][] enabled)
     {
-    super(rotAxis, FACE_AXIS, cuts,rotatable,DIST3D, size);
+    super(rotAxis, FACE_AXIS, cuts,rotatable,DIST3D, size, type, numEnabled, enabled);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -111,48 +111,76 @@ abstract class Movement12 extends Movement
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
-// 'point' is inside the pentagon - or 0 otherwise.
+
+  int returnPart(int type, int face, float[] point)
+    {
+    switch(type)
+      {
+      case TYPE_SPLIT_EDGE  : return partEdge(point,face);
+      case TYPE_SPLIT_CORNER: return partCorner(point,face);
+      default               : return 0;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Return 0,1,2,3,4 - the vertex of the pentagon to which point 'point' is the closest, if the
+// 'point' is inside the pentagon - or -1 otherwise.
 // The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
 // This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
 // pentagon.
 // Distance from the center to a vertex of the pentagon = 1/(6*COS54)
 
-  int returnPartOfThePentagon(float[] point, int face)
+  int partEdge(float[] point, int face)
     {
     float angle = returnAngle(face);
     float A = (float)(Math.PI/5);
 
     for(int i=0; i<5; i++)
       {
-      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
+      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return -1;
       }
 
     if( isOnTheLeft(point, 0, 2.5f*A-angle) )
       {
       if( isOnTheLeft(point, 0, 3.5f*A-angle) )
         {
-        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
+        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 3 : 4;
         }
-      else return 1;
+      else return 0;
       }
     else
       {
       if( isOnTheLeft(point, 0, 4.5f*A-angle) )
         {
-        return 3;
+        return 2;
         }
       else
         {
-        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
+        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 1 : 0;
         }
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO - no such object yet
+
+  int partCorner(float[] point, int face)
+    {
+    return 0;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   boolean isInsideFace(int face, float[] p)
     {
-    return returnPartOfThePentagon(p,face) > 0;
+    float angle = returnAngle(face);
+    float A = (float)(Math.PI/5);
+
+    for(int i=0; i<5; i++)
+      {
+      if( isOnTheLeft(p, DIST2D, (9-2*i)*A-angle) ) return false;
+      }
+
+    return true;
     }
 }
diff --git a/src/main/java/org/distorted/objects/Movement4.java b/src/main/java/org/distorted/objects/Movement4.java
index 388a970c..8bf1e7cb 100644
--- a/src/main/java/org/distorted/objects/Movement4.java
+++ b/src/main/java/org/distorted/objects/Movement4.java
@@ -19,14 +19,12 @@
 
 package org.distorted.objects;
 
-import static org.distorted.objects.TwistyObject.SQ2;
-
 import org.distorted.library.type.Static3D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Tetrahedral objects: map the 2D swipes of user's fingers to 3D rotations
 
-abstract class Movement4 extends Movement
+class Movement4 extends Movement
 {
   static final float DIST3D = SQ6/12;
   static final float DIST2D = SQ3/6;
@@ -41,9 +39,48 @@ abstract class Movement4 extends Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
+  Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size, int type, int[] numEnabled, int[][][] enabled)
     {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size, type, numEnabled, enabled);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// corner    edge
+//   |       \ 0 /
+// 2 | 0      \ /
+//  / \      2 | 1
+// / 1 \       |
+
+  int returnPart(int type, int face, float[] touchPoint)
+    {
+    switch(type)
+      {
+      case TYPE_NOT_SPLIT   : return 0;
+
+      case TYPE_SPLIT_EDGE  : float y1 = (face > 1 ? touchPoint[1] : -touchPoint[1]);
+                              float x1 = touchPoint[0];
+
+                              boolean e0 = x1>0;
+                              boolean e1 = y1>(+SQ3/3)*x1;
+                              boolean e2 = y1>(-SQ3/3)*x1;
+
+                              if(  e1 && e2 ) return 0;
+                              if( !e1 && e0 ) return 1;
+                              if( !e0 &&!e2 ) return 2;
+
+      case TYPE_SPLIT_CORNER: float y2 = (face > 1 ? touchPoint[1] : -touchPoint[1]);
+                              float x2 = touchPoint[0];
+
+                              boolean c0 = x2>0;
+                              boolean c1 = y2>(+SQ3/3)*x2;
+                              boolean c2 = y2>(-SQ3/3)*x2;
+
+                              if(  c0 && c2 ) return 0;
+                              if( !c1 &&!c2 ) return 1;
+                              if( !c0 && c1 ) return 2;
+      }
+
+    return 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement6.java b/src/main/java/org/distorted/objects/Movement6.java
index c82bd75c..9225052a 100644
--- a/src/main/java/org/distorted/objects/Movement6.java
+++ b/src/main/java/org/distorted/objects/Movement6.java
@@ -19,14 +19,12 @@
 
 package org.distorted.objects;
 
-import static org.distorted.objects.TwistyObject.SQ2;
-
 import org.distorted.library.type.Static3D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Hexahedral objects: map the 2D swipes of user's fingers to 3D rotations
 
-abstract class Movement6 extends Movement
+class Movement6 extends Movement
 {
   static final float DIST3D = 0.5f;
   static final float DIST2D = 0.5f;
@@ -40,9 +38,32 @@ abstract class Movement6 extends Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
+  Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size, int type, int[] numEnabled, int[][][] enabled)
     {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size, type, numEnabled, enabled);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+//  corner    edge
+//  \ 0 /     3 | 0
+// 3 \ / 1  ___ | ___
+//   / \        |
+//  / 2 \     2 | 1
+
+  int returnPart(int type, int face, float[] touchPoint)
+    {
+    switch(type)
+      {
+      case TYPE_NOT_SPLIT   : return 0;
+      case TYPE_SPLIT_EDGE  : boolean e0 = touchPoint[0] > 0;
+                              boolean e1 = touchPoint[1] > 0;
+                              return e0 ? (e1 ? 0:1) : (e1 ? 3:2);
+      case TYPE_SPLIT_CORNER: boolean c0 = touchPoint[1] >= touchPoint[0];
+                              boolean c1 = touchPoint[1] >=-touchPoint[0];
+                              return c0 ? (c1 ? 0:3) : (c1 ? 1:2);
+      }
+
+    return 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/Movement8.java b/src/main/java/org/distorted/objects/Movement8.java
index 6d020929..cd3397dc 100644
--- a/src/main/java/org/distorted/objects/Movement8.java
+++ b/src/main/java/org/distorted/objects/Movement8.java
@@ -19,14 +19,12 @@
 
 package org.distorted.objects;
 
-import static org.distorted.objects.TwistyObject.SQ2;
-
 import org.distorted.library.type.Static3D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Octahedral objects: map the 2D swipes of user's fingers to 3D rotations
 
-abstract class Movement8 extends Movement
+class Movement8 extends Movement
 {
   static final float DIST3D = SQ6/6;
   static final float DIST2D = SQ3/6;
@@ -41,9 +39,48 @@ abstract class Movement8 extends Movement
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size)
+  Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, int size, int type, int[] numEnabled, int[][][] enabled)
     {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size);
+    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, size, type, numEnabled, enabled);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// corner    edge
+//   |       \ 0 /
+// 2 | 0      \ /
+//  / \      2 | 1
+// / 1 \       |
+
+  int returnPart(int type, int face, float[] touchPoint)
+    {
+    switch(type)
+      {
+      case TYPE_NOT_SPLIT   : return 0;
+
+      case TYPE_SPLIT_EDGE  : float y1 = (face%2 == 0 ? touchPoint[1] : -touchPoint[1]);
+                              float x1 = touchPoint[0];
+
+                              boolean e0 = x1>0;
+                              boolean e1 = y1>(+SQ3/3)*x1;
+                              boolean e2 = y1>(-SQ3/3)*x1;
+
+                              if(  e1 && e2 ) return 0;
+                              if( !e1 && e0 ) return 1;
+                              if( !e0 &&!e2 ) return 2;
+
+      case TYPE_SPLIT_CORNER: float y2 = (face%2 == 0 ? touchPoint[1] : -touchPoint[1]);
+                              float x2 = touchPoint[0];
+
+                              boolean c0 = x2>0;
+                              boolean c1 = y2>(+SQ3/3)*x2;
+                              boolean c2 = y2>(-SQ3/3)*x2;
+
+                              if(  c0 && c2 ) return 0;
+                              if( !c1 &&!c2 ) return 1;
+                              if( !c0 && c1 ) return 2;
+      }
+
+    return 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/MovementCornerTwisting.java b/src/main/java/org/distorted/objects/MovementCornerTwisting.java
deleted file mode 100644
index 1c255594..00000000
--- a/src/main/java/org/distorted/objects/MovementCornerTwisting.java
+++ /dev/null
@@ -1,58 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementCornerTwisting extends Movement6
-{
-  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0,1},{3,1},{2,3},{0,2}},
-          {{2,3},{3,1},{0,1},{0,2}},
-          {{1,2},{0,1},{0,3},{2,3}},
-          {{1,2},{2,3},{0,3},{0,1}},
-          {{0,3},{0,2},{1,2},{1,3}},
-          {{1,2},{0,2},{0,3},{1,3}},
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementCornerTwisting(float[][] cuts, boolean[][] rotatable,int size)
-    {
-    super(TwistySkewb.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    boolean p0 = touchPoint[1] >= touchPoint[0];
-    boolean p1 = touchPoint[1] >=-touchPoint[0];
-    int part = p0 ? (p1 ? 0:3) : (p1 ? 1:2);
-
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][part], 0, enabled, 1, num);
-    }
-}
-
diff --git a/src/main/java/org/distorted/objects/MovementCube.java b/src/main/java/org/distorted/objects/MovementCube.java
deleted file mode 100644
index 4423a8f7..00000000
--- a/src/main/java/org/distorted/objects/MovementCube.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementCube extends Movement6
-{
-  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementCube(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyCube.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementDiamond.java b/src/main/java/org/distorted/objects/MovementDiamond.java
deleted file mode 100644
index fa6519ae..00000000
--- a/src/main/java/org/distorted/objects/MovementDiamond.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementDiamond extends Movement8
-{
-  private static final int[] NUM_ENABLED = {3,3,3,3,3,3,3,3};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{1,2,3}},{{0,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,3}},{{0,1,2}},{{0,1,2}}
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementDiamond(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyDiamond.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementHelicopter.java b/src/main/java/org/distorted/objects/MovementHelicopter.java
deleted file mode 100644
index cb41405f..00000000
--- a/src/main/java/org/distorted/objects/MovementHelicopter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementHelicopter extends Movement6
-{
-  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{2,5},{2,4},{3,4},{3,5}},
-          {{2,4},{2,5},{3,5},{3,4}},
-          {{0,5},{1,5},{1,4},{0,4}},
-          {{0,4},{1,4},{1,5},{0,5}},
-          {{1,3},{0,3},{0,2},{1,2}},
-          {{0,3},{1,3},{1,2},{0,2}},
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementHelicopter(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyHelicopter.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    boolean p0 = touchPoint[0] > 0;
-    boolean p1 = touchPoint[1] > 0;
-    int part = p0 ? (p1 ? 0:1) : (p1 ? 3:2);
-
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][part], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementIvy.java b/src/main/java/org/distorted/objects/MovementIvy.java
deleted file mode 100644
index c008c511..00000000
--- a/src/main/java/org/distorted/objects/MovementIvy.java
+++ /dev/null
@@ -1,57 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementIvy extends Movement6
-{
-  private static final int[] NUM_ENABLED = {1,1,1,1,1,1};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0},{3},{3},{0}},
-          {{2},{1},{1},{2}},
-          {{2},{0},{0},{2}},
-          {{1},{3},{3},{1}},
-          {{0},{0},{1},{1}},
-          {{2},{2},{3},{3}},
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementIvy(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyIvy.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    boolean p0 = touchPoint[1] >= touchPoint[0];
-    boolean p1 = touchPoint[1] >=-touchPoint[0];
-    int part = p0 ? (p1 ? 0:3) : (p1 ? 1:2);
-
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][part], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementJing.java b/src/main/java/org/distorted/objects/MovementJing.java
deleted file mode 100644
index 84af3ba0..00000000
--- a/src/main/java/org/distorted/objects/MovementJing.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementJing extends Movement4
-{
-  private static final int[] NUM_ENABLED = {3,3,3,3};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementJing(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyJing.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementMinx.java b/src/main/java/org/distorted/objects/MovementMinx.java
deleted file mode 100644
index 1043cf72..00000000
--- a/src/main/java/org/distorted/objects/MovementMinx.java
+++ /dev/null
@@ -1,65 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementMinx extends Movement12
-{
-  private static final int[] NUM_ENABLED = {2,2,2,2,2,2,2,2,2,2,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{2,3},{3,5},{1,5},{1,4},{2,4}},
-          {{0,5},{2,5},{2,3},{3,4},{0,4}},
-          {{2,3},{2,5},{0,5},{0,4},{3,4}},
-          {{1,5},{3,5},{2,3},{2,4},{1,4}},
-          {{0,3},{0,4},{4,5},{1,5},{1,3}},
-          {{1,2},{1,4},{4,5},{0,5},{0,2}},
-          {{4,5},{1,4},{1,2},{0,2},{0,5}},
-          {{4,5},{0,4},{0,3},{1,3},{1,5}},
-          {{0,2},{0,1},{1,3},{3,5},{2,5}},
-          {{3,4},{2,4},{1,2},{0,1},{0,3}},
-          {{2,4},{3,4},{0,3},{0,1},{1,2}},
-          {{1,3},{0,1},{0,2},{2,5},{3,5}},
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementMinx(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyMinx.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int part = returnPartOfThePentagon(touchPoint,face);
-
-    if( part>0 )
-      {
-      int num = NUM_ENABLED[face];
-      enabled[0] = num;
-      System.arraycopy(ENABLED[face][part-1], 0, enabled, 1, num);
-      }
-    else enabled[0] = 0;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementPyraminx.java b/src/main/java/org/distorted/objects/MovementPyraminx.java
deleted file mode 100644
index ad1977e3..00000000
--- a/src/main/java/org/distorted/objects/MovementPyraminx.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementPyraminx extends Movement4
-{
-  private static final int[] NUM_ENABLED = {3,3,3,3};
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
-      };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementPyraminx(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyPyraminx.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementSquare.java b/src/main/java/org/distorted/objects/MovementSquare.java
deleted file mode 100644
index 77d65841..00000000
--- a/src/main/java/org/distorted/objects/MovementSquare.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementSquare extends Movement6
-{
-  private static final int[] NUM_ENABLED = {1,1,1,1,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-    {
-      {{0}},{{0}},{{1}},{{1}},{{0,1}},{{0,1}}
-    };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementSquare(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistySquare.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
diff --git a/src/main/java/org/distorted/objects/MovementUltimate.java b/src/main/java/org/distorted/objects/MovementUltimate.java
deleted file mode 100644
index bbc74156..00000000
--- a/src/main/java/org/distorted/objects/MovementUltimate.java
+++ /dev/null
@@ -1,48 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class MovementUltimate extends Movement12
-{
-  private static final int[] NUM_ENABLED = {2,2,2,2,2,2,2,2,2,2,2,2};
-
-  private static final int[][][] ENABLED = new int[][][]
-    {
-      {{2,3}},{{1,3}},{{1,3}},{{2,3}},{{0,3}},{{0,2}},{{0,2}},{{0,3}},{{1,2}},{{0,1}},{{0,1}},{{1,2}}
-    };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MovementUltimate(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    super(TwistyUltimate.ROT_AXIS,cuts,rotatable,size);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int num = NUM_ENABLED[face];
-    enabled[0] = num;
-    System.arraycopy(ENABLED[face][0], 0, enabled, 1, num);
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
index 58654b9d..7c3a1f8d 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -51,6 +53,13 @@ abstract class TwistyBandagedAbstract extends Twisty6
          {2,2,2}
         };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
+      };
+
   private static final int NUM_STICKERS = 4;
 
   private int[] mBasicAngle;
@@ -120,7 +129,7 @@ abstract class TwistyBandagedAbstract extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -457,8 +466,7 @@ abstract class TwistyBandagedAbstract extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCube(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
index e181aae9..98abe32a 100644
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ b/src/main/java/org/distorted/objects/TwistyCube.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -42,6 +44,13 @@ class TwistyCube extends Twisty6
            new Static3D(0,0,1)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
+      };
+
   private ScrambleState[] mStates;
   private Static4D[] mQuats;
   private float[][] mCuts;
@@ -155,7 +164,7 @@ class TwistyCube extends Twisty6
     {
     if( mQuats ==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status], mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -354,8 +363,7 @@ class TwistyCube extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCube(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index 2f9f360b..73fca157 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -44,6 +46,13 @@ public class TwistyDiamond extends Twisty8
            new Static3D(     0,-SQ3/3,+SQ6/3)
          };
 
+  private static final int[] NUM_ENABLED = {3,3,3,3,3,3,3,3};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2,3}},{{1,2,3}},{{0,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,3}},{{0,1,2}},{{0,1,2}}
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private int[] mFaceMap;
@@ -116,7 +125,7 @@ public class TwistyDiamond extends Twisty8
     if( mQuats==null ) initializeQuats();
     if( mFaceMap==null ) mFaceMap = new int[] {4,0,6,2,7,3,5,1};
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementDiamond.FACE_AXIS[mFaceMap[status]],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement8.FACE_AXIS[mFaceMap[status]],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -497,8 +506,7 @@ public class TwistyDiamond extends Twisty8
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementDiamond(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement8(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyDino.java b/src/main/java/org/distorted/objects/TwistyDino.java
index 8bfce17c..d67de040 100644
--- a/src/main/java/org/distorted/objects/TwistyDino.java
+++ b/src/main/java/org/distorted/objects/TwistyDino.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,18 @@ public abstract class TwistyDino extends Twisty6
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{0,1},{3,1},{2,3},{0,2}},
+          {{2,3},{3,1},{0,1},{0,2}},
+          {{1,2},{0,1},{0,3},{2,3}},
+          {{1,2},{2,3},{0,3},{0,1}},
+          {{0,3},{0,2},{1,2},{1,3}},
+          {{1,2},{0,2},{0,3},{1,3}},
+      };
+
   private int[] mBasicAngle;
   private Static4D[] mQuats;
   private float[][] mCuts;
@@ -226,8 +240,7 @@ public abstract class TwistyDino extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index 3f641c67..c0c159e1 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_EDGE;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -46,6 +48,18 @@ public class TwistyHelicopter extends Twisty6
            new Static3D(-SQ2/2, -SQ2/2,      0)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{2,5},{2,4},{3,4},{3,5}},
+          {{2,4},{2,5},{3,5},{3,4}},
+          {{0,5},{1,5},{1,4},{0,4}},
+          {{0,4},{1,4},{1,5},{0,5}},
+          {{1,3},{0,3},{0,2},{1,2}},
+          {{0,3},{1,3},{1,2},{0,2}},
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
@@ -133,7 +147,7 @@ public class TwistyHelicopter extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementHelicopter.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -419,8 +433,7 @@ public class TwistyHelicopter extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementHelicopter(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_EDGE,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
index ce715616..698c914e 100644
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objects/TwistyIvy.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,18 @@ public class TwistyIvy extends Twisty6
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] NUM_ENABLED = {1,1,1,1,1,1};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{0},{3},{3},{0}},
+          {{2},{1},{1},{2}},
+          {{2},{0},{0},{2}},
+          {{1},{3},{3},{1}},
+          {{0},{0},{1},{1}},
+          {{2},{2},{3},{3}},
+      };
+
   private static final int NUM_STICKERS = 2;
   public static final float IVY_D = 0.006f;
   private static final int  IVY_N = 8;
@@ -109,7 +123,7 @@ public class TwistyIvy extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -446,8 +460,7 @@ public class TwistyIvy extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementIvy(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyJing.java b/src/main/java/org/distorted/objects/TwistyJing.java
index 0aef5fa2..7573b9fc 100644
--- a/src/main/java/org/distorted/objects/TwistyJing.java
+++ b/src/main/java/org/distorted/objects/TwistyJing.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,13 @@ public class TwistyJing extends Twisty4
            new Static3D(-SQ6/3,+SQ3/3,     0),
          };
 
+  private static final int[] NUM_ENABLED = {3,3,3,3};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
+      };
+
   static final float F = 0.48f;  // length of the edge of the corner cubit. Keep<0.5
                                  // Assuming the length of the edge of the whole
                                  // tetrahedron is 2.0 (ie standard, equal to numLayers
@@ -110,7 +119,7 @@ public class TwistyJing extends Twisty4
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementJing.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -410,8 +419,7 @@ public class TwistyJing extends Twisty4
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementJing(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement4(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index cddcd419..03787276 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_EDGE;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectSticker;
@@ -57,6 +59,24 @@ abstract class TwistyMinx extends Twisty12
            new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2,2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{2,3},{3,5},{1,5},{1,4},{2,4}},
+          {{0,5},{2,5},{2,3},{3,4},{0,4}},
+          {{2,3},{2,5},{0,5},{0,4},{3,4}},
+          {{1,5},{3,5},{2,3},{2,4},{1,4}},
+          {{0,3},{0,4},{4,5},{1,5},{1,3}},
+          {{1,2},{1,4},{4,5},{0,5},{0,2}},
+          {{4,5},{1,4},{1,2},{0,2},{0,5}},
+          {{4,5},{0,4},{0,3},{1,3},{1,5}},
+          {{0,2},{0,1},{1,3},{3,5},{2,5}},
+          {{3,4},{2,4},{1,2},{0,1},{0,3}},
+          {{2,4},{3,4},{0,3},{0,1},{1,2}},
+          {{1,3},{0,1},{0,2},{2,5},{3,5}},
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private int[] mFaceMap;
@@ -496,7 +516,7 @@ abstract class TwistyMinx extends Twisty12
     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]],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[mFaceMap[status]],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -513,7 +533,7 @@ abstract class TwistyMinx extends Twisty12
     if( mCuts==null )
       {
       mCuts = new float[6][numLayers-1];
-      float D = numLayers*MovementMinx.DIST3D;
+      float D = numLayers*Movement12.DIST3D;
       float X = 2*D/(2+SIN18);  // height of the 'upper' part of a dodecahedron, i.e. put it on a table,
                                 // its height is then 2D, it has one 'lower' part of height X, one
                                 // 'middle' part of height Y and one upper part of height X again.
@@ -589,8 +609,7 @@ abstract class TwistyMinx extends Twisty12
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementMinx(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement12(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_EDGE,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyMirror.java b/src/main/java/org/distorted/objects/TwistyMirror.java
index 19765e08..22830b54 100644
--- a/src/main/java/org/distorted/objects/TwistyMirror.java
+++ b/src/main/java/org/distorted/objects/TwistyMirror.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -42,6 +44,13 @@ class TwistyMirror extends Twisty6
            new Static3D(0,0,1)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
+      };
+
   private static final int[] FACE_COLORS = new int[] { COLOR_WHITE };
   private static final float DX = 0.10f;
   private static final float DY = 0.25f;
@@ -654,8 +663,7 @@ class TwistyMirror extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCube(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index f22904fd..b7cea39b 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,13 @@ public class TwistyPyraminx extends Twisty4
            new Static3D(-SQ6/3,+SQ3/3,     0),
          };
 
+  private static final int[] NUM_ENABLED = {3,3,3,3};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
@@ -135,7 +144,7 @@ public class TwistyPyraminx extends Twisty4
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -381,8 +390,7 @@ public class TwistyPyraminx extends Twisty4
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementPyraminx(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement4(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
index f2bddced..fe564771 100644
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objects/TwistyRedi.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,18 @@ public class TwistyRedi extends Twisty6
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{0,1},{3,1},{2,3},{0,2}},
+          {{2,3},{3,1},{0,1},{0,2}},
+          {{1,2},{0,1},{0,3},{2,3}},
+          {{1,2},{2,3},{0,3},{0,1}},
+          {{0,3},{0,2},{1,2},{1,3}},
+          {{1,2},{0,2},{0,3},{1,3}},
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
@@ -112,7 +126,7 @@ public class TwistyRedi extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementCornerTwisting.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -416,8 +430,7 @@ public class TwistyRedi extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistyRex.java b/src/main/java/org/distorted/objects/TwistyRex.java
index 6bceb02a..4fb56860 100644
--- a/src/main/java/org/distorted/objects/TwistyRex.java
+++ b/src/main/java/org/distorted/objects/TwistyRex.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,18 @@ public class TwistyRex extends Twisty6
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{0,1},{3,1},{2,3},{0,2}},
+          {{2,3},{3,1},{0,1},{0,2}},
+          {{1,2},{0,1},{0,3},{2,3}},
+          {{1,2},{2,3},{0,3},{0,1}},
+          {{0,3},{0,2},{1,2},{1,3}},
+          {{1,2},{0,2},{0,3},{1,3}},
+      };
+
   public static final float REX_D = 0.2f;
 
   private ScrambleState[] mStates;
@@ -107,7 +121,7 @@ public class TwistyRex extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementCornerTwisting.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -449,8 +463,7 @@ public class TwistyRex extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
index 24a1aa31..2fd0226e 100644
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objects/TwistySkewb.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -43,6 +45,18 @@ public class TwistySkewb extends Twisty6
            new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+      {
+          {{0,1},{3,1},{2,3},{0,2}},
+          {{2,3},{3,1},{0,1},{0,2}},
+          {{1,2},{0,1},{0,3},{2,3}},
+          {{1,2},{2,3},{0,3},{0,1}},
+          {{0,3},{0,2},{1,2},{1,3}},
+          {{1,2},{0,2},{0,3},{1,3}},
+      };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
@@ -106,7 +120,7 @@ public class TwistySkewb extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementCornerTwisting.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -552,8 +566,7 @@ public class TwistySkewb extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementCornerTwisting(mCuts,mLayerRotatable,2*numLayers-2);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,2*numLayers-2,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistySquare.java b/src/main/java/org/distorted/objects/TwistySquare.java
index 037c0289..3ac29cf0 100644
--- a/src/main/java/org/distorted/objects/TwistySquare.java
+++ b/src/main/java/org/distorted/objects/TwistySquare.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.library.main.DistortedEffects;
@@ -46,6 +48,13 @@ abstract class TwistySquare extends Twisty6
       new Static3D(0,-1,0),
     };
 
+  private static final int[] NUM_ENABLED = {1,1,1,1,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+    {
+      {{0}},{{0}},{{1}},{{1}},{{0,1}},{{0,1}}
+    };
+
   private int[] mBasicAngle;
   private float[][] mCuts;
   private boolean[][] mLayerRotatable;
@@ -155,8 +164,7 @@ abstract class TwistySquare extends Twisty6
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementSquare(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
diff --git a/src/main/java/org/distorted/objects/TwistySquare1.java b/src/main/java/org/distorted/objects/TwistySquare1.java
index d6891e12..045b3c92 100644
--- a/src/main/java/org/distorted/objects/TwistySquare1.java
+++ b/src/main/java/org/distorted/objects/TwistySquare1.java
@@ -70,7 +70,7 @@ class TwistySquare1 extends TwistySquare
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementSquare.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyUltimate.java b/src/main/java/org/distorted/objects/TwistyUltimate.java
index d4cfc0ce..f4d40758 100644
--- a/src/main/java/org/distorted/objects/TwistyUltimate.java
+++ b/src/main/java/org/distorted/objects/TwistyUltimate.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
+
 import android.content.res.Resources;
 
 import org.distorted.helpers.ObjectShape;
@@ -51,6 +53,13 @@ class TwistyUltimate extends Twisty12
            new Static3D( 0,C,-B)
          };
 
+  private static final int[] NUM_ENABLED = {2,2,2,2,2,2,2,2,2,2,2,2};
+
+  private static final int[][][] ENABLED = new int[][][]
+    {
+      {{2,3}},{{1,3}},{{1,3}},{{2,3}},{{0,3}},{{0,2}},{{0,2}},{{0,3}},{{1,2}},{{0,1}},{{0,1}},{{1,2}}
+    };
+
   private ScrambleState[] mStates;
   private int[] mBasicAngle;
   private Static4D[] mQuats;
@@ -114,7 +123,7 @@ class TwistyUltimate extends Twisty12
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementUltimate.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -409,8 +418,7 @@ class TwistyUltimate extends Twisty12
       int numLayers = getNumLayers();
       if( mCuts==null ) getCuts(numLayers);
       getLayerRotatable(numLayers);
-
-      mMovement = new MovementUltimate(mCuts,mLayerRotatable,numLayers);
+      mMovement = new Movement12(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
       }
     return mMovement;
     }
