commit a2a4df1b96b80baecf77e926c6529014b12dfcf9
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Aug 20 01:03:37 2021 +0200

    Move 1) Helicopter 2) Ivy to the new cubit creation scheme.

diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index df076053..2f2cd0a6 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -22,6 +22,7 @@ package org.distorted.objects;
 import android.content.res.Resources;
 
 import org.distorted.helpers.FactoryCubit;
+import org.distorted.helpers.ObjectShape;
 import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
@@ -302,72 +303,78 @@ public class TwistyHelicopter extends TwistyObject
     return CENTERS;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectShape getObjectShape(int cubit, int numLayers)
+    {
+    int variant = getCubitVariant(cubit,numLayers);
+
+    if( variant==0 )
+      {
+      float[][] bands= new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,5} };
+      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
+      float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
+      int[] cornerIndices = new int[] { 1,1,1,0,0 };
+      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
+      int[] centerIndices = new int[] { 0,0,0,-1,0 };
+      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
+      }
+    else
+      {
+      float[][] bands= new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,3} };
+      int[] bandIndices   = new int[] { 0,1,1,1 };
+      float[][] corners   = new float[][] { {0.06f,0.15f}, {0.06f,0.20f} };
+      int[] cornerIndices = new int[] { 0,1,1,-1 };
+      float[][] centers   = new float[][] { {-1.0f/12, -1.0f/12, -1.0f/4} };
+      int[] centerIndices = new int[] { 0,0,0,-1 };
+      return new ObjectShape(VERTICES_FACE,VERT_INDEXES_FACE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private Static4D getQuat(int cubit, int numLayers)
+    {
+    return QUATS[QUAT_INDICES[cubit]];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getNumCubitVariants(int numLayers)
+    {
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getCubitVariant(int cubit, int numLayers)
+    {
+    return cubit<8 ? 0:1;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   MeshBase createCubitMesh(int cubit, int numLayers)
     {
+    int variant = getCubitVariant(cubit,numLayers);
+
     if( mMeshes==null )
       {
       FactoryCubit factory = FactoryCubit.getInstance();
       factory.clear();
-      mMeshes = new MeshBase[2];
+      mMeshes = new MeshBase[getNumCubitVariants(numLayers)];
       }
 
-    MeshBase mesh;
-
-    if( cubit<8 )
-      {
-      if( mMeshes[0]==null )
-        {
-        float[][] bands= new float[][]
-          {
-             {0.028f,35,0.16f,0.7f,7,3,3},
-             {0.000f, 0,1.00f,0.0f,3,1,5}
-          };
-        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
-        float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
-        int[] cornerIndexes = new int[] { 1,1,1,0,0 };
-        float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
-        int[] centerIndexes = new int[] { 0,0,0,-1,0 };
-
-        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(), null );
-        }
-      mesh = mMeshes[0].copy(true);
-      }
-    else
+    if( mMeshes[variant]==null )
       {
-      if( mMeshes[1]==null )
-        {
-        float[][] bands= new float[][]
-          {
-             {0.028f,35,0.16f,0.7f,7,3,3},
-             {0.000f, 0,1.00f,0.0f,3,1,3}
-          };
-        int[] bandIndexes   = new int[] { 0,1,1,1 };
-        float[][] corners   = new float[][] { {0.06f,0.15f}, {0.06f,0.20f} };
-        int[] cornerIndexes = new int[] { 0,1,1,-1 };
-        float[][] centers   = new float[][] { {-1.0f/12, -1.0f/12, -1.0f/4} };
-        int[] centerIndexes = new int[] { 0,0,0,-1 };
-
-        FactoryCubit factory = FactoryCubit.getInstance();
-        factory.createNewFaceTransform(VERTICES_FACE,VERT_INDEXES_FACE);
-        mMeshes[1] = factory.createRoundedSolid(VERTICES_FACE, VERT_INDEXES_FACE,
-                                                bands, bandIndexes,
-                                                corners, cornerIndexes,
-                                                centers, centerIndexes,
-                                                getNumCubitFaces(), null );
-        }
-      mesh = mMeshes[1].copy(true);
+      ObjectShape shape = getObjectShape(cubit,numLayers);
+      FactoryCubit factory = FactoryCubit.getInstance();
+      factory.createNewFaceTransform(shape);
+      mMeshes[variant] = factory.createRoundedSolid(shape);
       }
 
-    int index = QUAT_INDICES[cubit];
-    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[index], new Static3D(0,0,0) );
+    MeshBase mesh = mMeshes[variant].copy(true);
+    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
     mesh.apply(quat,0xffffffff,0);
 
     return mesh;
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
index 55dcc6d4..b503b5ce 100644
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objects/TwistyIvy.java
@@ -22,6 +22,7 @@ package org.distorted.objects;
 import android.content.res.Resources;
 
 import org.distorted.helpers.FactoryCubit;
+import org.distorted.helpers.ObjectShape;
 import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
@@ -201,210 +202,220 @@ public class TwistyIvy extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int getQuat(int cubit)
+  ObjectShape getObjectShape(int cubit, int numLayers)
     {
-    switch(cubit)
+    int variant = getCubitVariant(cubit,numLayers);
+
+    if( variant==0 )
       {
-      case  0: return 0;
-      case  1: return 2;
-      case  2: return 3;
-      case  3: return 1;
-
-      case  4: return 8;
-      case  5: return 11;
-      case  6: return 10;
-      case  7: return 9;
-      case  8: return 0;
-      case  9: return 2;
+      final float angle = (float)Math.PI/(2*IVY_N);
+      final float CORR  = 1.0f - 2*IVY_D;
+
+      float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
+      float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
+      int[] cornerIndices= new int[3*(IVY_N+1)+4];
+      int[] centerIndices= new int[3*(IVY_N+1)+4];
+      double[][] vertices= new double[3*(IVY_N+1)+4][3];
+      int[][] vertIndices= new int[6][IVY_N+4];
+      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
+
+      float[][] bands =
+        {
+          {+0.015f,20,0.2f,0.5f,7,1,2},
+          {-0.100f,20,0.2f,0.0f,2,1,2}
+        };
+
+      for(int i=0; i<3*(IVY_N+1); i++)
+        {
+        cornerIndices[i+4] = -1;
+        centerIndices[i+4] = -1;
+        }
+
+      cornerIndices[0] = 1;
+      cornerIndices[1] = 0;
+      cornerIndices[2] = 0;
+      cornerIndices[3] = 0;
+
+      centerIndices[0] = 0;
+      centerIndices[1] = 0;
+      centerIndices[2] = 0;
+      centerIndices[3] = 0;
+
+      vertices[0][0] = 0.0;
+      vertices[0][1] = 0.0;
+      vertices[0][2] = 0.0;
+      vertices[1][0] =-1.0;
+      vertices[1][1] = 0.0;
+      vertices[1][2] = 0.0;
+      vertices[2][0] = 0.0;
+      vertices[2][1] =-1.0;
+      vertices[2][2] = 0.0;
+      vertices[3][0] = 0.0;
+      vertices[3][1] = 0.0;
+      vertices[3][2] =-1.0;
+
+      vertIndices[0][0] = 2;
+      vertIndices[0][1] = 0;
+      vertIndices[0][2] = 1;
+      vertIndices[3][0] = 2;
+      vertIndices[3][1] = 0;
+      vertIndices[3][2] = 1;
+
+      vertIndices[1][0] = 3;
+      vertIndices[1][1] = 0;
+      vertIndices[1][2] = 2;
+      vertIndices[4][0] = 3;
+      vertIndices[4][1] = 0;
+      vertIndices[4][2] = 2;
+
+      vertIndices[2][0] = 1;
+      vertIndices[2][1] = 0;
+      vertIndices[2][2] = 3;
+      vertIndices[5][0] = 1;
+      vertIndices[5][1] = 0;
+      vertIndices[5][2] = 3;
+
+      int N1 = 4;
+      int N2 = N1 + IVY_N + 1;
+      int N3 = N2 + IVY_N + 1;
+
+      for(int i=0; i<=IVY_N; i++)
+        {
+        double cos1 = Math.cos((IVY_N-i)*angle);
+        double sin1 = Math.sin((IVY_N-i)*angle);
+        double cos2 = Math.cos((      i)*angle);
+        double sin2 = Math.sin((      i)*angle);
+
+        vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
+        vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
+        vertices[N1+i][2] = 0.0;
+
+        vertices[N2+i][0] = 0.0;
+        vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
+        vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
+
+        vertices[N3+i][0] = CORR*(cos2-0.5) - 0.5;
+        vertices[N3+i][1] = 0.0;
+        vertices[N3+i][2] = CORR*(sin2-0.5) - 0.5;
+
+        vertIndices[0][i+3] = N1 + i;
+        vertIndices[1][i+3] = N2 + i;
+        vertIndices[2][i+3] = N3 + i;
+        vertIndices[3][i+3] = N1 + i;
+        vertIndices[4][i+3] = N2 + i;
+        vertIndices[5][i+3] = N3 + i;
+        }
+
+      float C = 0.5f - SQ2/4;
+      float[] convexCenter = new float[] {-C,-C,-C};
+      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
       }
+    else
+      {
+      final float angle = (float)Math.PI/(2*IVY_N);
+      final float CORR  = 1.0f - 2*IVY_D;
+      double[][] vertices = new double[2*IVY_N][3];
+      int[][] vert_indices = new int[2][2*IVY_N];
+
+      int[] bandIndices= new int[] { 0,1 };
+      int[] indexes    = new int[2*IVY_N];
+      float[][] corners= new float[][] { {0.03f,0.10f} };
+      float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
 
-    return 0;
+      for(int i=0; i<IVY_N; i++)
+        {
+        double sin = Math.sin(i*angle);
+        double cos = Math.cos(i*angle);
+
+        vertices[i      ][0] = CORR*(0.5f-cos);
+        vertices[i      ][1] = CORR*(0.5f-sin);
+        vertices[i      ][2] = 0;
+        vertices[i+IVY_N][0] = CORR*(cos-0.5f);
+        vertices[i+IVY_N][1] = CORR*(sin-0.5f);
+        vertices[i+IVY_N][2] = 0;
+        }
+
+      for(int i=0; i<2*IVY_N; i++)
+        {
+        vert_indices[0][i] = i;
+        vert_indices[1][i] = 2*IVY_N-1-i;
+        }
+
+      for(int i=0; i<2*IVY_N; i++)
+        {
+        indexes[i] = -1;
+        }
+      indexes[0] = indexes[IVY_N] = 0;
+
+      float[][] bands =
+        {
+          {+0.03f,35,0.5f,0.5f,5,0,0},
+          {+0.10f,45,0.5f,0.0f,2,0,0}
+        };
+
+      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createCubitMesh(int cubit, int numLayers)
+  private Static4D getQuat(int cubit, int numLayers)
     {
-    if( mMeshes==null )
+    switch(cubit)
       {
-      FactoryCubit factory = FactoryCubit.getInstance();
-      factory.clear();
-      mMeshes = new MeshBase[2];
+      case  0: return QUATS[0];
+      case  1: return QUATS[2];
+      case  2: return QUATS[3];
+      case  3: return QUATS[1];
+
+      case  4: return QUATS[8];
+      case  5: return QUATS[11];
+      case  6: return QUATS[10];
+      case  7: return QUATS[9];
+      case  8: return QUATS[0];
+      case  9: return QUATS[2];
       }
 
-    MeshBase mesh;
+    return QUATS[0];
+    }
 
-    if( cubit<4 )
-      {
-      if( mMeshes[0]==null )
-        {
-        final float angle = (float)Math.PI/(2*IVY_N);
-        final float CORR  = 1.0f - 2*IVY_D;
-
-        float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
-        float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
-        int[] cornerIndexes= new int[3*(IVY_N+1)+4];
-        int[] centerIndexes= new int[3*(IVY_N+1)+4];
-        double[][] vertices= new double[3*(IVY_N+1)+4][3];
-        int[][] vertIndexes= new int[6][IVY_N+4];
-        int[] bandIndexes= new int[] { 0,0,0,1,1,1 };
-
-        float[][] bands =
-          {
-               {+0.015f,20,0.2f,0.5f,7,1,2},
-               {-0.100f,20,0.2f,0.0f,2,1,2}
-          };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        for(int i=0; i<3*(IVY_N+1); i++)
-          {
-          cornerIndexes[i+4] = -1;
-          centerIndexes[i+4] = -1;
-          }
-        cornerIndexes[0] = 1;
-        cornerIndexes[1] = 0;
-        cornerIndexes[2] = 0;
-        cornerIndexes[3] = 0;
-
-        centerIndexes[0] = 0;
-        centerIndexes[1] = 0;
-        centerIndexes[2] = 0;
-        centerIndexes[3] = 0;
-
-        vertices[0][0] = 0.0;
-        vertices[0][1] = 0.0;
-        vertices[0][2] = 0.0;
-        vertices[1][0] =-1.0;
-        vertices[1][1] = 0.0;
-        vertices[1][2] = 0.0;
-        vertices[2][0] = 0.0;
-        vertices[2][1] =-1.0;
-        vertices[2][2] = 0.0;
-        vertices[3][0] = 0.0;
-        vertices[3][1] = 0.0;
-        vertices[3][2] =-1.0;
-
-        vertIndexes[0][0] = 2;
-        vertIndexes[0][1] = 0;
-        vertIndexes[0][2] = 1;
-        vertIndexes[3][0] = 2;
-        vertIndexes[3][1] = 0;
-        vertIndexes[3][2] = 1;
-
-        vertIndexes[1][0] = 3;
-        vertIndexes[1][1] = 0;
-        vertIndexes[1][2] = 2;
-        vertIndexes[4][0] = 3;
-        vertIndexes[4][1] = 0;
-        vertIndexes[4][2] = 2;
-
-        vertIndexes[2][0] = 1;
-        vertIndexes[2][1] = 0;
-        vertIndexes[2][2] = 3;
-        vertIndexes[5][0] = 1;
-        vertIndexes[5][1] = 0;
-        vertIndexes[5][2] = 3;
-
-        int N1 = 4;
-        int N2 = N1 + IVY_N + 1;
-        int N3 = N2 + IVY_N + 1;
-
-        for(int i=0; i<=IVY_N; i++)
-          {
-          double cos1 = Math.cos((IVY_N-i)*angle);
-          double sin1 = Math.sin((IVY_N-i)*angle);
-          double cos2 = Math.cos((      i)*angle);
-          double sin2 = Math.sin((      i)*angle);
-
-          vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
-          vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
-          vertices[N1+i][2] = 0.0;
-
-          vertices[N2+i][0] = 0.0;
-          vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
-          vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
-
-          vertices[N3+i][0] = CORR*(cos2-0.5) - 0.5;
-          vertices[N3+i][1] = 0.0;
-          vertices[N3+i][2] = CORR*(sin2-0.5) - 0.5;
-
-          vertIndexes[0][i+3] = N1 + i;
-          vertIndexes[1][i+3] = N2 + i;
-          vertIndexes[2][i+3] = N3 + i;
-          vertIndexes[3][i+3] = N1 + i;
-          vertIndexes[4][i+3] = N2 + i;
-          vertIndexes[5][i+3] = N3 + i;
-          }
-
-        float C = 0.5f - SQ2/4;
-        float[] convexCenter = new float[] {-C,-C,-C};
-
-        FactoryCubit factory = FactoryCubit.getInstance();
-        factory.createNewFaceTransform(vertices,vertIndexes);
-        mMeshes[0] = factory.createRoundedSolid(vertices, vertIndexes,
-                                                bands, bandIndexes,
-                                                corners, cornerIndexes,
-                                                centers, centerIndexes,
-                                                getNumCubitFaces(), convexCenter );
-        }
-      mesh = mMeshes[0].copy(true);
-      }
-    else
-      {
-      if( mMeshes[1]==null )
-        {
-        final float angle = (float)Math.PI/(2*IVY_N);
-        final float CORR  = 1.0f - 2*IVY_D;
-        double[][] vertices = new double[2*IVY_N][3];
-        int[][] vert_indices = new int[2][2*IVY_N];
+  private int getNumCubitVariants(int numLayers)
+    {
+    return 2;
+    }
 
-        int[] bandIndexes= new int[] { 0,1 };
-        int[] indexes    = new int[2*IVY_N];
-        float[][] corners= new float[][] { {0.03f,0.10f} };
-        float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        for(int i=0; i<IVY_N; i++)
-          {
-          double sin = Math.sin(i*angle);
-          double cos = Math.cos(i*angle);
-
-          vertices[i      ][0] = CORR*(0.5f-cos);
-          vertices[i      ][1] = CORR*(0.5f-sin);
-          vertices[i      ][2] = 0;
-          vertices[i+IVY_N][0] = CORR*(cos-0.5f);
-          vertices[i+IVY_N][1] = CORR*(sin-0.5f);
-          vertices[i+IVY_N][2] = 0;
-          }
-
-        for(int i=0; i<2*IVY_N; i++)
-          {
-          vert_indices[0][i] = i;
-          vert_indices[1][i] = 2*IVY_N-1-i;
-          }
+  int getCubitVariant(int cubit, int numLayers)
+    {
+    return cubit<4 ? 0:1;
+    }
 
-        for(int i=0; i<2*IVY_N; i++)
-          {
-          indexes[i] = -1;
-          }
-        indexes[0] = indexes[IVY_N] = 0;
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        float[][] bands =
-          {
-               {+0.03f,35,0.5f,0.5f,5,0,0},
-               {+0.10f,45,0.5f,0.0f,2,0,0}
-          };
+  MeshBase createCubitMesh(int cubit, int numLayers)
+    {
+    int variant = getCubitVariant(cubit,numLayers);
 
-        FactoryCubit factory = FactoryCubit.getInstance();
-        factory.createNewFaceTransform(vertices,vert_indices);
-        mMeshes[1] = factory.createRoundedSolid(vertices, vert_indices,
-                                                bands, bandIndexes,
-                                                corners, indexes,
-                                                centers, indexes,
-                                                getNumCubitFaces(), null );
-        }
-      mesh = mMeshes[1].copy(true);
+    if( mMeshes==null )
+      {
+      FactoryCubit factory = FactoryCubit.getInstance();
+      factory.clear();
+      mMeshes = new MeshBase[getNumCubitVariants(numLayers)];
+      }
+
+    if( mMeshes[variant]==null )
+      {
+      ObjectShape shape = getObjectShape(cubit,numLayers);
+      FactoryCubit factory = FactoryCubit.getInstance();
+      factory.createNewFaceTransform(shape);
+      mMeshes[variant] = factory.createRoundedSolid(shape);
       }
 
-    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( QUATS[getQuat(cubit)], new Static3D(0,0,0) );
+    MeshBase mesh = mMeshes[variant].copy(true);
+    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
     mesh.apply(quat,0xffffffff,0);
 
     return mesh;
