commit 1beffb694477e800a761ebe4093af4798130d129
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Mon Sep 14 23:30:18 2020 +0100

    Procedural Skewb cubits and the Skewb mesh for MeshFile.

diff --git a/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java b/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
index 03c830a..f1a2f85 100644
--- a/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
+++ b/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
@@ -45,7 +45,8 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
 
     private LinearLayout mLayout;
     private int mResource;
-    private String[] mNames = new String[] { "deferredjob",
+    private String[] mNames = new String[] { "procedural" ,
+                                             "deferredjob",
                                              "meshjoin"   ,
                                              "predeform"  ,
                                              "cube2"      ,
@@ -56,7 +57,7 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
                                              "pyra4"      ,
                                              "pyra5"      ,
                                              "dino"       ,
-                                             "procedural"
+                                             "skewb"
                                            };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -183,18 +184,19 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
         {
         switch(pos)
           {
-          case  0: mResource = R.raw.deferredjob; break;
-          case  1: mResource = R.raw.meshjoin   ; break;
-          case  2: mResource = R.raw.predeform  ; break;
-          case  3: mResource = R.raw.cube2      ; break;
-          case  4: mResource = R.raw.cube3      ; break;
-          case  5: mResource = R.raw.cube4      ; break;
-          case  6: mResource = R.raw.cube5      ; break;
-          case  7: mResource = R.raw.pyra3      ; break;
-          case  8: mResource = R.raw.pyra4      ; break;
-          case  9: mResource = R.raw.pyra5      ; break;
-          case 10: mResource = R.raw.dino       ; break;
-          case 11: mResource = PROCEDURAL       ; break;
+          case  0: mResource = PROCEDURAL       ; break;
+          case  1: mResource = R.raw.deferredjob; break;
+          case  2: mResource = R.raw.meshjoin   ; break;
+          case  3: mResource = R.raw.predeform  ; break;
+          case  4: mResource = R.raw.cube2      ; break;
+          case  5: mResource = R.raw.cube3      ; break;
+          case  6: mResource = R.raw.cube4      ; break;
+          case  7: mResource = R.raw.cube5      ; break;
+          case  8: mResource = R.raw.pyra3      ; break;
+          case  9: mResource = R.raw.pyra4      ; break;
+          case 10: mResource = R.raw.pyra5      ; break;
+          case 11: mResource = R.raw.dino       ; break;
+          case 12: mResource = R.raw.skewb      ; break;
           }
         }
       }
diff --git a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
index 48761f5..1188e7f 100644
--- a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
+++ b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
@@ -34,6 +34,7 @@ import org.distorted.library.effect.VertexEffectDeform;
 import org.distorted.library.effect.VertexEffectDisappear;
 import org.distorted.library.effect.VertexEffectMove;
 import org.distorted.library.effect.VertexEffectRotate;
+import org.distorted.library.effect.VertexEffectScale;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedLibrary;
@@ -43,6 +44,7 @@ import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshFile;
 import org.distorted.library.mesh.MeshJoined;
 import org.distorted.library.mesh.MeshPolygon;
+import org.distorted.library.mesh.MeshTriangle;
 import org.distorted.library.type.DynamicQuat;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
@@ -137,7 +139,7 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
       VertexEffectRotate.enable();
       VertexEffectDeform.enable();
 
-      DistortedLibrary.setMax(EffectType.VERTEX, 12);
+      DistortedLibrary.setMax(EffectType.VERTEX, 14);
 
       DistortedLibrary.onCreate(mView.getContext(), this);
       }
@@ -207,6 +209,7 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
                                                                          0xff0000ff,
                                                                          0xffff0000 };
                                    return createTetrahedronTexture(TET_COLORS4);
+          case  PROCEDURAL       :
           case  R.raw.predeform  : return createGridTexture(3);
           case  R.raw.cube2      :
           case  R.raw.cube3      :
@@ -218,7 +221,6 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
                                                                          0xffff0000,
                                                                          0xffb5651d };
                                    return createCubeTexture(CUBE_COLORS);
-          case  PROCEDURAL       :
           case  R.raw.pyra3      :
           case  R.raw.pyra4      :
           case  R.raw.pyra5      : final int[] TET_COLORS5 = new int[] { 0xffffff00,
@@ -235,6 +237,13 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
                                                                          0xffb5651d,
                                                                          0xff000000 };
                                    return createTetrahedronTexture(TET_COLORS7);
+          case R.raw.skewb       : final int[] SKEW_COLORS = new int[] { 0xffffff00,
+                                                                         0xffffffff,
+                                                                         0xff0000ff,
+                                                                         0xff00ff00,
+                                                                         0xffff0000,
+                                                                         0xffb5651d };
+                                   return createSkewbTexture(SKEW_COLORS);
           }
 
       return null;
@@ -339,10 +348,91 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
       return result;
       }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void createSkewbFaceTexture(Canvas canvas, Paint paint, int[] faceColors, int face, int left, int top, int side)
+    {
+    final int COLORS = 6;
+    final float SQ2 = (float)Math.sqrt(2);
+
+    if( face<COLORS )
+      {
+      float STROKE = 0.035f*side;
+      float L= left+0.125f*side;
+      float H= 0.375f*side;
+      float LEN = 0.5f*side;
+
+      paint.setAntiAlias(true);
+      paint.setStrokeWidth(STROKE);
+      paint.setColor(faceColors[face]);
+      paint.setStyle(Paint.Style.FILL);
+
+      canvas.drawRect(left,top,left+side,top+side,paint);
+
+      paint.setColor(0xff000000);
+      paint.setStyle(Paint.Style.STROKE);
+
+      canvas.drawLine( L    , H,  L+LEN, H    , paint);
+      canvas.drawLine( L    , H,  L+LEN, H+LEN, paint);
+      canvas.drawLine( L+LEN, H,  L+LEN, H+LEN, paint);
+
+      float S1 = 0.125f*side;
+      float S2 = 0.070f*side;
+      float X  = 0.7f*S2;
+
+      float LA = left+0.625f*side;
+      float RA = left+0.125f*side;
+      float TA = 0.375f*side;
+      float BA = 0.875f*side;
+
+      canvas.drawArc( LA-S1, TA     , LA     , TA+S1, 270, 90, false, paint);
+      canvas.drawArc( RA+X , TA     , RA+X+S2, TA+S2, 135,135, false, paint);
+      canvas.drawArc( LA-S2, BA-X-S2, LA     , BA-X ,   0,135, false, paint);
+      }
+    else
+      {
+      final float R = (SQ2/2)*side*0.10f;
+      final float M = side*(0.5f-SQ2/4+0.018f);
+
+      paint.setColor(faceColors[face-COLORS]);
+      paint.setStyle(Paint.Style.FILL);
+      canvas.drawRoundRect( left+M, top+M, left+side-M, top+side-M, R, R, paint);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private Bitmap createSkewbTexture(int[] faceColors)
+      {
+      final int TEXTURE_HEIGHT = 256;
+      final int NUM_TEXTURES = 2*6;
+      Bitmap bitmap;
+
+      Paint paint = new Paint();
+      bitmap = Bitmap.createBitmap( (NUM_TEXTURES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
+      Canvas canvas = new Canvas(bitmap);
+
+      paint.setAntiAlias(true);
+      paint.setTextAlign(Paint.Align.CENTER);
+      paint.setStyle(Paint.Style.FILL);
+
+      paint.setColor(0xff000000);
+      canvas.drawRect(0, 0, (NUM_TEXTURES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
+
+      for(int i=0; i<NUM_TEXTURES; i++)
+        {
+        createSkewbFaceTexture(canvas, paint, faceColors, i, i*TEXTURE_HEIGHT, 0, TEXTURE_HEIGHT);
+        }
+
+      return bitmap;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private MeshBase createStaticMesh()
     {
+    /*
     final float SQ2 = (float)Math.sqrt(2);
     final float SQ3 = (float)Math.sqrt(3);
     final float angleFaces = (float)((180/Math.PI)*(2*Math.asin(SQ3/3))); // angle between two faces of a tetrahedron
@@ -455,6 +545,133 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
     result.setTextureMap(maps,0);
     result.setShowNormals(true);
 
+    return result;
+     */
+    final float SQ2 = (float)Math.sqrt(2);
+    final float SQ3 = (float)Math.sqrt(3);
+
+    final int FACES_PER_CUBIT=6;
+
+    float D = 0.02f;
+    float E = 0.5f;
+    float F = SQ2/2;
+
+    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
+
+    float[] bands0 = { 1.0f    , 0,
+                       1.0f-2*D, D*0.25f,
+                       1.0f-4*D, D*0.35f,
+                       1.0f-8*D, D*0.6f,
+                       0.60f   , D*1.0f,
+                       0.30f   , D*1.375f,
+                       0.0f    , D*1.4f };
+
+    MeshBase[] meshes = new MeshBase[FACES_PER_CUBIT];
+
+    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
+    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[] vertices1 = { 0,0, F,0, F/2,(SQ3/2)*F };
+    float[] bands1 = { 1.0f, 0.0f, 0.0f, 0.0f };
+
+    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);
+
+    MeshBase result = new MeshJoined(meshes);
+
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisY  = new Static3D(0,1,0);
+    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
+    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
+    Static1D angle1 = new Static1D(+90);
+    Static1D angle2 = new Static1D(-90);
+    Static1D angle3 = new Static1D(-15);
+    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
+    Static1D angle5 = new Static1D(120);
+    Static1D angle6 = new Static1D(240);
+    Static3D center1= new Static3D(0,0,0);
+    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
+    Static3D move1  = new Static3D(-E/4,-E/4,0);
+    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
+
+    float d0 =-0.04f;
+    float d1 = 0.04f;
+    float r0 = 0.15f;
+    float r1 = 0.10f;
+
+    Static3D vec0   = new Static3D(d0*(+SQ3/3),d0*(+SQ3/3),d0*(+SQ3/3));
+    Static3D vec1   = new Static3D(d1*(+SQ3/3),d1*(-SQ3/3),d1*(-SQ3/3));
+    Static3D vec2   = new Static3D(d1*(-SQ3/3),d1*(+SQ3/3),d1*(-SQ3/3));
+    Static3D vec3   = new Static3D(d1*(-SQ3/3),d1*(-SQ3/3),d1*(+SQ3/3));
+
+    Static1D radius = new Static1D(0.5f);
+
+    Static3D cent0  = new Static3D( 0.0f, 0.0f, 0.0f);
+    Static3D cent1  = new Static3D(-0.5f, 0.0f, 0.0f);
+    Static3D cent2  = new Static3D( 0.0f,-0.5f, 0.0f);
+    Static3D cent3  = new Static3D( 0.0f, 0.0f,-0.5f);
+
+    Static4D reg0   = new Static4D(0,0,0,r0);
+    Static4D reg1   = new Static4D(0,0,0,r1);
+
+    VertexEffectMove   effect0 = new VertexEffectMove(move1);
+    VertexEffectScale  effect1 = new VertexEffectScale(new Static3D(1,1,-1));
+    VertexEffectRotate effect2 = new VertexEffectRotate(angle1,axisX,center1);
+    VertexEffectRotate effect3 = new VertexEffectRotate(angle2,axisY,center1);
+    VertexEffectMove   effect4 = new VertexEffectMove(move2);
+    VertexEffectRotate effect5 = new VertexEffectRotate(angle1,axisX,center2);
+    VertexEffectRotate effect6 = new VertexEffectRotate(angle3,axisY,center2);
+    VertexEffectRotate effect7 = new VertexEffectRotate(angle4,axis0,center2);
+    VertexEffectRotate effect8 = new VertexEffectRotate(angle5,axis1,center2);
+    VertexEffectRotate effect9 = new VertexEffectRotate(angle6,axis1,center2);
+
+    VertexEffectDeform effect10= new VertexEffectDeform(vec0,radius,cent0,reg0);
+    VertexEffectDeform effect11= new VertexEffectDeform(vec1,radius,cent1,reg1);
+    VertexEffectDeform effect12= new VertexEffectDeform(vec2,radius,cent2,reg1);
+    VertexEffectDeform effect13= new VertexEffectDeform(vec3,radius,cent3,reg1);
+
+    effect0.setMeshAssociation( 7,-1);  // meshes 0,1,2
+    effect1.setMeshAssociation( 6,-1);  // meshes 1,2
+    effect2.setMeshAssociation( 2,-1);  // mesh 1
+    effect3.setMeshAssociation( 4,-1);  // mesh 2
+    effect4.setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect5.setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect6.setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect7.setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect8.setMeshAssociation(16,-1);  // mesh 4
+    effect9.setMeshAssociation(32,-1);  // mesh 5
+
+    effect10.setMeshAssociation(63,-1); // all meshes
+    effect11.setMeshAssociation(63,-1); // all meshes
+    effect12.setMeshAssociation(63,-1); // all meshes
+    effect13.setMeshAssociation(63,-1); // all meshes
+
+    result.apply(effect0);
+    result.apply(effect1);
+    result.apply(effect2);
+    result.apply(effect3);
+    result.apply(effect4);
+    result.apply(effect5);
+    result.apply(effect6);
+    result.apply(effect7);
+    result.apply(effect8);
+    result.apply(effect9);
+    result.apply(effect10);
+
+    result.apply(effect11);
+    result.apply(effect12);
+    result.apply(effect13);
+
+//result.setShowNormals(true);
+
     return result;
     }
 
diff --git a/src/main/res/raw/skewb.dmesh b/src/main/res/raw/skewb.dmesh
new file mode 100644
index 0000000..752ba10
Binary files /dev/null and b/src/main/res/raw/skewb.dmesh differ
