commit 16f34a980a599bd8e121b4cdfc16a5dc7cee6711
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Apr 1 23:53:52 2021 +0200

    Progress with any size Kilominx.

diff --git a/src/main/java/org/distorted/objects/FactoryCubit.java b/src/main/java/org/distorted/objects/FactoryCubit.java
index 74413526..1f1f5f4d 100644
--- a/src/main/java/org/distorted/objects/FactoryCubit.java
+++ b/src/main/java/org/distorted/objects/FactoryCubit.java
@@ -708,7 +708,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createFacesMegaminxCorner(int numLayers)
+  MeshBase createFacesMinxCorner(int numLayers)
     {
     MeshBase[] meshes = new MeshPolygon[6];
 
@@ -740,6 +740,50 @@ class FactoryCubit
     return new MeshJoined(meshes);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createFacesKilominxEdge(int numLayers, float width, float height)
+    {
+     MeshBase[] meshes = new MeshPolygon[6];
+
+    float D = height/COS18;
+    float W = D*SIN18;
+    float X1 = height/2;
+    float Y1 = width/2;
+    float Y2 = (width+W)/2;
+    float X3 = D*SIN54;
+    float Y3 = D*COS54;
+    float X4 = height*SIN_HALFD;
+    float Y4 = height*COS_HALFD;
+
+    float[] vertices0 = { -X1,-Y1, X1, -Y1, X1, Y1+W,-X1, Y1 };
+    float[] vertices1 = { -X1,-Y2, X1, -Y2, X1, Y2+W,-X1, Y2 };
+    float[] vertices2 = { -X3, 0.0f, 0.0f, -Y3, X3, 0.0f, 0.0f, Y3 };
+    float[] vertices3 = { -X4, 0.0f, 0.0f, -Y4, X4, 0.0f, 0.0f, Y4 };
+
+    int numBands0 = numLayers<=5 ? 5 : 3;
+    int numBands1 = numLayers<=5 ? 3 : 2;
+    float h       = numLayers<=5 ? 0.03f : 0.03f;
+
+    float[] bands0 = computeBands(h    ,34,0.2f,0.2f,numBands0);
+    float[] bands1 = computeBands(0.01f,34,0.3f,0.2f,numBands1);
+
+    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, 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, 2);
+    meshes[4].setEffectAssociation(0,16,0);
+    meshes[5] = new MeshPolygon(vertices3, bands1, 1, 2);
+    meshes[5].setEffectAssociation(0,32,0);
+
+    return new MeshJoined(meshes);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   MeshBase createFacesMegaminxEdge(int numLayers, float width, float height)
@@ -1409,7 +1453,7 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  VertexEffect[] createVertexEffectsMegaminxCorner(int numLayers)
+  VertexEffect[] createVertexEffectsMinxCorner(float width)
     {
     VertexEffect[] effect = new VertexEffect[9];
 
@@ -1418,7 +1462,7 @@ class FactoryCubit
     float sinA = (2*SIN54*SIN54-1)/COS54;
     float cosA = (float)Math.sqrt(1-sinA*sinA);
     float LEN  = 0.5f/SIN54;
-    float scale= (numLayers/3.0f)*(0.5f-MEGA_D)/(LEN*0.5f*(numLayers-1));
+    float scale= width/LEN;
 
     Static3D axisA = new Static3D( SIN54, COS54, 0.0f);
     Static3D axisB = new Static3D(-SIN54, COS54, 0.0f);
@@ -1454,6 +1498,73 @@ class FactoryCubit
     return effect;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsKilominxEdge(float width, float height, boolean left)
+    {
+    VertexEffect[] effect = new VertexEffect[11 + (left ? 0:1)];
+
+    float D = height/COS18;
+    float W = D*SIN18;
+    float X1 = height/2;
+    float Y1 = width/2;
+    float Y2 = (width+W)/2;
+    float Y3 = D*COS54;
+    float Y4 = height*COS_HALFD;
+    float Z = 2*height*COS_HALFD;
+    float alpha = 90-DIHEDRAL1/2;
+
+    Static1D angle1 = new Static1D(alpha);
+    Static1D angle2 = new Static1D(180-alpha);
+    Static1D angle3 = new Static1D(DIHEDRAL2);
+    Static1D angle4 = new Static1D(90);
+
+    Static3D move1 = new Static3D(+X1,-Y1,0);
+    Static3D move2 = new Static3D(-X1,-Y2+W,-Z);
+    Static3D move3 = new Static3D(0,+Y3,0);
+    Static3D move4 = new Static3D(0,-Y4-width,0);
+    Static3D scale = new Static3D(+1,+1,-1);
+
+    Static3D axisXplus = new Static3D(+1, 0, 0);
+    Static3D axisYplus = 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);
+
+    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, axisYplus , center2);
+    effect[ 8] = new VertexEffectRotate(angle2, axisYplus , center2);
+    effect[ 9] = new VertexEffectRotate(angle3, axisXplus , center1);
+    effect[10] = new VertexEffectRotate(angle4, axisXplus , center3);
+
+    if( !left )
+      {
+      Static3D scale1 = new Static3D(+1,-1,+1);
+      effect[11] = new VertexEffectScale(scale1);
+      }
+
+    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;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   VertexEffect[] createVertexEffectsMegaminxEdge(float width, float height)
@@ -1964,14 +2075,15 @@ class FactoryCubit
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // numLayers==3 --> index=0; numLayers=5 --> index=1 ...
 // type: 0,1,... 0 --> edge, 1 --> 1 layer deeper, etc
-// TODO
 
-  MeshBase createKilominxEdgeMesh(int numLayers, float width, float height)
+  MeshBase createKilominxEdgeMesh(int numLayers, float width, float height, boolean left)
     {
-    MeshBase mesh = createFacesMegaminxEdge(numLayers,width,height);
-    VertexEffect[] effects = createVertexEffectsMegaminxEdge(width,height);
+    MeshBase mesh = createFacesKilominxEdge(numLayers,width,height);
+    VertexEffect[] effects = createVertexEffectsKilominxEdge(width,height,left);
     for( VertexEffect effect : effects ) mesh.apply(effect);
 
+// round...
+
     mesh.mergeEffComponents();
 
     return mesh;
@@ -1979,27 +2091,28 @@ class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createMinxCornerMesh(ObjectList object, int numLayers)
+  MeshBase createMinxCornerMesh(int numLayers, float width)
     {
-    MeshBase mesh = createFacesMegaminxCorner(numLayers);
-    VertexEffect[] effects = createVertexEffectsMegaminxCorner(numLayers);
+    MeshBase mesh = createFacesMinxCorner(numLayers);
+    VertexEffect[] effects = createVertexEffectsMinxCorner(width);
     for( VertexEffect effect : effects ) mesh.apply(effect);
 
     float A = (2*SQ3/3)* SIN54;
     float B = 0.4f;
+/*
     float X = SIN_HALFD* SIN54 * COS54;
     float Y = SIN54 * SIN54 - 0.5f;
     float Z = COS_HALFD* SIN54 * COS54;
-    float S = 2*SIN54*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
-
+    float S = 2*width;
+*/
     Static3D center = new Static3D(0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B);
-
-    Static3D[] vertices = new Static3D[4];
+    Static3D[] vertices = new Static3D[1];
     vertices[0] = new Static3D( 0.0f, 0.0f  , 0.0f);
+/*
     vertices[1] = new Static3D( 0.0f,-0.5f*S, 0.0f);
     vertices[2] = new Static3D(-X*S , Y*S   ,-Z*S );
     vertices[3] = new Static3D(+X*S , Y*S   ,-Z*S );
-
+*/
     roundCorners(mesh,center,vertices,0.04f,0.10f);
 
     mesh.mergeEffComponents();
diff --git a/src/main/java/org/distorted/objects/TwistyKilominx.java b/src/main/java/org/distorted/objects/TwistyKilominx.java
index 03d88aeb..fff8ef7e 100644
--- a/src/main/java/org/distorted/objects/TwistyKilominx.java
+++ b/src/main/java/org/distorted/objects/TwistyKilominx.java
@@ -188,17 +188,19 @@ public class TwistyKilominx extends TwistyMinx
   private float[] computeEdge(int numLayers, int edge, int part)
     {
     float D = numLayers/3.0f;
-
     float[] c1 = CORNERS[ mEdgeMap[edge][0] ];
     float[] c2 = CORNERS[ mEdgeMap[edge][1] ];
-    float x = D * (c1[0]+c2[0]) / 2;
-    float y = D * (c1[1]+c2[1]) / 2;
-    float z = D * (c1[2]+c2[2]) / 2;
 
+    int leftRight = 2*(part%2) -1;
     part /= 2;
 
     if( part==0 )
       {
+      float T = 0.5f + leftRight/(numLayers-1.0f);
+      float x = D * (T*c1[0]+(1.0f-T)*c2[0]);
+      float y = D * (T*c1[1]+(1.0f-T)*c2[1]);
+      float z = D * (T*c1[2]+(1.0f-T)*c2[2]);
+
       return new float[] { x, y, z };
       }
     else
@@ -206,15 +208,23 @@ public class TwistyKilominx extends TwistyMinx
       int mult = (part+1)/2;
       int dir  = (part+1)%2;
       float[] center = mCenterCoords[ mEdgeMap[edge][dir+2] ];
+      float x = 0.5f * D * (c1[0]+c2[0]);
+      float y = 0.5f * D * (c1[1]+c2[1]);
+      float z = 0.5f * D * (c1[2]+c2[2]);
 
       float vX = D*center[0] - x;
       float vY = D*center[1] - y;
       float vZ = D*center[2] - z;
 
-      float A = mult*D*COS18/(numLayers-1);
-      A /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
+      float T = 0.5f + leftRight*(mult*D*SIN18 + 1.0f)/(numLayers-1);
+      x = D * (T*c1[0]+(1.0f-T)*c2[0]);
+      y = D * (T*c1[1]+(1.0f-T)*c2[1]);
+      z = D * (T*c1[2]+(1.0f-T)*c2[2]);
+
+      float H = mult*D*COS18/(numLayers-1);
+      H /= (float)Math.sqrt(vX*vX+vY*vY+vZ*vZ);
 
-      return new float[] { x+A*vX, y+A*vY, z+A*vZ };
+      return new float[] { x + H*vX, y + H*vY, z + H*vZ };
       }
     }
 
@@ -318,7 +328,8 @@ public class TwistyKilominx extends TwistyMinx
       {
       if( mCornerMeshes[indexCornerEdge]==null )
         {
-        mCornerMeshes[indexCornerEdge] = FactoryCubit.getInstance().createMinxCornerMesh(ObjectList.KILO,numLayers);
+        float width = (numLayers/3.0f)/(numLayers-1);
+        mCornerMeshes[indexCornerEdge] = FactoryCubit.getInstance().createMinxCornerMesh(numLayers,width);
         }
       mesh = mCornerMeshes[indexCornerEdge].copy(true);
       }
@@ -332,7 +343,7 @@ public class TwistyKilominx extends TwistyMinx
         float height= tmp*COS18;
         float width = tmp + type*height*SIN18/COS18;
 
-        mEdgeMeshes[indexCornerEdge][type] = FactoryCubit.getInstance().createKilominxEdgeMesh(numLayers,width,height);
+        mEdgeMeshes[indexCornerEdge][type] = FactoryCubit.getInstance().createKilominxEdgeMesh(numLayers,width,height, (type%2)==0 );
         }
 
       mesh = mEdgeMeshes[indexCornerEdge][type].copy(true);
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index c019707e..8a05c7ae 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -283,7 +283,8 @@ public class TwistyMegaminx extends TwistyMinx
       {
       if( mCornerMeshes[index]==null )
         {
-        mCornerMeshes[index] = FactoryCubit.getInstance().createMinxCornerMesh(ObjectList.MEGA,numLayers);
+        float width = (numLayers/3.0f)*(0.5f-MEGA_D)/(0.5f*(numLayers-1));
+        mCornerMeshes[index] = FactoryCubit.getInstance().createMinxCornerMesh(numLayers, width);
         }
       mesh = mCornerMeshes[index].copy(true);
       }
diff --git a/src/main/java/org/distorted/objects/TwistyMinx.java b/src/main/java/org/distorted/objects/TwistyMinx.java
index 68178cdf..380f707c 100644
--- a/src/main/java/org/distorted/objects/TwistyMinx.java
+++ b/src/main/java/org/distorted/objects/TwistyMinx.java
@@ -218,10 +218,10 @@ abstract class TwistyMinx extends TwistyObject
           {false,  true,  true,  true,  true, false}
       };
 
-  // the quadruple ( vertex1, vertex2, face1, face2 ) defining an edge.
-  // In fact the 2 vertices already define it, the faces only provide easy
+  // the quadruple ( corner1, corner2, face1, face2 ) defining an edge.
+  // In fact the 2 corners already define it, the faces only provide easy
   // way to get to know the colors. Order: arbitrary. Face1 arbitrarily on
-  // the 'left' or right of vector vertex1 --> vertex2, according to Quat.
+  // the 'left' or right of vector corner1 --> corner2, according to Quat.
   static final int[][] mEdgeMap =
          {
            {  0, 12,  0,  8},
