commit e4bf4d02d64b74cb07005c8e157afeddce774b60
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Jan 27 11:26:24 2021 +0100

    Progress with Megaminx.

diff --git a/src/main/java/org/distorted/objects/FactoryCubit.java b/src/main/java/org/distorted/objects/FactoryCubit.java
index e6280ba0..1c92c642 100644
--- a/src/main/java/org/distorted/objects/FactoryCubit.java
+++ b/src/main/java/org/distorted/objects/FactoryCubit.java
@@ -776,15 +776,15 @@ class FactoryCubit
     float[] bands0 = computeBands(0.04f,34,  X1,0.2f,5);
     float[] bands1 = computeBands(0.00f,34,0.3f,0.2f,2);
 
-    meshes[0] = new MeshPolygon(vertices0, bands0, 1, 1);
+    meshes[0] = new MeshPolygon(vertices0, bands0, 0, 0);
     meshes[0].setEffectAssociation(0, 1,0);
     meshes[1] = meshes[0].copy(true);
     meshes[1].setEffectAssociation(0, 2,0);
-    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 4);
+    meshes[2] = new MeshPolygon(vertices1, bands1, 0, 0);
     meshes[2].setEffectAssociation(0, 4,0);
     meshes[3] = meshes[2].copy(true);
     meshes[3].setEffectAssociation(0, 8,0);
-    meshes[4] = new MeshPolygon(vertices2, bands1, 1, 4);
+    meshes[4] = new MeshPolygon(vertices2, bands1, 0, 0);
     meshes[4].setEffectAssociation(0,16,0);
     meshes[5] = meshes[4].copy(true);
     meshes[5].setEffectAssociation(0,32,0);
@@ -792,6 +792,31 @@ class FactoryCubit
     return new MeshJoined(meshes);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createFacesMegaminxCenter(float width)
+    {
+    MeshBase[] meshes = new MeshPolygon[2];
+
+    float R  = width/(2*COS54);
+
+    float X1 = width/2;
+    float Y1 = R*SIN54;
+    float X2 = R*COS18;
+    float Y2 = R*SIN18;
+
+    float[] vertices0 = { -X1,+Y1, -X2,-Y2, 0.0f,-R, +X2,-Y2, +X1,+Y1 };
+    float[] bands0 = computeBands(+0.04f,45, R/3,0.2f,4);
+    float[] bands1 = computeBands( 0.00f,34, R/3,0.2f,2);
+
+    meshes[0] = new MeshPolygon(vertices0, bands0, 0, 0);
+    meshes[0].setEffectAssociation(0,1,0);
+    meshes[1] = new MeshPolygon(vertices0, bands1, 0, 0);
+    meshes[1].setEffectAssociation(0,2,0);
+
+    return new MeshJoined(meshes);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // EFFECTS
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1451,6 +1476,21 @@ class FactoryCubit
     return effect;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsMegaminxCenter()
+    {
+    VertexEffect[] effect = new VertexEffect[1];
+
+    Static1D angle = new Static1D(DIHEDRAL2);
+    Static3D axisX = new Static3D( 1.0f, 0.0f, 0.0f);
+    Static3D center= new Static3D( 0, 0, 0);
+
+    effect[0] = new VertexEffectRotate(angle, axisX, center);
+
+    return effect;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // OBJECTS
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1875,6 +1915,23 @@ class FactoryCubit
 
     mesh.mergeEffComponents();
 
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createMegaminxCenterMesh(float width)
+    {
+    MeshBase mesh = createFacesMegaminxCenter(width);
+    VertexEffect[] effects = createVertexEffectsMegaminxCenter();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    mesh.mergeEffComponents();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+
     return mesh;
     }
   }
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index d5d98ab3..71c09a24 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -40,7 +40,7 @@ import static org.distorted.objects.FactoryCubit.SIN18;
 
 public class TwistyMegaminx extends TwistyMinx
 {
-  static final float MEGA_D = 0.05f;
+  static final float MEGA_D = 0.04f;
 
   private static final int NUM_CORNERS = 20;
   private static final int NUM_CENTERS = 12;
@@ -102,6 +102,19 @@ public class TwistyMegaminx extends TwistyMinx
            {  3, 15,  3,  5},
          };
 
+
+  private static final int[] QUAT_EDGE_INDICES =
+      {
+        56, 40, 43, 59,  0, 55, 10, 17, 25, 49,
+        48, 57, 18,  7, 53, 32, 20, 11, 31, 38,
+        37, 30,  8, 28, 36, 44,  1, 46, 12, 14
+      };
+
+  private static final int[] QUAT_CENTER_INDICES =
+      {
+        16, 18, 22,  1, 20, 13, 14, 15,  0, 12,  2,  3
+      };
+
   private static final float[][] mCenterCoords = new float[NUM_CENTERS][3];
 
   static
@@ -175,7 +188,7 @@ public class TwistyMegaminx extends TwistyMinx
 
   int getNumStickerTypes(int numLayers)
     {
-    return numLayers-1; //numLayers;
+    return (numLayers+3)/2;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -203,10 +216,12 @@ public class TwistyMegaminx extends TwistyMinx
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void computeCenter(Static3D[] array, int center)
+  private void computeCenter(Static3D pos, int center, int numLayers)
     {
     float[] coords = mCenterCoords[center];
-    array[center].set( coords[0], coords[1], coords[2]);
+    float A = numLayers/3.0f;
+
+    pos.set( A*coords[0], A*coords[1], A*coords[2] );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -298,7 +313,7 @@ public class TwistyMegaminx extends TwistyMinx
     {
     int numCubitsPerCorner = numCubitsPerCorner(numLayers);
     int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
-    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge;// + NUM_CENTERS;
+    int numCubits = NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge + NUM_CENTERS;
     int index=0;
 
     final Static3D[] CENTERS = new Static3D[numCubits];
@@ -322,43 +337,34 @@ public class TwistyMegaminx extends TwistyMinx
         computeEdge(CENTERS[index], numLayers, edge, part );
         }
       }
-/*
+
     for(int center=0; center<NUM_CENTERS; center++, index++)
       {
-      computeCenter(CENTERS,index);
+      CENTERS[index] = new Static3D(0,0,0);
+      computeCenter(CENTERS[index], center, numLayers);
       }
-*/
+
     return CENTERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int getQuat(int cubit, int numLayers)
+  private int getQuat(int cubit, int numCubitsPerCorner, int numCubitsPerEdge)
     {
-    int numCubitsPerCorner = numCubitsPerCorner(numLayers);
-
     if( cubit < NUM_CORNERS*numCubitsPerCorner )
       {
       int corner = cubit/numCubitsPerCorner;
       return QUAT_CORNER_INDICES[corner];
       }
 
-    int numCubitsPerEdge = numCubitsPerEdge(numLayers);
-
     if( cubit < NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
       {
       int edge = (cubit-NUM_CORNERS*numCubitsPerCorner)/numCubitsPerEdge;
       return QUAT_EDGE_INDICES[edge];
       }
 
-/*
-    else
-      {
-      // TODO: centers
-      }
-*/
-
-    return 0;
+    int center = cubit - NUM_CORNERS*numCubitsPerCorner - NUM_EDGES*numCubitsPerEdge;
+    return QUAT_CENTER_INDICES[center];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -374,6 +380,7 @@ public class TwistyMegaminx extends TwistyMinx
 
     if( mCornerMeshes==null ) mCornerMeshes = new MeshBase[variants];
     if( mEdgeMeshes  ==null ) mEdgeMeshes   = new MeshBase[variants][(sizes[variants-1]-1)/2];
+    if( mCenterMeshes==null ) mCenterMeshes = new MeshBase[variants];
 
     if( cubit < NUM_CORNERS*numCubitsPerCorner )
       {
@@ -383,7 +390,7 @@ public class TwistyMegaminx extends TwistyMinx
         }
       mesh = mCornerMeshes[index].copy(true);
       }
-    else //if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
+    else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
       {
       int type = computeEdgeType(cubit,numCubitsPerCorner,numCubitsPerEdge);
 
@@ -397,13 +404,18 @@ public class TwistyMegaminx extends TwistyMinx
 
       mesh = mEdgeMeshes[index][type].copy(true);
       }
-/*
     else
       {
-      // TODO: centers
+      if( mCenterMeshes[index]==null )
+        {
+        float width = 2 * (numLayers/3.0f) * (MEGA_D+(0.5f-MEGA_D)*SIN18);
+        mCenterMeshes[index] = FactoryCubit.getInstance().createMegaminxCenterMesh(width);
+        }
+
+      mesh = mCenterMeshes[index].copy(true);
       }
-*/
-    Static4D q = QUATS[getQuat(cubit,numLayers)];
+
+    Static4D q = QUATS[getQuat(cubit,numCubitsPerCorner,numCubitsPerEdge)];
     MatrixEffectQuaternion quat = new MatrixEffectQuaternion( q, new Static3D(0,0,0) );
     mesh.apply(quat,0xffffffff,0);
 
@@ -454,27 +466,21 @@ public class TwistyMegaminx extends TwistyMinx
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  int getEdgeColor(int cubit, int cubitface, int numLayers, int numCubitsPerCorner, int numCubitsPerEdge)
+  int getEdgeColor(int edge, int cubitface, int numCubitsPerEdge)
     {
     if( cubitface<0 || cubitface>1 ) return NUM_TEXTURES;
 
-    int part = (cubit - NUM_CORNERS*numCubitsPerCorner) % numCubitsPerEdge;
-    int edge = (cubit - NUM_CORNERS*numCubitsPerCorner) / numCubitsPerEdge;
+    int part    = edge % numCubitsPerEdge;
+    int variant = edge / numCubitsPerEdge;
 
-    if( part==0 )
-      {
-      return mEdgeMap[edge][cubitface+2];
-      }
-
-    return cubitface==((part+1)%2) ? mEdgeMap[edge][cubitface+2] : NUM_TEXTURES;
+    return (part==0 || cubitface==((part+1)%2)) ? mEdgeMap[variant][cubitface+2] + (part+1)*NUM_FACES : NUM_TEXTURES;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
 
-  int getCenterColor(int cubit, int cubitface, int numLayers)
+  int getCenterColor(int center, int cubitface, int numLayers)
     {
-    return 0;
+    return cubitface>0 ? NUM_TEXTURES : center + NUM_FACES*(numLayers+1)/2;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -490,11 +496,13 @@ public class TwistyMegaminx extends TwistyMinx
       }
     else if( cubit<NUM_CORNERS*numCubitsPerCorner + NUM_EDGES*numCubitsPerEdge )
       {
-      return getEdgeColor(cubit,cubitface,numLayers,numCubitsPerCorner,numCubitsPerEdge);
+      int edge = cubit - NUM_CORNERS*numCubitsPerCorner;
+      return getEdgeColor(edge,cubitface,numCubitsPerEdge);
       }
     else
       {
-      return getCenterColor(cubit,cubitface,numLayers);
+      int center = cubit-NUM_CORNERS*numCubitsPerCorner-NUM_EDGES*numCubitsPerEdge;
+      return getCenterColor( center, cubitface, numLayers);
       }
     }
 
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index f5b667ff..d1c7f2bd 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -192,19 +192,12 @@ abstract class TwistyMinx extends TwistyObject
            {  6, 2, 3 },
          };
 
-  static final int[] QUAT_CORNER_INDICES
-    = {
+  static final int[] QUAT_CORNER_INDICES =
+      {
          0,  2,  3,  1, 40, 31, 41, 30, 39, 35,
         36, 34, 56, 32, 43, 21, 48, 28, 42, 23
       };
 
-  static final int[] QUAT_EDGE_INDICES
-    = {
-        56, 40, 43, 59,  0, 55, 10, 17, 25, 49,
-        48, 57, 18,  7, 53, 32, 20, 11, 31, 38,
-        37, 30,  8, 28, 36, 44,  1, 46, 12, 14
-      };
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyMinx(int numLayers, int realSize, Static4D quat, DistortedTexture texture, MeshSquare mesh,
