commit ccf9fec5a91575885dd75ff0064eb1a1cb479e5d
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Jun 13 23:43:59 2020 +0100

    Read the meshes from .dmesh files (rather than compute them dynamically).
    This (along with single-mesh mode) hopefully makes the rendering much faster, while keeping the time needed for Object Change low.
    
    The only downside: this increases the size of the release APK from 6 MB to 9.6 MB.

diff --git a/src/main/java/org/distorted/main/RubikPreRender.java b/src/main/java/org/distorted/main/RubikPreRender.java
index f09a07b8..10bf4df9 100644
--- a/src/main/java/org/distorted/main/RubikPreRender.java
+++ b/src/main/java/org/distorted/main/RubikPreRender.java
@@ -19,7 +19,9 @@
 
 package org.distorted.main;
 
+import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.res.Resources;
 import android.os.Bundle;
 
 import org.distorted.dialogs.RubikDialogNewRecord;
@@ -102,7 +104,10 @@ public class RubikPreRender implements EffectListener
     if( mOldObject!=null ) mOldObject.releaseResources();
     mOldObject = mNewObject;
 
-    mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves);
+    Context con = mView.getContext();
+    Resources res = con.getResources();
+
+    mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves, res);
 
     if( mNewObject!=null )
       {
diff --git a/src/main/java/org/distorted/objects/RubikCube.java b/src/main/java/org/distorted/objects/RubikCube.java
index 13f676a4..8d90c2e7 100644
--- a/src/main/java/org/distorted/objects/RubikCube.java
+++ b/src/main/java/org/distorted/objects/RubikCube.java
@@ -19,6 +19,7 @@
 
 package org.distorted.objects;
 
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 
@@ -98,9 +99,10 @@ class RubikCube extends RubikObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, int[][] moves)
+  RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture,
+            MeshRectangles mesh, DistortedEffects effects, int[][] moves, Resources res)
     {
-    super(size, 60, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.CUBE);
+    super(size, 60, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.CUBE, res);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/RubikObject.java b/src/main/java/org/distorted/objects/RubikObject.java
index 149abadb..9b46d935 100644
--- a/src/main/java/org/distorted/objects/RubikObject.java
+++ b/src/main/java/org/distorted/objects/RubikObject.java
@@ -20,6 +20,7 @@
 package org.distorted.objects;
 
 import android.content.SharedPreferences;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -27,7 +28,6 @@ import android.graphics.Paint;
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.VertexEffectQuaternion;
@@ -36,7 +36,7 @@ import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.mesh.MeshJoined;
+import org.distorted.library.mesh.MeshFile;
 import org.distorted.library.mesh.MeshRectangles;
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.type.Dynamic1D;
@@ -44,6 +44,10 @@ import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
 
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public abstract class RubikObject extends DistortedNode
@@ -87,7 +91,7 @@ public abstract class RubikObject extends DistortedNode
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   RubikObject(int size, int fov, Static4D quatCur, Static4D quatAcc, DistortedTexture nodeTexture,
-              MeshRectangles nodeMesh, DistortedEffects nodeEffects, int[][] moves, RubikObjectList list)
+              MeshRectangles nodeMesh, DistortedEffects nodeEffects, int[][] moves, RubikObjectList list, Resources res)
     {
     super(nodeTexture,nodeEffects,nodeMesh);
 
@@ -125,20 +129,29 @@ public abstract class RubikObject extends DistortedNode
 
     mCubits = new Cubit[NUM_CUBITS];
     mTexture = new DistortedTexture();
-    MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS];
+
+    int sizeIndex = RubikObjectList.getSizeIndex(list.ordinal(),mSize);
+    int resourceID= list.getResourceIDs()[sizeIndex];
+
+    InputStream is = res.openRawResource(resourceID);
+    DataInputStream dos = new DataInputStream(is);
+    mMesh = new MeshFile(dos);
+
+    try
+      {
+      is.close();
+      }
+    catch(IOException e)
+      {
+      android.util.Log.e("meshFile", "Error closing InputStream: "+e.toString());
+      }
 
     for(int i=0; i<NUM_CUBITS; i++)
       {
       mCubits[i] = new Cubit(this,mOrigPos[i]);
-      cubitMesh[i] = createCubitMesh(i);
-      cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0);
-      cubitMesh[i].setEffectAssociation(0, mCubits[i].computeAssociation(), 0);
+      mMesh.setEffectAssociation(i, mCubits[i].computeAssociation(), 0);
       }
 
-    mMesh = new MeshJoined(cubitMesh);
-
-    resetAllTextureMaps();
-
     mEffects = new DistortedEffects();
 
     int num_quats = QUATS.length;
diff --git a/src/main/java/org/distorted/objects/RubikObjectList.java b/src/main/java/org/distorted/objects/RubikObjectList.java
index 15543ff2..715e4d32 100644
--- a/src/main/java/org/distorted/objects/RubikObjectList.java
+++ b/src/main/java/org/distorted/objects/RubikObjectList.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objects;
 
+import android.content.res.Resources;
+
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshRectangles;
@@ -33,10 +35,10 @@ public enum RubikObjectList
   {
   CUBE (
          new int[][] {
-                       {2 , 12, R.drawable.cube2} ,
-                       {3 , 16, R.drawable.cube3} ,
-                       {4 , 20, R.drawable.cube4} ,
-                       {5 , 24, R.drawable.cube5}
+                       {2 , 12, R.drawable.cube2, R.raw.cube2} ,
+                       {3 , 16, R.drawable.cube3, R.raw.cube3} ,
+                       {4 , 20, R.drawable.cube4, R.raw.cube4} ,
+                       {5 , 24, R.drawable.cube5, R.raw.cube5}
                      },
          RubikCube.class,
          new RubikCubeMovement()
@@ -44,9 +46,9 @@ public enum RubikObjectList
 
   PYRA (
          new int[][] {
-                       {3 , 10, R.drawable.pyra3} ,
-                       {4 , 15, R.drawable.pyra4} ,
-                       {5 , 20, R.drawable.pyra5}
+                       {3 , 10, R.drawable.pyra3, R.raw.pyra3} ,
+                       {4 , 15, R.drawable.pyra4, R.raw.pyra4} ,
+                       {5 , 20, R.drawable.pyra5, R.raw.pyra5}
                      },
          RubikPyraminx.class,
          new RubikPyraminxMovement()
@@ -58,7 +60,7 @@ public enum RubikObjectList
   public static final int MAX_LEVEL;
   public static final int MAX_OBJECT_SIZE;
 
-  private final int[] mObjectSizes, mMaxLevels, mIconIDs;
+  private final int[] mObjectSizes, mMaxLevels, mIconIDs, mResourceIDs;
   private final Class<? extends RubikObject> mObjectClass;
   private final RubikObjectMovement mObjectMovementClass;
   private static final RubikObjectList[] objects;
@@ -276,12 +278,14 @@ public enum RubikObjectList
     mObjectSizes= new int[length];
     mMaxLevels  = new int[length];
     mIconIDs    = new int[length];
+    mResourceIDs= new int[length];
 
     for(int i=0; i<length; i++)
       {
       mObjectSizes[i] = info[i][0];
       mMaxLevels[i]   = info[i][1];
       mIconIDs[i]     = info[i][2];
+      mResourceIDs[i] = info[i][3];
       }
 
     mObjectClass         = object;
@@ -311,7 +315,14 @@ public enum RubikObjectList
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public RubikObject create(int size, Static4D quatCur, Static4D quatAcc, int[][] moves)
+  public int[] getResourceIDs()
+    {
+    return mResourceIDs;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public RubikObject create(int size, Static4D quatCur, Static4D quatAcc, int[][] moves, Resources res)
     {
     DistortedTexture texture = new DistortedTexture();
     DistortedEffects effects = new DistortedEffects();
@@ -319,8 +330,8 @@ public enum RubikObjectList
 
     switch(ordinal())
       {
-      case 0: return new RubikCube    (size, quatCur, quatAcc, texture, mesh, effects, moves);
-      case 1: return new RubikPyraminx(size, quatCur, quatAcc, texture, mesh, effects, moves);
+      case 0: return new RubikCube    (size, quatCur, quatAcc, texture, mesh, effects, moves, res);
+      case 1: return new RubikPyraminx(size, quatCur, quatAcc, texture, mesh, effects, moves, res);
       }
 
     return null;
diff --git a/src/main/java/org/distorted/objects/RubikPyraminx.java b/src/main/java/org/distorted/objects/RubikPyraminx.java
index 468b84ef..eee28109 100644
--- a/src/main/java/org/distorted/objects/RubikPyraminx.java
+++ b/src/main/java/org/distorted/objects/RubikPyraminx.java
@@ -19,6 +19,7 @@
 
 package org.distorted.objects;
 
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 
@@ -98,9 +99,10 @@ public class RubikPyraminx extends RubikObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  RubikPyraminx(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects, int[][] moves)
+  RubikPyraminx(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture,
+                MeshRectangles mesh, DistortedEffects effects, int[][] moves, Resources res)
     {
-    super(size, 30, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.PYRA);
+    super(size, 30, quatCur,quatAcc,texture,mesh,effects,moves, RubikObjectList.PYRA, res);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/res/raw/cube2.dmesh b/src/main/res/raw/cube2.dmesh
new file mode 100644
index 00000000..6b19af78
Binary files /dev/null and b/src/main/res/raw/cube2.dmesh differ
diff --git a/src/main/res/raw/cube3.dmesh b/src/main/res/raw/cube3.dmesh
new file mode 100644
index 00000000..82ceaf3e
Binary files /dev/null and b/src/main/res/raw/cube3.dmesh differ
diff --git a/src/main/res/raw/cube4.dmesh b/src/main/res/raw/cube4.dmesh
new file mode 100644
index 00000000..1401fcd7
Binary files /dev/null and b/src/main/res/raw/cube4.dmesh differ
diff --git a/src/main/res/raw/cube5.dmesh b/src/main/res/raw/cube5.dmesh
new file mode 100644
index 00000000..ffed8ab8
Binary files /dev/null and b/src/main/res/raw/cube5.dmesh differ
diff --git a/src/main/res/raw/pyra3.dmesh b/src/main/res/raw/pyra3.dmesh
new file mode 100644
index 00000000..c6e594a9
Binary files /dev/null and b/src/main/res/raw/pyra3.dmesh differ
diff --git a/src/main/res/raw/pyra4.dmesh b/src/main/res/raw/pyra4.dmesh
new file mode 100644
index 00000000..b80e240d
Binary files /dev/null and b/src/main/res/raw/pyra4.dmesh differ
diff --git a/src/main/res/raw/pyra5.dmesh b/src/main/res/raw/pyra5.dmesh
new file mode 100644
index 00000000..e4ce5bde
Binary files /dev/null and b/src/main/res/raw/pyra5.dmesh differ
