commit d6994cc6b55099464b0c0dd38b07b0634f69e556
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Tue Jan 17 23:12:05 2017 +0000

    Correct construction of boundingVertices in MeshCubes.

diff --git a/src/main/java/org/distorted/library/MeshCubes.java b/src/main/java/org/distorted/library/MeshCubes.java
index 6d5df7d..a89927c 100644
--- a/src/main/java/org/distorted/library/MeshCubes.java
+++ b/src/main/java/org/distorted/library/MeshCubes.java
@@ -64,7 +64,7 @@ public class MeshCubes extends MeshObject
      }
    
    private int mCols, mRows;
-   private short[][] mCubes;
+   private int[][] mCubes;
    private ArrayList<Edge> mEdges = new ArrayList<>();
 
    private int remainingVert;
@@ -161,7 +161,7 @@ public class MeshCubes extends MeshObject
 
      return ret;
      }
-*/  
+*/
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /*
    private static String debug(Edge e)
@@ -194,17 +194,18 @@ public class MeshCubes extends MeshObject
        mCols = cols;
        mRows = desc.length()/cols;
 
-       mCubes = new short[mRows][mCols];
+       mCubes = new int[mRows][mCols];
        
        for(int j=0; j<mCols; j++)
          for(int i=0; i<mRows; i++)
-           mCubes[i][j] = (short)(desc.charAt(i*mCols+j) == '1' ? 1:0);
-       
+           mCubes[i][j] = (desc.charAt(i*mCols+j) == '1' ? 1:0);
+
+       buildBoundingVert(frontOnly);
+
        markRegions();
        dataLength = computeDataLength(frontOnly);
 
        remainingVert = dataLength;
-       buildBoundingVert(mCubes,frontOnly);
        }
      }
 
@@ -219,11 +220,11 @@ public class MeshCubes extends MeshObject
 
      if( cols>0 && rows>0 )
        {
-       mCubes = new short[mRows][mCols];
+       mCubes = new int[mRows][mCols];
 
        for(int j=0; j<mCols; j++)
          for(int i=0; i<mRows; i++)
-           mCubes[i][j] = (short)1;
+           mCubes[i][j] = 1;
 
        markRegions();
        dataLength = computeDataLength(frontOnly);
@@ -236,47 +237,62 @@ public class MeshCubes extends MeshObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private float retLeftmost(short[][] cubes, int row)
+  private float retRightmost(int row)
     {
+    if( row==0 )
+      {
+      for(int i=mCols-1; i>=0; i--)
+        if( mCubes[0][i]==1 )
+          return (float)(i+1);
+      }
+    else if(row==mRows)
+      {
+      for(int i=mCols-1; i>=0; i--)
+        if( mCubes[mRows-1][i]==1 )
+          return (float)(i+1);
+      }
+    else
+      {
+      for(int i=mCols-1; i>=0; i--)
+        if( mCubes[row][i]==1 || mCubes[row-1][i]==1 )
+          return (float)(i+1);
+      }
 
     return 0.0f;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
- private float retRightmost(short[][] cubes, int row)
+ private float retLeftmost(int row)
     {
     if( row==0 )
       {
       for(int i=0; i<mCols; i++)
-        {
-
-        }
+        if( mCubes[0][i]==1 )
+          return (float)i;
       }
     else if(row==mRows)
       {
       for(int i=0; i<mCols; i++)
-        {
-
-        }
+        if( mCubes[mRows-1][i]==1 )
+          return (float)i;
       }
     else
       {
       for(int i=0; i<mCols; i++)
-        {
-
-        }
+        if( mCubes[row][i]==1 || mCubes[row-1][i]==1 )
+          return (float)i;
       }
 
-    return 0.0f;
+    return (float)mCols;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int addLeftmost(float[] temp, short[][] cubes, int row, int index)
+  private int addLeftmost(float[] temp, int row, int index)
     {
-    float x2 = retLeftmost(cubes,row);
-    float y2 = row/mRows - 0.5f;
+    float x2 = retLeftmost(row)/mCols - 0.5f;
+    float y2 = (float)row      /mRows - 0.5f;
 
     if( index>1 )
       {
@@ -285,25 +301,30 @@ public class MeshCubes extends MeshObject
       float x1 = temp[2*index-2];
       float y1 = temp[2*index-1];
 
-      if( (x0-x2)*(y0-y1) <= (x0-x1)*(y0-y2) )
+      while( (x0-x2)*(y0-y1) <= (x0-x1)*(y0-y2) )
         {
-        temp[2*index-2] = x2;
-        temp[2*index-1] = y2;
-        return index;
+        if( --index>1 )
+          {
+          x1 = x0;
+          y1 = y0;
+          x0 = temp[2*index-4];
+          y0 = temp[2*index-3];
+          }
+        else break;
         }
       }
 
-    temp[2*index+0] = x2;
+    temp[2*index  ] = x2;
     temp[2*index+1] = y2;
     return index+1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int addRightmost(float[] temp, short[][] cubes, int row, int index)
+  private int addRightmost(float[] temp, int row, int index)
     {
-    float x2 = retRightmost(cubes,row);
-    float y2 = row/mRows - 0.5f;
+    float x2 = retRightmost(row)/mCols - 0.5f;
+    float y2 = (float)row       /mRows - 0.5f;
 
     if( index>1 )
       {
@@ -312,15 +333,20 @@ public class MeshCubes extends MeshObject
       float x1 = temp[2*index-2];
       float y1 = temp[2*index-1];
 
-      if( (x0-x2)*(y0-y1) >= (x0-x1)*(y0-y2) )
+      while( (x0-x2)*(y0-y1) >= (x0-x1)*(y0-y2) )
         {
-        temp[2*index-2] = x2;
-        temp[2*index-1] = y2;
-        return index;
+        if( --index>1 )
+          {
+          x1 = x0;
+          y1 = y0;
+          x0 = temp[2*index-4];
+          y0 = temp[2*index-3];
+          }
+        else break;
         }
       }
 
-    temp[2*index+0] = x2;
+    temp[2*index  ] = x2;
     temp[2*index+1] = y2;
     return index+1;
     }
@@ -329,18 +355,45 @@ public class MeshCubes extends MeshObject
 // fill up the mBoundingVert array with the smallest set of vertices which form the same convex hull
 // like the whole thing.
 
-  private void buildBoundingVert(short[][] cubes, boolean frontOnly)
+  private void buildBoundingVert(boolean frontOnly)
     {
     int lVert=0, rVert=0;
-    float[] tempL = new float[2*(mRows+1)];
-    float[] tempR = new float[2*(mRows+1)];
+    int firstRow=0, lastRow=mRows-1;
 
-    for(int i=0; i<=mRows; i++)
+    for(int i=0; i<mRows; i++)
+      for(int j=0; j<mCols; j++)
+        if(mCubes[i][j] !=0 )
+          {
+          firstRow = i;
+          i=mRows;
+          j=mCols;
+          }
+
+    for(int i=mRows-1; i>=0; i--)
+      for(int j=0; j<mCols; j++)
+        if(mCubes[i][j] !=0 )
+          {
+          lastRow = i;
+          i=-1;
+          j=mCols;
+          }
+
+//android.util.Log.d("cubes", "first :"+firstRow+" last: "+lastRow);
+
+    int numLines = lastRow-firstRow+2;
+
+    float[] tempL = new float[2*numLines];
+    float[] tempR = new float[2*numLines];
+
+    for(int i=firstRow; i<=lastRow+1; i++)
       {
-      lVert = addLeftmost (tempL,cubes,i,lVert);
-      rVert = addRightmost(tempR,cubes,i,rVert);
+      lVert = addLeftmost (tempL,i,lVert);
+      rVert = addRightmost(tempR,i,rVert);
       }
 
+//android.util.Log.d("cubes", "LEFT :"+debug(tempL,2));
+//android.util.Log.d("cubes", "RIGHT:"+debug(tempR,2));
+
     int numVert = lVert+rVert;
 
     mBoundingVert = new float[ numVert*(frontOnly ? 3:6) ];
@@ -368,6 +421,8 @@ public class MeshCubes extends MeshObject
         mBoundingVert[3*(i+numVert)+2] = BACKZ;
         }
       }
+
+//android.util.Log.d("cubes", "VERT:"+debug(mBoundingVert,3));
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -451,7 +506,7 @@ public class MeshCubes extends MeshObject
    
    private void markRegion(short newVal, int row, int col)
      {
-     short val = mCubes[row][col];
+     int val = mCubes[row][col];
      mCubes[row][col] = newVal;
      
      if( row>0       && mCubes[row-1][col  ]==val ) markRegion(newVal, row-1, col  );
@@ -560,7 +615,7 @@ public class MeshCubes extends MeshObject
 
    private int buildFrontBackGrid(boolean front, int vertex, float[] position, float[] normal, float[] texture)
      {
-     short last, current;
+     int last, current;
      boolean seenLand=false;
      boolean lastBlockIsNE = false;
      boolean currentBlockIsNE;
