commit 680f921e1e70000159323158d2042e43e335baa2
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Mar 29 01:03:39 2021 +0200

    Progress making the Diamond class support any size.

diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index 5ada7ff3..1edf9dee 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -78,28 +78,8 @@ public class TwistyDiamond extends TwistyObject
 
   private static final float DIST = 0.50f;
 
-  // centers of the 6 octahedrons + 8 tetrahedrons ( i.e. of the all 14 cubits)
-  private static final float[][] CENTERS = new float[][]
-         {
-             { DIST,          0, DIST },
-             { DIST,          0,-DIST },
-             {-DIST,          0,-DIST },
-             {-DIST,          0, DIST },
-             {    0, DIST*SQ2  ,    0 },
-             {    0,-DIST*SQ2  ,    0 },
-
-             {    0, DIST*SQ2/2, DIST },
-             { DIST, DIST*SQ2/2,    0 },
-             {    0, DIST*SQ2/2,-DIST },
-             {-DIST, DIST*SQ2/2,    0 },
-             {    0,-DIST*SQ2/2, DIST },
-             { DIST,-DIST*SQ2/2,    0 },
-             {    0,-DIST*SQ2/2,-DIST },
-             {-DIST,-DIST*SQ2/2,    0 }
-         };
-
   // Colors of the faces of cubits. Each cubit has 8 faces
-  private static final int[][] mFaceMap = new int[][]
+  private static final int[][] mOctaFaceMap = new int[][]
          {
            { 6,1,8,8, 2,5,8,8 },
            { 8,1,3,8, 8,5,7,8 },
@@ -107,17 +87,10 @@ public class TwistyDiamond extends TwistyObject
            { 6,8,8,4, 2,8,8,0 },
            { 6,1,3,4, 8,8,8,8 },
            { 8,8,8,8, 2,5,7,0 },
-
-           { 6,8,8,8, 8,8,8,8 },
-           { 1,8,8,8, 8,8,8,8 },
-           { 3,8,8,8, 8,8,8,8 },
-           { 4,8,8,8, 8,8,8,8 },
-           { 2,8,8,8, 8,8,8,8 },
-           { 5,8,8,8, 8,8,8,8 },
-           { 7,8,8,8, 8,8,8,8 },
-           { 0,8,8,8, 8,8,8,8 }
          };
 
+  private static final int[] mTetraFaceMap = new int[] { 1, 3, 4, 6, 5, 7, 0, 2 };
+
   private static MeshBase mOctaMesh, mTetraMesh;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -165,11 +138,26 @@ public class TwistyDiamond extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  float[] getCuts(int size)
+  float[] getCuts(int numLayers)
     {
-    float[] cuts = new float[1];
-    cuts[0] = 0.0f;
-    return cuts;
+    if( numLayers<2 )
+      {
+      return null;
+      }
+    else
+      {
+      float[] cuts = new float[numLayers-1];
+      float dist = SQ6*0.666f;
+      float cut  = 0.5f*dist*(2-numLayers);
+
+      for(int i=0; i<numLayers-1; i++)
+        {
+        cuts[i] = cut;
+        cut += dist;
+        }
+
+      return cuts;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -181,31 +169,178 @@ public class TwistyDiamond extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  float[][] getCubitPositions(int size)
+  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 createOctahedrons(float[][] centers, int index, int layers, float height)
+    {
+    float x = DIST*(layers-1);
+    float z = DIST*(layers+1);
+
+    for(int i=0; i<layers; i++, index++)
+      {
+      z -= 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      x -= 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      z += 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    for(int i=0; i<layers-2; i++, index++)
+      {
+      x += 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    return index;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int createTetrahedrons(float[][] centers, int index, int layers, float height)
     {
+    float x = DIST*(layers-1);
+    float z = DIST*layers;
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      z -= 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    x += DIST;
+    z -= DIST;
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      x -= 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    x -= DIST;
+    z -= DIST;
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      z += 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    x -= DIST;
+    z += DIST;
+
+    for(int i=0; i<layers-1; i++, index++)
+      {
+      x += 2*DIST;
+      centers[index][0] = x;
+      centers[index][1] = height;
+      centers[index][2] = z;
+      }
+
+    return index;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  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 = createOctahedrons(CENTERS,index,layers,height);
+
+    for(int i=layers-1; i>0; i--)
+      {
+      height += SQ2*DIST;
+      index = createOctahedrons(CENTERS,index,i,+height);
+      index = createOctahedrons(CENTERS,index,i,-height);
+      }
+
+    height = DIST*SQ2/2;
+
+    for(int i=layers; i>1; i--)
+      {
+      index = createTetrahedrons(CENTERS,index,i,+height);
+      index = createTetrahedrons(CENTERS,index,i,-height);
+      height += SQ2*DIST;
+      }
+
     return CENTERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO:
 
-  private Static4D getQuat(int cubit)
+  private int retFaceTetraBelongsTo(int tetra, int numLayers)
     {
-    switch(cubit)
+    switch(tetra)
       {
-      case  0:
-      case  1:
-      case  2:
-      case  3:
-      case  4:
-      case  5:
-      case  6: return QUATS[0];                          // unit quat
-      case  7: return new Static4D(0,-SQ2/2,0,SQ2/2);    //  90 along Y
-      case  8: return QUATS[1];                          // 180 along Y
-      case  9: return new Static4D(0,+SQ2/2,0,SQ2/2);    //  90 along Y
-      case 10: return new Static4D(0,     0,1,    0);    // 180 along Z
-      case 11: return new Static4D(SQ2/2, 0,SQ2/2,0);    //
-      case 12: return new Static4D(     1,0,0,    0);    // 180 along X
-      case 13: return new Static4D(-SQ2/2,0,SQ2/2,0);    //
+      case 0 : return 0;
+      case 1 : return 1;
+      case 2 : return 2;
+      case 3 : return 3;
+      case 4 : return 4;
+      case 5 : return 5;
+      case 6 : return 6;
+      case 7 : return 7;
+      default: return 8;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private Static4D getQuat(int cubit, int numLayers, int numO)
+    {
+    if( cubit<numO ) return QUATS[0];
+
+    switch( retFaceTetraBelongsTo(cubit-numO, numLayers) )
+      {
+      case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    //  90 along Y
+      case 1: return QUATS[1];                          // 180 along Y
+      case 2: return new Static4D(0,+SQ2/2,0,SQ2/2);    //  90 along Y
+      case 3: return QUATS[0];                          // unit quat
+      case 4: return new Static4D(SQ2/2, 0,SQ2/2,0);    //
+      case 5: return new Static4D(     1,0,0,    0);    // 180 along X
+      case 6: return new Static4D(-SQ2/2,0,SQ2/2,0);    //
+      case 7: return new Static4D(0,     0,1,    0);    // 180 along Z
       }
 
     return null;
@@ -216,8 +351,9 @@ public class TwistyDiamond extends TwistyObject
   MeshBase createCubitMesh(int cubit, int numLayers)
     {
     MeshBase mesh;
+    int numO = getNumOctahedrons(numLayers);
 
-    if( cubit<6 )
+    if( cubit<numO )
       {
       if( mOctaMesh==null ) mOctaMesh = FactoryCubit.getInstance().createOctaMesh();
       mesh = mOctaMesh.copy(true);
@@ -228,17 +364,28 @@ public class TwistyDiamond extends TwistyObject
       mesh = mTetraMesh.copy(true);
       }
 
-    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
+    Static4D sQ = getQuat(cubit,numLayers,numO);
+    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( sQ, new Static3D(0,0,0) );
     mesh.apply(quat,0xffffffff,0);
 
     return mesh;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// TODO
 
-  int getFaceColor(int cubit, int cubitface, int size)
+  int getFaceColor(int cubit, int cubitface, int numLayers)
     {
-    return mFaceMap[cubit][cubitface];
+    int numO = getNumOctahedrons(numLayers);
+
+    if( cubit<numO )
+      {
+      return mOctaFaceMap[cubit][cubitface];
+      }
+    else
+      {
+      return cubitface>0 ? 8 : mTetraFaceMap[retFaceTetraBelongsTo(cubit-numO, numLayers)];
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -266,10 +413,9 @@ public class TwistyDiamond extends TwistyObject
 
   float[] getRowChances(int numLayers)
     {
-    float[] chances = new float[2];
+    float[] chances = new float[numLayers];
 
-    chances[0] = 0.5f;
-    chances[1] = 1.0f;
+    for(int i=0; i<numLayers; i++) chances[i] = ((float)(i+1))/numLayers;
 
     return chances;
     }
@@ -373,6 +519,7 @@ public class TwistyDiamond extends TwistyObject
 // 2) cubits 7,13: can also be QUAT 4,8
 // 3) cubits 8,10: can also be QUAT 7,11
 // 4) cubits 9,11: can also be QUAT 5,9
+// TODO
 
   public boolean isSolved()
     {
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index 9393f43f..fd9fd0f7 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -80,7 +80,7 @@ public abstract class TwistyObject extends DistortedNode
   private static final float MAX_SIZE_CHANGE = 1.35f;
   private static final float MIN_SIZE_CHANGE = 0.75f;
 
-  private static final boolean mCreateFromDMesh = true;
+  private static final boolean mCreateFromDMesh = false;
 
   private static final Static3D CENTER = new Static3D(0,0,0);
   private static final int POST_ROTATION_MILLISEC = 500;
