commit f86b282a3f7ca9cf762048bf869b3aba91869498
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Nov 8 13:49:11 2021 +0100

    Minor.

diff --git a/src/main/java/org/distorted/objectlib/main/Movement12.java b/src/main/java/org/distorted/objectlib/main/Movement12.java
deleted file mode 100644
index e913c9df..00000000
--- a/src/main/java/org/distorted/objectlib/main/Movement12.java
+++ /dev/null
@@ -1,189 +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.objectlib.main;
-
-import static org.distorted.objectlib.main.TwistyObject.SQ5;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Dodecahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement12 extends Movement
-{
-  public static final float C2       = (SQ5+3)/4;
-  public static final float LEN      = (float)(Math.sqrt(1.25f+0.5f*SQ5));
-  public static final float SIN54    = (SQ5+1)/4;
-  public static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
-
-  public  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5);
-  private static final float DIST2D = (SIN54/COS54)/2;
-  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,
-                                        DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
-
-  public static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
-           new Static3D(    C2/LEN,-SIN54/LEN,    0      ),
-           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
-           new Static3D(   -C2/LEN,-SIN54/LEN,    0      ),
-           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
-           new Static3D( 0        ,    C2/LEN,-SIN54/LEN ),
-           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
-           new Static3D( 0        ,   -C2/LEN,-SIN54/LEN ),
-           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
-           new Static3D( SIN54/LEN,    0     ,   -C2/LEN ),
-           new Static3D(-SIN54/LEN,    0     ,    C2/LEN ),
-           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement12(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts,rotatable,D3D, size, type, enabled);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float returnRotationFactor(int[] numLayers, int row)
-    {
-    return 1.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return angle (in radians) that the line connecting the center C of the pentagonal face and the
-// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
-
-  private float returnAngle(int face)
-    {
-    switch(face)
-      {
-      case  0:
-      case  2:
-      case  6:
-      case  7: return 0.0f;
-      case  1:
-      case  3:
-      case  4:
-      case  5: return (float)(36*Math.PI/180);
-      case  9:
-      case 10: return (float)(54*Math.PI/180);
-      case  8:
-      case 11: return (float)(18*Math.PI/180);
-      }
-
-    return 0.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
-// from the center of the coordinate system to P.
-// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
-// P' and going in the direction of V.
-// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
-// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
-// directly upwards, is 'point' on the left or the right of it?
-
-  private boolean isOnTheLeft(float[] point, float distance, float angle)
-    {
-    float sin = (float)Math.sin(angle);
-    float cos = (float)Math.cos(angle);
-
-    float vx = point[0] + sin*distance;
-    float vy = point[1] - cos*distance;
-
-    return vx*sin < vy*cos;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  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 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 -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) ? 3 : 4;
-        }
-      else return 0;
-      }
-    else
-      {
-      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
-        {
-        return 2;
-        }
-      else
-        {
-        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)
-    {
-    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/objectlib/main/Movement4.java b/src/main/java/org/distorted/objectlib/main/Movement4.java
deleted file mode 100644
index 90265b1e..00000000
--- a/src/main/java/org/distorted/objectlib/main/Movement4.java
+++ /dev/null
@@ -1,106 +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.objectlib.main;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Tetrahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement4 extends Movement
-{
-  private static final float DIST3D = SQ6/12;
-  private static final float DIST2D = SQ3/6;
-
-  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D };
-
-  public static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D(     0,+SQ3/3,+SQ6/3),
-           new Static3D(     0,+SQ3/3,-SQ6/3),
-           new Static3D(-SQ6/3,-SQ3/3,     0),
-           new Static3D(+SQ6/3,-SQ3/3,     0),
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement4(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Jing has nL=2
-
-  public float returnRotationFactor(int[] numLayers, int row)
-    {
-    int numL = numLayers[0];
-
-    return numL==2 ? 1.0f : ((float)numL)/(numL-row);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean isInsideFace(int face, float[] p)
-    {
-    float y = (face > 1 ? p[1] : -p[1]);
-    float x = p[0];
-    return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/Movement6.java b/src/main/java/org/distorted/objectlib/main/Movement6.java
deleted file mode 100644
index 37b0c55b..00000000
--- a/src/main/java/org/distorted/objectlib/main/Movement6.java
+++ /dev/null
@@ -1,84 +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.objectlib.main;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Hexahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement6 extends Movement
-{
-  private static final float DIST3D = 0.5f;
-  private static final float DIST2D = 0.5f;
-
-  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
-
-  public static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D(1,0,0), new Static3D(-1,0,0),
-           new Static3D(0,1,0), new Static3D(0,-1,0),
-           new Static3D(0,0,1), new Static3D(0,0,-1)
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement6(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float returnRotationFactor(int[] numLayers, int row)
-    {
-    return 1.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean isInsideFace(int face, float[] p)
-    {
-    return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D );
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/Movement8.java b/src/main/java/org/distorted/objectlib/main/Movement8.java
deleted file mode 100644
index 73d10b2d..00000000
--- a/src/main/java/org/distorted/objectlib/main/Movement8.java
+++ /dev/null
@@ -1,103 +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.objectlib.main;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Octahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement8 extends Movement
-{
-  private static final float DIST3D = SQ6/6;
-  private static final float DIST2D = SQ3/6;
-
-  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
-
-  public static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ6/3,+SQ3/3,     0), new Static3D(-SQ6/3,-SQ3/3,     0),
-           new Static3D(-SQ6/3,+SQ3/3,     0), new Static3D(+SQ6/3,-SQ3/3,     0),
-           new Static3D(     0,+SQ3/3,+SQ6/3), new Static3D(     0,-SQ3/3,-SQ6/3),
-           new Static3D(     0,+SQ3/3,-SQ6/3), new Static3D(     0,-SQ3/3,+SQ6/3)
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement8(Static3D[] rotAxis,float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float returnRotationFactor(int[] numLayers, int row)
-    {
-    return 1.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean isInsideFace(int face, float[] p)
-    {
-    float y = (face%2 == 0 ? p[1] : -p[1]);
-    float x = p[0];
-    return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/MovementC.java b/src/main/java/org/distorted/objectlib/main/MovementC.java
deleted file mode 100644
index 859b6dd9..00000000
--- a/src/main/java/org/distorted/objectlib/main/MovementC.java
+++ /dev/null
@@ -1,74 +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.objectlib.main;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Cuboids
-
-public class MovementC extends Movement
-{
-  private final float[] mDist3D;
-
-  public static final Static3D[] FACE_AXIS = new Static3D[]
-         {
-           new Static3D(1,0,0), new Static3D(-1,0,0),
-           new Static3D(0,1,0), new Static3D(0,-1,0),
-           new Static3D(0,0,1), new Static3D(0,0,-1)
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public MovementC(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type,
-                   int[][][] enabled, float[] dist3D)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, dist3D, size, type, enabled);
-
-    mDist3D = dist3D;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int returnPart(int type, int face, float[] touchPoint)
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float returnRotationFactor(int[] numLayers, int row)
-    {
-    return 1.0f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean isInsideFace(int face, float[] p)
-    {
-    switch(face/2)
-      {
-      case 0: return ( p[0]<=mDist3D[4] && p[0]>=-mDist3D[4] && p[1]<=mDist3D[2] && p[1]>=-mDist3D[2] );
-      case 1: return ( p[0]<=mDist3D[0] && p[0]>=-mDist3D[0] && p[1]<=mDist3D[4] && p[1]>=-mDist3D[4] );
-      case 2: return ( p[0]<=mDist3D[0] && p[0]>=-mDist3D[0] && p[1]<=mDist3D[2] && p[1]>=-mDist3D[2] );
-      }
-    return false;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/MovementCuboids.java b/src/main/java/org/distorted/objectlib/main/MovementCuboids.java
new file mode 100644
index 00000000..3d461077
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/MovementCuboids.java
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.objectlib.main;
+
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Cuboids
+
+public class MovementCuboids extends Movement
+{
+  private final float[] mDist3D;
+
+  public static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D(1,0,0), new Static3D(-1,0,0),
+           new Static3D(0,1,0), new Static3D(0,-1,0),
+           new Static3D(0,0,1), new Static3D(0,0,-1)
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public MovementCuboids(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type,
+                         int[][][] enabled, float[] dist3D)
+    {
+    super(rotAxis, FACE_AXIS, cuts, rotatable, dist3D, size, type, enabled);
+
+    mDist3D = dist3D;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int returnPart(int type, int face, float[] touchPoint)
+    {
+    return 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float returnRotationFactor(int[] numLayers, int row)
+    {
+    return 1.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean isInsideFace(int face, float[] p)
+    {
+    switch(face/2)
+      {
+      case 0: return ( p[0]<=mDist3D[4] && p[0]>=-mDist3D[4] && p[1]<=mDist3D[2] && p[1]>=-mDist3D[2] );
+      case 1: return ( p[0]<=mDist3D[0] && p[0]>=-mDist3D[0] && p[1]<=mDist3D[4] && p[1]>=-mDist3D[4] );
+      case 2: return ( p[0]<=mDist3D[0] && p[0]>=-mDist3D[0] && p[1]<=mDist3D[2] && p[1]>=-mDist3D[2] );
+      }
+    return false;
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/MovementDodecahedron.java b/src/main/java/org/distorted/objectlib/main/MovementDodecahedron.java
new file mode 100644
index 00000000..f7cc1f53
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/MovementDodecahedron.java
@@ -0,0 +1,189 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.objectlib.main;
+
+import static org.distorted.objectlib.main.TwistyObject.SQ5;
+
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dodecahedral objects: map the 2D swipes of user's fingers to 3D rotations
+
+public class MovementDodecahedron extends Movement
+{
+  public static final float C2       = (SQ5+3)/4;
+  public static final float LEN      = (float)(Math.sqrt(1.25f+0.5f*SQ5));
+  public static final float SIN54    = (SQ5+1)/4;
+  public static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
+
+  public  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5);
+  private static final float DIST2D = (SIN54/COS54)/2;
+  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,
+                                        DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
+
+  public static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
+           new Static3D(    C2/LEN,-SIN54/LEN,    0      ),
+           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
+           new Static3D(   -C2/LEN,-SIN54/LEN,    0      ),
+           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
+           new Static3D( 0        ,    C2/LEN,-SIN54/LEN ),
+           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
+           new Static3D( 0        ,   -C2/LEN,-SIN54/LEN ),
+           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
+           new Static3D( SIN54/LEN,    0     ,   -C2/LEN ),
+           new Static3D(-SIN54/LEN,    0     ,    C2/LEN ),
+           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public MovementDodecahedron(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
+    {
+    super(rotAxis, FACE_AXIS, cuts,rotatable,D3D, size, type, enabled);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float returnRotationFactor(int[] numLayers, int row)
+    {
+    return 1.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// return angle (in radians) that the line connecting the center C of the pentagonal face and the
+// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
+
+  private float returnAngle(int face)
+    {
+    switch(face)
+      {
+      case  0:
+      case  2:
+      case  6:
+      case  7: return 0.0f;
+      case  1:
+      case  3:
+      case  4:
+      case  5: return (float)(36*Math.PI/180);
+      case  9:
+      case 10: return (float)(54*Math.PI/180);
+      case  8:
+      case 11: return (float)(18*Math.PI/180);
+      }
+
+    return 0.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
+// from the center of the coordinate system to P.
+// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
+// P' and going in the direction of V.
+// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
+// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
+// directly upwards, is 'point' on the left or the right of it?
+
+  private boolean isOnTheLeft(float[] point, float distance, float angle)
+    {
+    float sin = (float)Math.sin(angle);
+    float cos = (float)Math.cos(angle);
+
+    float vx = point[0] + sin*distance;
+    float vy = point[1] - cos*distance;
+
+    return vx*sin < vy*cos;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  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 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 -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) ? 3 : 4;
+        }
+      else return 0;
+      }
+    else
+      {
+      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
+        {
+        return 2;
+        }
+      else
+        {
+        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)
+    {
+    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/objectlib/main/MovementHexahedron.java b/src/main/java/org/distorted/objectlib/main/MovementHexahedron.java
new file mode 100644
index 00000000..c59633ec
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/MovementHexahedron.java
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.objectlib.main;
+
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Hexahedral objects: map the 2D swipes of user's fingers to 3D rotations
+
+public class MovementHexahedron extends Movement
+{
+  private static final float DIST3D = 0.5f;
+  private static final float DIST2D = 0.5f;
+
+  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
+
+  public static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D(1,0,0), new Static3D(-1,0,0),
+           new Static3D(0,1,0), new Static3D(0,-1,0),
+           new Static3D(0,0,1), new Static3D(0,0,-1)
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public MovementHexahedron(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
+    {
+    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float returnRotationFactor(int[] numLayers, int row)
+    {
+    return 1.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean isInsideFace(int face, float[] p)
+    {
+    return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D );
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/MovementOctahedron.java b/src/main/java/org/distorted/objectlib/main/MovementOctahedron.java
new file mode 100644
index 00000000..010b5116
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/MovementOctahedron.java
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.objectlib.main;
+
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Octahedral objects: map the 2D swipes of user's fingers to 3D rotations
+
+public class MovementOctahedron extends Movement
+{
+  private static final float DIST3D = SQ6/6;
+  private static final float DIST2D = SQ3/6;
+
+  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D,DIST3D };
+
+  public static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D(+SQ6/3,+SQ3/3,     0), new Static3D(-SQ6/3,-SQ3/3,     0),
+           new Static3D(-SQ6/3,+SQ3/3,     0), new Static3D(+SQ6/3,-SQ3/3,     0),
+           new Static3D(     0,+SQ3/3,+SQ6/3), new Static3D(     0,-SQ3/3,-SQ6/3),
+           new Static3D(     0,+SQ3/3,-SQ6/3), new Static3D(     0,-SQ3/3,+SQ6/3)
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public MovementOctahedron(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
+    {
+    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float returnRotationFactor(int[] numLayers, int row)
+    {
+    return 1.0f;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean isInsideFace(int face, float[] p)
+    {
+    float y = (face%2 == 0 ? p[1] : -p[1]);
+    float x = p[0];
+    return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/MovementTetrahedron.java b/src/main/java/org/distorted/objectlib/main/MovementTetrahedron.java
new file mode 100644
index 00000000..37481f75
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/MovementTetrahedron.java
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.objectlib.main;
+
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Tetrahedral objects: map the 2D swipes of user's fingers to 3D rotations
+
+public class MovementTetrahedron extends Movement
+{
+  private static final float DIST3D = SQ6/12;
+  private static final float DIST2D = SQ3/6;
+
+  private static final float[] D3D  = { DIST3D,DIST3D,DIST3D,DIST3D };
+
+  public static final Static3D[] FACE_AXIS = new Static3D[]
+         {
+           new Static3D(     0,+SQ3/3,+SQ6/3),
+           new Static3D(     0,+SQ3/3,-SQ6/3),
+           new Static3D(-SQ6/3,-SQ3/3,     0),
+           new Static3D(+SQ6/3,-SQ3/3,     0),
+         };
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public MovementTetrahedron(Static3D[] rotAxis, float[][] cuts, boolean[][] rotatable, float size, int type, int[][][] enabled)
+    {
+    super(rotAxis, FACE_AXIS, cuts, rotatable, D3D, size, type, 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;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Jing has nL=2
+
+  public float returnRotationFactor(int[] numLayers, int row)
+    {
+    int numL = numLayers[0];
+
+    return numL==2 ? 1.0f : ((float)numL)/(numL-row);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean isInsideFace(int face, float[] p)
+    {
+    float y = (face > 1 ? p[1] : -p[1]);
+    float x = p[0];
+    return (y >= -DIST2D) && (y <= DIST2D*(2-6*x)) && (y <= DIST2D*(2+6*x));
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/Twisty12.java b/src/main/java/org/distorted/objectlib/main/Twisty12.java
deleted file mode 100644
index 88db8438..00000000
--- a/src/main/java/org/distorted/objectlib/main/Twisty12.java
+++ /dev/null
@@ -1,96 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.objectlib.main;
-
-import java.io.InputStream;
-
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty12 extends TwistyObject
-{
-  static final int MINX_LGREEN = 0xff53aa00;
-  static final int MINX_PINK   = 0xfffd7ab7;
-  static final int MINX_SANDY  = 0xffefd48b;
-  static final int MINX_LBLUE  = 0xff00a2d7;
-  static final int MINX_ORANGE = 0xffff6200;
-  static final int MINX_VIOLET = 0xff7d59a4;
-  static final int MINX_DGREEN = 0xff007a47;
-  static final int MINX_DRED   = 0xffbd0000;
-  static final int MINX_DBLUE  = 0xff1a29b2;
-  static final int MINX_DYELLOW= 0xffffc400;
-  static final int MINX_WHITE  = 0xffffffff;
-  static final int MINX_GREY   = 0xff727c7b;
-
-  static final int[] FACE_COLORS = new int[]
-         {
-           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
-           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
-           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
-         };
-
-  static final int NUM_FACES = 12;
-  static final int FOV = 30;
-  static final float RATIO = 0.35f;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty12(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
-    {
-    super(numLayers, realSize, quat, move, scale, stream);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public final int getNumFaces()
-    {
-    return NUM_FACES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumFaceColors()
-    {
-    return FACE_COLORS.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getFOV()
-    {
-    return FOV;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getScreenRatio()
-    {
-    return RATIO;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/Twisty4.java b/src/main/java/org/distorted/objectlib/main/Twisty4.java
deleted file mode 100644
index bb37bb23..00000000
--- a/src/main/java/org/distorted/objectlib/main/Twisty4.java
+++ /dev/null
@@ -1,82 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.objectlib.main;
-
-import java.io.InputStream;
-
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty4 extends TwistyObject
-{
-  static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_GREEN , COLOR_YELLOW,
-           COLOR_BLUE  , COLOR_RED
-         };
-
-  static final int NUM_FACES = 4;
-  static final int FOV = 60;
-  static final float RATIO = 0.89f;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty4(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
-    {
-    super(numLayers, realSize, quat, move, scale, stream);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public final int getNumFaces()
-    {
-    return NUM_FACES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumFaceColors()
-    {
-    return FACE_COLORS.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getFOV()
-    {
-    return FOV;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getScreenRatio()
-    {
-    return RATIO;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/Twisty6.java b/src/main/java/org/distorted/objectlib/main/Twisty6.java
deleted file mode 100644
index 493adf67..00000000
--- a/src/main/java/org/distorted/objectlib/main/Twisty6.java
+++ /dev/null
@@ -1,83 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.objectlib.main;
-
-import java.io.InputStream;
-
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty6 extends TwistyObject
-{
-  static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_YELLOW, COLOR_WHITE,
-           COLOR_BLUE  , COLOR_GREEN,
-           COLOR_RED   , COLOR_ORANGE
-         };
-
-  static final int NUM_FACES = 6;
-  static final int FOV = 60;
-  static final float RATIO = 0.50f;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty6(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
-    {
-    super(numLayers, realSize, quat, move, scale, stream);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public final int getNumFaces()
-    {
-    return NUM_FACES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumFaceColors()
-    {
-    return FACE_COLORS.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getFOV()
-    {
-    return FOV;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getScreenRatio()
-    {
-    return RATIO;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/Twisty8.java b/src/main/java/org/distorted/objectlib/main/Twisty8.java
deleted file mode 100644
index 578cdd03..00000000
--- a/src/main/java/org/distorted/objectlib/main/Twisty8.java
+++ /dev/null
@@ -1,84 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 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.objectlib.main;
-
-import java.io.InputStream;
-
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty8 extends TwistyObject
-{
-  static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_ORANGE, COLOR_VIOLET,
-           COLOR_WHITE , COLOR_BLUE  ,
-           COLOR_YELLOW, COLOR_RED   ,
-           COLOR_GREEN , COLOR_GREY
-         };
-
-  static final int NUM_FACES = 8;
-  static final int FOV = 60;
-  static final float RATIO = 0.68f;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty8(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
-    {
-    super(numLayers, realSize, quat, move, scale, stream);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public final int getNumFaces()
-    {
-    return NUM_FACES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumFaceColors()
-    {
-    return FACE_COLORS.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getFOV()
-    {
-    return FOV;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getScreenRatio()
-    {
-    return RATIO;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyDodecahedron.java b/src/main/java/org/distorted/objectlib/main/TwistyDodecahedron.java
new file mode 100644
index 00000000..0c7c9605
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/TwistyDodecahedron.java
@@ -0,0 +1,96 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.objectlib.main;
+
+import java.io.InputStream;
+
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public abstract class TwistyDodecahedron extends TwistyObject
+{
+  static final int MINX_LGREEN = 0xff53aa00;
+  static final int MINX_PINK   = 0xfffd7ab7;
+  static final int MINX_SANDY  = 0xffefd48b;
+  static final int MINX_LBLUE  = 0xff00a2d7;
+  static final int MINX_ORANGE = 0xffff6200;
+  static final int MINX_VIOLET = 0xff7d59a4;
+  static final int MINX_DGREEN = 0xff007a47;
+  static final int MINX_DRED   = 0xffbd0000;
+  static final int MINX_DBLUE  = 0xff1a29b2;
+  static final int MINX_DYELLOW= 0xffffc400;
+  static final int MINX_WHITE  = 0xffffffff;
+  static final int MINX_GREY   = 0xff727c7b;
+
+  static final int[] FACE_COLORS = new int[]
+         {
+           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
+           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
+           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
+         };
+
+  static final int NUM_FACES = 12;
+  static final int FOV = 30;
+  static final float RATIO = 0.35f;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public TwistyDodecahedron(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
+    {
+    super(numLayers, realSize, quat, move, scale, stream);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public final int getNumFaces()
+    {
+    return NUM_FACES;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getNumFaceColors()
+    {
+    return FACE_COLORS.length;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getFOV()
+    {
+    return FOV;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float getScreenRatio()
+    {
+    return RATIO;
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyHexahedron.java b/src/main/java/org/distorted/objectlib/main/TwistyHexahedron.java
new file mode 100644
index 00000000..4c2a0daf
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/TwistyHexahedron.java
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.objectlib.main;
+
+import java.io.InputStream;
+
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public abstract class TwistyHexahedron extends TwistyObject
+{
+  static final int[] FACE_COLORS = new int[]
+         {
+           COLOR_YELLOW, COLOR_WHITE,
+           COLOR_BLUE  , COLOR_GREEN,
+           COLOR_RED   , COLOR_ORANGE
+         };
+
+  static final int NUM_FACES = 6;
+  static final int FOV = 60;
+  static final float RATIO = 0.50f;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public TwistyHexahedron(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
+    {
+    super(numLayers, realSize, quat, move, scale, stream);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public final int getNumFaces()
+    {
+    return NUM_FACES;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getNumFaceColors()
+    {
+    return FACE_COLORS.length;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getFOV()
+    {
+    return FOV;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float getScreenRatio()
+    {
+    return RATIO;
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyJson.java b/src/main/java/org/distorted/objectlib/main/TwistyJson.java
index 07a1abaa..a184131c 100644
--- a/src/main/java/org/distorted/objectlib/main/TwistyJson.java
+++ b/src/main/java/org/distorted/objectlib/main/TwistyJson.java
@@ -286,10 +286,10 @@ public class TwistyJson extends TwistyObject
     {
     switch( mReader.getNumFaces() )
       {
-      case  4: return Twisty4.FOV;
-      case  6: return Twisty6.FOV;
-      case  8: return Twisty8.FOV;
-      case 12: return Twisty12.FOV;
+      case  4: return TwistyTetrahedron.FOV;
+      case  6: return TwistyHexahedron.FOV;
+      case  8: return TwistyOctahedron.FOV;
+      case 12: return TwistyDodecahedron.FOV;
       }
 
     return 0;
@@ -301,10 +301,10 @@ public class TwistyJson extends TwistyObject
     {
     switch( mReader.getNumFaces() )
       {
-      case  4: return Twisty4.RATIO;
-      case  6: return Twisty6.RATIO;
-      case  8: return Twisty8.RATIO;
-      case 12: return Twisty12.RATIO;
+      case  4: return TwistyTetrahedron.RATIO;
+      case  6: return TwistyHexahedron.RATIO;
+      case  8: return TwistyOctahedron.RATIO;
+      case 12: return TwistyDodecahedron.RATIO;
       }
 
     return 0.0f;
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyObject.java b/src/main/java/org/distorted/objectlib/main/TwistyObject.java
index 34a87aeb..d0e204f8 100644
--- a/src/main/java/org/distorted/objectlib/main/TwistyObject.java
+++ b/src/main/java/org/distorted/objectlib/main/TwistyObject.java
@@ -1339,16 +1339,16 @@ public abstract class TwistyObject
 
       switch(movementType)
         {
-        case MOVEMENT_TETRAHEDRON : mMovement = new Movement4(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
+        case MOVEMENT_TETRAHEDRON : mMovement = new MovementTetrahedron(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
                                     break;
-        case MOVEMENT_HEXAHEDRON  : mMovement = new Movement6(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
+        case MOVEMENT_HEXAHEDRON  : mMovement = new MovementHexahedron(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
                                     break;
-        case MOVEMENT_OCTAHEDRON  : mMovement = new Movement8(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
+        case MOVEMENT_OCTAHEDRON  : mMovement = new MovementOctahedron(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
                                     break;
-        case MOVEMENT_DODECAHEDRON: mMovement = new Movement12(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
+        case MOVEMENT_DODECAHEDRON: mMovement = new MovementDodecahedron(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled);
                                     break;
         case MOVEMENT_SHAPECHANGE : float[] dist3D = getDist3D(numLayers);
-                                    mMovement = new MovementC(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled,dist3D);
+                                    mMovement = new MovementCuboids(mAxis,mCuts,mLayerRotatable,mSize,movementSplit,mEnabled,dist3D);
                                     break;
         }
       }
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyOctahedron.java b/src/main/java/org/distorted/objectlib/main/TwistyOctahedron.java
new file mode 100644
index 00000000..049e1409
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/TwistyOctahedron.java
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.objectlib.main;
+
+import java.io.InputStream;
+
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public abstract class TwistyOctahedron extends TwistyObject
+{
+  static final int[] FACE_COLORS = new int[]
+         {
+           COLOR_ORANGE, COLOR_VIOLET,
+           COLOR_WHITE , COLOR_BLUE  ,
+           COLOR_YELLOW, COLOR_RED   ,
+           COLOR_GREEN , COLOR_GREY
+         };
+
+  static final int NUM_FACES = 8;
+  static final int FOV = 60;
+  static final float RATIO = 0.68f;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public TwistyOctahedron(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
+    {
+    super(numLayers, realSize, quat, move, scale, stream);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public final int getNumFaces()
+    {
+    return NUM_FACES;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getNumFaceColors()
+    {
+    return FACE_COLORS.length;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getFOV()
+    {
+    return FOV;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float getScreenRatio()
+    {
+    return RATIO;
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/main/TwistyTetrahedron.java b/src/main/java/org/distorted/objectlib/main/TwistyTetrahedron.java
new file mode 100644
index 00000000..1f731b3b
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/main/TwistyTetrahedron.java
@@ -0,0 +1,82 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 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.objectlib.main;
+
+import java.io.InputStream;
+
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public abstract class TwistyTetrahedron extends TwistyObject
+{
+  static final int[] FACE_COLORS = new int[]
+         {
+           COLOR_GREEN , COLOR_YELLOW,
+           COLOR_BLUE  , COLOR_RED
+         };
+
+  static final int NUM_FACES = 4;
+  static final int FOV = 60;
+  static final float RATIO = 0.89f;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public TwistyTetrahedron(int[] numLayers, float realSize, Static4D quat, Static3D move, float scale, InputStream stream)
+    {
+    super(numLayers, realSize, quat, move, scale, stream);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public final int getNumFaces()
+    {
+    return NUM_FACES;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getNumFaceColors()
+    {
+    return FACE_COLORS.length;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getFOV()
+    {
+    return FOV;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float getScreenRatio()
+    {
+    return RATIO;
+    }
+}
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objectlib/objects/TwistyBandagedAbstract.java
index a62db01f..bb5c34fc 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyBandagedAbstract.java
@@ -27,16 +27,16 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-abstract class TwistyBandagedAbstract extends Twisty6
+abstract class TwistyBandagedAbstract extends TwistyHexahedron
 {
   // the three rotation axis of a 3x3 Cube. Must be normalized.
   static final Static3D[] ROT_AXIS = new Static3D[]
@@ -121,7 +121,7 @@ abstract class TwistyBandagedAbstract extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java b/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
index ad09c35b..b8639fce 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.MovementC;
+import org.distorted.objectlib.main.MovementCuboids;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyCuboid extends Twisty6
+public class TwistyCuboid extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -210,7 +210,7 @@ public class TwistyCuboid extends Twisty6
     {
     if( mQuats ==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(MovementC.FACE_AXIS[status], mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementCuboids.FACE_AXIS[status], mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyDiamond.java b/src/main/java/org/distorted/objectlib/objects/TwistyDiamond.java
index 17ef788e..f8299012 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyDiamond.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement8;
+import org.distorted.objectlib.main.MovementOctahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty8;
+import org.distorted.objectlib.main.TwistyOctahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyDiamond extends Twisty8
+public class TwistyDiamond extends TwistyOctahedron
 {
   // the four rotation axis of a Diamond. Must be normalized.
   static final Static3D[] ROT_AXIS = new Static3D[]
@@ -118,7 +118,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(Movement8.FACE_AXIS[mFaceMap[status]],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementOctahedron.FACE_AXIS[mFaceMap[status]],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyDino.java b/src/main/java/org/distorted/objectlib/objects/TwistyDino.java
index 553cf6aa..094c53f4 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyDino.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyDino.java
@@ -31,11 +31,11 @@ import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-abstract class TwistyDino extends Twisty6
+abstract class TwistyDino extends TwistyHexahedron
 {
   // the four rotation axis of a RubikDino. Must be normalized.
   static final Static3D[] ROT_AXIS = new Static3D[]
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objectlib/objects/TwistyHelicopter.java
index c1e07bbb..00bcef2b 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyHelicopter.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyHelicopter extends Twisty6
+public class TwistyHelicopter extends TwistyHexahedron
 {
   // the six rotation axis of a Helicopter. Must be normalized.
   static final Static3D[] ROT_AXIS = new Static3D[]
@@ -134,7 +134,7 @@ public class TwistyHelicopter extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyIvy.java b/src/main/java/org/distorted/objectlib/objects/TwistyIvy.java
index 9598aaf1..369b6a83 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyIvy.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyIvy extends Twisty6
+public class TwistyIvy extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -110,7 +110,7 @@ public class TwistyIvy extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyJing.java b/src/main/java/org/distorted/objectlib/objects/TwistyJing.java
index fe4b5980..acdb345a 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyJing.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyJing.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement4;
+import org.distorted.objectlib.main.MovementTetrahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty4;
+import org.distorted.objectlib.main.TwistyTetrahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyJing extends Twisty4
+public class TwistyJing extends TwistyTetrahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -111,7 +111,7 @@ public class TwistyJing extends Twisty4
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementTetrahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyKilominx.java b/src/main/java/org/distorted/objectlib/objects/TwistyKilominx.java
index 53c1a0fb..99f3102a 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyKilominx.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyKilominx.java
@@ -19,8 +19,8 @@
 
 package org.distorted.objectlib.objects;
 
-import static org.distorted.objectlib.main.Movement12.COS54;
-import static org.distorted.objectlib.main.Movement12.SIN54;
+import static org.distorted.objectlib.main.MovementDodecahedron.COS54;
+import static org.distorted.objectlib.main.MovementDodecahedron.SIN54;
 
 import java.io.InputStream;
 
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objectlib/objects/TwistyMegaminx.java
index ba5dfaa9..6b0c8b3f 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyMegaminx.java
@@ -19,8 +19,8 @@
 
 package org.distorted.objectlib.objects;
 
-import static org.distorted.objectlib.main.Movement12.COS54;
-import static org.distorted.objectlib.main.Movement12.SIN54;
+import static org.distorted.objectlib.main.MovementDodecahedron.COS54;
+import static org.distorted.objectlib.main.MovementDodecahedron.SIN54;
 
 import java.io.InputStream;
 
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyMinx.java b/src/main/java/org/distorted/objectlib/objects/TwistyMinx.java
index af311356..dc73815a 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyMinx.java
@@ -21,22 +21,22 @@ package org.distorted.objectlib.objects;
 
 import static org.distorted.objectlib.main.Movement.MOVEMENT_DODECAHEDRON;
 import static org.distorted.objectlib.main.Movement.TYPE_SPLIT_EDGE;
-import static org.distorted.objectlib.main.Movement12.C2;
-import static org.distorted.objectlib.main.Movement12.LEN;
-import static org.distorted.objectlib.main.Movement12.SIN54;
+import static org.distorted.objectlib.main.MovementDodecahedron.C2;
+import static org.distorted.objectlib.main.MovementDodecahedron.LEN;
+import static org.distorted.objectlib.main.MovementDodecahedron.SIN54;
 
 import java.io.InputStream;
 
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.main.Movement12;
+import org.distorted.objectlib.main.MovementDodecahedron;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty12;
+import org.distorted.objectlib.main.TwistyDodecahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-abstract class TwistyMinx extends Twisty12
+abstract class TwistyMinx extends TwistyDodecahedron
 {
   static final int NUM_CORNERS = 20;
   static final int NUM_CENTERS = 12;
@@ -494,7 +494,7 @@ abstract class TwistyMinx extends Twisty12
     if( mQuats==null ) initializeQuats();
     if( mFaceMap==null ) mFaceMap = new int[] {8,10,3,7,1,9,11,2,4,0,5,6};
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[mFaceMap[status]],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementDodecahedron.FACE_AXIS[mFaceMap[status]],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -512,7 +512,7 @@ abstract class TwistyMinx extends Twisty12
     if( mCuts==null )
       {
       mCuts = new float[6][numLayers-1];
-      float D = numLayers*Movement12.DIST3D;
+      float D = numLayers* MovementDodecahedron.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.
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyMirror.java b/src/main/java/org/distorted/objectlib/objects/TwistyMirror.java
index 5a305670..67f0e752 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyMirror.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyMirror.java
@@ -32,11 +32,11 @@ import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyMirror extends Twisty6
+public class TwistyMirror extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objectlib/objects/TwistyPyraminx.java
index 061fa9d3..2d729f1f 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyPyraminx.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement4;
+import org.distorted.objectlib.main.MovementTetrahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty4;
+import org.distorted.objectlib.main.TwistyTetrahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyPyraminx extends Twisty4
+public class TwistyPyraminx extends TwistyTetrahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -136,7 +136,7 @@ public class TwistyPyraminx extends Twisty4
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementTetrahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyRedi.java b/src/main/java/org/distorted/objectlib/objects/TwistyRedi.java
index 95e88953..5316d7e1 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyRedi.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyRedi extends Twisty6
+public class TwistyRedi extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -113,7 +113,7 @@ public class TwistyRedi extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyRex.java b/src/main/java/org/distorted/objectlib/objects/TwistyRex.java
index 666a5a23..dc794786 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyRex.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyRex.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyRex extends Twisty6
+public class TwistyRex extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -108,7 +108,7 @@ public class TwistyRex extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistySkewb.java b/src/main/java/org/distorted/objectlib/objects/TwistySkewb.java
index 53fe9062..07295e4c 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistySkewb.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistySkewb extends Twisty6
+public class TwistySkewb extends TwistyHexahedron
 {
   static final Static3D[] ROT_AXIS = new Static3D[]
          {
@@ -109,7 +109,7 @@ public class TwistySkewb extends Twisty6
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistySquare.java b/src/main/java/org/distorted/objectlib/objects/TwistySquare.java
index d253134c..1c7ddb38 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistySquare.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistySquare.java
@@ -26,11 +26,11 @@ import java.io.InputStream;
 
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.main.Twisty6;
+import org.distorted.objectlib.main.TwistyHexahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-abstract class TwistySquare extends Twisty6
+abstract class TwistySquare extends TwistyHexahedron
 {
   static final float COS15 = (SQ6+SQ2)/4;
   static final float SIN15 = (SQ6-SQ2)/4;
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistySquare1.java b/src/main/java/org/distorted/objectlib/objects/TwistySquare1.java
index dcd5d229..4f8d29f5 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistySquare1.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistySquare1.java
@@ -24,7 +24,7 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement6;
+import org.distorted.objectlib.main.MovementHexahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
@@ -70,7 +70,7 @@ public class TwistySquare1 extends TwistySquare
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementHexahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyUltimate.java b/src/main/java/org/distorted/objectlib/objects/TwistyUltimate.java
index 73ece3b5..33fdefd3 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyUltimate.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyUltimate.java
@@ -27,17 +27,17 @@ import java.io.InputStream;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import org.distorted.objectlib.main.Movement12;
+import org.distorted.objectlib.main.MovementDodecahedron;
 import org.distorted.objectlib.main.ObjectControl;
 import org.distorted.objectlib.main.ObjectType;
 import org.distorted.objectlib.helpers.ObjectShape;
 import org.distorted.objectlib.helpers.ObjectSticker;
 import org.distorted.objectlib.helpers.ScrambleState;
-import org.distorted.objectlib.main.Twisty12;
+import org.distorted.objectlib.main.TwistyDodecahedron;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-public class TwistyUltimate extends Twisty12
+public class TwistyUltimate extends TwistyDodecahedron
 {
   private static final float A = (float)Math.sqrt(21*SQ5+47);
   private static final float B = SQ6*(5*SQ5+11)/(6*A);
@@ -115,7 +115,7 @@ public class TwistyUltimate extends Twisty12
     {
     if( mQuats==null ) initializeQuats();
     int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[status],mQuats);
+    return status<0 ? null : buildSolvedQuats(MovementDodecahedron.FACE_AXIS[status],mQuats);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
