commit fdccfe1e72763292b8821eb461e239ac8d6c3077
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Nov 2 13:26:33 2021 +0100

    Introduce the third type of a cuboid's cubit: the edge.
    Makes the meshes much smaller!

diff --git a/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java b/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
index e0f21cde..e3b4290f 100644
--- a/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
+++ b/src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
@@ -180,24 +180,24 @@ public class TwistyCuboid extends Twisty6
          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),  // 4
          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),  // 10
          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),  // 16
          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),  // 20
          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)
@@ -258,7 +258,20 @@ public class TwistyCuboid extends Twisty6
     if( variant==0 )
       {
       float[][] bands   = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
-      int[] bandIndices = new int[] { 0,0,0,0,0,0};
+      int[] bandIndices = new int[] {0,0,0,0,0,0};
+      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
+      }
+    else if( variant==1 )
+      {
+      int extraI2 = numL<=3 ? num-2 : 0;
+
+      float[][] bands   = new float[][]
+        {
+          {height,35,0.5f,0.7f,num,extraI,extraV},
+          {height,35,0.5f,0.7f,  2,extraI2,    0},
+        };
+
+      int[] bandIndices = new int[] {1,1,1,0,1,0};
       return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
       }
     else
@@ -271,16 +284,58 @@ public class TwistyCuboid extends Twisty6
           {height,35,0.5f,0.7f,  2,extraI2,     0},
           {height,35,0.5f,0.7f,  2,      0,     0},
         };
-      int[] bandIndices = new int[] { 1,1,1,1,0,2};
+      int[] bandIndices = new int[] {1,1,1,1,0,2};
       return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getEdgeNum(int cubit, int[] numLayers)
+    {
+    int x = numLayers[0];
+    int y = numLayers[1];
+    int z = numLayers[2];
+
+    if(x==1 || y==1 || z==1 ) return 0;
+
+    int numCorners = getNumCorners(numLayers);
+    int numEdges   = getNumEdges(numLayers);
+    int num = cubit - numCorners;
+
+    if( num>=0 && num<numEdges )
+      {
+      int numLR = (x-2);
+      if( num<  numLR ) return 0;
+      if( num<2*numLR ) return 1;
+      if( num<3*numLR ) return 2;
+      if( num<4*numLR ) return 3;
+      num -= 4*numLR;
+
+      int numTD = (y-2);
+      if( num<  numTD ) return 4;
+      if( num<2*numTD ) return 5;
+      if( num<3*numTD ) return 6;
+      if( num<4*numTD ) return 7;
+      num -= 4*numTD;
+
+      int numFB = (z-2);
+      if( num<  numFB ) return 8;
+      if( num<2*numFB ) return 9;
+      if( num<3*numFB ) return 10;
+      if( num<4*numFB ) return 11;
+      }
+
+    return -1;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private int getCenterNum(int cubit, int[] numLayers)
     {
-    int num = cubit - getNumCornersAndEdges(numLayers);
+    int numCorners = getNumCorners(numLayers);
+    int numEdges   = getNumEdges(numLayers);
+    int num = cubit - numCorners - numEdges;
 
     if( num>=0 )
       {
@@ -304,13 +359,24 @@ public class TwistyCuboid extends Twisty6
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int getNumCornersAndEdges(int[] numLayers)
+  private int getNumCorners(int[] numLayers)
     {
     int x = numLayers[0];
     int y = numLayers[1];
     int z = numLayers[2];
 
-    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) ) + 8;
+    return ( x==1 || y==1 || z==1 ) ? x*y*z : 8;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getNumEdges(int[] numLayers)
+    {
+    int x = numLayers[0];
+    int y = numLayers[1];
+    int z = numLayers[2];
+
+    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -409,32 +475,67 @@ public class TwistyCuboid extends Twisty6
     {
     if( mQuats ==null ) initializeQuats();
 
-    int centerNum = getCenterNum(cubit,numLayers);
+    int variant = getCubitVariant(cubit,numLayers);
 
-    switch(centerNum)
+    switch(variant)
       {
-      case 0 : return mQuats[13];
-      case 1 : return mQuats[12];
-      case 2 : return mQuats[ 8];
-      case 3 : return mQuats[ 9];
-      case 4 : return mQuats[ 0];
-      case 5 : return mQuats[ 1];
-      default: return mQuats[ 0];
+      case 0: return mQuats[0];
+      case 1: int edgeEdge   = getEdgeNum(cubit,numLayers);
+              switch(edgeEdge)
+                {
+                case  0: return mQuats[ 0];
+                case  1: return mQuats[ 8];
+                case  2: return mQuats[ 9];
+                case  3: return mQuats[ 1];
+                case  4: return mQuats[20];
+                case  5: return mQuats[ 4];
+                case  6: return mQuats[23];
+                case  7: return mQuats[ 5];
+                case  8: return mQuats[16];
+                case  9: return mQuats[ 6];
+                case 10: return mQuats[22];
+                case 11: return mQuats[ 7];
+                }
+              break;
+      case 2: int centerFace = getCenterNum(cubit,numLayers);
+              switch(centerFace)
+                {
+                case 0 : return mQuats[13];
+                case 1 : return mQuats[12];
+                case 2 : return mQuats[ 8];
+                case 3 : return mQuats[ 9];
+                case 4 : return mQuats[ 0];
+                case 5 : return mQuats[ 1];
+                }
       }
+
+    return mQuats[0];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getNumCubitVariants(int[] numLayers)
     {
-    return numLayers[0]>2 ? 2:1;
+    final int X = numLayers[0];
+    final int Y = numLayers[1];
+    final int Z = numLayers[2];
+
+    if( X==1 || Y==1 || Z==1 ) return 1;
+    if( X<=2 && Y<=2 && Z<=2 ) return 1;
+
+    return 3;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getCubitVariant(int cubit, int[] numLayers)
     {
-    return cubit < getNumCornersAndEdges(numLayers) ? 0 : 1;
+    int numCorners = getNumCorners(numLayers);
+    if( cubit < numCorners          ) return 0;
+    int numEdges = getNumEdges(numLayers);
+    if( cubit < numCorners+numEdges ) return 1;
+
+    return 2;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -448,17 +549,36 @@ public class TwistyCuboid extends Twisty6
 
   public int getCubitFaceColor(int cubit, int face, int[] numLayers)
     {
-    int centerNum = getCenterNum(cubit,numLayers);
+    int variant = getCubitVariant(cubit,numLayers);
 
-    if( centerNum<0 )
-      {
-      int axis = face/2;
-      return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
-      }
-    else
+    switch(variant)
       {
-      return face==4 ? centerNum : -1;
+      case 0: int axis = face/2;
+              return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
+      case 1: if( face!=3 && face !=5 ) return -1;
+              int edge = getEdgeNum(cubit,numLayers);
+
+              switch(edge)
+                {
+                case  0: return face==3 ? 3 : 5;
+                case  1: return face==3 ? 4 : 3;
+                case  2: return face==3 ? 5 : 2;
+                case  3: return face==3 ? 2 : 4;
+                case  4: return face==3 ? 5 : 1;
+                case  5: return face==3 ? 1 : 4;
+                case  6: return face==3 ? 5 : 0;
+                case  7: return face==3 ? 0 : 4;
+                case  8: return face==3 ? 1 : 3;
+                case  9: return face==3 ? 2 : 1;
+                case 10: return face==3 ? 0 : 3;
+                case 11: return face==3 ? 2 : 0;
+                default: return 0;
+                }
+
+      case 2: return face==4 ? getCenterNum(cubit,numLayers) : -1;
       }
+
+    return -1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
