commit db608887156a670a3364bda11e8b324090c2bfa7
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Jan 26 10:35:47 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 3062307a..28aacd4f 100644
--- a/src/main/java/org/distorted/objects/FactoryCubit.java
+++ b/src/main/java/org/distorted/objects/FactoryCubit.java
@@ -47,12 +47,16 @@ class FactoryCubit
   private static final float SQ5 = (float)Math.sqrt(5);
   private static final float SQ6 = (float)Math.sqrt(6);
 
-  static final float SIN54   = (SQ5+1)/4;                         // sin(54 deg)
-  static final float COS54   = (float)(Math.sqrt(10-2*SQ5)/4);    // cos(54 deg)
-
-  static final float MINX_C0  = (SQ5-1)/4;
+  static final float SIN54    = (SQ5+1)/4;
+  static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
+  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)
+
+  static final float DIHEDRAL1= (float)(Math.acos(-SQ5/5)*180/Math.PI);
+  static final float DIHEDRAL2= (float)((180/Math.PI)*Math.asin((2*SIN54*SIN54-1)/COS54) - 90);
+
   static final float MINX_SC  = 0.5f;
 
   private static final int IVY_N = 8;
@@ -749,6 +753,45 @@ class FactoryCubit
     return new MeshJoined(meshes);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createFacesMegaminxEdge(float width, float height)
+    {
+    MeshBase[] meshes = new MeshPolygon[6];
+
+    float D = height/COS18;
+    float W = D*SIN18;
+
+    float Y1 = 0.5f*width;
+    float Y2 = 0.5f*width + W;
+    float Y3 = 0.5f*width + 2*W;
+    float X2 = D*SIN54;
+    float X1 = 0.5f*height;
+    float Y4 = D*COS54;
+
+    float[] vertices0 = { -X1, Y1, -X1, -Y1, X1, -Y2, X1, Y2 };
+    float[] vertices1 = { -X1, Y3, -X1, -Y3, X1, -Y2, X1, Y2 };
+    float[] vertices2 = { -X2, 0.0f, 0.0f, -Y4, X2, 0.0f, 0.0f, Y4 };
+
+    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].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].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].setEffectAssociation(0,16,0);
+    meshes[5] = meshes[4].copy(true);
+    meshes[5].setEffectAssociation(0,32,0);
+
+    return new MeshJoined(meshes);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // EFFECTS
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1256,8 +1299,8 @@ class FactoryCubit
     float Y1= (float)(Math.sqrt(2+0.4f*SQ5)/4);
     float Y2= H/(2*COS_HALFD);
     float A = (float)(Math.acos(-SQ5/5)*180/Math.PI);  // dihedral angle of a dedecahedron in degrees
-    float sin18 = MINX_C0;
-    float cos18 = (float)(Math.sqrt(1-MINX_C0*MINX_C0));
+    float sin18 = SIN18;
+    float cos18 = (float)(Math.sqrt(1- SIN18 * SIN18));
     float LEN   = (float)Math.sqrt(H*H/(COS_HALFD*COS_HALFD) + 0.25f);
 
     Static3D axisZ = new Static3D(0.0f  , 0.0f , 1.0f);
@@ -1308,7 +1351,6 @@ class FactoryCubit
     VertexEffect[] effect = new VertexEffect[9];
 
     float Y = COS54/(2*SIN54);
-    float A = (float)(Math.acos(-SQ5/5)*180/Math.PI);  // dihedral angle of a dedecahedron in degrees
 
     float sinA = (2*SIN54*SIN54-1)/COS54;
     float cosA = (float)Math.sqrt(1-sinA*sinA);
@@ -1325,9 +1367,9 @@ class FactoryCubit
     Static3D move1= new Static3D(0.0f, -sinA*LEN, -cosA*LEN );
     Static3D move2= new Static3D(0.0f, Y , 0.0f );
 
-    Static1D angleD = new Static1D(A);
-    Static1D angleE = new Static1D(360-A);
-    Static1D angleF = new Static1D( (float)((180/Math.PI)*Math.asin(sinA) - 90) );
+    Static1D angleD = new Static1D(DIHEDRAL1);
+    Static1D angleE = new Static1D(360-DIHEDRAL1);
+    Static1D angleF = new Static1D(DIHEDRAL2);
 
     effect[0] = new VertexEffectScale ( new Static3D( 1, 1,-1) );
     effect[1] = new VertexEffectRotate(angleE, axisA, centerU);
@@ -1349,6 +1391,66 @@ class FactoryCubit
     return effect;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsMegaminxEdge(float width, float height)
+    {
+    VertexEffect[] effect = new VertexEffect[11];
+
+    float X = 0.5f*height;
+    float Y = height*(COS54/COS18) + width*0.5f;
+    float Z = 2*height*COS_HALFD;
+
+    float alpha = 90-DIHEDRAL1/2;
+    float beta  = DIHEDRAL2;
+
+    Static1D angle1 = new Static1D(alpha);
+    Static1D angle2 = new Static1D(180-alpha);
+    Static1D angle3 = new Static1D(beta);
+
+    Static3D move1 = new Static3D(X,0,0);
+    Static3D move2 = new Static3D(X,0,-Z);
+    Static3D move3 = new Static3D(0,+Y,0);
+    Static3D move4 = new Static3D(0,-Y,0);
+    Static3D scale = new Static3D(+1,+1,-1);
+
+    Static3D axisXplus = new Static3D(+1, 0, 0);
+    Static3D axisXminus= new Static3D(-1, 0, 0);
+    Static3D axisYplus = new Static3D( 0,+1, 0);
+    Static3D axisYminus= new Static3D( 0,-1, 0);
+
+    Static3D center1= new Static3D( 0, 0, 0);
+    Static3D center2= new Static3D( 0, 0,-Z);
+    Static3D center3= new Static3D( 0,+width*0.5f, 0);
+    Static3D center4= new Static3D( 0,-width*0.5f, 0);
+
+    effect[ 0] = new VertexEffectMove(move1);
+    effect[ 1] = new VertexEffectMove(move2);
+    effect[ 2] = new VertexEffectMove(move3);
+    effect[ 3] = new VertexEffectMove(move4);
+    effect[ 4] = new VertexEffectScale(scale);
+    effect[ 5] = new VertexEffectRotate(angle1, axisYplus , center1);
+    effect[ 6] = new VertexEffectRotate(angle2, axisYplus , center1);
+    effect[ 7] = new VertexEffectRotate(angle1, axisYminus, center2);
+    effect[ 8] = new VertexEffectRotate(angle2, axisYminus, center2);
+    effect[ 9] = new VertexEffectRotate(angle3, axisXplus , center3);
+    effect[10] = new VertexEffectRotate(angle3, axisXminus, center4);
+
+    effect[ 0].setMeshAssociation( 3,-1);  // meshes 0,1
+    effect[ 1].setMeshAssociation(12,-1);  // meshes 2,3
+    effect[ 2].setMeshAssociation(16,-1);  // mesh 4
+    effect[ 3].setMeshAssociation(32,-1);  // mesh 5
+    effect[ 4].setMeshAssociation( 2,-1);  // mesh 1
+    effect[ 5].setMeshAssociation( 1,-1);  // mesh 0
+    effect[ 6].setMeshAssociation( 2,-1);  // mesh 1
+    effect[ 7].setMeshAssociation( 4,-1);  // mesh 2
+    effect[ 8].setMeshAssociation( 8,-1);  // mesh 3
+    effect[ 9].setMeshAssociation(16,-1);  // mesh 4
+    effect[10].setMeshAssociation(32,-1);  // mesh 5
+
+    return effect;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // OBJECTS
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1765,9 +1867,14 @@ class FactoryCubit
 // numLayers==3 --> index=0; numLayers=5 --> index=1 ...
 // type: 0,1,... 0 --> edge, 1 --> 1 layer deeper, etc
 
-  MeshBase createMegaminxEdgeMesh(int index, int type)
+  MeshBase createMegaminxEdgeMesh(float width, float height)
     {
+    MeshBase mesh = createFacesMegaminxEdge(width,height);
+    VertexEffect[] effects = createVertexEffectsMegaminxEdge(width,height);
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    mesh.mergeEffComponents();
 
-    return createTetraMesh();
+    return mesh;
     }
   }
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index 74dbae38..30dc8ac0 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -362,11 +362,12 @@ public class TwistyMegaminx extends TwistyMinx
     int numCubitsPerCorner = numCubitsPerCorner(numLayers);
     int numCubitsPerEdge   = numCubitsPerEdge(numLayers);
     int index = (numLayers-3)/2;
-    int variants = ObjectList.MEGA.getNumVariants();
+    int[] sizes = ObjectList.MEGA.getSizes();
+    int variants = sizes.length;
     MeshBase mesh;
 
     if( mCornerMeshes==null ) mCornerMeshes = new MeshBase[variants];
-    if( mEdgeMeshes  ==null ) mEdgeMeshes   = new MeshBase[variants][index+1];
+    if( mEdgeMeshes  ==null ) mEdgeMeshes   = new MeshBase[variants][(sizes[variants-1]-1)/2];
 
     if( cubit < NUM_CORNERS*numCubitsPerCorner )
       {
