commit 6991ece532c1d890e0a2f5b2efcf70599d9e68a0
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu Sep 10 15:03:52 2020 +0100

    Add possibility to display also a procedurally created Mesh in MeshFile.

diff --git a/src/main/java/org/distorted/examples/TableOfContents.java b/src/main/java/org/distorted/examples/TableOfContents.java
index fbe2825..cbd6c5c 100644
--- a/src/main/java/org/distorted/examples/TableOfContents.java
+++ b/src/main/java/org/distorted/examples/TableOfContents.java
@@ -86,6 +86,9 @@ public class TableOfContents extends ListActivity
 
   private enum Application
     {
+    MESHFILE          (R.drawable.icon_example_meshfile        , R.string.example_meshfile           , R.string.example_meshfile_subtitle           ,            MeshFileActivity.class),
+
+
     MONALISA          (R.drawable.icon_example_monalisa        , R.string.example_monalisa        , R.string.example_monalisa_subtitle        ,         MonaLisaActivity.class),
     SINK              (R.drawable.icon_example_sink            , R.string.example_sink            , R.string.example_sink_subtitle            ,             SinkActivity.class),
     BEAN              (R.drawable.icon_example_bean            , R.string.example_bean            , R.string.example_bean_subtitle            ,             BeanActivity.class),
@@ -126,7 +129,6 @@ public class TableOfContents extends ListActivity
     PREDEFORM         (R.drawable.icon_example_predeform       , R.string.example_predeform           , R.string.example_predeform_subtitle           ,            PredeformActivity.class),
     DEFERREDJOB       (R.drawable.icon_example_deferredjob     , R.string.example_deferredjob           , R.string.example_deferredjob_subtitle           ,            DeferredJobActivity.class),
     SINGLEMESH        (R.drawable.icon_example_singlemesh      , R.string.example_singlemesh           , R.string.example_singlemesh_subtitle           ,            SingleMeshActivity.class),
-    MESHFILE          (R.drawable.icon_example_meshfile        , R.string.example_meshfile           , R.string.example_meshfile_subtitle           ,            MeshFileActivity.class),
     ;
 
     final int icon, title, subtitle;
diff --git a/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java b/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
index f850676..03c830a 100644
--- a/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
+++ b/src/main/java/org/distorted/examples/meshfile/MeshFileActivity.java
@@ -34,13 +34,15 @@ import android.widget.ToggleButton;
 
 import org.distorted.examples.R;
 import org.distorted.library.main.DistortedLibrary;
-import org.distorted.library.mesh.MeshFile;
+import org.distorted.library.mesh.MeshBase;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class MeshFileActivity extends Activity implements AdapterView.OnItemSelectedListener,
                                                           SeekBar.OnSeekBarChangeListener
 {
+    final static int PROCEDURAL = -1;
+
     private LinearLayout mLayout;
     private int mResource;
     private String[] mNames = new String[] { "deferredjob",
@@ -53,7 +55,8 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
                                              "pyra3"      ,
                                              "pyra4"      ,
                                              "pyra5"      ,
-                                             "dino"
+                                             "dino"       ,
+                                             "procedural"
                                            };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -164,7 +167,7 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
           {
           MeshFileSurfaceView view = findViewById(R.id.meshfileSurfaceView);
           MeshFileRenderer renderer = view.getRenderer();
-          MeshFile mesh = renderer.getMesh();
+          MeshBase mesh = renderer.getMesh();
           mesh.setEffectAssociation(component,isChecked ? 1:0,component);
           }
         }) ;
@@ -191,6 +194,7 @@ public class MeshFileActivity extends Activity implements AdapterView.OnItemSele
           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;
           }
         }
       }
diff --git a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
index 2cd49e7..f6ac7bd 100644
--- a/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
+++ b/src/main/java/org/distorted/examples/meshfile/MeshFileRenderer.java
@@ -27,15 +27,24 @@ import android.graphics.Paint;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.examples.R;
+import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
+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.VertexEffectSink;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
+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.type.DynamicQuat;
+import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
@@ -46,6 +55,8 @@ import java.io.InputStream;
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
+import static org.distorted.examples.meshfile.MeshFileActivity.PROCEDURAL;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
@@ -59,7 +70,7 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
     private Static3D mScale;
     private long mTime;
     private float mCurrentScale;
-    private MeshFile mMesh;
+    private MeshBase mMesh;
 
     Static4D mQuat1, mQuat2;
     int mScreenMin;
@@ -123,6 +134,11 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
       VertexEffectDisappear.enable();
 
+      VertexEffectRotate.enable();
+      VertexEffectDeform.enable();
+
+      DistortedLibrary.setMax(EffectType.VERTEX, 12);
+
       DistortedLibrary.onCreate(mView.getContext(), this);
       }
 
@@ -161,7 +177,16 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
       mTexture.setTexture( createTexture(resourceID) );
 
       long t1 = System.currentTimeMillis();
-      createMesh(resourceID);
+
+      if( resourceID!=PROCEDURAL )
+        {
+        openMesh(resourceID);
+        }
+      else
+        {
+        createMesh();
+        }
+
       long t2 = System.currentTimeMillis();
 
       mTime = t2-t1;
@@ -193,6 +218,7 @@ 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,
@@ -269,19 +295,23 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
     private Bitmap createTetrahedronTexture(int[] faceColors)
       {
+      final float SQ3 = (float)Math.sqrt(3);
       final int FACES=faceColors.length;
-      int SIZE = 200;
+      int SIZE = 256;
       float STROKE = 0.05f*SIZE;
       float OFF = STROKE/2 -1;
       float OFF2 = 0.5f*SIZE + OFF;
       float HEIGHT = SIZE - OFF;
-      float RADIUS = SIZE/12;
+      float RADIUS = SIZE/12.0f;
       float ARC1_H = 0.2f*SIZE;
       float ARC1_W = SIZE*0.5f;
       float ARC2_W = 0.153f*SIZE;
       float ARC2_H = 0.905f*SIZE;
       float ARC3_W = SIZE-ARC2_W;
 
+      float M = SQ3/2;
+      float D = (M/2 - 0.51f)*SIZE;
+
       Bitmap result = Bitmap.createBitmap(FACES*SIZE,SIZE, Bitmap.Config.ARGB_8888);
       Canvas canvas = new Canvas(result);
       Paint paint = new Paint();
@@ -298,21 +328,153 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
         paint.setColor(0xff000000);
         paint.setStyle(Paint.Style.STROKE);
 
-        canvas.drawLine(           i*SIZE, HEIGHT,  SIZE       +i*SIZE, HEIGHT, paint);
-        canvas.drawLine(      OFF +i*SIZE,   SIZE,       OFF2  +i*SIZE,      0, paint);
-        canvas.drawLine((SIZE-OFF)+i*SIZE,   SIZE, (SIZE-OFF2) +i*SIZE,      0, paint);
+        canvas.drawLine(           i*SIZE, M*HEIGHT+D,  SIZE       +i*SIZE, M*HEIGHT+D, paint);
+        canvas.drawLine(      OFF +i*SIZE, M*SIZE  +D,       OFF2  +i*SIZE,          D, paint);
+        canvas.drawLine((SIZE-OFF)+i*SIZE, M*SIZE  +D, (SIZE-OFF2) +i*SIZE,          D, paint);
 
-        canvas.drawArc( ARC1_W-RADIUS+i*SIZE, ARC1_H-RADIUS, ARC1_W+RADIUS+i*SIZE, ARC1_H+RADIUS, 225, 90, false, paint);
-        canvas.drawArc( ARC2_W-RADIUS+i*SIZE, ARC2_H-RADIUS, ARC2_W+RADIUS+i*SIZE, ARC2_H+RADIUS, 105, 90, false, paint);
-        canvas.drawArc( ARC3_W-RADIUS+i*SIZE, ARC2_H-RADIUS, ARC3_W+RADIUS+i*SIZE, ARC2_H+RADIUS, 345, 90, false, paint);
+        canvas.drawArc( ARC1_W-RADIUS+i*SIZE, M*(ARC1_H-RADIUS)+D, ARC1_W+RADIUS+i*SIZE, M*(ARC1_H+RADIUS)+D, 225, 90, false, paint);
+        canvas.drawArc( ARC2_W-RADIUS+i*SIZE, M*(ARC2_H-RADIUS)+D, ARC2_W+RADIUS+i*SIZE, M*(ARC2_H+RADIUS)+D, 105, 90, false, paint);
+        canvas.drawArc( ARC3_W-RADIUS+i*SIZE, M*(ARC2_H-RADIUS)+D, ARC3_W+RADIUS+i*SIZE, M*(ARC2_H+RADIUS)+D, 345, 90, false, paint);
         }
 
       return result;
       }
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  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
+    final int MESHES=4;
+
+    int association = 1;
+    MeshBase[] meshes;
+
+    float D = 0.0003f;
+    float E = SQ3/2 - 3*D*SQ2;
+    float F = 0.5f - D*SQ2*SQ3;
+
+    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
+    float[] bands = new float[] {    1.0f    ,-D,
+                                     1.0f  -D,-D*0.80f,
+                                     1.0f-2*D,-D*0.65f,
+                                     1.0f-4*D,+D*0.10f,
+                                     0.50f, 0.035f,
+                                     0.0f, 0.040f };
+
+    meshes = new MeshPolygon[MESHES];
+    meshes[0] = new MeshPolygon(vertices, bands, 2,2);
+    meshes[0].setEffectAssociation(0,association,0);
+
+    for(int i=1; i<MESHES; i++)
+      {
+      association <<= 1;
+      meshes[i] = meshes[0].copy(true);
+      meshes[i].setEffectAssociation(0,association,0);
+      }
+
+    MeshBase result = new MeshJoined(meshes);
+
+    Static3D a0 = new Static3D(         0,        1,       0 );
+    Static3D a1 = new Static3D(         0,  -1.0f/3, 2*SQ2/3 );
+    Static3D a2 = new Static3D(-SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 );
+    Static3D a3 = new Static3D( SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 );
+
+    float tetraHeight = SQ2*SQ3/3;
+    float d1 = (0.75f-2*SQ2*D)*tetraHeight;
+    float d2 =-0.06f*tetraHeight;
+    float d3 = 0.05f*tetraHeight;
+    float d4 = 0.70f*tetraHeight;
+    float d5 = 1.2f;
+
+    Static3D dCen0 = new Static3D( d1*a0.get0(), d1*a0.get1(), d1*a0.get2() );
+    Static3D dCen1 = new Static3D( d1*a1.get0(), d1*a1.get1(), d1*a1.get2() );
+    Static3D dCen2 = new Static3D( d1*a2.get0(), d1*a2.get1(), d1*a2.get2() );
+    Static3D dCen3 = new Static3D( d1*a3.get0(), d1*a3.get1(), d1*a3.get2() );
+
+    Static3D dVec0 = new Static3D( d2*a0.get0(), d2*a0.get1(), d2*a0.get2() );
+    Static3D dVec1 = new Static3D( d2*a1.get0(), d2*a1.get1(), d2*a1.get2() );
+    Static3D dVec2 = new Static3D( d2*a2.get0(), d2*a2.get1(), d2*a2.get2() );
+    Static3D dVec3 = new Static3D( d2*a3.get0(), d2*a3.get1(), d2*a3.get2() );
+
+    Static4D dReg  = new Static4D(0,0,0,d3);
+    Static1D dRad  = new Static1D(1);
+    Static3D center= new Static3D(0,0,0);
+    Static4D sReg  = new Static4D(0,0,0,d4);
+    Static1D sink  = new Static1D(d5);
+
+    Static1D angle  = new Static1D(angleFaces);
+    Static3D axis1  = new Static3D(  -1, 0,      0);
+    Static3D axis2  = new Static3D(0.5f, 0, -SQ3/2);
+    Static3D axis3  = new Static3D(0.5f, 0, +SQ3/2);
+    Static3D center1= new Static3D(0,-SQ3*SQ2/12,-SQ3/6);
+    Static3D center2= new Static3D(0,-SQ3*SQ2/12,+SQ3/3);
+
+    VertexEffectRotate  effect1 = new VertexEffectRotate( new Static1D(90), new Static3D(1,0,0), center );
+    VertexEffectMove    effect2 = new VertexEffectMove  ( new Static3D(0,-SQ3*SQ2/12,0) );
+    VertexEffectRotate  effect3 = new VertexEffectRotate( new Static1D(180), new Static3D(0,0,1), center1 );
+    VertexEffectRotate  effect4 = new VertexEffectRotate( angle, axis1, center1 );
+    VertexEffectRotate  effect5 = new VertexEffectRotate( angle, axis2, center2 );
+    VertexEffectRotate  effect6 = new VertexEffectRotate( angle, axis3, center2 );
+
+    VertexEffectDeform  effect7 = new VertexEffectDeform(dVec0, dRad, dCen0, dReg);
+    VertexEffectDeform  effect8 = new VertexEffectDeform(dVec1, dRad, dCen1, dReg);
+    VertexEffectDeform  effect9 = new VertexEffectDeform(dVec2, dRad, dCen2, dReg);
+    VertexEffectDeform  effect10= new VertexEffectDeform(dVec3, dRad, dCen3, dReg);
+
+    VertexEffectSink    effect11= new VertexEffectSink(sink,center, sReg);
+
+    effect3.setMeshAssociation(14,-1);  // apply to mesh[1], [2] and [3]
+    effect4.setMeshAssociation( 2,-1);  // apply only to mesh[1]
+    effect5.setMeshAssociation( 4,-1);  // apply only to mesh[2]
+    effect6.setMeshAssociation( 8,-1);  // apply only to mesh[3]
+
+    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);
+
+    final float ratio = 0.2f;
+    final Static4D[] maps = new Static4D[MESHES];
+
+    for(int mesh=0; mesh<MESHES; mesh++)
+      {
+      maps[mesh] = new Static4D( mesh*ratio, 0.0f, ratio, 1.0f);
+      }
+
+    result.setTextureMap(maps,0);
+    result.setShowNormals(true);
+
+    return result;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private void createMesh()
+      {
+      mMesh = createStaticMesh();
+
+      int numEff = mMesh.numEffComponents();
+
+      for(int i=0; i<numEff; i++)
+        {
+        mMesh.setEffectAssociation(i, 0, i);
+        }
+      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private void createMesh(int resourceID)
+    private void openMesh(int resourceID)
       {
       Context con = mView.getContext();
       Resources res = con.getResources();
@@ -339,7 +501,7 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    MeshFile getMesh()
+    MeshBase getMesh()
       {
       return mMesh;
       }
@@ -355,7 +517,12 @@ class MeshFileRenderer implements GLSurfaceView.Renderer, DistortedLibrary.Excep
 
     int getBytes()
       {
-      return mMesh.getNumBytes();
+      if( mMesh instanceof MeshFile )
+        {
+        return ((MeshFile)mMesh).getNumBytes();
+        }
+
+      return 0;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
