Project

General

Profile

Download (36.4 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / mesh / MeshCubes.java @ 4f81e0c8

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4 46b572b5 Leszek Koltunski
// This file is part of Distorted.                                                               //
5 d333eb6b Leszek Koltunski
//                                                                                               //
6 46b572b5 Leszek Koltunski
// Distorted is free software: you can redistribute it and/or modify                             //
7 d333eb6b Leszek Koltunski
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11 46b572b5 Leszek Koltunski
// Distorted is distributed in the hope that it will be useful,                                  //
12 d333eb6b Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17 46b572b5 Leszek Koltunski
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 6c00149d Leszek Koltunski
package org.distorted.library.mesh;
21 6a06a912 Leszek Koltunski
22 91cfe462 Leszek Koltunski
import org.distorted.library.type.Static4D;
23
24 6a06a912 Leszek Koltunski
import java.util.ArrayList;
25
26
///////////////////////////////////////////////////////////////////////////////////////////////////
27 e0b6c593 Leszek Koltunski
/**
28
 * Create a 3D grid composed of Cubes.
29
 * <p>
30 91cfe462 Leszek Koltunski
 * Any subset of a MxNx1 cuboid is possible. (repeated arbitrary number of times into Z-dir)
31 e0b6c593 Leszek Koltunski
 */
32 715e7726 Leszek Koltunski
public class MeshCubes extends MeshBase
33 6a06a912 Leszek Koltunski
   {
34 c90aca24 Leszek Koltunski
   private static final float R = 0.0f;
35 f08b268d Leszek Koltunski
36 91cfe462 Leszek Koltunski
   private static final int FRONT = 0;
37
   private static final int BACK  = 1;
38
   private static final int LEFT  = 2;
39
   private static final int RIGHT = 3;
40
   private static final int TOP   = 4;
41
   private static final int BOTTOM= 5;
42
43 6a06a912 Leszek Koltunski
   private static final int NORTH = 0;
44
   private static final int WEST  = 1;
45
   private static final int EAST  = 2;
46
   private static final int SOUTH = 3;
47 ce7f3833 Leszek Koltunski
48 6a06a912 Leszek Koltunski
   private static final float[] mNormalX = new float[4];
49
   private static final float[] mNormalY = new float[4];
50 ce7f3833 Leszek Koltunski
   private static final float[] mNormalZ = new float[4];
51
52 cbd502ec Leszek Koltunski
   private static class Edge
53 6a06a912 Leszek Koltunski
     {
54
     final int side; 
55
     final int row;
56
     final int col;
57
     
58 06d71892 Leszek Koltunski
     Edge(int s, int r, int c)
59 6a06a912 Leszek Koltunski
       {
60
       side= s; 
61
       row = r;
62
       col = c;
63
       }
64 39cbf9dc Leszek Koltunski
     }
65 91cfe462 Leszek Koltunski
66
   private float[] mTexMappingX,mTexMappingY, mTexMappingW, mTexMappingH;
67
68 80cb15ab leszek
   private int mCols, mRows, mSlices;
69 d6994cc6 Leszek Koltunski
   private int[][] mCubes;
70 9d0df4c6 Leszek Koltunski
   private byte[][] mInflateX, mInflateY;
71 39cbf9dc Leszek Koltunski
   private ArrayList<Edge> mEdges = new ArrayList<>();
72 ce7f3833 Leszek Koltunski
73 15290f35 Leszek Koltunski
   private int currVert;
74 da681e7e Leszek Koltunski
   private int numVertices;
75 8d9da98a Leszek Koltunski
   private int mSideBends;
76
   private int mEdgeNum;
77 b62632fc Leszek Koltunski
   private int mSideWalls;
78 ce7f3833 Leszek Koltunski
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80
// a Block is split into two triangles along the NE-SW line iff it is in the top-right
81
// or bottom-left quadrant of the grid.
82
83
   private boolean isNE(int row,int col)
84
     {
85 29dd01c6 Leszek Koltunski
     return ( (2*row<mRows)^(2*col<mCols) );
86 ce7f3833 Leszek Koltunski
     }
87
88 91cfe462 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
89
// fill per-side texture mappings. Default: all 6 sides map to the whole texture.
90
// Each Static4D describes the way its side will map. Format:
91
//
92
// 1st float: X-coord of the texture point that our top-left corner of the side maps to
93
// 2nd float: Y-coord of the texture point that our top-left corner of the side maps to
94
// 3rd float: X-coord of the texture point that our bot-right corner of the side maps to
95
// 4th float: Y-coord of the texture point that our bot-right corner of the side maps to
96
97
   private void fillTexMappings(Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom)
98
     {
99
     if( mTexMappingX==null ) mTexMappingX = new float[6];
100
     if( mTexMappingY==null ) mTexMappingY = new float[6];
101
     if( mTexMappingW==null ) mTexMappingW = new float[6];
102
     if( mTexMappingH==null ) mTexMappingH = new float[6];
103
104 ece89b28 Leszek Koltunski
     mTexMappingX[FRONT]  = front.get0();
105
     mTexMappingY[FRONT]  = front.get1();
106
     mTexMappingW[FRONT]  = front.get2() - front.get0();
107
     mTexMappingH[FRONT]  = front.get3() - front.get1();
108
109
     mTexMappingX[BACK]   = back.get0();
110
     mTexMappingY[BACK]   = back.get1();
111
     mTexMappingW[BACK]   = back.get2() - back.get0();
112
     mTexMappingH[BACK]   = back.get3() - back.get1();
113
114
     mTexMappingX[LEFT]   = left.get0();
115
     mTexMappingY[LEFT]   = left.get1();
116
     mTexMappingW[LEFT]   = left.get2() - left.get0();
117
     mTexMappingH[LEFT]   = left.get3() - left.get1();
118
119
     mTexMappingX[RIGHT]  = right.get0();
120
     mTexMappingY[RIGHT]  = right.get1();
121
     mTexMappingW[RIGHT]  = right.get2() - right.get0();
122
     mTexMappingH[RIGHT]  = right.get3() - right.get1();
123
124
     mTexMappingX[TOP]    = top.get0();
125
     mTexMappingY[TOP]    = top.get1();
126
     mTexMappingW[TOP]    = top.get2() - top.get0();
127
     mTexMappingH[TOP]    = top.get3() - top.get1();
128
129
     mTexMappingX[BOTTOM] = bottom.get0();
130
     mTexMappingY[BOTTOM] = bottom.get1();
131
     mTexMappingW[BOTTOM] = bottom.get2() - bottom.get0();
132
     mTexMappingH[BOTTOM] = bottom.get3() - bottom.get1();
133 91cfe462 Leszek Koltunski
     }
134
135 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
136 84ee2a6a Leszek Koltunski
// return the number of vertices our grid will contain
137 6a06a912 Leszek Koltunski
138 d1a396b2 leszek
   private int computeDataLength()
139 6a06a912 Leszek Koltunski
      {
140 b62632fc Leszek Koltunski
      int frontWalls=0, frontSegments=0, triangleShifts=0, windingShifts=0;
141 ce7f3833 Leszek Koltunski
      int shiftCol = (mCols-1)/2;
142
143
      boolean lastBlockIsNE=false;
144
      boolean thisBlockIsNE;        // the block we are currently looking at is split into
145
                                    // two triangles along the NE-SW line (rather than NW-SE)
146 29dd01c6 Leszek Koltunski
      for(int row=0; row<mRows; row++)
147 b62632fc Leszek Koltunski
        {
148
        if( mCols>=2 && (mCubes[row][shiftCol]%2 == 1) && (mCubes[row][shiftCol+1]%2 == 1) ) triangleShifts++;
149 ce7f3833 Leszek Koltunski
150 b62632fc Leszek Koltunski
        for(int col=0; col<mCols; col++)
151
          {
152
          if( mCubes[row][col]%2 == 1 )  // land
153 6a06a912 Leszek Koltunski
            {
154 b62632fc Leszek Koltunski
            thisBlockIsNE = isNE(row,col);
155
            if( thisBlockIsNE^lastBlockIsNE ) windingShifts++;
156
            lastBlockIsNE = thisBlockIsNE;
157
            frontWalls++;
158
            if( col==mCols-1 || mCubes[row][col+1]%2 == 0 ) frontSegments++;
159 6a06a912 Leszek Koltunski
            }
160 b62632fc Leszek Koltunski
          }
161
        }
162 ce7f3833 Leszek Koltunski
163 5f2853be Leszek Koltunski
      int frontVert       = 2*( frontWalls + 2*frontSegments - 1) +2*triangleShifts + windingShifts;
164
      int sideVertOneSlice= 2*( mSideWalls + mSideBends + mEdgeNum -1);
165
      int sideVert        = 2*(mSlices-1) + mSlices*sideVertOneSlice;
166
      int firstWinding    = (mSlices>0 && (frontVert+1)%2==1 ) ? 1:0;
167
      int dataL           = mSlices==0 ? frontVert : (frontVert+1) +firstWinding+ (1+sideVert+1) + (1+frontVert);
168 c90aca24 Leszek Koltunski
169 6a06a912 Leszek Koltunski
      return dataL<0 ? 0:dataL;
170
      }
171
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173
174 80cb15ab leszek
   private void prepareDataStructures(int cols, String desc, int slices)
175 6a06a912 Leszek Koltunski
     {
176 e92785ba Leszek Koltunski
     mRows       =0;
177
     mCols       =0;
178
     mSlices     =slices;
179 da681e7e Leszek Koltunski
     numVertices =0;
180 554ce72b Leszek Koltunski
181 0729bc41 Leszek Koltunski
     if( cols>0 && desc.contains("1") )
182 6a06a912 Leszek Koltunski
       {
183 0729bc41 Leszek Koltunski
       mCols = cols;
184
       mRows = desc.length()/cols;
185 6a06a912 Leszek Koltunski
186 9d0df4c6 Leszek Koltunski
       mCubes    = new int[mRows][mCols];
187
       mInflateX = new byte[mRows+1][mCols+1];
188
       mInflateY = new byte[mRows+1][mCols+1];
189
190 20156af7 Leszek Koltunski
       for(int col=0; col<mCols; col++)
191
         for(int row=0; row<mRows; row++)
192
           mCubes[row][col] = (desc.charAt(row * mCols + col) == '1' ? 1 : 0);
193 9d0df4c6 Leszek Koltunski
194 20156af7 Leszek Koltunski
       for(int col=0; col<mCols+1; col++)
195
         for(int row=0; row<mRows+1; row++)
196 9d0df4c6 Leszek Koltunski
           {
197 20156af7 Leszek Koltunski
           fillInflate(row,col);
198 9d0df4c6 Leszek Koltunski
           }
199 d6994cc6 Leszek Koltunski
200 0729bc41 Leszek Koltunski
       markRegions();
201 da681e7e Leszek Koltunski
       numVertices = computeDataLength();
202 15290f35 Leszek Koltunski
       currVert = 0;
203 6a06a912 Leszek Koltunski
       }
204
     }
205 665e2c45 Leszek Koltunski
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207
// full grid
208
209 80cb15ab leszek
   private void prepareDataStructures(int cols, int rows, int slices)
210 665e2c45 Leszek Koltunski
     {
211 e92785ba Leszek Koltunski
     mRows        =rows;
212
     mCols        =cols;
213
     mSlices      =slices;
214 da681e7e Leszek Koltunski
     numVertices  =0;
215 665e2c45 Leszek Koltunski
216
     if( cols>0 && rows>0 )
217
       {
218 9d0df4c6 Leszek Koltunski
       mCubes    = new int[mRows][mCols];
219
       mInflateX = new byte[mRows+1][mCols+1];
220
       mInflateY = new byte[mRows+1][mCols+1];
221 665e2c45 Leszek Koltunski
222 20156af7 Leszek Koltunski
       for(int col=0; col<mCols; col++)
223
         for(int row=0; row<mRows; row++)
224
           mCubes[row][col] = 1;
225 665e2c45 Leszek Koltunski
226 20156af7 Leszek Koltunski
       for(int col=0; col<mCols+1; col++)
227
         for(int row=0; row<mRows+1; row++)
228 9d0df4c6 Leszek Koltunski
           {
229 20156af7 Leszek Koltunski
           fillInflate(row,col);
230 9d0df4c6 Leszek Koltunski
           }
231
232 665e2c45 Leszek Koltunski
       markRegions();
233 da681e7e Leszek Koltunski
       numVertices = computeDataLength();
234 15290f35 Leszek Koltunski
       currVert = 0;
235 665e2c45 Leszek Koltunski
       }
236
     }
237
238 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
239
// Mark all the 'regions' of our grid  - i.e. separate pieces of 'land' (connected blocks that will 
240
// be rendered) and 'water' (connected holes in between) with integers. Each connected block of land
241
// gets a unique odd integer, each connected block of water a unique even integer.
242
//
243
// Water on the edges of the grid is also considered connected to itself!   
244
//   
245
// This function also creates a list of 'Edges'. Each Edge is a data structure from which later on we
246 2e96ee72 Leszek Koltunski
// will start building the side walls of each connected block of land (and sides of holes of water
247 91cfe462 Leszek Koltunski
// inside). Each Edge needs to point from Land to Water (thus the '(SOUTH,row-1,col)' below) - otherwise
248 8d9da98a Leszek Koltunski
// later on setting up normal vectors wouldn't work.
249 6a06a912 Leszek Koltunski
   
250 a51fe521 Leszek Koltunski
  private void markRegions()
251 6a06a912 Leszek Koltunski
     {
252 91cfe462 Leszek Koltunski
     int row, col, numWater=1, numLand=0;
253 6a06a912 Leszek Koltunski
     
254 91cfe462 Leszek Koltunski
     for(row=0; row<mRows; row++) if( mCubes[    row][      0]==0 ) markRegion((short)2,    row,       0);
255
     for(row=0; row<mRows; row++) if( mCubes[    row][mCols-1]==0 ) markRegion((short)2,    row, mCols-1);
256
     for(col=0; col<mCols; col++) if( mCubes[0      ][    col]==0 ) markRegion((short)2,      0,     col);
257
     for(col=0; col<mCols; col++) if( mCubes[mRows-1][    col]==0 ) markRegion((short)2,mRows-1,     col);
258 6a06a912 Leszek Koltunski
           
259 91cfe462 Leszek Koltunski
     for(row=0; row<mRows; row++)
260
        for(col=0; col<mCols; col++)
261 6a06a912 Leszek Koltunski
           {
262 91cfe462 Leszek Koltunski
           if( mCubes[row][col] == 0 ) { numWater++; markRegion( (short)(2*numWater ),row,col); mEdges.add(new Edge(SOUTH,row-1,col)); }
263
           if( mCubes[row][col] == 1 ) { numLand ++; markRegion( (short)(2*numLand+1),row,col); mEdges.add(new Edge(NORTH,row  ,col)); }
264 6a06a912 Leszek Koltunski
           }
265
     
266 8d9da98a Leszek Koltunski
     // now we potentially need to kick out some Edges . Otherwise the following does not work:
267 6a06a912 Leszek Koltunski
     //
268
     // 0 1 0
269
     // 1 0 1
270
     // 0 1 0
271
     
272 8d9da98a Leszek Koltunski
     mEdgeNum= mEdges.size();
273
     int initCol, initRow, initSide, lastSide;
274
     Edge e1,e2;
275 6a06a912 Leszek Koltunski
     
276 91cfe462 Leszek Koltunski
     for(int edge=0; edge<mEdgeNum; edge++)
277 6a06a912 Leszek Koltunski
       {
278 91cfe462 Leszek Koltunski
       e1 = mEdges.get(edge);
279 8d9da98a Leszek Koltunski
       initRow= e1.row;
280
       initCol= e1.col;
281
       initSide=e1.side;
282
283
       do
284 6a06a912 Leszek Koltunski
         {
285 b62632fc Leszek Koltunski
         mSideWalls++;
286
287 8d9da98a Leszek Koltunski
         if( e1.side==NORTH || e1.side==SOUTH )
288 6a06a912 Leszek Koltunski
           {
289 91cfe462 Leszek Koltunski
           for(int j=edge+1;j<mEdgeNum;j++)
290 6a06a912 Leszek Koltunski
             {
291 8d9da98a Leszek Koltunski
             e2 = mEdges.get(j);
292
293
             if( e2.side==e1.side && e2.row==e1.row && e2.col==e1.col )
294
               {
295
               mEdges.remove(j);
296
               mEdgeNum--;
297
               j--;
298
               }
299 6a06a912 Leszek Koltunski
             }
300
           }
301 8d9da98a Leszek Koltunski
302
         lastSide = e1.side;
303
         e1 = getNextEdge(e1);
304
         if( e1.side!=lastSide ) mSideBends++;
305 6a06a912 Leszek Koltunski
         }
306 8d9da98a Leszek Koltunski
       while( e1.col!=initCol || e1.row!=initRow || e1.side!=initSide );
307 6a06a912 Leszek Koltunski
       }
308
     }
309
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311
// when calling, make sure that newVal != val
312
   
313 a51fe521 Leszek Koltunski
  private void markRegion(short newVal, int row, int col)
314 6a06a912 Leszek Koltunski
     {
315 d6994cc6 Leszek Koltunski
     int val = mCubes[row][col];
316 6a06a912 Leszek Koltunski
     mCubes[row][col] = newVal;
317
     
318
     if( row>0       && mCubes[row-1][col  ]==val ) markRegion(newVal, row-1, col  );
319
     if( row<mRows-1 && mCubes[row+1][col  ]==val ) markRegion(newVal, row+1, col  );
320
     if( col>0       && mCubes[row  ][col-1]==val ) markRegion(newVal, row  , col-1);
321
     if( col<mCols-1 && mCubes[row  ][col+1]==val ) markRegion(newVal, row  , col+1);
322
     }
323
   
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325
   
326 a51fe521 Leszek Koltunski
  private void createNormals(boolean front, int row, int col)
327 6a06a912 Leszek Koltunski
     {
328
     int td,lr; 
329
      
330 2e96ee72 Leszek Koltunski
     int nw = (col>0       && row>0      ) ? (mCubes[row-1][col-1]%2) : 0;
331
     int w  = (col>0                     ) ? (mCubes[row  ][col-1]%2) : 0;
332
     int n  = (               row>0      ) ? (mCubes[row-1][col  ]%2) : 0;
333
     int c  =                                (mCubes[row  ][col  ]%2);
334
     int sw = (col>0       && row<mRows-1) ? (mCubes[row+1][col-1]%2) : 0;
335 6a06a912 Leszek Koltunski
     int s  = (               row<mRows-1) ? (mCubes[row+1][col  ]%2) : 0;
336
     int ne = (col<mCols-1 && row>0      ) ? (mCubes[row-1][col+1]%2) : 0;
337
     int e  = (col<mCols-1               ) ? (mCubes[row  ][col+1]%2) : 0;
338
     int se = (col<mCols-1 && row<mRows-1) ? (mCubes[row+1][col+1]%2) : 0;
339 ce7f3833 Leszek Koltunski
340
     if(front)
341
       {
342
       mNormalZ[0] = 1.0f;
343
       mNormalZ[1] = 1.0f;
344
       mNormalZ[2] = 1.0f;
345
       mNormalZ[3] = 1.0f;
346
       }
347
     else
348
       {
349
       mNormalZ[0] =-1.0f;
350
       mNormalZ[1] =-1.0f;
351
       mNormalZ[2] =-1.0f;
352
       mNormalZ[3] =-1.0f;
353
       }
354
355 6a06a912 Leszek Koltunski
     td = nw+n-w-c;
356
     lr = c+n-w-nw;
357
     if( td<0 ) td=-1;
358
     if( td>0 ) td= 1;
359
     if( lr<0 ) lr=-1;
360
     if( lr>0 ) lr= 1;
361
     mNormalX[0] = lr*R;
362
     mNormalY[0] = td*R;
363
     
364
     td = w+c-sw-s;
365
     lr = c+s-w-sw;
366
     if( td<0 ) td=-1;
367
     if( td>0 ) td= 1;
368
     if( lr<0 ) lr=-1;
369
     if( lr>0 ) lr= 1;
370
     mNormalX[1] = lr*R;
371
     mNormalY[1] = td*R;
372
     
373
     td = n+ne-c-e;
374
     lr = e+ne-c-n;
375
     if( td<0 ) td=-1;
376
     if( td>0 ) td= 1;
377
     if( lr<0 ) lr=-1;
378
     if( lr>0 ) lr= 1;
379
     mNormalX[2] = lr*R;
380
     mNormalY[2] = td*R;
381
     
382
     td = c+e-s-se;
383
     lr = e+se-c-s;
384
     if( td<0 ) td=-1;
385
     if( td>0 ) td= 1;
386
     if( lr<0 ) lr=-1;
387
     if( lr>0 ) lr= 1;
388
     mNormalX[3] = lr*R;
389
     mNormalY[3] = td*R;
390
     }
391 ce7f3833 Leszek Koltunski
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394 e54bfada Leszek Koltunski
  private void buildFrontBackGrid(boolean front, float[] attribs1, float[] attribs2)
395 6a06a912 Leszek Koltunski
     {
396 d6994cc6 Leszek Koltunski
     int last, current;
397 ce7f3833 Leszek Koltunski
     boolean seenLand=false;
398
     boolean lastBlockIsNE = false;
399
     boolean currentBlockIsNE;
400 f08b268d Leszek Koltunski
     float vectZ = (front ? 0.5f : -0.5f);
401 ce7f3833 Leszek Koltunski
402 e5d9b235 Leszek Koltunski
     for(int row=0; row<mRows; row++)
403 6a06a912 Leszek Koltunski
       {
404
       last =0;
405
         
406 e5d9b235 Leszek Koltunski
       for(int col=0; col<mCols; col++)
407 6a06a912 Leszek Koltunski
         {
408 e5d9b235 Leszek Koltunski
         current = mCubes[row][col];
409 ce7f3833 Leszek Koltunski
410 6a06a912 Leszek Koltunski
         if( current%2 == 1 )
411
           {
412 e5d9b235 Leszek Koltunski
           currentBlockIsNE = isNE(row,col);
413 84ee2a6a Leszek Koltunski
414 15290f35 Leszek Koltunski
           if( !seenLand && !front && ((currVert%2==1)^currentBlockIsNE) )
415 84ee2a6a Leszek Koltunski
             {
416 e54bfada Leszek Koltunski
             repeatLast(attribs1,attribs2);
417 84ee2a6a Leszek Koltunski
             }
418
419 e5d9b235 Leszek Koltunski
           createNormals(front,row,col);
420 ce7f3833 Leszek Koltunski
421 e5d9b235 Leszek Koltunski
           if( currentBlockIsNE )
422 6a06a912 Leszek Koltunski
             {
423 e5d9b235 Leszek Koltunski
             if( (last!=current) || !lastBlockIsNE )
424
               {
425 e54bfada Leszek Koltunski
               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
426
               addFrontVertex( 0, vectZ, col, row, attribs1,attribs2);
427
               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
428
               if( !lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs1,attribs2);
429
               addFrontVertex( 1, vectZ, col, row+1, attribs1,attribs2);
430 e5d9b235 Leszek Koltunski
               }
431 e54bfada Leszek Koltunski
             addFrontVertex( 2, vectZ, col+1, row  , attribs1,attribs2);
432
             addFrontVertex( 3, vectZ, col+1, row+1, attribs1,attribs2);
433 e5d9b235 Leszek Koltunski
             }
434
           else
435
             {
436
             if( (last!=current) || lastBlockIsNE )
437
               {
438 e54bfada Leszek Koltunski
               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
439
               addFrontVertex( 1, vectZ, col, row+1, attribs1,attribs2);
440
               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
441
               if( lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs1,attribs2);
442
               addFrontVertex( 0, vectZ, col, row, attribs1,attribs2);
443 e5d9b235 Leszek Koltunski
               }
444 e54bfada Leszek Koltunski
             addFrontVertex( 3, vectZ, col+1, row+1, attribs1,attribs2);
445
             addFrontVertex( 2, vectZ, col+1, row  , attribs1,attribs2);
446 6a06a912 Leszek Koltunski
             }
447 ce7f3833 Leszek Koltunski
448
           seenLand = true;
449
           lastBlockIsNE = currentBlockIsNE;
450 6a06a912 Leszek Koltunski
           }
451
            
452
         last = current;
453
         }
454
       }
455
     }
456
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458
459 e54bfada Leszek Koltunski
  private void buildSideGrid(float[] attribs1,float[] attribs2)
460 6a06a912 Leszek Koltunski
     {
461 8d9da98a Leszek Koltunski
     for(int i=0; i<mEdgeNum; i++)
462 6a06a912 Leszek Koltunski
       {
463 e54bfada Leszek Koltunski
       buildIthSide(mEdges.get(i), attribs1, attribs2);
464 15290f35 Leszek Koltunski
       }
465 6a06a912 Leszek Koltunski
     }
466
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468
469 e54bfada Leszek Koltunski
  private void buildIthSide(Edge curr, float[] attribs1, float[] attribs2)
470 6a06a912 Leszek Koltunski
     {
471 5f2853be Leszek Koltunski
     Edge prev, next;
472
     int col, row, side;
473
474 6a06a912 Leszek Koltunski
     if( curr.side==NORTH ) // water outside
475
       {
476
       prev = new Edge(WEST,curr.row,curr.col);
477
       }
478 d1a396b2 leszek
     else                   // land outside; we need to move forward one link because we are
479
       {                    // going in opposite direction and we need to start from a bend.
480 6a06a912 Leszek Koltunski
       prev = curr;
481
       curr = new Edge(EAST,curr.row+1,curr.col-1);
482
       }
483 5f2853be Leszek Koltunski
484 9d0df4c6 Leszek Koltunski
     for(int slice=0; slice<mSlices; slice++)
485 6a06a912 Leszek Koltunski
       {
486 5f2853be Leszek Koltunski
       col = curr.col;
487
       row = curr.row;
488
       side= curr.side;
489
       next = getNextEdge(curr);
490
     
491 e54bfada Leszek Koltunski
       addSideVertex(curr,true,slice+1,prev.side,attribs1,attribs2);
492 5f2853be Leszek Koltunski
493
       do
494 6a06a912 Leszek Koltunski
         {
495 5f2853be Leszek Koltunski
         if( prev.side!=curr.side )
496
           {
497 e54bfada Leszek Koltunski
           addSideVertex(curr,true,slice+1,prev.side,attribs1,attribs2);
498
           addSideVertex(curr,true,slice  ,prev.side,attribs1,attribs2);
499 5f2853be Leszek Koltunski
           }
500 6a06a912 Leszek Koltunski
       
501 e54bfada Leszek Koltunski
         addSideVertex(curr,false,slice+1,next.side,attribs1,attribs2);
502
         addSideVertex(curr,false,slice  ,next.side,attribs1,attribs2);
503 6a06a912 Leszek Koltunski
       
504 5f2853be Leszek Koltunski
         prev = curr;
505
         curr = next;
506
         next = getNextEdge(curr);
507
         }
508
       while( curr.col!=col || curr.row!=row || curr.side!=side );
509 6a06a912 Leszek Koltunski
     
510 e54bfada Leszek Koltunski
       repeatLast(attribs1,attribs2);
511 5f2853be Leszek Koltunski
       }
512 6a06a912 Leszek Koltunski
     }
513
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515
516 a51fe521 Leszek Koltunski
  private Edge getNextEdge(Edge curr)
517 6a06a912 Leszek Koltunski
     {
518
     int col = curr.col;
519
     int row = curr.row;
520 c90aca24 Leszek Koltunski
521 6a06a912 Leszek Koltunski
     switch(curr.side) 
522
       {
523
       case NORTH: if( col==mCols-1 ) 
524
                     return new Edge(EAST,row,col);
525
                   if( row>0 && mCubes[row-1][col+1]==mCubes[row][col] )
526
                     return new Edge(WEST,row-1,col+1);
527
                   if( mCubes[row][col+1]==mCubes[row][col] )
528
                     return new Edge(NORTH,row,col+1);
529
                   else  
530
                     return new Edge(EAST,row,col);
531
                   
532
       case SOUTH: if( col==0 ) 
533
                     return new Edge(WEST,row,col);
534
                   if( (row<mRows-1) && mCubes[row+1][col-1]==mCubes[row][col] )
535
                     return new Edge(EAST,row+1,col-1); 
536
                   if( mCubes[row][col-1]==mCubes[row][col] )
537
                     return new Edge(SOUTH,row,col-1);
538
                   else
539
                     return new Edge(WEST,row,col); 
540
                     
541
       case EAST : if( row==mRows-1 ) 
542
                     return new Edge(SOUTH,row,col);
543
                   if( (col<mCols-1) && mCubes[row+1][col+1]==mCubes[row][col] )
544
                     return new Edge(NORTH,row+1,col+1);
545
                   if( mCubes[row+1][col]==mCubes[row][col] )
546
                     return new Edge(EAST,row+1,col);
547
                   else 
548
                     return new Edge(SOUTH,row,col);
549
                   
550 8d9da98a Leszek Koltunski
       default   : if( row==0 )
551 6a06a912 Leszek Koltunski
                     return new Edge(NORTH,row,col);
552
                   if( col>0 && mCubes[row-1][col-1]==mCubes[row][col] )
553
                     return new Edge(SOUTH,row-1,col-1);
554
                   if( mCubes[row-1][col]==mCubes[row][col] )
555
                     return new Edge(WEST,row-1,col);
556
                   else
557
                     return new Edge(NORTH,row,col);     
558
       }
559
     }
560
561 9d0df4c6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
562
563 20156af7 Leszek Koltunski
  private void fillInflate(int row, int col)
564 9d0df4c6 Leszek Koltunski
    {
565
    int diff;
566
567 20156af7 Leszek Koltunski
         if( col==0     ) mInflateX[row][col] = -1;
568
    else if( col==mCols ) mInflateX[row][col] = +1;
569 9d0df4c6 Leszek Koltunski
    else
570
      {
571
      if( row==0 )
572
        {
573
        diff = mCubes[0][col-1]-mCubes[0][col];
574
        }
575
      else if( row==mRows )
576
        {
577
        diff = mCubes[mRows-1][col-1]-mCubes[mRows-1][col];
578
        }
579
      else
580
        {
581
        diff = (mCubes[row  ][col-1]-mCubes[row  ][col]) +
582
               (mCubes[row-1][col-1]-mCubes[row-1][col]) ;
583
584
        if( diff==-2 ) diff=-1;
585
        if( diff== 2 ) diff= 1;
586
        }
587
588 20156af7 Leszek Koltunski
      mInflateX[row][col] = (byte)diff;
589 9d0df4c6 Leszek Koltunski
      }
590
591 20156af7 Leszek Koltunski
         if( row==0     ) mInflateY[row][col] = +1;
592
    else if( row==mRows ) mInflateY[row][col] = -1;
593 9d0df4c6 Leszek Koltunski
    else
594
      {
595
      if( col==0 )
596
        {
597
        diff = mCubes[row][0]-mCubes[row-1][0];
598
        }
599
      else if( col==mCols )
600
        {
601
        diff = mCubes[row][mCols-1]-mCubes[row-1][mCols-1];
602
        }
603
      else
604
        {
605
        diff = (mCubes[row  ][col-1]+mCubes[row  ][col]) -
606
               (mCubes[row-1][col-1]+mCubes[row-1][col]) ;
607
608
        if( diff==-2 ) diff=-1;
609
        if( diff== 2 ) diff= 1;
610
        }
611
612 20156af7 Leszek Koltunski
      mInflateY[row][col] = (byte)diff;
613 9d0df4c6 Leszek Koltunski
      }
614
    }
615
616 a51fe521 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
617
618 e54bfada Leszek Koltunski
  private void addFrontVertex(int index, float vectZ, int col, int row, float[] attribs1, float[] attribs2)
619 a51fe521 Leszek Koltunski
     {
620
     float x = (float)col/mCols;
621
     float y = (float)row/mRows;
622
623 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x-0.5f;
624
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f-y;
625
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = vectZ;
626 6f2d931d Leszek Koltunski
627 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = mNormalX[index];
628
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = mNormalY[index];
629
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = mNormalZ[index];
630 6f2d931d Leszek Koltunski
631 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
632
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
633
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = vectZ;
634 6f2d931d Leszek Koltunski
635 91cfe462 Leszek Koltunski
     if( vectZ>0 )
636
       {
637 e54bfada Leszek Koltunski
       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[FRONT] +       x  * mTexMappingW[FRONT];
638
       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[FRONT] + (1.0f-y) * mTexMappingH[FRONT];
639 91cfe462 Leszek Koltunski
       }
640
     else
641
       {
642 e54bfada Leszek Koltunski
       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BACK]  +       x  * mTexMappingW[BACK];
643
       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BACK]  + (1.0f-y) * mTexMappingH[BACK];
644 91cfe462 Leszek Koltunski
       }
645 a51fe521 Leszek Koltunski
646 1e672c1d Leszek Koltunski
     attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB] = DEFAULT_ASSOCIATION;
647 bc208a9c Leszek Koltunski
648 15290f35 Leszek Koltunski
     currVert++;
649 a51fe521 Leszek Koltunski
     }
650
651 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
652 2d203318 Leszek Koltunski
653 e54bfada Leszek Koltunski
  private void addSideVertex(Edge curr, boolean back, int slice, int side, float[] attribs1, float[] attribs2)
654 6a06a912 Leszek Koltunski
     {
655 9d0df4c6 Leszek Koltunski
     float x, y, z;
656 91cfe462 Leszek Koltunski
     int row, col;
657 985ea9c5 Leszek Koltunski
658 6a06a912 Leszek Koltunski
     switch(curr.side)
659
       {
660 9d0df4c6 Leszek Koltunski
       case NORTH: row = curr.row;
661
                   col = (back ? (curr.col  ):(curr.col+1));
662
                   x = (float)col/mCols;
663
                   y = 0.5f - (float)row/mRows;
664
                   z = 0.5f - (float)slice/mSlices;
665 985ea9c5 Leszek Koltunski
666 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
667
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = y;
668
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
669 6f2d931d Leszek Koltunski
670 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = side==NORTH ? 0.0f : (side==WEST?-R:R);
671
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = 1.0f;
672
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
673 6f2d931d Leszek Koltunski
674 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
675
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
676
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
677 a16bf106 Leszek Koltunski
678 e54bfada Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[TOP] +       x  * mTexMappingW[TOP];
679
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[TOP] + (0.5f-z) * mTexMappingH[TOP];
680 1e672c1d Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB  ] = DEFAULT_ASSOCIATION;
681 15ed35e6 Leszek Koltunski
682 6a06a912 Leszek Koltunski
                   break;
683 9d0df4c6 Leszek Koltunski
       case SOUTH: row = curr.row+1;
684
                   col = (back ? (curr.col+1):(curr.col));
685
                   x = (float)col/mCols;
686
                   y = 0.5f - (float)row/mRows;
687
                   z = 0.5f - (float)slice/mSlices;
688 985ea9c5 Leszek Koltunski
689 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
690
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = y;
691
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
692 6f2d931d Leszek Koltunski
693 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = side==SOUTH ? 0.0f: (side==EAST?-R:R);
694
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] =-1.0f;
695
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
696 6f2d931d Leszek Koltunski
697 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
698
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
699
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
700 a16bf106 Leszek Koltunski
701 e54bfada Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BOTTOM] +       x  * mTexMappingW[BOTTOM];
702
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BOTTOM] + (0.5f-z) * mTexMappingH[BOTTOM];
703 1e672c1d Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB  ] = DEFAULT_ASSOCIATION;
704 15ed35e6 Leszek Koltunski
705 6a06a912 Leszek Koltunski
                   break;
706 9d0df4c6 Leszek Koltunski
       case WEST : row = (back  ? (curr.row+1):(curr.row));
707
                   col = curr.col;
708
                   x = (float)col/mCols -0.5f;
709
                   y = (float)row/mRows;
710
                   z = 0.5f - (float)slice/mSlices;
711 985ea9c5 Leszek Koltunski
712 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x;
713
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
714
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
715 6f2d931d Leszek Koltunski
716 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] =-1.0f;
717
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = side==WEST ? 0.0f : (side==NORTH?-R:R);
718
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
719 6f2d931d Leszek Koltunski
720 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
721
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
722
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
723 6f2d931d Leszek Koltunski
724 e54bfada Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[LEFT] + (0.5f-z) * mTexMappingW[LEFT];
725
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[LEFT] + (1.0f-y) * mTexMappingH[LEFT];
726 1e672c1d Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB  ] = DEFAULT_ASSOCIATION;
727 2d203318 Leszek Koltunski
728 6a06a912 Leszek Koltunski
                   break;
729 9d0df4c6 Leszek Koltunski
       case EAST : row = (back  ? (curr.row):(curr.row+1));
730
                   col = (curr.col+1);
731
                   x = (float)col/mCols -0.5f;
732
                   y = (float)row/mRows;
733
                   z = 0.5f - (float)slice/mSlices;
734 985ea9c5 Leszek Koltunski
735 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x;
736
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
737
                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
738 6f2d931d Leszek Koltunski
739 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = 1.0f;
740
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = side==EAST ? 0.0f : (side==SOUTH?-R:R);
741
                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
742 6f2d931d Leszek Koltunski
743 e54bfada Leszek Koltunski
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
744
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
745
                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
746 6f2d931d Leszek Koltunski
747 e54bfada Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[RIGHT] + (0.5f-z) * mTexMappingW[RIGHT];
748
                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[RIGHT] + (1.0f-y) * mTexMappingH[RIGHT];
749 1e672c1d Leszek Koltunski
                   attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB  ] = DEFAULT_ASSOCIATION;
750 a16bf106 Leszek Koltunski
751 2d203318 Leszek Koltunski
                   break;
752 a16bf106 Leszek Koltunski
       }
753 2d203318 Leszek Koltunski
754 15290f35 Leszek Koltunski
     currVert++;
755 6f2d931d Leszek Koltunski
     }
756
757
///////////////////////////////////////////////////////////////////////////////////////////////////
758
759 e54bfada Leszek Koltunski
   private void repeatLast(float[] attribs1, float[] attribs2)
760 6f2d931d Leszek Koltunski
     {
761 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB  ];
762
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB+1];
763
     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB+2];
764 6f2d931d Leszek Koltunski
765 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB  ];
766
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB+1];
767
     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB+2];
768 6f2d931d Leszek Koltunski
769 e54bfada Leszek Koltunski
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB  ];
770
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB+1];
771
     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB+2];
772 6f2d931d Leszek Koltunski
773 e54bfada Leszek Koltunski
     attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = attribs2[VERT2_ATTRIBS*(currVert-1) + TEX_ATTRIB  ];
774
     attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = attribs2[VERT2_ATTRIBS*(currVert-1) + TEX_ATTRIB+1];
775 1e672c1d Leszek Koltunski
     attribs2[VERT2_ATTRIBS*currVert + ASS_ATTRIB  ] = DEFAULT_ASSOCIATION;
776 6f2d931d Leszek Koltunski
777 15290f35 Leszek Koltunski
     currVert++;
778 6a06a912 Leszek Koltunski
     }
779
780 665e2c45 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
781
782 d1a396b2 leszek
  private void build()
783 665e2c45 Leszek Koltunski
     {
784 e54bfada Leszek Koltunski
     float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
785
     float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
786 665e2c45 Leszek Koltunski
787 e54bfada Leszek Koltunski
     buildFrontBackGrid(true,attribs1,attribs2);
788 665e2c45 Leszek Koltunski
789 d1a396b2 leszek
     if( mSlices>0 )
790 665e2c45 Leszek Koltunski
       {
791 e54bfada Leszek Koltunski
       repeatLast(attribs1,attribs2);
792
       if( currVert%2==1 ) repeatLast(attribs1,attribs2);
793
       buildSideGrid(attribs1,attribs2);
794
       buildFrontBackGrid(false,attribs1,attribs2);
795 665e2c45 Leszek Koltunski
       }
796
797 8d9da98a Leszek Koltunski
     mEdges.clear();
798
     mEdges = null;
799
     mCubes = null;
800 9d0df4c6 Leszek Koltunski
     mInflateX = null;
801
     mInflateY = null;
802 8d9da98a Leszek Koltunski
803 15290f35 Leszek Koltunski
     if( currVert!=numVertices )
804
       android.util.Log.e("MeshCubes", "currVert " +currVert+" numVertices="+numVertices );
805 665e2c45 Leszek Koltunski
806 e54bfada Leszek Koltunski
     setAttribs(attribs1,attribs2);
807 665e2c45 Leszek Koltunski
     }
808
809 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
810
// PUBLIC API
811
///////////////////////////////////////////////////////////////////////////////////////////////////
812
/**
813 05403bba Leszek Koltunski
 * Creates the underlying mesh of vertices, normals, texture coords.
814 6a06a912 Leszek Koltunski
 *    
815 80cb15ab leszek
 * @param cols   Integer helping to parse the next parameter.
816
 * @param desc   String describing the subset of a MxNx1 cuboid that we want to create.
817
 *               Its MxN characters - all 0 or 1 - decide of appropriate field is taken or not.
818
 *               <p></p>
819
 *               <p>
820
 *               <pre>
821 91cfe462 Leszek Koltunski
 *               For example, (cols=2, desc="111010", slices=1) describes the following shape:
822 a56bc359 Leszek Koltunski
 *
823 80cb15ab leszek
 *               XX
824
 *               X
825
 *               X
826 a56bc359 Leszek Koltunski
 *
827 91cfe462 Leszek Koltunski
 *               whereas (cols=2,desc="110001", slices=1) describes
828 a56bc359 Leszek Koltunski
 *
829 80cb15ab leszek
 *               XX
830 a56bc359 Leszek Koltunski
 *
831 80cb15ab leszek
 *                X
832
 *               </pre>
833
 *               </p>
834
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
835 6a06a912 Leszek Koltunski
 */
836 80cb15ab leszek
 public MeshCubes(int cols, String desc, int slices)
837 a51fe521 Leszek Koltunski
   {
838 0f10a0b6 Leszek Koltunski
   super();
839 91cfe462 Leszek Koltunski
   Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f);
840
   fillTexMappings(map,map,map,map,map,map);
841
   prepareDataStructures(cols,desc,slices);
842
   build();
843
   }
844
845
///////////////////////////////////////////////////////////////////////////////////////////////////
846
/**
847
 * Creates the underlying mesh of vertices, normals, texture coords with custom texture mappings.
848
 *
849
 * The mappings decide what part of the texture appears on a given side. Example:
850
 * front = (0.0,0.5,0.5,1.0) means that the front side of the grid will be textured with the
851
 * bottom-left quadrant of the texture.
852
 *
853
 * Default is: each of the 6 sides maps to the whole texture, i.e. (0.0,0.0,1.0,1.0)
854
 *
855
 * @param cols   Integer helping to parse the next parameter.
856
 * @param desc   String describing the subset of a MxNx1 cuboid that we want to create.
857
 *               Its MxN characters - all 0 or 1 - decide of appropriate field is taken or not.
858
 *               <p></p>
859
 *               <p>
860
 *               <pre>
861
 *               For example, (cols=2, desc="111010", slices=1) describes the following shape:
862
 *
863
 *               XX
864
 *               X
865
 *               X
866
 *
867
 *               whereas (cols=2,desc="110001", slices=1) describes
868
 *
869
 *               XX
870
 *
871
 *                X
872
 *               </pre>
873
 *               </p>
874
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
875
 * @param front  Texture mapping the front side maps to.
876
 * @param back   Texture mapping the back side maps to.
877
 * @param left   Texture mapping the left side maps to.
878
 * @param right  Texture mapping the right side maps to.
879
 * @param top    Texture mapping the top side maps to.
880
 * @param bottom Texture mapping the bottom side maps to.
881
 */
882
 public MeshCubes(int cols, String desc, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom)
883
   {
884 0f10a0b6 Leszek Koltunski
   super();
885 91cfe462 Leszek Koltunski
   fillTexMappings(front,back,left,right,top,bottom);
886 80cb15ab leszek
   prepareDataStructures(cols,desc,slices);
887 d1a396b2 leszek
   build();
888 a51fe521 Leszek Koltunski
   }
889 6a06a912 Leszek Koltunski
890 665e2c45 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
891
/**
892 05403bba Leszek Koltunski
 * Creates a full, hole-less underlying mesh of vertices, normals, texture coords and colors.
893 665e2c45 Leszek Koltunski
 *
894 80cb15ab leszek
 * @param cols   Number of columns, i.e. 'width' of the Mesh.
895
 * @param rows   Number of rows, i.e. 'height' of the Mesh.
896
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
897 665e2c45 Leszek Koltunski
 */
898 80cb15ab leszek
 public MeshCubes(int cols, int rows, int slices)
899 a51fe521 Leszek Koltunski
   {
900 0f10a0b6 Leszek Koltunski
   super();
901 91cfe462 Leszek Koltunski
   Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f);
902
   fillTexMappings(map,map,map,map,map,map);
903
   prepareDataStructures(cols,rows,slices);
904
   build();
905
   }
906
907
///////////////////////////////////////////////////////////////////////////////////////////////////
908
/**
909
 * Creates a full, hole-less underlying mesh of vertices, normals, texture coords and colors with
910
 * custom texture mappings.
911
 *
912
 * The mappings decide what part of the texture appears on a given side. Example:
913
 * front = (0.0,0.5,0.5,1.0) means that the front side of the grid will be textured with the
914
 * bottom-left quadrant of the texture.
915
 *
916
 * Default is: each of the 6 sides maps to the whole texture, i.e. (0.0,0.0,1.0,1.0)
917
 *
918
 * @param cols   Number of columns, i.e. 'width' of the Mesh.
919
 * @param rows   Number of rows, i.e. 'height' of the Mesh.
920
 * @param slices Number of slices, i.e. 'depth' of the Mesh.
921
 * @param front  Texture mapping the front side maps to.
922
 * @param back   Texture mapping the back side maps to.
923
 * @param left   Texture mapping the left side maps to.
924
 * @param right  Texture mapping the right side maps to.
925
 * @param top    Texture mapping the top side maps to.
926
 * @param bottom Texture mapping the bottom side maps to.
927
 */
928
 public MeshCubes(int cols, int rows, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom)
929
   {
930 0f10a0b6 Leszek Koltunski
   super();
931 91cfe462 Leszek Koltunski
   fillTexMappings(front,back,left,right,top,bottom);
932 80cb15ab leszek
   prepareDataStructures(cols,rows,slices);
933 d1a396b2 leszek
   build();
934 6a06a912 Leszek Koltunski
   }
935 cbd502ec Leszek Koltunski
936
///////////////////////////////////////////////////////////////////////////////////////////////////
937
/**
938 4f81e0c8 Leszek Koltunski
 * Copy constructor.
939 cbd502ec Leszek Koltunski
 */
940 4f81e0c8 Leszek Koltunski
 public MeshCubes(MeshCubes mesh, boolean deep)
941 cbd502ec Leszek Koltunski
   {
942 4f81e0c8 Leszek Koltunski
   super(mesh,deep);
943 cbd502ec Leszek Koltunski
   }
944
945
///////////////////////////////////////////////////////////////////////////////////////////////////
946
/**
947 4f81e0c8 Leszek Koltunski
 * Copy the Mesh.
948
 *
949
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
950
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
951
 *             coordinates and effect assocciations, is always deep copied).
952 cbd502ec Leszek Koltunski
 */
953 4f81e0c8 Leszek Koltunski
 public MeshCubes copy(boolean deep)
954 cbd502ec Leszek Koltunski
   {
955 4f81e0c8 Leszek Koltunski
   return new MeshCubes(this,deep);
956 cbd502ec Leszek Koltunski
   }
957 a51fe521 Leszek Koltunski
 }