commit 221a409016f435bb9c8b69e14cb3457e3c40e358
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Mar 17 14:31:24 2021 +0100

    Simplification with objects.

diff --git a/build.gradle b/build.gradle
index b66719b7..d7717eb8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,7 +36,7 @@ android {
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'com.google.firebase:firebase-analytics:18.0.2'
-    implementation 'com.google.firebase:firebase-crashlytics:17.3.1'
+    implementation 'com.google.firebase:firebase-crashlytics:17.4.0'
     implementation 'com.google.android.play:core:1.10.0'
 
     api project(':distorted-library')
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
index 136fd2dc..b17bc82b 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
@@ -30,7 +30,6 @@ import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshSquare;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
-import org.distorted.main.RubikSurfaceView;
 
 import java.util.Random;
 
@@ -389,6 +388,7 @@ android.util.Log.e("DISTORTED", "posIndex="+posIndex+" dimIndex="+dimIndex);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO
 
   public boolean isSolved()
     {
@@ -402,65 +402,6 @@ android.util.Log.e("DISTORTED", "posIndex="+posIndex+" dimIndex="+dimIndex);
     return true;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
-// then if it were rotated by quaternion 'quat'.
-// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
-// middle squares get interchanged. No visible difference!
-//
-// So: this is true iff the cubit
-// a) is a corner or edge and the quaternions are the same
-// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
-
-  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
-    {
-    if ( cubit.mQuatIndex == quatIndex ) return true;
-
-    int belongsToHowManyFaces = 0;
-    int lastLayer = getNumLayers()-1;
-    float row;
-    final float MAX_ERROR = 0.01f;
-
-    for(int i=0; i<NUM_AXIS; i++)
-      {
-      row = cubit.mRotationRow[i];
-      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
-          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
-      }
-
-    switch(belongsToHowManyFaces)
-      {
-      case 0 : return true ;  // 'inside' cubit that does not lie on any face
-      case 1 :                // cubit that lies inside one of the faces
-               Static3D orig = cubit.getOrigPosition();
-               Static4D quat1 = QUATS[quatIndex];
-               Static4D quat2 = QUATS[cubit.mQuatIndex];
-
-               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
-               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
-               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
-
-               float row1, row2;
-               float x1 = rotated1.get0();
-               float y1 = rotated1.get1();
-               float z1 = rotated1.get2();
-               float x2 = rotated2.get0();
-               float y2 = rotated2.get1();
-               float z2 = rotated2.get2();
-
-               for(int i=0; i<NUM_AXIS; i++)
-                 {
-                 row1 = computeRow(x1,y1,z1,i);
-                 row2 = computeRow(x2,y2,z2,i);
-
-                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
-                 }
-               return false;
-
-      default: return false;  // edge or corner
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // only needed for solvers - there are no Bandaged solvers ATM)
 
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
index b9deef7e..e1cbefcb 100644
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ b/src/main/java/org/distorted/objects/TwistyCube.java
@@ -216,8 +216,7 @@ class TwistyCube extends TwistyObject
 
   int getFaceColor(int cubit, int cubitface, int size)
     {
-    float diff = CUBITS[cubit].mRotationRow[cubitface/2] - (cubitface%2==0 ? size-1:0);
-    return diff*diff < 0.0001f ? cubitface : NUM_FACES;
+    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? size-1:0) ? cubitface : NUM_FACES;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -301,65 +300,6 @@ class TwistyCube extends TwistyObject
     return true;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
-// then if it were rotated by quaternion 'quat'.
-// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
-// middle squares get interchanged. No visible difference!
-//
-// So: this is true iff the cubit
-// a) is a corner or edge and the quaternions are the same
-// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
-
-  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
-    {
-    if ( cubit.mQuatIndex == quatIndex ) return true;
-
-    int belongsToHowManyFaces = 0;
-    int lastLayer = getNumLayers()-1;
-    float row;
-    final float MAX_ERROR = 0.01f;
-
-    for(int i=0; i<NUM_AXIS; i++)
-      {
-      row = cubit.mRotationRow[i];
-      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
-          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
-      }
-
-    switch(belongsToHowManyFaces)
-      {
-      case 0 : return true ;  // 'inside' cubit that does not lie on any face
-      case 1 :                // cubit that lies inside one of the faces
-               Static3D orig = cubit.getOrigPosition();
-               Static4D quat1 = QUATS[quatIndex];
-               Static4D quat2 = QUATS[cubit.mQuatIndex];
-
-               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
-               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
-               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
-
-               float row1, row2;
-               float x1 = rotated1.get0();
-               float y1 = rotated1.get1();
-               float z1 = rotated1.get2();
-               float x2 = rotated2.get0();
-               float y2 = rotated2.get1();
-               float z2 = rotated2.get2();
-
-               for(int i=0; i<NUM_AXIS; i++)
-                 {
-                 row1 = computeRow(x1,y1,z1,i);
-                 row2 = computeRow(x2,y2,z2,i);
-
-                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
-                 }
-               return false;
-
-      default: return false;  // edge or corner
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // order: Up --> Right --> Front --> Down --> Left --> Back
 // (because the first implemented Solver - the two-phase Cube3 one - expects such order)
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index 969a9fea..c664ca51 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -582,65 +582,6 @@ public class TwistyMegaminx extends TwistyMinx
     return true;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
-// then if it were rotated by quaternion 'quat'.
-// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
-// middle squares get interchanged. No visible difference!
-//
-// So: this is true iff the cubit
-// a) is a corner or edge and the quaternions are the same
-// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
-
-  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
-    {
-    if ( cubit.mQuatIndex == quatIndex ) return true;
-
-    int belongsToHowManyFaces = 0;
-    int lastLayer = getNumLayers()-1;
-    float row;
-    final float MAX_ERROR = 0.01f;
-
-    for(int i=0; i<NUM_AXIS; i++)
-      {
-      row = cubit.mRotationRow[i];
-      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
-          (row-lastLayer<MAX_ERROR && row-lastLayer>-MAX_ERROR)  ) belongsToHowManyFaces++;
-      }
-
-    switch(belongsToHowManyFaces)
-      {
-      case 0 : return true ;  // 'inside' cubit that does not lie on any face
-      case 1 :                // cubit that lies inside one of the faces
-               Static3D orig = cubit.getOrigPosition();
-               Static4D quat1 = QUATS[quatIndex];
-               Static4D quat2 = QUATS[cubit.mQuatIndex];
-
-               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
-               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
-               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
-
-               float row1, row2;
-               float x1 = rotated1.get0();
-               float y1 = rotated1.get1();
-               float z1 = rotated1.get2();
-               float x2 = rotated2.get0();
-               float y2 = rotated2.get1();
-               float z2 = rotated2.get2();
-
-               for(int i=0; i<NUM_AXIS; i++)
-                 {
-                 row1 = computeRow(x1,y1,z1,i);
-                 row2 = computeRow(x2,y2,z2,i);
-
-                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
-                 }
-               return false;
-
-      default: return false;  // edge or corner
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getObjectName(int numLayers)
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index 95630bb7..e422fae4 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -47,6 +47,7 @@ import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 import org.distorted.main.BuildConfig;
+import org.distorted.main.RubikSurfaceView;
 
 import java.io.DataInputStream;
 import java.io.IOException;
@@ -306,8 +307,7 @@ public abstract class TwistyObject extends DistortedNode
 
   private boolean belongsToRotation( int cubit, int axis, int rowBitmap)
     {
-    int cubitRow = (int)(CUBITS[cubit].mRotationRow[axis]+0.5f);
-    return ((1<<cubitRow)&rowBitmap)!=0;
+    return ((1<<CUBITS[cubit].mRotationRow[axis]) & rowBitmap) != 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -396,6 +396,63 @@ public abstract class TwistyObject extends DistortedNode
     pos.set( mOrigPos[minErrorIndex] );
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
+// then if it were rotated by quaternion 'quat'.
+// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
+// middle squares get interchanged. No visible difference!
+//
+// So: this is true iff the cubit
+// a) is a corner or edge and the quaternions are the same
+// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
+
+  boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
+    {
+    if ( cubit.mQuatIndex == quatIndex ) return true;
+
+    int belongsToHowManyFaces = 0;
+    int lastLayer = getNumLayers()-1;
+    int row;
+
+    for(int i=0; i<NUM_AXIS; i++)
+      {
+      row = cubit.mRotationRow[i];
+      if( row==0 || row==lastLayer ) belongsToHowManyFaces++;
+      }
+
+    switch(belongsToHowManyFaces)
+      {
+      case 0 : return true ;  // 'inside' cubit that does not lie on any face
+      case 1 :                // cubit that lies inside one of the faces
+               Static3D orig = cubit.getOrigPosition();
+               Static4D quat1 = QUATS[quatIndex];
+               Static4D quat2 = QUATS[cubit.mQuatIndex];
+
+               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
+               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
+               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
+
+               float row1, row2;
+               float x1 = rotated1.get0();
+               float y1 = rotated1.get1();
+               float z1 = rotated1.get2();
+               float x2 = rotated2.get0();
+               float y2 = rotated2.get1();
+               float z2 = rotated2.get2();
+
+               for(int i=0; i<NUM_AXIS; i++)
+                 {
+                 row1 = computeRow(x1,y1,z1,i);
+                 row2 = computeRow(x2,y2,z2,i);
+
+                 if( (row1==0 && row2==0) || (row1==lastLayer && row2==lastLayer) ) return true;
+                 }
+               return false;
+
+      default: return false;  // edge or corner
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // the getFaceColors + final black in a grid (so that we do not exceed the maximum texture size)
 
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index 818a463a..0c50b103 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -193,8 +193,7 @@ public class TwistyPyraminx extends TwistyObject
 
   private int faceColor(int cubit, int axis)
     {
-    float row = CUBITS[cubit].mRotationRow[axis];
-    return row*row < 0.1f ? axis : NUM_FACES;
+    return CUBITS[cubit].mRotationRow[axis] == 0 ? axis : NUM_FACES;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -333,66 +332,7 @@ public class TwistyPyraminx extends TwistyObject
     return true;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// return if the Cubit, when rotated with its own mQuatScramble, would have looked any different
-// then if it were rotated by quaternion 'quat'.
-// No it is not so simple as the quats need to be the same - imagine a 4x4x4 cube where the two
-// middle squares get interchanged. No visible difference!
-//
-// So: this is true iff the cubit
-// a) is a corner or edge and the quaternions are the same
-// b) is inside one of the faces and after rotations by both quats it ends up on the same face.
-
-  private boolean thereIsNoVisibleDifference(Cubit cubit, int quatIndex)
-    {
-    if ( cubit.mQuatIndex == quatIndex ) return true;
-
-    int belongsToHowManyFaces = 0;
-    int numLayers = getNumLayers()-1;
-    float row;
-    final float MAX_ERROR = 0.01f;
-
-    for(int i=0; i<NUM_AXIS; i++)
-      {
-      row = cubit.mRotationRow[i];
-      if( (row          <MAX_ERROR && row          >-MAX_ERROR) ||
-          (row-numLayers<MAX_ERROR && row-numLayers>-MAX_ERROR)  ) belongsToHowManyFaces++;
-      }
-
-    switch(belongsToHowManyFaces)
-      {
-      case 0 : return true ;  // 'inside' cubit that does not lie on any face
-      case 1 :                // cubit that lies inside one of the faces
-               Static3D orig = cubit.getOrigPosition();
-               Static4D quat1 = QUATS[quatIndex];
-               Static4D quat2 = QUATS[cubit.mQuatIndex];
-
-               Static4D cubitCenter = new Static4D( orig.get0(), orig.get1(), orig.get2(), 0);
-               Static4D rotated1 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat1 );
-               Static4D rotated2 = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat2 );
-
-               float row1, row2;
-               float x1 = rotated1.get0();
-               float y1 = rotated1.get1();
-               float z1 = rotated1.get2();
-               float x2 = rotated2.get0();
-               float y2 = rotated2.get1();
-               float z2 = rotated2.get2();
-
-               for(int i=0; i<NUM_AXIS; i++)
-                 {
-                 row1 = computeRow(x1,y1,z1,i);
-                 row2 = computeRow(x2,y2,z2,i);
-
-                 if( (row1==0 && row2==0) || (row1==numLayers && row2==numLayers) ) return true;
-                 }
-               return false;
-
-      default: return false;  // edge or corner
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
 // only needed for solvers - there are no Pyraminx solvers ATM)
 
   public String retObjectString()
