commit 3f7a4363de0d0d6811a7af427db00e7264c09c3b
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Sep 29 16:07:33 2021 +0200

    Remove all files that have been separated into a new library 'objectlib'

diff --git a/build.gradle b/build.gradle
index acbc5977..9fab29b5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -34,12 +34,13 @@ android {
 }
 
 dependencies {
+    api project(':distorted-library')
+    api project(':distorted-objectlib')
+
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'com.google.firebase:firebase-analytics:19.0.1'
     implementation 'com.google.firebase:firebase-crashlytics:18.2.1'
     implementation 'com.google.android.play:core:1.10.2'
-
-    api project(':distorted-library')
     implementation 'androidx.appcompat:appcompat:1.3.1'
     implementation 'com.google.android.material:material:1.4.0'
 }
diff --git a/src/main/java/org/distorted/control/RubikControl.java b/src/main/java/org/distorted/control/RubikControl.java
index 83f09cbd..57fb7b31 100644
--- a/src/main/java/org/distorted/control/RubikControl.java
+++ b/src/main/java/org/distorted/control/RubikControl.java
@@ -24,9 +24,11 @@ import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.type.Static4D;
+
+import org.distorted.objectlib.main.TwistyObject;
+
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikSurfaceView;
-import org.distorted.objectlib.TwistyObject;
 
 import java.lang.ref.WeakReference;
 
diff --git a/src/main/java/org/distorted/control/RubikControlRotate.java b/src/main/java/org/distorted/control/RubikControlRotate.java
index d825aec8..a5b723ca 100644
--- a/src/main/java/org/distorted/control/RubikControlRotate.java
+++ b/src/main/java/org/distorted/control/RubikControlRotate.java
@@ -22,7 +22,6 @@ package org.distorted.control;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 
-import org.distorted.objectlib.QuatHelper;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.main.DistortedEffects;
@@ -36,9 +35,12 @@ import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
+
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.objectlib.main.QuatHelper;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.TwistyObject;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/src/main/java/org/distorted/control/RubikControlWhole.java b/src/main/java/org/distorted/control/RubikControlWhole.java
index 05936ffc..3a21092f 100644
--- a/src/main/java/org/distorted/control/RubikControlWhole.java
+++ b/src/main/java/org/distorted/control/RubikControlWhole.java
@@ -32,6 +32,7 @@ import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Dynamic;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikSurfaceView;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogEffects.java b/src/main/java/org/distorted/dialogs/RubikDialogEffects.java
index 9d9389cc..949323f0 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogEffects.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogEffects.java
@@ -51,7 +51,7 @@ import org.distorted.main.RubikActivity;
 
 public class RubikDialogEffects extends AppCompatDialogFragment implements SeekBar.OnSeekBarChangeListener, AdapterView.OnItemSelectedListener
   {
-  private TextView[] mDurationText;
+  private final TextView[] mDurationText;
   private float mTextSize;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
index 9ace877e..938f2745 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogNewRecord.java
@@ -35,9 +35,10 @@ import android.view.Window;
 import android.widget.Button;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java b/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
index 0dceb398..d9a51af5 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPattern.java
@@ -39,9 +39,10 @@ import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.patterns.RubikPatternList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
index caebeaf3..35f081e8 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternListAdapter.java
@@ -35,8 +35,8 @@ import org.distorted.main.R;
 
 class RubikDialogPatternListAdapter extends BaseExpandableListAdapter
   {
-  private Context mContext;
-  private int mTab, mWidth;
+  private final Context mContext;
+  private final int mTab, mWidth;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java
index f469b6a5..479624ea 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternPagerAdapter.java
@@ -33,10 +33,10 @@ import org.distorted.patterns.RubikPatternList;
 
 class RubikDialogPatternPagerAdapter extends PagerAdapter
   {
-  private FragmentActivity mAct;
-  private RubikDialogPatternView[] mViews;
-  private RubikDialogPattern mDialog;
-  private int mNumTabs;
+  private final FragmentActivity mAct;
+  private final RubikDialogPatternView[] mViews;
+  private final RubikDialogPattern mDialog;
+  private final int mNumTabs;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
index 80a640c4..98aaa5e0 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPatternView.java
@@ -26,9 +26,10 @@ import android.view.View;
 import android.widget.ExpandableListView;
 import android.widget.FrameLayout;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.patterns.RubikPattern;
 import org.distorted.patterns.RubikPatternList;
 import org.distorted.screens.ScreenList;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java b/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java
index a2979478..e959f132 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogPrivacy.java
@@ -29,7 +29,6 @@ import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
-import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.TextView;
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScores.java b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
index ed0748c9..9e00c0c1 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScores.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScores.java
@@ -38,9 +38,10 @@ import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
index 2883de4b..bb65bfd4 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScoresPagerAdapter.java
@@ -30,10 +30,11 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.network.RubikScores;
 import org.distorted.network.RubikNetwork;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.screens.RubikScreenPlay;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java b/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
index c828c44b..f3a53e08 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogScoresView.java
@@ -31,9 +31,10 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 
 import static org.distorted.network.RubikNetwork.MAX_PLACES;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
index 14a1e0c6..5ab56b2f 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSetName.java
@@ -38,9 +38,10 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogSolverError.java b/src/main/java/org/distorted/dialogs/RubikDialogSolverError.java
index fcea3acd..942c11d1 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogSolverError.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogSolverError.java
@@ -32,7 +32,6 @@ import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
-import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.TextView;
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java b/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
index c4aaf24e..51f61785 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogTutorialView.java
@@ -35,10 +35,11 @@ import androidx.fragment.app.FragmentActivity;
 
 import com.google.firebase.analytics.FirebaseAnalytics;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.BuildConfig;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.tutorials.TutorialList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effects/BaseEffect.java b/src/main/java/org/distorted/effects/BaseEffect.java
index 3d37932a..27a51fa4 100644
--- a/src/main/java/org/distorted/effects/BaseEffect.java
+++ b/src/main/java/org/distorted/effects/BaseEffect.java
@@ -23,11 +23,12 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import android.content.SharedPreferences;
 
+import org.distorted.library.main.DistortedScreen;
+
 import org.distorted.effects.scramble.ScrambleEffect;
 import org.distorted.effects.objectchange.ObjectChangeEffect;
 import org.distorted.effects.solve.SolveEffect;
 import org.distorted.effects.win.WinEffect;
-import org.distorted.library.main.DistortedScreen;
 import org.distorted.main.R;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effects/EffectController.java b/src/main/java/org/distorted/effects/EffectController.java
index ec2fe22d..885119e7 100644
--- a/src/main/java/org/distorted/effects/EffectController.java
+++ b/src/main/java/org/distorted/effects/EffectController.java
@@ -19,9 +19,9 @@
 
 package org.distorted.effects;
 
-import org.distorted.helpers.MovesFinished;
 import org.distorted.library.message.EffectListener;
-import org.distorted.objectlib.TwistyObject;
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.helpers.MovesFinished;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
index 67378ec1..fb6e816b 100644
--- a/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
+++ b/src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
@@ -19,15 +19,17 @@
 
 package org.distorted.effects.objectchange;
 
-import org.distorted.effects.BaseEffect;
+import java.lang.reflect.Method;
+
 import org.distorted.library.effect.Effect;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
-import org.distorted.effects.EffectController;
-import org.distorted.objectlib.TwistyObject;
 
-import java.lang.reflect.Method;
+import org.distorted.objectlib.main.TwistyObject;
+
+import org.distorted.effects.BaseEffect;
+import org.distorted.effects.EffectController;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java b/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
index 2b52cc6b..7de0c200 100644
--- a/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
+++ b/src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
@@ -19,18 +19,20 @@
 
 package org.distorted.effects.scramble;
 
-import org.distorted.effects.BaseEffect;
-import org.distorted.helpers.MovesFinished;
+import java.lang.reflect.Method;
+import java.util.Random;
+
 import org.distorted.library.effect.Effect;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
-import org.distorted.effects.EffectController;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.TwistyObject;
 
-import java.lang.reflect.Method;
-import java.util.Random;
+import org.distorted.objectlib.main.ObjectList;
+import org.distorted.objectlib.main.TwistyObject;
+
+import org.distorted.effects.BaseEffect;
+import org.distorted.effects.EffectController;
+import org.distorted.helpers.MovesFinished;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/effects/scramble/ScrambleEffectRotations.java b/src/main/java/org/distorted/effects/scramble/ScrambleEffectRotations.java
index 1370c10b..9bfb2863 100644
--- a/src/main/java/org/distorted/effects/scramble/ScrambleEffectRotations.java
+++ b/src/main/java/org/distorted/effects/scramble/ScrambleEffectRotations.java
@@ -19,6 +19,8 @@
 
 package org.distorted.effects.scramble;
 
+import java.util.Random;
+
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
@@ -28,8 +30,6 @@ import org.distorted.library.type.DynamicQuat;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
-import java.util.Random;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class ScrambleEffectRotations extends ScrambleEffect
diff --git a/src/main/java/org/distorted/effects/solve/SolveEffect.java b/src/main/java/org/distorted/effects/solve/SolveEffect.java
index eed228d8..b7a9f7dd 100644
--- a/src/main/java/org/distorted/effects/solve/SolveEffect.java
+++ b/src/main/java/org/distorted/effects/solve/SolveEffect.java
@@ -19,15 +19,17 @@
 
 package org.distorted.effects.solve;
 
-import org.distorted.effects.BaseEffect;
+import java.lang.reflect.Method;
+
 import org.distorted.library.effect.Effect;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
-import org.distorted.effects.EffectController;
-import org.distorted.objectlib.TwistyObject;
 
-import java.lang.reflect.Method;
+import org.distorted.objectlib.main.TwistyObject;
+
+import org.distorted.effects.BaseEffect;
+import org.distorted.effects.EffectController;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/effects/win/WinEffect.java b/src/main/java/org/distorted/effects/win/WinEffect.java
index 6752d90a..ce1f4905 100644
--- a/src/main/java/org/distorted/effects/win/WinEffect.java
+++ b/src/main/java/org/distorted/effects/win/WinEffect.java
@@ -19,15 +19,17 @@
 
 package org.distorted.effects.win;
 
-import org.distorted.effects.BaseEffect;
+import java.lang.reflect.Method;
+
 import org.distorted.library.effect.Effect;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
-import org.distorted.effects.EffectController;
-import org.distorted.objectlib.TwistyObject;
 
-import java.lang.reflect.Method;
+import org.distorted.objectlib.main.TwistyObject;
+
+import org.distorted.effects.BaseEffect;
+import org.distorted.effects.EffectController;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/helpers/BlockController.java b/src/main/java/org/distorted/helpers/BlockController.java
index 53e01049..a36e54be 100644
--- a/src/main/java/org/distorted/helpers/BlockController.java
+++ b/src/main/java/org/distorted/helpers/BlockController.java
@@ -21,13 +21,13 @@ package org.distorted.helpers;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
-import org.distorted.library.message.EffectMessageSender;
-import org.distorted.main.BuildConfig;
-
 import java.lang.ref.WeakReference;
 import java.util.Timer;
 import java.util.TimerTask;
 
+import org.distorted.library.message.EffectMessageSender;
+import org.distorted.main.BuildConfig;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class BlockController
diff --git a/src/main/java/org/distorted/helpers/MovesAndLockController.java b/src/main/java/org/distorted/helpers/MovesAndLockController.java
index a5fda393..9264b03e 100644
--- a/src/main/java/org/distorted/helpers/MovesAndLockController.java
+++ b/src/main/java/org/distorted/helpers/MovesAndLockController.java
@@ -19,6 +19,10 @@
 
 package org.distorted.helpers;
 
+import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
+
 import android.view.View;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
@@ -26,10 +30,6 @@ import android.widget.LinearLayout;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 
-import java.util.ArrayList;
-import java.util.Timer;
-import java.util.TimerTask;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class MovesAndLockController implements MovesFinished
diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index e735bc65..471a0304 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -21,7 +21,6 @@ package org.distorted.main;
 
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.LocaleList;
@@ -36,44 +35,21 @@ import android.widget.LinearLayout;
 
 import com.google.firebase.analytics.FirebaseAnalytics;
 
+import org.distorted.library.main.DistortedLibrary;
+import org.distorted.library.main.DistortedScreen;
+import org.distorted.library.type.Static4D;
+
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.dialogs.RubikDialogError;
 import org.distorted.dialogs.RubikDialogPrivacy;
 import org.distorted.effects.BaseEffect;
 import org.distorted.helpers.BlockController;
 import org.distorted.helpers.TwistyActivity;
 import org.distorted.helpers.TwistyPreRender;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedLibrary;
-
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.TwistyObject;
 import org.distorted.network.RubikScores;
 import org.distorted.network.RubikNetwork;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objects.TwistyBandaged2Bar;
-import org.distorted.objects.TwistyBandaged3Plate;
-import org.distorted.objects.TwistyBandagedEvil;
-import org.distorted.objects.TwistyBandagedFused;
-import org.distorted.objects.TwistyCube;
-import org.distorted.objects.TwistyDiamond;
-import org.distorted.objects.TwistyDino4;
-import org.distorted.objects.TwistyDino6;
-import org.distorted.objects.TwistyHelicopter;
-import org.distorted.objects.TwistyIvy;
-import org.distorted.objects.TwistyJing;
-import org.distorted.objects.TwistyKilominx;
-import org.distorted.objects.TwistyMegaminx;
-import org.distorted.objects.TwistyMirror;
-import org.distorted.objects.TwistyPyraminx;
-import org.distorted.objects.TwistyRedi;
-import org.distorted.objects.TwistyRex;
-import org.distorted.objects.TwistySkewb;
-import org.distorted.objects.TwistySquare1;
-import org.distorted.objects.TwistySquare2;
-import org.distorted.objects.TwistyUltimate;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.tutorials.TutorialActivity;
@@ -674,40 +650,4 @@ public class RubikActivity extends TwistyActivity
       myIntent.putExtra("siz", size);
       startActivity(myIntent);
       }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static TwistyObject create(ObjectList object, int size, Static4D quat, int[][] moves, Resources res, int scrWidth)
-    {
-    DistortedTexture texture = new DistortedTexture();
-    DistortedEffects effects = new DistortedEffects();
-    MeshSquare mesh          = new MeshSquare(20,20);   // mesh of the node, not of the cubits
-
-    switch(object.ordinal())
-      {
-      case  0: return new TwistyCube           (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  1: return new TwistyJing           (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  2: return new TwistyPyraminx       (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  3: return new TwistyKilominx       (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  4: return new TwistyMegaminx       (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  5: return new TwistyUltimate       (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  6: return new TwistyDiamond        (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  7: return new TwistyDino6          (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  8: return new TwistyDino4          (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case  9: return new TwistyRedi           (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 10: return new TwistyHelicopter     (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 11: return new TwistySkewb          (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 12: return new TwistyIvy            (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 13: return new TwistyRex            (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 14: return new TwistyBandagedFused  (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 15: return new TwistyBandaged2Bar   (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 16: return new TwistyBandaged3Plate (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 17: return new TwistyBandagedEvil   (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 18: return new TwistySquare1        (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 19: return new TwistySquare2        (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      case 20: return new TwistyMirror         (size, quat, texture, mesh, effects, moves, res, scrWidth);
-      }
-
-    return null;
-    }
 }
diff --git a/src/main/java/org/distorted/main/RubikPreRender.java b/src/main/java/org/distorted/main/RubikPreRender.java
index df6c4100..b35fda65 100644
--- a/src/main/java/org/distorted/main/RubikPreRender.java
+++ b/src/main/java/org/distorted/main/RubikPreRender.java
@@ -34,6 +34,9 @@ import com.google.android.play.core.tasks.OnFailureListener;
 import com.google.android.play.core.tasks.Task;
 import com.google.firebase.analytics.FirebaseAnalytics;
 
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.dialogs.RubikDialogNewRecord;
 import org.distorted.dialogs.RubikDialogSolved;
 import org.distorted.effects.BaseEffect;
@@ -42,8 +45,6 @@ import org.distorted.effects.scramble.ScrambleEffect;
 import org.distorted.helpers.BlockController;
 import org.distorted.helpers.MovesFinished;
 import org.distorted.helpers.TwistyPreRender;
-import org.distorted.objectlib.TwistyObject;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.ScreenList;
@@ -124,7 +125,7 @@ public class RubikPreRender implements EffectController, TwistyPreRender
     Context con = mView.getContext();
     Resources res = con.getResources();
 
-    mNewObject = RubikActivity.create(object,size, mView.getQuat(), moves, res, mScreenWidth);
+    mNewObject = object.create(size, mView.getQuat(), moves, res, mScreenWidth);
 
     if( mNewObject!=null )
       {
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index adf843ea..ce68f80a 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -30,17 +30,19 @@ import android.view.MotionEvent;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
-import org.distorted.objectlib.QuatHelper;
 import org.distorted.library.type.Static2D;
 import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.TwistyObject;
-import org.distorted.objectlib.Movement;
+
+import org.distorted.objectlib.main.QuatHelper;
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.objectlib.main.Movement;
+
 import org.distorted.screens.RubikScreenReady;
-import org.distorted.solvers.SolverMain;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.RubikScreenSolver;
 import org.distorted.screens.RubikScreenSolving;
+import org.distorted.solvers.SolverMain;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/network/RubikNetwork.java b/src/main/java/org/distorted/network/RubikNetwork.java
index e1207644..ec092b03 100644
--- a/src/main/java/org/distorted/network/RubikNetwork.java
+++ b/src/main/java/org/distorted/network/RubikNetwork.java
@@ -19,6 +19,13 @@
 
 package org.distorted.network;
 
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
 import android.app.Activity;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -27,16 +34,9 @@ import androidx.appcompat.app.AppCompatActivity;
 import androidx.fragment.app.FragmentActivity;
 
 import org.distorted.library.main.DistortedLibrary;
-import org.distorted.objectlib.ObjectList;
-
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.distorted.objectlib.main.ObjectList;
 
-import static org.distorted.objectlib.ObjectList.MAX_LEVEL;
+import static org.distorted.objectlib.main.ObjectList.MAX_LEVEL;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/network/RubikScores.java b/src/main/java/org/distorted/network/RubikScores.java
index 3f298859..0b07ef66 100644
--- a/src/main/java/org/distorted/network/RubikScores.java
+++ b/src/main/java/org/distorted/network/RubikScores.java
@@ -19,20 +19,21 @@
 
 package org.distorted.network;
 
+import java.util.UUID;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.telephony.TelephonyManager;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
-import org.distorted.main.BuildConfig;
-import org.distorted.objectlib.ObjectList;
+import static org.distorted.objectlib.main.ObjectList.MAX_NUM_OBJECTS;
+import static org.distorted.objectlib.main.ObjectList.NUM_OBJECTS;
+import static org.distorted.objectlib.main.ObjectList.MAX_LEVEL;
 
-import java.util.UUID;
+import org.distorted.objectlib.main.ObjectList;
 
-import static org.distorted.objectlib.ObjectList.MAX_NUM_OBJECTS;
-import static org.distorted.objectlib.ObjectList.NUM_OBJECTS;
-import static org.distorted.objectlib.ObjectList.MAX_LEVEL;
+import org.distorted.main.BuildConfig;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // hold my own scores, and some other statistics.
diff --git a/src/main/java/org/distorted/objectlib/Cubit.java b/src/main/java/org/distorted/objectlib/Cubit.java
deleted file mode 100644
index 21393a9c..00000000
--- a/src/main/java/org/distorted/objectlib/Cubit.java
+++ /dev/null
@@ -1,227 +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;
-
-import android.content.SharedPreferences;
-
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class Cubit
-  {
-  private final float[] mOrigPosition;
-  private final float[] mCurrentPosition;
-  private final int mNumAxis;
-  private final int mLen;
-  private final int[] mRotationRow;
-  private TwistyObject mParent;
-
-  int mQuatIndex;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Cubit(TwistyObject parent, float[] position, int numAxis)
-    {
-    mQuatIndex= 0;
-    mParent   = parent;
-    mLen      = position.length;
-
-    mOrigPosition    = new float[mLen];
-    mCurrentPosition = new float[mLen];
-
-    for(int i=0; i<mLen; i++)
-      {
-      mOrigPosition[i]    = position[i];
-      mCurrentPosition[i] = position[i];
-      }
-
-    mNumAxis     = numAxis;
-    mRotationRow = new int[mNumAxis];
-    computeRotationRow();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Because of quatMultiplication, errors can accumulate - so to avoid this, we
-// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
-// list QUATS.
-//
-// We also have to remember that the group of unit quaternions is a double-cover of rotations
-// in 3D ( q represents the same rotation as -q ) - so invert if needed.
-
-  private int normalizeScrambleQuat(Static4D quat)
-    {
-    float x = quat.get0();
-    float y = quat.get1();
-    float z = quat.get2();
-    float w = quat.get3();
-    float xd,yd,zd,wd;
-    float diff, mindiff = Float.MAX_VALUE;
-    int ret=0;
-    int num_quats = mParent.OBJECT_QUATS.length;
-    Static4D qt;
-
-    for(int q=0; q<num_quats; q++)
-      {
-      qt = mParent.OBJECT_QUATS[q];
-
-      xd = x - qt.get0();
-      yd = y - qt.get1();
-      zd = z - qt.get2();
-      wd = w - qt.get3();
-
-      diff = xd*xd + yd*yd + zd*zd + wd*wd;
-
-      if( diff < mindiff )
-        {
-        ret = q;
-        mindiff = diff;
-        }
-
-      xd = x + qt.get0();
-      yd = y + qt.get1();
-      zd = z + qt.get2();
-      wd = w + qt.get3();
-
-      diff = xd*xd + yd*yd + zd*zd + wd*wd;
-
-      if( diff < mindiff )
-        {
-        ret = q;
-        mindiff = diff;
-        }
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computeRotationRow()
-    {
-    for(int i=0; i<mNumAxis; i++)
-      {
-      mRotationRow[i] = mParent.computeRow(mCurrentPosition,i);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void modifyCurrentPosition(Static4D quat)
-    {
-    Static4D cubitCenter;
-    Static4D rotatedCenter;
-    int len = mLen/3;
-
-    for(int i=0; i<len; i++)
-      {
-      cubitCenter =  new Static4D(mCurrentPosition[3*i], mCurrentPosition[3*i+1], mCurrentPosition[3*i+2], 0);
-      rotatedCenter = QuatHelper.rotateVectorByQuat( cubitCenter, quat);
-
-      mCurrentPosition[3*i  ] = rotatedCenter.get0();
-      mCurrentPosition[3*i+1] = rotatedCenter.get1();
-      mCurrentPosition[3*i+2] = rotatedCenter.get2();
-
-      mParent.clampPos(mCurrentPosition, 3*i);
-      }
-
-    computeRotationRow();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int computeAssociation()
-    {
-    int result = 0, accumulativeShift = 0;
-
-    for(int axis=0; axis<mNumAxis; axis++)
-      {
-      result += (mRotationRow[axis]<<accumulativeShift);
-      accumulativeShift += ObjectList.MAX_OBJECT_SIZE;
-      }
-
-    return result;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void savePreferences(SharedPreferences.Editor editor)
-    {
-    String number = mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
-    editor.putInt("q_"+number, mQuatIndex);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int restorePreferences(SharedPreferences preferences)
-    {
-    String number = mOrigPosition[0]+"_"+mOrigPosition[1]+"_"+mOrigPosition[2];
-    mQuatIndex = preferences.getInt("q_"+number, 0);
-    return mQuatIndex;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int removeRotationNow(Static4D quat)
-    {
-    Static4D q = QuatHelper.quatMultiply(quat,mParent.OBJECT_QUATS[mQuatIndex]);
-    mQuatIndex = normalizeScrambleQuat(q);
-
-    modifyCurrentPosition(quat);
-
-    return mQuatIndex;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void solve()
-    {
-    mQuatIndex = 0;
-    System.arraycopy(mOrigPosition, 0, mCurrentPosition, 0, mCurrentPosition.length);
-    computeRotationRow();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void releaseResources()
-    {
-    mParent = null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// this is only needed for MODE_REPLACE objects (i.e. - currently - CUBE_3), so it is enough to only
-// take into consideration the first position.
-
-  float getDistSquared(float[] point)
-    {
-    float dx = mCurrentPosition[0] - point[0];
-    float dy = mCurrentPosition[1] - point[1];
-    float dz = mCurrentPosition[2] - point[2];
-
-    return dx*dx + dy*dy + dz*dz;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getRotRow(int index)
-    {
-    return mRotationRow[index];
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/distorted/objectlib/FactoryCubit.java b/src/main/java/org/distorted/objectlib/FactoryCubit.java
deleted file mode 100644
index bafd998c..00000000
--- a/src/main/java/org/distorted/objectlib/FactoryCubit.java
+++ /dev/null
@@ -1,940 +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;
-
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectQuaternion;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.effect.VertexEffect;
-import org.distorted.library.effect.VertexEffectDeform;
-import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.mesh.MeshJoined;
-import org.distorted.library.mesh.MeshPolygon;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-import java.util.ArrayList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class FactoryCubit
-  {
-  private static final Static1D RADIUS = new Static1D(1);
-  private static FactoryCubit mThis;
-
-  private static final double[] mBuffer = new double[3];
-  private static final double[] mQuat1  = new double[4];
-  private static final double[] mQuat2  = new double[4];
-  private static final double[] mQuat3  = new double[4];
-  private static final double[] mQuat4  = new double[4];
-
-  private static class StickerCoords
-    {
-    double[] vertices;
-    }
-
-  private static class FaceTransform
-    {
-    int sticker;
-    double vx,vy,vz;
-    double scale;
-    double qx,qy,qz,qw;
-    boolean flip;
-    }
-
-  private static final ArrayList<FaceTransform> mNewFaceTransf = new ArrayList<>();
-  private static final ArrayList<FaceTransform> mOldFaceTransf = new ArrayList<>();
-  private static final ArrayList<StickerCoords> mStickerCoords = new ArrayList<>();
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private FactoryCubit()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static FactoryCubit getInstance()
-    {
-    if( mThis==null ) mThis = new FactoryCubit();
-
-    return mThis;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// H - height of the band in the middle
-// alpha - angle of the edge  [0,90]
-// dist - often in a polygon the distance from edge to center is not 1, but something else.
-// This is the distance.
-// K - where to begin the second, much more flat part of the band. [0,1]
-// N - number of bands. N>=3
-//
-// theory: two distinct parts to the band:
-// 1) (0,B) - steep
-// 2) (B,1) - flat
-//
-// In first part, we have y = g(x) ; in second - y = g(f(x)) where
-//
-// g(x) = sqrt( R^2 - (x-D)^2 ) - R*cos(alpha)
-// f(x) = ((D-B)/(1-B)*x + B*(1-D)/(1-B)
-// h(x) = R*(sin(alpha) - sin(x))
-// R = H/(1-cos(alpha))
-// D = H*sin(alpha)
-// B = h(K*alpha)
-//
-// The N points are taken at:
-//
-// 1) in the second part, there are K2 = (N-3)/3 such points
-// 2) in the first - K1 = (N-3) - K2
-// 3) also, the 3 points 0,B,1
-//
-// so we have the sequence A[i] of N points
-//
-// 0
-// h((i+1)*(1-K)*alpha/(K1+1)) (i=0,1,...,K1-1)
-// B
-// (1-B)*(i+1)/(K2+1) + B   (i=0,i,...,K2-1)
-// 1
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float f(float D, float B, float x)
-    {
-    return ((D-B)*x + B*(1-D))/(1-B);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float g(float R, float D, float x, float cosAlpha)
-    {
-    float d = x-D;
-    return (float)(Math.sqrt(R*R-d*d)-R*cosAlpha);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float h(float R, float sinAlpha, float x)
-    {
-    return R*(sinAlpha-(float)Math.sin(x));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean areColinear(double[][] vertices, int index1, int index2, int index3)
-    {
-    double x1 = vertices[index1][0];
-    double y1 = vertices[index1][1];
-    double z1 = vertices[index1][2];
-    double x2 = vertices[index2][0];
-    double y2 = vertices[index2][1];
-    double z2 = vertices[index2][2];
-    double x3 = vertices[index3][0];
-    double y3 = vertices[index3][1];
-    double z3 = vertices[index3][2];
-
-    double v1x = x2-x1;
-    double v1y = y2-y1;
-    double v1z = z2-z1;
-    double v2x = x3-x1;
-    double v2y = y3-y1;
-    double v2z = z3-z1;
-
-    double A = Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) );
-
-    return (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computeNormalVector(double[][] vertices, int index1, int index2, int index3)
-    {
-    double x1 = vertices[index1][0];
-    double y1 = vertices[index1][1];
-    double z1 = vertices[index1][2];
-    double x2 = vertices[index2][0];
-    double y2 = vertices[index2][1];
-    double z2 = vertices[index2][2];
-    double x3 = vertices[index3][0];
-    double y3 = vertices[index3][1];
-    double z3 = vertices[index3][2];
-
-    double v1x = x2-x1;
-    double v1y = y2-y1;
-    double v1z = z2-z1;
-    double v2x = x3-x1;
-    double v2y = y3-y1;
-    double v2z = z3-z1;
-
-    mBuffer[0] = v1y*v2z - v2y*v1z;
-    mBuffer[1] = v1z*v2x - v2z*v1x;
-    mBuffer[2] = v1x*v2y - v2x*v1y;
-
-    double len = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
-    len = Math.sqrt(len);
-    mBuffer[0] /= len;
-    mBuffer[1] /= len;
-    mBuffer[2] /= len;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return quat1*quat2
-
-  private static void quatMultiply( double[] quat1, double[] quat2, double[] result )
-    {
-    double qx = quat1[0];
-    double qy = quat1[1];
-    double qz = quat1[2];
-    double qw = quat1[3];
-
-    double rx = quat2[0];
-    double ry = quat2[1];
-    double rz = quat2[2];
-    double rw = quat2[3];
-
-    result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
-    result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
-    result[2] = rw*qz + rz*qw - ry*qx + rx*qy;
-    result[3] = rw*qw - rz*qz - ry*qy - rx*qx;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void fitInSquare(FaceTransform info, double[][] vert3D)
-    {
-    double minX = Double.MAX_VALUE;
-    double maxX =-Double.MAX_VALUE;
-    double minY = Double.MAX_VALUE;
-    double maxY =-Double.MAX_VALUE;
-
-    for (double[] vert : vert3D)
-      {
-      double x = vert[0];
-      double y = vert[1];
-
-      if (x > maxX) maxX = x;
-      if (x < minX) minX = x;
-      if (y > maxY) maxY = y;
-      if (y < minY) minY = y;
-      }
-
-    minX = minX<0 ? -minX:minX;
-    maxX = maxX<0 ? -maxX:maxX;
-    minY = minY<0 ? -minY:minY;
-    maxY = maxY<0 ? -maxY:maxY;
-
-    double max1 = Math.max(minX,minY);
-    double max2 = Math.max(maxX,maxY);
-    double max3 = Math.max(max1,max2);
-
-    info.scale = max3/0.5;
-
-    int len = vert3D.length;
-    StickerCoords sInfo = new StickerCoords();
-    sInfo.vertices = new double[2*len];
-
-    for( int vertex=0; vertex<len; vertex++ )
-      {
-      sInfo.vertices[2*vertex  ] = vert3D[vertex][0] / info.scale;
-      sInfo.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
-      }
-
-    mStickerCoords.add(sInfo);
-
-    info.sticker = mStickerCoords.size() -1;
-    info.flip = false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private FaceTransform constructNewTransform(final double[][] vert3D)
-    {
-    FaceTransform ft = new FaceTransform();
-
-    // compute center of gravity
-    ft.vx = 0.0f;
-    ft.vy = 0.0f;
-    ft.vz = 0.0f;
-    int len = vert3D.length;
-
-    for (double[] vert : vert3D)
-      {
-      ft.vx += vert[0];
-      ft.vy += vert[1];
-      ft.vz += vert[2];
-      }
-
-    ft.vx /= len;
-    ft.vy /= len;
-    ft.vz /= len;
-
-    // move all vertices so that their center of gravity is at (0,0,0)
-    for (int i=0; i<len; i++)
-      {
-      vert3D[i][0] -= ft.vx;
-      vert3D[i][1] -= ft.vy;
-      vert3D[i][2] -= ft.vz;
-      }
-
-    // find 3 non-colinear vertices
-    int foundIndex = -1;
-
-    for(int vertex=2; vertex<len; vertex++)
-      {
-      if( !areColinear(vert3D,0,1,vertex) )
-        {
-        foundIndex = vertex;
-        break;
-        }
-      }
-
-    // compute the normal vector
-    if( foundIndex==-1 )
-      {
-      throw new RuntimeException("all vertices colinear");
-      }
-
-    computeNormalVector(vert3D,0,1,foundIndex);
-
-    // rotate so that the normal vector becomes (0,0,1)
-    double axisX, axisY, axisZ;
-
-    if( mBuffer[0]!=0.0f || mBuffer[1]!=0.0f )
-      {
-      axisX = -mBuffer[1];
-      axisY =  mBuffer[0];
-      axisZ = 0.0f;
-
-      double axiLen = axisX*axisX + axisY*axisY;
-      axiLen = Math.sqrt(axiLen);
-      axisX /= axiLen;
-      axisY /= axiLen;
-      axisZ /= axiLen;
-      }
-    else
-      {
-      axisX = 0.0f;
-      axisY = 1.0f;
-      axisZ = 0.0f;
-      }
-
-    double cosTheta = mBuffer[2];
-    double sinTheta = Math.sqrt(1-cosTheta*cosTheta);
-    double sinHalfTheta = computeSinHalf(cosTheta);
-    double cosHalfTheta = computeCosHalf(sinTheta,cosTheta);
-
-    mQuat1[0] = axisX*sinHalfTheta;
-    mQuat1[1] = axisY*sinHalfTheta;
-    mQuat1[2] = axisZ*sinHalfTheta;
-    mQuat1[3] = cosHalfTheta;
-    mQuat2[0] =-axisX*sinHalfTheta;
-    mQuat2[1] =-axisY*sinHalfTheta;
-    mQuat2[2] =-axisZ*sinHalfTheta;
-    mQuat2[3] = cosHalfTheta;
-
-    for (double[] vert : vert3D)
-      {
-      quatMultiply(mQuat1, vert  , mQuat3);
-      quatMultiply(mQuat3, mQuat2, vert  );
-      }
-
-    // fit the whole thing in a square and remember the scale & 2D vertices
-    fitInSquare(ft, vert3D);
-
-    // remember the rotation
-    ft.qx =-mQuat1[0];
-    ft.qy =-mQuat1[1];
-    ft.qz =-mQuat1[2];
-    ft.qw = mQuat1[3];
-
-    return ft;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void rotateAllVertices(double[] result, int len, double[] vertices, double sin, double cos)
-    {
-    for(int i=0; i<len; i++)
-      {
-      result[2*i  ] = vertices[2*i  ]*cos - vertices[2*i+1]*sin;
-      result[2*i+1] = vertices[2*i  ]*sin + vertices[2*i+1]*cos;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private double computeScale(double[] v1, double[] v2, int v1i, int v2i)
-    {
-    double v1x = v1[2*v1i];
-    double v1y = v1[2*v1i+1];
-    double v2x = v2[2*v2i];
-    double v2y = v2[2*v2i+1];
-
-    double lenSq1 = v1x*v1x + v1y*v1y;
-    double lenSq2 = v2x*v2x + v2y*v2y;
-
-    return Math.sqrt(lenSq2/lenSq1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// valid for 0<angle<2*PI
-
-  private double computeSinHalf(double cos)
-    {
-    return Math.sqrt((1-cos)/2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// valid for 0<angle<2*PI
-
-  private double computeCosHalf(double sin, double cos)
-    {
-    double cosHalf = Math.sqrt((1+cos)/2);
-    return sin<0 ? -cosHalf : cosHalf;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeRotatedIndex(int oldVertex, int len, int rotatedVertex, boolean inverted)
-    {
-    int v = (rotatedVertex + (inverted? -oldVertex : oldVertex));
-    if( v>=len ) v-=len;
-    if( v< 0   ) v+=len;
-
-    return v;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isScaledVersionOf(double[] newVert, double[] oldVert, int len, int vertex, boolean inverted)
-    {
-    int newZeroIndex = computeRotatedIndex(0,len,vertex,inverted);
-    double EPSILON = 0.001;
-    double scale = computeScale(newVert,oldVert,newZeroIndex,0);
-
-    for(int i=1; i<len; i++)
-      {
-      int index = computeRotatedIndex(i,len,vertex,inverted);
-
-      double horz = oldVert[2*i  ] - scale*newVert[2*index  ];
-      double vert = oldVert[2*i+1] - scale*newVert[2*index+1];
-
-      if( horz>EPSILON || horz<-EPSILON || vert>EPSILON || vert<-EPSILON ) return false;
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void mirrorAllVertices(double[] output, int len, double[] input)
-    {
-    for(int vertex=0; vertex<len; vertex++)
-      {
-      output[2*vertex  ] = input[2*vertex  ];
-      output[2*vertex+1] =-input[2*vertex+1];
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void correctInfo(FaceTransform info, double scale, double sin, double cos, int oldSticker, boolean flip)
-    {
-    mStickerCoords.remove(info.sticker);
-
-    info.flip    = flip;
-    info.sticker = oldSticker;
-    info.scale  *= scale;
-
-    mQuat1[0] = info.qx;
-    mQuat1[1] = info.qy;
-    mQuat1[2] = info.qz;
-    mQuat1[3] = info.qw;
-
-    double sinHalf = computeSinHalf(cos);
-    double cosHalf = computeCosHalf(sin,cos);
-
-    if( flip )
-      {
-      mQuat3[0] = 0.0f;
-      mQuat3[1] = 0.0f;
-      mQuat3[2] = sinHalf;
-      mQuat3[3] = cosHalf;
-
-      mQuat4[0] = 1.0;
-      mQuat4[1] = 0.0;
-      mQuat4[2] = 0.0;
-      mQuat4[3] = 0.0;
-
-      quatMultiply( mQuat3, mQuat4, mQuat2 );
-      }
-    else
-      {
-      mQuat2[0] = 0.0f;
-      mQuat2[1] = 0.0f;
-      mQuat2[2] = sinHalf;
-      mQuat2[3] = cosHalf;
-      }
-
-    quatMultiply( mQuat1, mQuat2, mQuat3 );
-
-    info.qx = mQuat3[0];
-    info.qy = mQuat3[1];
-    info.qz = mQuat3[2];
-    info.qw = mQuat3[3];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void printVert(double[] buffer)
-    {
-    int len = buffer.length/2;
-    String str = "";
-
-    for(int i=0; i<len; i++)
-      {
-      str += (" ("+buffer[2*i]+" , "+buffer[2*i+1]+" ) ");
-      }
-
-    android.util.Log.d("D", str);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean foundVertex(FaceTransform info, double[] buffer, int len, double[] newVert,
-                              double[] oldVert, double lenFirstOld, int oldSticker, boolean inverted)
-    {
-    for(int vertex=0; vertex<len; vertex++)
-      {
-      double newX = newVert[2*vertex  ];
-      double newY = newVert[2*vertex+1];
-      double lenIthNew = Math.sqrt(newX*newX + newY*newY);
-      double cos = QuatHelper.computeCos( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
-      double sin = QuatHelper.computeSin( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
-
-      rotateAllVertices(buffer,len,newVert,sin,cos);
-
-      if( isScaledVersionOf(buffer,oldVert,len,vertex,inverted) )
-        {
-        int newZeroIndex = computeRotatedIndex(0,len,vertex,inverted);
-        double scale = computeScale(oldVert,newVert,0,newZeroIndex);
-        correctInfo(info,scale,sin,cos,oldSticker,inverted);
-        return true;
-        }
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean successfullyCollapsedStickers(final FaceTransform newInfo, final FaceTransform oldInfo)
-    {
-    StickerCoords sNewInfo = mStickerCoords.get(newInfo.sticker);
-    StickerCoords sOldInfo = mStickerCoords.get(oldInfo.sticker);
-    double[] newVert = sNewInfo.vertices;
-    double[] oldVert = sOldInfo.vertices;
-    int oldLen = oldVert.length;
-    int newLen = newVert.length;
-
-    if( oldLen == newLen )
-      {
-      int oldSticker = oldInfo.sticker;
-      double[] buffer1 = new double[oldLen];
-      double lenFirstOld = Math.sqrt(oldVert[0]*oldVert[0] + oldVert[1]*oldVert[1]);
-      if( foundVertex(newInfo, buffer1, oldLen/2, newVert, oldVert, lenFirstOld, oldSticker, false) ) return true;
-      double[] buffer2 = new double[oldLen];
-      mirrorAllVertices(buffer2, newLen/2, newVert);
-      if( foundVertex(newInfo, buffer1, oldLen/2, buffer2, oldVert, lenFirstOld, oldSticker, true ) ) return true;
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private double[][] constructVert(double[][] vertices, int[] index)
-    {
-    int len = index.length;
-    double[][] ret = new double[len][4];
-
-    for(int i=0; i<len; i++)
-      {
-      ret[i][0] = vertices[index[i]][0];
-      ret[i][1] = vertices[index[i]][1];
-      ret[i][2] = vertices[index[i]][2];
-      ret[i][3] = 1.0f;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void prepareAndRoundCorners(MeshBase mesh, double[][] vertices,
-                                      float[][] corners, int[] cornerIndexes,
-                                      float[][] centers, int[] centerIndexes )
-    {
-    int lenV = vertices.length;
-    Static3D[] staticVert = new Static3D[1];
-    Static3D center = new Static3D(0,0,0);
-
-    for(int v=0; v<lenV; v++)
-      {
-      staticVert[0] = new Static3D( (float)vertices[v][0], (float)vertices[v][1], (float)vertices[v][2]);
-
-      int cent = centerIndexes[v];
-
-      if( cent>=0 )
-        {
-        center.set( centers[cent][0], centers[cent][1], centers[cent][2]);
-
-        int corn = cornerIndexes[v];
-
-        if( corn>=0 )
-          {
-          float strength = corners[corn][0];
-          float radius   = corners[corn][1];
-          roundCorners(mesh, center, staticVert, strength, radius);
-          }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void correctComponents(MeshBase mesh, int numComponents)
-    {
-    int numTexToBeAdded = numComponents-mesh.getNumTexComponents();
-
-    mesh.mergeEffComponents();
-
-    for(int i=0; i<numTexToBeAdded; i++ ) mesh.addEmptyTexComponent();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void printTransform(FaceTransform f)
-    {
-    android.util.Log.e("D", "q=("+f.qx+", "+f.qy+", "+f.qz+", "+f.qw+") v=("
-                       +f.vx+", "+f.vy+", "+f.vz+") scale="+f.scale+" sticker="+f.sticker);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC
-
-  public float[] computeBands(float H, int alpha, float dist, float K, int N)
-    {
-    float[] bands = new float[2*N];
-
-    bands[0] = 1.0f;
-    bands[1] = 0.0f;
-
-    float beta = (float)Math.atan(dist*Math.tan(Math.PI*alpha/180));
-    float sinBeta = (float)Math.sin(beta);
-    float cosBeta = (float)Math.cos(beta);
-    float R = cosBeta<1.0f ? H/(1.0f-cosBeta) : 0.0f;
-    float D = R*sinBeta;
-    float B = h(R,sinBeta,K*beta);
-
-    if( D>1.0f )
-      {
-      for(int i=1; i<N; i++)
-        {
-        bands[2*i  ] = (float)(N-1-i)/(N-1);
-        bands[2*i+1] = H*(1-bands[2*i]);
-        }
-      }
-    else
-      {
-      int K2 = (int)((N-3)*K);
-      int K1 = (N-3)-K2;
-
-      for(int i=0; i<=K1; i++)
-        {
-        float angle = K*beta + (1-K)*beta*(K1-i)/(K1+1);
-        float x = h(R,sinBeta,angle);
-        bands[2*i+2] = 1.0f - x;
-        bands[2*i+3] = g(R,D,x,cosBeta);
-        }
-
-      for(int i=0; i<=K2; i++)
-        {
-        float x = (1-B)*(i+1)/(K2+1) + B;
-        bands[2*K1+2 + 2*i+2] = 1.0f - x;
-        bands[2*K1+2 + 2*i+3] = g(R,D,f(D,B,x),cosBeta);
-        }
-      }
-
-    bands[2*N-2] = 0.0f;
-    bands[2*N-1] =    H;
-
-    return bands;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius)
-    {
-    Static4D reg= new Static4D(0,0,0,regionRadius);
-
-    float centX = center.get0();
-    float centY = center.get1();
-    float centZ = center.get2();
-
-    for (Static3D vertex : vertices)
-      {
-      float x = strength*(centX - vertex.get0());
-      float y = strength*(centY - vertex.get1());
-      float z = strength*(centZ - vertex.get2());
-
-      VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg);
-      mesh.apply(effect);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void printStickerCoords()
-    {
-    int stickers = mStickerCoords.size();
-
-    android.util.Log.d("D", "---- STICKER COORDS ----");
-
-    for(int s=0; s<stickers; s++)
-      {
-      String ver = "{ ";
-      StickerCoords info = mStickerCoords.get(s);
-      int len = info.vertices.length/2;
-
-      for(int i =0; i<len; i++)
-        {
-        if( i!=0 ) ver += ", ";
-        ver += ( (float)info.vertices[2*i]+"f, "+(float)info.vertices[2*i+1]+"f");
-        }
-
-      ver += " }";
-      android.util.Log.d("D", ver);
-      }
-
-    android.util.Log.d("D", "---- END STICKER COORDS ----");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void printFaceTransform()
-    {
-    android.util.Log.d("D", "---- OLD FACE TRANSFORM ---");
-
-    int oldfaces = mOldFaceTransf.size();
-
-    for(int f=0; f<oldfaces; f++)
-      {
-      printTransform(mOldFaceTransf.get(f));
-      }
-
-    android.util.Log.d("D", "---- NEW FACE TRANSFORM ---");
-
-    int newfaces = mNewFaceTransf.size();
-
-    for(int f=0; f<newfaces; f++)
-      {
-      printTransform(mNewFaceTransf.get(f));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void clear()
-    {
-    mStickerCoords.clear();
-    mNewFaceTransf.clear();
-    mOldFaceTransf.clear();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void createNewFaceTransform( final double[][] vertices, final int[][] indexes)
-    {
-    FaceTransform ft;
-    int numNew = mNewFaceTransf.size();
-
-    for(int i=0; i<numNew; i++)
-      {
-      ft = mNewFaceTransf.remove(0);
-      mOldFaceTransf.add(ft);
-      }
-
-    int numFaces = indexes.length;
-    int numOld = mOldFaceTransf.size();
-
-    for (int face=0; face<numFaces; face++)
-      {
-      boolean collapsed = false;
-
-      double[][] vert = constructVert(vertices, indexes[face]);
-      FaceTransform newT = constructNewTransform(vert);
-
-      for (int old=0; !collapsed && old<numOld; old++)
-        {
-        ft = mOldFaceTransf.get(old);
-        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
-        }
-
-      for (int pre=0; !collapsed && pre<face; pre++)
-        {
-        ft = mNewFaceTransf.get(pre);
-        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
-        }
-
-      mNewFaceTransf.add(newT);
-      }
-    }
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void createNewFaceTransform(final ObjectShape shape)
-    {
-    double[][] vertices = shape.getVertices();
-    int[][] indices = shape.getVertIndices();
-    createNewFaceTransform(vertices,indices);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computeConvexityCenter(double[] out, float[] in, FaceTransform ft)
-    {
-    if( in==null )
-      {
-      out[0] = out[1] = 0.0f;
-      }
-    else
-      {
-      out[0] = in[0] - ft.vx;
-      out[1] = in[1] - ft.vy;
-      out[2] = in[2] - ft.vz;
-      out[3] = 1.0f;
-
-      mQuat1[0] =-ft.qx;
-      mQuat1[1] =-ft.qy;
-      mQuat1[2] =-ft.qz;
-      mQuat1[3] = ft.qw;
-
-      mQuat2[0] = -mQuat1[0];
-      mQuat2[1] = -mQuat1[1];
-      mQuat2[2] = -mQuat1[2];
-      mQuat2[3] = +mQuat1[3];
-
-      quatMultiply(mQuat1, out  , mQuat3);
-      quatMultiply(mQuat3, mQuat2, out  );
-
-      out[0] /= ft.scale;
-      out[1] /= ft.scale;
-      out[2] /= ft.scale;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public MeshBase createRoundedSolid(final ObjectShape shape)
-    {
-    double[][] vertices     = shape.getVertices();
-    int[][] vertIndexes     = shape.getVertIndices();
-    float[][] bands         = shape.getBands();
-    int[]   bandIndexes     = shape.getBandIndices();
-    float[][] corners       = shape.getCorners();
-    int[]   cornerIndexes   = shape.getCornerIndices();
-    float[][] centers       = shape.getCenters();
-    int[]   centerIndexes   = shape.getCenterIndices();
-    int numComponents       = shape.getNumComponents();
-    float[] convexityCenter = shape.getConvexityCenter();
-
-    return createRoundedSolid(vertices,vertIndexes,bands,bandIndexes,corners,cornerIndexes,
-                              centers,centerIndexes,numComponents,convexityCenter);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public MeshBase createRoundedSolid(final double[][] vertices, final int[][] vertIndexes,
-                                     final float[][] bands    , final int[]   bandIndexes,
-                                     final float[][] corners  , final int[]   cornerIndexes,
-                                     final float[][] centers  , final int[]   centerIndexes,
-                                     final int numComponents  , final float[] convexityCenter )
-    {
-    int numFaces = vertIndexes.length;
-    float[] band, bandsComputed;
-    MeshBase[] meshes = new MeshBase[numFaces];
-    FaceTransform fInfo;
-    StickerCoords sInfo;
-    double[] convexXY = new double[4];
-
-    for(int face=0; face<numFaces; face++)
-      {
-      fInfo = mNewFaceTransf.get(face);
-      sInfo = mStickerCoords.get(fInfo.sticker);
-
-      double[] verts = sInfo.vertices;
-      int lenVerts = verts.length;
-      float[] vertsFloat = new float[lenVerts];
-      for(int i=0; i<lenVerts; i++) vertsFloat[i] = (float)verts[i];
-
-      computeConvexityCenter(convexXY,convexityCenter,fInfo);
-
-      band = bands[bandIndexes[face]];
-      bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
-      meshes[face] = new MeshPolygon(vertsFloat,bandsComputed,(int)band[5],(int)band[6], (float)convexXY[0], (float)convexXY[1]);
-      meshes[face].setEffectAssociation(0,(1<<face),0);
-      }
-
-    MeshBase mesh = new MeshJoined(meshes);
-    Static3D center = new Static3D(0,0,0);
-
-    for(int face=0; face<numFaces; face++)
-      {
-      int assoc = (1<<face);
-      fInfo = mNewFaceTransf.get(face);
-
-      float vx = (float)fInfo.vx;
-      float vy = (float)fInfo.vy;
-      float vz = (float)fInfo.vz;
-      float sc = (float)fInfo.scale;
-      float qx = (float)fInfo.qx;
-      float qy = (float)fInfo.qy;
-      float qz = (float)fInfo.qz;
-      float qw = (float)fInfo.qw;
-
-      Static3D scale = new Static3D(sc,sc, fInfo.flip ? -sc : sc);
-      Static3D move3D= new Static3D(vx,vy,vz);
-      Static4D quat  = new Static4D(qx,qy,qz,qw);
-
-      mesh.apply(new MatrixEffectScale(scale)           ,assoc,-1);
-      mesh.apply(new MatrixEffectQuaternion(quat,center),assoc,-1);
-      mesh.apply(new MatrixEffectMove(move3D)           ,assoc,-1);
-      }
-
-    prepareAndRoundCorners(mesh, vertices, corners, cornerIndexes, centers, centerIndexes);
-
-    correctComponents(mesh,numComponents);
-
-    return mesh;
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/FactorySticker.java b/src/main/java/org/distorted/objectlib/FactorySticker.java
deleted file mode 100644
index 0cd605d6..00000000
--- a/src/main/java/org/distorted/objectlib/FactorySticker.java
+++ /dev/null
@@ -1,315 +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;
-
-import static org.distorted.objectlib.TwistyObject.COLOR_BLACK;
-import static org.distorted.objectlib.TwistyObject.TEXTURE_HEIGHT;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class FactorySticker
-  {
-  private static FactorySticker mThis;
-  private float mOX, mOY, mR;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private FactorySticker()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static FactorySticker getInstance()
-    {
-    if( mThis==null ) mThis = new FactorySticker();
-
-    return mThis;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float computeAngle(float dx, float dy)
-    {
-    float PI = (float)Math.PI;
-    double angle = Math.atan2(dy,dx);
-    float ret = (float)(3*PI/2-angle);
-
-    if( ret>2*PI ) ret-= 2*PI;
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float getAngle(float[] angles, int index)
-    {
-    return angles==null ? 0 : angles[index];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computeCircleCoords(float lX,float lY, float rX, float rY, float alpha)
-    {
-    float ctg= 1.0f/((float)Math.tan(alpha));
-    mOX = 0.5f*(lX+rX) + ctg*0.5f*(lY-rY);
-    mOY = 0.5f*(lY+rY) - ctg*0.5f*(lX-rX);
-    float dx = mOX-lX;
-    float dy = mOY-lY;
-    mR = (float)Math.sqrt(dx*dx+dy*dy);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// circle1: center (x1,y1) radius r1; circle2: center (x2,y2) radius r2.
-// Guaranteed to intersect in two points. Find the intersection. Which one? the one that's closer
-// to (nearx,neary).
-
-  private void findCircleIntersection(float x1,float y1, float r1, float x2, float y2, float r2, float nearx, float neary )
-    {
-    float dx = x2-x1;
-    float dy = y2-y1;
-    float d = (float)Math.sqrt(dx*dx+dy*dy);
-
-    if( d>0 )
-      {
-      float Dx = dx/d;
-      float Dy = dy/d;
-      float cos = (r1*r1+d*d-r2*r2)/(2*r1*d);
-      float sin = (float)Math.sqrt(1-cos*cos);
-
-      float ox1 = x1 + r1*cos*Dx + r1*sin*Dy;
-      float oy1 = y1 + r1*cos*Dy - r1*sin*Dx;
-      float ox2 = x1 + r1*cos*Dx - r1*sin*Dy;
-      float oy2 = y1 + r1*cos*Dy + r1*sin*Dx;
-
-      dx = nearx-ox1;
-      dy = neary-oy1;
-      float d1 = dx*dx+dy*dy;
-      dx = nearx-ox2;
-      dy = neary-oy2;
-      float d2 = dx*dx+dy*dy;
-
-      if( d1<d2 )
-        {
-        mOX = ox1;
-        mOY = oy1;
-        }
-      else
-        {
-        mOX = ox2;
-        mOY = oy2;
-        }
-      }
-    else
-      {
-      mOX = x1;
-      mOY = y1;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void drawCurrCurveV(Canvas canvas, Paint paint, int left, int top, float r, float stroke, float pX, float pY, float cX, float cY, float nX, float nY, float pA, float cA)
-    {
-    pX = (0.5f+pX)*TEXTURE_HEIGHT;
-    pY = (0.5f-pY)*TEXTURE_HEIGHT;
-    cX = (0.5f+cX)*TEXTURE_HEIGHT;
-    cY = (0.5f-cY)*TEXTURE_HEIGHT;
-    nX = (0.5f+nX)*TEXTURE_HEIGHT;
-    nY = (0.5f-nY)*TEXTURE_HEIGHT;
-
-    computeCircleCoords(pX,pY,cX,cY,pA);
-    float o1x = mOX;
-    float o1y = mOY;
-    float r1  = mR;
-    computeCircleCoords(cX,cY,nX,nY,cA);
-    float o2x = mOX;
-    float o2y = mOY;
-    float r2  = mR;
-
-    float dx = o1x-pX;
-    float dy = o1y-pY;
-    float startA = computeAngle(dy,dx);
-    float sweepA = 2*pA;
-
-    startA *= 180/(Math.PI);
-    sweepA *= 180/(Math.PI);
-
-    canvas.drawArc( left+o1x-r1, top+o1y-r1, left+o1x+r1, top+o1y+r1, startA, sweepA, false, paint);
-
-    float r3 = r*TEXTURE_HEIGHT + stroke/2;
-    float R1 = r1 + (pA < 0 ? r3:-r3);
-    float R2 = r2 + (cA < 0 ? r3:-r3);
-    findCircleIntersection(o1x,o1y,R1,o2x,o2y,R2,cX,cY);
-    float o3x = mOX;
-    float o3y = mOY;
-
-    dx = pA<0 ? o3x-o1x : o1x-o3x;
-    dy = pA<0 ? o3y-o1y : o1y-o3y;
-    startA = computeAngle(dy,dx);
-    dx = cA<0 ? o3x-o2x : o2x-o3x;
-    dy = cA<0 ? o3y-o2y : o2y-o3y;
-    float endA = computeAngle(dy,dx);
-
-    sweepA = endA-startA;
-    if( sweepA<0 ) sweepA += 2*Math.PI;
-
-    startA *= 180/(Math.PI);
-    sweepA *= 180/(Math.PI);
-
-    canvas.drawArc( left+o3x-r3, top+o3y-r3, left+o3x+r3, top+o3y+r3, startA, sweepA, false, paint);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void drawCurrVertex(Canvas canvas, Paint paint, int left, int top, float r, float stroke, float pX, float pY, float cX, float cY, float nX, float nY)
-    {
-    pX = (0.5f+pX)*TEXTURE_HEIGHT;
-    pY = (0.5f-pY)*TEXTURE_HEIGHT;
-    cX = (0.5f+cX)*TEXTURE_HEIGHT;
-    cY = (0.5f-cY)*TEXTURE_HEIGHT;
-    nX = (0.5f+nX)*TEXTURE_HEIGHT;
-    nY = (0.5f-nY)*TEXTURE_HEIGHT;
-
-    canvas.drawLine(left+pX,top+pY,left+cX,top+cY,paint);
-
-    float aX = pX-cX;
-    float aY = pY-cY;
-    float bX = cX-nX;
-    float bY = cY-nY;
-
-    float aLen = (float)Math.sqrt(aX*aX+aY*aY);
-    float bLen = (float)Math.sqrt(bX*bX+bY*bY);
-
-    aX /= aLen;
-    aY /= aLen;
-    bX /= bLen;
-    bY /= bLen;
-
-    float sX = (aX-bX)/2;
-    float sY = (aY-bY)/2;
-    float sLen = (float)Math.sqrt(sX*sX+sY*sY);
-    sX /= sLen;
-    sY /= sLen;
-
-    float startAngle = computeAngle(bX,-bY);
-    float endAngle   = computeAngle(aX,-aY);
-    float sweepAngle = endAngle-startAngle;
-    if( sweepAngle<0 ) sweepAngle += 2*Math.PI;
-
-    float R = r*TEXTURE_HEIGHT+stroke/2;
-    float C = (float)Math.cos(sweepAngle/2);
-    float A = R/C;
-
-    left += (cX+A*sX);
-    top  += (cY+A*sY);
-
-    if( C< (2*R-stroke)/(2*R+stroke) )
-      {
-      float alpha = startAngle + sweepAngle/2;
-      float B  = (R-stroke/2)/C;
-      float sx = (float)Math.cos(alpha);
-      float sy = (float)Math.sin(alpha);
-
-      float startX = left + R*sx;
-      float startY = top  + R*sy;
-      float stopX  = left + B*sx;
-      float stopY  = top  + B*sy;
-
-      canvas.drawLine(startX,startY,stopX,stopY,paint);
-      }
-
-    startAngle *= 180/(Math.PI);
-    sweepAngle *= 180/(Math.PI);
-
-    canvas.drawArc( left-R, top-R, left+R, top+R, startAngle, sweepAngle, false, paint);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC
-
-  public void drawRoundedPolygon(Canvas canvas, Paint paint, int left, int top, int color, ObjectSticker sticker)
-    {
-    float stroke = sticker.getStroke();
-    float[] vertices = sticker.getCoords();
-    float[] angles = sticker.getCurvature();
-    float[] radii = sticker.getRadii();
-
-    stroke *= TEXTURE_HEIGHT;
-
-    paint.setAntiAlias(true);
-    paint.setStrokeWidth(stroke);
-    paint.setColor(color);
-    paint.setStyle(Paint.Style.FILL);
-
-    canvas.drawRect(left,top,left+TEXTURE_HEIGHT,top+TEXTURE_HEIGHT,paint);
-
-    paint.setColor(COLOR_BLACK);
-    paint.setStyle(Paint.Style.STROKE);
-
-    int length = vertices.length;
-    int numVertices = length/2;
-
-    float prevX = vertices[length-2];
-    float prevY = vertices[length-1];
-    float currX = vertices[0];
-    float currY = vertices[1];
-    float nextX = vertices[2];
-    float nextY = vertices[3];
-
-    float prevA = getAngle(angles,numVertices-1);
-    float currA = getAngle(angles,0);
-
-    for(int vert=0; vert<numVertices; vert++)
-      {
-      if( prevA==0 )
-        {
-        drawCurrVertex(canvas, paint, left, top, radii[vert], stroke, prevX,prevY,currX,currY,nextX,nextY);
-        }
-      else
-        {
-        drawCurrCurveV(canvas, paint, left, top, radii[vert], stroke, prevX,prevY,currX,currY,nextX,nextY,prevA,currA);
-        }
-
-      prevX = currX;
-      prevY = currY;
-      currX = nextX;
-      currY = nextY;
-
-      prevA = currA;
-      currA = getAngle(angles, vert==numVertices-1 ? 0 : vert+1);
-
-      if( 2*(vert+2)+1 < length )
-        {
-        nextX = vertices[2*(vert+2)  ];
-        nextY = vertices[2*(vert+2)+1];
-        }
-      else
-        {
-        nextX = vertices[0];
-        nextY = vertices[1];
-        }
-      }
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/Movement.java b/src/main/java/org/distorted/objectlib/Movement.java
deleted file mode 100644
index b69f812a..00000000
--- a/src/main/java/org/distorted/objectlib/Movement.java
+++ /dev/null
@@ -1,477 +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;
-
-import org.distorted.library.type.Static2D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Movement
-  {
-  // it doesn't matter where we touch a face - the list of enabled rotAxis will always be the same
-  public static final int TYPE_NOT_SPLIT    = 0;
-  // each face is split into several parts by lines coming from its center to the midpoints of each edge
-  public static final int TYPE_SPLIT_EDGE   = 1;
-  // each face is split into several parts by lines coming from its center to the vertices
-  public static final int TYPE_SPLIT_CORNER = 2;
-
-  static final float SQ3 = (float)Math.sqrt(3);
-  static final float SQ6 = (float)Math.sqrt(6);
-
-  private final int mNumFaceAxis;
-  private final float[] mPoint, mCamera, mTouch;
-  private final float[] mPoint2D, mMove2D;
-  private final int[] mEnabledRotAxis;
-  private final float mDistanceCenterFace3D;
-  private final Static3D[] mFaceAxis;
-
-  private int mLastTouchedFace;
-  private float[][][] mCastedRotAxis;
-  private Static4D[][] mCastedRotAxis4D;
-  private float[][] mTouchBorders, mA, mB;
-
-  private final int mType;
-  private final int[][][] mEnabled;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract int returnPart(int type, int face, float[] touchPoint);
-  abstract boolean isInsideFace(int face, float[] point);
-  public abstract float returnRotationFactor(int numLayers, int row);
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  Movement(Static3D[] rotAxis, Static3D[] faceAxis, float[][] cuts, boolean[][] rotatable,
-           float distance3D, int size, int type, int[][][] enabled)
-    {
-    mPoint = new float[3];
-    mCamera= new float[3];
-    mTouch = new float[3];
-
-    mPoint2D = new float[2];
-    mMove2D  = new float[2];
-
-    mType = type;
-    mEnabled = enabled;
-
-    mFaceAxis   = faceAxis;
-    mNumFaceAxis= mFaceAxis.length;
-
-    mEnabledRotAxis = new int[rotAxis.length+1];
-
-    mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces
-
-    computeCastedAxis(rotAxis);
-    computeBorders(cuts,rotatable,size);
-    computeLinear(distance3D,rotAxis,faceAxis);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// mCastedRotAxis[1][2]{0,1} are the 2D coords of the 2nd rotAxis cast onto the face defined by the
-// 1st faceAxis.
-
-  private void computeCastedAxis(Static3D[] rotAxis)
-    {
-    mCastedRotAxis   = new float[mNumFaceAxis][rotAxis.length][2];
-    mCastedRotAxis4D = new Static4D[mNumFaceAxis][rotAxis.length];
-
-    float fx,fy,fz,f;
-
-    for( int casted=0; casted<rotAxis.length; casted++)
-      {
-      Static3D a = rotAxis[casted];
-      mPoint[0]= a.get0();
-      mPoint[1]= a.get1();
-      mPoint[2]= a.get2();
-
-      for( int face=0; face<mNumFaceAxis; face++)
-        {
-        convertTo2Dcoords( mPoint, mFaceAxis[face], mCastedRotAxis[face][casted]);
-        normalize2D(mCastedRotAxis[face][casted]);
-
-        fx = mFaceAxis[face].get0();
-        fy = mFaceAxis[face].get1();
-        fz = mFaceAxis[face].get2();
-        f  = mPoint[0]*fx + mPoint[1]*fy + mPoint[2]*fz;
-        mCastedRotAxis4D[face][casted] = new Static4D( mPoint[0]-f*fx, mPoint[1]-f*fy, mPoint[2]-f*fz, 0);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void normalize2D(float[] vect)
-    {
-    float len = (float)Math.sqrt(vect[0]*vect[0] + vect[1]*vect[1]);
-    vect[0] /= len;
-    vect[1] /= len;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// find the casted axis with which our move2D vector forms an angle closest to 90 deg.
-
-  private int computeRotationIndex(int faceAxis, float[] move2D, int[] enabled)
-    {
-    float cosAngle, minCosAngle = Float.MAX_VALUE;
-    int minIndex=0, index;
-    float m0 = move2D[0];
-    float m1 = move2D[1];
-    float len = (float)Math.sqrt(m0*m0 + m1*m1);
-
-    if( len!=0.0f )
-      {
-      m0 /= len;
-      m1 /= len;
-      }
-    else
-      {
-      m0 = 1.0f;  // arbitrarily
-      m1 = 0.0f;  //
-      }
-
-    int numAxis = enabled[0];
-
-    for(int axis=1; axis<=numAxis; axis++)
-      {
-      index = enabled[axis];
-      cosAngle = m0*mCastedRotAxis[faceAxis][index][0] + m1*mCastedRotAxis[faceAxis][index][1];
-      if( cosAngle<0 ) cosAngle = -cosAngle;
-
-      if( cosAngle<minCosAngle )
-        {
-        minCosAngle=cosAngle;
-        minIndex = index;
-        }
-      }
-
-    return minIndex;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// in the center of the face offset is always 0 regardless of the axis
-
-  private float computeOffset(float[] point, float[] axis)
-    {
-    return point[0]*axis[0] + point[1]*axis[1];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean faceIsVisible(Static3D faceAxis)
-    {
-    float castCameraOnAxis = mCamera[0]*faceAxis.get0() + mCamera[1]*faceAxis.get1() + mCamera[2]*faceAxis.get2();
-    return castCameraOnAxis > mDistanceCenterFace3D;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
-// compute point 'output[]' which:
-// 1) lies on a face of the Object, i.e. surface defined by (axis, distance from (0,0,0))
-// 2) is co-linear with mCamera and mPoint
-//
-// output = camera + alpha*(point-camera), where alpha = [dist-axis*camera] / [axis*(point-camera)]
-
-  private void castTouchPointOntoFace(Static3D faceAxis, float[] output)
-    {
-    float d0 = mPoint[0]-mCamera[0];
-    float d1 = mPoint[1]-mCamera[1];
-    float d2 = mPoint[2]-mCamera[2];
-    float a0 = faceAxis.get0();
-    float a1 = faceAxis.get1();
-    float a2 = faceAxis.get2();
-
-    float denom = a0*d0 + a1*d1 + a2*d2;
-
-    if( denom != 0.0f )
-      {
-      float axisCam = a0*mCamera[0] + a1*mCamera[1] + a2*mCamera[2];
-      float alpha = (mDistanceCenterFace3D-axisCam)/denom;
-
-      output[0] = mCamera[0] + d0*alpha;
-      output[1] = mCamera[1] + d1*alpha;
-      output[2] = mCamera[2] + d2*alpha;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert the 3D point3D into a 2D point on the same face surface, but in a different
-// coordinate system: a in-plane 2D coord where the origin is in the point where the axis intersects
-// the surface, and whose Y axis points 'north' i.e. is in the plane given by the 3D origin, the
-// original 3D Y axis and our 2D in-plane origin.
-// If those 3 points constitute a degenerate triangle which does not define a plane - which can only
-// happen if axis is vertical (or in theory when 2D origin and 3D origin meet, but that would have to
-// mean that the distance between the center of the Object and its faces is 0) - then we arbitrarily
-// decide that 2D Y = (0,0,-1) in the North Pole and (0,0,1) in the South Pole)
-
-  private void convertTo2Dcoords(float[] point3D, Static3D faceAxis, float[] output)
-    {
-    float y0,y1,y2; // base Y vector of the 2D coord system
-    float a0 = faceAxis.get0();
-    float a1 = faceAxis.get1();
-    float a2 = faceAxis.get2();
-
-    if( a0==0.0f && a2==0.0f )
-      {
-      y0=0; y1=0; y2=-a1;
-      }
-    else if( a1==0.0f )
-      {
-      y0=0; y1=1; y2=0;
-      }
-    else
-      {
-      float norm = (float)(-a1/Math.sqrt(1-a1*a1));
-      y0 = norm*a0; y1= norm*(a1-1/a1); y2=norm*a2;
-      }
-
-    float x0 = y1*a2 - y2*a1;  //
-    float x1 = y2*a0 - y0*a2;  // (2D coord baseY) x (axis) = 2D coord baseX
-    float x2 = y0*a1 - y1*a0;  //
-
-    float originAlpha = point3D[0]*a0 + point3D[1]*a1 + point3D[2]*a2;
-
-    float origin0 = originAlpha*a0; // coords of the point where axis
-    float origin1 = originAlpha*a1; // intersects surface plane i.e.
-    float origin2 = originAlpha*a2; // the origin of our 2D coord system
-
-    float v0 = point3D[0] - origin0;
-    float v1 = point3D[1] - origin1;
-    float v2 = point3D[2] - origin2;
-
-    output[0] = v0*x0 + v1*x1 + v2*x2;
-    output[1] = v0*y0 + v1*y1 + v2*y2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeBorder(float[] cuts, boolean[] rotatable, int size)
-    {
-    int len = cuts.length;
-    float[] border = new float[len];
-
-    for(int i=0; i<len; i++)
-      {
-      if( !rotatable[i] )
-        {
-        border[i] = i>0 ? border[i-1] : -Float.MAX_VALUE;
-        }
-      else
-        {
-        if( rotatable[i+1] ) border[i] = cuts[i]/size;
-        else
-          {
-          int found = -1;
-
-          for(int j=i+2; j<=len; j++)
-            {
-            if( rotatable[j] )
-              {
-              found=j;
-              break;
-              }
-            }
-
-          border[i] = found>0 ? (cuts[i]+cuts[found-1])/(2*size) : Float.MAX_VALUE;
-          }
-        }
-      }
-
-    return border;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// size, not numLayers (see Master Skewb where size!=numLayers)
-
-  void computeBorders(float[][] cuts, boolean[][] rotatable, int size)
-    {
-    int numCuts = cuts.length;
-    mTouchBorders = new float[numCuts][];
-
-    for(int i=0; i<numCuts; i++)
-      {
-      mTouchBorders[i] = computeBorder(cuts[i],rotatable[i],size);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeSign(Static3D a, Static3D b)
-    {
-    float a1 = a.get0();
-    float a2 = a.get1();
-    float a3 = a.get2();
-    float b1 = b.get0();
-    float b2 = b.get1();
-    float b3 = b.get2();
-
-    return a1*b1+a2*b2+a3*b3 < 0 ? 1:-1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float crossProductLen(Static3D a, Static3D b)
-    {
-    float a1 = a.get0();
-    float a2 = a.get1();
-    float a3 = a.get2();
-    float b1 = b.get0();
-    float b2 = b.get1();
-    float b3 = b.get2();
-
-    float x1 = a2*b3-a3*b2;
-    float x2 = a3*b1-a1*b3;
-    float x3 = a1*b2-a2*b1;
-
-    return (float)Math.sqrt(x1*x1 + x2*x2 + x3*x3);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// compute the array of 'A' and 'B' coeffs of the Ax+B linear function by which we need to multiply
-// the 3D 'cuts' to translate it from 3D (i.e. with respect to the rotAxis) to 2D in-face (i.e. with
-// respect to the 2D rotAxis cast into a particular face)
-
-  private void computeLinear(float distance3D, Static3D[] rotAxis, Static3D[] faceAxis)
-    {
-    int numFaces = faceAxis.length;
-    int numRot   = rotAxis.length;
-
-    mA = new float[numFaces][numRot];
-    mB = new float[numFaces][numRot];
-
-    for(int i=0; i<numFaces; i++)
-      for(int j=0; j<numRot; j++)
-        {
-        mA[i][j] = crossProductLen(faceAxis[i],rotAxis[j]);
-
-        if( mA[i][j]!=0.0f )
-          {
-          float coeff = (float)Math.sqrt(1/(mA[i][j]*mA[i][j]) -1);
-          int sign = computeSign(faceAxis[i],rotAxis[j]);
-          mB[i][j] = sign*distance3D*coeff;
-          }
-        else mB[i][j] = 0.0f;
-        }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeRowFromOffset(int face, int axisIndex, float offset)
-    {
-    float[] borders = mTouchBorders[axisIndex];
-    int len = borders.length;
-    float A = mA[face][axisIndex];
-
-    if( A!=0.0f )
-      {
-      float B = mB[face][axisIndex];
-
-      for(int i=0; i<len; i++)
-        {
-        float translated = B + borders[i]/A;
-        if( offset<translated ) return i;
-        }
-      }
-
-    return len;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
-    {
-    int part = returnPart(mType,face,touchPoint);
-
-    int num = mEnabled[face][0].length;
-    enabled[0] = num;
-    System.arraycopy(mEnabled[face][part], 0, enabled, 1, num);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public boolean faceTouched(Static4D rotatedTouchPoint, Static4D rotatedCamera, float objectRatio)
-    {
-    mPoint[0]  = rotatedTouchPoint.get0()/objectRatio;
-    mPoint[1]  = rotatedTouchPoint.get1()/objectRatio;
-    mPoint[2]  = rotatedTouchPoint.get2()/objectRatio;
-
-    mCamera[0] = rotatedCamera.get0()/objectRatio;
-    mCamera[1] = rotatedCamera.get1()/objectRatio;
-    mCamera[2] = rotatedCamera.get2()/objectRatio;
-
-    for( mLastTouchedFace=0; mLastTouchedFace<mNumFaceAxis; mLastTouchedFace++)
-      {
-      if( faceIsVisible(mFaceAxis[mLastTouchedFace]) )
-        {
-        castTouchPointOntoFace(mFaceAxis[mLastTouchedFace], mTouch);
-        convertTo2Dcoords(mTouch, mFaceAxis[mLastTouchedFace], mPoint2D);
-        if( isInsideFace(mLastTouchedFace,mPoint2D) ) return true;
-        }
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Static2D newRotation(Static4D rotatedTouchPoint, float objectRatio)
-    {
-    mPoint[0] = rotatedTouchPoint.get0()/objectRatio;
-    mPoint[1] = rotatedTouchPoint.get1()/objectRatio;
-    mPoint[2] = rotatedTouchPoint.get2()/objectRatio;
-
-    castTouchPointOntoFace(mFaceAxis[mLastTouchedFace], mTouch);
-    convertTo2Dcoords(mTouch, mFaceAxis[mLastTouchedFace], mMove2D);
-
-    mMove2D[0] -= mPoint2D[0];
-    mMove2D[1] -= mPoint2D[1];
-
-    computeEnabledAxis(mLastTouchedFace, mPoint2D, mEnabledRotAxis);
-    int rotIndex = computeRotationIndex(mLastTouchedFace, mMove2D, mEnabledRotAxis);
-    float offset = computeOffset(mPoint2D, mCastedRotAxis[mLastTouchedFace][rotIndex]);
-    int row      = computeRowFromOffset(mLastTouchedFace,rotIndex,offset);
-
-    return new Static2D(rotIndex,row);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Static4D getCastedRotAxis(int rotIndex)
-    {
-    return mCastedRotAxis4D[mLastTouchedFace][rotIndex];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getTouchedFace()
-    {
-    return mLastTouchedFace;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[] getTouchedPoint3D()
-    {
-    return mTouch;
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/Movement12.java b/src/main/java/org/distorted/objectlib/Movement12.java
deleted file mode 100644
index 9696a5fb..00000000
--- a/src/main/java/org/distorted/objectlib/Movement12.java
+++ /dev/null
@@ -1,187 +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;
-
-import static org.distorted.objectlib.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);
-  public static final float DIST2D = (SIN54/COS54)/2;
-
-  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, int size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts,rotatable,DIST3D, 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/Movement4.java b/src/main/java/org/distorted/objectlib/Movement4.java
deleted file mode 100644
index ec4599ff..00000000
--- a/src/main/java/org/distorted/objectlib/Movement4.java
+++ /dev/null
@@ -1,102 +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;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Tetrahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement4 extends Movement
-{
-  public static final float DIST3D = SQ6/12;
-  public static final float DIST2D = SQ3/6;
-
-  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, int size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, 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)
-    {
-    return numLayers==2 ? 1.0f : ((float)numLayers)/(numLayers-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/Movement6.java b/src/main/java/org/distorted/objectlib/Movement6.java
deleted file mode 100644
index c5ae97ba..00000000
--- a/src/main/java/org/distorted/objectlib/Movement6.java
+++ /dev/null
@@ -1,82 +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;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Hexahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement6 extends Movement
-{
-  public static final float DIST3D = 0.5f;
-  public static final float DIST2D = 0.5f;
-
-  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, int size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, 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/Movement8.java b/src/main/java/org/distorted/objectlib/Movement8.java
deleted file mode 100644
index 8eb3414b..00000000
--- a/src/main/java/org/distorted/objectlib/Movement8.java
+++ /dev/null
@@ -1,101 +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;
-
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Octahedral objects: map the 2D swipes of user's fingers to 3D rotations
-
-public class Movement8 extends Movement
-{
-  public static final float DIST3D = SQ6/6;
-  public static final float DIST2D = SQ3/6;
-
-  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, int size, int type, int[][][] enabled)
-    {
-    super(rotAxis, FACE_AXIS, cuts, rotatable, DIST3D, 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/ObjectList.java b/src/main/java/org/distorted/objectlib/ObjectList.java
deleted file mode 100644
index 2115db6d..00000000
--- a/src/main/java/org/distorted/objectlib/ObjectList.java
+++ /dev/null
@@ -1,559 +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;
-
-import org.distorted.main.R;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-  CUBE_2 ( 0, new int[] {2 , 12, 12, R.raw.cube2, R.drawable.ui_small_cube2, R.drawable.ui_medium_cube2, R.drawable.ui_big_cube2, R.drawable.ui_huge_cube2} ),
-  CUBE_3 ( 0, new int[] {3 , 16, 17, R.raw.cube3, R.drawable.ui_small_cube3, R.drawable.ui_medium_cube3, R.drawable.ui_big_cube3, R.drawable.ui_huge_cube3} ),
-  CUBE_4 ( 0, new int[] {4 , 20, 24, R.raw.cube4, R.drawable.ui_small_cube4, R.drawable.ui_medium_cube4, R.drawable.ui_big_cube4, R.drawable.ui_huge_cube4} ),
-  CUBE_5 ( 0, new int[] {5 , 24, 28, R.raw.cube5, R.drawable.ui_small_cube5, R.drawable.ui_medium_cube5, R.drawable.ui_big_cube5, R.drawable.ui_huge_cube5} ),
-  JING_2 ( 1, new int[] {2 , 11, 11, R.raw.jing , R.drawable.ui_small_jing2, R.drawable.ui_medium_jing2, R.drawable.ui_big_jing2, R.drawable.ui_huge_jing2} ),
-  PYRA_3 ( 1, new int[] {3 , 10, 10, R.raw.pyra3, R.drawable.ui_small_pyra3, R.drawable.ui_medium_pyra3, R.drawable.ui_big_pyra3, R.drawable.ui_huge_pyra3} ),
-  PYRA_4 ( 1, new int[] {4 , 14, 17, R.raw.pyra4, R.drawable.ui_small_pyra4, R.drawable.ui_medium_pyra4, R.drawable.ui_big_pyra4, R.drawable.ui_huge_pyra4} ),
-  PYRA_5 ( 1, new int[] {5 , 20, 23, R.raw.pyra5, R.drawable.ui_small_pyra5, R.drawable.ui_medium_pyra5, R.drawable.ui_big_pyra5, R.drawable.ui_huge_pyra5} ),
-  KILO_3 ( 2, new int[] {3 , 18, 18, R.raw.kilo3, R.drawable.ui_small_kilo3, R.drawable.ui_medium_kilo3, R.drawable.ui_big_kilo3, R.drawable.ui_huge_kilo3} ),
-  KILO_5 ( 2, new int[] {5 , 33, 33, R.raw.kilo5, R.drawable.ui_small_kilo5, R.drawable.ui_medium_kilo5, R.drawable.ui_big_kilo5, R.drawable.ui_huge_kilo5} ),
-  MEGA_3 ( 2, new int[] {3 , 21, 21, R.raw.mega3, R.drawable.ui_small_mega3, R.drawable.ui_medium_mega3, R.drawable.ui_big_mega3, R.drawable.ui_huge_mega3} ),
-  MEGA_5 ( 2, new int[] {5 , 35, 37, R.raw.mega5, R.drawable.ui_small_mega5, R.drawable.ui_medium_mega5, R.drawable.ui_big_mega5, R.drawable.ui_huge_mega5} ),
-  ULTI_2 ( 3, new int[] {2 , 18, 18, R.raw.ulti , R.drawable.ui_small_ulti , R.drawable.ui_medium_ulti , R.drawable.ui_big_ulti , R.drawable.ui_huge_ulti } ),
-  DIAM_2 ( 3, new int[] {2 , 10, 12, R.raw.diam2, R.drawable.ui_small_diam2, R.drawable.ui_medium_diam2, R.drawable.ui_big_diam2, R.drawable.ui_huge_diam2} ),
-  DIAM_3 ( 3, new int[] {3 , 18, 24, R.raw.diam3, R.drawable.ui_small_diam3, R.drawable.ui_medium_diam3, R.drawable.ui_big_diam3, R.drawable.ui_huge_diam3} ),
-  DIAM_4 ( 3, new int[] {4 , 32, 32, R.raw.diam4, R.drawable.ui_small_diam4, R.drawable.ui_medium_diam4, R.drawable.ui_big_diam4, R.drawable.ui_huge_diam4} ),
-  DINO_3 ( 4, new int[] {3 , 10, 10, R.raw.dino , R.drawable.ui_small_dino , R.drawable.ui_medium_dino , R.drawable.ui_big_dino , R.drawable.ui_huge_dino } ),
-  DIN4_3 ( 4, new int[] {3 ,  7,  7, R.raw.dino , R.drawable.ui_small_din4 , R.drawable.ui_medium_din4 , R.drawable.ui_big_din4 , R.drawable.ui_huge_din4 } ),
-  REDI_3 ( 4, new int[] {3 , 14, 16, R.raw.redi , R.drawable.ui_small_redi , R.drawable.ui_medium_redi , R.drawable.ui_big_redi , R.drawable.ui_huge_redi } ),
-  HELI_3 ( 4, new int[] {3 , 18, 20, R.raw.heli , R.drawable.ui_small_heli , R.drawable.ui_medium_heli , R.drawable.ui_big_heli , R.drawable.ui_huge_heli } ),
-  SKEW_2 ( 5, new int[] {2 , 11, 11, R.raw.skew2, R.drawable.ui_small_skew2, R.drawable.ui_medium_skew2, R.drawable.ui_big_skew2, R.drawable.ui_huge_skew2} ),
-  SKEW_3 ( 5, new int[] {3 , 17, 21, R.raw.skew3, R.drawable.ui_small_skew3, R.drawable.ui_medium_skew3, R.drawable.ui_big_skew3, R.drawable.ui_huge_skew3} ),
-  IVY_2  ( 5, new int[] {2 ,  8,  8, R.raw.ivy  , R.drawable.ui_small_ivy  , R.drawable.ui_medium_ivy  , R.drawable.ui_big_ivy  , R.drawable.ui_huge_ivy  } ),
-  REX_3  ( 5, new int[] {3 , 16, 19, R.raw.rex  , R.drawable.ui_small_rex  , R.drawable.ui_medium_rex  , R.drawable.ui_big_rex  , R.drawable.ui_huge_rex  } ),
-  BAN1_3 ( 6, new int[] {3 , 16, 16, R.raw.ban1 , R.drawable.ui_small_ban1 , R.drawable.ui_medium_ban1 , R.drawable.ui_big_ban1 , R.drawable.ui_huge_ban1 } ),
-  BAN2_3 ( 6, new int[] {3 , 16, 16, R.raw.ban2 , R.drawable.ui_small_ban2 , R.drawable.ui_medium_ban2 , R.drawable.ui_big_ban2 , R.drawable.ui_huge_ban2 } ),
-  BAN3_3 ( 6, new int[] {3 , 16, 16, R.raw.ban3 , R.drawable.ui_small_ban3 , R.drawable.ui_medium_ban3 , R.drawable.ui_big_ban3 , R.drawable.ui_huge_ban3 } ),
-  BAN4_3 ( 6, new int[] {3 , 16, 16, R.raw.ban4 , R.drawable.ui_small_ban4 , R.drawable.ui_medium_ban4 , R.drawable.ui_big_ban4 , R.drawable.ui_huge_ban4 } ),
-  SQU1_3 ( 7, new int[] {3 , 24, 24, R.raw.squa1, R.drawable.ui_small_squa1, R.drawable.ui_medium_squa1, R.drawable.ui_big_squa1, R.drawable.ui_huge_squa1} ),
-  SQU2_3 ( 7, new int[] {3 , 24, 24, R.raw.squa2, R.drawable.ui_small_squa2, R.drawable.ui_medium_squa2, R.drawable.ui_big_squa2, R.drawable.ui_huge_squa2} ),
-  MIRR_2 ( 7, new int[] {2 , 12, 12, R.raw.mirr2, R.drawable.ui_small_mirr2, R.drawable.ui_medium_mirr2, R.drawable.ui_big_mirr2, R.drawable.ui_huge_mirr2} ),
-  MIRR_3 ( 7, new int[] {3 , 16, 17, R.raw.mirr3, R.drawable.ui_small_mirr3, R.drawable.ui_medium_mirr3, R.drawable.ui_big_mirr3, R.drawable.ui_huge_mirr3} ),
-  ;
-*/
-
-public enum ObjectList
-  {
-  ///////////////////// Size // DB Level // NumScrambles // Mesh // small icon // medium icon // big icon // huge icon
-
-  CUBE (
-         new int[][] {
-                       {2 , 12, 12, R.raw.cube2, R.drawable.ui_small_cube2, R.drawable.ui_medium_cube2, R.drawable.ui_big_cube2, R.drawable.ui_huge_cube2} ,
-                       {3 , 16, 17, R.raw.cube3, R.drawable.ui_small_cube3, R.drawable.ui_medium_cube3, R.drawable.ui_big_cube3, R.drawable.ui_huge_cube3} ,
-                       {4 , 20, 24, R.raw.cube4, R.drawable.ui_small_cube4, R.drawable.ui_medium_cube4, R.drawable.ui_big_cube4, R.drawable.ui_huge_cube4} ,
-                       {5 , 24, 28, R.raw.cube5, R.drawable.ui_small_cube5, R.drawable.ui_medium_cube5, R.drawable.ui_big_cube5, R.drawable.ui_huge_cube5}
-                     },
-         0
-       ),
-
-  JING (
-         new int[][] {
-                       {2 , 11, 11, R.raw.jing, R.drawable.ui_small_jing2, R.drawable.ui_medium_jing2, R.drawable.ui_big_jing2, R.drawable.ui_huge_jing2} ,
-                     },
-         1
-       ),
-
-  PYRA (
-         new int[][] {
-                       {3 , 10, 10, R.raw.pyra3, R.drawable.ui_small_pyra3, R.drawable.ui_medium_pyra3, R.drawable.ui_big_pyra3, R.drawable.ui_huge_pyra3} ,
-                       {4 , 15, 17, R.raw.pyra4, R.drawable.ui_small_pyra4, R.drawable.ui_medium_pyra4, R.drawable.ui_big_pyra4, R.drawable.ui_huge_pyra4} ,
-                       {5 , 20, 23, R.raw.pyra5, R.drawable.ui_small_pyra5, R.drawable.ui_medium_pyra5, R.drawable.ui_big_pyra5, R.drawable.ui_huge_pyra5}
-                     },
-         1
-       ),
-
-  KILO (
-         new int[][] {
-                       {3 , 18, 18, R.raw.kilo3, R.drawable.ui_small_kilo3, R.drawable.ui_medium_kilo3, R.drawable.ui_big_kilo3, R.drawable.ui_huge_kilo3} ,
-                       {5 , 33, 33, R.raw.kilo5, R.drawable.ui_small_kilo5, R.drawable.ui_medium_kilo5, R.drawable.ui_big_kilo5, R.drawable.ui_huge_kilo5} ,
-                     },
-         2
-       ),
-
-  MEGA (
-         new int[][] {
-                       {3 , 21, 21, R.raw.mega3, R.drawable.ui_small_mega3, R.drawable.ui_medium_mega3, R.drawable.ui_big_mega3, R.drawable.ui_huge_mega3} ,
-                       {5 , 35, 37, R.raw.mega5, R.drawable.ui_small_mega5, R.drawable.ui_medium_mega5, R.drawable.ui_big_mega5, R.drawable.ui_huge_mega5} ,
-                     },
-         2
-       ),
-
-  ULTI (
-         new int[][] {
-                       {2 , 18, 18, R.raw.ulti, R.drawable.ui_small_ulti, R.drawable.ui_medium_ulti, R.drawable.ui_big_ulti, R.drawable.ui_huge_ulti} ,
-                     },
-         3
-       ),
-
-  DIAM (
-         new int[][] {
-                       {2 , 10, 12, R.raw.diam2, R.drawable.ui_small_diam2, R.drawable.ui_medium_diam2, R.drawable.ui_big_diam2, R.drawable.ui_huge_diam2} ,
-                       {3 , 18, 24, R.raw.diam3, R.drawable.ui_small_diam3, R.drawable.ui_medium_diam3, R.drawable.ui_big_diam3, R.drawable.ui_huge_diam3} ,
-                       {4 , 32, 32, R.raw.diam4, R.drawable.ui_small_diam4, R.drawable.ui_medium_diam4, R.drawable.ui_big_diam4, R.drawable.ui_huge_diam4} ,
-                     },
-         3
-       ),
-
-  DINO (
-         new int[][] {
-                       {3 , 10, 10, R.raw.dino, R.drawable.ui_small_dino, R.drawable.ui_medium_dino, R.drawable.ui_big_dino, R.drawable.ui_huge_dino} ,
-                     },
-         4
-       ),
-
-  DIN4 (
-         new int[][] {
-                       {3 , 7, 7, R.raw.dino, R.drawable.ui_small_din4, R.drawable.ui_medium_din4, R.drawable.ui_big_din4, R.drawable.ui_huge_din4} ,
-                     },
-         4
-       ),
-
-  REDI (
-         new int[][] {
-                       {3 , 14, 16, R.raw.redi, R.drawable.ui_small_redi, R.drawable.ui_medium_redi, R.drawable.ui_big_redi, R.drawable.ui_huge_redi} ,
-                     },
-         4
-       ),
-
-  HELI (
-         new int[][] {
-                       {3 , 18, 20, R.raw.heli, R.drawable.ui_small_heli, R.drawable.ui_medium_heli, R.drawable.ui_big_heli, R.drawable.ui_huge_heli} ,
-                     },
-         4
-       ),
-
-  SKEW (
-         new int[][] {
-                       {2 , 11, 11, R.raw.skew2, R.drawable.ui_small_skew2, R.drawable.ui_medium_skew2, R.drawable.ui_big_skew2, R.drawable.ui_huge_skew2} ,
-                       {3 , 17, 21, R.raw.skew3, R.drawable.ui_small_skew3, R.drawable.ui_medium_skew3, R.drawable.ui_big_skew3, R.drawable.ui_huge_skew3} ,
-                     },
-         5
-       ),
-
-  IVY  (
-         new int[][] {
-                       {2 , 8, 8, R.raw.ivy, R.drawable.ui_small_ivy, R.drawable.ui_medium_ivy, R.drawable.ui_big_ivy, R.drawable.ui_huge_ivy} ,
-                     },
-         5
-       ),
-
-  REX  (
-         new int[][] {
-                       {3 , 16, 19, R.raw.rex, R.drawable.ui_small_rex, R.drawable.ui_medium_rex, R.drawable.ui_big_rex, R.drawable.ui_huge_rex} ,
-                     },
-         5
-       ),
-
-  BAN1 (
-         new int[][] {
-                       {3 , 16, 16, R.raw.ban1, R.drawable.ui_small_ban1, R.drawable.ui_medium_ban1, R.drawable.ui_big_ban1, R.drawable.ui_huge_ban1} ,
-                     },
-         6
-       ),
-
-  BAN2 (
-         new int[][] {
-                       {3 , 16, 16, R.raw.ban2, R.drawable.ui_small_ban2, R.drawable.ui_medium_ban2, R.drawable.ui_big_ban2, R.drawable.ui_huge_ban2} ,
-                     },
-         6
-       ),
-
-  BAN3 (
-         new int[][] {
-                       {3 , 16, 16, R.raw.ban3, R.drawable.ui_small_ban3, R.drawable.ui_medium_ban3, R.drawable.ui_big_ban3, R.drawable.ui_huge_ban3} ,
-                     },
-         6
-       ),
-
-  BAN4 (
-         new int[][] {
-                       {3 , 16, 16, R.raw.ban4, R.drawable.ui_small_ban4, R.drawable.ui_medium_ban4, R.drawable.ui_big_ban4, R.drawable.ui_huge_ban4} ,
-                     },
-         6
-       ),
-
-  SQU1 (
-         new int[][] {
-                       {3 , 24, 24, R.raw.squa1, R.drawable.ui_small_squa1, R.drawable.ui_medium_squa1, R.drawable.ui_big_squa1, R.drawable.ui_huge_squa1} ,
-                     },
-         7
-       ),
-
-  SQU2 (
-         new int[][] {
-                       {3 , 24, 24, R.raw.squa2, R.drawable.ui_small_squa2, R.drawable.ui_medium_squa2, R.drawable.ui_big_squa2, R.drawable.ui_huge_squa2} ,
-                     },
-         7
-       ),
-
-  MIRR (
-         new int[][] {
-                       {2 , 12, 12, R.raw.mirr2, R.drawable.ui_small_mirr2, R.drawable.ui_medium_mirr2, R.drawable.ui_big_mirr2, R.drawable.ui_huge_mirr2} ,
-                       {3 , 16, 17, R.raw.mirr3, R.drawable.ui_small_mirr3, R.drawable.ui_medium_mirr3, R.drawable.ui_big_mirr3, R.drawable.ui_huge_mirr3} ,
-                     },
-         7
-       ),
-  ;
-
-  public static final int NUM_OBJECTS = values().length;
-  public static final int MAX_NUM_OBJECTS;
-  public static final int MAX_LEVEL;
-  public static final int MAX_SCRAMBLE;
-  public static final int MAX_OBJECT_SIZE;
-
-  private final int[] mObjectSizes, mDBLevels, mNumScrambles, mSmallIconIDs, mMediumIconIDs, mBigIconIDs, mHugeIconIDs, mResourceIDs;
-  private final int mRow, mNumSizes;
-
-  private static final ObjectList[] objects;
-  private static int mNumAll;
-  private static int[] mIndices;
-  private static int mColCount, mRowCount;
-
-  static
-    {
-    mNumAll = 0;
-    int num, i = 0;
-    objects = new ObjectList[NUM_OBJECTS];
-    int maxNum     = Integer.MIN_VALUE;
-    int maxLevel   = Integer.MIN_VALUE;
-    int maxScramble= Integer.MIN_VALUE;
-    int maxSize    = Integer.MIN_VALUE;
-
-    for(ObjectList object: ObjectList.values())
-      {
-      objects[i] = object;
-      i++;
-      num = object.mObjectSizes.length;
-      mNumAll += num;
-      if( num> maxNum ) maxNum = num;
-
-      for(int j=0; j<num; j++)
-        {
-        if( object.mNumScrambles[j]> maxScramble ) maxScramble= object.mNumScrambles[j];
-        if( object.mDBLevels[j]    > maxLevel    ) maxLevel   = object.mDBLevels[j];
-        if( object.mObjectSizes[j] > maxSize     ) maxSize    = object.mObjectSizes[j];
-        }
-      }
-
-    MAX_NUM_OBJECTS = maxNum;
-    MAX_LEVEL       = maxLevel;
-    MAX_SCRAMBLE    = maxScramble;
-    MAX_OBJECT_SIZE = maxSize;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void setUpColAndRow()
-    {
-    mIndices = new int[NUM_OBJECTS];
-    mRowCount= 0;
-
-    for(int obj=0; obj<NUM_OBJECTS; obj++)
-      {
-      mIndices[obj] = objects[obj].mRow;
-      if( mIndices[obj]>=mRowCount ) mRowCount = mIndices[obj]+1;
-      }
-
-    mColCount = 0;
-
-    for(int row=0; row<mRowCount; row++)
-      {
-      int numObjects = computeNumObjectsInRow(row);
-      if( numObjects>mColCount ) mColCount = numObjects;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int computeNumObjectsInRow(int row)
-    {
-    int num=0;
-
-    for(int object=0; object<NUM_OBJECTS; object++)
-      {
-      if( objects[object].mRow == row )
-        {
-        num += objects[object].mNumSizes;
-        }
-      }
-
-    return num;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getColumnCount()
-    {
-    if( mIndices==null ) setUpColAndRow();
-
-    return mColCount;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getRowCount()
-    {
-    if( mIndices==null ) setUpColAndRow();
-
-    return mRowCount;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int[] getIndices()
-    {
-    if( mIndices==null ) setUpColAndRow();
-
-    return mIndices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static ObjectList getObject(int ordinal)
-    {
-    return ordinal>=0 && ordinal<NUM_OBJECTS ? objects[ordinal] : CUBE;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int pack(int object, int sizeIndex)
-    {
-    int ret = 0;
-    for(int i=0; i<object; i++) ret += objects[i].mObjectSizes.length;
-
-    return ret+sizeIndex;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int unpackSizeIndex(int number)
-    {
-    int num;
-
-    for(int i=0; i<NUM_OBJECTS; i++)
-      {
-      num = objects[i].mObjectSizes.length;
-      if( number<num ) return number;
-      number -= num;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int unpackObject(int number)
-    {
-    int num;
-
-    for(int i=0; i<NUM_OBJECTS; i++)
-      {
-      num = objects[i].mObjectSizes.length;
-      if( number<num ) return i;
-      number -= num;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int unpackObjectFromString(String obj)
-    {
-    int u = obj.indexOf('_');
-    int l = obj.length();
-
-    if( u>0 )
-      {
-      String name = obj.substring(0,u);
-      int size = Integer.parseInt( obj.substring(u+1,l) );
-
-      for(int i=0; i<NUM_OBJECTS; i++)
-        {
-        if( objects[i].name().equals(name) )
-          {
-          int sizeIndex = getSizeIndex(i,size);
-          return pack(i,sizeIndex);
-          }
-        }
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static String getObjectList()
-    {
-    String name;
-    StringBuilder list = new StringBuilder();
-    int len;
-    int[] sizes;
-
-    for(int i=0; i<NUM_OBJECTS; i++)
-      {
-      sizes = objects[i].mObjectSizes;
-      len   = sizes.length;
-      name  = objects[i].name();
-
-      for(int j=0; j<len; j++)
-        {
-        if( i>0 || j>0 ) list.append(',');
-        list.append(name);
-        list.append('_');
-        list.append(sizes[j]);
-        }
-      }
-
-    return list.toString();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getTotal()
-    {
-    return mNumAll;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getDBLevel(int ordinal, int sizeIndex)
-    {
-    if( ordinal>=0 && ordinal<NUM_OBJECTS )
-      {
-      int num = objects[ordinal].mObjectSizes.length;
-      return sizeIndex>=0 && sizeIndex<num ? objects[ordinal].mDBLevels[sizeIndex] : 0;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getNumScramble(int ordinal, int sizeIndex)
-    {
-    if( ordinal>=0 && ordinal<NUM_OBJECTS )
-      {
-      int num = objects[ordinal].mObjectSizes.length;
-      return sizeIndex>=0 && sizeIndex<num ? objects[ordinal].mNumScrambles[sizeIndex] : 0;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getOrdinal(String name)
-    {
-    for(int i=0; i<NUM_OBJECTS; i++)
-      {
-      if(objects[i].name().equals(name)) return i;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static int getSizeIndex(int ordinal, int size)
-    {
-    if( ordinal>=0 && ordinal<NUM_OBJECTS )
-      {
-      int[] sizes = objects[ordinal].getSizes();
-      int len = sizes.length;
-
-      for(int i=0; i<len; i++)
-        {
-        if( sizes[i]==size ) return i;
-        }
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  ObjectList(int[][] info, int row)
-    {
-    mNumSizes = info.length;
-
-    mObjectSizes  = new int[mNumSizes];
-    mDBLevels     = new int[mNumSizes];
-    mNumScrambles = new int[mNumSizes];
-    mResourceIDs  = new int[mNumSizes];
-    mSmallIconIDs = new int[mNumSizes];
-    mMediumIconIDs= new int[mNumSizes];
-    mBigIconIDs   = new int[mNumSizes];
-    mHugeIconIDs  = new int[mNumSizes];
-
-    for(int i=0; i<mNumSizes; i++)
-      {
-      mObjectSizes[i]  = info[i][0];
-      mDBLevels[i]     = info[i][1];
-      mNumScrambles[i] = info[i][2];
-      mResourceIDs[i]  = info[i][3];
-      mSmallIconIDs[i] = info[i][4];
-      mMediumIconIDs[i]= info[i][5];
-      mBigIconIDs[i]   = info[i][6];
-      mHugeIconIDs[i]  = info[i][7];
-      }
-
-    mRow  = row;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getSizes()
-    {
-    return mObjectSizes;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getIconIDs(int size)
-    {
-    switch(size)
-      {
-      case 0: return mSmallIconIDs;
-      case 1: return mMediumIconIDs;
-      case 2: return mBigIconIDs;
-      case 3: return mHugeIconIDs;
-      }
-
-    return mSmallIconIDs;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getResourceIDs()
-    {
-    return mResourceIDs;
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/ObjectShape.java b/src/main/java/org/distorted/objectlib/ObjectShape.java
deleted file mode 100644
index b50dc607..00000000
--- a/src/main/java/org/distorted/objectlib/ObjectShape.java
+++ /dev/null
@@ -1,124 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class ObjectShape
-  {
-  private final double[][] mVertices;
-  private final int[][] mVertIndices;
-  private final float[][] mBands;
-  private final int[] mBandIndices;
-  private final float[][] mCorners;
-  private final int[] mCornerIndices;
-  private final float[][] mCenters;
-  private final int[] mCenterIndices;
-  private final int mNumComponents;
-  private final float[] mConvexityCenter;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ObjectShape(double[][] vertices, int[][] vertIndices, float[][] bands, int[] bandIndices,
-                     float[][] corners, int[] cornIndices, float[][] centers, int[] centIndices,
-                     int numComponents, float[] convexityCenter)
-    {
-    mVertices        = vertices;
-    mVertIndices     = vertIndices;
-    mBands           = bands;
-    mBandIndices     = bandIndices;
-    mCorners         = corners;
-    mCornerIndices   = cornIndices;
-    mCenters         = centers;
-    mCenterIndices   = centIndices;
-    mNumComponents   = numComponents;
-    mConvexityCenter = convexityCenter;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public double[][] getVertices()
-    {
-    return mVertices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[][] getVertIndices()
-    {
-    return mVertIndices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[][] getBands()
-    {
-    return mBands;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBandIndices()
-    {
-    return mBandIndices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[][] getCorners()
-    {
-    return mCorners;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getCornerIndices()
-    {
-    return mCornerIndices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[][] getCenters()
-    {
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getCenterIndices()
-    {
-    return mCenterIndices;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumComponents()
-    {
-    return mNumComponents;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[] getConvexityCenter()
-    {
-    return mConvexityCenter;
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/ObjectSticker.java b/src/main/java/org/distorted/objectlib/ObjectSticker.java
deleted file mode 100644
index 3ec70849..00000000
--- a/src/main/java/org/distorted/objectlib/ObjectSticker.java
+++ /dev/null
@@ -1,68 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class ObjectSticker
-  {
-  private final float[] mCoords;
-  private final float[] mCurvature;
-  private final float[] mRadii;
-  private final float mStroke;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ObjectSticker(float[] coords, float[] curvature, float[] radii, float stroke)
-    {
-    mCoords    = coords;
-    mCurvature = curvature;
-    mRadii     = radii;
-    mStroke    = stroke;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[] getCoords()
-    {
-    return mCoords;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[] getCurvature()
-    {
-    return mCurvature;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float[] getRadii()
-    {
-    return mRadii;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getStroke()
-    {
-    return mStroke;
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/QuatHelper.java b/src/main/java/org/distorted/objectlib/QuatHelper.java
deleted file mode 100644
index 0efff80d..00000000
--- a/src/main/java/org/distorted/objectlib/QuatHelper.java
+++ /dev/null
@@ -1,163 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class QuatHelper
-  {
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return quat1*quat2
-
-  public static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
-    {
-    float qx = quat1.get0();
-    float qy = quat1.get1();
-    float qz = quat1.get2();
-    float qw = quat1.get3();
-
-    float rx = quat2.get0();
-    float ry = quat2.get1();
-    float rz = quat2.get2();
-    float rw = quat2.get3();
-
-    float tx = rw*qx - rz*qy + ry*qz + rx*qw;
-    float ty = rw*qy + rz*qx + ry*qw - rx*qz;
-    float tz = rw*qz + rz*qw - ry*qx + rx*qy;
-    float tw = rw*qw - rz*qz - ry*qy - rx*qx;
-
-    return new Static4D(tx,ty,tz,tw);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// rotate 'vector' by quat  ( i.e. return quat*vector*(quat^-1) )
-
-  public static Static4D rotateVectorByQuat(Static4D vector, Static4D quat)
-    {
-    float qx = quat.get0();
-    float qy = quat.get1();
-    float qz = quat.get2();
-    float qw = quat.get3();
-
-    Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
-    Static4D tmp = quatMultiply(quat,vector);
-
-    return quatMultiply(tmp,quatInverted);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// rotate 'vector' by quat^(-1)  ( i.e. return (quat^-1)*vector*quat )
-
-  public static Static4D rotateVectorByInvertedQuat(Static4D vector, Static4D quat)
-    {
-    float qx = quat.get0();
-    float qy = quat.get1();
-    float qz = quat.get2();
-    float qw = quat.get3();
-
-    Static4D quatInverted= new Static4D(-qx,-qy,-qz,qw);
-    Static4D tmp = quatMultiply(quatInverted,vector);
-
-    return quatMultiply(tmp,quat);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static Static4D quatFromDrag(float dragX, float dragY)
-    {
-    float axisX = dragY;  // inverted X and Y - rotation axis is perpendicular to (dragX,dragY)
-    float axisY = dragX;  // Why not (-dragY, dragX) ? because Y axis is also inverted!
-    float axisZ = 0;
-    float axisL = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
-
-    if( axisL>0 )
-      {
-      axisX /= axisL;
-      axisY /= axisL;
-      axisZ /= axisL;
-
-      float ratio = axisL;
-      ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
-
-      float cosA = (float)Math.cos(Math.PI*ratio);
-      float sinA = (float)Math.sqrt(1-cosA*cosA);
-
-      return new Static4D(axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
-      }
-
-    return new Static4D(0f, 0f, 0f, 1f);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2)
-    {
-    double ret= (oldX*newX+oldY*newY) / (len1*len2);
-    if( ret<-1.0 ) return -1.0;
-    if( ret> 1.0 ) return  1.0;
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise!
-
-  public static double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2)
-    {
-    double ret= (newX*oldY-oldX*newY) / (len1*len2);
-    if( ret<-1.0 ) return -1.0;
-    if( ret> 1.0 ) return  1.0;
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return quat Q that turns 3D vector A=(ax,ay,az) to another 3D vector B=(bx,by,bz)
-// take care of double-cover by ensuring that always Q.get3() >=0
-
-  public static Static4D retRotationQuat(float ax, float ay, float az, float bx, float by, float bz)
-    {
-    float nx = ay*bz - az*by;
-    float ny = az*bx - ax*bz;
-    float nz = ax*by - ay*bx;
-
-    float sin = (float)Math.sqrt(nx*nx + ny*ny + nz*nz);
-    float cos = ax*bx + ay*by + az*bz;
-
-    if( sin!=0 )
-      {
-      nx /= sin;
-      ny /= sin;
-      nz /= sin;
-      }
-
-    // Why sin<=0 and cos>=0 ?
-    // 0<angle<180 -> 0<halfAngle<90 -> both sin and cos are positive.
-    // But1: quats work counterclockwise -> negate cos.
-    // But2: double-cover, we prefer to have the cos positive (so that unit=(0,0,0,1))
-    // so negate again both cos and sin.
-    float sinHalf =-(float)Math.sqrt((1-cos)/2);
-    float cosHalf = (float)Math.sqrt((1+cos)/2);
-
-    return new Static4D(nx*sinHalf,ny*sinHalf,nz*sinHalf,cosHalf);
-    }
-  }
diff --git a/src/main/java/org/distorted/objectlib/ScrambleState.java b/src/main/java/org/distorted/objectlib/ScrambleState.java
deleted file mode 100644
index 7a53bbd9..00000000
--- a/src/main/java/org/distorted/objectlib/ScrambleState.java
+++ /dev/null
@@ -1,141 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-import java.util.Random;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class ScrambleState
-{
-  private final int mTotal, mNumAxis;
-  private final int[] mNum;
-  private final int[] mInfo;
-  private final int[] mTmp;
-  private final int LEN = 4;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ScrambleState(int[][] axis)
-    {
-    mTmp = new int[LEN];
-
-    mNumAxis = axis.length;
-    mNum = new int[mNumAxis];
-    int total =0;
-
-    for(int i=0; i<mNumAxis; i++)
-      {
-      mNum[i] = axis[i]==null ? 0 : axis[i].length/(LEN-1);
-      total += mNum[i];
-      }
-
-    mTotal = total;
-
-    mInfo = new int[LEN*total];
-    int start = 0;
-
-    for(int i=0; i<mNumAxis; i++)
-      {
-      for(int j=0; j<mNum[i]; j++)
-        {
-        mInfo[LEN*j   + start] = i;
-        mInfo[LEN*j+1 + start] = axis[i][(LEN-1)*j  ];
-        mInfo[LEN*j+2 + start] = axis[i][(LEN-1)*j+1];
-        mInfo[LEN*j+3 + start] = axis[i][(LEN-1)*j+2];
-        }
-
-      start += LEN*mNum[i];
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getIndex(int num, int indexExcluded)
-    {
-    int current= -1;
-
-    for(int i=0; i<mTotal; i++)
-      if( mInfo[LEN*i]!=indexExcluded && ++current==num ) return i;
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getRandom(Random rnd, int indexExcluded, int[][] scrambleTable, int[] numOccurences)
-    {
-    int num=0, total=0, max=0, ax, layer;
-
-    for(int i=0; i<mTotal; i++)
-      {
-      ax = mInfo[LEN*i];
-
-      if( ax!=indexExcluded )
-        {
-        layer = mInfo[LEN*i+1];
-        int value = scrambleTable[ax][layer];
-        if( value>max ) max=value;
-        }
-      }
-
-    for(int i=0; i<mTotal; i++)
-      {
-      ax = mInfo[LEN*i];
-
-      if( ax!=indexExcluded )
-        {
-        layer = mInfo[LEN*i+1];
-        int value = scrambleTable[ax][layer];
-        numOccurences[total] = 1 + max - value + (total==0 ? 0 : numOccurences[total-1]);
-        total++;
-        }
-      }
-
-    float random= rnd.nextFloat()*numOccurences[total-1];
-
-    for(int i=0; i<total; i++)
-      {
-      if( random <= numOccurences[i] )
-        {
-        num=i;
-        break;
-        }
-      }
-
-    int index = getIndex(num,indexExcluded);
-
-    mTmp[0] = mInfo[LEN*index  ];   // axis
-    mTmp[1] = mInfo[LEN*index+1];   // row
-    mTmp[2] = mInfo[LEN*index+2];   // angle
-    mTmp[3] = mInfo[LEN*index+3];   // next state
-
-    scrambleTable[mTmp[0]][mTmp[1]]++;
-
-    return mTmp;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getTotal(int indexExcluded)
-    {
-    return ( indexExcluded>=0 && indexExcluded<mNumAxis ) ? mTotal-mNum[indexExcluded] : mTotal;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/distorted/objectlib/ScrambleStateBandagedEvil.java b/src/main/java/org/distorted/objectlib/ScrambleStateBandagedEvil.java
deleted file mode 100644
index 085956b8..00000000
--- a/src/main/java/org/distorted/objectlib/ScrambleStateBandagedEvil.java
+++ /dev/null
@@ -1,669 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-import java.util.ArrayList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// producer of the ScrambleStateGraph - but only for a single Twisty Puzzle, the 'BandagedEvil'.
-
-public class ScrambleStateBandagedEvil
-{
-  private static final int INVALID_MOVE = -1;
-
-  private static final int CORNER_S = 0;
-  private static final int CORNER_X = 1;
-  private static final int CORNER_Y = 2;
-  private static final int CORNER_Z = 3;
-
-  private static final int CENTER_0 = 0;
-  private static final int CENTER_1 = 1;
-  private static final int CENTER_2 = 2;
-  private static final int CENTER_3 = 3;
-
-  private int mID;
-  private final int[] mMoves;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ScrambleStateBandagedEvil(int id)
-    {
-    mID = id;
-    mMoves = createMoves(mID);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void computeGraph()
-    {
-    ArrayList<ScrambleStateBandagedEvil> graph;
-
-    int id = 0;
-    int id1 = setCenter(id  , CENTER_2, 0);
-    int id2 = setCenter(id1 , CENTER_2, 1);
-    int id3 = setCenter(id2 , CENTER_3, 2);
-    int id4 = setCenter(id3 , CENTER_2, 3);
-
-    int id5 = setCorner(id4 , CORNER_X, 0);
-    int id6 = setCorner(id5 , CORNER_Y, 1);
-    int id7 = setCorner(id6 , CORNER_X, 2);
-    int id8 = setCorner(id7 , CORNER_Z, 3);
-    int id9 = setCorner(id8 , CORNER_Y, 4);
-    int id10= setCorner(id9 , CORNER_Y, 5);
-    int id11= setCorner(id10, CORNER_S, 6);
-    int id12= setCorner(id11, CORNER_Z, 7);
-
-    ScrambleStateBandagedEvil bsg = new ScrambleStateBandagedEvil(id12);
-    graph = new ArrayList<>();
-    graph.add(bsg);
-
-    insertChildren(graph,id12);
-    pruneGraph(graph);
-    remapGraph(graph);
-
-    int num = graph.size();
-    android.util.Log.e("D", "\n"+num+" states\n");
-
-    for(int i=0; i<num; i++)
-      {
-      bsg = graph.get(i);
-      android.util.Log.e("D", formatMoves(bsg));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void insertChildren(ArrayList<ScrambleStateBandagedEvil> list, int id)
-    {
-    ScrambleStateBandagedEvil bsg = findState(list,id);
-
-    if( bsg==null )
-      {
-      android.util.Log.e("D", "error: "+id+" doesn't exist");
-      return;
-      }
-
-    for(int i=0; i<12; i++)
-      {
-      int move = bsg.getMove(i);
-
-      if( move!=INVALID_MOVE )
-        {
-        ScrambleStateBandagedEvil tmp = findState(list,move);
-
-        if( tmp==null )
-          {
-          tmp = new ScrambleStateBandagedEvil(move);
-          list.add(tmp);
-          insertChildren(list,move);
-          }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void pruneGraph(ArrayList<ScrambleStateBandagedEvil> list)
-    {
-    int num = list.size(), numAxis;
-    boolean pruned = false;
-    ScrambleStateBandagedEvil bsg;
-
-    for(int i=0; i<num; i++)
-      {
-      bsg = list.get(i);
-      numAxis = bsg.numAxis();
-
-      if( numAxis<2 )
-        {
-        list.remove(i);
-        int id = bsg.getID();
-        pruned = true;
-        remapID(list,id,INVALID_MOVE);
-        break;
-        }
-      }
-
-    if( pruned ) pruneGraph(list);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void remapGraph(ArrayList<ScrambleStateBandagedEvil> list)
-    {
-    int id, num = list.size();
-    ScrambleStateBandagedEvil bsg;
-
-    for(int i=0; i<num; i++ )
-      {
-      bsg = list.get(i);
-      id = bsg.getID();
-      bsg.setID(i);
-      remapID(list,id,i);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void remapID(ArrayList<ScrambleStateBandagedEvil> list, int id, int newId)
-    {
-    ScrambleStateBandagedEvil bsg;
-    int size = list.size();
-
-    for(int i=0; i<size; i++)
-      {
-      bsg = list.get(i);
-
-      for(int j=0; j<12; j++)
-        {
-        if( bsg.getMove(j)==id ) bsg.setMove(j,newId);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static ScrambleStateBandagedEvil findState(ArrayList<ScrambleStateBandagedEvil> list, int id)
-    {
-    ScrambleStateBandagedEvil bsg;
-    int num = list.size();
-
-    for(int i=0; i<num; i++)
-      {
-      bsg= list.get(i);
-      if( bsg.getID() == id ) return bsg;
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String formatMoves(ScrambleStateBandagedEvil bsg)
-    {
-    String x = getTable(bsg,0);
-    String y = getTable(bsg,3);
-    String z = getTable(bsg,6);
-
-    return "    new ScrambleStateGraph( new int[][] { "+x+", "+y+", "+z+" } ),";
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String getTable(ScrambleStateBandagedEvil sc, int index)
-    {
-    String ret = "";
-
-    if( index==0 || index==3 )
-      {
-      int m0 = sc.getMove(index  );
-      int m1 = sc.getMove(index+1);
-      int m2 = sc.getMove(index+2);
-
-      if( m0==INVALID_MOVE && m1==INVALID_MOVE && m2==INVALID_MOVE ) return formatL("{}");
-
-      if( m0!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m0);
-      if( m1!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m1);
-      if( m2!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m2);
-      }
-    else
-      {
-      int m0 = sc.getMove(index  );
-      int m1 = sc.getMove(index+1);
-      int m2 = sc.getMove(index+2);
-      int m3 = sc.getMove(index+3);
-      int m4 = sc.getMove(index+4);
-      int m5 = sc.getMove(index+5);
-
-      if( m0==INVALID_MOVE && m1==INVALID_MOVE && m2==INVALID_MOVE &&
-          m3==INVALID_MOVE && m4==INVALID_MOVE && m5==INVALID_MOVE  )
-        {
-        return formatL("{}");
-        }
-
-      if( m0!=INVALID_MOVE ) ret += formatRet(ret,0, 1,m0);
-      if( m1!=INVALID_MOVE ) ret += formatRet(ret,0, 2,m1);
-      if( m2!=INVALID_MOVE ) ret += formatRet(ret,0,-1,m2);
-      if( m3!=INVALID_MOVE ) ret += formatRet(ret,2, 1,m3);
-      if( m4!=INVALID_MOVE ) ret += formatRet(ret,2, 2,m4);
-      if( m5!=INVALID_MOVE ) ret += formatRet(ret,2,-1,m5);
-      }
-
-    return formatL("{" + ret + "}");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String formatRet(String str, int row, int angle, int id)
-    {
-    String ret = str.length()!=0 ? ",":"";
-
-    ret += row;
-    ret += angle<0 ? "," : ", ";
-    ret += angle;
-
-         if( id< 10 ) ret += (",  "+id);
-    else if( id<100 ) ret += (", " +id);
-    else              ret += (","  +id);
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static final int LENGTH = 28;
-
-  private static String formatL(String input)
-    {
-    int len = input.length();
-    String ret = input;
-    for(int i=0 ;i<LENGTH-len; i++) ret += " ";
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getID()
-    {
-    return mID;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setID(int id)
-    {
-    mID = id;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getMove(int index)
-    {
-    return (index>=0 && index<12) ? mMoves[index] : -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numAxis()
-    {
-    int num = 0;
-
-    if( mMoves[ 0]!=INVALID_MOVE || mMoves[ 1]!=INVALID_MOVE || mMoves[ 2]!=INVALID_MOVE ) num++;
-    if( mMoves[ 3]!=INVALID_MOVE || mMoves[ 4]!=INVALID_MOVE || mMoves[ 5]!=INVALID_MOVE ) num++;
-    if( mMoves[ 6]!=INVALID_MOVE || mMoves[ 7]!=INVALID_MOVE || mMoves[ 8]!=INVALID_MOVE ) num++;
-    if( mMoves[ 9]!=INVALID_MOVE || mMoves[10]!=INVALID_MOVE || mMoves[11]!=INVALID_MOVE ) num++;
-
-    return num;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setMove(int index, int newMove)
-    {
-    if( index>=0 && index<12 ) mMoves[index] = newMove;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String debug(int id)
-    {
-    int ce0 = getCenter(id,0);
-    int ce1 = getCenter(id,1);
-    int ce2 = getCenter(id,2);
-    int ce3 = getCenter(id,3);
-
-    int co0 = getCorner(id,0);
-    int co1 = getCorner(id,1);
-    int co2 = getCorner(id,2);
-    int co3 = getCorner(id,3);
-    int co4 = getCorner(id,4);
-    int co5 = getCorner(id,5);
-    int co6 = getCorner(id,6);
-    int co7 = getCorner(id,7);
-
-    String center = centerString(ce0) + centerString(ce1) + centerString(ce2) + centerString(ce3);
-    String corner = cornerString(co0) + cornerString(co1) + cornerString(co2) + cornerString(co3) +
-                    cornerString(co4) + cornerString(co5) + cornerString(co6) + cornerString(co7);
-
-    return center + " -" + corner;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String centerString(int center)
-    {
-    return " "+center;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String cornerString(int corner)
-    {
-    switch(corner)
-      {
-      case CORNER_S: return " S";
-      case CORNER_X: return " X";
-      case CORNER_Y: return " Y";
-      case CORNER_Z: return " Z";
-      }
-
-    return "?";
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int[] createMoves(int id)
-    {
-    int[] ret = new int[12];
-
-    boolean moveX  = xPossible(id);
-    boolean moveY  = yPossible(id);
-    boolean moveZ0 = z0Possible(id);
-    boolean moveZ2 = z2Possible(id);
-
-    if( moveX ) createXmoves(id,ret);
-    else        { ret[ 0] = INVALID_MOVE; ret[ 1] = INVALID_MOVE; ret[ 2] = INVALID_MOVE; }
-    if( moveY ) createYmoves(id,ret);
-    else        { ret[ 3] = INVALID_MOVE; ret[ 4] = INVALID_MOVE; ret[ 5] = INVALID_MOVE; }
-    if( moveZ0) createZ0moves(id,ret);
-    else        { ret[ 6] = INVALID_MOVE; ret[ 7] = INVALID_MOVE; ret[ 8] = INVALID_MOVE; }
-    if( moveZ2) createZ2moves(id,ret);
-    else        { ret[ 9] = INVALID_MOVE; ret[10] = INVALID_MOVE; ret[11] = INVALID_MOVE; }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static boolean xPossible(int id)
-    {
-    if( getCorner(id,4)==CORNER_X ) return false;
-    if( getCorner(id,5)==CORNER_X ) return false;
-    if( getCorner(id,6)==CORNER_X ) return false;
-    if( getCorner(id,7)==CORNER_X ) return false;
-
-    if( getCenter(id,1)==CENTER_1 ) return false;
-    if( getCenter(id,2)==CENTER_1 ) return false;
-    if( getCenter(id,3)==CENTER_1 ) return false;
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static boolean yPossible(int id)
-    {
-    if( getCorner(id,2)==CORNER_Y ) return false;
-    if( getCorner(id,3)==CORNER_Y ) return false;
-    if( getCorner(id,6)==CORNER_Y ) return false;
-    if( getCorner(id,7)==CORNER_Y ) return false;
-
-    if( getCenter(id,0)==CENTER_0 ) return false;
-    if( getCenter(id,2)==CENTER_0 ) return false;
-    if( getCenter(id,3)==CENTER_0 ) return false;
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static boolean z0Possible(int id)
-    {
-    if( getCorner(id,0)==CORNER_Z ) return false;
-    if( getCorner(id,2)==CORNER_Z ) return false;
-    if( getCorner(id,4)==CORNER_Z ) return false;
-    if( getCorner(id,6)==CORNER_Z ) return false;
-
-    if( getCenter(id,0)==CENTER_1 ) return false;
-    if( getCenter(id,1)==CENTER_0 ) return false;
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static boolean z2Possible(int id)
-    {
-    if( getCorner(id,1)==CORNER_Z ) return false;
-    if( getCorner(id,3)==CORNER_Z ) return false;
-    if( getCorner(id,5)==CORNER_Z ) return false;
-    if( getCorner(id,7)==CORNER_Z ) return false;
-
-    if( getCenter(id,0)==CENTER_3 ) return false;
-    if( getCenter(id,1)==CENTER_2 ) return false;
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int getCorner(int id, int index)
-    {
-    return (id>>(14-2*index))&3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int getCenter(int id, int index)
-    {
-    return (id>>(22-2*index))&3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int setCorner(int id, int corner, int index)
-    {
-    return id + ((corner-getCorner(id,index))<<(14-2*index));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int setCenter(int id, int center, int index)
-    {
-    return id + ((center-getCenter(id,index))<<(22-2*index));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createXmoves(int id, int[] moves)
-    {
-    int id1 = rotateX(id);
-    moves[0] = id1;
-    int id2 = rotateX(id1);
-    moves[1] = id2;
-    int id3 = rotateX(id2);
-    moves[2] = id3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createYmoves(int id, int[] moves)
-    {
-    int id1 = rotateY(id);
-    moves[3] = id1;
-    int id2 = rotateY(id1);
-    moves[4] = id2;
-    int id3 = rotateY(id2);
-    moves[5] = id3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createZ0moves(int id, int[] moves)
-    {
-    int id1 = rotateZ0(id);
-    moves[6] = id1;
-    int id2 = rotateZ0(id1);
-    moves[7] = id2;
-    int id3 = rotateZ0(id2);
-    moves[8] = id3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createZ2moves(int id, int[] moves)
-    {
-    int id1 = rotateZ2(id);
-    moves[ 9] = id1;
-    int id2 = rotateZ2(id1);
-    moves[10] = id2;
-    int id3 = rotateZ2(id2);
-    moves[11] = id3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotateX(int id)
-    {
-    int newCorner4 = rotCornerX(getCorner(id,5));
-    int newCorner5 = rotCornerX(getCorner(id,7));
-    int newCorner6 = rotCornerX(getCorner(id,4));
-    int newCorner7 = rotCornerX(getCorner(id,6));
-    int newCenter  = rotCenter (getCenter(id,0));
-
-    int id1 = setCorner(id ,newCorner4,4);
-    int id2 = setCorner(id1,newCorner5,5);
-    int id3 = setCorner(id2,newCorner6,6);
-    int id4 = setCorner(id3,newCorner7,7);
-    int id5 = setCenter(id4,newCenter ,0);
-
-    return id5;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotateY(int id)
-    {
-    int newCorner2 = rotCornerY(getCorner(id,6));
-    int newCorner3 = rotCornerY(getCorner(id,2));
-    int newCorner6 = rotCornerY(getCorner(id,7));
-    int newCorner7 = rotCornerY(getCorner(id,3));
-    int newCenter  = rotCenter (getCenter(id,1));
-
-    int id1 = setCorner(id ,newCorner2,2);
-    int id2 = setCorner(id1,newCorner3,3);
-    int id3 = setCorner(id2,newCorner6,6);
-    int id4 = setCorner(id3,newCorner7,7);
-    int id5 = setCenter(id4,newCenter ,1);
-
-    return id5;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotateZ0(int id)
-    {
-    int newCorner0 = rotCornerZ(getCorner(id,2));
-    int newCorner2 = rotCornerZ(getCorner(id,6));
-    int newCorner4 = rotCornerZ(getCorner(id,0));
-    int newCorner6 = rotCornerZ(getCorner(id,4));
-    int newCenter  = rotCenter (getCenter(id,2));
-
-    int id1 = setCorner(id ,newCorner0,0);
-    int id2 = setCorner(id1,newCorner2,2);
-    int id3 = setCorner(id2,newCorner4,4);
-    int id4 = setCorner(id3,newCorner6,6);
-    int id5 = setCenter(id4,newCenter ,2);
-
-    return id5;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotateZ2(int id)
-    {
-    int newCorner1 = rotCornerZ(getCorner(id,3));
-    int newCorner3 = rotCornerZ(getCorner(id,7));
-    int newCorner5 = rotCornerZ(getCorner(id,1));
-    int newCorner7 = rotCornerZ(getCorner(id,5));
-    int newCenter  = rotCenter (getCenter(id,3));
-
-    int id1 = setCorner(id ,newCorner1,1);
-    int id2 = setCorner(id1,newCorner3,3);
-    int id3 = setCorner(id2,newCorner5,5);
-    int id4 = setCorner(id3,newCorner7,7);
-    int id5 = setCenter(id4,newCenter ,3);
-
-    return id5;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotCornerX(int corner)
-    {
-    switch(corner)
-      {
-      case CORNER_S: return CORNER_S;
-      case CORNER_X: android.util.Log.e("DIST", "rotateX: ERROR");
-                     return CORNER_S;
-      case CORNER_Y: return CORNER_Z;
-      case CORNER_Z: return CORNER_Y;
-      }
-
-    return CORNER_S;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotCornerY(int corner)
-    {
-    switch(corner)
-      {
-      case CORNER_S: return CORNER_S;
-      case CORNER_X: return CORNER_Z;
-      case CORNER_Y: android.util.Log.e("DIST", "rotateY: ERROR");
-                     return CORNER_S;
-      case CORNER_Z: return CORNER_X;
-      }
-
-    return CORNER_S;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotCornerZ(int corner)
-    {
-    switch(corner)
-      {
-      case CORNER_S: return CORNER_S;
-      case CORNER_X: return CORNER_Y;
-      case CORNER_Y: return CORNER_X;
-      case CORNER_Z: android.util.Log.e("DIST", "rotateZ: ERROR");
-                     return CORNER_S;
-      }
-
-    return CORNER_S;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int rotCenter(int center)
-    {
-    switch(center)
-      {
-      case CENTER_0: return CENTER_3;
-      case CENTER_1: return CENTER_0;
-      case CENTER_2: return CENTER_1;
-      case CENTER_3: return CENTER_2;
-      }
-
-    return CENTER_0;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/ScrambleStateSquare1.java b/src/main/java/org/distorted/objectlib/ScrambleStateSquare1.java
deleted file mode 100644
index 8969715c..00000000
--- a/src/main/java/org/distorted/objectlib/ScrambleStateSquare1.java
+++ /dev/null
@@ -1,593 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-import java.util.ArrayList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// producer of the ScrambleStateGraph - but only for a single Twisty Puzzle, the 'Square-1'.
-
-public class ScrambleStateSquare1
-{
-  private static final int INVALID_MOVE = -1;
-  private static final int NUM_MOVES = 23;
-
-  private int mDist;
-  private boolean mFresh;
-  private long mID;
-  private final long[] mMoves;
-
-  private final int[][] mPermittedAngles;
-  private final int[] mCornerQuat, mTmp;
-
-  // QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
-  static final int[][] QUAT_MULT = new int[][]
-    {
-      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
-      {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12,},
-      {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13,},
-      {  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14,},
-      {  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15,},
-      {  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16,},
-      {  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17,},
-      {  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18,},
-      {  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19,},
-      {  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20,},
-      { 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,},
-      { 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,},
-      { 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,},
-      { 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,},
-      { 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,},
-      { 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,},
-      { 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,},
-      { 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,},
-      { 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,},
-      { 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,},
-      { 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,},
-      { 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,},
-      { 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11,},
-      { 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,}
-    };
-
-  // quat indices that make corner cubits bandage the puzzle.
-  private static final int[][] BAD_CORNER_QUATS = new int[][]
-    {
-      { 2, 8,17,23},
-      { 5,11,14,20},
-    };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ScrambleStateSquare1(long id, int dist)
-    {
-    mCornerQuat = new int[8];
-    mTmp        = new int[8];
-    mPermittedAngles = new int[2][12];
-
-    mDist = dist;
-    mFresh = true;
-    mID = id;
-    mMoves = createMoves(mID);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setNotFresh()
-    {
-    mFresh = false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isFresh()
-    {
-    return mFresh;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void computeGraph()
-    {
-    ArrayList<ScrambleStateSquare1> graph;
-
-    ScrambleStateSquare1 bsg = new ScrambleStateSquare1(0,0);
-    graph = new ArrayList<>();
-    graph.add(bsg);
-
-android.util.Log.e("D", "INSERTING");
-
-    insertChildren(graph,0);
-
-//android.util.Log.e("D", "PRUNING "+graph.size());
-
-//    pruneGraph(graph);
-
-android.util.Log.e("D", "REMAPPING "+graph.size());
-
-    remapGraph(graph);
-
-    int num = graph.size();
-    android.util.Log.e("D", "\n"+num+" states\n");
-
-    for(int i=0; i<num; i++)
-      {
-      bsg = graph.get(i);
-      android.util.Log.e("D", formatMoves(bsg));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void insertChildren(ArrayList<ScrambleStateSquare1> list, long id)
-    {
-    ScrambleStateSquare1 bsg = findState(list,id);
-
-    if( bsg==null )
-      {
-      android.util.Log.e("D", "error: "+id+" doesn't exist");
-      return;
-      }
-
-    int dist = bsg.mDist;
-    if( dist>6 ) return;
-
-    for(int i=0; i<NUM_MOVES; i++)
-      {
-      long moveID = bsg.getMoveID(i);
-
-      if( moveID!=INVALID_MOVE )
-        {
-        ScrambleStateSquare1 tmp = findState(list,moveID);
-
-        if( tmp==null )
-          {
-          tmp = new ScrambleStateSquare1(moveID,dist+1);
-          list.add(tmp);
-          }
-        }
-      }
-
-    for(int i=0; i<NUM_MOVES; i++)
-      {
-      long moveID = bsg.getMoveID(i);
-
-      if( moveID!=INVALID_MOVE )
-        {
-        ScrambleStateSquare1 tmp = findState(list,moveID);
-
-        if( tmp.isFresh() )
-          {
-          tmp.setNotFresh();
-          insertChildren(list,moveID);
-          }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void pruneGraph(ArrayList<ScrambleStateSquare1> list)
-    {
-    int num = list.size(), numAxis;
-    boolean pruned = false;
-    ScrambleStateSquare1 bsg;
-
-    for(int i=0; i<num; i++)
-      {
-      bsg = list.get(i);
-      numAxis = bsg.numAxis();
-
-      if( numAxis<2 )
-        {
-        list.remove(i);
-        long id = bsg.getID();
-        pruned = true;
-        remapID(list,id,INVALID_MOVE);
-        break;
-        }
-      }
-
-    if( pruned ) pruneGraph(list);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void remapGraph(ArrayList<ScrambleStateSquare1> list)
-    {
-    long id;
-    int num = list.size();
-    ScrambleStateSquare1 bsg;
-
-    for(int i=0; i<num; i++ )
-      {
-      bsg = list.get(i);
-      id = bsg.getID();
-      bsg.setID(i);
-      remapID(list,id,i);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void remapID(ArrayList<ScrambleStateSquare1> list, long id, long newId)
-    {
-    ScrambleStateSquare1 bsg;
-    int size = list.size();
-
-    for(int i=0; i<size; i++)
-      {
-      bsg = list.get(i);
-
-      for(int j=0; j<NUM_MOVES; j++)
-        {
-        if( bsg.getMoveID(j)==id ) bsg.setMoveID(j,newId);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static ScrambleStateSquare1 findState(ArrayList<ScrambleStateSquare1> list, long id)
-    {
-    ScrambleStateSquare1 bsg;
-    int num = list.size();
-
-    for(int i=0; i<num; i++)
-      {
-      bsg= list.get(i);
-      if( bsg.getID() == id ) return bsg;
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String formatMoves(ScrambleStateSquare1 bsg)
-    {
-    String x = getTable(bsg,0);
-    String y = getTable(bsg,11);
-    String z = getTable(bsg,12);
-
-    //return "    new ScrambleStateGraph( new int[][] { "+x+", "+y+", "+z+" } ),";
-
-    long id = bsg.getID();
-
-    return id+" "+x+" , "+y+" , "+z;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String getTable(ScrambleStateSquare1 sc, int index)
-    {
-    String ret = "";
-    long m;
-    int half = (NUM_MOVES)/2;
-
-    if( index==11 )
-      {
-      m = sc.getMoveID(index);
-      if( m==INVALID_MOVE ) return formatL("{}");
-      ret += formatRet(ret,0,1,m);
-      }
-    else
-      {
-      for(int i=0; i<half; i++)
-        {
-        m = sc.getMoveID(index+i);
-        int row = index==0 ? 0:2;
-        int angle = i+1;
-        if( m!=INVALID_MOVE ) ret += formatRet(ret,row,angle,m);
-        }
-      }
-
-    return formatL("{" + ret + "}");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static String formatRet(String str, int row, int angle, long id)
-    {
-    String ret = str.length()!=0 ? "  ,":"  ";
-
-    ret += row;
-    ret += angle<0 ? "," : ",";
-    ret += angle;
-
-         if( id< 10 ) ret += (",  "+id);
-    else if( id<100 ) ret += (", " +id);
-    else              ret += (","  +id);
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static final int LENGTH = 28;
-
-  private static String formatL(String input)
-    {
-    int len = input.length();
-    String ret = input;
-    for(int i=0 ;i<LENGTH-len; i++) ret += " ";
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private long getID()
-    {
-    return mID;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setID(long id)
-    {
-    mID = id;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private long getMoveID(int index)
-    {
-    return (index>=0 && index<NUM_MOVES) ? mMoves[index] : -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void setMoveID(int index, long newID)
-    {
-    if( index>=0 && index<NUM_MOVES ) mMoves[index] = newID;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numAxis()
-    {
-    int num = 0;
-    int half = (NUM_MOVES)/2;
-
-    for(int i=0; i<half; i++)
-      {
-      if( mMoves[i]!=INVALID_MOVE )
-        {
-        num++;
-        break;
-        }
-      }
-
-    for(int i=half; i<NUM_MOVES-1; i++)
-      {
-      if( mMoves[i]!=INVALID_MOVE )
-        {
-        num++;
-        break;
-        }
-      }
-
-    if( mMoves[NUM_MOVES-1]!=INVALID_MOVE ) num++;
-
-    return num;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private long[] createMoves(long id)
-    {
-    long[] ret = new long[NUM_MOVES];
-    fillCornerQuat(id);
-    computePermittedAngles();
-
-    generateUMoves(ret, 0);
-    generateSMoves(ret,11);
-    generateLMoves(ret,12);
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void generateUMoves(long[] table, int index)
-    {
-    for(int angle=1; angle<12; angle++)
-      {
-      table[index+angle-1] = mPermittedAngles[1][angle]==1 ? updateCornerQuats(0,2,angle) : INVALID_MOVE;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void generateLMoves(long[] table, int index)
-    {
-    for(int angle=1; angle<12; angle++)
-      {
-      table[index+angle-1] = mPermittedAngles[0][angle]==1 ? updateCornerQuats(0,0,angle) : INVALID_MOVE;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void generateSMoves(long[] table, int index)
-    {
-    table[index] = updateCornerQuats(1,1,1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void fillCornerQuat(long id)
-    {
-    int NUM_QUATS = 24;
-
-    for(int i=0; i<8; i++)
-      {
-      mCornerQuat[i] = (int)(id%NUM_QUATS);
-      id/=NUM_QUATS;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static long returnID(int[] cornerQuat)
-    {
-    int NUM_QUATS = 24;
-    long mult=1,ret=0;
-
-    for(int i=0; i<8; i++)
-      {
-      ret += mult*cornerQuat[i];
-      mult*=NUM_QUATS;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsUp(int index)
-    {
-    return ((index<4) ^ (mCornerQuat[index]>=12));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsLeft(int index)
-    {
-    int q = mCornerQuat[index];
-
-    switch(index)
-      {
-      case 0:
-      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
-      case 1:
-      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
-      case 2:
-      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
-      case 3:
-      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int makeQuat(int axis,int index)
-    {
-    if( axis==1 ) return 13;
-    if( index<0 ) index+=12;
-    return index;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerBelongs(int index, int axis, int layer)
-    {
-    if( axis==0 )
-      {
-      boolean up = cornerIsUp(index);
-      return ((up && layer==2) || (!up && layer==0));
-      }
-    else
-      {
-      boolean le = cornerIsLeft(index);
-      return ((le && layer==0) || (!le && layer==1));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private long updateCornerQuats(int axis, int layer, int index)
-    {
-    int quat = makeQuat(axis,index);
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerBelongs(corner,axis,layer) )
-        {
-        int curr = mCornerQuat[corner];
-        mTmp[corner] = QUAT_MULT[quat][curr];
-        }
-      else
-        {
-        mTmp[corner] = mCornerQuat[corner];
-        }
-      }
-
-    return returnID(mTmp);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean quatIsBad(int quatIndex, int corner)
-    {
-    int index = (corner%2);
-
-    return ( quatIndex==BAD_CORNER_QUATS[index][0] ||
-             quatIndex==BAD_CORNER_QUATS[index][1] ||
-             quatIndex==BAD_CORNER_QUATS[index][2] ||
-             quatIndex==BAD_CORNER_QUATS[index][3]  );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int isPermittedDo(int angle)
-    {
-    for(int corner=0; corner<8; corner++)
-      {
-      if( !cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= QUAT_MULT[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return 0;
-        }
-      }
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int isPermittedUp(int angle)
-    {
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= QUAT_MULT[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return 0;
-        }
-      }
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computePermittedAngles()
-    {
-    for(int angle=0; angle<12; angle++)
-      {
-      mPermittedAngles[0][angle] = isPermittedDo(angle);
-      mPermittedAngles[1][angle] = isPermittedUp(angle);
-      }
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/Twisty12.java b/src/main/java/org/distorted/objectlib/Twisty12.java
deleted file mode 100644
index 22ea3246..00000000
--- a/src/main/java/org/distorted/objectlib/Twisty12.java
+++ /dev/null
@@ -1,95 +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;
-
-import android.content.res.Resources;
-
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-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
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty12(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-           DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
-    {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, list, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaceColors()
-    {
-    return 12;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getFOV()
-    {
-    return 30;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float getScreenRatio()
-    {
-    return 0.35f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnMultiplier()
-    {
-    return 1.0f;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/Twisty4.java b/src/main/java/org/distorted/objectlib/Twisty4.java
deleted file mode 100644
index 72818ca2..00000000
--- a/src/main/java/org/distorted/objectlib/Twisty4.java
+++ /dev/null
@@ -1,81 +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;
-
-import android.content.res.Resources;
-
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty4 extends TwistyObject
-{
-  private static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_GREEN , COLOR_YELLOW,
-           COLOR_BLUE  , COLOR_RED
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty4(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-          DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
-    {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, list, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaceColors()
-    {
-    return 4;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getFOV()
-    {
-    return 30;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float getScreenRatio()
-    {
-    return 0.88f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnMultiplier()
-    {
-    return getNumLayers()/(SQ6/3);
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/Twisty6.java b/src/main/java/org/distorted/objectlib/Twisty6.java
deleted file mode 100644
index 8c424f85..00000000
--- a/src/main/java/org/distorted/objectlib/Twisty6.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;
-
-import android.content.res.Resources;
-
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty6 extends TwistyObject
-{
-  private static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_YELLOW, COLOR_WHITE,
-           COLOR_BLUE  , COLOR_GREEN,
-           COLOR_RED   , COLOR_ORANGE
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty6(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-          DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
-    {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, list, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaceColors()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getFOV()
-    {
-    return 60;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float getScreenRatio()
-    {
-    return 0.5f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnMultiplier()
-    {
-    return getNumLayers();
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/Twisty8.java b/src/main/java/org/distorted/objectlib/Twisty8.java
deleted file mode 100644
index cbc0cbb8..00000000
--- a/src/main/java/org/distorted/objectlib/Twisty8.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;
-
-import android.content.res.Resources;
-
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class Twisty8 extends TwistyObject
-{
-  private static final int[] FACE_COLORS = new int[]
-         {
-           COLOR_ORANGE, COLOR_VIOLET,
-           COLOR_WHITE , COLOR_BLUE  ,
-           COLOR_YELLOW, COLOR_RED   ,
-           COLOR_GREEN , COLOR_GREY
-         };
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Twisty8(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-          DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
-    {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, list, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaceColors()
-    {
-    return 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getFOV()
-    {
-    return 60;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float getScreenRatio()
-    {
-    return 0.65f;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float returnMultiplier()
-    {
-    return 1.5f;
-    }
-}
diff --git a/src/main/java/org/distorted/objectlib/TwistyObject.java b/src/main/java/org/distorted/objectlib/TwistyObject.java
deleted file mode 100644
index de070a7d..00000000
--- a/src/main/java/org/distorted/objectlib/TwistyObject.java
+++ /dev/null
@@ -1,1314 +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;
-
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-
-import com.google.firebase.crashlytics.FirebaseCrashlytics;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectQuaternion;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.effect.VertexEffectQuaternion;
-import org.distorted.library.effect.VertexEffectRotate;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedLibrary;
-import org.distorted.library.main.DistortedNode;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.mesh.MeshFile;
-import org.distorted.library.mesh.MeshJoined;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.message.EffectListener;
-import org.distorted.library.type.Dynamic1D;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.BuildConfig;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Random;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class TwistyObject extends DistortedNode
-  {
-  public static final int COLOR_YELLOW = 0xffffff00;
-  public static final int COLOR_WHITE  = 0xffffffff;
-  public static final int COLOR_BLUE   = 0xff0000ff;
-  public static final int COLOR_GREEN  = 0xff00bb00;
-  public static final int COLOR_RED    = 0xff990000;
-  public static final int COLOR_ORANGE = 0xffff6200;
-  public static final int COLOR_GREY   = 0xff727c7b;
-  public static final int COLOR_VIOLET = 0xff7700bb;
-  public static final int COLOR_BLACK  = 0xff000000;
-
-  public static final int TEXTURE_HEIGHT = 256;
-  static final int NUM_STICKERS_IN_ROW = 4;
-
-  public static final float SQ2 = (float)Math.sqrt(2);
-  public static final float SQ3 = (float)Math.sqrt(3);
-  public static final float SQ5 = (float)Math.sqrt(5);
-  public static final float SQ6 = (float)Math.sqrt(6);
-
-  private static final float NODE_RATIO = 1.60f;
-  private static final float MAX_SIZE_CHANGE = 1.35f;
-  private static final float MIN_SIZE_CHANGE = 0.75f;
-
-  private static final Static3D CENTER = new Static3D(0,0,0);
-  private static final int POST_ROTATION_MILLISEC = 500;
-
-  protected final int NUM_FACE_COLORS;
-  protected final int NUM_TEXTURES;
-  protected final Cubit[] CUBITS;
-
-  MeshBase[] mMeshes;
-  final Static4D[] OBJECT_QUATS;
-  final int NUM_CUBITS;
-  final int NUM_AXIS;
-  final int NUM_QUATS;
-
-  private final int mNumCubitFaces;
-  private final Static3D[] mAxis;
-  private final float[][] mCuts;
-  private final int[] mNumCuts;
-  private final int mNodeSize;
-  private final float[][] mOrigPos;
-  private final Static3D mNodeScale;
-  private final Static4D mQuat;
-  private final int mNumLayers, mRealSize;
-  private final ObjectList mList;
-  private final DistortedEffects mEffects;
-  private final VertexEffectRotate mRotateEffect;
-  private final Dynamic1D mRotationAngle;
-  private final Static3D mRotationAxis;
-  private final Static3D mObjectScale;
-  private final int[] mQuatDebug;
-  private final float mCameraDist;
-  private final Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
-  private final DistortedTexture mTexture;
-  private final float mInitScreenRatio;
-  private final int mSolvedFunctionIndex;
-  private final boolean mIsBandaged;
-  private float mObjectScreenRatio;
-  private int[][] mSolvedQuats;
-  private int[][] mQuatMult;
-  private int[] mTmpQuats;
-  private int mNumTexRows, mNumTexCols;
-  private int mRotRowBitmap;
-  private int mRotAxis;
-  private MeshBase mMesh;
-  private final TwistyObjectScrambler mScrambler;
-
-  //////////////////// SOLVED1 ////////////////////////
-
-  private int[] mFaceMap;
-  private int[][] mScramble;
-  private int[] mColors;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyObject(int numLayers, int realSize, Static4D quat, DistortedTexture nodeTexture, MeshSquare nodeMesh,
-               DistortedEffects nodeEffects, int[][] moves, ObjectList list, Resources res, int screenWidth)
-    {
-    super(nodeTexture,nodeEffects,nodeMesh);
-
-    mNodeSize = screenWidth;
-
-    resizeFBO(mNodeSize, (int)(NODE_RATIO*mNodeSize));
-
-    mNumLayers = numLayers;
-    mRealSize = realSize;
-    mList = list;
-    mOrigPos = getCubitPositions(mNumLayers);
-    mAxis = getRotationAxis();
-    mInitScreenRatio = getScreenRatio();
-    mObjectScreenRatio = 1.0f;
-    mNumCubitFaces = getNumCubitFaces();
-    mSolvedFunctionIndex = getSolvedFunctionIndex();
-
-    mCuts = getCuts(mNumLayers);
-    mNumCuts = new int[mAxis.length];
-    if( mCuts==null ) for(int i=0; i<mAxis.length; i++) mNumCuts[i] = 0;
-    else              for(int i=0; i<mAxis.length; i++) mNumCuts[i] = mCuts[i].length;
-
-    OBJECT_QUATS = getQuats();
-    NUM_CUBITS  = mOrigPos.length;
-    NUM_FACE_COLORS = getNumFaceColors();
-    NUM_TEXTURES = getNumStickerTypes(mNumLayers)*NUM_FACE_COLORS;
-    NUM_AXIS = mAxis.length;
-    NUM_QUATS = OBJECT_QUATS.length;
-
-    int scramblingType = getScrambleType();
-    ScrambleState[] states = getScrambleStates();
-    mScrambler = new TwistyObjectScrambler(scramblingType,NUM_AXIS,numLayers,states);
-
-    boolean bandaged=false;
-
-    for(int c=0; c<NUM_CUBITS; c++)
-      {
-      if( mOrigPos[c].length>3 )
-        {
-        bandaged=true;
-        break;
-        }
-      }
-
-    mIsBandaged = bandaged;
-
-    mQuatDebug = new int[NUM_CUBITS];
-
-    if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE;
-    if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE;
-
-    mNodeScale= new Static3D(1,NODE_RATIO,1);
-    mQuat = quat;
-
-    mRotationAngle= new Dynamic1D();
-    mRotationAxis = new Static3D(1,0,0);
-    mRotateEffect = new VertexEffectRotate(mRotationAngle, mRotationAxis, CENTER);
-
-    mRotationAngleStatic = new Static1D(0);
-    mRotationAngleMiddle = new Static1D(0);
-    mRotationAngleFinal  = new Static1D(0);
-
-    float scale  = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize;
-    mObjectScale = new Static3D(scale,scale,scale);
-    MatrixEffectScale scaleEffect = new MatrixEffectScale(mObjectScale);
-    MatrixEffectQuaternion quatEffect  = new MatrixEffectQuaternion(quat, CENTER);
-
-    MatrixEffectScale nodeScaleEffect = new MatrixEffectScale(mNodeScale);
-    nodeEffects.apply(nodeScaleEffect);
-
-    mNumTexCols = NUM_STICKERS_IN_ROW;
-    mNumTexRows = (NUM_TEXTURES+1)/NUM_STICKERS_IN_ROW;
-
-    if( mNumTexCols*mNumTexRows < NUM_TEXTURES+1 ) mNumTexRows++;
-
-    CUBITS = new Cubit[NUM_CUBITS];
-    createMeshAndCubits(list,res);
-    createDataStructuresForSolved(numLayers);
-
-    mTexture = new DistortedTexture();
-    mEffects = new DistortedEffects();
-
-    for(int q=0; q<NUM_QUATS; q++)
-      {
-      VertexEffectQuaternion vq = new VertexEffectQuaternion(OBJECT_QUATS[q],CENTER);
-      vq.setMeshAssociation(0,q);
-      mEffects.apply(vq);
-      }
-
-    mEffects.apply(mRotateEffect);
-    mEffects.apply(quatEffect);
-    mEffects.apply(scaleEffect);
-
-    // Now postprocessed effects (the glow when you solve an object) require component centers. In
-    // order for the effect to be in front of the object, we need to set the center to be behind it.
-    getMesh().setComponentCenter(0,0,0,-0.1f);
-
-    attach( new DistortedNode(mTexture,mEffects,mMesh) );
-
-    setupPosition(moves);
-
-    float fov = getFOV();
-    double halfFOV = fov * (Math.PI/360);
-    mCameraDist = 0.5f*NODE_RATIO / (float)Math.tan(halfFOV);
-
-    setProjection( fov, 0.1f);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private Static3D getPos(float[] origPos)
-    {
-    int len = origPos.length/3;
-    float sumX = 0.0f;
-    float sumY = 0.0f;
-    float sumZ = 0.0f;
-
-    for(int i=0; i<len; i++)
-      {
-      sumX += origPos[3*i  ];
-      sumY += origPos[3*i+1];
-      sumZ += origPos[3*i+2];
-      }
-
-    sumX /= len;
-    sumY /= len;
-    sumZ /= len;
-
-    return new Static3D(sumX,sumY,sumZ);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void createMeshAndCubits(ObjectList list, Resources res)
-    {
-    int sizeIndex = ObjectList.getSizeIndex(list.ordinal(),mNumLayers);
-    int resourceID= list.getResourceIDs()[sizeIndex];
-
-    if( resourceID!=0 )
-      {
-      InputStream is = res.openRawResource(resourceID);
-      DataInputStream dos = new DataInputStream(is);
-      mMesh = new MeshFile(dos);
-
-      try
-        {
-        is.close();
-        }
-      catch(IOException e)
-        {
-        android.util.Log.e("meshFile", "Error closing InputStream: "+e.toString());
-        }
-
-      for(int i=0; i<NUM_CUBITS; i++)
-        {
-        CUBITS[i] = new Cubit(this,mOrigPos[i], NUM_AXIS);
-        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
-        }
-
-      if( shouldResetTextureMaps() ) resetAllTextureMaps();
-      }
-    else
-      {
-      MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS];
-
-      for(int i=0; i<NUM_CUBITS; i++)
-        {
-        CUBITS[i] = new Cubit(this,mOrigPos[i], NUM_AXIS);
-        cubitMesh[i] = createCubitMesh(i,mNumLayers);
-        Static3D pos = getPos(mOrigPos[i]);
-        cubitMesh[i].apply(new MatrixEffectMove(pos),1,0);
-        cubitMesh[i].setEffectAssociation(0, CUBITS[i].computeAssociation(), 0);
-        }
-
-      mMesh = new MeshJoined(cubitMesh);
-      resetAllTextureMaps();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private MeshBase createCubitMesh(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( mMeshes==null )
-      {
-      FactoryCubit factory = FactoryCubit.getInstance();
-      factory.clear();
-      mMeshes = new MeshBase[getNumCubitVariants(numLayers)];
-      }
-
-    if( mMeshes[variant]==null )
-      {
-      ObjectShape shape = getObjectShape(cubit,numLayers);
-      FactoryCubit factory = FactoryCubit.getInstance();
-      factory.createNewFaceTransform(shape);
-      mMeshes[variant] = factory.createRoundedSolid(shape);
-      }
-
-    MeshBase mesh = mMeshes[variant].copy(true);
-    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
-    mesh.apply(quat,0xffffffff,0);
-
-    return mesh;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void createDataStructuresForSolved(int numLayers)
-    {
-    mTmpQuats = new int[NUM_QUATS];
-    mSolvedQuats = new int[NUM_CUBITS][];
-
-    for(int c=0; c<NUM_CUBITS; c++)
-      {
-      mSolvedQuats[c] = getSolvedQuats(c,numLayers);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// This is used to build internal data structures for the generic 'isSolved()'
-//
-// if this is an internal cubit (all faces black): return -1
-// if this is a face cubit (one non-black face): return the color index of the only non-black face.
-// Color index, i.e. the index into the 'FACE_COLORS' table.
-// else (edge or corner cubit, more than one non-black face): return -2.
-
-  public int retCubitSolvedStatus(int cubit, int numLayers)
-    {
-    int numNonBlack=0, nonBlackIndex=-1, color;
-
-    for(int face=0; face<mNumCubitFaces; face++)
-      {
-      color = getFaceColor(cubit,face,numLayers);
-
-      if( color<NUM_TEXTURES )
-        {
-        numNonBlack++;
-        nonBlackIndex = color%NUM_FACE_COLORS;
-        }
-      }
-
-    if( numNonBlack==0 ) return -1;
-    if( numNonBlack>=2 ) return -2;
-
-    return nonBlackIndex;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean shouldResetTextureMaps()
-    {
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] buildSolvedQuats(Static3D faceAx, Static4D[] quats)
-    {
-    final float MAXD = 0.0001f;
-    float x = faceAx.get0();
-    float y = faceAx.get1();
-    float z = faceAx.get2();
-    float a,dx,dy,dz,qx,qy,qz;
-    Static4D quat;
-
-    int len = quats.length;
-    int place = 0;
-
-    for(int q=1; q<len; q++)
-      {
-      quat = quats[q];
-      qx = quat.get0();
-      qy = quat.get1();
-      qz = quat.get2();
-
-           if( x!=0.0f ) { a = qx/x; }
-      else if( y!=0.0f ) { a = qy/y; }
-      else               { a = qz/z; }
-
-      dx = a*x-qx;
-      dy = a*y-qy;
-      dz = a*z-qz;
-
-      if( dx>-MAXD && dx<MAXD && dy>-MAXD && dy<MAXD && dz>-MAXD && dz<MAXD )
-        {
-        mTmpQuats[place++] = q;
-        }
-      }
-
-    if( place!=0 )
-      {
-      int[] ret = new int[place];
-      System.arraycopy(mTmpQuats,0,ret,0,place);
-      return ret;
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getMultQuat(int index1, int index2)
-    {
-    if( mQuatMult==null )
-      {
-      mQuatMult = new int[NUM_QUATS][NUM_QUATS];
-
-      for(int i=0; i<NUM_QUATS; i++)
-        for(int j=0; j<NUM_QUATS; j++) mQuatMult[i][j] = -1;
-      }
-
-    if( mQuatMult[index1][index2]==-1 )
-      {
-      mQuatMult[index1][index2] = mulQuat(index1,index2);
-      }
-
-    return mQuatMult[index1][index2];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public boolean isSolved()
-    {
-    if( mSolvedFunctionIndex==0 ) return isSolved0();
-    if( mSolvedFunctionIndex==1 ) return isSolved1();
-    if( mSolvedFunctionIndex==2 ) return isSolved2();
-    if( mSolvedFunctionIndex==3 ) return isSolved3();
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public boolean isSolved0()
-    {
-    int len, q1,q = CUBITS[0].mQuatIndex;
-    int[] solved;
-    boolean skip;
-
-    for(int c=1; c<NUM_CUBITS; c++)
-      {
-      q1 = CUBITS[c].mQuatIndex;
-
-      if( q1==q ) continue;
-
-      skip = false;
-      solved = mSolvedQuats[c];
-      len = solved==null ? 0:solved.length;
-
-      for(int i=0; i<len; i++)
-        {
-        if( q1==getMultQuat(q,solved[i]) )
-          {
-          skip = true;
-          break;
-          }
-        }
-
-      if( !skip ) return false;
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeScramble(int quatNum, int centerNum)
-    {
-    float MAXDIFF = 0.01f;
-    float[] center= mOrigPos[centerNum];
-    Static4D sc = new Static4D(center[0], center[1], center[2], 1.0f);
-    Static4D result = QuatHelper.rotateVectorByQuat(sc,OBJECT_QUATS[quatNum]);
-
-    float x = result.get0();
-    float y = result.get1();
-    float z = result.get2();
-
-    for(int c=0; c<NUM_CUBITS; c++)
-      {
-      float[] cent = mOrigPos[c];
-
-      float qx = cent[0] - x;
-      float qy = cent[1] - y;
-      float qz = cent[2] - z;
-
-      if( qx>-MAXDIFF && qx<MAXDIFF &&
-          qy>-MAXDIFF && qy<MAXDIFF &&
-          qz>-MAXDIFF && qz<MAXDIFF  ) return c;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Dino4 uses this. It is solved if and only if groups of cubits
-// (0,3,7), (1,2,5), (4,8,9), (6,10,11)
-// or
-// (0,1,4), (2,3,6), (5,9,10), (7,8,11)
-// are all the same color.
-
-  public boolean isSolved1()
-    {
-    if( mScramble==null )
-      {
-      mScramble = new int[NUM_QUATS][NUM_CUBITS];
-      mColors   = new int[NUM_CUBITS];
-
-      for(int q=0; q<NUM_QUATS; q++)
-        for(int c=0; c<NUM_CUBITS; c++) mScramble[q][c] = computeScramble(q,c);
-      }
-
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[] { 4, 2, 2, 4, 0, 2, 1, 4, 0, 0, 1, 1 };
-      }
-
-    for(int c=0; c<NUM_CUBITS; c++)
-      {
-      int index = mScramble[CUBITS[c].mQuatIndex][c];
-      mColors[index] = mFaceMap[c];
-      }
-
-    if( mColors[0]==mColors[3] && mColors[0]==mColors[7] &&
-        mColors[1]==mColors[2] && mColors[1]==mColors[5] &&
-        mColors[4]==mColors[8] && mColors[4]==mColors[9]  ) return true;
-
-    if( mColors[0]==mColors[1] && mColors[0]==mColors[4] &&
-        mColors[2]==mColors[3] && mColors[2]==mColors[6] &&
-        mColors[5]==mColors[9] && mColors[5]==mColors[10] ) return true;
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Dino6 uses this. It is solved if and only if:
-//
-// All four 'X' cubits (i.e. those whose longest edge goes along the X axis) are rotated
-// by the same quaternion qX, similarly all four 'Y' cubits by the same qY and all four 'Z'
-// by the same qZ, and then either:
-//
-// a) qX = qY = qZ
-// b) qY = qX*Q2 and qZ = qX*Q8  (i.e. swap of WHITE and YELLOW faces)
-// c) qX = qY*Q2 and qZ = qY*Q10 (i.e. swap of BLUE and GREEN faces)
-// d) qX = qZ*Q8 and qY = qZ*Q10 (i.e. swap of RED and BROWN faces)
-//
-// BUT: cases b), c) and d) are really the same - it's all just a mirror image of the original.
-//
-// X cubits: 0, 2, 8, 10
-// Y cubits: 1, 3, 9, 11
-// Z cubits: 4, 5, 6, 7
-
-  public boolean isSolved2()
-    {
-    int qX = CUBITS[0].mQuatIndex;
-    int qY = CUBITS[1].mQuatIndex;
-    int qZ = CUBITS[4].mQuatIndex;
-
-    if( CUBITS[2].mQuatIndex != qX || CUBITS[8].mQuatIndex != qX || CUBITS[10].mQuatIndex != qX ||
-        CUBITS[3].mQuatIndex != qY || CUBITS[9].mQuatIndex != qY || CUBITS[11].mQuatIndex != qY ||
-        CUBITS[5].mQuatIndex != qZ || CUBITS[6].mQuatIndex != qZ || CUBITS[ 7].mQuatIndex != qZ  )
-      {
-      return false;
-      }
-
-    return ( qX==qY && qX==qZ ) || ( qY==mulQuat(qX,2) && qZ==mulQuat(qX,8) );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Square-2 is solved iff
-// a) all of its cubits are rotated with the same quat
-// b) its two 'middle' cubits are rotated with the same quat, the 6 'front' and 6 'back'
-// edges and corners with this quat multiplied by QUATS[18] (i.e. those are upside down)
-// and all the 12 left and right edges and corners also with the same quat multiplied by
-// QUATS[12] - i.e. also upside down.
-
-  public boolean isSolved3()
-    {
-    int index = CUBITS[0].mQuatIndex;
-
-    if( CUBITS[1].mQuatIndex!=index ) return false;
-
-    boolean solved = true;
-
-    for(int i=2; i<NUM_CUBITS; i++)
-      {
-      if( CUBITS[i].mQuatIndex!=index )
-        {
-        solved = false;
-        break;
-        }
-      }
-
-    if( solved ) return true;
-
-    int indexX = mulQuat(index,12);  // QUATS[12] = 180deg (1,0,0)
-    int indexZ = mulQuat(index,18);  // QUATS[18] = 180deg (0,0,1)
-
-    for(int i= 2; i<        18; i+=2) if( CUBITS[i].mQuatIndex != indexZ ) return false;
-    for(int i= 3; i<        18; i+=2) if( CUBITS[i].mQuatIndex != indexX ) return false;
-    for(int i=18; i<NUM_CUBITS; i+=2) if( CUBITS[i].mQuatIndex != indexX ) return false;
-    for(int i=19; i<NUM_CUBITS; i+=2) if( CUBITS[i].mQuatIndex != indexZ ) return false;
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setObjectRatio(float sizeChange)
-    {
-    mObjectScreenRatio *= (1.0f+sizeChange)/2;
-
-    if( mObjectScreenRatio>MAX_SIZE_CHANGE) mObjectScreenRatio = MAX_SIZE_CHANGE;
-    if( mObjectScreenRatio<MIN_SIZE_CHANGE) mObjectScreenRatio = MIN_SIZE_CHANGE;
-
-    float scale = mObjectScreenRatio*mInitScreenRatio*mNodeSize/mRealSize;
-    mObjectScale.set(scale,scale,scale);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getObjectRatio()
-    {
-    return mObjectScreenRatio*mInitScreenRatio;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int computeRow(float[] pos, int axisIndex)
-    {
-    int ret=0;
-    int len = pos.length / 3;
-    Static3D axis = mAxis[axisIndex];
-    float axisX = axis.get0();
-    float axisY = axis.get1();
-    float axisZ = axis.get2();
-    float casted;
-
-    for(int i=0; i<len; i++)
-      {
-      casted = pos[3*i]*axisX + pos[3*i+1]*axisY + pos[3*i+2]*axisZ;
-      ret |= computeSingleRow(axisIndex,casted);
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeSingleRow(int axisIndex,float casted)
-    {
-    int num = mNumCuts[axisIndex];
-
-    for(int i=0; i<num; i++)
-      {
-      if( casted<mCuts[axisIndex][i] ) return (1<<i);
-      }
-
-    return (1<<num);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean wasRotateApplied()
-    {
-    return mEffects.exists(mRotateEffect.getID());
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean belongsToRotation( int cubit, int axis, int rowBitmap)
-    {
-    return (CUBITS[cubit].getRotRow(axis) & rowBitmap) != 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// note the minus in front of the sin() - we rotate counterclockwise
-// when looking towards the direction where the axis increases in values.
-
-  private Static4D makeQuaternion(int axisIndex, int angleInDegrees)
-    {
-    Static3D axis = mAxis[axisIndex];
-
-    while( angleInDegrees<0 ) angleInDegrees += 360;
-    angleInDegrees %= 360;
-    
-    float cosA = (float)Math.cos(Math.PI*angleInDegrees/360);
-    float sinA =-(float)Math.sqrt(1-cosA*cosA);
-
-    return new Static4D(axis.get0()*sinA, axis.get1()*sinA, axis.get2()*sinA, cosA);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private synchronized void setupPosition(int[][] moves)
-    {
-    if( moves!=null )
-      {
-      Static4D quat;
-      int index, axis, rowBitmap, angle;
-      int[] basic = getBasicAngle();
-
-      for(int[] move: moves)
-        {
-        axis     = move[0];
-        rowBitmap= move[1];
-        angle    = move[2]*(360/basic[axis]);
-        quat     = makeQuaternion(axis,angle);
-
-        for(int j=0; j<NUM_CUBITS; j++)
-          if( belongsToRotation(j,axis,rowBitmap) )
-            {
-            index = CUBITS[j].removeRotationNow(quat);
-            mMesh.setEffectAssociation(j, CUBITS[j].computeAssociation(),index);
-            }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getScrambleType()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int computeBitmapFromRow(int rowBitmap, int axis)
-    {
-    if( mIsBandaged )
-      {
-      int bitmap, initBitmap=0;
-
-      while( initBitmap!=rowBitmap )
-        {
-        initBitmap = rowBitmap;
-
-        for(int cubit=0; cubit<NUM_CUBITS; cubit++)
-          {
-          bitmap = CUBITS[cubit].getRotRow(axis);
-          if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
-          }
-        }
-      }
-
-    return rowBitmap;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Clamp all rotated positions to one of those original ones to avoid accumulating errors.
-// Do so only if minimal Error is appropriately low (shape-shifting puzzles - Square-1)
-
-  void clampPos(float[] pos, int offset)
-    {
-    float currError, minError = Float.MAX_VALUE;
-    int minErrorIndex1 = -1;
-    int minErrorIndex2 = -1;
-
-    float x = pos[offset  ];
-    float y = pos[offset+1];
-    float z = pos[offset+2];
-
-    float xo,yo,zo;
-
-    for(int i=0; i<NUM_CUBITS; i++)
-      {
-      int len = mOrigPos[i].length / 3;
-
-      for(int j=0; j<len; j++)
-        {
-        xo = mOrigPos[i][3*j  ];
-        yo = mOrigPos[i][3*j+1];
-        zo = mOrigPos[i][3*j+2];
-
-        currError = (xo-x)*(xo-x) + (yo-y)*(yo-y) + (zo-z)*(zo-z);
-
-        if( currError<minError )
-          {
-          minError = currError;
-          minErrorIndex1 = i;
-          minErrorIndex2 = j;
-          }
-        }
-      }
-
-    if( minError< 0.1f ) // TODO: 0.1 ?
-      {
-      pos[offset  ] = mOrigPos[minErrorIndex1][3*minErrorIndex2  ];
-      pos[offset+1] = mOrigPos[minErrorIndex1][3*minErrorIndex2+1];
-      pos[offset+2] = mOrigPos[minErrorIndex1][3*minErrorIndex2+2];
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// remember about the double cover or unit quaternions!
-
-  int mulQuat(int q1, int q2)
-    {
-    Static4D result = QuatHelper.quatMultiply(OBJECT_QUATS[q1],OBJECT_QUATS[q2]);
-
-    float rX = result.get0();
-    float rY = result.get1();
-    float rZ = result.get2();
-    float rW = result.get3();
-
-    final float MAX_ERROR = 0.1f;
-    float dX,dY,dZ,dW;
-
-    for(int i=0; i<NUM_QUATS; i++)
-      {
-      dX = OBJECT_QUATS[i].get0() - rX;
-      dY = OBJECT_QUATS[i].get1() - rY;
-      dZ = OBJECT_QUATS[i].get2() - rZ;
-      dW = OBJECT_QUATS[i].get3() - rW;
-
-      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
-          dY<MAX_ERROR && dY>-MAX_ERROR &&
-          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
-          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
-
-      dX = OBJECT_QUATS[i].get0() + rX;
-      dY = OBJECT_QUATS[i].get1() + rY;
-      dZ = OBJECT_QUATS[i].get2() + rZ;
-      dW = OBJECT_QUATS[i].get3() + rW;
-
-      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
-          dY<MAX_ERROR && dY>-MAX_ERROR &&
-          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
-          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getCubitFaceColorIndex(int cubit, int face)
-    {
-    Static4D texMap = mMesh.getTextureMap(NUM_FACE_COLORS*cubit + face);
-
-    int x = (int)(texMap.get0()/texMap.get2());
-    int y = (int)(texMap.get1()/texMap.get3());
-
-    return (mNumTexRows-1-y)*NUM_STICKERS_IN_ROW + x;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size)
-
-  public void createTexture()
-    {
-    Bitmap bitmap;
-
-    Paint paint = new Paint();
-    bitmap = Bitmap.createBitmap( mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
-    Canvas canvas = new Canvas(bitmap);
-
-    paint.setAntiAlias(true);
-    paint.setTextAlign(Paint.Align.CENTER);
-    paint.setStyle(Paint.Style.FILL);
-
-    paint.setColor(COLOR_BLACK);
-    canvas.drawRect(0, 0, mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, paint);
-
-    int face = 0;
-    FactorySticker factory = FactorySticker.getInstance();
-
-    for(int row=0; row<mNumTexRows; row++)
-      for(int col=0; col<mNumTexCols; col++)
-        {
-        if( face>=NUM_TEXTURES ) break;
-        ObjectSticker sticker = retSticker(face);
-        factory.drawRoundedPolygon(canvas, paint, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT, getColor(face%NUM_FACE_COLORS), sticker);
-        face++;
-        }
-
-    if( !mTexture.setTexture(bitmap) )
-      {
-      int max = DistortedLibrary.getMaxTextureSize();
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.log("failed to set texture of size "+bitmap.getWidth()+"x"+bitmap.getHeight()+" max is "+max);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNumLayers()
-    {
-    return mNumLayers;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void continueRotation(float angleInDegrees)
-    {
-    mRotationAngleStatic.set0(angleInDegrees);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Static4D getRotationQuat()
-      {
-      return mQuat;
-      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void recomputeScaleFactor(int scrWidth)
-    {
-    mNodeScale.set(scrWidth,NODE_RATIO*scrWidth,scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void savePreferences(SharedPreferences.Editor editor)
-    {
-    for(int i=0; i<NUM_CUBITS; i++) CUBITS[i].savePreferences(editor);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public synchronized void restorePreferences(SharedPreferences preferences)
-    {
-    boolean error = false;
-
-    for(int i=0; i<NUM_CUBITS; i++)
-      {
-      mQuatDebug[i] = CUBITS[i].restorePreferences(preferences);
-
-      if( mQuatDebug[i]>=0 && mQuatDebug[i]<NUM_QUATS)
-        {
-        CUBITS[i].modifyCurrentPosition(OBJECT_QUATS[mQuatDebug[i]]);
-        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),mQuatDebug[i]);
-        }
-      else
-        {
-        error = true;
-        }
-      }
-
-    if( error )
-      {
-      for(int i=0; i<NUM_CUBITS; i++)
-        {
-        CUBITS[i].solve();
-        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),0);
-        }
-      recordQuatsState("Failed to restorePreferences");
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void recordQuatsState(String message)
-    {
-    StringBuilder quats = new StringBuilder();
-
-    for(int j=0; j<NUM_CUBITS; j++)
-      {
-      quats.append(mQuatDebug[j]);
-      quats.append(" ");
-      }
-
-    if( BuildConfig.DEBUG )
-      {
-      android.util.Log.e("quats" , quats.toString());
-      android.util.Log.e("object", mList.name()+"_"+mNumLayers);
-      }
-    else
-      {
-      Exception ex = new Exception(message);
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.setCustomKey("quats" , quats.toString());
-      crashlytics.setCustomKey("object", mList.name()+"_"+mNumLayers );
-      crashlytics.recordException(ex);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void releaseResources()
-    {
-    mTexture.markForDeletion();
-    mMesh.markForDeletion();
-    mEffects.markForDeletion();
-
-    for(int j=0; j<NUM_CUBITS; j++)
-      {
-      CUBITS[j].releaseResources();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void apply(Effect effect, int position)
-    {
-    mEffects.apply(effect, position);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void remove(long effectID)
-    {
-    mEffects.abortById(effectID);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public synchronized void solve()
-    {
-    for(int i=0; i<NUM_CUBITS; i++)
-      {
-      CUBITS[i].solve();
-      mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(), 0);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void resetAllTextureMaps()
-    {
-    final float ratioW = 1.0f/mNumTexCols;
-    final float ratioH = 1.0f/mNumTexRows;
-    int color, row, col;
-
-    for(int cubit=0; cubit<NUM_CUBITS; cubit++)
-      {
-      final Static4D[] maps = new Static4D[mNumCubitFaces];
-
-      for(int cubitface=0; cubitface<mNumCubitFaces; cubitface++)
-        {
-        color = getFaceColor(cubit,cubitface,mNumLayers);
-        row = (mNumTexRows-1) - color/mNumTexCols;
-        col = color%mNumTexCols;
-        maps[cubitface] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH);
-        }
-
-      mMesh.setTextureMap(maps,mNumCubitFaces*cubit);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void setTextureMap(int cubit, int face, int newColor)
-    {
-    final float ratioW = 1.0f/mNumTexCols;
-    final float ratioH = 1.0f/mNumTexRows;
-    final Static4D[] maps = new Static4D[mNumCubitFaces];
-    int row = (mNumTexRows-1) - newColor/mNumTexCols;
-    int col = newColor%mNumTexCols;
-
-    maps[face] = new Static4D( col*ratioW, row*ratioH, ratioW, ratioH);
-    mMesh.setTextureMap(maps,mNumCubitFaces*cubit);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public synchronized void beginNewRotation(int axis, int row )
-    {
-    if( axis<0 || axis>=NUM_AXIS )
-      {
-      android.util.Log.e("object", "invalid rotation axis: "+axis);
-      return;
-      }
-    if( row<0 || row>=mNumLayers )
-      {
-      android.util.Log.e("object", "invalid rotation row: "+row);
-      return;
-      }
-
-    mRotAxis     = axis;
-    mRotRowBitmap= computeBitmapFromRow( (1<<row),axis );
-    mRotationAngleStatic.set0(0.0f);
-    mRotationAxis.set( mAxis[axis] );
-    mRotationAngle.add(mRotationAngleStatic);
-    mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis* ObjectList.MAX_OBJECT_SIZE) , -1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
-    {
-    if( wasRotateApplied() )
-      {
-      mRotAxis     = axis;
-      mRotRowBitmap= computeBitmapFromRow( rowBitmap,axis );
-
-      mRotationAngleStatic.set0(0.0f);
-      mRotationAxis.set( mAxis[axis] );
-      mRotationAngle.setDuration(durationMillis);
-      mRotationAngle.resetToBeginning();
-      mRotationAngle.add(new Static1D(0));
-      mRotationAngle.add(new Static1D(angle));
-      mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*ObjectList.MAX_OBJECT_SIZE) , -1);
-      mRotateEffect.notifyWhenFinished(listener);
-
-      return mRotateEffect.getID();
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public long finishRotationNow(EffectListener listener, int nearestAngleInDegrees)
-    {
-    if( wasRotateApplied() )
-      {
-      float angle = getAngle();
-      mRotationAngleStatic.set0(angle);
-      mRotationAngleFinal.set0(nearestAngleInDegrees);
-      mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f );
-
-      mRotationAngle.setDuration(POST_ROTATION_MILLISEC);
-      mRotationAngle.resetToBeginning();
-      mRotationAngle.removeAll();
-      mRotationAngle.add(mRotationAngleStatic);
-      mRotationAngle.add(mRotationAngleMiddle);
-      mRotationAngle.add(mRotationAngleFinal);
-      mRotateEffect.notifyWhenFinished(listener);
-
-      return mRotateEffect.getID();
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float getAngle()
-    {
-    int pointNum = mRotationAngle.getNumPoints();
-
-    if( pointNum>=1 )
-      {
-      return mRotationAngle.getPoint(pointNum-1).get0();
-      }
-    else
-      {
-      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
-      crashlytics.log("points in RotationAngle: "+pointNum);
-      return 0;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public synchronized void removeRotationNow()
-    {
-    float angle = getAngle();
-    double nearestAngleInRadians = angle*Math.PI/180;
-    float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
-    float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
-    float axisX = mAxis[mRotAxis].get0();
-    float axisY = mAxis[mRotAxis].get1();
-    float axisZ = mAxis[mRotAxis].get2();
-    Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA);
-
-    mRotationAngle.removeAll();
-    mRotationAngleStatic.set0(0);
-
-    for(int i=0; i<NUM_CUBITS; i++)
-      if( belongsToRotation(i,mRotAxis,mRotRowBitmap) )
-        {
-        int index = CUBITS[i].removeRotationNow(quat);
-        mMesh.setEffectAssociation(i, CUBITS[i].computeAssociation(),index);
-        }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void initializeObject(int[][] moves)
-    {
-    solve();
-    setupPosition(moves);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getCubit(float[] point3D)
-    {
-    float dist, minDist = Float.MAX_VALUE;
-    int currentBest=-1;
-    float multiplier = returnMultiplier();
-
-    point3D[0] *= multiplier;
-    point3D[1] *= multiplier;
-    point3D[2] *= multiplier;
-
-    for(int i=0; i<NUM_CUBITS; i++)
-      {
-      dist = CUBITS[i].getDistSquared(point3D);
-      if( dist<minDist )
-        {
-        minDist = dist;
-        currentBest = i;
-        }
-      }
-
-    return currentBest;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int computeNearestAngle(int axis, float angle, float speed)
-    {
-    int[] basicArray = getBasicAngle();
-    int basicAngle   = basicArray[axis>=basicArray.length ? 0 : axis];
-    int nearestAngle = 360/basicAngle;
-
-    int tmp = (int)((angle+nearestAngle/2)/nearestAngle);
-    if( angle< -(nearestAngle*0.5) ) tmp-=1;
-
-    if( tmp!=0 ) return nearestAngle*tmp;
-
-    return speed> 1.2f ? nearestAngle*(angle>0 ? 1:-1) : 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public float getCameraDist()
-    {
-    return mCameraDist;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getNodeSize()
-    {
-    return mNodeSize;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public ObjectList getObjectList()
-    {
-    return mList;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
-    {
-    mScrambler.randomizeNewScramble(scramble,rnd,curr,total);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract int getFOV();
-  abstract int getNumFaceColors();
-  abstract int getColor(int face);
-  abstract float returnMultiplier();
-  abstract float getScreenRatio();
-
-  protected abstract float[][] getCuts(int numLayers);
-  protected abstract int getNumCubitFaces();
-  protected abstract Static4D[] getQuats();
-  protected abstract float[][] getCubitPositions(int numLayers);
-  protected abstract int getCubitVariant(int cubit, int numLayers);
-  protected abstract int getNumCubitVariants(int numLayers);
-  protected abstract Static4D getQuat(int cubit, int numLayers);
-  protected abstract ObjectShape getObjectShape(int cubit, int numLayers);
-  protected abstract int[] getSolvedQuats(int cubit, int numLayers);
-  protected abstract int getSolvedFunctionIndex();
-  protected abstract ScrambleState[] getScrambleStates();
-  protected abstract int getNumStickerTypes(int numLayers);
-  protected abstract ObjectSticker retSticker(int face);
-  protected abstract int getFaceColor(int cubit, int cubitface, int numLayers);
-
-  public abstract Movement getMovement();
-  public abstract Static3D[] getRotationAxis();
-  public abstract int[] getBasicAngle();
-  public abstract int getObjectName(int numLayers);
-  public abstract int getInventor(int numLayers);
-  public abstract int getComplexity(int numLayers);
-  }
diff --git a/src/main/java/org/distorted/objectlib/TwistyObjectScrambler.java b/src/main/java/org/distorted/objectlib/TwistyObjectScrambler.java
deleted file mode 100644
index 37b31b7d..00000000
--- a/src/main/java/org/distorted/objectlib/TwistyObjectScrambler.java
+++ /dev/null
@@ -1,392 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 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;
-
-import java.util.Random;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyObjectScrambler
-  {
-  private final ScrambleState[] mStates;
-  private final int mType;
-  private final int mNumAxis;
-  private final int mNumLayers;
-
-  // type=0, i.e. main
-  private int mCurrState;
-  private int mIndexExcluded;
-  private int[][] mScrambleTable;
-  private int[] mNumOccurences;
-
-  // type=1, i.e. the exception: Square-1
-  private static final int BASIC_ANGLE = 12;
-  private static final int LAST_SL = 0; // automatic rotations: last rot was a 'slash' i.e. along ROT_AXIS[1]
-  private static final int LAST_UP = 1; // last rot was along ROT_AXIS[0], upper layer and forelast was a slash
-  private static final int LAST_LO = 2; // last rot was along ROT_AXIS[0], lower layer and forelast was a slash
-  private static final int LAST_UL = 3; // two last rots were along ROT_AXIS[0] (so the next must be a slash)
-
-  private int[][] mPermittedAngles;
-  private int[] mCornerQuat;
-  private int mPermittedUp, mPermittedDo;
-  private int[][] mBadCornerQuats;
-  private int mLastRot;
-  private int[][] mQuatMult;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyObjectScrambler(int type, int numAxis, int numLayers, ScrambleState[] states)
-    {
-    mType = type;
-    mNumAxis = numAxis;
-    mNumLayers = numLayers;
-    mStates = states;
-
-    if( mType==1 )
-      {
-      mPermittedAngles = new int[2][BASIC_ANGLE];
-      mCornerQuat = new int[8];
-      mLastRot = LAST_SL;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// QUATS[i]*QUATS[j] = QUATS[QUAT_MULT[i][j]]
-
-  void initializeQuatMult()
-    {
-    mQuatMult = new int[][]
-      {
-        {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,},
-        {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12,},
-        {  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13,},
-        {  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14,},
-        {  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3, 16, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15,},
-        {  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4, 17, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16,},
-        {  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5, 18, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17,},
-        {  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6, 19, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18,},
-        {  8,  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7, 20, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19,},
-        {  9, 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8, 21, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20,},
-        { 10, 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 22, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,},
-        { 11,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 23, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,},
-        { 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,},
-        { 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,},
-        { 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16, 15,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,  3,},
-        { 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17, 16,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,  4,},
-        { 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18, 17,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,  5,},
-        { 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19, 18,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,  6,},
-        { 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20, 19,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,  7,},
-        { 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21, 20,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,  8,},
-        { 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, 21,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,  9,},
-        { 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11, 10,},
-        { 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0, 11,},
-        { 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0,}
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambling()
-    {
-    if( mScrambleTable ==null )
-      {
-      mScrambleTable = new int[mNumAxis][mNumLayers];
-      }
-    if( mNumOccurences ==null )
-      {
-      int max=0;
-
-      for (ScrambleState mState : mStates)
-        {
-        int tmp = mState.getTotal(-1);
-        if (max < tmp) max = tmp;
-        }
-
-      mNumOccurences = new int[max];
-      }
-
-    for(int i=0; i<mNumAxis; i++)
-      for(int j=0; j<mNumLayers; j++) mScrambleTable[i][j] = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  private void randomizeNewScramble0(int[][] scramble, Random rnd, int curr, int total)
-    {
-    if( curr==0 )
-      {
-      mCurrState     = 0;
-      mIndexExcluded =-1;
-      initializeScrambling();
-      }
-
-    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
-
-    scramble[curr][0] = info[0];
-    scramble[curr][1] = info[1];
-    scramble[curr][2] = info[2];
-
-    mCurrState     = info[3];
-    mIndexExcluded = info[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsUp(int index)
-    {
-    return ((index<4) ^ (mCornerQuat[index]>=12));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerIsLeft(int index)
-    {
-    int q = mCornerQuat[index];
-
-    switch(index)
-      {
-      case 0:
-      case 4: return ((q>=3 && q<= 7) || (q>=18 && q<=22));
-      case 1:
-      case 5: return ((q>=6 && q<=10) || (q>=15 && q<=19));
-      case 2:
-      case 6: return ((q==0 || q==1 || (q>=9 && q<=11)) || (q>=12 && q<=16));
-      case 3:
-      case 7: return ((q>=0 && q<=4) || (q==12 || q==13 || (q>=21 && q<=23)));
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean quatIsBad(int quatIndex, int corner)
-    {
-    if( mBadCornerQuats ==null )
-      {
-      // quat indices that make corner cubits bandage the puzzle.
-      mBadCornerQuats = new int[][] { { 2, 8,17,23}, { 5,11,14,20} };
-      }
-
-    int index = (corner%2);
-
-    return ( quatIndex== mBadCornerQuats[index][0] ||
-             quatIndex== mBadCornerQuats[index][1] ||
-             quatIndex== mBadCornerQuats[index][2] ||
-             quatIndex== mBadCornerQuats[index][3]  );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isPermittedDo(int angle)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( !cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= mQuatMult[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return false;
-        }
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean isPermittedUp(int angle)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerIsUp(corner) )
-        {
-        int currQuat = mCornerQuat[corner];
-        int finalQuat= mQuatMult[angle][currQuat];
-        if( quatIsBad(finalQuat,corner) ) return false;
-        }
-      }
-
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void computePermittedAngles()
-    {
-    mPermittedDo = 0;
-
-    for(int angle=0; angle<BASIC_ANGLE; angle++)
-      {
-      if( isPermittedDo(angle ) ) mPermittedAngles[0][mPermittedDo++] = angle;
-      }
-
-    mPermittedUp = 0;
-
-    for(int angle=0; angle<BASIC_ANGLE; angle++)
-      {
-      if( isPermittedUp(angle ) ) mPermittedAngles[1][mPermittedUp++] = angle;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNextAngle(Random rnd, int layer)
-    {
-    int num = layer==0 ? mPermittedDo:mPermittedUp;
-    int index = rnd.nextInt(num);
-    int angle = mPermittedAngles[layer][index];
-    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNextAngleNotZero(Random rnd, int layer)
-    {
-    int num = layer==0 ? mPermittedDo:mPermittedUp;
-    int index = rnd.nextInt(num-1);
-    int angle = mPermittedAngles[layer][index+1];
-    return angle<BASIC_ANGLE/2 ? -angle : BASIC_ANGLE-angle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int makeQuat(int axis,int index)
-    {
-    if( axis==1 ) return 13;
-    if( index<0 ) index+=12;
-    return index;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private boolean cornerBelongs(int index, int axis, int layer)
-    {
-    if( axis==0 )
-      {
-      boolean up = cornerIsUp(index);
-      return ((up && layer==2) || (!up && layer==0));
-      }
-    else
-      {
-      boolean le = cornerIsLeft(index);
-      return ((le && layer==0) || (!le && layer==1));
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void updateCornerQuats(int[] rotInfo)
-    {
-    if( mQuatMult==null ) initializeQuatMult();
-
-    int axis = rotInfo[0];
-    int layer= rotInfo[1];
-    int index=-rotInfo[2];
-
-    int quat = makeQuat(axis,index);
-
-    for(int corner=0; corner<8; corner++)
-      {
-      if( cornerBelongs(corner,axis,layer) )
-        {
-        int curr = mCornerQuat[corner];
-        mCornerQuat[corner] = mQuatMult[quat][curr];
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void randomizeNewScramble1(int[][] scramble, Random rnd, int curr, int total)
-    {
-    int layer, nextAngle;
-
-    if( curr==0 )
-      {
-      for(int corner=0; corner<8; corner++) mCornerQuat[corner] = 0;
-      mLastRot = rnd.nextInt(4);
-      computePermittedAngles();
-      }
-
-    switch(mLastRot)
-      {
-      case LAST_SL: layer = rnd.nextInt(2);
-                    nextAngle = getNextAngle(rnd,layer);
-
-                    if( nextAngle==0 )
-                      {
-                      layer = 1-layer;
-                      nextAngle = getNextAngleNotZero(rnd,layer);
-                      }
-
-                    scramble[curr][0] = 0;
-                    scramble[curr][1] = 2*layer;
-                    scramble[curr][2] = nextAngle;
-                    mLastRot = layer==0 ? LAST_LO : LAST_UP;
-                    updateCornerQuats(scramble[curr]);
-                    break;
-      case LAST_LO:
-      case LAST_UP: layer = mLastRot==LAST_LO ? 1:0;
-                    nextAngle = getNextAngle(rnd,layer);
-
-                    if( nextAngle!=0 )
-                      {
-                      scramble[curr][0] = 0;
-                      scramble[curr][1] = 2*layer;
-                      scramble[curr][2] = nextAngle;
-                      updateCornerQuats(scramble[curr]);
-                      mLastRot = LAST_UL;
-                      }
-                    else
-                      {
-                      scramble[curr][0] = 1;
-                      scramble[curr][1] = rnd.nextInt(2);
-                      scramble[curr][2] = 1;
-                      mLastRot = LAST_SL;
-                      updateCornerQuats(scramble[curr]);
-                      computePermittedAngles();
-                      }
-
-                    break;
-      case LAST_UL: scramble[curr][0] = 1;
-                    scramble[curr][1] = rnd.nextInt(2);
-                    scramble[curr][2] = 1;
-                    mLastRot = LAST_SL;
-                    updateCornerQuats(scramble[curr]);
-                    computePermittedAngles();
-                    break;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
-    {
-    if( mType==0 ) randomizeNewScramble0(scramble, rnd, curr, total);
-    if( mType==1 ) randomizeNewScramble1(scramble, rnd, curr, total);
-    }
-  }
diff --git a/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java b/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java
deleted file mode 100644
index 037fa7bb..00000000
--- a/src/main/java/org/distorted/objects/TwistyBandaged2Bar.java
+++ /dev/null
@@ -1,128 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyBandaged2Bar extends TwistyBandagedAbstract
-{
-  public TwistyBandaged2Bar(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN2, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { {}                                          , {0,1,1, 0,-1,1, 2,1,2, 2,-1,2}, {} }),
-        new ScrambleState( new int[][] { {0,-1,1, 0,1,1, 0,2,1, 2,-1,1, 2,1,1, 2,2,1}, {0,2,1, 2,2,1}                , {} }),
-        new ScrambleState( new int[][] { {}, {0,2,2, 2,2,2}                , {0,-1,2, 0,1,2, 0,2,2, 2,-1,2, 2,1,2, 2,2,2} })
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[][] getPositions()
-    {
-    if( POSITIONS==null )
-      {
-      POSITIONS = new float[][]
-        {
-         { 0.0f, +1.0f,  1.0f, 0.0f, +1.0f,  0.0f, 0.0f, +1.0f, -1.0f},
-         {-1.0f, -1.0f,  0.0f, 0.0f, -1.0f,  0.0f, 1.0f, -1.0f,  0.0f},
-         {-1.0f, +1.0f, +1.0f},
-         {-1.0f, +1.0f,  0.0f},
-         {-1.0f, +1.0f, -1.0f},
-         {-1.0f,  0.0f, +1.0f},
-         {-1.0f,  0.0f,  0.0f},
-         {-1.0f,  0.0f, -1.0f},
-         {-1.0f, -1.0f, +1.0f},
-         {-1.0f, -1.0f, -1.0f},
-         {+1.0f, +1.0f, +1.0f},
-         {+1.0f, +1.0f,  0.0f},
-         {+1.0f, +1.0f, -1.0f},
-         {+1.0f,  0.0f, +1.0f},
-         {+1.0f,  0.0f,  0.0f},
-         {+1.0f,  0.0f, -1.0f},
-         {+1.0f, -1.0f, +1.0f},
-         {+1.0f, -1.0f, -1.0f},
-         { 0.0f,  0.0f, +1.0f},
-         { 0.0f, -1.0f, +1.0f},
-         { 0.0f,  0.0f, -1.0f},
-         { 0.0f, -1.0f, -1.0f}
-        };
-      }
-
-    return POSITIONS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int[] getQuatIndices()
-    {
-    if( QUAT_INDICES==null )
-      {
-      QUAT_INDICES = new int[] { 2 };
-      }
-
-    return QUAT_INDICES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.bandaged_2bar;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.bandaged_2bar_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 8;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java b/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
deleted file mode 100644
index f7edb245..00000000
--- a/src/main/java/org/distorted/objects/TwistyBandaged3Plate.java
+++ /dev/null
@@ -1,135 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyBandaged3Plate extends TwistyBandagedAbstract
-{
-  public TwistyBandaged3Plate(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                              DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN3, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {{ 2,-1, 1, 2, 1, 6                  }, { 0,-1, 5, 0, 1, 3                  }, { 2,-1, 2, 2, 1, 4                  }} ),
-        new ScrambleState( new int[][] {{ 2, 1, 0                           }, {                                   }, { 2, 1,10, 2, 2, 7                  }} ),
-        new ScrambleState( new int[][] {{                                   }, { 0,-1,11, 0, 2, 8                  }, { 2, 1, 0                           }} ),
-        new ScrambleState( new int[][] {{ 2, 1,12, 2, 2, 9                  }, { 0,-1, 0                           }, {                                   }} ),
-        new ScrambleState( new int[][] {{ 2,-1,10, 2, 2,13                  }, {                                   }, { 2,-1, 0                           }} ),
-        new ScrambleState( new int[][] {{                                   }, { 0, 1, 0                           }, { 2,-1,11, 2, 2,14                  }} ),
-        new ScrambleState( new int[][] {{ 2,-1, 0                           }, { 0, 1,12, 0, 2,15                  }, {                                   }} ),
-        new ScrambleState( new int[][] {{                                   }, { 2,-2, 7, 2,-1, 7, 2, 1, 7, 2, 2, 7}, { 2,-1,10, 2, 2, 1                  }} ),
-        new ScrambleState( new int[][] {{ 0,-2, 8, 0,-1, 8, 0, 1, 8, 0, 2, 8}, { 0, 1,11, 0, 2, 2                  }, {                                   }} ),
-        new ScrambleState( new int[][] {{ 2,-1,12, 2, 2, 3                  }, {                                   }, { 0,-2, 9, 0,-1, 9, 0, 1, 9, 0, 2, 9}} ),
-        new ScrambleState( new int[][] {{ 2,-1,13, 2, 1, 4                  }, { 2,-2,10, 2,-1,10, 2, 1,10, 2, 2,10}, { 2,-1, 1, 2, 1, 7                  }} ),
-        new ScrambleState( new int[][] {{ 0,-2,11, 0,-1,11, 0, 1,11, 0, 2,11}, { 0,-1, 8, 0, 1, 2                  }, { 2,-1,14, 2, 1, 5                  }} ),
-        new ScrambleState( new int[][] {{ 2,-1, 3, 2, 1, 9                  }, { 0,-1, 6, 0, 1,15                  }, { 0,-2,12, 0,-1,12, 0, 1,12, 0, 2,12}} ),
-        new ScrambleState( new int[][] {{ 2, 1,10, 2, 2, 4                  }, { 2,-2,13, 2,-1,13, 2, 1,13, 2, 2,13}, {                                   }} ),
-        new ScrambleState( new int[][] {{ 0,-2,14, 0,-1,14, 0, 1,14, 0, 2,14}, {                                   }, { 2, 1,11, 2, 2, 5                  }} ),
-        new ScrambleState( new int[][] {{                                   }, { 0,-1,12, 0, 2, 6                  }, { 0,-2,15, 0,-1,15, 0, 1,15, 0, 2,15}} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[][] getPositions()
-    {
-    if( POSITIONS==null )
-      {
-      POSITIONS = new float[][]
-        {
-          {-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
-          { 1.0f,  0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  0.0f},
-          {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f},
-          { 1.0f,  1.0f,  1.0f},
-          { 1.0f,  0.0f,  1.0f},
-          { 1.0f, -1.0f,  1.0f},
-          {-1.0f, -1.0f,  1.0f},
-          { 0.0f, -1.0f,  1.0f},
-          { 1.0f, -1.0f,  0.0f},
-          { 1.0f, -1.0f, -1.0f},
-          {-1.0f,  1.0f, -1.0f},
-          {-1.0f,  1.0f,  0.0f},
-          { 0.0f,  1.0f, -1.0f},
-          { 0.0f,  1.0f,  0.0f},
-          {-1.0f,  0.0f, -1.0f},
-          {-1.0f,  0.0f,  0.0f},
-          { 0.0f,  0.0f, -1.0f}
-        };
-      }
-    return POSITIONS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int[] getQuatIndices()
-    {
-    if( QUAT_INDICES==null )
-      {
-      QUAT_INDICES = new int[] { 1,3 };
-      }
-
-    return QUAT_INDICES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.bandaged_3plate;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.bandaged_3plate_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 8;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
deleted file mode 100644
index 6aa795fd..00000000
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ /dev/null
@@ -1,483 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract class TwistyBandagedAbstract extends Twisty6
-{
-  // the three rotation axis of a 3x3 Cube. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(1,0,0),
-           new Static3D(0,1,0),
-           new Static3D(0,0,1)
-         };
-
-  private static final int[][] mDimensions = new int[][]
-        {
-         {1,1,1},  // has to be X>=Z>=Y so that all
-         {2,1,1},  // the faces are horizontal
-         {3,1,1},
-         {2,1,2},
-         {2,2,2}
-        };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
-      };
-
-  private static final int NUM_STICKERS = 4;
-
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private ObjectSticker[] mStickers;
-  private Static4D[] mInitQuats;
-  private int[][] mAxisMap;
-  private int[][] mFaceMap;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private Movement mMovement;
-  ScrambleState[] mStates;
-  float[][] POSITIONS;
-  int[] QUAT_INDICES;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract float[][] getPositions();
-  abstract int[] getQuatIndices();
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
-         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
-
-         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
-         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
-
-         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
-         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumCubits()
-    {
-    return getPositions().length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] getCubitPosition(int cubit)
-    {
-    float[][] pos = getPositions();
-
-    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getQuatIndex(int cubit)
-    {
-    int[] indices = getQuatIndices();
-    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    final int[][] vert_indices =
-      {
-        {2,3,1,0},
-        {7,6,4,5},
-        {4,0,1,5},
-        {7,3,2,6},
-        {6,2,0,4},
-        {3,7,5,1},
-      };
-
-    float defHeight = 0.048f;
-    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
-    float[][] corners = new float[][] { {0.04f,0.15f} };
-    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
-
-    int X = mDimensions[variant][0];
-    int Y = mDimensions[variant][1];
-    int Z = mDimensions[variant][2];
-
-    int maxXY = Math.max(X,Y);
-    int maxXZ = Math.max(X,Z);
-    int maxYZ = Math.max(Y,Z);
-
-    double[][] vertices =
-      {
-        {+0.5f*X,+0.5f*Y,+0.5f*Z},
-        {+0.5f*X,+0.5f*Y,-0.5f*Z},
-        {+0.5f*X,-0.5f*Y,+0.5f*Z},
-        {+0.5f*X,-0.5f*Y,-0.5f*Z},
-        {-0.5f*X,+0.5f*Y,+0.5f*Z},
-        {-0.5f*X,+0.5f*Y,-0.5f*Z},
-        {-0.5f*X,-0.5f*Y,+0.5f*Z},
-        {-0.5f*X,-0.5f*Y,-0.5f*Z}
-      };
-
-    float[][] bands= new float[][]
-      {
-        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
-        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
-        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
-      };
-
-    float[][] centers = new float[][]
-      {
-        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
-        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
-        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
-        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
-        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
-        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
-        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
-        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
-      };
-
-    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mInitQuats ==null )
-      {
-      mInitQuats = new Static4D[]
-        {
-        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
-        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
-        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
-        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
-        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
-        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
-        };
-      }
-
-    return mInitQuats[getQuatIndex(cubit)];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return mDimensions.length;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    float[][] pos = getPositions();
-
-    if( cubit>=0 && cubit<pos.length )
-      {
-      int numPoints = pos[cubit].length/3;
-      return numPoints==8 ? 4 : numPoints-1;
-      }
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      mStickers = new ObjectSticker[NUM_STICKERS];
-
-      int[][] stickerDimensions = new int[][]
-        {
-         {1,1},  // dimensions of the faces of
-         {2,1},  // the cuboids defined in mDimensions
-         {3,1},
-         {2,2}
-        };
-
-      for(int s=0; s<NUM_STICKERS; s++)
-        {
-        float X = stickerDimensions[s][0];
-        float Y = stickerDimensions[s][1];
-        float MAX = Math.max(X,Y);
-        X /= (2*MAX);
-        Y /= (2*MAX);
-
-        float R = 0.10f / MAX;
-        float S = 0.08f / MAX;
-        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
-        float[] radii = new float[] {R,R,R,R};
-        mStickers[s] = new ObjectSticker(coords,null,radii,S);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int size)
-    {
-    int numCubits = getNumCubits();
-    float[][] tmp = new float[numCubits][];
-
-    for(int cubit=0; cubit<numCubits; cubit++)
-      {
-      tmp[cubit] = getCubitPosition(cubit);
-      }
-
-    return tmp;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( numLayers<2 ) return null;
-
-    if( mCuts==null )
-      {
-      mCuts = new float[3][numLayers-1];
-
-      for(int i=0; i<numLayers-1; i++)
-        {
-        float cut = (2-numLayers)*0.5f + i;
-        mCuts[0][i] = cut;
-        mCuts[1][i] = cut;
-        mCuts[2][i] = cut;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return NUM_STICKERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int retStickerIndex(int horzSize, int vertSize)
-    {
-    switch(horzSize)
-      {
-      case 1: return 0;
-      case 2: return vertSize==1 ? 1:3;
-      case 3: return 2;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getStickerIndex(int cubitface, int[] dim)
-    {
-    switch(cubitface)
-      {
-      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
-      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
-      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mFaceMap==null )
-      {
-      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
-      mFaceMap = new int[][]
-          {
-              {0,0,5,2,4,2},
-              {1,1,4,3,5,3},
-              {2,4,2,1,1,4},
-              {3,5,3,0,0,5},
-              {4,3,0,4,3,0},
-              {5,2,1,5,2,1}
-          };
-      }
-
-    if( mAxisMap==null )
-      {
-      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
-      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
-      }
-
-    int variant      = getCubitVariant(cubit,numLayers);
-    int[] dim        = mDimensions[variant];
-    float[] pos      = getCubitPosition(cubit);
-    int stickerIndex = getStickerIndex(cubitface,dim);
-    int quatIndex    = getQuatIndex(cubit);
-    int face         = mFaceMap[cubitface][quatIndex];
-    int multiplier   = (face%2)==0 ? 1:-1;
-    int posIndex     = face/2;
-    int dimIndex     = mAxisMap[posIndex][quatIndex];
-
-    float position = 0.0f;
-    int len = pos.length/3;
-    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
-    position /= len;
-
-    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
-
-    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
-    return mBasicAngle;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java b/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
deleted file mode 100644
index 9e0ab7e2..00000000
--- a/src/main/java/org/distorted/objects/TwistyBandagedEvil.java
+++ /dev/null
@@ -1,259 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyBandagedEvil extends TwistyBandagedAbstract
-{
-  public TwistyBandagedEvil(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN4, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {{2, 1,  1,2,-1,  2}         , {2, 2,142,2,-1, 28}         , {0, 1,114}          }),   //0
-        new ScrambleState( new int[][] {{2, 2,  2}                  , {2,-1,143}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 2,  1}                  , {}                          , {0, 1,  3,0, 2, 47} }),
-        new ScrambleState( new int[][] {{2, 1,  4}                  , {2, 1,132,2,-1,131}         , {0, 1, 47,0,-1,  2} }),
-        new ScrambleState( new int[][] {{2,-1,  3}                  , {2, 1,  5,2,-1,  6}         , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,  6,2,-1,  4}         , {0, 1, 51}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,  4,2, 2,  5}         , {2, 2,  7,2,-1, 80} }),
-        new ScrambleState( new int[][] {{2, 2,  8}                  , {}                          , {2, 1, 80,2, 2,  6} }),
-        new ScrambleState( new int[][] {{2, 2,  7}                  , {}                          , {0,-1,  9}          }),
-        new ScrambleState( new int[][] {{2, 1, 10,2, 2, 11,2,-1, 12}, {}                          , {0, 1,  8}          }),
-        new ScrambleState( new int[][] {{2, 1, 11,2, 2, 12,2,-1,  9}, {}                          , {0,-1,118}          }),   //10
-        new ScrambleState( new int[][] {{2, 1, 12,2, 2,  9,2,-1, 10}, {}                          , {2, 1, 77}          }),
-        new ScrambleState( new int[][] {{2, 1,  9,2, 2, 10,2,-1, 11}, {}                          , {2, 1, 13,2, 2,143} }),
-        new ScrambleState( new int[][] {{2, 1, 14,2, 2, 15,2,-1, 16}, {2, 1, 57,2,-1, 58}         , {2, 1,143,2,-1, 12} }),
-        new ScrambleState( new int[][] {{2, 1, 15,2, 2, 16,2,-1, 13}, {}                          , {2, 1, 41}          }),
-        new ScrambleState( new int[][] {{2, 1, 16,2, 2, 13,2,-1, 14}, {}                          , {0, 1, 82}          }),
-        new ScrambleState( new int[][] {{2, 1, 13,2, 2, 14,2,-1, 15}, {2, 1, 17,2,-1, 18}         , {0, 1,111,0,-1,115} }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 18,2,-1, 16}         , {0,-1,139}          }),
-        new ScrambleState( new int[][] {{2, 1, 19,2,-1, 20}         , {2, 1, 16,2, 2, 17}         , {2, 1,142}          }),
-        new ScrambleState( new int[][] {{2, 2, 20,2,-1, 18}         , {}                          , {2, 1, 39,2, 2,140} }),
-        new ScrambleState( new int[][] {{2, 1, 18,2, 2, 19}         , {2, 1, 21}                  , {}                  }),   //20
-        new ScrambleState( new int[][] {{}                          , {2,-1, 20}                  , {0,-1, 22}          }),
-        new ScrambleState( new int[][] {{2, 2, 23,2,-1, 24}         , {}                          , {0, 1, 21}          }),
-        new ScrambleState( new int[][] {{2, 1, 24,2, 2, 22}         , {}                          , {2, 1, 92}          }),
-        new ScrambleState( new int[][] {{2, 1, 22,2,-1, 23}         , {}                          , {0, 1, 25}          }),
-        new ScrambleState( new int[][] {{2, 1, 26,2, 2, 27}         , {}                          , {0,-1, 24}          }),
-        new ScrambleState( new int[][] {{2, 1, 27,2,-1, 25}         , {2, 1, 74}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 2, 25,2,-1, 26}         , {}                          , {2, 1, 28,2, 2,124} }),
-        new ScrambleState( new int[][] {{2, 1, 29,2, 2, 30,2,-1, 31}, {2,-1,142}                  , {2, 1,124,2,-1, 27} }),
-        new ScrambleState( new int[][] {{2, 1, 30,2, 2, 31,2,-1, 28}, {}                          , {2, 1,141}          }),
-        new ScrambleState( new int[][] {{2, 1, 31,2, 2, 28,2,-1, 29}, {}                          , {0, 1,130}          }),   //30
-        new ScrambleState( new int[][] {{2, 1, 28,2, 2, 29,2,-1, 30}, {2, 1, 32,2,-1, 33}         , {0, 1, 89,0,-1, 90} }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 33,2,-1, 31}         , {0,-1,137}          }),
-        new ScrambleState( new int[][] {{2, 1, 34}                  , {2, 1, 31,2, 2, 32}         , {}                  }),
-        new ScrambleState( new int[][] {{2,-1, 33}                  , {}                          , {2, 1, 35}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 36}                  , {2,-1, 34}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 35}                  , {2,-1, 37}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 38,2, 2, 93}         , {2, 1, 36}          }),
-        new ScrambleState( new int[][] {{2, 1, 39}                  , {2, 1, 93,2,-1, 37}         , {}                  }),
-        new ScrambleState( new int[][] {{2,-1, 38}                  , {2, 1, 40,2,-1, 64}         , {2, 1,140,2,-1, 19} }),
-        new ScrambleState( new int[][] {{2, 1, 41,2,-1, 42}         , {2, 2, 64,2,-1, 39}         , {}                  }),   //40
-        new ScrambleState( new int[][] {{2, 2, 42,2,-1, 40}         , {}                          , {2,-1, 14}          }),
-        new ScrambleState( new int[][] {{2, 1, 40,2, 2, 41}         , {}                          , {0, 1, 43,0, 2,128} }),
-        new ScrambleState( new int[][] {{2, 1, 44,2,-1, 45}         , {2, 1,114,2, 2,113,2,-1, 86}, {0, 1,128,0,-1, 42} }),
-        new ScrambleState( new int[][] {{2, 2, 45,2,-1, 43}         , {2, 1, 48,2,-1,108}         , {2,-1, 81}          }),
-        new ScrambleState( new int[][] {{2, 1, 43,2, 2, 44}         , {}                          , {0, 1, 46}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 47}                  , {0,-1, 45}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 46}                  , {0, 2,  2,0,-1,  3} }),
-        new ScrambleState( new int[][] {{2,-1, 49}                  , {2, 2,108,2,-1, 44}         , {}                  }),
-        new ScrambleState( new int[][] {{2, 1, 48}                  , {}                          , {0, 1, 50}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 51,2, 2, 52}         , {0,-1, 49}          }),   //50
-        new ScrambleState( new int[][] {{}                          , {2, 1, 52,2,-1, 50}         , {0,-1,  5}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 50,2,-1, 51}         , {2,-1, 53}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 54,2, 2, 55}         , {2, 1, 52}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 55,2,-1, 53}         , {0,-1,104}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 53,2,-1, 54}         , {0, 2, 56,0,-1, 65} }),
-        new ScrambleState( new int[][] {{2, 1, 57}                  , {}                          , {0, 1, 65,0, 2, 55} }),
-        new ScrambleState( new int[][] {{2,-1, 56}                  , {2, 2, 58,2,-1, 13}         , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 13,2, 2, 57}         , {2,-1, 59}          }),
-        new ScrambleState( new int[][] {{2, 1, 60}                  , {}                          , {2, 1, 58}          }),
-        new ScrambleState( new int[][] {{2,-1, 59}                  , {}                          , {2, 1, 61}          }),   //60
-        new ScrambleState( new int[][] {{2,-1, 62}                  , {}                          , {2,-1, 60}          }),
-        new ScrambleState( new int[][] {{2, 1, 61}                  , {2,-1, 63}                  , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 62}                  , {2, 1, 64}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 39,2, 2, 40}         , {2,-1, 63}          }),
-        new ScrambleState( new int[][] {{2, 1, 66,2,-1, 67}         , {2, 1, 78,2, 2, 79,2,-1, 80}, {0, 1, 55,0,-1, 56} }),
-        new ScrambleState( new int[][] {{2, 2, 67,2,-1, 65}         , {2,-1,107}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 1, 65,2, 2, 66}         , {}                          , {0, 1, 68}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 69}                  , {0,-1, 67}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 68}                  , {0,-1, 70}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 71}                  , {0, 1, 69}          }),   //70
-        new ScrambleState( new int[][] {{2,-1, 72}                  , {2, 1, 70}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 1, 71}                  , {}                          , {0,-1, 73}          }),
-        new ScrambleState( new int[][] {{2, 1, 74,2, 2, 75}         , {}                          , {0, 1, 72}          }),
-        new ScrambleState( new int[][] {{2, 1, 75,2,-1, 73}         , {2,-1, 26}                  , {0, 1, 83,0,-1,138} }),
-        new ScrambleState( new int[][] {{2, 2, 73,2,-1, 74}         , {2, 1, 76,2,-1, 77}         , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 77,2,-1, 75}         , {0, 1, 78}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 75,2, 2, 76}         , {2,-1, 11}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 79,2, 2, 80,2,-1, 65}, {0,-1, 76}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 80,2, 2, 65,2,-1, 78}, {2,-1,110}          }),
-        new ScrambleState( new int[][] {{2, 1, 81,2,-1, 82}         , {2, 1, 65,2, 2, 78,2,-1, 79}, {2, 1,  6,2,-1,  7} }),   //80
-        new ScrambleState( new int[][] {{2, 2, 82,2,-1, 80}         , {}                          , {2, 1, 44}          }),
-        new ScrambleState( new int[][] {{2, 1, 80,2, 2, 81}         , {2, 1, 83,2,-1, 84}         , {0,-1, 15}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 84,2,-1, 82}         , {0, 2,138,0,-1, 74} }),
-        new ScrambleState( new int[][] {{2, 1, 85}                  , {2, 1, 82,2, 2, 83}         , {}                  }),
-        new ScrambleState( new int[][] {{2,-1, 84}                  , {}                          , {2, 1, 86,2, 2,119} }),
-        new ScrambleState( new int[][] {{2, 1, 87,2,-1, 88}         , {2, 1, 43,2, 2,114,2,-1,113}, {2, 1,119,2,-1, 85} }),
-        new ScrambleState( new int[][] {{2, 2, 88,2,-1, 86}         , {}                          , {2, 1, 94}          }),
-        new ScrambleState( new int[][] {{2, 1, 86,2, 2, 87}         , {2, 1, 89}                  , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 88}                  , {0, 2, 90,0,-1, 31} }),
-        new ScrambleState( new int[][] {{2, 1, 91,2, 2, 92}         , {}                          , {0, 1, 31,0, 2, 89} }),   //90
-        new ScrambleState( new int[][] {{2, 1, 92,2,-1, 90}         , {}                          , {0, 1, 93}          }),
-        new ScrambleState( new int[][] {{2, 2, 90,2,-1, 91}         , {}                          , {2,-1, 23}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2, 37,2,-1, 38}         , {0,-1, 91}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1, 95}                  , {2,-1, 87}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 94}                  , {2,-1, 96}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 97}                  , {2, 1, 95}          }),
-        new ScrambleState( new int[][] {{2, 1, 98}                  , {2,-1, 96}                  , {}                  }),
-        new ScrambleState( new int[][] {{2,-1, 97}                  , {}                          , {2,-1, 99}          }),
-        new ScrambleState( new int[][] {{2, 2,100,2,-1,101}         , {}                          , {2, 1, 98}          }),
-        new ScrambleState( new int[][] {{2, 1,101,2, 2, 99}         , {2, 1,111,2,-1,112}         , {}                  }),   //100
-        new ScrambleState( new int[][] {{2, 1, 99,2,-1,100}         , {2, 1,102}                  , {2, 1,108,2,-1,109} }),
-        new ScrambleState( new int[][] {{2, 1,103,2,-1,104}         , {2,-1,101}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 2,104,2,-1,102}         , {}                          , {2,-1,105}          }),
-        new ScrambleState( new int[][] {{2, 1,102,2, 2,103}         , {}                          , {0, 1, 54}          }),
-        new ScrambleState( new int[][] {{2,-1,106}                  , {}                          , {2, 1,103}          }),
-        new ScrambleState( new int[][] {{2, 1,105}                  , {}                          , {2, 1,107}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 66}                  , {2,-1,106}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 44,2, 2, 48}         , {2, 2,109,2,-1,101} }),
-        new ScrambleState( new int[][] {{2,-1,110}                  , {}                          , {2, 1,101,2, 2,108} }),
-        new ScrambleState( new int[][] {{2, 1,109}                  , {}                          , {2, 1, 79}          }),   //110
-        new ScrambleState( new int[][] {{}                          , {2, 2,112,2,-1,100}         , {0, 2,115,0,-1, 16} }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,100,2, 2,111}         , {2, 1,113}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 86,2, 2, 43,2,-1,114}, {2,-1,112}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,113,2, 2, 86,2,-1, 43}, {0,-1,  0}          }),
-        new ScrambleState( new int[][] {{2, 2,116}                  , {}                          , {0, 1, 16,0, 2,111} }),
-        new ScrambleState( new int[][] {{2, 2,115}                  , {}                          , {2,-1,117}          }),
-        new ScrambleState( new int[][] {{2, 1,118}                  , {}                          , {2, 1,116}          }),
-        new ScrambleState( new int[][] {{2,-1,117}                  , {}                          , {0, 1, 10}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,120,2, 2,121,2,-1,122}, {2, 2, 85,2,-1, 86} }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,121,2, 2,122,2,-1,119}, {2,-1,129}          }),   //120
-        new ScrambleState( new int[][] {{}                          , {2, 1,122,2, 2,119,2,-1,120}, {0, 1,125}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,119,2, 2,120,2,-1,121}, {0,-1,123}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,124}                  , {0, 1,122}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,123}                  , {2, 2, 27,2,-1, 28} }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,126}                  , {0,-1,121}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1,125}                  , {2,-1,127}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,128}                  , {2, 1,126}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,127}                  , {0, 2, 42,0,-1, 43} }),
-        new ScrambleState( new int[][] {{2, 2,130,2,-1,131}         , {}                          , {2, 1,120}          }),
-        new ScrambleState( new int[][] {{2, 1,131,2, 2,129}         , {}                          , {0,-1, 30}          }),   //130
-        new ScrambleState( new int[][] {{2, 1,129,2,-1,130}         , {2, 1,  3,2, 2,132}         , {}                  }),
-        new ScrambleState( new int[][] {{}                          , {2, 2,131,2,-1,  3}         , {0,-1,133}          }),
-        new ScrambleState( new int[][] {{}                          , {2,-1,134}                  , {0, 1,132}          }),
-        new ScrambleState( new int[][] {{2,-1,135}                  , {2, 1,133}                  , {}                  }),
-        new ScrambleState( new int[][] {{2, 1,134}                  , {}                          , {0,-1,136}          }),
-        new ScrambleState( new int[][] {{2, 1,137}                  , {}                          , {0, 1,135}          }),
-        new ScrambleState( new int[][] {{2,-1,136}                  , {}                          , {0, 1, 32}          }),
-        new ScrambleState( new int[][] {{2, 1,139}                  , {}                          , {0, 1, 74,0, 2, 83} }),
-        new ScrambleState( new int[][] {{2,-1,138}                  , {}                          , {0, 1, 17}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,141}                  , {2, 2, 19,2,-1, 39} }),   //140
-        new ScrambleState( new int[][] {{}                          , {2,-1,140}                  , {2,-1, 29}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1, 28}                  , {2,-1, 18}          }),
-        new ScrambleState( new int[][] {{}                          , {2, 1,  1}                  , {2, 2, 12,2,-1, 13} })
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[][] getPositions()
-    {
-    if( POSITIONS==null )
-      {
-      POSITIONS = new float[][]
-        {
-          { 1.0f,  1.0f, -1.0f},
-          {-1.0f, -1.0f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f},
-          {-1.0f,  1.0f, -1.0f,  0.0f,  1.0f, -1.0f},
-          {-1.0f,  0.0f, -1.0f,  0.0f,  0.0f, -1.0f},
-          {-1.0f, -1.0f, -1.0f,  0.0f, -1.0f, -1.0f},
-          {-1.0f,  1.0f,  0.0f, -1.0f,  1.0f,  1.0f},
-          { 0.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f},
-          { 1.0f,  1.0f,  0.0f,  1.0f,  1.0f,  1.0f},
-          {-1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  1.0f},
-          { 0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
-          { 1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  1.0f},
-          { 1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  0.0f},
-          { 1.0f, -1.0f, -1.0f,  1.0f,  0.0f, -1.0f}
-        };
-      }
-    return POSITIONS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int[] getQuatIndices()
-    {
-    if( QUAT_INDICES==null )
-      {
-      QUAT_INDICES = new int[] { 0, 1, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 3 };
-      }
-
-    return QUAT_INDICES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.bandaged_evil;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.bandaged_evil_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 8;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedFused.java b/src/main/java/org/distorted/objects/TwistyBandagedFused.java
deleted file mode 100644
index c72683f1..00000000
--- a/src/main/java/org/distorted/objects/TwistyBandagedFused.java
+++ /dev/null
@@ -1,128 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyBandagedFused extends TwistyBandagedAbstract
-{
-  public TwistyBandagedFused(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.BAN1, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] tmp = {0,-1,0, 0,1,0, 0,2,0, 2,-1,0, 2,1,0, 2,2,0};
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[][] getPositions()
-    {
-    if( POSITIONS==null )
-      {
-      POSITIONS = new float[][]
-        {
-          {-1.0f, -1.0f, +0.0f,
-           -1.0f, -1.0f, +1.0f,
-           -1.0f,  0.0f, +0.0f,
-           -1.0f,  0.0f, +1.0f,
-            0.0f, -1.0f, +0.0f,
-            0.0f, -1.0f, +1.0f,
-            0.0f,  0.0f, +0.0f,
-            0.0f,  0.0f, +1.0f},
-          {-1.0f, +1.0f, +1.0f},
-          {-1.0f, +1.0f, +0.0f},
-          {-1.0f, +1.0f, -1.0f},
-          { 0.0f, +1.0f, +1.0f},
-          { 0.0f, +1.0f, +0.0f},
-          { 0.0f, +1.0f, -1.0f},
-          { 1.0f, +1.0f, +1.0f},
-          { 1.0f, +1.0f, +0.0f},
-          { 1.0f, +1.0f, -1.0f},
-          { 1.0f,  0.0f, +1.0f},
-          { 1.0f,  0.0f, +0.0f},
-          { 1.0f,  0.0f, -1.0f},
-          { 1.0f, -1.0f, +1.0f},
-          { 1.0f, -1.0f, +0.0f},
-          { 1.0f, -1.0f, -1.0f},
-          {-1.0f, -1.0f, -1.0f},
-          {-1.0f,  0.0f, -1.0f},
-          { 0.0f, -1.0f, -1.0f},
-          { 0.0f,  0.0f, -1.0f}
-        };
-      }
-    return POSITIONS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int[] getQuatIndices()
-    {
-    if( QUAT_INDICES==null ) QUAT_INDICES = new int[] { 0 };
-    return QUAT_INDICES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC APi
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.bandaged_fused;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.bandaged_fused_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 8;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
deleted file mode 100644
index 8d01baae..00000000
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ /dev/null
@@ -1,422 +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.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyCube extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(1,0,0),
-           new Static3D(0,1,0),
-           new Static3D(0,0,1)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
-      };
-
-  private ScrambleState[] mStates;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[] mBasicAngle;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyCube(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                    DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int size = getNumLayers();
-      int[][] m = new int[16][];
-      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
-        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
-        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
-        new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
-        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
-        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
-        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
-        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
-        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
-        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
-        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
-        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
-        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
-        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
-        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
-        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[] createEdges(int size, int vertex)
-    {
-    int[] ret = new int[9*size];
-
-    for(int l=0; l<size; l++)
-      {
-      ret[9*l  ] = l;
-      ret[9*l+1] =-1;
-      ret[9*l+2] = vertex;
-      ret[9*l+3] = l;
-      ret[9*l+4] = 1;
-      ret[9*l+5] = vertex;
-      ret[9*l+6] = l;
-      ret[9*l+7] = 2;
-      ret[9*l+8] = vertex;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
-         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
-
-         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
-         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
-
-         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
-         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats ==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int extraI, extraV, num;
-    float height;
-
-    switch(numLayers)
-      {
-      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
-      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
-      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
-      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
-      }
-
-    double[][] vertices = new double[][]
-          {
-              { 0.5, 0.5, 0.5 },
-              { 0.5, 0.5,-0.5 },
-              { 0.5,-0.5, 0.5 },
-              { 0.5,-0.5,-0.5 },
-              {-0.5, 0.5, 0.5 },
-              {-0.5, 0.5,-0.5 },
-              {-0.5,-0.5, 0.5 },
-              {-0.5,-0.5,-0.5 },
-          };
-
-    int[][] vert_indices = new int[][]
-          {
-              {2,3,1,0},
-              {7,6,4,5},
-              {4,0,1,5},
-              {7,3,2,6},
-              {6,2,0,4},
-              {3,7,5,1}
-          };
-
-    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
-    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
-    float[][] corners   = new float[][] { {0.036f,0.12f} };
-    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-
-    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats ==null ) initializeQuats();
-    return mQuats[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
-      final float radius = 0.10f;
-      final float stroke = 0.08f;
-      final float[] radii = {radius,radius,radius,radius};
-      mStickers = new ObjectSticker[STICKERS.length];
-      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
-    float[][] tmp = new float[numCubits][];
-
-    float diff = 0.5f*(numLayers-1);
-    int currentPosition = 0;
-
-    for(int x = 0; x<numLayers; x++)
-      for(int y = 0; y<numLayers; y++)
-        for(int z = 0; z<numLayers; z++)
-          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
-            {
-            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
-            }
-
-    return tmp;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats ==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( numLayers<2 ) return null;
-
-    if( mCuts==null )
-      {
-      mCuts = new float[3][numLayers-1];
-
-      for(int i=0; i<numLayers-1; i++)
-        {
-        float cut = (2-numLayers)*0.5f + i;
-        mCuts[0][i] = cut;
-        mCuts[1][i] = cut;
-        mCuts[2][i] = cut;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    return CUBITS[cubit].getRotRow(cubitface/2) == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.cube2;
-      case 3: return R.string.cube3;
-      case 4: return R.string.cube4;
-      case 5: return R.string.cube5;
-      }
-    return R.string.cube3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.cube2_inventor;
-      case 3: return R.string.cube3_inventor;
-      case 4: return R.string.cube4_inventor;
-      case 5: return R.string.cube5_inventor;
-      }
-    return R.string.cube3_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return 4;
-      case 3: return 6;
-      case 4: return 8;
-      case 5: return 10;
-      }
-    return 6;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
deleted file mode 100644
index da462f58..00000000
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ /dev/null
@@ -1,565 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement8;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty8;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyDiamond extends Twisty8
-{
-  // the four rotation axis of a Diamond. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           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)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{1,2,3}},{{0,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,3}},{{0,1,2}},{{0,1,2}}
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private int[] mFaceMap;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private Static4D[] mQuats;
-  private int[] mTetraToFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyDiamond(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                       DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.DIAM, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int size = getNumLayers();
-      int[] tmp = new int[3*2*size];
-
-      for(int i=0; i<2*size; i++)
-        {
-        tmp[3*i  ] = (i<size) ?  i:i-size;
-        tmp[3*i+1] = (i%2==0) ? -1:1;
-        tmp[3*i+2] = 0;
-        }
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-          new Static4D(  0.0f,  0.0f,   0.0f,  1.0f ),
-          new Static4D(  0.0f,  1.0f,   0.0f,  0.0f ),
-          new Static4D(+SQ2/2,  0.0f, -SQ2/2,  0.0f ),
-          new Static4D(-SQ2/2,  0.0f, -SQ2/2,  0.0f ),
-
-          new Static4D(+SQ2/2,  0.5f,   0.0f,  0.5f ),
-          new Static4D(-SQ2/2,  0.5f,   0.0f,  0.5f ),
-          new Static4D(  0.0f,  0.5f, +SQ2/2,  0.5f ),
-          new Static4D(  0.0f,  0.5f, -SQ2/2,  0.5f ),
-          new Static4D(+SQ2/2,  0.5f,   0.0f, -0.5f ),
-          new Static4D(-SQ2/2,  0.5f,   0.0f, -0.5f ),
-          new Static4D(  0.0f,  0.5f, +SQ2/2, -0.5f ),
-          new Static4D(  0.0f,  0.5f, -SQ2/2, -0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    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);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( numLayers<2 ) return null;
-
-    if( mCuts==null )
-      {
-      mCuts = new float[4][numLayers-1];
-      float cut = (SQ6/6)*(2-numLayers);
-
-      for(int i=0; i<numLayers-1; i++)
-        {
-        mCuts[0][i] = cut;
-        mCuts[1][i] = cut;
-        mCuts[2][i] = cut;
-        mCuts[3][i] = cut;
-        cut += SQ6/3;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumOctahedrons(int layers)
-    {
-    return layers==1 ? 1 : 4*(layers-1)*(layers-1) + 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumTetrahedrons(int layers)
-    {
-    return 4*layers*(layers-1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int createOctaPositions(float[][] centers, int index, int layers, float height)
-    {
-    float x = (layers-1)*0.5f;
-    float z = (layers+1)*0.5f;
-
-    for(int i=0; i<layers; i++, index++)
-      {
-      z -= 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      x -= 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      z += 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    for(int i=0; i<layers-2; i++, index++)
-      {
-      x += 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    return index;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int createTetraPositions(float[][] centers, int index, int layers, float height)
-    {
-    float x = (layers-1)*0.5f;
-    float z =  layers*0.5f;
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      z -= 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    x += 0.5f;
-    z -= 0.5f;
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      x -= 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    x -= 0.5f;
-    z -= 0.5f;
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      z += 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    x -= 0.5f;
-    z += 0.5f;
-
-    for(int i=0; i<layers-1; i++, index++)
-      {
-      x += 1;
-      centers[index][0] = x;
-      centers[index][1] = height;
-      centers[index][2] = z;
-      }
-
-    return index;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int layers)
-    {
-    int numO = getNumOctahedrons(layers);
-    int numT = getNumTetrahedrons(layers);
-    int index = 0;
-    float height = 0.0f;
-
-    float[][] CENTERS = new float[numO+numT][3];
-
-    index = createOctaPositions(CENTERS,index,layers,height);
-
-    for(int i=layers-1; i>0; i--)
-      {
-      height += SQ2/2;
-      index = createOctaPositions(CENTERS,index,i,+height);
-      index = createOctaPositions(CENTERS,index,i,-height);
-      }
-
-    height = SQ2/4;
-
-    for(int i=layers; i>1; i--)
-      {
-      index = createTetraPositions(CENTERS,index,i,+height);
-      index = createTetraPositions(CENTERS,index,i,-height);
-      height += SQ2/2;
-      }
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int retFaceTetraBelongsTo(int tetra, int numLayers)
-    {
-    if( mTetraToFaceMap==null ) mTetraToFaceMap = new int[] {1,2,3,0,5,6,7,4};
-
-    for(int i=numLayers-1; i>0; i--)
-      {
-      if( tetra < 8*i ) return mTetraToFaceMap[tetra/i];
-      tetra -= 8*i;
-      }
-
-    return -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-    int N = numLayers>3 ? 5:6;
-    int E = numLayers>2 ? (numLayers>3 ? 0:1):2;
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-          {
-             { 0.5,   0.0, 0.5},
-             { 0.5,   0.0,-0.5},
-             {-0.5,   0.0,-0.5},
-             {-0.5,   0.0, 0.5},
-             { 0.0, SQ2/2, 0.0},
-             { 0.0,-SQ2/2, 0.0}
-          };
-
-      int[][] vert_indices = new int[][]
-          {
-             {3,0,4},
-             {0,1,4},
-             {1,2,4},
-             {2,3,4},
-             {5,0,3},
-             {5,1,0},
-             {5,2,1},
-             {5,3,2}
-          };
-
-      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
-      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
-      float[][] corners   = new float[][] { {0.04f,0.20f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][] { {-0.5, SQ2/4, 0.0}, { 0.5, SQ2/4, 0.0}, { 0.0,-SQ2/4, 0.5}, { 0.0,-SQ2/4,-0.5} };
-      int[][] vert_indices = new int[][]  { {2,1,0}, {2,3,1}, {3,2,0}, {3,0,1} };
-      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
-      int[] bandIndices   = new int[] { 0,0,0,0 };
-      float[][] corners   = new float[][] { {0.08f,0.15f} };
-      int[] cornerIndices = new int[] { 0,0,0,0 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int numO = getNumOctahedrons(numLayers);
-
-    if( cubit<numO ) return mQuats[0];
-
-    switch( retFaceTetraBelongsTo(cubit-numO, numLayers) )
-      {
-      case 0: return mQuats[0];                         // unit quat
-      case 1: return new Static4D(0,-SQ2/2,0,SQ2/2);    //  90 along Y
-      case 2: return mQuats[1];                         // 180 along Y
-      case 3: return new Static4D(0,+SQ2/2,0,SQ2/2);    //  90 along
-      case 4: return new Static4D(0,     0,1,    0);    // 180 along Z
-      case 5: return new Static4D(SQ2/2, 0,SQ2/2,0);    //
-      case 6: return new Static4D(     1,0,0,    0);    // 180 along X
-      case 7: return new Static4D(-SQ2/2,0,SQ2/2,0);    //
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<getNumOctahedrons(numLayers) ? 0 : 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    int numO = getNumOctahedrons(size);
-
-    if( cubit<numO )
-      {
-      int axis = 0;
-      int layer= 1;
-
-      switch(cubitface)
-        {
-        case 0: axis = 2; layer =             1; break;
-        case 1: axis = 0; layer = (1<<(size-1)); break;
-        case 2: axis = 3; layer =             1; break;
-        case 3: axis = 1; layer = (1<<(size-1)); break;
-        case 4: axis = 3; layer = (1<<(size-1)); break;
-        case 5: axis = 1; layer =             1; break;
-        case 6: axis = 2; layer = (1<<(size-1)); break;
-        case 7: axis = 0; layer =             1; break;
-        }
-
-      return CUBITS[cubit].getRotRow(axis) == layer ? cubitface : NUM_TEXTURES;
-      }
-    else
-      {
-      return cubitface>0 ? NUM_TEXTURES : retFaceTetraBelongsTo(cubit-numO, size);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
-      float radius = 0.06f;
-      float stroke = 0.07f;
-      float[] radii = new float[] {radius,radius,radius};
-      mStickers     = new ObjectSticker[STICKERS.length];
-      mStickers[0]  = new ObjectSticker(STICKERS[0],null,radii,stroke);
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement8(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.diam2;
-      case 3: return R.string.diam3;
-      case 4: return R.string.diam4;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.diam2_inventor;
-      case 3: return R.string.diam3_inventor;
-      case 4: return R.string.diam4_inventor;
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return 4;
-      case 3: return 6;
-      case 4: return 8;
-      }
-
-    return 0;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyDino.java b/src/main/java/org/distorted/objects/TwistyDino.java
deleted file mode 100644
index b4a8078b..00000000
--- a/src/main/java/org/distorted/objects/TwistyDino.java
+++ /dev/null
@@ -1,264 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_CORNER;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract class TwistyDino extends Twisty6
-{
-  // the four rotation axis of a RubikDino. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0,1},{3,1},{2,3},{0,2}},
-          {{2,3},{3,1},{0,1},{0,2}},
-          {{1,2},{0,1},{0,3},{2,3}},
-          {{1,2},{2,3},{0,3},{0,1}},
-          {{0,3},{0,2},{1,2},{1,3}},
-          {{1,2},{0,2},{0,3},{1,3}},
-      };
-
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private ObjectSticker[] mStickers;
-  private float[][] mCenters;
-  private Movement mMovement;
-  ScrambleState[] mStates;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyDino(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-             DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, obj, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int size)
-    {
-    if( mCuts==null )
-      {
-      float[] cut = new float[] { -SQ3/3, +SQ3/3 };
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[] {true,false,true};
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 4;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int size)
-    {
-    if( mCenters ==null )
-      {
-      mCenters = new float[][]
-         {
-             { 0.0f, 1.5f, 1.5f },
-             { 1.5f, 0.0f, 1.5f },
-             { 0.0f,-1.5f, 1.5f },
-             {-1.5f, 0.0f, 1.5f },
-             { 1.5f, 1.5f, 0.0f },
-             { 1.5f,-1.5f, 0.0f },
-             {-1.5f,-1.5f, 0.0f },
-             {-1.5f, 1.5f, 0.0f },
-             { 0.0f, 1.5f,-1.5f },
-             { 1.5f, 0.0f,-1.5f },
-             { 0.0f,-1.5f,-1.5f },
-             {-1.5f, 0.0f,-1.5f }
-         };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    double[][] vertices = new double[][] { {-1.5, 0.0, 0.0},{ 1.5, 0.0, 0.0},{ 0.0,-1.5, 0.0},{ 0.0, 0.0,-1.5} };
-    int[][] vert_indices= new int[][] { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
-    float[][] bands     = new float[][] { {0.035f,30,0.16f,0.8f,6,2,2}, {0.010f,30,0.16f,0.2f,6,2,2} };
-    int[] bandIndices   = new int[] { 0,0,1,1 };
-    float[][] corners   = new float[][] { {0.07f,0.40f}, {0.05f,0.30f} };
-    int[] cornerIndices = new int[] { 0,0,1,1 };
-    float[][] centers   = new float[][] { {0.0f, -0.75f, -0.75f} };
-    int[] centerIndices = new int[] { 0,0,0,0 };
-    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats[cubit];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][] { { 0.0f, -1.0f/3, 0.5f, 1.0f/6, -0.5f, 1.0f/6 } };
-      float radius = 0.025f;
-      float stroke = 0.050f;
-      float[] radii = new float[] {radius,radius,radius};
-      mStickers     = new ObjectSticker[STICKERS.length];
-      mStickers[0]  = new ObjectSticker(STICKERS[0],null,radii,stroke);
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 2;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyDino4.java b/src/main/java/org/distorted/objects/TwistyDino4.java
deleted file mode 100644
index 53eb2872..00000000
--- a/src/main/java/org/distorted/objects/TwistyDino4.java
+++ /dev/null
@@ -1,111 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyDino4 extends TwistyDino
-{
-  private int[] mFaceMap;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyDino4(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                     DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.DIN4, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5              },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null ) mFaceMap = new int[] { 4, 2, 2, 4, 0, 2, 1, 4, 0, 0, 1, 1 };
-    return (cubitface==0 || cubitface==1) ? mFaceMap[cubit] : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean shouldResetTextureMaps()
-    {
-    return true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.din43;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.din43_inventor;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyDino6.java b/src/main/java/org/distorted/objects/TwistyDino6.java
deleted file mode 100644
index 8c752875..00000000
--- a/src/main/java/org/distorted/objects/TwistyDino6.java
+++ /dev/null
@@ -1,113 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyDino6 extends TwistyDino
-{
-  private int[] mFaceMap;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyDino6(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                     DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.DINO, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[] { 4,2, 0,4, 4,3, 1,4, 2,0, 3,0, 3,1, 2,1, 5,2, 0,5, 5,3, 1,5 };
-      }
-
-    switch(cubitface)
-      {
-      case 0 : return mFaceMap[2*cubit];
-      case 1 : return mFaceMap[2*cubit+1];
-      default: return NUM_TEXTURES;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.dino3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.dino3_inventor;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
deleted file mode 100644
index 10eae53e..00000000
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ /dev/null
@@ -1,471 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_EDGE;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyHelicopter extends Twisty6
-{
-  // the six rotation axis of a Helicopter. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(     0, +SQ2/2, -SQ2/2),
-           new Static3D(     0, -SQ2/2, -SQ2/2),
-           new Static3D(+SQ2/2,      0, -SQ2/2),
-           new Static3D(-SQ2/2,      0, -SQ2/2),
-           new Static3D(+SQ2/2, -SQ2/2,      0),
-           new Static3D(-SQ2/2, -SQ2/2,      0)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{2,5},{2,4},{3,4},{3,5}},
-          {{2,4},{2,5},{3,5},{3,4}},
-          {{0,5},{1,5},{1,4},{0,4}},
-          {{0,4},{1,4},{1,5},{0,5}},
-          {{1,3},{0,3},{0,2},{1,2}},
-          {{0,3},{1,3},{1,2},{0,2}},
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private float[][] mCenters;
-  private int[] mQuatIndices;
-  private int[][] mFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyHelicopter(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                          DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { {0,1,1,2,1,2},{0,1,3,2,1,4},{0,1,5,2,1,6},{0,1,7,2,1,8},{0,1,9,2,1,10},{0,1,11,2,1,12} } ),
-        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
-        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
-        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
-        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
-        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
-        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
-        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
-        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
-        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
-        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
-        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
-        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D( 0.00f,  0.00f,  0.00f,  1.00f ),
-         new Static4D( 1.00f,  0.00f,  0.00f,  0.00f ),
-         new Static4D( 0.00f,  1.00f,  0.00f,  0.00f ),
-         new Static4D( 0.00f,  0.00f,  1.00f,  0.00f ),
-
-         new Static4D( SQ2/2,  SQ2/2,  0.00f,  0.00f ),
-         new Static4D( SQ2/2, -SQ2/2,  0.00f,  0.00f ),
-         new Static4D( SQ2/2,  0.00f,  SQ2/2,  0.00f ),
-         new Static4D( SQ2/2,  0.00f, -SQ2/2,  0.00f ),
-         new Static4D( SQ2/2,  0.00f,  0.00f,  SQ2/2 ),
-         new Static4D( SQ2/2,  0.00f,  0.00f, -SQ2/2 ),
-         new Static4D( 0.00f,  SQ2/2,  SQ2/2,  0.00f ),
-         new Static4D( 0.00f,  SQ2/2, -SQ2/2,  0.00f ),
-         new Static4D( 0.00f,  SQ2/2,  0.00f,  SQ2/2 ),
-         new Static4D( 0.00f,  SQ2/2,  0.00f, -SQ2/2 ),
-         new Static4D( 0.00f,  0.00f,  SQ2/2,  SQ2/2 ),
-         new Static4D( 0.00f,  0.00f,  SQ2/2, -SQ2/2 ),
-
-         new Static4D( 0.50f,  0.50f,  0.50f,  0.50f ),
-         new Static4D( 0.50f,  0.50f,  0.50f, -0.50f ),
-         new Static4D( 0.50f,  0.50f, -0.50f,  0.50f ),
-         new Static4D( 0.50f,  0.50f, -0.50f, -0.50f ),
-         new Static4D( 0.50f, -0.50f,  0.50f,  0.50f ),
-         new Static4D( 0.50f, -0.50f,  0.50f, -0.50f ),
-         new Static4D( 0.50f, -0.50f, -0.50f,  0.50f ),
-         new Static4D( 0.50f, -0.50f, -0.50f, -0.50f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int size)
-    {
-    if( mCuts==null )
-      {
-      float[] cut = new float[] { -3*SQ2/4, +3*SQ2/4 };
-      mCuts = new float[][] { cut,cut,cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[] {true,false,true};
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 4;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int size)
-    {
-    if( mCenters==null )
-      {
-      float DIST_CORNER = 1.50f;
-      float DIST_CENTER = 1.50f;
-      float XY_CENTER = DIST_CORNER/3;
-
-      mCenters = new float[][]
-         {
-             {   DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
-             {   DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
-             {   DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
-             {   DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
-             {  -DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
-             {  -DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
-             {  -DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
-             {  -DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
-
-             {   DIST_CENTER,     XY_CENTER,     XY_CENTER },
-             {   DIST_CENTER,     XY_CENTER,    -XY_CENTER },
-             {   DIST_CENTER,    -XY_CENTER,     XY_CENTER },
-             {   DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
-
-             {  -DIST_CENTER,     XY_CENTER,     XY_CENTER },
-             {  -DIST_CENTER,     XY_CENTER,    -XY_CENTER },
-             {  -DIST_CENTER,    -XY_CENTER,     XY_CENTER },
-             {  -DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
-
-             {   XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
-             {   XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
-             {  -XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
-             {  -XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
-
-             {   XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
-             {   XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
-             {  -XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
-             {  -XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
-
-             {   XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
-             {   XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
-             {  -XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
-             {  -XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
-
-             {   XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
-             {   XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
-             {  -XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
-             {  -XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
-         };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-          {
-            {-1.50f, 0.00f, 0.00f},
-            { 0.00f,-1.50f, 0.00f},
-            { 0.00f, 0.00f,-1.50f},
-            {-0.75f,-0.75f,-0.75f},
-            { 0.00f, 0.00f, 0.00f}
-          };
-
-      int[][] vert_indices = new int[][]
-          {
-            {0,1,4},
-            {2,0,4},
-            {1,2,4},
-            {3,1,0},
-            {3,2,1},
-            {3,0,2}
-          };
-
-      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,5} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
-      float[][] corners   = new float[][] { {0.08f,0.20f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0 };
-      float[][] centers   = new float[][] { {-0.75f, -0.75f, -0.75f} };
-      int[] centerIndices = new int[] { 0,0,0,-1,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-          {
-            { 0.50f, 0.50f, 0.00f },
-            {-1.00f, 0.50f, 0.00f },
-            { 0.50f,-1.00f, 0.00f },
-            {-0.25f,-0.25f,-0.75f },
-          };
-
-      int[][] vert_indices = new int[][]
-          {
-            { 0,1,2 },
-            { 2,1,3 },
-            { 0,1,3 },
-            { 2,0,3 }
-          };
-
-      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,3} };
-      int[] bandIndices   = new int[] { 0,1,1,1 };
-      float[][] corners   = new float[][] { {0.06f,0.20f} };
-      int[] cornerIndices = new int[] { 0,0,0,-1 };
-      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.75f} };
-      int[] centerIndices = new int[] { 0,0,0,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    if( mQuatIndices==null ) mQuatIndices = new int[] { 0,13,14,1,12,2,3,7,20,6,13,17,7,23,18,12,22,10,8,16,11,21,19,9,3,15,14,0,5,2,1,4 };
-    return mQuats[mQuatIndices[cubit]];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<8 ? 0:1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[][]
-         {
-           { 4,2,0, 6,6,6 },
-           { 0,2,5, 6,6,6 },
-           { 4,0,3, 6,6,6 },
-           { 5,3,0, 6,6,6 },
-           { 1,2,4, 6,6,6 },
-           { 5,2,1, 6,6,6 },
-           { 4,3,1, 6,6,6 },
-           { 1,3,5, 6,6,6 },
-
-           { 0 , 6,6,6,6,6 },
-           { 0 , 6,6,6,6,6 },
-           { 0 , 6,6,6,6,6 },
-           { 0 , 6,6,6,6,6 },
-
-           { 1 , 6,6,6,6,6 },
-           { 1 , 6,6,6,6,6 },
-           { 1 , 6,6,6,6,6 },
-           { 1 , 6,6,6,6,6 },
-
-           { 2 , 6,6,6,6,6 },
-           { 2 , 6,6,6,6,6 },
-           { 2 , 6,6,6,6,6 },
-           { 2 , 6,6,6,6,6 },
-
-           { 3 , 6,6,6,6,6 },
-           { 3 , 6,6,6,6,6 },
-           { 3 , 6,6,6,6,6 },
-           { 3 , 6,6,6,6,6 },
-
-           { 4 , 6,6,6,6,6 },
-           { 4 , 6,6,6,6,6 },
-           { 4 , 6,6,6,6,6 },
-           { 4 , 6,6,6,6,6 },
-
-           { 5 , 6,6,6,6,6 },
-           { 5 , 6,6,6,6,6 },
-           { 5 , 6,6,6,6,6 },
-           { 5 , 6,6,6,6,6 },
-         };
-      }
-
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][] { { -0.5f, 0.25f, 0.25f, -0.5f, 0.25f, 0.25f } };
-      float radius = 0.03f;
-      float stroke = 0.05f;
-      float[] radii = new float[] {radius,radius,radius};
-      mStickers = new ObjectSticker[STICKERS.length];
-      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_EDGE,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 2,2,2,2,2,2 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.heli3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.heli3_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 8;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
deleted file mode 100644
index baea1354..00000000
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ /dev/null
@@ -1,498 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_CORNER;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyIvy extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0},{3},{3},{0}},
-          {{2},{1},{1},{2}},
-          {{2},{0},{0},{2}},
-          {{1},{3},{3},{1}},
-          {{0},{0},{1},{1}},
-          {{2},{2},{3},{3}},
-      };
-
-  private static final int NUM_STICKERS = 2;
-  public static final float IVY_D = 0.006f;
-  private static final int  IVY_N = 8;
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[][] mFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyIvy(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                   DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return NUM_STICKERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      float[] cut = new float[] {0.0f};
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    final float DIST_CORNER = numLayers-1;
-    final float DIST_CENTER = numLayers-1;
-
-    final float[][] CENTERS = new float[10][];
-
-    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
-    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
-    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
-    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
-    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
-    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
-    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
-    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
-    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
-    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      final float angle = (float)Math.PI/(2*IVY_N);
-      final float CORR  = 1.0f - 2*IVY_D;
-
-      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
-      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
-      int[] cornerIndices= new int[3*(IVY_N+1)+4];
-      int[] centerIndices= new int[3*(IVY_N+1)+4];
-      double[][] vertices= new double[3*(IVY_N+1)+4][3];
-      int[][] vertIndices= new int[6][IVY_N+4];
-      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
-
-      float[][] bands =
-        {
-          {+0.015f,20,0.2f,0.5f,7,1,2},
-          {-0.100f,20,0.2f,0.0f,2,1,2}
-        };
-
-      for(int i=0; i<3*(IVY_N+1); i++)
-        {
-        cornerIndices[i+4] = -1;
-        centerIndices[i+4] = -1;
-        }
-
-      cornerIndices[0] = 1;
-      cornerIndices[1] = 0;
-      cornerIndices[2] = 0;
-      cornerIndices[3] = 0;
-
-      centerIndices[0] = 0;
-      centerIndices[1] = 0;
-      centerIndices[2] = 0;
-      centerIndices[3] = 0;
-
-      vertices[0][0] = 0.0;
-      vertices[0][1] = 0.0;
-      vertices[0][2] = 0.0;
-      vertices[1][0] =-2.0;
-      vertices[1][1] = 0.0;
-      vertices[1][2] = 0.0;
-      vertices[2][0] = 0.0;
-      vertices[2][1] =-2.0;
-      vertices[2][2] = 0.0;
-      vertices[3][0] = 0.0;
-      vertices[3][1] = 0.0;
-      vertices[3][2] =-2.0;
-
-      vertIndices[0][0] = 2;
-      vertIndices[0][1] = 0;
-      vertIndices[0][2] = 1;
-      vertIndices[3][0] = 2;
-      vertIndices[3][1] = 0;
-      vertIndices[3][2] = 1;
-
-      vertIndices[1][0] = 3;
-      vertIndices[1][1] = 0;
-      vertIndices[1][2] = 2;
-      vertIndices[4][0] = 3;
-      vertIndices[4][1] = 0;
-      vertIndices[4][2] = 2;
-
-      vertIndices[2][0] = 1;
-      vertIndices[2][1] = 0;
-      vertIndices[2][2] = 3;
-      vertIndices[5][0] = 1;
-      vertIndices[5][1] = 0;
-      vertIndices[5][2] = 3;
-
-      int N1 = 4;
-      int N2 = N1 + IVY_N + 1;
-      int N3 = N2 + IVY_N + 1;
-
-      for(int i=0; i<=IVY_N; i++)
-        {
-        double cos1 = Math.cos((IVY_N-i)*angle);
-        double sin1 = Math.sin((IVY_N-i)*angle);
-        double cos2 = Math.cos((      i)*angle);
-        double sin2 = Math.sin((      i)*angle);
-
-        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
-        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
-        vertices[N1+i][2] = 0.0;
-
-        vertices[N2+i][0] = 0.0;
-        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
-        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
-
-        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
-        vertices[N3+i][1] = 0.0;
-        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
-
-        vertIndices[0][i+3] = N1 + i;
-        vertIndices[1][i+3] = N2 + i;
-        vertIndices[2][i+3] = N3 + i;
-        vertIndices[3][i+3] = N1 + i;
-        vertIndices[4][i+3] = N2 + i;
-        vertIndices[5][i+3] = N3 + i;
-        }
-
-      float C = 1.0f - SQ2/2;
-      float[] convexCenter = new float[] {-C,-C,-C};
-      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
-      }
-    else
-      {
-      final float angle = (float)Math.PI/(2*IVY_N);
-      final float CORR  = 1.0f - 2*IVY_D;
-      double[][] vertices = new double[2*IVY_N][3];
-      int[][] vert_indices = new int[2][2*IVY_N];
-
-      int[] bandIndices= new int[] { 0,1 };
-      int[] indexes    = new int[2*IVY_N];
-      float[][] corners= new float[][] { {0.05f,0.20f} };
-      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
-
-      for(int i=0; i<IVY_N; i++)
-        {
-        double sin = Math.sin(i*angle);
-        double cos = Math.cos(i*angle);
-
-        vertices[i      ][0] = CORR*(1.0f-2*cos);
-        vertices[i      ][1] = CORR*(1.0f-2*sin);
-        vertices[i      ][2] = 0;
-        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
-        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
-        vertices[i+IVY_N][2] = 0;
-        }
-
-      for(int i=0; i<2*IVY_N; i++)
-        {
-        vert_indices[0][i] = i;
-        vert_indices[1][i] = 2*IVY_N-1-i;
-        }
-
-      for(int i=0; i<2*IVY_N; i++)
-        {
-        indexes[i] = -1;
-        }
-      indexes[0] = indexes[IVY_N] = 0;
-
-      float[][] bands =
-        {
-          {+0.03f,35,0.5f,0.5f,5,0,0},
-          {+0.10f,45,0.5f,0.0f,2,0,0}
-        };
-
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-
-    switch(cubit)
-      {
-      case  0: return mQuats[0];
-      case  1: return mQuats[2];
-      case  2: return mQuats[3];
-      case  3: return mQuats[1];
-
-      case  4: return mQuats[8];
-      case  5: return mQuats[11];
-      case  6: return mQuats[10];
-      case  7: return mQuats[9];
-      case  8: return mQuats[0];
-      case  9: return mQuats[2];
-      }
-
-    return mQuats[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<4 ? 0:1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[][]
-         {
-           {  4, 0, 2, 12,12,12 },
-           {  5, 1, 2, 12,12,12 },
-           {  4, 1, 3, 12,12,12 },
-           {  5, 0, 3, 12,12,12 },
-
-           {  6, 12,12,12,12,12 },
-           {  7, 12,12,12,12,12 },
-           {  8, 12,12,12,12,12 },
-           {  9, 12,12,12,12,12 },
-           { 10, 12,12,12,12,12 },
-           { 11, 12,12,12,12,12 },
-         };
-      }
-
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
-      mStickers = new ObjectSticker[NUM_STICKERS];
-      float D = (float)(Math.PI/4);
-      final float[][] angles = { { 0,0,D },{ D,D } };
-      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
-      final float[] strokes = { 0.03f, 0.08f };
-      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.ivy2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.ivy2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 1;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyJing.java b/src/main/java/org/distorted/objects/TwistyJing.java
deleted file mode 100644
index 6c9b55df..00000000
--- a/src/main/java/org/distorted/objects/TwistyJing.java
+++ /dev/null
@@ -1,457 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement4;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty4;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyJing extends Twisty4
-{
-  static final Static3D[] ROT_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),
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
-      };
-
-  static final float F = 0.48f;  // length of the edge of the corner cubit. Keep<0.5
-                                 // Assuming the length of the edge of the whole
-                                 // tetrahedron is 2.0 (ie standard, equal to numLayers
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private int[] mRotQuat;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private float[][] mCenters;
-  private int[][] mFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyJing(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                    DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.JING, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
-         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
-         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
-         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
-         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
-         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
-         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
-         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
-         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
-         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
-         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
-         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int size)
-    {
-    if( mCenters==null )
-      {
-      mCenters = new float[][]
-         {
-           { 0.000f, -SQ2/2, 1.000f },
-           { 0.000f, -SQ2/2,-1.000f },
-           {-1.000f,  SQ2/2, 0.000f },
-           { 1.000f,  SQ2/2, 0.000f },
-
-           { 0.000f, -SQ2/2, 0.000f },
-           {-0.500f, 0.000f, 0.500f },
-           { 0.500f, 0.000f, 0.500f },
-           {-0.500f, 0.000f,-0.500f },
-           { 0.500f, 0.000f,-0.500f },
-           { 0.000f,  SQ2/2, 0.000f },
-
-           { 0.000f,  SQ2/6, 1.0f/3 },
-           { 0.000f,  SQ2/6,-1.0f/3 },
-           {-1.0f/3, -SQ2/6, 0.000f },
-           { 1.0f/3, -SQ2/6, 0.000f },
-         };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int size)
-    {
-    if( mCuts==null )
-      {
-      float[] cut = { (F-0.5f)*(SQ6/3) };
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null )
-      {
-      // Colors of the faces of cubits.
-      // GREEN 0 YELLOW 1 BLUE  2 RED 3
-      // GREEN 4 YELLOW 5 BLUE  6 RED 7
-      // GREEN 8 YELLOW 9 BLUE 10 RED 11
-      mFaceMap = new int[][]
-         {
-           {  0,  3,  2, 12, 12, 12 },
-           {  1,  2,  3, 12, 12, 12 },
-           {  1,  0,  2, 12, 12, 12 },
-           {  1,  3,  0, 12, 12, 12 },
-
-           {  7,  6, 12, 12, 12, 12 },
-           {  4,  6, 12, 12, 12, 12 },
-           {  7,  4, 12, 12, 12, 12 },
-           {  5,  6, 12, 12, 12, 12 },
-           {  7,  5, 12, 12, 12, 12 },
-           {  4,  5, 12, 12, 12, 12 },
-
-           {  8, 12, 12, 12, 12, 12 },
-           {  9, 12, 12, 12, 12, 12 },
-           { 10, 12, 12, 12, 12, 12 },
-           { 11, 12, 12, 12, 12, 12 },
-         };
-      }
-
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    final float X = F/2;
-    final float Y = F*SQ2/2;
-    final float Z =-F/2;
-    final float L = (2.0f-3*F);
-    final float X2= L/2;
-    final float Y2= L*SQ2/2;
-    final float Z2=-L/2;
-    final float D = F/L;
-    final float G = 1.0f-F;
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-          {
-             { 0.0, 0.0, 0.0 },
-             {   X,   Y,   Z },
-             { 0.0, 2*Y, 2*Z },
-             {  -X,   Y,   Z },
-             { 0.0, 0.0,    -F },
-             {   X,   Y,   Z-F },
-             { 0.0, 2*Y, 2*Z-F },
-             {  -X,   Y,   Z-F },
-          };
-      int[][] vert_indices = new int[][]
-          {
-             {0,1,2,3},
-             {1,0,4,5},
-             {7,4,0,3},
-             {1,5,6,2},
-             {7,3,2,6},
-             {4,7,6,5}
-          };
-
-      float[][] bands     = new float[][] { {0.015f,35,0.5f*F,F,5,1,1},{0.001f,35,0.5f*F,F,5,1,1} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
-      float[][] corners   = new float[][] { {0.08f,0.20f*F},{0.07f,0.20f*F} };
-      int[] cornerIndices = new int[] { 0,1,1,-1,1,-1,-1,-1 };
-      float[][] centers   = new float[][] { { 0.0f, F*SQ2/2, -F} };
-      int[] centerIndices = new int[] { 0,0,0,-1,0,-1,-1,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      double[][] vertices = new double[][]
-          {
-             { 0.0, 0.0,     G },
-             {   X,   Y,   Z+G },
-             { 0.0, 2*Y, 2*Z+G },
-             {  -X,   Y,   Z+G },
-             { 0.0, 0.0,    -G },
-             {   X,   Y,  -Z-G },
-             { 0.0, 2*Y,-2*Z-G },
-             {  -X,   Y,  -Z-G },
-          };
-      int[][] vert_indices = new int[][]
-          {
-             {0,4,5,1},
-             {3,7,4,0},
-             {0,1,2,3},
-             {4,7,6,5},
-             {1,5,6,2},
-             {2,6,7,3}
-          };
-
-      float[][] bands     = new float[][] { {0.015f,35,0.5f*F,F,5,1,1},{0.001f,35,0.5f*F,F,5,1,1} };
-      int[] bandIndices   = new int[] { 0,0,1,1,1,1 };
-      float[][] corners   = new float[][] { {0.07f,0.20f*F} };
-      int[] cornerIndices = new int[] { 0,0,-1,0,0,0,-1,0 };
-      float[][] centers   = new float[][] { { 0, F*SQ2/2, 0 } };
-      int[] centerIndices = new int[] { 0,0,-1,0,0,0,-1,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-          {
-             {    0.0,     -2*Y2/3,   -2*Z2/3 },
-             {      X2,       Y2/3,      Z2/3 },
-             {     -X2,       Y2/3,      Z2/3 },
-             {    0.0,     -2*Y2/3,-2*Z2/3+2*D*Z2 },
-             {  X2-D*X2, Y2/3-D*Y2, Z2/3+D*Z2 },
-             { -X2+D*X2, Y2/3-D*Y2, Z2/3+D*Z2 },
-          };
-      int[][] vert_indices = new int[][]
-          {
-             {0,1,2},
-             {3,5,4},
-             {0,3,4,1},
-             {5,3,0,2},
-             {4,5,2,1}
-          };
-
-      float[][] bands     = new float[][] { {0.020f,35,0.20f*L,0.6f*L,5,1,1}, {0.001f,35,0.05f*L,0.1f*L,5,1,1} };
-      int[] bandIndices   = new int[] { 0,1,1,1,1,1 };
-      float[][] corners   = new float[][] { {0.04f,0.6f*F} };
-      int[] cornerIndices = new int[] { 0,0,0,-1,-1,-1 };
-      float[][] centers   = new float[][] { { 0, -2*Y/3, 4*Z/3 } };
-      int[] centerIndices = new int[] { 0,0,0,-1,-1,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    if( mRotQuat ==null ) mRotQuat = new int[] {0,1,2,7,0,2,7,6,3,10,0,1,3,5};
-    return mQuats[mRotQuat[cubit]];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<4 ? 0 : (cubit<10?1:2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-          {
-             { 0.0f, -0.5f, 0.28867516f, 0.0f, 0.0f, 0.5f, -0.28867516f, 0.0f },
-             { -0.5f, 0.11983269f, 0.27964598f, -0.43146032f, 0.3200817f, 0.007388768f, -0.09972769f, 0.30423886f },
-             { 0.0f, -0.5f, 0.43301272f, 0.25f, -0.43301272f, 0.25f },
-          };
-
-      mStickers = new ObjectSticker[STICKERS.length];
-      final float R1 = 0.05f;
-      final float R2 = 0.10f;
-      final float R3 = 0.03f;
-      final float[][] radii  = { { R1,R1,R1,R1 },{ R3,R3,R2,R2 },{ R1,R1,R1 } };
-      final float[] strokes = { 0.06f, 0.03f, 0.05f };
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement4(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.jing;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.jing_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 4;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyKilominx.java b/src/main/java/org/distorted/objects/TwistyKilominx.java
deleted file mode 100644
index edd09936..00000000
--- a/src/main/java/org/distorted/objects/TwistyKilominx.java
+++ /dev/null
@@ -1,711 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement12.COS54;
-import static org.distorted.objectlib.Movement12.SIN54;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.QuatHelper;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyKilominx extends TwistyMinx
-{
-  private int[] mCenterFaceMap;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyKilominx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.KILO, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeCenterFaceMap()
-    {
-    mCenterFaceMap = new int[]
-      {
-        0,0,0,0,1,
-        1,0,1,1,0,
-        2,0,1,1,0,
-        2,2,1,0,2,
-        2,1,0,0,1,
-        1,2,0,1,0,
-        0,1,0,1,1,
-        0,1,0,2,0,
-        2,1,2,2,2,
-        1,0,2,1,2,
-        2,1,0,1,2,
-        2,2,2,2,2
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numCubitsPerCorner(int numLayers)
-    {
-    return 3*((numLayers-3)/2)*((numLayers-5)/2) + (numLayers<5 ? 0:1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numCubitsPerEdge(int numLayers)
-    {
-    return numLayers<5 ? 0 : 2*(numLayers-4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return numLayers<5 ? 1 : numLayers/2 + 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    return genericGetCuts(numLayers,0.5f);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Fill out mCurrCorner{X,Y,Z} by applying appropriate Quat to mBasicCorner{X,Y,Z}
-// Appropriate one: QUATS[QUAT_INDICES[corner]].
-
-  private void computeBasicCornerVectors(int corner)
-    {
-    if( mQuatCornerIndices==null ) initializeQuatIndices();
-    if( mQuats==null ) initializeQuats();
-    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
-
-    Static4D quat = mQuats[mQuatCornerIndices[corner]];
-
-    mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
-    mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
-    mCurrCornerV[2] = QuatHelper.rotateVectorByQuat(mBasicCornerV[2],quat);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
-    {
-    if( mCorners==null ) initializeCorners();
-    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
-
-    float D = numLayers/3.0f;
-    float[] corn = mCorners[corner];
-
-    if( part==0 )
-      {
-      return new float[] { corn[0]*D, corn[1]*D, corn[2]*D };
-      }
-    else
-      {
-      float E = D/(0.5f*(numLayers-1));   // ?? maybe 0.5*
-      int N = (numCubitsPerCorner-1)/3;
-      int block = (part-1) % N;
-      int index = (part-1) / N;
-      Static4D pri = mCurrCornerV[index];
-      Static4D sec = mCurrCornerV[(index+2)%3];
-
-      int layers= (numLayers-5)/2;
-      int multP = (block % layers) + 1;
-      int multS = (block / layers);
-
-      return new float[] {
-                          corn[0]*D + (pri.get0()*multP + sec.get0()*multS)*E,
-                          corn[1]*D + (pri.get1()*multP + sec.get1()*multS)*E,
-                          corn[2]*D + (pri.get2()*multP + sec.get2()*multS)*E
-                         };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeCenter(int numLayers, int center, int part)
-    {
-    if( mCenterCoords==null ) initializeCenterCoords();
-    if( mCorners     ==null ) initializeCorners();
-    if( mCenterMap   ==null ) initializeCenterMap();
-
-    int corner = mCenterMap[center][part];
-    float[] cent = mCenterCoords[center];
-    float[] corn = mCorners[corner];
-    float D = numLayers/3.0f;
-    float F = 1.0f - (2.0f*numLayers-6.0f)/(numLayers-1)*COS54*COS54;
-
-    return new float[]
-      {
-        D * ( cent[0] + (corn[0]-cent[0])*F),
-        D * ( cent[1] + (corn[1]-cent[1])*F),
-        D * ( cent[2] + (corn[2]-cent[2])*F)
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeEdgeType(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
-    {
-    int part = (cubit - NUM_CORNERS*numCubitsPerCorner) % numCubitsPerEdge;
-    return part - 2*(part/4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeEdge(int numLayers, int edge, int part)
-    {
-    if( mCenterCoords==null ) initializeCenterCoords();
-    if( mCorners==null ) initializeCorners();
-    if( mEdgeMap==null ) initializeEdgeMap();
-
-    float D = numLayers/3.0f;
-    float[] c1 = mCorners[ mEdgeMap[edge][0] ];
-    float[] c2 = mCorners[ mEdgeMap[edge][1] ];
-
-    int leftRight = 2*(part%2) -1;
-    part /= 2;
-
-    if( part==0 )
-      {
-      float T = 0.5f + leftRight/(numLayers-1.0f);
-      float x = D * (T*c1[0]+(1.0f-T)*c2[0]);
-      float y = D * (T*c1[1]+(1.0f-T)*c2[1]);
-      float z = D * (T*c1[2]+(1.0f-T)*c2[2]);
-
-      return new float[] { x, y, z };
-      }
-    else
-      {
-      int mult = (part+1)/2;
-      int dir  = (part+1)%2;
-      float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
-      float x = 0.5f * D * (c1[0]+c2[0]);
-      float y = 0.5f * D * (c1[1]+c2[1]);
-      float z = 0.5f * D * (c1[2]+c2[2]);
-
-      float vX = D*center[0] - x;
-      float vY = D*center[1] - y;
-      float vZ = D*center[2] - z;
-
-      float T = 0.5f + leftRight*(mult*SIN18 + 1.0f)/(numLayers-1);
-
-      x = D * (T*c1[0]+(1.0f-T)*c2[0]);
-      y = D * (T*c1[1]+(1.0f-T)*c2[1]);
-      z = D * (T*c1[2]+(1.0f-T)*c2[2]);
-
-      float H = mult*D*COS18/(numLayers-1);
-      H /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
-
-      return new float[] { x + H*vX, y + H*vY, z + H*vZ };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    if( mCorners==null ) initializeCorners();
-    if( numLayers<5 ) return mCorners;
-
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-    int numCubitsPerCenter = 5;
-    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge + NUM_CENTERS*numCubitsPerCenter;
-    int index=0;
-
-    final float[][] CENTERS = new float[numCubits][];
-
-    for(int corner=0; corner<NUM_CORNERS; corner++)
-      {
-      computeBasicCornerVectors(corner);
-
-      for(int part=0; part<numCubitsPerCorner; part++, index++)
-        {
-        CENTERS[index] = computeCorner(numCubitsPerCorner,numLayers,corner,part);
-        }
-      }
-
-    for(int edge=0; edge<NUM_EDGES; edge++)
-      {
-      for(int part=0; part<numCubitsPerEdge; part++, index++)
-        {
-        CENTERS[index] = computeEdge(numLayers, edge, part );
-        }
-      }
-
-    for(int center=0; center<NUM_CENTERS; center++)
-      {
-      for(int part=0; part<numCubitsPerCenter; part++, index++)
-        {
-        CENTERS[index] = computeCenter(numLayers,center, part);
-        }
-      }
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
-    {
-    if( mQuatCornerIndices==null || mQuatEdgeIndices==null ) initializeQuatIndices();
-    if( mCenterMap==null ) initializeCenterMap();
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner )
-      {
-      int corner = cubit/numCubitsPerCorner;
-      return mQuatCornerIndices[corner];
-      }
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
-      return mQuatEdgeIndices[edge];
-      }
-
-    if( numCubitsPerCorner==0 )
-      {
-      return mQuatCornerIndices[cubit];
-      }
-    else
-      {
-      cubit -= (NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge);
-      int numCubitsPerCenter = 5;
-      int face = cubit/numCubitsPerCenter;
-      int index= cubit%numCubitsPerCenter;
-      int center=mCenterMap[face][index];
-      return mQuatCornerIndices[center];
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-    int numVariants = getNumCubitVariants(numLayers);
-
-    if( variant==0 )
-      {
-      float width = numLayers/(numLayers-1.0f);
-      float A = (2*SQ3/3)*SIN54;
-      float B = 0.4f;
-      double X = width*COS18*SIN_HALFD;
-      double Y = width*SIN18;
-      double Z = width*COS18*COS_HALFD;
-
-      double[][] vertices = new double[][]
-        {
-            { 0.0, 0.0      , 0.0 },
-            {   X,   Y      ,  -Z },
-            { 0.0, 2*Y      ,-2*Z },
-            {  -X,   Y      ,  -Z },
-            { 0.0, 0.0-width, 0.0 },
-            {   X,   Y-width,  -Z },
-            { 0.0, 2*Y-width,-2*Z },
-            {  -X,   Y-width,  -Z },
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-            {4,5,1,0},
-            {7,4,0,3},
-            {0,1,2,3},
-            {4,5,6,7},
-            {6,5,1,2},
-            {7,6,2,3}
-        };
-
-      float[][] bands     = new float[][]
-        {
-         {0.04f,34,0.3f,0.2f, 3, 1, 0},
-         {0.00f, 0,0.0f,0.0f, 2, 1, 0}
-        };
-
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1};
-      float[][] corners   = new float[][] { {0.04f,0.10f} };
-      int[] cornerIndices = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
-      float[][] centers   = new float[][] { {0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B} };
-      int[] centerIndices = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    if( variant<numVariants-1 )
-      {
-      int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-      int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-      int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);
-      float tmpVal= numLayers/(numLayers-1.0f);
-      float height= tmpVal*COS18;
-      float width = tmpVal + (type/2)*tmpVal*SIN18;
-      boolean left = (type%2)==0;
-
-      double X = height*SIN_HALFD;
-      double Y = height*SIN18/COS18;
-      double Z = height*COS_HALFD;
-
-      double[][] vertices = new double[][]
-        {
-            { 0.0, 0.0   , 0.0 },
-            {   X,   Y   ,  -Z },
-            { 0.0, 2*Y   ,-2*Z },
-            {  -X,   Y   ,  -Z },
-            { 0.0, -width, 0.0 },
-            {   X, -width,  -Z },
-            { 0.0, -width,-2*Z },
-            {  -X, -width,  -Z },
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-            {4,5,1,0},
-            {7,4,0,3},
-            {7,6,2,3},
-            {6,5,1,2},
-            {0,1,2,3},
-            {4,5,6,7}
-        };
-
-      if( !left )
-        {
-        int tmp, len = vertices.length;
-        for(int i=0; i<len; i++) vertices[i][1] = -vertices[i][1];
-
-        len = vertIndexes.length;
-        for(int i=0; i<len; i++)
-          {
-          tmp = vertIndexes[i][0];
-          vertIndexes[i][0] = vertIndexes[i][3];
-          vertIndexes[i][3] = tmp;
-          tmp = vertIndexes[i][1];
-          vertIndexes[i][1] = vertIndexes[i][2];
-          vertIndexes[i][2] = tmp;
-          }
-        }
-
-      int numBands0 = numLayers<=5 ? 4 : 3;
-      int numBands1 = numLayers<=5 ? 3 : 2;
-
-      float[][] bands     = new float[][]
-        {
-         {0.04f,34,0.2f,0.2f,numBands0,1,1},
-         {0.00f, 0,0.0f,0.0f,numBands1,0,0}
-        };
-
-      int[] bandIndices   = new int[] { 0,0,1,1,1,1};
-      float[][] corners   = new float[][] { {0.04f,0.10f} };
-      int[] cornerIndices = new int[] { 0,-1,-1,-1, 0,-1,-1,-1 };
-      float[][] centers   = new float[][] { {0.0f, -width/2, (float)(-2*Z)} };
-      int[] centerIndices = new int[] { 0,-1,-1,-1, 0,-1,-1,-1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      float width = (1+0.5f*(numLayers-3)*SIN18)*numLayers/(numLayers-1);
-
-      double X = width*COS18*SIN_HALFD;
-      double Y = width*SIN18;
-      double Z = width*COS18*COS_HALFD;
-      double H = width*(SIN54/COS54);
-      double H3= H/COS_HALFD;
-      double X3= H*SIN_HALFD;
-      double Z3= H*COS_HALFD;
-      double C = 1/(COS54*Math.sqrt(2-2*SIN18));
-      int N = numLayers==3 ? 4 : 3;
-      int E = numLayers==3 ? 1 : 0;
-
-      double[][] vertices = new double[][]
-        {
-            { 0.0, 0.0  ,   0.0 },
-            {   X,   Y  ,    -Z },
-            { 0.0,C*2*Y ,-2*C*Z },
-            {  -X,   Y  ,    -Z },
-            { 0.0,-width,   0.0 },
-            {  X3,-width,   -Z3 },
-            { 0.0,-width,   -H3 },
-            { -X3,-width,   -Z3 }
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-            {4,5,1,0},
-            {7,4,0,3},
-            {0,1,2,3},
-            {7,6,2,3},
-            {6,5,1,2},
-            {4,5,6,7}
-        };
-
-      float[][] bands = new float[][]
-        {
-         {0.04f,17,0.3f,0.2f,N,1,E},
-         {0.00f,17,0.3f,0.2f,N,1,E}
-        };
-
-      float A = (2*SQ3/3)*SIN54;
-      float B = 0.4f;
-
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1};
-      float[][] corners   = new float[][] { {0.03f,0.10f} };
-      int[] cornerIndices = new int[] { 0, 0,-1, 0, 0,-1,-1,-1 };
-      float[][] centers   = new float[][] { {0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B} };
-      int[] centerIndices = new int[] { 0, 0,-1, 0, 0,-1,-1,-1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    return mQuats[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    int[] sizes = ObjectList.KILO.getSizes();
-    int variants = sizes.length;
-    int highestSize = sizes[variants-1];
-
-    return highestSize-1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-
-    if( cubit<NUM_CORNERS*numCubitsPerCorner ) return 0;
-
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);
-      return type+1;
-      }
-
-    int[] sizes = ObjectList.KILO.getSizes();
-    int variants = sizes.length;
-    int highestSize = sizes[variants-1];
-
-    return highestSize-2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCornerColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner)
-    {
-    if( mCornerFaceMap==null ) initializeCornerFaceMap();
-    if( cubitface<0 || cubitface>2 ) return NUM_TEXTURES;
-
-    int part  = cubit % numCubitsPerCorner;
-    int corner= cubit / numCubitsPerCorner;
-
-    if( part==0 )
-      {
-      return mCornerFaceMap[corner][cubitface];
-      }
-    else
-      {
-      int N = (numCubitsPerCorner-1)/3;
-      int block = (part-1) % N;
-      int index = (part-1) / N;
-
-      if( block< (numLayers-3)/2 )
-        {
-        switch(index)
-          {
-          case 0: return cubitface==1 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          case 1: return cubitface==0 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          case 2: return cubitface==2 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          }
-        }
-      else
-        {
-        switch(index)
-          {
-          case 0: return cubitface==0 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          case 1: return cubitface==2 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          case 2: return cubitface==1 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          }
-        }
-      }
-
-    return NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getEdgeColor(int edge, int cubitface, int numCubitsPerEdge)
-    {
-    if( cubitface<0 || cubitface>1 ) return NUM_TEXTURES;
-
-    int part    = edge % numCubitsPerEdge;
-    int variant = edge / numCubitsPerEdge;
-    if( mEdgeMap==null ) initializeEdgeMap();
-
-    part /=2;
-
-    return (part==0 || cubitface==((part+1)%2)) ? mEdgeMap[variant][cubitface+2] + ((part+3)/2)*NUM_FACE_COLORS : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCenterColor(int center, int cubitface, int numLayers)
-    {
-    if( mCenterFaceMap==null ) initializeCenterFaceMap();
-    if( mCornerFaceMap==null ) initializeCornerFaceMap();
-
-    if( numLayers==3 )
-      {
-      return cubitface>=0 && cubitface<3 ? mCornerFaceMap[center][cubitface] : NUM_TEXTURES;
-      }
-
-    return cubitface==mCenterFaceMap[center] ? center/5 + NUM_FACE_COLORS*(numLayers-1)/2 : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner )
-      {
-      return getCornerColor(cubit,cubitface,numLayers,numCubitsPerCorner);
-      }
-    else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int edge = cubit - NUM_CORNERS*numCubitsPerCorner;
-      return getEdgeColor(edge,cubitface,numCubitsPerEdge);
-      }
-    else
-      {
-      int center = cubit-NUM_CORNERS*numCubitsPerCorner-NUM_EDGES*numCubitsPerEdge;
-      return getCenterColor( center, cubitface, numLayers);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-        {
-          { -0.36616942f, -0.36327124f, 0.5f, -0.36327124f, 0.23233888f, 0.4605048f, -0.36616942f, 0.26603764f },
-          { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
-          { -0.3249197f, -0.39442718f, 0.3249197f, -0.39442718f, 0.3249197f, 0.5f, -0.3249197f, 0.2888544f }
-        };
-
-      float CENTER_CORR = 0.87f;
-      float C = 1.14f; // make the 'center' sticker artificially larger, so that we paint over the area in the center of the face.
-
-      STICKERS[0][0] *= C;
-      STICKERS[0][1] *= C;
-      STICKERS[0][2] *= C;
-      STICKERS[0][3] *= C;
-      STICKERS[0][4] *= C;
-      STICKERS[0][5] *= C;
-      STICKERS[0][6] *= C;
-      STICKERS[0][7] *= C;
-
-      STICKERS[0][2] *= CENTER_CORR;
-      STICKERS[0][3] *= CENTER_CORR;
-
-      mStickers = new ObjectSticker[STICKERS.length];
-
-      float R = 0.10f;
-      final float[][] radii = { {R,R,R,R},{R,R,R,R},{R,R,R,R} };
-      final float[] strokes = { 0.20f, 0.11f, 0.10f };
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[getStickerIndex(face)];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getStickerIndex(int face)
-    {
-    int variant = face/NUM_FACE_COLORS;
-    int numLayers = getNumLayers();
-
-    if( variant == (numLayers-1)/2 || numLayers==3 ) return 0;
-    if( variant==0 ) return 1;
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    if( numLayers==3 ) return R.string.minx2;
-    if( numLayers==5 ) return R.string.minx4;
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    if( numLayers==3 ) return R.string.minx2_inventor;
-    if( numLayers==5 ) return R.string.minx4_inventor;
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 3;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
deleted file mode 100644
index df0c9157..00000000
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ /dev/null
@@ -1,619 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement12.COS54;
-import static org.distorted.objectlib.Movement12.SIN54;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.QuatHelper;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyMegaminx extends TwistyMinx
-{
-  static final float MEGA_D = 0.04f;
-  private int[] mQuatCenterIndices;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyMegaminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.MEGA, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeCenterIndices()
-    {
-    mQuatCenterIndices = new int[] { 16, 18, 22,  1, 20, 13, 14, 15,  0, 12,  2,  3 };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numCubitsPerCorner(int numLayers)
-    {
-    return 3*((numLayers-1)/2)*((numLayers-3)/2) + 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int numCubitsPerEdge(int numLayers)
-    {
-    return numLayers-2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return (numLayers+3)/2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    return genericGetCuts(numLayers,0.5f-MEGA_D);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeCenter(int center, int numLayers)
-    {
-    if( mCenterCoords==null ) initializeCenterCoords();
-    float[] coords = mCenterCoords[center];
-    float A = 0.33f*numLayers;
-
-    return new float[] { A*coords[0], A*coords[1], A*coords[2] };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Fill out mCurrCorner{X,Y,Z} by applying appropriate Quat to mBasicCorner{X,Y,Z}
-// Appropriate one: QUATS[QUAT_INDICES[corner]].
-
-  private void computeBasicCornerVectors(int corner)
-    {
-    if( mQuatCornerIndices==null ) initializeQuatIndices();
-    if( mQuats==null ) initializeQuats();
-    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
-
-    Static4D quat = mQuats[mQuatCornerIndices[corner]];
-
-    mCurrCornerV[0] = QuatHelper.rotateVectorByQuat(mBasicCornerV[0],quat);
-    mCurrCornerV[1] = QuatHelper.rotateVectorByQuat(mBasicCornerV[1],quat);
-    mCurrCornerV[2] = QuatHelper.rotateVectorByQuat(mBasicCornerV[2],quat);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeCorner(int numCubitsPerCorner, int numLayers, int corner, int part)
-    {
-    if( mCorners==null ) initializeCorners();
-    if( mCurrCornerV==null || mBasicCornerV==null ) initializeCornerV();
-
-    float D = numLayers/3.0f;
-    float[] corn = mCorners[corner];
-
-    if( part==0 )
-      {
-      return new float[] { corn[0]*D, corn[1]*D, corn[2]*D };
-      }
-    else
-      {
-      float E = 2.0f*D*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
-      int N = (numCubitsPerCorner-1)/3;
-      int block = (part-1) % N;
-      int index = (part-1) / N;
-      Static4D pri = mCurrCornerV[index];
-      Static4D sec = mCurrCornerV[(index+2)%3];
-
-      int layers= (numLayers-3)/2;
-      int multP = (block % layers) + 1;
-      int multS = (block / layers);
-
-      return new float[] {
-                          corn[0]*D + (pri.get0()*multP + sec.get0()*multS)*E,
-                          corn[1]*D + (pri.get1()*multP + sec.get1()*multS)*E,
-                          corn[2]*D + (pri.get2()*multP + sec.get2()*multS)*E
-                         };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int computeEdgeType(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
-    {
-    int part = (cubit - NUM_CORNERS*numCubitsPerCorner) % numCubitsPerEdge;
-    return (part+1)/2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] computeEdge(int numLayers, int edge, int part)
-    {
-    if( mCenterCoords==null ) initializeCenterCoords();
-    if( mCorners==null ) initializeCorners();
-    if( mEdgeMap==null ) initializeEdgeMap();
-
-    float D = numLayers/3.0f;
-    float[] c1 = mCorners[ mEdgeMap[edge][0] ];
-    float[] c2 = mCorners[ mEdgeMap[edge][1] ];
-    float x = D * (c1[0]+c2[0]) / 2;
-    float y = D * (c1[1]+c2[1]) / 2;
-    float z = D * (c1[2]+c2[2]) / 2;
-
-    if( part==0 )
-      {
-      return new float[] { x, y, z };
-      }
-    else
-      {
-      int mult = (part+1)/2;
-      int dir  = (part+1)%2;
-      float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
-
-      float vX = D*center[0] - x;
-      float vY = D*center[1] - y;
-      float vZ = D*center[2] - z;
-
-      float A = 3*mult*D*(0.5f-MEGA_D)*COS18/((numLayers-1)*0.5f);
-      A /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
-
-      return new float[] { x+A*vX, y+A*vY, z+A*vZ };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge + NUM_CENTERS;
-    int index=0;
-
-    final float[][] CENTERS = new float[numCubits][];
-
-    for(int corner=0; corner<NUM_CORNERS; corner++)
-      {
-      computeBasicCornerVectors(corner);
-
-      for(int part=0; part<numCubitsPerCorner; part++, index++)
-        {
-        CENTERS[index] = computeCorner(numCubitsPerCorner,numLayers,corner,part);
-        }
-      }
-
-    for(int edge=0; edge<NUM_EDGES; edge++)
-      {
-      for(int part=0; part<numCubitsPerEdge; part++, index++)
-        {
-        CENTERS[index] = computeEdge(numLayers, edge, part );
-        }
-      }
-
-    for(int center=0; center<NUM_CENTERS; center++, index++)
-      {
-      CENTERS[index] = computeCenter(center, numLayers);
-      }
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
-    {
-    if( mQuatCornerIndices==null || mQuatEdgeIndices==null ) initializeQuatIndices();
-    if( mQuatCenterIndices==null ) initializeCenterIndices();
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner )
-      {
-      int corner = cubit/numCubitsPerCorner;
-      return mQuatCornerIndices[corner];
-      }
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
-      return mQuatEdgeIndices[edge];
-      }
-
-    int center = cubit - NUM_CORNERS*numCubitsPerCorner - NUM_EDGES*numCubitsPerEdge;
-    return mQuatCenterIndices[center];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-    int numVariants = getNumCubitVariants(numLayers);
-
-    if( variant==0 )
-      {
-      float width = numLayers*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
-      float A = (2*SQ3/3)*SIN54;
-      float B = 0.4f;
-      double X = width*COS18*SIN_HALFD;
-      double Y = width*SIN18;
-      double Z = width*COS18*COS_HALFD;
-      int N = numLayers==3 ? 1:0;
-
-      double[][] vertices = new double[][]
-        {
-            { 0.0, 0.0      , 0.0 },
-            {   X,   Y      ,  -Z },
-            { 0.0, 2*Y      ,-2*Z },
-            {  -X,   Y      ,  -Z },
-            { 0.0, 0.0-width, 0.0 },
-            {   X,   Y-width,  -Z },
-            { 0.0, 2*Y-width,-2*Z },
-            {  -X,   Y-width,  -Z },
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-            {4,5,1,0},
-            {7,4,0,3},
-            {0,1,2,3},
-            {4,5,6,7},
-            {6,5,1,2},
-            {7,6,2,3}
-        };
-
-      float[][] bands    = new float[][]
-        {
-         {0.04f,34,0.3f,0.2f, 3, N, 0},
-         {0.00f, 0,0.0f,0.0f, 2, N, 0}
-        };
-
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1};
-      float[][] corners   = new float[][] { {0.04f,0.10f} };
-      int[] cornerIndices = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
-      float[][] centers   = new float[][] { {0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B} };
-      int[] centerIndices = new int[] { 0,-1,-1,-1,-1,-1,-1,-1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    if( variant<numVariants-1 )
-      {
-      int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-      int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-      int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);
-      float height= numLayers*(0.5f-MEGA_D)*COS18/((numLayers-1)*0.5f);
-      float width = numLayers*2*MEGA_D + 2*type*height*SIN18/COS18;
-
-      double W = width/2;
-      double X = height*SIN_HALFD;
-      double Y = height*SIN18/COS18;
-      double Z = height*COS_HALFD;
-
-      double[][] vertices = new double[][]
-        {
-            { 0.0,   W   , 0.0 },
-            {   X, W+Y   ,  -Z },
-            { 0.0, W+2*Y ,-2*Z },
-            {  -X, W+Y   ,  -Z },
-            { 0.0,  -W   , 0.0 },
-            {   X,-W-Y   ,  -Z },
-            { 0.0,-W-2*Y ,-2*Z },
-            {  -X,-W-Y   ,  -Z },
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-            {4,5,1,0},
-            {7,4,0,3},
-            {7,6,2,3},
-            {6,5,1,2},
-            {0,1,2,3},
-            {4,5,6,7}
-        };
-
-      int N = numLayers<=5 ? 5 : 3;
-
-      float[][] bands     = new float[][]
-        {
-         {0.04f,34,0.2f,0.2f,N,0,0},
-         {0.00f, 0,0.3f,0.2f,2,0,0}
-        };
-      int[] bandIndices   = new int[] { 0,0,1,1,1,1};
-      float[][] corners   = new float[][] { {0.04f,0.10f} };
-      int[] cornerIndices = new int[] { -1,-1,-1,-1, -1,-1,-1,-1 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, (float)(-2*Z)} };
-      int[] centerIndices = new int[] { -1,-1,-1,-1, -1,-1,-1,-1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      float width = 2*numLayers*(MEGA_D+(0.5f-MEGA_D)*SIN18);
-      final double V = 0.83;   // ??
-      final double ANGLE = V*Math.PI;
-      final double cosA  = Math.cos(ANGLE);
-      final double sinA  = Math.sin(ANGLE);
-
-      float R  = 0.5f*width/COS54;
-      float X1 = R*COS54;
-      float Y1 = R*SIN54;
-      float X2 = R*COS18;
-      float Y2 = R*SIN18;
-
-      double[][] vertices = new double[][]
-        {
-          {-X1,+Y1*sinA, Y1*cosA},
-          {-X2,-Y2*sinA,-Y2*cosA},
-          {0.0f,-R*sinA, -R*cosA},
-          {+X2,-Y2*sinA,-Y2*cosA},
-          {+X1,+Y1*sinA, Y1*cosA}
-        };
-
-      int[][] vertIndexes = new int[][]
-        {
-          {0,1,2,3,4},
-          {0,1,2,3,4}
-        };
-
-      int N = numLayers==3 ? 4 : 3;
-
-      float[][] bands = new float[][]
-        {
-         {0.04f,45, R/3,0.2f,N,0,0},
-         {0.00f, 0, R/3,0.2f,2,0,0}
-        };
-
-      int[] bandIndices   = new int[] { 0,1 };
-      float[][] corners   = new float[][] { {0.04f,0.10f} };
-      int[] cornerIndices = new int[] { -1,-1,-1,-1, -1 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { -1,-1,-1,-1, -1 };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    return mQuats[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    int[] sizes = ObjectList.MEGA.getSizes();
-    int variants = sizes.length;
-
-    return 2+(sizes[variants-1]-1)/2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-
-    if( cubit<NUM_CORNERS*numCubitsPerCorner ) return 0;
-
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);
-      return type+1;
-      }
-
-    int[] sizes = ObjectList.MEGA.getSizes();
-    int variants = sizes.length;
-    int numShapes = 2+(sizes[variants-1]-1)/2;
-
-    return numShapes-1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCornerColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner)
-    {
-    if( mCornerFaceMap==null ) initializeCornerFaceMap();
-    if( cubitface<0 || cubitface>2 ) return NUM_TEXTURES;
-
-    int part  = cubit % numCubitsPerCorner;
-    int corner= cubit / numCubitsPerCorner;
-
-    if( part==0 )
-      {
-      return mCornerFaceMap[corner][cubitface];
-      }
-    else
-      {
-      int N = (numCubitsPerCorner-1)/3;
-      int block = (part-1) % N;
-      int index = (part-1) / N;
-
-      if( block< (numLayers-3)/2 )
-        {
-        switch(index)
-          {
-          case 0: return cubitface==1 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          case 1: return cubitface==0 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          case 2: return cubitface==2 ? NUM_TEXTURES : mCornerFaceMap[corner][cubitface];
-          }
-        }
-      else
-        {
-        switch(index)
-          {
-          case 0: return cubitface==0 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          case 1: return cubitface==2 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          case 2: return cubitface==1 ? mCornerFaceMap[corner][cubitface] : NUM_TEXTURES;
-          }
-        }
-      }
-
-    return NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getEdgeColor(int edge, int cubitface, int numCubitsPerEdge)
-    {
-    if( cubitface<0 || cubitface>1 ) return NUM_TEXTURES;
-
-    int part    = edge % numCubitsPerEdge;
-    int variant = edge / numCubitsPerEdge;
-    if( mEdgeMap==null ) initializeEdgeMap();
-
-    return (part==0 || cubitface==((part+1)%2)) ? mEdgeMap[variant][cubitface+2] + ((part+3)/2)*NUM_FACE_COLORS : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getCenterColor(int center, int cubitface, int numLayers)
-    {
-    return cubitface>0 ? NUM_TEXTURES : center + NUM_FACE_COLORS*(numLayers+1)/2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-    int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-
-    if( cubit < NUM_CORNERS*numCubitsPerCorner )
-      {
-      return getCornerColor(cubit,cubitface,numLayers,numCubitsPerCorner);
-      }
-    else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
-      {
-      int edge = cubit - NUM_CORNERS*numCubitsPerCorner;
-      return getEdgeColor(edge,cubitface,numCubitsPerEdge);
-      }
-    else
-      {
-      int center = cubit-NUM_CORNERS*numCubitsPerCorner-NUM_EDGES*numCubitsPerEdge;
-      return getCenterColor( center, cubitface, numLayers);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-        {
-          { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
-          { -0.5f, -0.0914315f, 0.5f, -0.4163512f, 0.5f, 0.4163512f, -0.5f, 0.0914315f },
-          { -0.49233657f, -0.18006028f, 0.49233657f, -0.5f, 0.49233657f, 0.5f, -0.49233657f, 0.18006028f },
-          { -0.3002273f, -0.30490047f, 0.3002273f, -0.5f, 0.3002273f, 0.5f, -0.3002273f, 0.30490047f },
-          { -0.29389262f, 0.4045085f, -0.47552824f, -0.1545085f, 0.0f, -0.5f, 0.47552824f, -0.1545085f, 0.29389262f, 0.4045085f }
-        };
-
-      mStickers = new ObjectSticker[STICKERS.length];
-
-      final float R0 = 0.08f;
-      final float R1 = 0.12f;
-      final float R2 = 0.12f;
-      final float R3 = 0.08f;
-      final float R4 = 0.10f;
-      final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4,R4,R4} };
-      final float[] strokes = { 0.10f,0.12f,0.12f,0.08f,0.07f };
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[getStickerIndex(face)];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getStickerIndex(int face)
-    {
-    int variant = face/NUM_FACE_COLORS;
-
-    if( variant==0 ) return 0;
-
-    int numLayers = getNumLayers();
-
-    if( variant < (numLayers+1)/2 )
-      {
-      if( numLayers==3 ) return 1;
-      else
-        {
-        if( variant==1 ) return 2;
-        else             return 3;
-        }
-      }
-
-    return 4;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    if( numLayers==3 ) return R.string.minx3;
-    if( numLayers==5 ) return R.string.minx5;
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    if( numLayers==3 ) return R.string.minx3_inventor;
-    if( numLayers==5 ) return R.string.minx5_inventor;
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    if( numLayers==3 ) return 4;
-
-    return 5;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
deleted file mode 100644
index 6807fef1..00000000
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ /dev/null
@@ -1,625 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_EDGE;
-import static org.distorted.objectlib.Movement12.C2;
-import static org.distorted.objectlib.Movement12.LEN;
-import static org.distorted.objectlib.Movement12.SIN54;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement12;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty12;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract class TwistyMinx extends Twisty12
-{
-  static final int NUM_CORNERS = 20;
-  static final int NUM_CENTERS = 12;
-  static final int NUM_EDGES   = 30;
-
-  static final float SIN18    = (SQ5-1)/4;
-  static final float COS18    = (float)(0.25f*Math.sqrt(10.0f+2.0f*SQ5));
-  static final float COS_HALFD= (float)(Math.sqrt(0.5f-0.1f*SQ5)); // cos(half the dihedral angle)
-  static final float SIN_HALFD= (float)(Math.sqrt(0.5f+0.1f*SQ5)); // sin(half the dihedral angle)
-
-  // the six rotation axis of a Minx. Must be normalized.
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           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( SIN54/LEN,    0     ,    C2/LEN ),
-           new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{2,3},{3,5},{1,5},{1,4},{2,4}},
-          {{0,5},{2,5},{2,3},{3,4},{0,4}},
-          {{2,3},{2,5},{0,5},{0,4},{3,4}},
-          {{1,5},{3,5},{2,3},{2,4},{1,4}},
-          {{0,3},{0,4},{4,5},{1,5},{1,3}},
-          {{1,2},{1,4},{4,5},{0,5},{0,2}},
-          {{4,5},{1,4},{1,2},{0,2},{0,5}},
-          {{4,5},{0,4},{0,3},{1,3},{1,5}},
-          {{0,2},{0,1},{1,3},{3,5},{2,5}},
-          {{3,4},{2,4},{1,2},{0,1},{0,3}},
-          {{2,4},{3,4},{0,3},{0,1},{1,2}},
-          {{1,3},{0,1},{0,2},{2,5},{3,5}},
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private int[] mFaceMap;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private Movement mMovement;
-  Static4D[] mQuats;
-  float[][] mCenterCoords;
-  float[][] mCorners;
-  int[][] mCornerFaceMap;
-  int[] mQuatEdgeIndices;
-  int[] mQuatCornerIndices;
-  int[][] mEdgeMap;
-  int[][] mCenterMap;
-  Static4D[] mBasicCornerV, mCurrCornerV;
-  ObjectSticker[] mStickers;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-             DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
-    {
-    super(numLayers, realSize, quat, texture, mesh, effects, moves, obj, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int numLayers = getNumLayers();
-      initializeScrambleStates(numLayers);
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeCornerV()
-    {
-    mBasicCornerV = new Static4D[3];
-    mCurrCornerV  = new Static4D[3];
-
-    mBasicCornerV[0] = new Static4D( (SQ5+1)*0.375f, (SQ5-1)*0.375f, -0.750f, 0.0f );
-    mBasicCornerV[1] = new Static4D(-(SQ5+1)*0.375f, (SQ5-1)*0.375f, -0.750f, 0.0f );
-    mBasicCornerV[2] = new Static4D(              0,        -1.500f,    0.0f, 0.0f );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// the five vertices that form a given face. Order: the same as colors of the faces in TwistyMinx.
-
-  void initializeCenterMap()
-    {
-    mCenterMap = new int[][]
-         {
-           { 0, 12,  4, 14,  2},
-           { 0,  2, 18,  6, 16},
-           { 6, 18, 11, 19,  7},
-           { 3, 15,  9, 11, 19},
-           { 4,  5, 15,  9, 14},
-           { 1, 13,  5, 15,  3},
-           { 1,  3, 19,  7, 17},
-           {10, 16,  6,  7, 17},
-           { 0, 12,  8, 10, 16},
-           { 8, 13,  5,  4, 12},
-           { 1, 13,  8, 10, 17},
-           { 2, 14,  9, 11, 18},
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// the quadruple ( corner1, corner2, face1, face2 ) defining an edge.
-// In fact the 2 corners already define it, the faces only provide easy
-// way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
-// the 'left' or right of vector corner1 --> corner2, according to Quat.
-
-  void initializeEdgeMap()
-    {
-    mEdgeMap = new int[][]
-         {
-           {  0, 12,  0,  8}, //0
-           { 12,  4,  0,  9},
-           {  4, 14,  0,  4},
-           { 14,  2,  0, 11},
-           {  2,  0,  0,  1},
-           { 14,  9, 11,  4}, //5
-           {  9, 11, 11,  3},
-           { 11, 18, 11,  2},
-           { 18,  2, 11,  1},
-           { 18,  6,  1,  2},
-           {  6, 16,  1,  7}, //10
-           { 16,  0,  1,  8},
-           { 16, 10,  8,  7},
-           { 10,  8,  8, 10},
-           {  8, 12,  8,  9},
-           {  8, 13,  9, 10}, //15
-           { 13,  5,  9,  5},
-           {  5,  4,  9,  4},
-           {  5, 15,  4,  5},
-           { 15,  9,  4,  3},
-           { 11, 19,  2,  3}, //20
-           { 19,  7,  2,  6},
-           {  7,  6,  2,  7},
-           {  7, 17,  7,  6},
-           { 17, 10,  7, 10},
-           { 17,  1, 10,  6}, //25
-           {  1,  3,  5,  6},
-           {  3, 19,  3,  6},
-           {  1, 13, 10,  5},
-           {  3, 15,  5,  3},
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeQuatIndices()
-    {
-    mQuatEdgeIndices = new int[]
-      {
-        56, 40, 43, 59,  0, 19,  9, 54, 58, 49,
-        48, 24, 52,  4, 16, 32, 20, 11, 21, 35,
-        37, 30,  8, 28, 36, 44,  1, 46, 12, 47
-      };
-    mQuatCornerIndices = new int[]
-      {
-         0,  2,  3,  1, 40, 31, 41, 30, 39, 35,
-        36, 34, 56, 32, 43, 21, 48, 28, 42, 23
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeCornerFaceMap()
-    {
-    mCornerFaceMap = new int[][]
-         {
-           {  0, 1, 8 },
-           {  6, 5,10 },
-           {  1, 0,11 },
-           {  5, 6, 3 },
-           {  0, 9, 4 },
-           {  5, 4, 9 },
-           {  7, 1, 2 },
-           {  2, 6, 7 },
-           { 10, 9, 8 },
-           {  4, 3,11 },
-           {  7,10, 8 },
-           {  3, 2,11 },
-           {  0, 8, 9 },
-           {  9,10, 5 },
-           {  0, 4,11 },
-           {  4, 5, 3 },
-           {  1, 7, 8 },
-           {  7, 6,10 },
-           {  2, 1,11 },
-           {  6, 2, 3 },
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),  //0
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),  //4
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D( -0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D( -0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D( -0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D( -0.5f, -0.5f, -0.5f,  0.5f ),
-
-         new Static4D(  0.5f, SIN54, SIN18,  0.0f ), // 12
-         new Static4D(  0.5f, SIN54,-SIN18,  0.0f ),
-         new Static4D(  0.5f,-SIN54, SIN18,  0.0f ),
-         new Static4D(  0.5f,-SIN54,-SIN18,  0.0f ),
-         new Static4D( SIN18,  0.5f, SIN54,  0.0f ),
-         new Static4D( SIN18,  0.5f,-SIN54,  0.0f ),
-         new Static4D(-SIN18,  0.5f, SIN54,  0.0f ),
-         new Static4D(-SIN18,  0.5f,-SIN54,  0.0f ),
-         new Static4D( SIN54, SIN18,  0.5f,  0.0f ),
-         new Static4D( SIN54,-SIN18,  0.5f,  0.0f ),
-         new Static4D(-SIN54, SIN18,  0.5f,  0.0f ),
-         new Static4D(-SIN54,-SIN18,  0.5f,  0.0f ),
-
-         new Static4D(  0.0f, SIN18, SIN54,  0.5f ), //24
-         new Static4D(  0.0f, SIN18,-SIN54,  0.5f ),
-         new Static4D(  0.0f,-SIN18, SIN54,  0.5f ),
-         new Static4D(  0.0f,-SIN18,-SIN54,  0.5f ),
-         new Static4D( SIN18, SIN54,  0.0f,  0.5f ),
-         new Static4D( SIN18,-SIN54,  0.0f,  0.5f ),
-         new Static4D(-SIN18, SIN54,  0.0f,  0.5f ),
-         new Static4D(-SIN18,-SIN54,  0.0f,  0.5f ),
-         new Static4D( SIN54,  0.0f, SIN18,  0.5f ),
-         new Static4D( SIN54,  0.0f,-SIN18,  0.5f ),
-         new Static4D(-SIN54,  0.0f, SIN18,  0.5f ),
-         new Static4D(-SIN54,  0.0f,-SIN18,  0.5f ),
-
-         new Static4D(  0.0f, SIN54,  0.5f, SIN18 ), //36
-         new Static4D(  0.0f, SIN54, -0.5f, SIN18 ),
-         new Static4D(  0.0f,-SIN54,  0.5f, SIN18 ),
-         new Static4D(  0.0f,-SIN54, -0.5f, SIN18 ),
-         new Static4D(  0.5f,  0.0f, SIN54, SIN18 ),
-         new Static4D(  0.5f,  0.0f,-SIN54, SIN18 ),
-         new Static4D( -0.5f,  0.0f, SIN54, SIN18 ),
-         new Static4D( -0.5f,  0.0f,-SIN54, SIN18 ),
-         new Static4D( SIN54,  0.5f,  0.0f, SIN18 ),
-         new Static4D( SIN54, -0.5f,  0.0f, SIN18 ),
-         new Static4D(-SIN54,  0.5f,  0.0f, SIN18 ),
-         new Static4D(-SIN54, -0.5f,  0.0f, SIN18 ),
-
-         new Static4D(  0.0f,  0.5f, SIN18, SIN54 ), //48
-         new Static4D(  0.0f,  0.5f,-SIN18, SIN54 ),
-         new Static4D(  0.0f, -0.5f, SIN18, SIN54 ),
-         new Static4D(  0.0f, -0.5f,-SIN18, SIN54 ),
-         new Static4D(  0.5f, SIN18,  0.0f, SIN54 ),
-         new Static4D(  0.5f,-SIN18,  0.0f, SIN54 ),
-         new Static4D( -0.5f, SIN18,  0.0f, SIN54 ),
-         new Static4D( -0.5f,-SIN18,  0.0f, SIN54 ),
-         new Static4D( SIN18,  0.0f,  0.5f, SIN54 ),
-         new Static4D( SIN18,  0.0f, -0.5f, SIN54 ),
-         new Static4D(-SIN18,  0.0f,  0.5f, SIN54 ),
-         new Static4D(-SIN18,  0.0f, -0.5f, SIN54 ),
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Coordinates of all 20 corners of a Minx
-
-  void initializeCorners()
-    {
-    float cA = 1.5f;
-    float cB = 3*C2;
-    float cC = 3*SIN54;
-
-    mCorners = new float[][]
-         {
-             {  0, cA, cB},
-             {  0, cA,-cB},
-             {  0,-cA, cB},
-             {  0,-cA,-cB},
-             { cB,  0, cA},
-             { cB,  0,-cA},
-             {-cB,  0, cA},
-             {-cB,  0,-cA},
-             { cA, cB,  0},
-             { cA,-cB,  0},
-             {-cA, cB,  0},
-             {-cA,-cB,  0},
-             { cC, cC, cC},
-             { cC, cC,-cC},
-             { cC,-cC, cC},
-             { cC,-cC,-cC},
-             {-cC, cC, cC},
-             {-cC, cC,-cC},
-             {-cC,-cC, cC},
-             {-cC,-cC,-cC},
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeCenterCoords()
-    {
-    if( mCorners==null ) initializeCorners();
-    if( mCenterMap==null ) initializeCenterMap();
-
-    mCenterCoords = new float[NUM_CENTERS][3];
-
-    for(int center=0; center<NUM_CENTERS; center++)
-      {
-      int[] map = mCenterMap[center];
-
-      float x = mCorners[map[0]][0] +
-                mCorners[map[1]][0] +
-                mCorners[map[2]][0] +
-                mCorners[map[3]][0] +
-                mCorners[map[4]][0] ;
-
-      float y = mCorners[map[0]][1] +
-                mCorners[map[1]][1] +
-                mCorners[map[2]][1] +
-                mCorners[map[3]][1] +
-                mCorners[map[4]][1] ;
-
-      float z = mCorners[map[0]][2] +
-                mCorners[map[1]][2] +
-                mCorners[map[2]][2] +
-                mCorners[map[3]][2] +
-                mCorners[map[4]][2] ;
-
-      mCenterCoords[center][0] = x/5;
-      mCenterCoords[center][1] = y/5;
-      mCenterCoords[center][2] = z/5;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[] generateL(int numLayers, int index)
-    {
-    int rows = (numLayers-1)/2;
-    int[] ret = new int[3*4*rows];
-
-    for(int i=0; i<rows; i++)
-      {
-      ret[12*i   ] = i;
-      ret[12*i+ 1] =-2;
-      ret[12*i+ 2] = index;
-      ret[12*i+ 3] = i;
-      ret[12*i+ 4] =-1;
-      ret[12*i+ 5] = index;
-      ret[12*i+ 6] = i;
-      ret[12*i+ 7] =+1;
-      ret[12*i+ 8] = index;
-      ret[12*i+ 9] = i;
-      ret[12*i+10] =+2;
-      ret[12*i+11] = index;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[] generateR(int numLayers, int index)
-    {
-    int rows = (numLayers-1)/2;
-    int[] ret = new int[3*4*rows];
-
-    for(int i=0; i<rows; i++)
-      {
-      int lay = rows+i+1;
-
-      ret[12*i   ] = lay;
-      ret[12*i+ 1] =-2;
-      ret[12*i+ 2] = index;
-      ret[12*i+ 3] = lay;
-      ret[12*i+ 4] =-1;
-      ret[12*i+ 5] = index;
-      ret[12*i+ 6] = lay;
-      ret[12*i+ 7] =+1;
-      ret[12*i+ 8] = index;
-      ret[12*i+ 9] = lay;
-      ret[12*i+10] =+2;
-      ret[12*i+11] = index;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[] generateB(int numLayers, int index)
-    {
-    int rows = (numLayers-1);
-    int half = rows/2;
-    int[] ret = new int[3*4*rows];
-
-    for(int i=0; i<rows; i++)
-      {
-      int ind = i<half? index : index+1;
-      int lay = i<half? i : i+1;
-
-      ret[12*i   ] = lay;
-      ret[12*i+ 1] =-2;
-      ret[12*i+ 2] = ind;
-      ret[12*i+ 3] = lay;
-      ret[12*i+ 4] =-1;
-      ret[12*i+ 5] = ind;
-      ret[12*i+ 6] = lay;
-      ret[12*i+ 7] =+1;
-      ret[12*i+ 8] = ind;
-      ret[12*i+ 9] = lay;
-      ret[12*i+10] =+2;
-      ret[12*i+11] = ind;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambleStates(int numLayers)
-    {
-    int[] LEFT0 = generateL(numLayers,1);
-    int[] RIGH0 = generateR(numLayers,2);
-    int[] LEFT1 = generateL(numLayers,3);
-    int[] RIGH1 = generateR(numLayers,4);
-    int[] LEFT2 = generateL(numLayers,5);
-    int[] RIGH2 = generateR(numLayers,6);
-    int[] LEFT3 = generateL(numLayers,7);
-    int[] RIGH3 = generateR(numLayers,8);
-    int[] LEFT4 = generateL(numLayers,9);
-    int[] RIGH4 = generateR(numLayers,10);
-    int[] LEFT5 = generateL(numLayers,11);
-    int[] RIGH5 = generateR(numLayers,12);
-
-    int[] BOTH1 = generateB(numLayers,1);
-    int[] BOTH3 = generateB(numLayers,3);
-    int[] BOTH5 = generateB(numLayers,5);
-    int[] BOTH7 = generateB(numLayers,7);
-    int[] BOTH9 = generateB(numLayers,9);
-    int[] BOTH11= generateB(numLayers,11);
-
-    mStates = new ScrambleState[]
-      {
-      new ScrambleState( new int[][] { BOTH1,BOTH3,BOTH5,BOTH7,BOTH9,BOTH11 } ), // beg
-      new ScrambleState( new int[][] { {}   ,RIGH1,LEFT2,RIGH3,LEFT4,LEFT5  } ), // 0L
-      new ScrambleState( new int[][] { {}   ,LEFT1,RIGH2,LEFT3,RIGH4,RIGH5  } ), // 0R
-      new ScrambleState( new int[][] { RIGH0,{}   ,LEFT2,RIGH3,RIGH4,RIGH5  } ), // 1L
-      new ScrambleState( new int[][] { LEFT0,{}   ,RIGH2,LEFT3,LEFT4,LEFT5  } ), // 1R
-      new ScrambleState( new int[][] { LEFT0,LEFT1,{}   ,RIGH3,LEFT4,RIGH5  } ), // 2L
-      new ScrambleState( new int[][] { RIGH0,RIGH1,{}   ,LEFT3,RIGH4,LEFT5  } ), // 2R
-      new ScrambleState( new int[][] { RIGH0,RIGH1,RIGH2,{}   ,LEFT4,RIGH5  } ), // 3L
-      new ScrambleState( new int[][] { LEFT0,LEFT1,LEFT2,{}   ,RIGH4,LEFT5  } ), // 3R
-      new ScrambleState( new int[][] { LEFT0,RIGH1,LEFT2,LEFT3,{}   ,RIGH5  } ), // 4L
-      new ScrambleState( new int[][] { RIGH0,LEFT1,RIGH2,RIGH3,{}   ,LEFT5  } ), // 4R
-      new ScrambleState( new int[][] { LEFT0,RIGH1,RIGH2,RIGH3,RIGH4,{}     } ), // 5L
-      new ScrambleState( new int[][] { RIGH0,LEFT1,LEFT2,LEFT3,LEFT4,{}     } ), // 5R
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    if( mFaceMap==null ) mFaceMap = new int[] {8,10,3,7,1,11,9,2,4,0,5,6};
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[mFaceMap[status]],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  float[][] genericGetCuts(int numLayers, float dist)
-    {
-    if( mCuts==null )
-      {
-      mCuts = new float[6][numLayers-1];
-      float D = numLayers*Movement12.DIST3D;
-      float X = 2*D/(2+SIN18);  // height of the 'upper' part of a dodecahedron, i.e. put it on a table,
-                                // its height is then 2D, it has one 'lower' part of height X, one
-                                // 'middle' part of height Y and one upper part of height X again.
-      int num = (numLayers-1)/2;
-      float G = X*dist/num;     // height of one Layer
-
-      for(int i=0; i<num; i++)
-        {
-        float cut = -D + (i+0.85f)*G;  // 0.85? not fully correct; attempt to make it
-                                       // easier to rotate the outer layers
-        int j = 2*num-1-i;
-        mCuts[0][i] = +cut;
-        mCuts[0][j] = -cut;
-        mCuts[1][i] = +cut;
-        mCuts[1][j] = -cut;
-        mCuts[2][i] = +cut;
-        mCuts[2][j] = -cut;
-        mCuts[3][i] = +cut;
-        mCuts[3][j] = -cut;
-        mCuts[4][i] = +cut;
-        mCuts[4][j] = -cut;
-        mCuts[5][i] = +cut;
-        mCuts[5][j] = -cut;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      tmp[numLayers/2] = false;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement12(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_EDGE,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 5,5,5,5,5,5 };
-    return mBasicAngle;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyMirror.java b/src/main/java/org/distorted/objects/TwistyMirror.java
deleted file mode 100644
index 3846e29e..00000000
--- a/src/main/java/org/distorted/objects/TwistyMirror.java
+++ /dev/null
@@ -1,716 +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.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyMirror extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(1,0,0),
-           new Static3D(0,1,0),
-           new Static3D(0,0,1)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
-      };
-
-  private static final int[] FACE_COLORS = new int[] { COLOR_WHITE };
-  private static final float DX = 0.10f;
-  private static final float DY = 0.25f;
-  private static final float DZ = 0.40f;
-
-  private ScrambleState[] mStates;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[] mBasicAngle;
-  private ObjectSticker[] mStickers;
-  private float[][] mPositions;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyMirror(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                      DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.MIRR, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int size = getNumLayers();
-      int[][] m = new int[16][];
-      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
-        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
-        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
-        new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
-        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
-        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
-        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
-        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
-        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
-        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
-        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
-        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
-        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
-        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
-        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
-        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[] createEdges(int size, int vertex)
-    {
-    int[] ret = new int[9*size];
-
-    for(int l=0; l<size; l++)
-      {
-      ret[9*l  ] = l;
-      ret[9*l+1] =-1;
-      ret[9*l+2] = vertex;
-      ret[9*l+3] = l;
-      ret[9*l+4] = 1;
-      ret[9*l+5] = vertex;
-      ret[9*l+6] = l;
-      ret[9*l+7] = 2;
-      ret[9*l+8] = vertex;
-      }
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
-         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
-         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
-
-         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
-         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
-         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
-         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
-         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
-         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
-         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
-
-         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
-         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
-         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
-         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// we cannot do this the standard, automatic way because there's only 1 color in the FACE_COLORS
-// table and retCubitSolvedStatus() always returns -1,-1 or 0.
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( numLayers==3 )
-      {
-      switch(cubit)
-        {
-        case  4:
-        case 21: return new int[] {1,8,9};
-        case 10:
-        case 15: return new int[] {2,12,13};
-        case 12:
-        case 13: return new int[] {3,14,15};
-        }
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( numLayers==2 )
-      {
-      switch(cubitface)
-        {
-        case 0: if( cubit==4 ) return 11;
-                if( cubit==5 ) return 10;
-                if( cubit==6 ) return  9;
-                if( cubit==7 ) return  8;
-                return NUM_TEXTURES;
-        case 1: if( cubit==0 ) return 11;
-                if( cubit==1 ) return 10;
-                if( cubit==2 ) return  9;
-                if( cubit==3 ) return  8;
-                return NUM_TEXTURES;
-        case 2: if( cubit==3 ) return  4;
-                if( cubit==7 ) return  5;
-                if( cubit==2 ) return  6;
-                if( cubit==6 ) return  7;
-                return NUM_TEXTURES;
-        case 3: if( cubit==1 ) return  4;
-                if( cubit==5 ) return  5;
-                if( cubit==0 ) return  6;
-                if( cubit==4 ) return  7;
-                return NUM_TEXTURES;
-        case 4: if( cubit==3 ) return  0;
-                if( cubit==7 ) return  1;
-                if( cubit==1 ) return  2;
-                if( cubit==5 ) return  3;
-                return NUM_TEXTURES;
-        case 5: if( cubit==2 ) return  0;
-                if( cubit==6 ) return  1;
-                if( cubit==0 ) return  2;
-                if( cubit==4 ) return  3;
-                return NUM_TEXTURES;
-        }
-      }
-    if( numLayers==3 )
-      {
-      switch(cubitface)
-        {
-        case 0: if( cubit==17 ) return 24;
-                if( cubit==18 ) return 23;
-                if( cubit==19 ) return 22;
-                if( cubit==20 ) return 21;
-                if( cubit==21 ) return  0;
-                if( cubit==22 ) return 20;
-                if( cubit==23 ) return 19;
-                if( cubit==24 ) return 18;
-                if( cubit==25 ) return 17;
-                return NUM_TEXTURES;
-        case 1: if( cubit== 0 ) return 24;
-                if( cubit== 1 ) return 23;
-                if( cubit== 2 ) return 22;
-                if( cubit== 3 ) return 21;
-                if( cubit== 4 ) return  0;
-                if( cubit== 5 ) return 20;
-                if( cubit== 6 ) return 19;
-                if( cubit== 7 ) return 18;
-                if( cubit== 8 ) return 17;
-                return NUM_TEXTURES;
-        case 2: if( cubit== 6 ) return 14;
-                if( cubit==14 ) return  2; // theoretically should have been 15, but this must have gotten collapsed in the Factory
-                if( cubit==23 ) return 16;
-                if( cubit== 7 ) return 12;
-                if( cubit==15 ) return  0;
-                if( cubit==24 ) return 13;
-                if( cubit== 8 ) return  9;
-                if( cubit==16 ) return 20; // ditto, theoretically 10
-                if( cubit==25 ) return 11;
-                return NUM_TEXTURES;
-        case 3: if( cubit== 0 ) return 14;
-                if( cubit== 9 ) return  2; // ditto, theoretically 15
-                if( cubit==17 ) return 16;
-                if( cubit== 1 ) return 12;
-                if( cubit==10 ) return  0;
-                if( cubit==18 ) return 13;
-                if( cubit== 2 ) return  9;
-                if( cubit==11 ) return 20; // ditto, theoretically 10
-                if( cubit==19 ) return 11;
-                return NUM_TEXTURES;
-        case 4: if( cubit== 8 ) return  1;
-                if( cubit==16 ) return  2;
-                if( cubit==25 ) return  3;
-                if( cubit== 5 ) return  4;
-                if( cubit==13 ) return  0;
-                if( cubit==22 ) return  5;
-                if( cubit== 2 ) return  6;
-                if( cubit==11 ) return  7;
-                if( cubit==19 ) return  8;
-                return NUM_TEXTURES;
-        case 5: if( cubit== 6 ) return  1;
-                if( cubit==14 ) return  2;
-                if( cubit==23 ) return  3;
-                if( cubit== 3 ) return  4;
-                if( cubit==12 ) return  0;
-                if( cubit==20 ) return  5;
-                if( cubit== 0 ) return  6;
-                if( cubit== 9 ) return  7;
-                if( cubit==17 ) return  8;
-                return NUM_TEXTURES;
-        }
-      }
-
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float returnStroke(float x, float y)
-    {
-    return 0.08f/(Math.max(x,y));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] generateStrokes()
-    {
-    int num = getNumLayers();
-    final float A = 0.08f;
-
-    if( num==2 )
-      {
-      return new float[] {
-                           returnStroke(1-DX,1-DY),
-                           returnStroke(1+DX,1-DY),
-                           returnStroke(1-DX,1+DY),
-                           returnStroke(1+DX,1+DY),
-                           returnStroke(1-DX,1-DZ),
-                           returnStroke(1+DX,1-DZ),
-                           returnStroke(1-DX,1+DZ),
-                           returnStroke(1+DX,1+DZ),
-                           returnStroke(1-DZ,1-DY),
-                           returnStroke(1+DZ,1-DY),
-                           returnStroke(1-DZ,1+DY),
-                           returnStroke(1+DZ,1+DY),
-
-                           A/(1-DX), A/(1+DX), A/(1+DY), A/(1+DY),
-                           A/(1-DX), A/(1+DX), A/(1+DZ), A/(1+DZ),
-                           A/(1-DY), A/(1+DY), A/(1+DZ), A/(1+DZ),
-                         };
-      }
-    else
-      {
-      return new float[] {
-                           returnStroke(1   ,1   ),
-
-                           returnStroke(1-DX,1-DY),
-                           returnStroke(1   ,1-DY),
-                           returnStroke(1+DX,1-DY),
-                           returnStroke(1-DX,1   ),
-                           returnStroke(1+DX,1   ),
-                           returnStroke(1-DX,1+DY),
-                           returnStroke(1   ,1+DY),
-                           returnStroke(1+DX,1+DY),
-
-                           returnStroke(1-DX,1-DZ),
-                           returnStroke(1   ,1-DZ),
-                           returnStroke(1+DX,1-DZ),
-                           returnStroke(1-DX,1   ),
-                           returnStroke(1+DX,1   ),
-                           returnStroke(1-DX,1+DZ),
-                           returnStroke(1   ,1+DZ),
-                           returnStroke(1+DX,1+DZ),
-
-                           returnStroke(1-DZ,1-DY),
-                           returnStroke(1   ,1-DY),
-                           returnStroke(1+DZ,1-DY),
-                           returnStroke(1-DZ,1   ),
-                           returnStroke(1+DZ,1   ),
-                           returnStroke(1-DZ,1+DY),
-                           returnStroke(1   ,1+DY),
-                           returnStroke(1+DZ,1+DY),
-                         };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[] returnSticker(float x, float y)
-    {
-      float H = 0.5f;
-
-      if( x<y ) { float D=H*x/y; return new float[] {-D,-H,+D,-H,+D,+H,-D,+H}; }
-      else      { float D=H*y/x; return new float[] {-H,-D,+H,-D,+H,+D,-H,+D}; }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private float[][] generateStickers()
-    {
-    int num = getNumLayers();
-
-    if( num==2 )
-      {
-      return new float[][]
-          {
-              returnSticker(1-DX,1-DY),
-              returnSticker(1+DX,1-DY),
-              returnSticker(1-DX,1+DY),
-              returnSticker(1+DX,1+DY),
-              returnSticker(1-DX,1-DZ),
-              returnSticker(1+DX,1-DZ),
-              returnSticker(1-DX,1+DZ),
-              returnSticker(1+DX,1+DZ),
-              returnSticker(1-DZ,1-DY),
-              returnSticker(1+DZ,1-DY),
-              returnSticker(1-DZ,1+DY),
-              returnSticker(1+DZ,1+DY),
-          };
-      }
-    else
-      {
-      return new float[][]
-          {
-              returnSticker(1   ,1   ),
-
-              returnSticker(1-DX,1-DY),
-              returnSticker(1   ,1-DY),
-              returnSticker(1+DX,1-DY),
-              returnSticker(1-DX,1   ),
-              returnSticker(1+DX,1   ),
-              returnSticker(1-DX,1+DY),
-              returnSticker(1   ,1+DY),
-              returnSticker(1+DX,1+DY),
-
-              returnSticker(1-DX,1-DZ),
-              returnSticker(1   ,1-DZ),
-              returnSticker(1+DX,1-DZ),
-              returnSticker(1-DX,1   ),
-              returnSticker(1+DX,1   ),
-              returnSticker(1-DX,1+DZ),
-              returnSticker(1   ,1+DZ),
-              returnSticker(1+DX,1+DZ),
-
-              returnSticker(1-DZ,1-DY),
-              returnSticker(1   ,1-DY),
-              returnSticker(1+DZ,1-DY),
-              returnSticker(1-DZ,1   ),
-              returnSticker(1+DZ,1   ),
-              returnSticker(1-DZ,1+DY),
-              returnSticker(1   ,1+DY),
-              returnSticker(1+DZ,1+DY),
-          };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      final float[][] STICKERS = generateStickers();
-      final float[] STROKES = generateStrokes();
-      final int NUM_STICKERS = STICKERS.length;
-      final float radius = 0.10f;
-      final float[] radii = {radius,radius,radius,radius};
-      mStickers = new ObjectSticker[NUM_STICKERS];
-
-      for(int i=0; i<NUM_STICKERS; i++)
-        {
-        mStickers[i] = new ObjectSticker(STICKERS[i],null,radii,STROKES[i]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return numLayers==2 ? 12 : 25;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getRow(int cubit, int numLayers, int dim)
-    {
-    return (int)(mPositions[cubit][dim] + 0.5f*(numLayers-1));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int extraI, extraV, num;
-    float height;
-
-    switch(numLayers)
-      {
-      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
-      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
-      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
-      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
-      }
-
-    int xrow = getRow(cubit,numLayers,0);
-    int yrow = getRow(cubit,numLayers,1);
-    int zrow = getRow(cubit,numLayers,2);
-
-    float XL = -0.5f + (xrow==          0 ? DX : 0);
-    float XR = +0.5f + (xrow==numLayers-1 ? DX : 0);
-    float YL = -0.5f - (yrow==          0 ? DY : 0);
-    float YR = +0.5f - (yrow==numLayers-1 ? DY : 0);
-    float ZL = -0.5f - (zrow==          0 ? DZ : 0);
-    float ZR = +0.5f - (zrow==numLayers-1 ? DZ : 0);
-
-    double[][] vertices = new double[][]
-          {
-              { XR, YR, ZR },
-              { XR, YR, ZL },
-              { XR, YL, ZR },
-              { XR, YL, ZL },
-              { XL, YR, ZR },
-              { XL, YR, ZL },
-              { XL, YL, ZR },
-              { XL, YL, ZL },
-          };
-
-    int[][] vert_indices = new int[][]
-          {
-              {2,3,1,0},
-              {7,6,4,5},
-              {4,0,1,5},
-              {7,3,2,6},
-              {6,2,0,4},
-              {3,7,5,1}
-          };
-
-    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
-    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
-    float[][] corners   = new float[][] { {0.036f,0.12f} };
-    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-
-    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats ==null ) initializeQuats();
-    return mQuats[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 6*numLayers*numLayers - 12*numLayers + 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getColor(int face)
-    {
-    return FACE_COLORS[face];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    if( mPositions==null )
-      {
-      int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
-      mPositions = new float[numCubits][];
-
-      float diff = 0.5f*(numLayers-1);
-      int currentPosition = 0;
-
-      for(int x = 0; x<numLayers; x++)
-        for(int y = 0; y<numLayers; y++)
-          for(int z = 0; z<numLayers; z++)
-            if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
-              {
-              mPositions[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
-              }
-      }
-
-    return mPositions;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats ==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumFaceColors()
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      mCuts = new float[3][numLayers-1];
-
-      for(int i=0; i<numLayers-1; i++)
-        {
-        float cut = (2-numLayers)*0.5f + i;
-        mCuts[0][i] = cut;
-        mCuts[1][i] = cut;
-        mCuts[2][i] = cut;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.mirr2;
-      case 3: return R.string.mirr3;
-      }
-    return R.string.mirr3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.mirr2_inventor;
-      case 3: return R.string.mirr3_inventor;
-      }
-    return R.string.mirr3_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return 5;
-      case 3: return 7;
-      }
-    return 7;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
deleted file mode 100644
index 9c6fa2cb..00000000
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ /dev/null
@@ -1,446 +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.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement4;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty4;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyPyraminx extends Twisty4
-{
-  static final Static3D[] ROT_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),
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int numLayers = getNumLayers();
-      initializeScrambleStates(numLayers);
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
-         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
-         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
-         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
-         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
-         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
-         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
-         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
-         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
-         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
-         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
-         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int[][] generateState(int start, int end)
-    {
-    int len = end-start+1;
-    int[] tmp = new int[6*len];
-
-    for(int i=0; i<len; i++)
-      {
-      tmp[6*i  ] = start;
-      tmp[6*i+1] = -1;
-      tmp[6*i+2] = start;
-      tmp[6*i+3] = start;
-      tmp[6*i+4] = +1;
-      tmp[6*i+5] = start;
-
-      start++;
-      }
-
-    return new int[][] {tmp,tmp,tmp,tmp};
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeScrambleStates(int numLayers)
-    {
-    mStates = new ScrambleState[numLayers];
-
-    for(int i=0; i<numLayers-1; i++)
-      {
-      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
-      }
-
-    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void addTetrahedralLattice(int size, int index, float[][] pos)
-    {
-    final float DX = 1.0f;
-    final float DY = SQ2/2;
-    final float DZ = 1.0f;
-
-    float startX = 0.0f;
-    float startY =-DY*(size-1)/2;
-    float startZ = DZ*(size-1)/2;
-
-    for(int layer=0; layer<size; layer++)
-      {
-      float currX = startX;
-      float currY = startY;
-
-      for(int x=0; x<layer+1; x++)
-        {
-        float currZ = startZ;
-
-        for(int z=0; z<size-layer; z++)
-          {
-          pos[index] = new float[] {currX,currY,currZ};
-          index++;
-          currZ -= DZ;
-          }
-
-        currX += DX;
-        }
-
-      startX-=DX/2;
-      startY+=DY;
-      startZ-=DZ/2;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
-
-  protected float[][] getCubitPositions(int size)
-    {
-    int numOcta = (size-1)*size*(size+1)/6;
-    int numTetra= size*(size+1)*(size+2)/6;
-    float[][] ret = new float[numOcta+numTetra][];
-
-    addTetrahedralLattice(size-1,      0,ret);
-    addTetrahedralLattice(size  ,numOcta,ret);
-
-    return ret;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      mCuts = new float[4][numLayers-1];
-
-      for(int i=0; i<numLayers-1; i++)
-        {
-        float cut = (1.0f+i-numLayers/4.0f)*(SQ6/3);
-        mCuts[0][i] = cut;
-        mCuts[1][i] = cut;
-        mCuts[2][i] = cut;
-        mCuts[3][i] = cut;
-        }
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumOctahedrons(int numLayers)
-    {
-    return (numLayers-1)*numLayers*(numLayers+1)/6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int faceColor(int cubit, int axis)
-    {
-    return CUBITS[cubit].getRotRow(axis) == 1 ? axis : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( cubit< (size-1)*size*(size+1)/6 )
-      {
-      switch( cubitface )
-        {
-        case 0: return faceColor(cubit,0);
-        case 2: return faceColor(cubit,1);
-        case 5: return faceColor(cubit,3);
-        case 7: return faceColor(cubit,2);
-        default:return NUM_TEXTURES;
-        }
-      }
-    else
-      {
-      return cubitface<NUM_TEXTURES ? faceColor(cubit,cubitface) : NUM_TEXTURES;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][] { { 0.5,0.0,0.5},{ 0.5,0.0,-0.5},{-0.5,0.0,-0.5},{-0.5,0.0,0.5},{ 0.0,SQ2/2,0.0},{ 0.0,-SQ2/2,0.0} };
-      int[][] vert_indices = new int[][] { {3,0,4},{0,1,4},{1,2,4},{2,3,4},{5,0,3},{5,1,0},{5,2,1},{5,3,2} };
-      int N = numLayers==3? 6 : 5;
-      int E = numLayers==3? 2 : 1;
-      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
-      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
-      float[][] corners   = new float[][] { {0.04f,0.20f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][] { {-0.5, SQ2/4, 0.0},{ 0.5, SQ2/4, 0.0},{ 0.0,-SQ2/4, 0.5},{ 0.0,-SQ2/4,-0.5} };
-      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
-      int N = numLayers==3? 6 : 5;
-      int E = numLayers==3? 2 : 1;
-      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
-      int[] bandIndices   = new int[] { 0,0,0,0 };
-      float[][] corners   = new float[][] { {0.06f,0.15f} };
-      int[] cornerIndices = new int[] { 0,0,0,0 };
-      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<getNumOctahedrons(numLayers) ? 0:1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
-      final float stroke = 0.08f;
-      final float radius = 0.06f;
-      final float[] radii= {radius,radius,radius};
-      mStickers = new ObjectSticker[STICKERS.length];
-      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// public API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement4(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 3: return R.string.pyra3;
-      case 4: return R.string.pyra4;
-      case 5: return R.string.pyra5;
-      }
-    return R.string.pyra3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 3: return R.string.pyra3_inventor;
-      case 4: return R.string.pyra4_inventor;
-      case 5: return R.string.pyra5_inventor;
-      }
-    return R.string.pyra3_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 3: return 4;
-      case 4: return 6;
-      case 5: return 8;
-      }
-    return 4;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
deleted file mode 100644
index d60f70db..00000000
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ /dev/null
@@ -1,468 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_CORNER;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyRedi extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0,1},{3,1},{2,3},{0,2}},
-          {{2,3},{3,1},{0,1},{0,2}},
-          {{1,2},{0,1},{0,3},{2,3}},
-          {{1,2},{2,3},{0,3},{0,1}},
-          {{0,3},{0,2},{1,2},{1,3}},
-          {{1,2},{0,2},{0,3},{1,3}},
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private float[][] mCenters;
-  private int[][] mFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                    DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REDI, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1, 2,1,2,2,-1,2},{0,1,3,0,-1,3, 2,1,4,2,-1,4},{0,1,5,0,-1,5, 2,1,6,2,-1,6},{0,1,7,0,-1,7, 2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {                          },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{                          },{              2,1,6,2,-1,6},{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{                          },{0,1,5,0,-1,5,             },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{                          },{0,1,7,0,-1,7              } } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{                          },{              2,1,8,2,-1,8} } ),
-        new ScrambleState( new int[][] { {              2,1,2,2,-1,2},{0,1,3,0,-1,3              },{0,1,5,0,-1,5,             },{                          } } ),
-        new ScrambleState( new int[][] { {0,1,1,0,-1,1              },{              2,1,4,2,-1,4},{              2,1,6,2,-1,6},{                          } } ),
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int size)
-    {
-    if( mCuts==null )
-      {
-      float C = +SQ3/3 +0.05f;
-      float[] cut = new float[] {-C,+C};
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[] {true,false,true};
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 9;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int size)
-    {
-    if( mCenters==null )
-      {
-      final float DIST_CORNER = 1.0f;
-      final float DIST_EDGE   = 1.5f;
-
-      mCenters = new float[][]
-         {
-             { DIST_CORNER, DIST_CORNER, DIST_CORNER },
-             { DIST_CORNER, DIST_CORNER,-DIST_CORNER },
-             { DIST_CORNER,-DIST_CORNER, DIST_CORNER },
-             { DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
-             {-DIST_CORNER, DIST_CORNER, DIST_CORNER },
-             {-DIST_CORNER, DIST_CORNER,-DIST_CORNER },
-             {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
-             {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
-
-             {      0.0f, DIST_EDGE, DIST_EDGE },
-             { DIST_EDGE,      0.0f, DIST_EDGE },
-             {      0.0f,-DIST_EDGE, DIST_EDGE },
-             {-DIST_EDGE,      0.0f, DIST_EDGE },
-             { DIST_EDGE, DIST_EDGE,      0.0f },
-             { DIST_EDGE,-DIST_EDGE,      0.0f },
-             {-DIST_EDGE,-DIST_EDGE,      0.0f },
-             {-DIST_EDGE, DIST_EDGE,      0.0f },
-             {      0.0f, DIST_EDGE,-DIST_EDGE },
-             { DIST_EDGE,      0.0f,-DIST_EDGE },
-             {      0.0f,-DIST_EDGE,-DIST_EDGE },
-             {-DIST_EDGE,      0.0f,-DIST_EDGE }
-         };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-          {
-             { 0.0f, 0.0f, 0.0f },
-             {-0.5f, 0.5f, 0.5f },
-             {-0.5f,-0.5f, 0.5f },
-             { 0.5f, 0.5f, 0.5f },
-             { 0.5f,-0.5f, 0.5f },
-             { 0.5f, 0.5f,-0.5f },
-             { 0.5f,-0.5f,-0.5f },
-             {-0.5f, 0.5f,-0.5f },
-          };
-
-      int[][] vert_indices = new int[][]
-          {
-             { 2,4,3,1 },
-             { 1,3,5,7 },
-             { 4,6,5,3 },
-
-             { 2,4,0 },
-             { 5,7,0 },
-             { 4,6,0 },
-             { 7,1,0 },
-             { 1,2,0 },
-             { 6,5,0 }
-          };
-
-      float[][] bands     = new float[][] { {0.06f,35,0.5f,0.7f,5,2,2}, {0.01f,35,0.2f,0.4f,5,2,2} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1,1,1,1 };
-      float[][] corners   = new float[][] { {0.06f,0.12f} };
-      int[] cornerIndices = new int[]  { -1,0,-1,0,0,0,-1,-1 };
-      float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { -1,0,-1,0,0,0,-1,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-          {
-             {-0.5f, 0.0f, 0.0f},
-             { 0.5f, 0.0f, 0.0f},
-             {-0.5f,-1.0f, 0.0f},
-             { 0.5f,-1.0f, 0.0f},
-             { 0.0f,-1.5f, 0.0f},
-             {-0.5f, 0.0f,-1.0f},
-             { 0.5f, 0.0f,-1.0f},
-             { 0.0f, 0.0f,-1.5f},
-          };
-
-      int[][] vert_indices = new int[][]
-          {
-             { 0,2,4,3,1 },
-             { 0,1,6,7,5 },
-             { 1,3,6 },
-             { 0,2,5 },
-             { 4,7,6,3 },
-             { 4,7,5,2 }
-          };
-
-      float[][] bands     = new float[][] { {0.038f,35,0.250f,0.7f,7,2,2}, {0.020f,35,0.125f,0.2f,3,1,2}, {0.020f,35,0.125f,0.2f,3,1,1} };
-      int[] bandIndices   = new int[] { 0,0,1,1,2,2 };
-      float[][] corners   = new float[][] { {0.06f,0.20f} };
-      int[] cornerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
-      float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
-      int[] centerIndices = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-
-    switch(cubit)
-      {
-      case  0: return mQuats[0];                         //  unit quat
-      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
-      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
-      case  3: return mQuats[1];                         // 180 along X
-      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
-      case  5: return mQuats[2];                         // 180 along Y
-      case  6: return mQuats[3];                         // 180 along Z
-      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
-
-      case  8: return mQuats[0];
-      case  9: return mQuats[5];
-      case 10: return mQuats[3];
-      case 11: return mQuats[11];
-      case 12: return mQuats[4];
-      case 13: return mQuats[7];
-      case 14: return mQuats[9];
-      case 15: return mQuats[10];
-      case 16: return mQuats[2];
-      case 17: return mQuats[8];
-      case 18: return mQuats[1];
-      case 19: return mQuats[6];
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<8 ? 0:1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null )
-      {
-      // Colors of the faces of cubits.
-      // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4  ORANGE 5
-      // YELLOW 6 WHITE 7 BLUE 8 GREEN 9 RED 10 ORANGE 11
-      mFaceMap = new int[][]
-         {
-           {  4, 2, 0 },
-           {  2, 5, 0 },
-           {  3, 4, 0 },
-           {  5, 3, 0 },
-           {  1, 2, 4 },
-           {  5, 2, 1 },
-           {  4, 3, 1 },
-           {  1, 3, 5 },
-
-           { 10, 8,12 },
-           {  6,10,12 },
-           { 10, 9,12 },
-           {  7,10,12 },
-           {  8, 6,12 },
-           {  9, 6,12 },
-           {  9, 7,12 },
-           {  8, 7,12 },
-           { 11, 8,12 },
-           {  6,11,12 },
-           { 11, 9,12 },
-           {  7,11,12 },
-         };
-      }
-
-    return cubitface<3 ? mFaceMap[cubit][cubitface] : NUM_TEXTURES;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-          {
-             { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
-             { -0.3125f, 0.4375f, -0.3125f, -0.1875f, 0.0f, -0.5f, 0.3125f, -0.1875f, 0.3125f, 0.4375f }
-          };
-
-      final float R0 = 0.09f;
-      final float R1 = 0.06f;
-      final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1,R1} };
-      final float[] strokes = { 0.09f,0.06f };
-
-      mStickers = new ObjectSticker[STICKERS.length];
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.redi2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.redi2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 4;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyRex.java b/src/main/java/org/distorted/objects/TwistyRex.java
deleted file mode 100644
index 744522d9..00000000
--- a/src/main/java/org/distorted/objects/TwistyRex.java
+++ /dev/null
@@ -1,501 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_CORNER;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyRex extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0,1},{3,1},{2,3},{0,2}},
-          {{2,3},{3,1},{0,1},{0,2}},
-          {{1,2},{0,1},{0,3},{2,3}},
-          {{1,2},{2,3},{0,3},{0,1}},
-          {{0,3},{0,2},{1,2},{1,3}},
-          {{1,2},{0,2},{0,3},{1,3}},
-      };
-
-  public static final float REX_D = 0.2f;
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[][] mFaceMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                   DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      float C = SQ3*0.45f; // bit less than 1/2 of the length of the main diagonal
-      float[] cut = new float[] {-C,+C};
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[] {true,false,true};
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    final float DIST1= 1.50f;
-    final float DIST2= (1+2*REX_D)/2;
-    final float DIST3= 1.53f;
-
-    final float[][] CENTERS = new float[24+6+12][];
-
-    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
-    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
-    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
-    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
-    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
-    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
-    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
-    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
-    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
-    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
-    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
-    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
-    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
-    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
-    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
-    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
-    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
-    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
-    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
-    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
-    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
-    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
-    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
-    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
-
-    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
-    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
-    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
-    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
-    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
-    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
-
-    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
-    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
-    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
-    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
-    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
-    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
-    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
-    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
-    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
-    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
-    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
-    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      float G = (1-REX_D)*SQ2/2;
-      double[][] vertices ={{-0.10f,0.70f,0},{-0.70f,0.10f,0},{+0.65f,-0.71f,0},{+0.71f,-0.65f,0}};
-      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
-      float[][] centers= new float[][] { {0.0f,0.0f,-G} };
-      float[][] corners= new float[][] { {0.03f,0.30f} };
-      int[] indices= {-1,-1,0,0};
-      int[] bandIndices= new int[] { 0,1 };
-      float[][] bands = { {+0.016f,10,G/3,0.5f,5,1,1},{+0.230f,45,G/3,0.0f,2,0,0} };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      float G = 3*REX_D;
-      double[][] vertices= { { -G, 0, 0 },{ 0, -G, 0 },{ +G, 0, 0 },{ 0,+G,0 } };
-      int[][] vertIndexes= { {0,1,2,3},{3,2,1,0} };
-      int[] indices= {-1,-1,-1,-1};
-      int[] bandIndices= new int[] { 0,1 };
-      float[][] bands = { {0.025f,10,G/2,0.5f,5,0,0},{0.000f,45,G/2,0.0f,2,0,0} };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      float E = 1.5f - 3*REX_D;
-      float F = 1.5f;
-      float G = (float)Math.sqrt(E*E+F*F);
-      double[][] vertices = { { -F, 0, 0 },{  0,-E, 0 },{ +F, 0, 0 },{  0, 0,-E } };
-      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
-      float[][] centers= new float[][] { {0.0f,-1.5f,-1.5f} };
-      float[][] corners= new float[][] { {0.06f,0.20f} };
-      int[] indices= {0,-1,0,-1};
-      int[] bandIndices= new int[] { 0,0,1,1 };
-      float[][] bands = { {0.03f,27,F/3,0.8f,5,2,3},{0.01f,45,G/3,0.2f,3,1,2} };
-
-      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-
-    switch(cubit)
-      {
-      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
-      case  1: return mQuats[5];
-      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
-      case  3: return mQuats[8];
-      case  4: return mQuats[6];
-      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
-      case  6: return mQuats[11];
-      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
-      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
-      case  9: return mQuats[10];
-      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
-      case 11: return mQuats[4];
-      case 12: return mQuats[9];
-      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
-      case 14: return mQuats[7];
-      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
-      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
-      case 17: return mQuats[0];
-      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
-      case 19: return mQuats[3];
-      case 20: return mQuats[1];
-      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
-      case 22: return mQuats[2];
-      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
-
-      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
-      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
-      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
-      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
-      case 28: return mQuats[0];
-      case 29: return mQuats[1];
-
-      case 30: return mQuats[0];
-      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
-      case 32: return mQuats[3];
-      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
-      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
-      case 35: return mQuats[7];
-      case 36: return mQuats[9];
-      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
-      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
-      case 39: return mQuats[8];
-      case 40: return mQuats[1];
-      case 41: return mQuats[6];
-      }
-
-    return mQuats[0];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<24 ? 0 : (cubit<30?1:2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[][]
-         {
-           {  0, 18,18,18,18,18 },
-           {  0, 18,18,18,18,18 },
-           {  0, 18,18,18,18,18 },
-           {  0, 18,18,18,18,18 },
-           {  1, 18,18,18,18,18 },
-           {  1, 18,18,18,18,18 },
-           {  1, 18,18,18,18,18 },
-           {  1, 18,18,18,18,18 },
-           {  2, 18,18,18,18,18 },
-           {  2, 18,18,18,18,18 },
-           {  2, 18,18,18,18,18 },
-           {  2, 18,18,18,18,18 },
-           {  3, 18,18,18,18,18 },
-           {  3, 18,18,18,18,18 },
-           {  3, 18,18,18,18,18 },
-           {  3, 18,18,18,18,18 },
-           {  4, 18,18,18,18,18 },
-           {  4, 18,18,18,18,18 },
-           {  4, 18,18,18,18,18 },
-           {  4, 18,18,18,18,18 },
-           {  5, 18,18,18,18,18 },
-           {  5, 18,18,18,18,18 },
-           {  5, 18,18,18,18,18 },
-           {  5, 18,18,18,18,18 },
-
-           {  6, 18,18,18,18,18 },
-           {  7, 18,18,18,18,18 },
-           {  8, 18,18,18,18,18 },
-           {  9, 18,18,18,18,18 },
-           { 10, 18,18,18,18,18 },
-           { 11, 18,18,18,18,18 },
-
-           { 16,14, 18,18,18,18 },
-           { 16,12, 18,18,18,18 },
-           { 16,15, 18,18,18,18 },
-           { 16,13, 18,18,18,18 },
-           { 12,14, 18,18,18,18 },
-           { 15,12, 18,18,18,18 },
-           { 15,13, 18,18,18,18 },
-           { 13,14, 18,18,18,18 },
-           { 14,17, 18,18,18,18 },
-           { 12,17, 18,18,18,18 },
-           { 17,15, 18,18,18,18 },
-           { 13,17, 18,18,18,18 },
-         };
-      }
-
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-          {
-             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
-             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
-             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
-          };
-
-      final float F = (float)(Math.PI/20);
-      final float R1= 0.02f;
-      final float R2= 0.09f;
-      final float R3= 0.06f;
-      final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
-      final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
-      final float[] strokes = { 0.06f, 0.07f, 0.05f };
-
-      mStickers = new ObjectSticker[STICKERS.length];
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.rex3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.rex3_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 3;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
deleted file mode 100644
index edec1f9a..00000000
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ /dev/null
@@ -1,619 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2020 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_SPLIT_CORNER;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistySkewb extends Twisty6
-{
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
-           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-      {
-          {{0,1},{3,1},{2,3},{0,2}},
-          {{2,3},{3,1},{0,1},{0,2}},
-          {{1,2},{0,1},{0,3},{2,3}},
-          {{1,2},{2,3},{0,3},{0,1}},
-          {{0,3},{0,2},{1,2},{1,3}},
-          {{1,2},{0,2},{0,3},{1,3}},
-      };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[][] mCornerMap,mEdgeMap,mCenterMap;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistySkewb(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                     DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int size = getNumLayers();
-      int[] tmp = {0,-1,0, 0,1,0, size-1,-1,0, size-1,1,0 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-
-         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
-         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumCorners()
-    {
-    return 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumEdges(int layers)
-    {
-    return (layers-2)*12;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int getNumCentersPerFace(int layers)
-    {
-    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      float[] c = numLayers==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/6,+SQ3/6});
-      mCuts = new float[][] {c,c,c,c};
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = numLayers==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    final float DIST_CORNER = numLayers-1;
-    final float DIST_EDGE   = numLayers-1;
-    final float DIST_CENTER = numLayers-1;
-
-    final int numCorners = getNumCorners();
-    final int numEdges   = getNumEdges(numLayers);
-    final int numCenters = 6*getNumCentersPerFace(numLayers);
-
-    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
-
-    /// CORNERS //////////////////////////////////////////////
-
-    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
-    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
-    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
-    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
-    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
-    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
-    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
-    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
-
-    /// EDGES ///////////////////////////////////////////////
-
-    final float[][]  edgeTable =
-        {
-            {0,+DIST_EDGE,+DIST_EDGE},
-            {+DIST_EDGE,0,+DIST_EDGE},
-            {0,-DIST_EDGE,+DIST_EDGE},
-            {-DIST_EDGE,0,+DIST_EDGE},
-            {+DIST_EDGE,+DIST_EDGE,0},
-            {+DIST_EDGE,-DIST_EDGE,0},
-            {-DIST_EDGE,-DIST_EDGE,0},
-            {-DIST_EDGE,+DIST_EDGE,0},
-            {0,+DIST_EDGE,-DIST_EDGE},
-            {+DIST_EDGE,0,-DIST_EDGE},
-            {0,-DIST_EDGE,-DIST_EDGE},
-            {-DIST_EDGE,0,-DIST_EDGE}
-        };
-
-    int index=8;
-
-    for (float[] edges : edgeTable)
-      {
-      float c = 3-numLayers;
-
-      for (int j=0; j<numLayers-2; j++, c+=2, index++)
-        {
-        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
-                                       edges[1]==0 ? c : edges[1] ,
-                                       edges[2]==0 ? c : edges[2] };
-        }
-      }
-
-    /// CENTERS //////////////////////////////////////////////
-
-    final float X= -1000.0f;
-    final float Y= -1001.0f;
-
-    final float[][]  centerTable =
-        {
-            {+DIST_CENTER,X,Y},
-            {-DIST_CENTER,X,Y},
-            {X,+DIST_CENTER,Y},
-            {X,-DIST_CENTER,Y},
-            {X,Y,+DIST_CENTER},
-            {X,Y,-DIST_CENTER}
-        };
-
-    float x,y, cen0, cen1, cen2;
-
-    for( float[] centers : centerTable )
-      {
-      x = 2-numLayers;
-
-      for(int i=0; i<numLayers-1; i++, x+=2)
-        {
-        y = 2-numLayers;
-
-        for(int j=0; j<numLayers-1; j++, y+=2, index++)
-          {
-               if( centers[0]==Y ) cen0 = y;
-          else if( centers[0]==X ) cen0 = x;
-          else                     cen0 = centers[0];
-
-               if( centers[1]==Y ) cen1 = y;
-          else if( centers[1]==X ) cen1 = x;
-          else                     cen1 = centers[1];
-
-               if( centers[2]==Y ) cen2 = y;
-          else if( centers[2]==X ) cen2 = x;
-          else                     cen2 = centers[2];
-
-          CENTERS[index] = new float[] {cen0,cen1,cen2};
-          }
-        }
-
-      x = 3-numLayers;
-
-      for(int i=0; i<numLayers-2; i++, x+=2)
-        {
-        y = 3-numLayers;
-
-        for(int j=0; j<numLayers-2; j++, y+=2, index++)
-          {
-               if( centers[0]==Y ) cen0 = y;
-          else if( centers[0]==X ) cen0 = x;
-          else                     cen0 = centers[0];
-
-               if( centers[1]==Y ) cen1 = y;
-          else if( centers[1]==X ) cen1 = x;
-          else                     cen1 = centers[1];
-
-               if( centers[2]==Y ) cen2 = y;
-          else if( centers[2]==X ) cen2 = x;
-          else                     cen2 = centers[2];
-
-          CENTERS[index] = new float[] {cen0,cen1,cen2};
-          }
-        }
-      }
-
-    return CENTERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int numCorners = getNumCorners();
-    int numEdges   = getNumEdges(numLayers);
-
-    if( cubit<numCorners )
-      {
-      switch(cubit)
-        {
-        case  0: return mQuats[0];                         //  unit quat
-        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
-        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
-        case  3: return mQuats[1];                         // 180 along X
-        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
-        case  5: return mQuats[2];                         // 180 along Y
-        case  6: return mQuats[3];                         // 180 along Z
-        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
-        }
-      }
-    else if( cubit<numCorners+numEdges )
-      {
-      int edge = (cubit-numCorners)/(numLayers-2);
-
-      switch(edge)
-        {
-        case  0: return mQuats[ 0];
-        case  1: return mQuats[ 5];
-        case  2: return mQuats[ 3];
-        case  3: return mQuats[11];
-        case  4: return mQuats[ 4];
-        case  5: return mQuats[ 7];
-        case  6: return mQuats[ 9];
-        case  7: return mQuats[10];
-        case  8: return mQuats[ 2];
-        case  9: return mQuats[ 8];
-        case 10: return mQuats[ 1];
-        case 11: return mQuats[ 6];
-        }
-      }
-    else
-      {
-      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
-
-      switch(center)
-        {
-        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
-        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
-        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
-        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
-        case 4: return mQuats[0];                         //  unit quaternion
-        case 5: return mQuats[1];                         // 180 along X
-        }
-      }
-
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][] { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
-      int[][] vert_indices = new int[][] { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
-      int N = numLayers==2 ? 7:5;
-      int E1= numLayers==2 ? 3:2;
-      int E2= numLayers==2 ? 5:3;
-      float[][] bands     = new float[][] { {0.020f,35,0.16f,0.7f,N,E1,E1}, {0.000f, 0,1.00f,0.0f,3,1,E2} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
-      float[][] corners   = new float[][] { {0.05f,0.25f}, {0.05f,0.20f} };
-      int[] cornerIndices = new int[] { 1,1,1,0,0 };
-      float[][] centers   = new float[][] { {-0.5f, -0.5f, -0.5f} };
-      int[] centerIndices = new int[] { 0,0,0,-1,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      double[][] vertices = new double[][] { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
-      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
-      int N = numLayers==2 ? 7:5;
-      int E = numLayers==2 ? 5:2;
-      float[][] bands     = new float[][] { {0.035f,30,0.16f,0.8f,N,2,E}, {0.020f,45,0.16f,0.2f,3,1,2} };
-      int[] bandIndices   = new int[] { 0,0,1,1 };
-      float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
-      int[] cornerIndices = new int[] { 0,0,1,1 };
-      float[][] centers   = new float[][] { {0.0f, -0.5f, -0.5f} };
-      int[] centerIndices = new int[] { 0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][] { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
-      int[][] vert_indices = new int[][] { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
-      int N = numLayers==2 ? 7:6;
-      int E = numLayers==2 ? 3:1;
-      float[][] bands     = new float[][] { {0.04f,35,SQ2/8,0.9f,N,E,E}, {0.000f,0,1,0.0f,3,0,0} };
-      int[] bandIndices   = new int[] { 0,1,1,1,1 };
-      float[][] corners   = new float[][] { {0.06f,0.15f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0 };
-      float[][] centers   = new float[][] { {0,0,-0.4f} };
-      int[] centerIndices = new int[] { 0,0,0,0,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    int numCorners = getNumCorners();
-    if( cubit<numCorners ) return 0;
-    int numEdges = getNumEdges(numLayers);
-    return cubit<numCorners+numEdges ? 1:2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mCornerMap==null || mEdgeMap==null || mCenterMap==null )
-      {
-      mCornerMap = new int[][]
-         {
-           {  4, 2, 0, 18,18,18 },
-           {  2, 5, 0, 18,18,18 },
-           {  3, 4, 0, 18,18,18 },
-           {  5, 3, 0, 18,18,18 },
-           {  1, 2, 4, 18,18,18 },
-           {  5, 2, 1, 18,18,18 },
-           {  4, 3, 1, 18,18,18 },
-           {  1, 3, 5, 18,18,18 },
-         };
-
-      mEdgeMap = new int[][]
-         {
-           { 10, 8, 18,18,18,18 },
-           {  6,10, 18,18,18,18 },
-           { 10, 9, 18,18,18,18 },
-           {  7,10, 18,18,18,18 },
-           {  8, 6, 18,18,18,18 },
-           {  9, 6, 18,18,18,18 },
-           {  9, 7, 18,18,18,18 },
-           {  8, 7, 18,18,18,18 },
-           { 11, 8, 18,18,18,18 },
-           {  6,11, 18,18,18,18 },
-           { 11, 9, 18,18,18,18 },
-           {  7,11, 18,18,18,18 }
-         };
-
-      mCenterMap = new int[][]
-         {
-           { 12, 18,18,18,18,18 },
-           { 13, 18,18,18,18,18 },
-           { 14, 18,18,18,18,18 },
-           { 15, 18,18,18,18,18 },
-           { 16, 18,18,18,18,18 },
-           { 17, 18,18,18,18,18 },
-         };
-      }
-
-    int numCorners = getNumCorners();
-    int numEdges   = getNumEdges(numLayers);
-
-    if( cubit<numCorners )
-      {
-      return mCornerMap[cubit][cubitface];
-      }
-    else if( cubit<numCorners+numEdges )
-      {
-      int edge = (cubit-numCorners)/(numLayers-2);
-      return mEdgeMap[edge][cubitface];
-      }
-    else
-      {
-      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
-      return mCenterMap[center][cubitface];
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-          {
-             { -0.5f, 0.25f, 0.25f,  -0.5f, 0.25f, 0.25f  },
-             { -0.5f, 0.00f, 0.00f,  -0.5f, 0.50f, 0.0f, 0.0f, 0.5f }
-          };
-
-      final float R1 = 0.025f;
-      final float R2 = 0.025f;
-      final float R3 = 0.055f;
-      final float[][] radii  = { { R1,R1,R1 },{ R2,R2,R2 },{ R3,R3,R3,R3 } };
-      final float[] strokes = { 0.045f, 0.035f, 0.035f };
-
-      mStickers = new ObjectSticker[STICKERS.length+1];
-
-      for(int s=0; s<STICKERS.length+1; s++)
-        {
-        int index = s<2 ? 0:1;
-        mStickers[s] = new ObjectSticker(STICKERS[index],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,2*numLayers-2,TYPE_SPLIT_CORNER,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.skew2;
-      case 3: return R.string.skew3;
-      }
-    return R.string.skew2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return R.string.skew2_inventor;
-      case 3: return R.string.skew3_inventor;
-      }
-    return R.string.skew2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    switch(numLayers)
-      {
-      case 2: return 4;
-      case 3: return 8;
-      }
-    return 5;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistySquare.java b/src/main/java/org/distorted/objects/TwistySquare.java
deleted file mode 100644
index a13f229a..00000000
--- a/src/main/java/org/distorted/objects/TwistySquare.java
+++ /dev/null
@@ -1,181 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty6;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract class TwistySquare extends Twisty6
-{
-  static final float COS15 = (SQ6+SQ2)/4;
-  static final float SIN15 = (SQ6-SQ2)/4;
-  static final float     X = 3*(2-SQ3)/2;
-
-  // The third, artificial axis is for the generic scrambling algorithm.
-  // Otherwise it wouldn't be possible to rotate the LO and UP layers
-  // consecutively.
-
-  static final Static3D[] ROT_AXIS = new Static3D[]
-    {
-      new Static3D(0,+1,0),
-      new Static3D(COS15,0,SIN15),
-      new Static3D(0,-1,0),
-    };
-
-  private static final int[][][] ENABLED = new int[][][]
-    {
-      {{0}},{{0}},{{1}},{{1}},{{0,1}},{{0,1}}
-    };
-
-  private int[] mBasicAngle;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private Movement mMovement;
-  Static4D[] mQuats;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  TwistySquare(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-               DistortedEffects effects, int[][] moves, ObjectList obj, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, obj, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeQuats()
-    {
-    mQuats = new Static4D[]
-      {
-      new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
-      new Static4D(  0.0f, SIN15,  0.0f, COS15 ),
-      new Static4D(  0.0f,  0.5f,  0.0f, SQ3/2 ),
-      new Static4D(  0.0f, SQ2/2,  0.0f, SQ2/2 ),
-      new Static4D(  0.0f, SQ3/2,  0.0f,  0.5f ),
-      new Static4D(  0.0f, COS15,  0.0f, SIN15 ),
-      new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
-      new Static4D(  0.0f, COS15,  0.0f,-SIN15 ),
-      new Static4D(  0.0f, SQ3/2,  0.0f, -0.5f ),
-      new Static4D(  0.0f, SQ2/2,  0.0f,-SQ2/2 ),
-      new Static4D(  0.0f,  0.5f,  0.0f,-SQ3/2 ),
-      new Static4D(  0.0f, SIN15,  0.0f,-COS15 ),
-
-      new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
-      new Static4D( COS15,  0.0f, SIN15,  0.0f ),
-      new Static4D( SQ3/2,  0.0f,  0.5f,  0.0f ),
-      new Static4D( SQ2/2,  0.0f, SQ2/2,  0.0f ),
-      new Static4D(  0.5f,  0.0f, SQ3/2,  0.0f ),
-      new Static4D( SIN15,  0.0f, COS15,  0.0f ),
-      new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
-      new Static4D(-SIN15,  0.0f, COS15,  0.0f ),
-      new Static4D( -0.5f,  0.0f, SQ3/2,  0.0f ),
-      new Static4D(-SQ2/2,  0.0f, SQ2/2,  0.0f ),
-      new Static4D(-SQ3/2,  0.0f,  0.5f,  0.0f ),
-      new Static4D(-COS15,  0.0f, SIN15,  0.0f )
-      };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void initializeBasicAngle()
-    {
-    mBasicAngle = new int[] {12,2,12};
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 6;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      mCuts = new float[][] { {-0.5f,+0.5f}, {0.0f}, {-0.5f,+0.5f} };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      mLayerRotatable = new boolean[][] { {true,false,true}, {true,true}, {true,false,true} };
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) initializeBasicAngle();
-    return mBasicAngle;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistySquare1.java b/src/main/java/org/distorted/objects/TwistySquare1.java
deleted file mode 100644
index 3fae438e..00000000
--- a/src/main/java/org/distorted/objects/TwistySquare1.java
+++ /dev/null
@@ -1,363 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement6;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistySquare1 extends TwistySquare
-{
-  private static final int NUM_STICKERS = 6;
-
-  private ObjectSticker[] mStickers;
-  private int[] mQuatNumber;
-  private float[][] mCenters;
-  private int[][] mStickerColor;
-  private int[][] mStickerType;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistySquare1(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                       DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.SQU1, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getScrambleType()
-    {
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-        {
-         { -1.5-X, 0.5, 1.5 },
-         {    0.0, 0.5, 1.5 },
-         {    0.0, 0.5,-1.5 },
-         { -1.5+X, 0.5,-1.5 },
-         { -1.5-X,-0.5, 1.5 },
-         {    0.0,-0.5, 1.5 },
-         {    0.0,-0.5,-1.5 },
-         { -1.5+X,-0.5,-1.5 }
-        };
-
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2,3},
-         {4,5,6,7},
-         {4,5,1,0},
-         {5,6,2,1},
-         {6,7,3,2},
-         {7,4,0,3}
-        };
-
-      float[][] bands     = new float[][] { {0.040f,35,0.8f,1.0f,5,2,1}, {0.020f,35,0.8f,1.0f,5,2,1}, {0.001f,35,0.8f,1.0f,5,2,1} };
-      int[] bandIndices   = new int[] { 2,2,1,1,0,2 };
-      float[][] corners   = new float[][] { {0.03f,0.05f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-      float[][] centers   = new float[][] { { -0.75f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      double[][] vertices = new double[][]
-        {
-         { -X, 0.5, 0.0 },
-         { +X, 0.5, 0.0 },
-         {0.0, 0.5,-1.5 },
-         { -X,-0.5, 0.0 },
-         { +X,-0.5, 0.0 },
-         {0.0,-0.5,-1.5 },
-        };
-
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2},
-         {3,4,5},
-         {3,4,1,0},
-         {4,5,2,1},
-         {5,3,0,2}
-        };
-
-      float[][] bands     = new float[][] { {0.038f,35,0.5f,0.9f, 5,2,1}, {0.001f,35,0.5f,0.9f, 5,2,1} };
-      int[] bandIndices   = new int[] { 0,1,0,1,1 };
-      float[][] corners   = new float[][] { {0.04f,0.15f} };
-      int[] cornerIndices = new int[] { 0,0,-1,0,0,-1 };
-      float[][] centers   = new float[][] { { 0.0f, 0.0f,-0.5f} };
-      int[] centerIndices = new int[] { 0,0,-1,0,0,-1 };
-
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-        {
-         { X-1.5, 0.5,  0.0 },
-         {   0.0, 0.5,  0.0 },
-         {   0.0, 0.5,X-1.5 },
-         {  -1.5, 0.5, -1.5 },
-         { X-1.5,-0.5,  0.0 },
-         {   0.0,-0.5,  0.0 },
-         {   0.0,-0.5,X-1.5 },
-         {  -1.5,-0.5, -1.5 }
-        };
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2,3},
-         {4,5,6,7},
-         {4,5,1,0},
-         {5,6,2,1},
-         {7,4,0,3},
-         {6,7,3,2}
-        };
-
-      float[][] bands     = new float[][] { {0.038f,35,0.9f,1.0f, 5,2,1}, {0.001f,35,0.9f,1.0f, 5,2,1} };
-      int[] bandIndices   = new int[] { 0,1,0,0,1,1 };
-      float[][] corners   = new float[][] { {0.05f,0.13f} };
-      int[] cornerIndices = new int[] { 0,0,0,-1,0,0,0,-1 };
-      float[][] centers   = new float[][] { { -0.5f, 0.0f,-0.5f} };
-      int[] centerIndices = new int[] { -1,0,-1,-1,-1,0,-1,-1 };
-
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    if( mQuatNumber ==null )
-      {
-      mQuatNumber = new int[]
-        {
-        0, 6,
-        0, 9, 6, 3, 18, 15, 12, 21,
-        0, 9, 6, 3, 15, 12, 21, 18
-        };
-      }
-
-    return mQuats[mQuatNumber[cubit]];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<2 ? 0 : (cubit<10 ? 1:2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-        {
-          { -0.5f, -0.26289170f, 0.5f, -0.26289170f, 0.5f, 0.26289170f, -0.5f, 0.26289170f }, // middle front
-          { -0.5f, -0.16666667f, 0.5f, -0.16666667f, 0.5f, 0.16666667f, -0.5f, 0.16666667f }, // middle right
-          { -0.5f, -0.45534182f, 0.5f, -0.45534182f, 0.5f, 0.45534182f, -0.5f, 0.45534182f }, // middle back
-          { -0.20096192f, -0.25f, 0.20096192f, -0.25f, 0.0f, 0.5f },                          // edge top
-          { -0.40192384f, -0.5f, 0.40192384f, -0.5f, 0.40192384f, 0.5f, -0.40192384f, 0.5f }, // edge face
-          { -0.2637079f, -0.38185397f, 0.38185397f, -0.38185397f, 0.38185397f, 0.2637079f, -0.5f, 0.5f } // corner top
-        };
-
-      final float R1 = 0.06f;
-      final float R2 = 0.04f;
-      final float R3 = 0.11f;
-      final float R4 = 0.03f;
-      final float R5 = 0.11f;
-      final float R6 = 0.08f;
-      final float[][] radii  = { {R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4},{R5,R5,R5,R5},{R6,R6,R6,R6} };
-      final float[] strokes = { 0.05f,0.04f,0.09f,0.05f,0.08f,0.08f };
-
-      mStickers = new ObjectSticker[NUM_STICKERS];
-
-      for(int s=0; s<NUM_STICKERS; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    if( mCenters==null )
-      {
-      mCenters = new float[][]
-        {
-         { 1.5f, 0.0f, 0.0f },
-         {-1.5f, 0.0f, 0.0f },
-
-         { 0.0f, 1.0f, 1.5f },
-         { 1.5f, 1.0f, 0.0f },
-         { 0.0f, 1.0f,-1.5f },
-         {-1.5f, 1.0f, 0.0f },
-         { 0.0f,-1.0f, 1.5f },
-         { 1.5f,-1.0f, 0.0f },
-         { 0.0f,-1.0f,-1.5f },
-         {-1.5f,-1.0f, 0.0f },
-
-         { 1.0f, 1.0f, 2.0f, 2.0f, 1.0f, 1.0f },
-         { 1.0f, 1.0f,-2.0f, 2.0f, 1.0f,-1.0f },
-         {-1.0f, 1.0f,-2.0f,-2.0f, 1.0f,-1.0f },
-         {-1.0f, 1.0f, 2.0f,-2.0f, 1.0f, 1.0f },
-         { 1.0f,-1.0f, 2.0f, 2.0f,-1.0f, 1.0f },
-         { 1.0f,-1.0f,-2.0f, 2.0f,-1.0f,-1.0f },
-         {-1.0f,-1.0f,-2.0f,-2.0f,-1.0f,-1.0f },
-         {-1.0f,-1.0f, 2.0f,-2.0f,-1.0f, 1.0f }
-        };
-      }
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return NUM_STICKERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mStickerColor==null )
-      {
-      // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4 ORANGE 5
-      mStickerColor = new int[][]
-        {
-          { 0, 0, 4, 0, 5, 0 },
-          { 0, 0, 5, 1, 4, 0 },
-
-          { 2, 0, 4, 0, 0, 0 },
-          { 2, 0, 0, 0, 0, 0 },
-          { 2, 0, 5, 0, 0, 0 },
-          { 2, 0, 1, 0, 0, 0 },
-          { 3, 0, 4, 0, 0, 0 },
-          { 3, 0, 0, 0, 0, 0 },
-          { 3, 0, 5, 0, 0, 0 },
-          { 3, 0, 1, 0, 0, 0 },
-
-          { 2, 0, 4, 0, 0, 0 },
-          { 2, 0, 0, 5, 0, 0 },
-          { 2, 0, 5, 1, 0, 0 },
-          { 2, 0, 1, 4, 0, 0 },
-          { 3, 0, 0, 4, 0, 0 },
-          { 3, 0, 5, 0, 0, 0 },
-          { 3, 0, 1, 5, 0, 0 },
-          { 3, 0, 4, 1, 0, 0 },
-        };
-      }
-
-    if( mStickerType==null )
-      {
-      mStickerType = new int[][]
-        {
-          {  NUM_STICKERS,NUM_STICKERS,0,           1,           2,NUM_STICKERS },
-          {             3,NUM_STICKERS,4,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
-          {             5,NUM_STICKERS,2,           2,NUM_STICKERS,NUM_STICKERS }
-        };
-      }
-
-    int variant = getCubitVariant(cubit,numLayers);
-    return 6*mStickerType[variant][cubitface] + mStickerColor[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.squa1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.squa1_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 9;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistySquare2.java b/src/main/java/org/distorted/objects/TwistySquare2.java
deleted file mode 100644
index 30605973..00000000
--- a/src/main/java/org/distorted/objects/TwistySquare2.java
+++ /dev/null
@@ -1,396 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objects;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistySquare2 extends TwistySquare
-{
-  private static final int NUM_STICKERS = 6;
-
-  private ScrambleState[] mStates;
-  private int[] mQuatNumber;
-  private float[][] mCenters;
-  private int[][] mStickerColor;
-  private int[][] mStickerType;
-  private ObjectSticker[] mStickers;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistySquare2(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                       DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, quat, texture, mesh, effects, moves, ObjectList.SQU2, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] SL_6 = new int[] { 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1, 0,1,1, 1,1,1};
-      int[] SL_1 = new int[] { 0,1,1, 1,1,1 };
-      int[] LO_2 = new int[] { 0,-5,2, 0,-4,2, 0,-3,2, 0,-2,2, 0,-1,2, 0,1,2, 0,2,2, 0,3,2, 0,4,2, 0,5,2, 0,5,2 };
-      int[] LO_3 = new int[] { 0,-5,3, 0,-4,3, 0,-3,3, 0,-2,3, 0,-1,3, 0,1,3, 0,2,3, 0,3,3, 0,4,3, 0,5,3, 0,5,3 };
-      int[] LO_4 = new int[] { 0,-5,4, 0,-4,4, 0,-3,4, 0,-2,4, 0,-1,4, 0,1,4, 0,2,4, 0,3,4, 0,4,4, 0,5,4, 0,5,4 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] { LO_2, SL_6, LO_3 } ),  // 0
-        new ScrambleState( new int[][] { LO_2, null, LO_3 } ),  // SL
-        new ScrambleState( new int[][] { null, SL_1, LO_4 } ),  // LO
-        new ScrambleState( new int[][] { LO_4, SL_1, null } ),  // UP
-        new ScrambleState( new int[][] { null, SL_1, null } ),  // UL
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    return null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-        {
-         { -1.5-X, 0.5, 1.5 },
-         {    0.0, 0.5, 1.5 },
-         {    0.0, 0.5,-1.5 },
-         { -1.5+X, 0.5,-1.5 },
-         { -1.5-X,-0.5, 1.5 },
-         {    0.0,-0.5, 1.5 },
-         {    0.0,-0.5,-1.5 },
-         { -1.5+X,-0.5,-1.5 }
-        };
-
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2,3},
-         {4,5,6,7},
-         {4,5,1,0},
-         {5,6,2,1},
-         {6,7,3,2},
-         {7,4,0,3}
-        };
-
-      float[][] bands     = new float[][] { {0.040f,35,0.8f,1.0f,5,2,1}, {0.020f,35,0.8f,1.0f,5,2,1}, {0.001f,35,0.8f,1.0f,5,2,1} };
-      int[] bandIndices   = new int[] { 2,2,1,1,0,2 };
-      float[][] corners   = new float[][] { {0.03f,0.05f} };
-      int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-      float[][] centers   = new float[][] { { -0.75f, 0.0f, 0.0f} };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      double[][] vertices = new double[][]
-        {
-         { -X, 0.5, 0.0 },
-         { +X, 0.5, 0.0 },
-         {0.0, 0.5,-1.5 },
-         { -X,-0.5, 0.0 },
-         { +X,-0.5, 0.0 },
-         {0.0,-0.5,-1.5 },
-        };
-
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2},
-         {3,4,5},
-         {3,4,1,0},
-         {4,5,2,1},
-         {5,3,0,2}
-        };
-
-      float[][] bands     = new float[][] { {0.038f,35,0.5f,0.9f, 5,2,1}, {0.001f,35,0.5f,0.9f, 5,2,1} };
-      int[] bandIndices   = new int[] { 0,1,0,1,1 };
-      float[][] corners   = new float[][] { {0.04f,0.15f} };
-      int[] cornerIndices = new int[] { 0,0,-1,0,0,-1 };
-      float[][] centers   = new float[][] { { 0.0f, 0.0f,-0.5f} };
-      int[] centerIndices = new int[] { 0,0,-1,0,0,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-        {
-         {-0.75f+X/2, 0.5,  0.0 },
-         { 0.75f-X/2, 0.5,  0.0 },
-         {-0.75f-X/2, 0.5, -1.5 },
-         {-0.75f+X/2,-0.5,  0.0 },
-         { 0.75f-X/2,-0.5,  0.0 },
-         {-0.75f-X/2,-0.5, -1.5 }
-        };
-      int[][] vert_indices = new int[][]
-        {
-         {0,1,2},
-         {5,4,3},
-         {3,4,1,0},
-         {4,5,2,1},
-         {5,3,0,2}
-        };
-
-      float[][] bands     = new float[][] { {0.030f,35,0.9f,1.0f, 5,2,1}, {0.001f,35,0.9f,1.0f, 5,2,1} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1 };
-      float[][] corners   = new float[][] { {0.05f,0.13f} };
-      int[] cornerIndices = new int[] { 0,0,-1,0,0,-1 };
-      float[][] centers   = new float[][] { { 0.0f, 0.0f,-0.5f} };
-      int[] centerIndices = new int[] { 0,0,-1,0,0,-1 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-
-    if( mQuatNumber ==null )
-      {
-      mQuatNumber = new int[]
-        {
-        0, 6,
-        0, 9, 6, 3, 18, 15, 12, 21,
-        0, 9, 6, 3, 0, 9, 6, 3,
-        15, 12, 21, 18, 15, 12, 21, 18
-        };
-      }
-
-    return mQuats[mQuatNumber[cubit]];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<2 ? 0 : (cubit<10 ? 1:2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-        {
-          { -0.5f, -0.26289170f, 0.5f, -0.26289170f, 0.5f, 0.26289170f, -0.5f, 0.26289170f }, // middle front
-          { -0.5f, -0.16666667f, 0.5f, -0.16666667f, 0.5f, 0.16666667f, -0.5f, 0.16666667f }, // middle right
-          { -0.5f, -0.45534182f, 0.5f, -0.45534182f, 0.5f, 0.45534182f, -0.5f, 0.45534182f }, // middle back
-          { -0.20096192f, -0.25f, 0.20096192f, -0.25f, 0.0f, 0.5f },                          // edge top
-          { -0.40192384f, -0.5f, 0.40192384f, -0.5f, 0.40192384f, 0.5f, -0.40192384f, 0.5f }, // edge face
-          { -0.11602539f, -0.25f, 0.4330127f, -0.25f, -0.3169873f, 0.5f }                     // corner top
-        };
-
-      final float R1 = 0.06f;
-      final float R2 = 0.04f;
-      final float R3 = 0.11f;
-      final float R4 = 0.03f;
-      final float R5 = 0.11f;
-      final float R6 = 0.025f;
-      final float[][] radii  = { {R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4},{R5,R5,R5,R5},{R6,R6,R6} };
-      final float[] strokes = { 0.05f,0.04f,0.09f,0.05f,0.08f,0.06f };
-
-      mStickers = new ObjectSticker[NUM_STICKERS];
-
-      for(int s=0; s<NUM_STICKERS; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    if( mCenters ==null )
-      {
-      float Y = 0.75f + X/2;
-
-      mCenters = new float[][]
-        {
-         { 1.5f, 0.0f, 0.0f },
-         {-1.5f, 0.0f, 0.0f },
-
-         { 0.0f, 1.0f, 1.5f },
-         { 1.5f, 1.0f, 0.0f },
-         { 0.0f, 1.0f,-1.5f },
-         {-1.5f, 1.0f, 0.0f },
-         { 0.0f,-1.0f, 1.5f },
-         { 1.5f,-1.0f, 0.0f },
-         { 0.0f,-1.0f,-1.5f },
-         {-1.5f,-1.0f, 0.0f },
-
-         {    Y, 1.0f, 1.5f },
-         { 1.5f, 1.0f,   -Y },
-         {   -Y, 1.0f,-1.5f },
-         {-1.5f, 1.0f,    Y },
-         {    Y,-1.0f, 1.5f },
-         { 1.5f,-1.0f,   -Y },
-         {   -Y,-1.0f,-1.5f },
-         {-1.5f,-1.0f,    Y },
-
-         { 1.5f, 1.0f,    Y },
-         {    Y, 1.0f,-1.5f },
-         {-1.5f, 1.0f,   -Y },
-         {   -Y, 1.0f, 1.5f },
-         { 1.5f,-1.0f,    Y },
-         {    Y,-1.0f,-1.5f },
-         {-1.5f,-1.0f,   -Y },
-         {   -Y,-1.0f, 1.5f },
-        };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return NUM_STICKERS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int numLayers)
-    {
-    if( mStickerColor==null )
-      {
-      // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4 ORANGE 5
-      mStickerColor = new int[][]
-        {
-         { 0, 0, 4, 0, 5, 0 }, // 0
-         { 0, 0, 5, 1, 4, 0 },
-
-         { 2, 0, 4, 0, 0, 0 }, // 2
-         { 2, 0, 0, 0, 0, 0 },
-         { 2, 0, 5, 0, 0, 0 },
-         { 2, 0, 1, 0, 0, 0 },
-         { 3, 0, 4, 0, 0, 0 },
-         { 3, 0, 0, 0, 0, 0 },
-         { 3, 0, 5, 0, 0, 0 },
-         { 3, 0, 1, 0, 0, 0 },
-
-         { 2, 0, 4, 0, 0, 0 }, // 10
-         { 2, 0, 0, 0, 0, 0 },
-         { 2, 0, 5, 0, 0, 0 },
-         { 2, 0, 1, 0, 0, 0 },
-         { 0, 3, 4, 0, 0, 0 },
-         { 0, 3, 0, 0, 0, 0 },
-         { 0, 3, 5, 0, 0, 0 },
-         { 0, 3, 1, 0, 0, 0 },
-
-         { 0, 2, 0, 0, 0, 0 }, // 18
-         { 0, 2, 5, 0, 0, 0 },
-         { 0, 2, 1, 0, 0, 0 },
-         { 0, 2, 4, 0, 0, 0 },
-         { 3, 0, 0, 0, 0, 0 },
-         { 3, 0, 5, 0, 0, 0 },
-         { 3, 0, 1, 0, 0, 0 },
-         { 3, 0, 4, 0, 0, 0 },
-        };
-      }
-
-    if( mStickerType==null )
-      {
-      mStickerType = new int[][]
-        {
-         {  NUM_STICKERS,NUM_STICKERS,0,           1,           2,NUM_STICKERS },
-         {             3,NUM_STICKERS,4,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
-         {             5,NUM_STICKERS,2,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
-         {  NUM_STICKERS,           5,2,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS }
-        };
-      }
-
-    int type;
-
-         if( cubit< 2             ) type = 0;
-    else if( cubit<10             ) type = 1;
-    else if( cubit>13 && cubit<22 ) type = 3;
-    else                            type = 2;
-
-    return 6*mStickerType[type][cubitface] + mStickerColor[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.squa2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.squa2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 7;
-    }
-}
diff --git a/src/main/java/org/distorted/objects/TwistyUltimate.java b/src/main/java/org/distorted/objects/TwistyUltimate.java
deleted file mode 100644
index 47f766c9..00000000
--- a/src/main/java/org/distorted/objects/TwistyUltimate.java
+++ /dev/null
@@ -1,456 +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.objects;
-
-import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
-
-import android.content.res.Resources;
-
-import org.distorted.objectlib.ObjectShape;
-import org.distorted.objectlib.ObjectSticker;
-import org.distorted.objectlib.ScrambleState;
-import org.distorted.library.main.DistortedEffects;
-import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshSquare;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static4D;
-import org.distorted.main.R;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.Movement12;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.Twisty12;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public class TwistyUltimate extends Twisty12
-{
-  private static final float A = (float)Math.sqrt(21*SQ5+47);
-  private static final float B = SQ6*(5*SQ5+11)/(6*A);
-  private static final float C = SQ6*(  SQ5+ 2)/(3*A);
-  private static final float D = SQ3/3;
-  private static final float E = (SQ5+1)/4;
-  private static final float F = (SQ5-1)/4;
-  private static final float G = (SQ5+3)/4;
-
-  static final Static3D[] ROT_AXIS = new Static3D[]
-         {
-           new Static3D( B,0,C ),
-           new Static3D( C,B,0 ),
-           new Static3D(-D,D,D ),
-           new Static3D( 0,C,-B)
-         };
-
-  private static final int[][][] ENABLED = new int[][][]
-    {
-      {{2,3}},{{1,3}},{{1,3}},{{2,3}},{{0,3}},{{0,2}},{{0,2}},{{0,3}},{{1,2}},{{0,1}},{{0,1}},{{1,2}}
-    };
-
-  private ScrambleState[] mStates;
-  private int[] mBasicAngle;
-  private Static4D[] mQuats;
-  private float[][] mCuts;
-  private boolean[][] mLayerRotatable;
-  private int[][] mFaceMap;
-  private float[][] mCenters;
-  private int[] mQuatIndex;
-  private ObjectSticker[] mStickers;
-  private Movement mMovement;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public TwistyUltimate(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
-                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
-    {
-    super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ScrambleState[] getScrambleStates()
-    {
-    if( mStates==null )
-      {
-      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
-
-      mStates = new ScrambleState[]
-        {
-        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
-        };
-      }
-
-    return mStates;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void initializeQuats()
-    {
-    mQuats = new Static4D[]
-         {
-         new Static4D( 0.0f, 0.0f, 0.0f, 1.0f ),
-         new Static4D(-0.5f, 0.5f, 0.5f, 0.5f ),
-         new Static4D( 0.5f,-0.5f,-0.5f, 0.5f ),
-         new Static4D( 0.0f,    F,   -E, 0.5f ),
-         new Static4D( 0.0f,   -F,    E, 0.5f ),
-         new Static4D(    E, 0.0f,    F, 0.5f ),
-         new Static4D(   -E, 0.0f,   -F, 0.5f ),
-         new Static4D(    F,    E, 0.0f, 0.5f ),
-         new Static4D(   -F,   -E, 0.0f, 0.5f ),
-         new Static4D(    E,    F,-0.5f, 0.0f ),
-         new Static4D( 0.5f,   -E,    F, 0.0f ),
-         new Static4D(    F, 0.5f,    E, 0.0f )
-         };
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int[] getSolvedQuats(int cubit, int numLayers)
-    {
-    if( mQuats==null ) initializeQuats();
-    int status = retCubitSolvedStatus(cubit,numLayers);
-    return status<0 ? null : buildSolvedQuats(Movement12.FACE_AXIS[status],mQuats);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectShape getObjectShape(int cubit, int numLayers)
-    {
-    int variant = getCubitVariant(cubit,numLayers);
-
-    if( variant==0 )
-      {
-      double[][] vertices = new double[][]
-         {
-           { 0.0  , 0.0  , 0.0   },
-           { -E   , E+0.5, -0.5  },
-           {-0.5  , -E   , -E-0.5},
-           { E+0.5, 0.5  , -E    },
-           { 0.0  , 1    , -2*E-1},
-           { 0.0  , 1    , 0.0   },
-           { -E   ,-E+0.5, -0.5  },
-           {  E   ,-E+0.5, -0.5  }
-         };
-      int[][] vert_indices = new int[][]
-         {
-           {6,0,5,1},
-           {0,7,3,5},
-           {0,6,2,7},
-           {4,3,5,1},
-           {4,2,7,3},
-           {4,1,6,2},
-         };
-
-      float[][] bands     = new float[][] { {0.03f,17,0.5f,0.2f,5,2,2}, {0.01f, 1,0.5f,0.2f,5,2,2} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
-      float[][] corners   = new float[][] {  { 0.013f, 0.16f } };
-      int[] cornerIndices = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
-      float[][] centers   = new float[][] { { 0.0f,-1.0f, -(SQ5+3)/2 } };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else if( variant==1 )
-      {
-      double[][] vertices = new double[][]
-         {
-            {         0.00,         0.00,         0.00},
-            {       - 0.50,-SQ5/4 - 0.25,-SQ5/4 - 0.75},
-            { SQ5/4 + 0.25,-SQ5/4 - 0.75,       + 0.50},
-            { SQ5/4 + 0.75,       + 0.50,-SQ5/4 - 0.25},
-            { SQ5/2 + 0.50,-SQ5/2 - 0.50,-SQ5/2 - 0.50},
-            { SQ5/4 - 0.25,       + 0.50,-SQ5/4 - 0.25},
-            {       - 0.50,-SQ5/4 - 0.25,-SQ5/4 + 0.25},
-            { SQ5/4 + 0.25,-SQ5/4 + 0.25,       + 0.50}
-         };
-      int[][] vert_indices  = new int[][]
-         {
-           {6,0,5,1},
-           {0,7,3,5},
-           {0,6,2,7},
-           {1,5,3,4},
-           {3,7,2,4},
-           {2,6,1,4},
-         };
-
-      float[][] bands     = new float[][] { {0.03f,17,0.5f,0.2f,5,2,2}, {0.01f, 1,0.5f,0.2f,5,2,2} };
-      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
-      float[][] corners   = new float[][] {  { 0.013f, 0.16f } };
-      int[] cornerIndices = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
-      float[][] centers   = new float[][] { { 0.0f,-1.0f, -(SQ5+3)/2 } };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    else
-      {
-      double[][] vertices = new double[][]
-         {
-           {  -E    ,-E+0.5,     0.5},
-           {   E    , E-0.5,    -0.5},
-           {-2*E    ,   0.0,     0.0},
-           {     0.5, E    ,  -E-0.5},
-           {  -E    ,-E-0.5,     0.5},
-           {   E+0.5,  -0.5,  -E    },
-           {-2*E    ,  -1.0,     0.0},
-           {     1.0,   0.0,-2*E    },
-           {-2*E+0.5, E    ,  -E-0.5},
-           {     0.5,-E-1.0,  -E+0.5},
-           {  -E    ,-E-0.5,-2*E-0.5}
-         };
-      int[][] vert_indices = new int[][]
-         {
-           {0,1,3,8,2},   // counterclockwise!
-           {0,4,9,5,1},
-           { 0,2,6,4},
-           { 1,5,7,3},
-           {10,9,4,6},
-           {10,9,5,7},
-           {10,8,3,7},
-           {10,8,2,6}
-         };
-
-      float[][] bands     = new float[][] { {0.04f,17,0.5f,0.2f,5,2,2}, {0.03f,17,0.5f,0.2f,5,2,2}, {0.01f, 1,0.5f,0.2f,5,2,2} };
-      int[] bandIndices   = new int[] { 0,0,1,1,2,2,2,2 };
-      float[][] corners   = new float[][] { { 0.013f, 0.16f } };
-      int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0,0,0,-1 };
-      float[][] centers   = new float[][] { { -(SQ5+1)/4, 0.5f, -(SQ5+5)/4 } };
-      int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0,0,0,0 };
-      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D getQuat(int cubit, int numLayers)
-    {
-    if( mQuats     ==null ) initializeQuats();
-    if( mQuatIndex ==null ) mQuatIndex = new int[] { 0,6,1,2,0,4,6,5,0,1,4,9,5,2 };
-    return mQuats[mQuatIndex[cubit]];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitVariants(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getCubitVariant(int cubit, int numLayers)
-    {
-    return cubit<4 ? 0 : (cubit<8 ? 1:2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCubitPositions(int numLayers)
-    {
-    if( mCenters==null )
-      {
-      mCenters = new float[][]
-         {
-           {   0,  -1, 2*G },
-           { 2*E,-2*E,-2*E },
-           {-2*G,   0,  -1 },
-           {   1, 2*G,   0 },
-
-           {-2*E,  2*E, 2*E },
-           { 2*G,    0,   1 },
-           {  -1, -2*G,   0 },
-           {   0,    1,-2*G },
-
-           {        E, (E+0.5f),    (E+G) },
-           {   -(E+G),       -E, (E+0.5f) },
-           { (E+0.5f),   -(E+G),        E },
-           {       -E,-(E+0.5f),   -(E+G) },
-           {    (E+G),        E,-(E+0.5f) },
-           {-(E+0.5f),    (E+G),       -E }
-         };
-      }
-
-    return mCenters;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getFaceColor(int cubit, int cubitface, int size)
-    {
-    if( mFaceMap==null )
-      {
-      mFaceMap = new int[][]
-         {
-           { 25,24,35, 36,36,36,36,36 },
-           { 27,28,29, 36,36,36,36,36 },
-           { 31,26,30, 36,36,36,36,36 },
-           { 32,34,33, 36,36,36,36,36 },
-
-           { 31,32,25, 36,36,36,36,36 },
-           { 33,28,24, 36,36,36,36,36 },
-           { 26,35,27, 36,36,36,36,36 },
-           { 30,29,34, 36,36,36,36,36 },
-
-           {  8, 0,13,21, 36,36,36,36 },
-           {  1, 2,19,23, 36,36,36,36 },
-           {  4,11,12,15, 36,36,36,36 },
-           {  3, 6,14,17, 36,36,36,36 },
-           {  5, 9,22,16, 36,36,36,36 },
-           {  7,10,20,18, 36,36,36,36 }
-         };
-      }
-
-    return mFaceMap[cubit][cubitface];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected ObjectSticker retSticker(int face)
-    {
-    if( mStickers==null )
-      {
-      float[][] STICKERS = new float[][]
-         {
-           { -0.14400357f, -0.47894150f, 0.50000000f,-0.011045523f, 0.37700626f, 0.36749030f,-0.26699730f, 0.36749026f, -0.46600536f, -0.24499352f }, // Big cubit 1st
-           {  0.36327127f,  0.26393202f,-0.36327127f, 0.500000000f,-0.36327127f,-0.26393202f, 0.36327127f,-0.50000000f },                             // Big cubit 2nd
-           { -0.29389262f, -0.50000000f, 0.29389262f,-0.309017000f, 0.29389262f, 0.30901700f,-0.29389262f, 0.50000000f },                             // Small cubit 1st
-         };
-
-      final float R1 = 0.08f;
-      final float R2 = 0.13f;
-      final float R3 = 0.11f;
-      final float[][] radii  = { {R1,R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3} };
-      final float[] strokes = { 0.07f, 0.09f, 0.08f };
-
-      mStickers = new ObjectSticker[STICKERS.length];
-
-      for(int s=0; s<STICKERS.length; s++)
-        {
-        mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
-        }
-      }
-
-    return mStickers[face/NUM_FACE_COLORS];
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected Static4D[] getQuats()
-    {
-    if( mQuats==null ) initializeQuats();
-    return mQuats;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getSolvedFunctionIndex()
-    {
-    return 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected float[][] getCuts(int numLayers)
-    {
-    if( mCuts==null )
-      {
-      float[] cut = new float[] {0.0f};
-      mCuts = new float[][] { cut,cut,cut,cut };
-      }
-
-    return mCuts;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void getLayerRotatable(int numLayers)
-    {
-    if( mLayerRotatable==null )
-      {
-      int numAxis = ROT_AXIS.length;
-      boolean[] tmp = new boolean[numLayers];
-      for(int i=0; i<numLayers; i++) tmp[i] = true;
-      mLayerRotatable = new boolean[numAxis][];
-      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumStickerTypes(int numLayers)
-    {
-    return 3;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  protected int getNumCubitFaces()
-    {
-    return 8;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-
-  public Static3D[] getRotationAxis()
-    {
-    return ROT_AXIS;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public Movement getMovement()
-    {
-    if( mMovement==null )
-      {
-      int numLayers = getNumLayers();
-      if( mCuts==null ) getCuts(numLayers);
-      getLayerRotatable(numLayers);
-      mMovement = new Movement12(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
-      }
-    return mMovement;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int[] getBasicAngle()
-    {
-    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
-    return mBasicAngle;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getObjectName(int numLayers)
-    {
-    return R.string.ulti2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getInventor(int numLayers)
-    {
-    return R.string.ulti2_inventor;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getComplexity(int numLayers)
-    {
-    return 6;
-    }
-}
diff --git a/src/main/java/org/distorted/patterns/RubikPattern.java b/src/main/java/org/distorted/patterns/RubikPattern.java
index 790f9749..c15e32c8 100644
--- a/src/main/java/org/distorted/patterns/RubikPattern.java
+++ b/src/main/java/org/distorted/patterns/RubikPattern.java
@@ -19,12 +19,12 @@
 
 package org.distorted.patterns;
 
-import org.distorted.helpers.MovesFinished;
-import org.distorted.main.RubikPreRender;
-
 import java.util.ArrayList;
 import java.util.List;
 
+import org.distorted.helpers.MovesFinished;
+import org.distorted.main.RubikPreRender;
+
 import static org.distorted.patterns.RubikPatternList.NUM_OBJECTS;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/patterns/RubikPatternList.java b/src/main/java/org/distorted/patterns/RubikPatternList.java
index d0dcc40e..bfb96c5f 100644
--- a/src/main/java/org/distorted/patterns/RubikPatternList.java
+++ b/src/main/java/org/distorted/patterns/RubikPatternList.java
@@ -19,7 +19,7 @@
 
 package org.distorted.patterns;
 
-import org.distorted.objectlib.ObjectList;
+import org.distorted.objectlib.main.ObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/screens/RubikScreenAbstract.java b/src/main/java/org/distorted/screens/RubikScreenAbstract.java
index 4a322c48..c6eb87d5 100644
--- a/src/main/java/org/distorted/screens/RubikScreenAbstract.java
+++ b/src/main/java/org/distorted/screens/RubikScreenAbstract.java
@@ -21,8 +21,9 @@ package org.distorted.screens;
 
 import android.content.SharedPreferences;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.patterns.RubikPatternList;
 import org.distorted.tutorials.TutorialList;
 
diff --git a/src/main/java/org/distorted/screens/RubikScreenPattern.java b/src/main/java/org/distorted/screens/RubikScreenPattern.java
index 9f442b79..bb7dcdbc 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPattern.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPattern.java
@@ -30,12 +30,13 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
+import org.distorted.main.R;
 import org.distorted.dialogs.RubikDialogPattern;
 import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikPreRender;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.patterns.RubikPattern;
 import org.distorted.patterns.RubikPatternList;
 
diff --git a/src/main/java/org/distorted/screens/RubikScreenPlay.java b/src/main/java/org/distorted/screens/RubikScreenPlay.java
index 70b713be..376903c3 100644
--- a/src/main/java/org/distorted/screens/RubikScreenPlay.java
+++ b/src/main/java/org/distorted/screens/RubikScreenPlay.java
@@ -35,16 +35,17 @@ import android.widget.LinearLayout;
 import android.widget.PopupWindow;
 import android.widget.ScrollView;
 
+import org.distorted.objectlib.main.ObjectList;
+
+import org.distorted.main.R;
+import org.distorted.main.RubikActivity;
+import org.distorted.main.RubikPreRender;
 import org.distorted.dialogs.RubikDialogAbout;
 import org.distorted.dialogs.RubikDialogPattern;
 import org.distorted.dialogs.RubikDialogScores;
 import org.distorted.dialogs.RubikDialogTutorial;
 import org.distorted.helpers.TransparentButton;
 import org.distorted.helpers.TransparentImageButton;
-import org.distorted.main.R;
-import org.distorted.main.RubikActivity;
-import org.distorted.main.RubikPreRender;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolution.java b/src/main/java/org/distorted/screens/RubikScreenSolution.java
index bd291242..9d1bfa1a 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolution.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolution.java
@@ -28,12 +28,13 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.TwistyObject;
+
 import org.distorted.helpers.MovesFinished;
 import org.distorted.helpers.TransparentImageButton;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikPreRender;
-import org.distorted.objectlib.TwistyObject;
 import org.distorted.patterns.RubikPattern;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolver.java b/src/main/java/org/distorted/screens/RubikScreenSolver.java
index 0341bd37..6a0871cc 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolver.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolver.java
@@ -19,6 +19,8 @@
 
 package org.distorted.screens;
 
+import java.lang.ref.WeakReference;
+
 import android.content.SharedPreferences;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -31,18 +33,17 @@ import android.view.View;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 
+import org.distorted.objectlib.main.TwistyObject;
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.dialogs.RubikDialogSolverError;
 import org.distorted.helpers.TransparentImageButton;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
 import org.distorted.main.RubikPreRender;
-import org.distorted.objectlib.TwistyObject;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.solvers.ImplementedSolversList;
 import org.distorted.solvers.SolverMain;
 
-import java.lang.ref.WeakReference;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikScreenSolver extends RubikScreenAbstract
diff --git a/src/main/java/org/distorted/screens/RubikScreenSolving.java b/src/main/java/org/distorted/screens/RubikScreenSolving.java
index de07badf..b1b8eba6 100644
--- a/src/main/java/org/distorted/screens/RubikScreenSolving.java
+++ b/src/main/java/org/distorted/screens/RubikScreenSolving.java
@@ -19,6 +19,9 @@
 
 package org.distorted.screens;
 
+import java.util.Timer;
+import java.util.TimerTask;
+
 import android.content.SharedPreferences;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
@@ -27,16 +30,14 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.dialogs.RubikDialogAbandon;
 import org.distorted.helpers.TransparentImageButton;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.network.RubikScores;
 
-import java.util.Timer;
-import java.util.TimerTask;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikScreenSolving extends RubikScreenBase
diff --git a/src/main/java/org/distorted/solvers/ImplementedSolversList.java b/src/main/java/org/distorted/solvers/ImplementedSolversList.java
index 5c005504..9a404997 100644
--- a/src/main/java/org/distorted/solvers/ImplementedSolversList.java
+++ b/src/main/java/org/distorted/solvers/ImplementedSolversList.java
@@ -19,7 +19,7 @@
 
 package org.distorted.solvers;
 
-import org.distorted.objectlib.ObjectList;
+import org.distorted.objectlib.main.ObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/solvers/SolverMain.java b/src/main/java/org/distorted/solvers/SolverMain.java
index 5ca877fe..ea494521 100644
--- a/src/main/java/org/distorted/solvers/SolverMain.java
+++ b/src/main/java/org/distorted/solvers/SolverMain.java
@@ -21,9 +21,10 @@ package org.distorted.solvers;
 
 import android.content.res.Resources;
 
+import org.distorted.objectlib.main.ObjectList;
+import org.distorted.objectlib.main.TwistyObject;
+
 import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.TwistyObject;
 import org.distorted.screens.ScreenList;
 import org.distorted.screens.RubikScreenSolver;
 
diff --git a/src/main/java/org/distorted/tutorials/TutorialActivity.java b/src/main/java/org/distorted/tutorials/TutorialActivity.java
index 7a81238e..78cf6f75 100644
--- a/src/main/java/org/distorted/tutorials/TutorialActivity.java
+++ b/src/main/java/org/distorted/tutorials/TutorialActivity.java
@@ -30,14 +30,16 @@ import android.widget.LinearLayout;
 
 import com.google.firebase.analytics.FirebaseAnalytics;
 
+import org.distorted.library.main.DistortedLibrary;
+
+import org.distorted.objectlib.main.ObjectList;
+import org.distorted.objectlib.main.TwistyObject;
+
 import org.distorted.dialogs.RubikDialogError;
 import org.distorted.helpers.BlockController;
 import org.distorted.helpers.TwistyActivity;
 import org.distorted.helpers.TwistyPreRender;
-import org.distorted.library.main.DistortedLibrary;
 import org.distorted.main.R;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.TwistyObject;
 
 import static org.distorted.main.RubikRenderer.BRIGHTNESS;
 
diff --git a/src/main/java/org/distorted/tutorials/TutorialList.java b/src/main/java/org/distorted/tutorials/TutorialList.java
index 2aba3989..9b1e60d2 100644
--- a/src/main/java/org/distorted/tutorials/TutorialList.java
+++ b/src/main/java/org/distorted/tutorials/TutorialList.java
@@ -19,8 +19,8 @@
 
 package org.distorted.tutorials;
 
+import org.distorted.objectlib.main.ObjectList;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/tutorials/TutorialPreRender.java b/src/main/java/org/distorted/tutorials/TutorialPreRender.java
index 681eb645..209cc287 100644
--- a/src/main/java/org/distorted/tutorials/TutorialPreRender.java
+++ b/src/main/java/org/distorted/tutorials/TutorialPreRender.java
@@ -22,14 +22,14 @@ package org.distorted.tutorials;
 import android.content.Context;
 import android.content.res.Resources;
 
+import org.distorted.objectlib.main.ObjectList;
+import org.distorted.objectlib.main.TwistyObject;
+
 import org.distorted.effects.BaseEffect;
 import org.distorted.effects.EffectController;
 import org.distorted.helpers.BlockController;
 import org.distorted.helpers.MovesFinished;
 import org.distorted.helpers.TwistyPreRender;
-import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
-import org.distorted.objectlib.TwistyObject;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -93,7 +93,7 @@ public class TutorialPreRender implements EffectController, TwistyPreRender
     Context con = mView.getContext();
     Resources res = con.getResources();
 
-    mNewObject = RubikActivity.create(object,size, mView.getQuat(), null, res, mScreenWidth);
+    mNewObject = object.create(size, mView.getQuat(), null, res, mScreenWidth);
 
     if( mNewObject!=null )
       {
diff --git a/src/main/java/org/distorted/tutorials/TutorialRenderer.java b/src/main/java/org/distorted/tutorials/TutorialRenderer.java
index 48a8d850..783345e8 100644
--- a/src/main/java/org/distorted/tutorials/TutorialRenderer.java
+++ b/src/main/java/org/distorted/tutorials/TutorialRenderer.java
@@ -19,17 +19,18 @@
 
 package org.distorted.tutorials;
 
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
 import android.opengl.GLSurfaceView;
 
-import org.distorted.effects.BaseEffect;
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.VertexEffectQuaternion;
 import org.distorted.library.effect.VertexEffectRotate;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedScreen;
 
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
+import org.distorted.effects.BaseEffect;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/main/java/org/distorted/tutorials/TutorialState.java b/src/main/java/org/distorted/tutorials/TutorialState.java
index 0b410bbe..1ed6ecdb 100644
--- a/src/main/java/org/distorted/tutorials/TutorialState.java
+++ b/src/main/java/org/distorted/tutorials/TutorialState.java
@@ -23,12 +23,13 @@ import android.view.View;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 
+import org.distorted.objectlib.main.ObjectList;
+
 import org.distorted.helpers.MovesAndLockController;
 import org.distorted.helpers.TwistyActivity;
 import org.distorted.helpers.TwistyPreRender;
 import org.distorted.main.R;
 import org.distorted.main.RubikActivity;
-import org.distorted.objectlib.ObjectList;
 import org.distorted.screens.RubikScreenPlay;
 import org.distorted.screens.ScreenList;
 import org.distorted.helpers.TransparentImageButton;
diff --git a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
index 06f3768d..115b450a 100644
--- a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
+++ b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
@@ -30,11 +30,12 @@ import android.view.MotionEvent;
 
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
-import org.distorted.objectlib.QuatHelper;
 import org.distorted.library.type.Static2D;
 import org.distorted.library.type.Static4D;
-import org.distorted.objectlib.Movement;
-import org.distorted.objectlib.TwistyObject;
+
+import org.distorted.objectlib.main.QuatHelper;
+import org.distorted.objectlib.main.Movement;
+import org.distorted.objectlib.main.TwistyObject;
 
 import static org.distorted.main.RubikSurfaceView.INVALID_POINTER_ID;
 import static org.distorted.main.RubikSurfaceView.NUM_SPEED_PROBES;
diff --git a/src/main/res/drawable-nodpi/ui_big_ban1.png b/src/main/res/drawable-nodpi/ui_big_ban1.png
deleted file mode 100644
index 188a6ec4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ban1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_ban2.png b/src/main/res/drawable-nodpi/ui_big_ban2.png
deleted file mode 100644
index 5d7ad6e1..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ban2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_ban3.png b/src/main/res/drawable-nodpi/ui_big_ban3.png
deleted file mode 100644
index b2b5cafd..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ban3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_ban4.png b/src/main/res/drawable-nodpi/ui_big_ban4.png
deleted file mode 100644
index 6a1643e5..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ban4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_cube2.png b/src/main/res/drawable-nodpi/ui_big_cube2.png
deleted file mode 100644
index 53e89cf2..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_cube2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_cube3.png b/src/main/res/drawable-nodpi/ui_big_cube3.png
deleted file mode 100644
index a22d8a4d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_cube3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_cube4.png b/src/main/res/drawable-nodpi/ui_big_cube4.png
deleted file mode 100644
index 472b70df..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_cube4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_cube5.png b/src/main/res/drawable-nodpi/ui_big_cube5.png
deleted file mode 100644
index 46fee585..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_cube5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_diam2.png b/src/main/res/drawable-nodpi/ui_big_diam2.png
deleted file mode 100644
index f0c27ea3..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_diam2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_diam3.png b/src/main/res/drawable-nodpi/ui_big_diam3.png
deleted file mode 100644
index e5892e7a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_diam3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_diam4.png b/src/main/res/drawable-nodpi/ui_big_diam4.png
deleted file mode 100644
index 167b52d0..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_diam4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_din4.png b/src/main/res/drawable-nodpi/ui_big_din4.png
deleted file mode 100644
index 212fd55b..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_din4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_dino.png b/src/main/res/drawable-nodpi/ui_big_dino.png
deleted file mode 100644
index d60ecd88..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_dino.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_heli.png b/src/main/res/drawable-nodpi/ui_big_heli.png
deleted file mode 100644
index 2ec198ac..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_heli.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_ivy.png b/src/main/res/drawable-nodpi/ui_big_ivy.png
deleted file mode 100644
index dde87775..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ivy.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_jing2.png b/src/main/res/drawable-nodpi/ui_big_jing2.png
deleted file mode 100644
index f9f80516..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_jing2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_kilo3.png b/src/main/res/drawable-nodpi/ui_big_kilo3.png
deleted file mode 100644
index 7e5779fd..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_kilo3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_kilo5.png b/src/main/res/drawable-nodpi/ui_big_kilo5.png
deleted file mode 100644
index 6ce95cb4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_kilo5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_mega3.png b/src/main/res/drawable-nodpi/ui_big_mega3.png
deleted file mode 100644
index 4e7aa6cf..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_mega3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_mega5.png b/src/main/res/drawable-nodpi/ui_big_mega5.png
deleted file mode 100644
index 0363ee35..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_mega5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_menu.png b/src/main/res/drawable-nodpi/ui_big_menu.png
deleted file mode 100644
index 85e5f276..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_menu.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_mirr2.png b/src/main/res/drawable-nodpi/ui_big_mirr2.png
deleted file mode 100644
index 3a5d3e8f..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_mirr2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_mirr3.png b/src/main/res/drawable-nodpi/ui_big_mirr3.png
deleted file mode 100644
index d3dcf556..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_mirr3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_pyra2.png b/src/main/res/drawable-nodpi/ui_big_pyra2.png
deleted file mode 100644
index 11358f12..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_pyra2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_pyra3.png b/src/main/res/drawable-nodpi/ui_big_pyra3.png
deleted file mode 100644
index 7d76defb..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_pyra3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_pyra4.png b/src/main/res/drawable-nodpi/ui_big_pyra4.png
deleted file mode 100644
index a1a7a377..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_pyra4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_pyra5.png b/src/main/res/drawable-nodpi/ui_big_pyra5.png
deleted file mode 100644
index fcc4b751..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_pyra5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_redi.png b/src/main/res/drawable-nodpi/ui_big_redi.png
deleted file mode 100644
index 4f054b9d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_redi.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_rex.png b/src/main/res/drawable-nodpi/ui_big_rex.png
deleted file mode 100644
index 7703be3d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_rex.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_skew2.png b/src/main/res/drawable-nodpi/ui_big_skew2.png
deleted file mode 100644
index 654d457c..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_skew2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_skew3.png b/src/main/res/drawable-nodpi/ui_big_skew3.png
deleted file mode 100644
index c4072f44..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_skew3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_squa1.png b/src/main/res/drawable-nodpi/ui_big_squa1.png
deleted file mode 100644
index 92892943..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_squa1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_squa2.png b/src/main/res/drawable-nodpi/ui_big_squa2.png
deleted file mode 100644
index f9cfa71d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_squa2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_big_ulti.png b/src/main/res/drawable-nodpi/ui_big_ulti.png
deleted file mode 100644
index 7da0c0e1..00000000
Binary files a/src/main/res/drawable-nodpi/ui_big_ulti.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ban1.png b/src/main/res/drawable-nodpi/ui_huge_ban1.png
deleted file mode 100644
index b70e0ba8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ban1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ban2.png b/src/main/res/drawable-nodpi/ui_huge_ban2.png
deleted file mode 100644
index a6a91af4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ban2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ban3.png b/src/main/res/drawable-nodpi/ui_huge_ban3.png
deleted file mode 100644
index 9312aef7..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ban3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ban4.png b/src/main/res/drawable-nodpi/ui_huge_ban4.png
deleted file mode 100644
index e5f69eed..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ban4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_cube2.png b/src/main/res/drawable-nodpi/ui_huge_cube2.png
deleted file mode 100644
index 1d541de4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_cube2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_cube3.png b/src/main/res/drawable-nodpi/ui_huge_cube3.png
deleted file mode 100644
index 1000bb32..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_cube3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_cube4.png b/src/main/res/drawable-nodpi/ui_huge_cube4.png
deleted file mode 100644
index 89ef3641..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_cube4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_cube5.png b/src/main/res/drawable-nodpi/ui_huge_cube5.png
deleted file mode 100644
index d44cb93c..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_cube5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_diam2.png b/src/main/res/drawable-nodpi/ui_huge_diam2.png
deleted file mode 100644
index 1339c979..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_diam2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_diam3.png b/src/main/res/drawable-nodpi/ui_huge_diam3.png
deleted file mode 100644
index c7164160..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_diam3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_diam4.png b/src/main/res/drawable-nodpi/ui_huge_diam4.png
deleted file mode 100644
index 6c9d024e..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_diam4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_din4.png b/src/main/res/drawable-nodpi/ui_huge_din4.png
deleted file mode 100644
index e4388e79..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_din4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_dino.png b/src/main/res/drawable-nodpi/ui_huge_dino.png
deleted file mode 100644
index af221779..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_dino.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_heli.png b/src/main/res/drawable-nodpi/ui_huge_heli.png
deleted file mode 100644
index a7cfb34a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_heli.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ivy.png b/src/main/res/drawable-nodpi/ui_huge_ivy.png
deleted file mode 100644
index f021dc4f..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ivy.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_jing2.png b/src/main/res/drawable-nodpi/ui_huge_jing2.png
deleted file mode 100644
index ad7bc551..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_jing2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_kilo3.png b/src/main/res/drawable-nodpi/ui_huge_kilo3.png
deleted file mode 100644
index 7babb464..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_kilo3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_kilo5.png b/src/main/res/drawable-nodpi/ui_huge_kilo5.png
deleted file mode 100644
index a1cabfae..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_kilo5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_mega3.png b/src/main/res/drawable-nodpi/ui_huge_mega3.png
deleted file mode 100644
index 620777b2..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_mega3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_mega5.png b/src/main/res/drawable-nodpi/ui_huge_mega5.png
deleted file mode 100644
index e86abd24..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_mega5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_mirr2.png b/src/main/res/drawable-nodpi/ui_huge_mirr2.png
deleted file mode 100644
index a1af6f6a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_mirr2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_mirr3.png b/src/main/res/drawable-nodpi/ui_huge_mirr3.png
deleted file mode 100644
index bfa71f6c..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_mirr3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_pyra2.png b/src/main/res/drawable-nodpi/ui_huge_pyra2.png
deleted file mode 100644
index 987469bb..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_pyra2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_pyra3.png b/src/main/res/drawable-nodpi/ui_huge_pyra3.png
deleted file mode 100644
index b3d64fe1..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_pyra3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_pyra4.png b/src/main/res/drawable-nodpi/ui_huge_pyra4.png
deleted file mode 100644
index 0e55237c..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_pyra4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_pyra5.png b/src/main/res/drawable-nodpi/ui_huge_pyra5.png
deleted file mode 100644
index 7a83df5b..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_pyra5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_redi.png b/src/main/res/drawable-nodpi/ui_huge_redi.png
deleted file mode 100644
index b6b3502f..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_redi.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_rex.png b/src/main/res/drawable-nodpi/ui_huge_rex.png
deleted file mode 100644
index 7b352855..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_rex.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_skew2.png b/src/main/res/drawable-nodpi/ui_huge_skew2.png
deleted file mode 100644
index f431b1e6..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_skew2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_skew3.png b/src/main/res/drawable-nodpi/ui_huge_skew3.png
deleted file mode 100644
index 8c096b81..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_skew3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_squa1.png b/src/main/res/drawable-nodpi/ui_huge_squa1.png
deleted file mode 100644
index f57d8ec6..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_squa1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_squa2.png b/src/main/res/drawable-nodpi/ui_huge_squa2.png
deleted file mode 100644
index 16772218..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_squa2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_huge_ulti.png b/src/main/res/drawable-nodpi/ui_huge_ulti.png
deleted file mode 100644
index fcfda055..00000000
Binary files a/src/main/res/drawable-nodpi/ui_huge_ulti.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ban1.png b/src/main/res/drawable-nodpi/ui_medium_ban1.png
deleted file mode 100644
index 9429379e..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ban1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ban2.png b/src/main/res/drawable-nodpi/ui_medium_ban2.png
deleted file mode 100644
index 79ea3141..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ban2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ban3.png b/src/main/res/drawable-nodpi/ui_medium_ban3.png
deleted file mode 100644
index 9bc05620..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ban3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ban4.png b/src/main/res/drawable-nodpi/ui_medium_ban4.png
deleted file mode 100644
index 4f249d0b..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ban4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_cube2.png b/src/main/res/drawable-nodpi/ui_medium_cube2.png
deleted file mode 100644
index e081b29d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_cube2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_cube3.png b/src/main/res/drawable-nodpi/ui_medium_cube3.png
deleted file mode 100644
index 3c0185d3..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_cube3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_cube4.png b/src/main/res/drawable-nodpi/ui_medium_cube4.png
deleted file mode 100644
index bf1db71c..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_cube4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_cube5.png b/src/main/res/drawable-nodpi/ui_medium_cube5.png
deleted file mode 100644
index 8efa6dd8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_cube5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_diam2.png b/src/main/res/drawable-nodpi/ui_medium_diam2.png
deleted file mode 100644
index c4e4e7ac..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_diam2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_diam3.png b/src/main/res/drawable-nodpi/ui_medium_diam3.png
deleted file mode 100644
index 864864fb..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_diam3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_diam4.png b/src/main/res/drawable-nodpi/ui_medium_diam4.png
deleted file mode 100644
index 5c2822d9..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_diam4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_din4.png b/src/main/res/drawable-nodpi/ui_medium_din4.png
deleted file mode 100644
index 66a81806..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_din4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_dino.png b/src/main/res/drawable-nodpi/ui_medium_dino.png
deleted file mode 100644
index f4eb1ba4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_dino.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_heli.png b/src/main/res/drawable-nodpi/ui_medium_heli.png
deleted file mode 100644
index 7b917554..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_heli.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ivy.png b/src/main/res/drawable-nodpi/ui_medium_ivy.png
deleted file mode 100644
index d56a5068..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ivy.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_jing2.png b/src/main/res/drawable-nodpi/ui_medium_jing2.png
deleted file mode 100644
index 6ddc93ea..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_jing2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_kilo3.png b/src/main/res/drawable-nodpi/ui_medium_kilo3.png
deleted file mode 100644
index 99ea4b3d..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_kilo3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_kilo5.png b/src/main/res/drawable-nodpi/ui_medium_kilo5.png
deleted file mode 100644
index 940cac29..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_kilo5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_mega3.png b/src/main/res/drawable-nodpi/ui_medium_mega3.png
deleted file mode 100644
index f1611980..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_mega3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_mega5.png b/src/main/res/drawable-nodpi/ui_medium_mega5.png
deleted file mode 100644
index 7337cb03..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_mega5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_mirr2.png b/src/main/res/drawable-nodpi/ui_medium_mirr2.png
deleted file mode 100644
index 123eafd9..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_mirr2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_mirr3.png b/src/main/res/drawable-nodpi/ui_medium_mirr3.png
deleted file mode 100644
index f17bad5e..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_mirr3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_pyra2.png b/src/main/res/drawable-nodpi/ui_medium_pyra2.png
deleted file mode 100644
index d11cf90e..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_pyra2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_pyra3.png b/src/main/res/drawable-nodpi/ui_medium_pyra3.png
deleted file mode 100644
index 61ebdbc4..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_pyra3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_pyra4.png b/src/main/res/drawable-nodpi/ui_medium_pyra4.png
deleted file mode 100644
index 6bb90d54..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_pyra4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_pyra5.png b/src/main/res/drawable-nodpi/ui_medium_pyra5.png
deleted file mode 100644
index 569ab4fe..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_pyra5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_redi.png b/src/main/res/drawable-nodpi/ui_medium_redi.png
deleted file mode 100644
index 0adaa838..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_redi.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_rex.png b/src/main/res/drawable-nodpi/ui_medium_rex.png
deleted file mode 100644
index 6c861927..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_rex.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_skew2.png b/src/main/res/drawable-nodpi/ui_medium_skew2.png
deleted file mode 100644
index 1dd3b3ef..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_skew2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_skew3.png b/src/main/res/drawable-nodpi/ui_medium_skew3.png
deleted file mode 100644
index bf6c510b..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_skew3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_squa1.png b/src/main/res/drawable-nodpi/ui_medium_squa1.png
deleted file mode 100644
index ed4e7c56..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_squa1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_squa2.png b/src/main/res/drawable-nodpi/ui_medium_squa2.png
deleted file mode 100644
index 37312fdf..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_squa2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_medium_ulti.png b/src/main/res/drawable-nodpi/ui_medium_ulti.png
deleted file mode 100644
index 5a3d3d16..00000000
Binary files a/src/main/res/drawable-nodpi/ui_medium_ulti.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ban1.png b/src/main/res/drawable-nodpi/ui_small_ban1.png
deleted file mode 100644
index 579fd1bb..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ban1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ban2.png b/src/main/res/drawable-nodpi/ui_small_ban2.png
deleted file mode 100644
index 543bf379..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ban2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ban3.png b/src/main/res/drawable-nodpi/ui_small_ban3.png
deleted file mode 100644
index 105def04..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ban3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ban4.png b/src/main/res/drawable-nodpi/ui_small_ban4.png
deleted file mode 100644
index 416c2c9a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ban4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_cube2.png b/src/main/res/drawable-nodpi/ui_small_cube2.png
deleted file mode 100644
index eb781e64..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_cube2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_cube3.png b/src/main/res/drawable-nodpi/ui_small_cube3.png
deleted file mode 100644
index dae0f164..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_cube3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_cube4.png b/src/main/res/drawable-nodpi/ui_small_cube4.png
deleted file mode 100644
index c37a2e75..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_cube4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_cube5.png b/src/main/res/drawable-nodpi/ui_small_cube5.png
deleted file mode 100644
index c6c5ff3a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_cube5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_diam2.png b/src/main/res/drawable-nodpi/ui_small_diam2.png
deleted file mode 100644
index 1c849467..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_diam2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_diam3.png b/src/main/res/drawable-nodpi/ui_small_diam3.png
deleted file mode 100644
index d8b719ec..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_diam3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_diam4.png b/src/main/res/drawable-nodpi/ui_small_diam4.png
deleted file mode 100644
index a8b13ead..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_diam4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_din4.png b/src/main/res/drawable-nodpi/ui_small_din4.png
deleted file mode 100644
index 8c68e947..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_din4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_dino.png b/src/main/res/drawable-nodpi/ui_small_dino.png
deleted file mode 100644
index 7b81d9d8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_dino.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_heli.png b/src/main/res/drawable-nodpi/ui_small_heli.png
deleted file mode 100644
index f39099c8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_heli.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ivy.png b/src/main/res/drawable-nodpi/ui_small_ivy.png
deleted file mode 100644
index ccb45204..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ivy.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_jing2.png b/src/main/res/drawable-nodpi/ui_small_jing2.png
deleted file mode 100644
index 20c31754..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_jing2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_kilo3.png b/src/main/res/drawable-nodpi/ui_small_kilo3.png
deleted file mode 100644
index 5895fcb8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_kilo3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_kilo5.png b/src/main/res/drawable-nodpi/ui_small_kilo5.png
deleted file mode 100644
index 87616aa7..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_kilo5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_mega3.png b/src/main/res/drawable-nodpi/ui_small_mega3.png
deleted file mode 100644
index 09e6b796..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_mega3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_mega5.png b/src/main/res/drawable-nodpi/ui_small_mega5.png
deleted file mode 100644
index 618d2508..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_mega5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_mirr2.png b/src/main/res/drawable-nodpi/ui_small_mirr2.png
deleted file mode 100644
index f47570aa..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_mirr2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_mirr3.png b/src/main/res/drawable-nodpi/ui_small_mirr3.png
deleted file mode 100644
index 7fcb8b67..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_mirr3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_pyra2.png b/src/main/res/drawable-nodpi/ui_small_pyra2.png
deleted file mode 100644
index 239d380a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_pyra2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_pyra3.png b/src/main/res/drawable-nodpi/ui_small_pyra3.png
deleted file mode 100644
index e7fa6640..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_pyra3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_pyra4.png b/src/main/res/drawable-nodpi/ui_small_pyra4.png
deleted file mode 100644
index 11b2e7fa..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_pyra4.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_pyra5.png b/src/main/res/drawable-nodpi/ui_small_pyra5.png
deleted file mode 100644
index 55aa5dba..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_pyra5.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_redi.png b/src/main/res/drawable-nodpi/ui_small_redi.png
deleted file mode 100644
index 16db11a8..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_redi.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_rex.png b/src/main/res/drawable-nodpi/ui_small_rex.png
deleted file mode 100644
index 0e6513cb..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_rex.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_skew2.png b/src/main/res/drawable-nodpi/ui_small_skew2.png
deleted file mode 100644
index e7d5f56a..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_skew2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_skew3.png b/src/main/res/drawable-nodpi/ui_small_skew3.png
deleted file mode 100644
index 8d675a93..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_skew3.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_squa1.png b/src/main/res/drawable-nodpi/ui_small_squa1.png
deleted file mode 100644
index f53f0b56..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_squa1.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_squa2.png b/src/main/res/drawable-nodpi/ui_small_squa2.png
deleted file mode 100644
index 9d2757b3..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_squa2.png and /dev/null differ
diff --git a/src/main/res/drawable-nodpi/ui_small_ulti.png b/src/main/res/drawable-nodpi/ui_small_ulti.png
deleted file mode 100644
index 1b5c4be6..00000000
Binary files a/src/main/res/drawable-nodpi/ui_small_ulti.png and /dev/null differ
diff --git a/src/main/res/raw/ban1.dmesh b/src/main/res/raw/ban1.dmesh
deleted file mode 100644
index b9d7abdf..00000000
Binary files a/src/main/res/raw/ban1.dmesh and /dev/null differ
diff --git a/src/main/res/raw/ban2.dmesh b/src/main/res/raw/ban2.dmesh
deleted file mode 100644
index 7b914a4c..00000000
Binary files a/src/main/res/raw/ban2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/ban3.dmesh b/src/main/res/raw/ban3.dmesh
deleted file mode 100644
index c8d5d2b7..00000000
Binary files a/src/main/res/raw/ban3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/ban4.dmesh b/src/main/res/raw/ban4.dmesh
deleted file mode 100644
index e3f207ad..00000000
Binary files a/src/main/res/raw/ban4.dmesh and /dev/null differ
diff --git a/src/main/res/raw/compute_quats.c b/src/main/res/raw/compute_quats.c
deleted file mode 100644
index 1f590acc..00000000
--- a/src/main/res/raw/compute_quats.c
+++ /dev/null
@@ -1,240 +0,0 @@
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h>
-
-#define SQUARE
-
-#define SQ2 1.41421356237f
-#define SQ3 1.73205080757f
-#define SQ5 2.23606797750f
-#define PI  3.14159265358f
-#define NUM_QUATS  200
-
-#ifdef PYRA 
-int basic[] = { 3,3,3,3 };
-
-float axis[][3] = { { SQ2*SQ3/3,   SQ3/3,          0 } ,
-                    {-SQ2*SQ3/3,   SQ3/3,          0 } ,
-                    {         0,  -SQ3/3, -SQ2*SQ3/3 } ,
-                    {         0,  -SQ3/3,  SQ2*SQ3/3 } };
-#endif
-
-#ifdef CUBE
-int basic[] = { 4,4,4 };
-
-float axis[][3] = { { 1,0,0 } , 
-                    { 0,1,0 } , 
-                    { 0,0,1 } };
-#endif
-
-#ifdef DINO
-int basic[] = { 3,3,3,3 };
-
-float axis[][3] = { {+SQ3/3,+SQ3/3,+SQ3/3} , 
-                    {+SQ3/3,+SQ3/3,-SQ3/3} , 
-                    {+SQ3/3,-SQ3/3,+SQ3/3} , 
-                    {+SQ3/3,-SQ3/3,-SQ3/3} };
-#endif
-
-#ifdef DIAM
-int basic[] = { 3,3,3,3 };
-
-float axis[][3] = { {+SQ3*SQ2/3,+SQ3/3,         0} ,
-                    {-SQ3*SQ2/3,+SQ3/3,         0} ,
-                    {         0,+SQ3/3,+SQ3*SQ2/3} ,
-                    {         0,+SQ3/3,-SQ3*SQ2/3} };
-#endif
-
-#ifdef HELI
-int basic[] = { 2,2,2,2,2,2 };
-
-float axis[][3] = { {     0, +SQ2/2, -SQ2/2} ,
-                    {     0, -SQ2/2, -SQ2/2} ,
-                    {+SQ2/2,      0, -SQ2/2} ,
-                    {-SQ2/2,      0, -SQ2/2} ,
-                    {+SQ2/2, -SQ2/2,      0} ,
-                    {-SQ2/2, -SQ2/2,      0} };
-
-#endif
-
-#ifdef ULTI
-int basic[] = { 3,3,3,3 };
-
-float axis[][3] = { { 5*SQ5/16 + 11.0f/16,              0.0f   ,    SQ5/8  + 1.0f/4 } ,
-                    {   SQ5/8  +  1.0f/4 ,  5*SQ5/16 + 11.0f/16,             0.0f   } ,
-                    {-3*SQ5/16 -  7.0f/16,  3*SQ5/16 +  7.0f/16,  3*SQ5/16 + 7.0f/16} ,
-                    {             0.0f   ,    SQ5/4  +  1.0f/2 , -5*SQ5/8  -11.0f/8 } };
-
-#endif
-
-#ifdef SQUARE
-#define COS15 (0.25f*SQ2*(SQ3+1))
-#define SIN15 (0.25f*SQ2*(SQ3-1))
-
-int basic[] = { 12, 2 };
-
-float axis[][3] = { {     0, 1,     0 } ,
-                    { COS15, 0, SIN15 } };
-#endif
-
-int inserted=0;
-
-///////////////////////////////////////////////////////////////////
-// q1*q2
-
-void multiply_quats( float* q1, float* q2, float* output)
-  {
-  output[0] = q2[3]*q1[0] - q2[2]*q1[1] + q2[1]*q1[2] + q2[0]*q1[3];
-  output[1] = q2[3]*q1[1] + q2[2]*q1[0] + q2[1]*q1[3] - q2[0]*q1[2];
-  output[2] = q2[3]*q1[2] + q2[2]*q1[3] - q2[1]*q1[0] + q2[0]*q1[1];
-  output[3] = q2[3]*q1[3] - q2[2]*q1[2] - q2[1]*q1[1] - q2[0]*q1[0];
-  }
-
-///////////////////////////////////////////////////////////////////
-// sin(A/2)*x, sin(A/2)*y, sin(A/2)*z, cos(A/2)
-
-void create_quat(float* axis, float angle, float* output)
-  {
-  float cosAngle = cos(angle/2);
-  float sinAngle = sin(angle/2);
-
-  output[0] = sinAngle*axis[0];
-  output[1] = sinAngle*axis[1];
-  output[2] = sinAngle*axis[2];
-  output[3] = cosAngle;
-  }
-
-///////////////////////////////////////////////////////////////////
-// double cover, so q == -q
-
-int is_the_same(float* q1, float* q2)
-  {
-  const float MAX = 0.01f;
-
-  float d0 = q1[0]-q2[0];
-  float d1 = q1[1]-q2[1];
-  float d2 = q1[2]-q2[2];
-  float d3 = q1[3]-q2[3];
-
-  if( d0<MAX && d0>-MAX &&
-      d1<MAX && d1>-MAX &&
-      d2<MAX && d2>-MAX &&
-      d3<MAX && d3>-MAX  ) return 1;
-
-  d0 = q1[0]+q2[0];
-  d1 = q1[1]+q2[1];
-  d2 = q1[2]+q2[2];
-  d3 = q1[3]+q2[3];
-
-  if( d0<MAX && d0>-MAX &&
-      d1<MAX && d1>-MAX &&
-      d2<MAX && d2>-MAX &&
-      d3<MAX && d3>-MAX  ) return 1;
-
-  return 0;
-  }
-
-///////////////////////////////////////////////////////////////////
-
-int getIndexInTable(float* quat, float* table)
-  {
-  for(int i=0; i<inserted; i++)
-    {
-    if( is_the_same(quat,table+4*i)==1 ) return i;
-    }
-
-  return -1;
-  }
-
-///////////////////////////////////////////////////////////////////
-
-void insert(float* quat, float* table)
-  {
-  if( getIndexInTable(quat,table)<0 )
-    {
-    if( inserted<NUM_QUATS )
-      {
-      table[4*inserted+0] = quat[0];
-      table[4*inserted+1] = quat[1];
-      table[4*inserted+2] = quat[2];
-      table[4*inserted+3] = quat[3];
-
-      inserted++;
-      }
-    else printf("Error: inserted=%d\n", inserted);
-    }
-  }
-
-///////////////////////////////////////////////////////////////////
-
-void normalize(int index)
-  {
-  float* a = axis[index];
-
-  float len = (float)(sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]));
-
-  a[0] /= len;  
-  a[1] /= len;  
-  a[2] /= len;  
-  }
-
-///////////////////////////////////////////////////////////////////
-
-int main(int argc, char** argv)
-  {
-  float tmp[4];
-  float table[4*NUM_QUATS];
-  int num,NUM_AXIS = sizeof(axis) / sizeof(axis[0]);
-
-  tmp[0] = 0.0f; tmp[1] = 0.0f; tmp[2] = 0.0f; tmp[3] = 1.0f;
-  insert(tmp,table);
-
-  for(int ax=0; ax<NUM_AXIS; ax++)
-    {
-    normalize(ax);
-    }
-
-  for( int ax=0; ax<NUM_AXIS; ax++)
-    for(int angle=1; angle<basic[ax]; angle++)
-      {
-      create_quat(axis[ax], 2*PI*angle/basic[ax], tmp);
-      insert(tmp,table); 
-      }
-
-  do
-    {
-    num = inserted;
-
-    for(int i=0; i<num; i++)
-      for(int j=0; j<num; j++)
-        {
-        multiply_quats( table+4*i, table+4*j, tmp);
-        insert(tmp,table);
-        }
-    }
-  while( num < inserted );
-
-  printf("\n");
-
-  for(int i=0; i<inserted; i++)
-    {
-    printf( "%2d %7.4f %7.4f %7.4f %7.4f\n", i, table[4*i], table[4*i+1], table[4*i+2], table[4*i+3] );
-    }
-
-  printf("\n");
-
-  for(int i=0; i<inserted; i++)
-    {
-    printf("{");
-
-    for(int j=0; j<inserted; j++)
-      {
-      multiply_quats( table+4*i, table+4*j, tmp);
-      num = getIndexInTable(tmp,table);
-      printf("%3d," , num);
-      }
-    printf("},\n");
-    }
- 
-return 0;
-}
diff --git a/src/main/res/raw/cube2.dmesh b/src/main/res/raw/cube2.dmesh
deleted file mode 100644
index fbebccf0..00000000
Binary files a/src/main/res/raw/cube2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/cube3.dmesh b/src/main/res/raw/cube3.dmesh
deleted file mode 100644
index ed588f7f..00000000
Binary files a/src/main/res/raw/cube3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/cube4.dmesh b/src/main/res/raw/cube4.dmesh
deleted file mode 100644
index 935b0f80..00000000
Binary files a/src/main/res/raw/cube4.dmesh and /dev/null differ
diff --git a/src/main/res/raw/cube5.dmesh b/src/main/res/raw/cube5.dmesh
deleted file mode 100644
index e8bb1492..00000000
Binary files a/src/main/res/raw/cube5.dmesh and /dev/null differ
diff --git a/src/main/res/raw/diam2.dmesh b/src/main/res/raw/diam2.dmesh
deleted file mode 100644
index 2ffc96ec..00000000
Binary files a/src/main/res/raw/diam2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/diam3.dmesh b/src/main/res/raw/diam3.dmesh
deleted file mode 100644
index 64a9247d..00000000
Binary files a/src/main/res/raw/diam3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/diam4.dmesh b/src/main/res/raw/diam4.dmesh
deleted file mode 100644
index ab6de2ee..00000000
Binary files a/src/main/res/raw/diam4.dmesh and /dev/null differ
diff --git a/src/main/res/raw/dino.dmesh b/src/main/res/raw/dino.dmesh
deleted file mode 100644
index 6a86ae85..00000000
Binary files a/src/main/res/raw/dino.dmesh and /dev/null differ
diff --git a/src/main/res/raw/heli.dmesh b/src/main/res/raw/heli.dmesh
deleted file mode 100644
index f50e871f..00000000
Binary files a/src/main/res/raw/heli.dmesh and /dev/null differ
diff --git a/src/main/res/raw/ivy.dmesh b/src/main/res/raw/ivy.dmesh
deleted file mode 100644
index 831b7d3c..00000000
Binary files a/src/main/res/raw/ivy.dmesh and /dev/null differ
diff --git a/src/main/res/raw/jing.dmesh b/src/main/res/raw/jing.dmesh
deleted file mode 100644
index 566c9492..00000000
Binary files a/src/main/res/raw/jing.dmesh and /dev/null differ
diff --git a/src/main/res/raw/kilo3.dmesh b/src/main/res/raw/kilo3.dmesh
deleted file mode 100644
index 89c96732..00000000
Binary files a/src/main/res/raw/kilo3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/kilo5.dmesh b/src/main/res/raw/kilo5.dmesh
deleted file mode 100644
index f936b1e3..00000000
Binary files a/src/main/res/raw/kilo5.dmesh and /dev/null differ
diff --git a/src/main/res/raw/mega3.dmesh b/src/main/res/raw/mega3.dmesh
deleted file mode 100644
index e50f88c7..00000000
Binary files a/src/main/res/raw/mega3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/mega5.dmesh b/src/main/res/raw/mega5.dmesh
deleted file mode 100644
index f346507f..00000000
Binary files a/src/main/res/raw/mega5.dmesh and /dev/null differ
diff --git a/src/main/res/raw/mirr2.dmesh b/src/main/res/raw/mirr2.dmesh
deleted file mode 100644
index 152caec7..00000000
Binary files a/src/main/res/raw/mirr2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/mirr3.dmesh b/src/main/res/raw/mirr3.dmesh
deleted file mode 100644
index a1c12104..00000000
Binary files a/src/main/res/raw/mirr3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/pyra3.dmesh b/src/main/res/raw/pyra3.dmesh
deleted file mode 100644
index e536f7d2..00000000
Binary files a/src/main/res/raw/pyra3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/pyra4.dmesh b/src/main/res/raw/pyra4.dmesh
deleted file mode 100644
index d2179266..00000000
Binary files a/src/main/res/raw/pyra4.dmesh and /dev/null differ
diff --git a/src/main/res/raw/pyra5.dmesh b/src/main/res/raw/pyra5.dmesh
deleted file mode 100644
index b1b43016..00000000
Binary files a/src/main/res/raw/pyra5.dmesh and /dev/null differ
diff --git a/src/main/res/raw/redi.dmesh b/src/main/res/raw/redi.dmesh
deleted file mode 100644
index 4d30d35e..00000000
Binary files a/src/main/res/raw/redi.dmesh and /dev/null differ
diff --git a/src/main/res/raw/rex.dmesh b/src/main/res/raw/rex.dmesh
deleted file mode 100644
index ac0dfe9e..00000000
Binary files a/src/main/res/raw/rex.dmesh and /dev/null differ
diff --git a/src/main/res/raw/skew2.dmesh b/src/main/res/raw/skew2.dmesh
deleted file mode 100644
index 637dbc83..00000000
Binary files a/src/main/res/raw/skew2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/skew3.dmesh b/src/main/res/raw/skew3.dmesh
deleted file mode 100644
index deae07bf..00000000
Binary files a/src/main/res/raw/skew3.dmesh and /dev/null differ
diff --git a/src/main/res/raw/squa1.dmesh b/src/main/res/raw/squa1.dmesh
deleted file mode 100644
index 239497d6..00000000
Binary files a/src/main/res/raw/squa1.dmesh and /dev/null differ
diff --git a/src/main/res/raw/squa2.dmesh b/src/main/res/raw/squa2.dmesh
deleted file mode 100644
index 56ff0c85..00000000
Binary files a/src/main/res/raw/squa2.dmesh and /dev/null differ
diff --git a/src/main/res/raw/ulti.dmesh b/src/main/res/raw/ulti.dmesh
deleted file mode 100644
index 27bfde0c..00000000
Binary files a/src/main/res/raw/ulti.dmesh and /dev/null differ
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index d61b6007..d977a0d8 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -74,72 +74,4 @@
     <string name="mo_placeholder">%1$d/%2$d</string>
     <string name="sq_placeholder" translatable="false">%1$2d.</string>
 
-    <string name="cube2" translatable="false">Pocket Cube</string>
-    <string name="cube3" translatable="false">Rubik Cube</string>
-    <string name="cube4" translatable="false">Rubik\'s Revenge</string>
-    <string name="cube5" translatable="false">Professor\'s Cube</string>
-    <string name="pyra3" translatable="false">Pyraminx</string>
-    <string name="pyra4" translatable="false">Master Pyraminx</string>
-    <string name="pyra5" translatable="false">Professor\'s Pyraminx</string>
-    <string name="skew2" translatable="false">Skewb</string>
-    <string name="skew3" translatable="false">Master Skewb</string>
-    <string name="diam2" translatable="false">Skewb Diamond</string>
-    <string name="diam3" translatable="false">Face Turning Octahedron</string>
-    <string name="diam4" translatable="false">Master Face Turning Octahedron</string>
-    <string name="redi2" translatable="false">Redi Cube</string>
-    <string name="heli3" translatable="false">Helicopter Cube</string>
-    <string name="ivy2"  translatable="false">Ivy Cube</string>
-    <string name="rex3"  translatable="false">Rex Cube</string>
-    <string name="dino3" translatable="false">Dino Cube (6 color)</string>
-    <string name="din43" translatable="false">Dino Cube (4 color)</string>
-    <string name="minx2" translatable="false">Kilominx</string>
-    <string name="minx3" translatable="false">Megaminx</string>
-    <string name="minx4" translatable="false">Master Kilominx</string>
-    <string name="minx5" translatable="false">Gigaminx</string>
-    <string name="ulti2" translatable="false">Skewb Ultimate</string>
-    <string name="squa1" translatable="false">Square-1</string>
-    <string name="squa2" translatable="false">Square-2</string>
-    <string name="jing"  translatable="false">Jing Pyraminx</string>
-    <string name="mirr2"  translatable="false">Mirror Cube</string>
-    <string name="mirr3"  translatable="false">Pocket Mirror</string>
-
-    <string name="bandaged_fused"  translatable="false">Fused Cube</string>
-    <string name="bandaged_2bar"   translatable="false">2Bar Cube</string>
-    <string name="bandaged_3plate" translatable="false">3Plate Cube</string>
-    <string name="bandaged_evil"   translatable="false">Evil Cube</string>
-
-    <string name="cube2_inventor" translatable="false">Larry Nichols, 1970</string>
-    <string name="cube3_inventor" translatable="false">Ernő Rubik, 1974</string>
-    <string name="cube4_inventor" translatable="false">Péter Sebestény, 1981</string>
-    <string name="cube5_inventor" translatable="false">Udo Krell, 1981</string>
-    <string name="pyra3_inventor" translatable="false">Uwe Meffert, 1970</string>
-    <string name="pyra4_inventor" translatable="false">Katsuhiko Okamoto, 2002</string>
-    <string name="pyra5_inventor" translatable="false">Timur Evbatyrov, 2011</string>
-    <string name="skew2_inventor" translatable="false">Tony Durham, 1982</string>
-    <string name="skew3_inventor" translatable="false">Katsuhiko Okamoto, 2003</string>
-    <string name="diam2_inventor" translatable="false">Uwe Meffert, 1984</string>
-    <string name="diam3_inventor" translatable="false">David Pitcher, 2003</string>
-    <string name="diam4_inventor" translatable="false">Timur Evbatyrov, 2011</string>
-    <string name="redi2_inventor" translatable="false">Oskar van Deventer, 2009</string>
-    <string name="heli3_inventor" translatable="false">Adam G. Cowan, 2006</string>
-    <string name="ivy2_inventor"  translatable="false">Eitan Cher, 2009</string>
-    <string name="rex3_inventor"  translatable="false">Andrew Cormier, 2009</string>
-    <string name="dino3_inventor" translatable="false">Robert Webb, 1985</string>
-    <string name="din43_inventor" translatable="false">Robert Webb, 1985</string>
-    <string name="minx2_inventor" translatable="false">Thomas de Bruin, 2008</string>
-    <string name="minx3_inventor" translatable="false">Ferenc Szlivka, 1982</string>
-    <string name="minx4_inventor" translatable="false">David Gugl, 2010</string>
-    <string name="minx5_inventor" translatable="false">Tyler Fox, 2006</string>
-    <string name="ulti2_inventor" translatable="false">Tony Fisher, 2000</string>
-    <string name="squa1_inventor" translatable="false">Vojtech Kopsky, Harel Hrsel, 1999</string>
-    <string name="squa2_inventor" translatable="false">David Litwin, 1995</string>
-    <string name="jing_inventor"  translatable="false">Tony Fisher, 1991</string>
-    <string name="mirr2_inventor" translatable="false">Thomas de Bruin, 2007</string>
-    <string name="mirr3_inventor" translatable="false">Hidetoshi Takeji, 2006</string>
-
-    <string name="bandaged_fused_inventor"  translatable="false">who knows</string>
-    <string name="bandaged_2bar_inventor"   translatable="false">who knows</string>
-    <string name="bandaged_3plate_inventor" translatable="false">who knows</string>
-    <string name="bandaged_evil_inventor"   translatable="false">who knows</string>
-
 </resources>
