Project

General

Profile

« Previous | Next » 

Revision 80cb15ab

Added by Leszek Koltunski almost 7 years ago

Change of API in anticipation for MeshCubes of any depth (currently only 0 and 1 work)

View differences:

src/main/java/org/distorted/library/MeshCubes.java
63 63
       }
64 64
     }
65 65
   
66
   private int mCols, mRows;
66
   private int mCols, mRows, mSlices;
67 67
   private int[][] mCubes;
68 68
   private ArrayList<Edge> mEdges = new ArrayList<>();
69 69

  
......
72 72
   private int mEdgeNum;
73 73
   private int mSideWalls;
74 74

  
75
   private float[] mBoundingVert;
76

  
77
   private static float[] mBoundingVert1 = new float[] { -0.5f,+0.5f, FRONTZ,
78
                                                         -0.5f,-0.5f, FRONTZ,
79
                                                         +0.5f,+0.5f, FRONTZ,
80
                                                         +0.5f,-0.5f, FRONTZ };
81

  
82
   private static float[] mBoundingVert2 = new float[] { -0.5f,+0.5f, FRONTZ,
83
                                                         -0.5f,-0.5f, FRONTZ,
84
                                                         +0.5f,+0.5f, FRONTZ,
85
                                                         +0.5f,-0.5f, FRONTZ,
86
                                                         -0.5f,+0.5f, BACKZ ,
87
                                                         -0.5f,-0.5f, BACKZ ,
88
                                                         +0.5f,+0.5f, BACKZ ,
89
                                                         +0.5f,-0.5f, BACKZ  };
90

  
91 75
///////////////////////////////////////////////////////////////////////////////////////////////////
92 76
// a Block is split into two triangles along the NE-SW line iff it is in the top-right
93 77
// or bottom-left quadrant of the grid.
......
100 84
///////////////////////////////////////////////////////////////////////////////////////////////////
101 85
// return the number of vertices our grid will contain
102 86

  
103
   private int computeDataLength(boolean frontOnly)
87
   private int computeDataLength(int slices)
104 88
      {
105 89
      int frontWalls=0, frontSegments=0, triangleShifts=0, windingShifts=0;
106 90
      int shiftCol = (mCols-1)/2;
......
127 111

  
128 112
      int frontVert = 2*( frontWalls + 2*frontSegments - 1) +2*triangleShifts + windingShifts;
129 113
      int sideVert  = 2*( mSideWalls + mSideBends + mEdgeNum -1);
130
      int firstWinding= (!frontOnly && (frontVert+1)%2==1 ) ? 1:0;
131
      int dataL = frontOnly ? frontVert : (frontVert+1) +firstWinding+ (1+sideVert+1) + (1+frontVert);
114
      int firstWinding= (slices>0 && (frontVert+1)%2==1 ) ? 1:0;
115
      int dataL = slices==0 ? frontVert : (frontVert+1) +firstWinding+ (1+sideVert+1) + (1+frontVert);
132 116
/*
133 117
      android.util.Log.e("CUBES","triangleShifts="+triangleShifts+" windingShifts="+windingShifts+" winding1="+firstWinding+" frontVert="+frontVert+" sideVert="+sideVert);
134 118
      android.util.Log.e("CUBES", "frontW="+frontWalls+" fSegments="+frontSegments+" sWalls="+mSideWalls+" sSegments="+mEdgeNum+" sideBends="+mSideBends+" dataLen="+dataL );
......
183 167
*/
184 168
///////////////////////////////////////////////////////////////////////////////////////////////////
185 169

  
186
   private void prepareDataStructures(int cols, String desc, boolean frontOnly)
170
   private void prepareDataStructures(int cols, String desc, int slices)
187 171
     {
188 172
     mRows      =0;
189 173
     mCols      =0;
174
     mSlices    =slices;
190 175
     numVertices=0;
191 176
     
192 177
     if( cols>0 && desc.contains("1") )
......
200 185
         for(int i=0; i<mRows; i++)
201 186
           mCubes[i][j] = (desc.charAt(i*mCols+j) == '1' ? 1:0);
202 187

  
203
       buildBoundingVert(frontOnly);
204

  
205
//android.util.Log.d("cubes", "VERT STRING:"+debug(mBoundingVert,3));
188
       //android.util.Log.d("cubes", "VERT STRING:"+debug(mBoundingVert,3));
206 189

  
207 190
       markRegions();
208
       numVertices = computeDataLength(frontOnly);
191
       numVertices = computeDataLength(slices);
209 192

  
210 193
       remainingVert = numVertices;
211 194
       }
......
214 197
///////////////////////////////////////////////////////////////////////////////////////////////////
215 198
// full grid
216 199

  
217
   private void prepareDataStructures(int cols, int rows, boolean frontOnly)
200
   private void prepareDataStructures(int cols, int rows, int slices)
218 201
     {
219 202
     mRows       =rows;
220 203
     mCols       =cols;
204
     mSlices     =slices;
221 205
     numVertices =   0;
222 206

  
223 207
     if( cols>0 && rows>0 )
......
228 212
         for(int i=0; i<mRows; i++)
229 213
           mCubes[i][j] = 1;
230 214

  
231
       mBoundingVert = frontOnly ? mBoundingVert1 : mBoundingVert2;
232

  
233
//android.util.Log.d("cubes", "VERT FULL:"+debug(mBoundingVert,3));
234

  
235 215
       markRegions();
236
       numVertices = computeDataLength(frontOnly);
216
       numVertices = computeDataLength(slices);
237 217

  
238 218
       remainingVert = numVertices;
239 219
       }
240 220
     }
241 221

  
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

  
244
  private float retRightmost(int row)
245
    {
246
    if( row==0 )
247
      {
248
      for(int i=mCols-1; i>=0; i--)
249
        if( mCubes[0][i]==1 )
250
          return (float)(i+1);
251
      }
252
    else if(row==mRows)
253
      {
254
      for(int i=mCols-1; i>=0; i--)
255
        if( mCubes[mRows-1][i]==1 )
256
          return (float)(i+1);
257
      }
258
    else
259
      {
260
      for(int i=mCols-1; i>=0; i--)
261
        if( mCubes[row][i]==1 || mCubes[row-1][i]==1 )
262
          return (float)(i+1);
263
      }
264

  
265
    return 0.0f;
266
    }
267

  
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

  
270
  private float retLeftmost(int row)
271
    {
272
    if( row==0 )
273
      {
274
      for(int i=0; i<mCols; i++)
275
        if( mCubes[0][i]==1 )
276
          return (float)i;
277
      }
278
    else if(row==mRows)
279
      {
280
      for(int i=0; i<mCols; i++)
281
        if( mCubes[mRows-1][i]==1 )
282
          return (float)i;
283
      }
284
    else
285
      {
286
      for(int i=0; i<mCols; i++)
287
        if( mCubes[row][i]==1 || mCubes[row-1][i]==1 )
288
          return (float)i;
289
      }
290

  
291
    return (float)mCols;
292
    }
293

  
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

  
296
  private int addLeftmost(float[] temp, int row, int index)
297
    {
298
    float x2 = retLeftmost(row)/mCols - 0.5f;
299
    float y2 = 0.5f - (float)row/mRows;
300

  
301
    if( index>1 )
302
      {
303
      float x0 = temp[2*index-4];
304
      float y0 = temp[2*index-3];
305
      float x1 = temp[2*index-2];
306
      float y1 = temp[2*index-1];
307

  
308
      while( (x0-x2)*(y0-y1) >= (x0-x1)*(y0-y2) )
309
        {
310
        if( --index>1 )
311
          {
312
          x1 = x0;
313
          y1 = y0;
314
          x0 = temp[2*index-4];
315
          y0 = temp[2*index-3];
316
          }
317
        else break;
318
        }
319
      }
320

  
321
    temp[2*index  ] = x2;
322
    temp[2*index+1] = y2;
323
    return index+1;
324
    }
325

  
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

  
328
  private int addRightmost(float[] temp, int row, int index)
329
    {
330
    float x2 = retRightmost(row)/mCols - 0.5f;
331
    float y2 = 0.5f - (float)row/mRows;
332

  
333
    if( index>1 )
334
      {
335
      float x0 = temp[2*index-4];
336
      float y0 = temp[2*index-3];
337
      float x1 = temp[2*index-2];
338
      float y1 = temp[2*index-1];
339

  
340
      while( (x0-x2)*(y0-y1) <= (x0-x1)*(y0-y2) )
341
        {
342
        if( --index>1 )
343
          {
344
          x1 = x0;
345
          y1 = y0;
346
          x0 = temp[2*index-4];
347
          y0 = temp[2*index-3];
348
          }
349
        else break;
350
        }
351
      }
352

  
353
    temp[2*index  ] = x2;
354
    temp[2*index+1] = y2;
355
    return index+1;
356
    }
357

  
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359
// fill up the mBoundingVert array with the smallest set of vertices which form the same convex hull
360
// like the whole thing.
361

  
362
  private void buildBoundingVert(boolean frontOnly)
363
    {
364
    int lVert=0, rVert=0;
365
    int firstRow=0, lastRow=mRows-1;
366

  
367
    for(int i=0; i<mRows; i++)
368
      for(int j=0; j<mCols; j++)
369
        if(mCubes[i][j] !=0 )
370
          {
371
          firstRow = i;
372
          i=mRows;
373
          j=mCols;
374
          }
375

  
376
    for(int i=mRows-1; i>=0; i--)
377
      for(int j=0; j<mCols; j++)
378
        if(mCubes[i][j] !=0 )
379
          {
380
          lastRow = i;
381
          i=-1;
382
          j=mCols;
383
          }
384

  
385
//android.util.Log.d("cubes", "first :"+firstRow+" last: "+lastRow);
386

  
387
    int numLines = lastRow-firstRow+2;
388

  
389
    float[] tempL = new float[2*numLines];
390
    float[] tempR = new float[2*numLines];
391

  
392
    for(int i=firstRow; i<=lastRow+1; i++)
393
      {
394
      lVert = addLeftmost (tempL,i,lVert);
395
      rVert = addRightmost(tempR,i,rVert);
396
      }
397

  
398
//android.util.Log.d("cubes", "LEFT :"+debug(tempL,2));
399
//android.util.Log.d("cubes", "RIGHT:"+debug(tempR,2));
400

  
401
    int numVert = lVert+rVert;
402

  
403
    mBoundingVert = new float[ numVert*(frontOnly ? 3:6) ];
404

  
405
    for(int i=0; i<lVert; i++)
406
      {
407
      mBoundingVert[3*i  ] = tempL[2*i  ];
408
      mBoundingVert[3*i+1] = tempL[2*i+1];
409
      mBoundingVert[3*i+2] = FRONTZ;
410
      }
411

  
412
    for(int i=0; i<rVert; i++)
413
      {
414
      mBoundingVert[3*(i+lVert)  ] = tempR[2*i  ];
415
      mBoundingVert[3*(i+lVert)+1] = tempR[2*i+1];
416
      mBoundingVert[3*(i+lVert)+2] = FRONTZ;
417
      }
418

  
419
    if( !frontOnly )
420
      {
421
      for(int i=0; i<numVert; i++)
422
        {
423
        mBoundingVert[3*(i+numVert)  ] = mBoundingVert[3*i  ];
424
        mBoundingVert[3*(i+numVert)+1] = mBoundingVert[3*i+1];
425
        mBoundingVert[3*(i+numVert)+2] = BACKZ;
426
        }
427
      }
428
    }
429

  
430 222
///////////////////////////////////////////////////////////////////////////////////////////////////
431 223
// Mark all the 'regions' of our grid  - i.e. separate pieces of 'land' (connected blocks that will 
432 224
// be rendered) and 'water' (connected holes in between) with integers. Each connected block of land
......
690 482
   
691 483
///////////////////////////////////////////////////////////////////////////////////////////////////
692 484

  
693
  private int buildSideGrid(int vertex, float[] attribs)
485
  private int buildSideGrid(int vertex, int slices, float[] attribs)
694 486
     {
695 487
     //android.util.Log.d("CUBES", "buildSide");
696 488

  
697 489
     for(int i=0; i<mEdgeNum; i++)
698 490
       {
699
       vertex = buildIthSide(mEdges.get(i), vertex, attribs);
491
       vertex = buildIthSide(mEdges.get(i), vertex, slices, attribs);
700 492
       } 
701 493
      
702 494
     return vertex;
......
704 496

  
705 497
///////////////////////////////////////////////////////////////////////////////////////////////////
706 498

  
707
  private int buildIthSide(Edge curr, int vertex, float[] attribs)
499
  private int buildIthSide(Edge curr, int vertex, int slices, float[] attribs)
708 500
     {
709 501
     Edge prev; 
710 502
     
......
888 680

  
889 681
///////////////////////////////////////////////////////////////////////////////////////////////////
890 682

  
891
  private void build(boolean frontOnly)
683
  private void build(int slices)
892 684
     {
893 685
     int vertSoFar=0;
894 686
     float[] attribs= new float[(POS_DATA_SIZE+NOR_DATA_SIZE+TEX_DATA_SIZE)*numVertices];
......
897 689

  
898 690
     vertSoFar = buildFrontBackGrid(true, vertSoFar,attribs);
899 691

  
900
     if( !frontOnly )
692
     if( slices>0 )
901 693
       {
902 694
       vertSoFar = repeatLast(vertSoFar,attribs);
903 695
       if( vertSoFar%2==1 )
......
909 701

  
910 702
       //android.util.Log.d("MeshCubes","building side grid...");
911 703

  
912
       vertSoFar = buildSideGrid (vertSoFar,attribs);
704
       vertSoFar = buildSideGrid (vertSoFar,slices,attribs);
913 705

  
914 706
       //android.util.Log.d("MeshCubes","building back grid...");
915 707

  
......
930 722
     mVertAttribs.put(attribs).position(0);
931 723
     }
932 724

  
933
///////////////////////////////////////////////////////////////////////////////////////////////////
934

  
935
  float[] getBoundingVertices()
936
     {
937
     return mBoundingVert;
938
     }
939

  
940 725
///////////////////////////////////////////////////////////////////////////////////////////////////
941 726
// PUBLIC API
942 727
///////////////////////////////////////////////////////////////////////////////////////////////////
943 728
/**
944 729
 * Creates the underlying mesh of vertices, normals, texture coords.
945 730
 *    
946
 * @param cols      Integer helping to parse the next parameter.
947
 * @param desc      String describing the subset of a MxNx1 cuboid that we want to create.
948
 *                  Its MxN characters - all 0 or 1 - decide of appropriate field is taken or not.
949
 *                  <p></p>
950
 *                  <p>
951
 *                  <pre>
952
 *                  For example, (cols=2, desc="111010") describes the following shape:
731
 * @param cols   Integer helping to parse the next parameter.
732
 * @param desc   String describing the subset of a MxNx1 cuboid that we want to create.
733
 *               Its MxN characters - all 0 or 1 - decide of appropriate field is taken or not.
734
 *               <p></p>
735
 *               <p>
736
 *               <pre>
737
 *               For example, (cols=2, desc="111010") describes the following shape:
953 738
 *
954
 *                  XX
955
 *                  X
956
 *                  X
739
 *               XX
740
 *               X
741
 *               X
957 742
 *
958
 *                  whereas (cols=2,desc="110001") describes
743
 *               whereas (cols=2,desc="110001") describes
959 744
 *
960
 *                  XX
745
 *               XX
961 746
 *
962
 *                   X
963
 *                  </pre>
964
 *                  </p>
965
 * @param frontOnly Only create the front wall or side and back as well?
747
 *                X
748
 *               </pre>
749
 *               </p>
750
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
966 751
 */
967
 public MeshCubes(int cols, String desc, boolean frontOnly)
752
 public MeshCubes(int cols, String desc, int slices)
968 753
   {
969
   super(frontOnly ? 0.0f:1.0f/cols);
970
   prepareDataStructures(cols,desc,frontOnly);
971
   build(frontOnly);
754
   super( (float)slices/cols);
755
   prepareDataStructures(cols,desc,slices);
756
   build(slices);
972 757
   }
973 758

  
974 759
///////////////////////////////////////////////////////////////////////////////////////////////////
975 760
/**
976 761
 * Creates a full, hole-less underlying mesh of vertices, normals, texture coords and colors.
977 762
 *
978
 * @param cols      Number of columns.
979
 * @param rows      Number of rows.
980
 * @param frontOnly Only create the front wall or side and back as well?
763
 * @param cols   Number of columns, i.e. 'width' of the Mesh.
764
 * @param rows   Number of rows, i.e. 'height' of the Mesh.
765
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
981 766
 */
982
 public MeshCubes(int cols, int rows, boolean frontOnly)
767
 public MeshCubes(int cols, int rows, int slices)
983 768
   {
984
   super(frontOnly ? 0.0f:1.0f/cols);
985
   prepareDataStructures(cols,rows,frontOnly);
986
   build(frontOnly);
769
   super( (float)slices/cols);
770
   prepareDataStructures(cols,rows,slices);
771
   build(slices);
987 772
   }
988 773
 }

Also available in: Unified diff