commit 680469e608f3e32d20a829d151d04be31181a818
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Apr 16 00:19:21 2021 +0200

    Convert the Redi Cube to the new engine.

diff --git a/src/main/java/org/distorted/helpers/FactoryCubit.java b/src/main/java/org/distorted/helpers/FactoryCubit.java
index f7ffac9a..17c89213 100644
--- a/src/main/java/org/distorted/helpers/FactoryCubit.java
+++ b/src/main/java/org/distorted/helpers/FactoryCubit.java
@@ -43,7 +43,6 @@ public class FactoryCubit
   private static final float SQ2 = (float)Math.sqrt(2);
   private static final float SQ3 = (float)Math.sqrt(3);
   private static final float SQ5 = (float)Math.sqrt(5);
-  private static final float SQ6 = (float)Math.sqrt(6);
 
   private static final Static1D RADIUS = new Static1D(1);
   private static FactoryCubit mThis;
@@ -238,105 +237,6 @@ public class FactoryCubit
       }
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MeshBase createFacesHelicopterFace()
-    {
-    MeshBase[] meshes = new MeshBase[4];
-
-    float E = 0.5f;
-    float F = SQ2/4;
-    float G = 1.0f/12;
-    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
-    float[] bands0 = computeBands(0.028f,35,E/4,0.7f,7);
-
-    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
-    meshes[0].setEffectAssociation(0,1,0);
-
-    float[] vertices1 = { -F,-G, +F,-G, 0,2*G};
-    float[] bands1 = computeBands(0.01f,45,F,0.0f,3);
-
-    meshes[1] = new MeshPolygon(vertices1, bands1, 1, 3);
-    meshes[1].setEffectAssociation(0,2,0);
-
-    float[] vertices2 = { -E/2,-F/3, +E/2,-F/3, 0,2*F/3};
-
-    meshes[2] = new MeshPolygon(vertices2, bands1, 1, 3);
-    meshes[2].setEffectAssociation(0,4,0);
-    meshes[3] = meshes[2].copy(true);
-    meshes[3].setEffectAssociation(0,8,0);
-
-    return new MeshJoined(meshes);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MeshBase createFacesRediEdge()
-    {
-    MeshBase[] meshes = new MeshPolygon[6];
-
-    float F = 0.25f;
-    float[] vertices0 = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
-    float[] bands0 = computeBands(0.038f,35,F,0.7f,7);
-
-    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 2);
-    meshes[0].setEffectAssociation(0,1,0);
-    meshes[1] = meshes[0].copy(true);
-    meshes[1].setEffectAssociation(0,2,0);
-
-    float[] bands1 = computeBands(0.02f,35,F/2,0.2f,3);
-    float[] vertices1 = { -F/2, +F/2, -F/2, -1.5f*F, 1.5f*F, +F/2 };
-
-    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
-    meshes[2].setEffectAssociation(0,4,0);
-    meshes[3] = meshes[2].copy(true);
-    meshes[3].setEffectAssociation(0,8,0);
-
-    float X = 0.25f*SQ2;
-    float Y = SQ6/16;
-    float[] vertices2 = { -X, Y, -1.5f*X, -Y, +1.5f*X, -Y, +X, Y };
-
-    meshes[4] = new MeshPolygon(vertices2, bands1, 1, 1);
-    meshes[4].setEffectAssociation(0,16,0);
-    meshes[5] = meshes[4].copy(true);
-    meshes[5].setEffectAssociation(0,32,0);
-
-    return new MeshJoined(meshes);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  MeshBase createFacesRediCorner()
-    {
-    MeshBase[] meshes = new MeshBase[6];
-
-    float E = 0.5f;
-    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
-    float[] bands0 = computeBands(0.06f,35,E,0.7f,6);
-
-    meshes[0] = new MeshPolygon(vertices0,bands0,2,2);
-    meshes[0].setEffectAssociation(0,1,0);
-    meshes[1] = meshes[0].copy(true);
-    meshes[1].setEffectAssociation(0,2,0);
-    meshes[2] = meshes[0].copy(true);
-    meshes[2].setEffectAssociation(0,4,0);
-
-    float F = 0.5f;
-    float X = 0.5f;
-    float G = 0.72f;
-    float[] vertices1 = { -E,+F, -E+X,0, -E,-F, -E*G,-F, +E*G,-F, +E,-F, +E-X,0, +E,+F, +E*G,+F, -E*G,+F };
-    float[] bands1 = computeBands(0.0f,0,1.0f,0.0f,2);
-
-    meshes[3] = new MeshPolygon(vertices1,bands1,0,0);
-    meshes[3].setEffectAssociation(0,8,0);
-    meshes[4] = meshes[3].copy(true);
-    meshes[4].setEffectAssociation(0,16,0);
-    meshes[5] = meshes[3].copy(true);
-    meshes[5].setEffectAssociation(0,32,0);
-
-    return new MeshJoined(meshes);
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   MeshBase createFacesIvyCorner()
@@ -722,91 +622,6 @@ public class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // EFFECTS
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  VertexEffect[] createVertexEffectsRediEdge()
-    {
-    Static3D move0 = new Static3D(0.0f, -0.5f, 0.0f);
-    Static3D move1 = new Static3D(0.25f, -0.25f, 0.0f);
-    Static3D move2 = new Static3D(0.5f, 0.0f, 0.0f);
-    Static3D move3 = new Static3D(0.0f, (SQ3-6)/8, (SQ3-6)/8);
-    Static3D flipZ = new Static3D(1,1,-1);
-    Static3D flipX = new Static3D(-1,1,1);
-    Static3D scale = new Static3D(2,2,2);
-    Static3D cent0 = new Static3D(0,0, 0);
-    Static3D cent1 = new Static3D(0,0, -1.5f);
-    Static3D axisX = new Static3D(1,0, 0);
-    Static3D axisY = new Static3D(0,1, 0);
-    Static3D axis  = new Static3D(0,SQ2/2,-SQ2/2);
-    Static1D angle1= new Static1D(90);
-    Static1D angle2= new Static1D(45);
-    Static1D angle3= new Static1D( (float)(180/Math.PI*Math.acos(SQ3/3)) );
-
-    VertexEffect[] effect = new VertexEffect[12];
-
-    effect[0] = new VertexEffectScale(scale);
-    effect[1] = new VertexEffectMove(move0);
-    effect[2] = new VertexEffectScale(flipZ);
-    effect[3] = new VertexEffectRotate(angle1,axisX,cent0);
-    effect[4] = new VertexEffectMove(move1);
-    effect[5] = new VertexEffectRotate(angle1,axisY,cent0);
-    effect[6] = new VertexEffectMove(move2);
-    effect[7] = new VertexEffectScale(flipX);
-    effect[8] = new VertexEffectRotate(angle2,axisX,cent0);
-    effect[9] = new VertexEffectMove(move3);
-    effect[10]= new VertexEffectRotate(angle3,axis ,cent1);
-    effect[11]= new VertexEffectScale(flipX);
-
-    effect[0].setMeshAssociation(63,-1);  // meshes 0,1,2,3,4,5
-    effect[1].setMeshAssociation( 3,-1);  // meshes 0,1
-    effect[2].setMeshAssociation( 2,-1);  // mesh 1
-    effect[3].setMeshAssociation( 2,-1);  // mesh 1
-    effect[4].setMeshAssociation(12,-1);  // meshes 2,3
-    effect[5].setMeshAssociation(60,-1);  // meshes 2,3,4,5
-    effect[6].setMeshAssociation(12,-1);  // meshes 2,3
-    effect[7].setMeshAssociation( 8,-1);  // mesh 3
-    effect[8].setMeshAssociation(48,-1);  // meshes 4,5
-    effect[9].setMeshAssociation(48,-1);  // meshes 4,5
-    effect[10].setMeshAssociation(48,-1); // meshes 4,5
-    effect[11].setMeshAssociation(32,-1); // mesh 5
-
-    return effect;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  VertexEffect[] createVertexEffectsRediCorner()
-    {
-    Static3D axisY   = new Static3D(0,1,0);
-    Static3D axisX   = new Static3D(1,0,0);
-    Static3D axisZ   = new Static3D(0,0,1);
-    Static3D center  = new Static3D(0,0,0);
-    Static1D angle90 = new Static1D(90);
-    Static1D angle270= new Static1D(270);
-    Static1D angle45 = new Static1D(-45);
-    Static3D scale   = new Static3D(1.0f, SQ2, 1.0f);
-
-    VertexEffect[] effect = new VertexEffect[7];
-
-    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
-    effect[1] = new VertexEffectRotate( angle270, axisX, center );
-    effect[2] = new VertexEffectRotate( angle90 , axisY, center );
-    effect[3] = new VertexEffectScale(scale);
-    effect[4] = new VertexEffectRotate( angle45 , axisX, center );
-    effect[5] = new VertexEffectRotate( angle90 , axisY, center );
-    effect[6] = new VertexEffectRotate( angle270, axisZ, center );
-
-    effect[0].setMeshAssociation( 7,-1);  // 0,1,2
-    effect[1].setMeshAssociation( 2,-1);  // 1
-    effect[2].setMeshAssociation( 4,-1);  // 2
-    effect[3].setMeshAssociation(56,-1);  // 3,4,5
-    effect[4].setMeshAssociation(56,-1);  // 3,4,5
-    effect[5].setMeshAssociation(16,-1);  // 4
-    effect[6].setMeshAssociation(32,-1);  // 5
-
-    return effect;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   VertexEffect[] createVertexEffectsIvyCorner()
@@ -1198,51 +1013,6 @@ public class FactoryCubit
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // OBJECTS
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public MeshBase createRediEdgeMesh()
-    {
-    MeshBase mesh = createFacesRediEdge();
-    VertexEffect[] effects = createVertexEffectsRediEdge();
-    for( VertexEffect effect : effects ) mesh.apply(effect);
-
-    Static3D center = new Static3D(0.0f,-0.75f,-0.75f);
-    Static3D[] vertices = new Static3D[2];
-    vertices[0] = new Static3D( 0.5f, 0.0f, 0.0f);
-    vertices[1] = new Static3D(-0.5f, 0.0f, 0.0f);
-    roundCorners(mesh,center,vertices,0.06f,0.20f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public MeshBase createRediCornerMesh()
-    {
-    MeshBase mesh = createFacesRediCorner();
-    VertexEffect[] effects = createVertexEffectsRediCorner();
-    for( VertexEffect effect : effects ) mesh.apply(effect);
-
-    Static3D center = new Static3D(0,0,0);
-    Static3D[] vertices = new Static3D[8];
-    vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
-    vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
-    vertices[2] = new Static3D(+0.5f,-0.5f,+0.5f);
-    vertices[3] = new Static3D(+0.5f,-0.5f,-0.5f);
-    vertices[4] = new Static3D(-0.5f,+0.5f,+0.5f);
-    vertices[5] = new Static3D(-0.5f,+0.5f,-0.5f);
-    vertices[6] = new Static3D(-0.5f,-0.5f,+0.5f);
-    vertices[7] = new Static3D(-0.5f,-0.5f,-0.5f);
-
-    roundCorners(mesh,center,vertices,0.06f,0.12f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public MeshBase createIvyCornerMesh()
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index 1bcb5cf4..9b0e3b6b 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -295,7 +295,7 @@ public class TwistyHelicopter extends TwistyObject
 
   int getNumStickerTypes(int numLayers)
     {
-    return 1;
+    return STICKERS.length;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
index a8f3cf4c..240ad854 100644
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objects/TwistyRedi.java
@@ -133,7 +133,73 @@ public class TwistyRedi extends TwistyObject
            {  7,11,12,12,12,12 },
          };
 
-  private static MeshBase mCornerMesh, mEdgeMesh;
+  private static final float G = 0.72f;
+
+  private static final double[][] VERTICES_CORNER = new double[][]
+          {
+             { 0.0f, 0.0f, 0.0f },
+             {-0.5f, 0.5f, 0.5f },
+             {-0.5f,-0.5f, 0.5f },
+             { 0.5f, 0.5f, 0.5f },
+             { 0.5f,-0.5f, 0.5f },
+             { 0.5f, 0.5f,-0.5f },
+             { 0.5f,-0.5f,-0.5f },
+             {-0.5f, 0.5f,-0.5f },
+
+             {-0.5f, 0.5f*G, 0.5f },
+             {-0.5f,-0.5f*G, 0.5f },
+             {-0.5f*G,-0.5f, 0.5f },
+             { 0.5f*G,-0.5f, 0.5f },
+             { 0.5f,-0.5f, 0.5f*G },
+             { 0.5f,-0.5f,-0.5f*G },
+             { 0.5f,-0.5f*G,-0.5f },
+             { 0.5f, 0.5f*G,-0.5f },
+             { 0.5f*G, 0.5f,-0.5f },
+             {-0.5f*G, 0.5f,-0.5f },
+             {-0.5f, 0.5f,-0.5f*G },
+             {-0.5f, 0.5f, 0.5f*G },
+          };
+
+  private static final int[][] VERT_INDEXES_CORNER = new int[][]
+          {
+             { 2,4,3,1 },
+             { 1,3,5,7 },
+             { 4,6,5,3 },
+
+             { 2,10,11,4,0,5,16,17,7,0},
+             { 4,12,13,6,0,7,18,19,1,0},
+             { 1, 8, 9,2,0,6,14,15,5,0}
+          };
+
+  private static final double[][] VERTICES_EDGE = new double[][]
+          {
+             {-0.5f, 0.0f, 0.0f},
+             { 0.5f, 0.0f, 0.0f},
+             {-0.5f,-1.0f, 0.0f},
+             { 0.5f,-1.0f, 0.0f},
+             { 0.0f,-1.5f, 0.0f},
+             {-0.5f, 0.0f,-1.0f},
+             { 0.5f, 0.0f,-1.0f},
+             { 0.0f, 0.0f,-1.5f},
+          };
+
+  private static final int[][] VERT_INDEXES_EDGE = new int[][]
+          {
+             { 0,2,4,3,1 },
+             { 0,1,6,7,5 },
+             { 1,3,6 },
+             { 0,2,5 },
+             { 4,7,6,3 },
+             { 4,7,5,2 }
+          };
+
+  private static final float[][] STICKERS = new float[][]
+          {
+             { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
+             { -0.3125f, 0.4375f, -0.3125f, -0.1875f, 0.0f, -0.5f, 0.3125f, -0.1875f, 0.3125f, 0.4375f }
+          };
+
+  private static MeshBase[] mMeshes;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -144,18 +210,20 @@ public class TwistyRedi extends TwistyObject
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
 
   double[][] getVertices(int cubitType)
     {
+    if( cubitType==0 ) return VERTICES_CORNER;
+    if( cubitType==1 ) return VERTICES_EDGE;
     return null;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// TODO
 
   int[][] getVertIndexes(int cubitType)
     {
+    if( cubitType==0 ) return VERT_INDEXES_CORNER;
+    if( cubitType==1 ) return VERT_INDEXES_EDGE;
     return null;
     }
 
@@ -263,17 +331,65 @@ public class TwistyRedi extends TwistyObject
 
   MeshBase createCubitMesh(int cubit, int numLayers)
     {
+    if( mMeshes==null )
+      {
+      FactoryCubit factory = FactoryCubit.getInstance();
+      factory.clear();
+      mMeshes = new MeshBase[2];
+      }
+
     MeshBase mesh;
 
     if( cubit<8 )
       {
-      if( mCornerMesh==null ) mCornerMesh = FactoryCubit.getInstance().createRediCornerMesh();
-      mesh = mCornerMesh.copy(true);
+      if( mMeshes[0]==null )
+        {
+        float[][] bands= new float[][]
+          {
+             {0.06f,35,0.5f,0.7f,6,2,2},
+             {0.00f, 0,1.0f,0.0f,2,0,0}
+          };
+        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
+        float[][] corners   = new float[][] { {0.06f,0.12f} };
+        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+        float[][] centers   = new float[][] { { 0.0f, 0.0f, 0.0f} };
+        int[] centerIndexes = new int[] { -1,0,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 };
+
+        FactoryCubit factory = FactoryCubit.getInstance();
+        factory.createNewFaceTransform(VERTICES_CORNER,VERT_INDEXES_CORNER);
+        mMeshes[0] = factory.createRoundedSolid(VERTICES_CORNER, VERT_INDEXES_CORNER,
+                                                bands, bandIndexes,
+                                                corners, cornerIndexes,
+                                                centers, centerIndexes,
+                                                getNumCubitFaces() );
+        }
+      mesh = mMeshes[0].copy(true);
       }
     else
       {
-      if( mEdgeMesh==null ) mEdgeMesh = FactoryCubit.getInstance().createRediEdgeMesh();
-      mesh = mEdgeMesh.copy(true);
+      if( mMeshes[1]==null )
+        {
+        float[][] bands= new float[][]
+          {
+            {0.038f,35,0.250f,0.7f, 7,2,2},
+            {0.020f,35,0.125f,0.2f, 3,1,2},
+            {0.020f,35,0.125f,0.2f, 3,1,1}
+          };
+        int[] bandIndexes   = new int[] { 0,0,1,1,2,2 };
+        float[][] corners   = new float[][] { {0.06f,0.20f} };
+        int[] cornerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
+        float[][] centers   = new float[][] { { 0.0f,-0.75f,-0.75f} };
+        int[] centerIndexes = new int[] { 0,0,-1,-1,-1,-1,-1,-1 };
+
+        FactoryCubit factory = FactoryCubit.getInstance();
+        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
+        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
+                                                bands, bandIndexes,
+                                                corners, cornerIndexes,
+                                                centers, centerIndexes,
+                                                getNumCubitFaces() );
+        }
+      mesh = mMeshes[1].copy(true);
       }
 
     MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
@@ -294,26 +410,18 @@ public class TwistyRedi extends TwistyObject
   void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
     {
     int COLORS = FACE_COLORS.length;
-    FactorySticker factory = FactorySticker.getInstance();
+    int stickerType = face/COLORS;
+    float R,S;
 
-    if( face<COLORS )
+    switch(stickerType)
       {
-      float F =  0.5f;
-      float R = 0.10f;
-      float S = 0.10f;
-      float[] vertices = { -F,-F, +F,-F, +F,+F, -F,+F};
-
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face], R);
+      case 0:  R = 0.09f; S = 0.09f; break;
+      case 1:  R = 0.06f; S = 0.06f; break;
+      default: R = 0.00f; S = 0.00f; break;
       }
-    else
-      {
-      float F = 0.25f;
-      float R = 0.05f;
-      float S = 0.05f;
-      float[] vertices = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
 
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face-COLORS], R);
-      }
+    FactorySticker factory = FactorySticker.getInstance();
+    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], S, FACE_COLORS[face%COLORS], R);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
