Revision 8d9da98a
Added by Leszek Koltunski about 8 years ago
src/main/java/org/distorted/library/DistortedCubesGrid.java | ||
---|---|---|
64 | 64 |
private ArrayList<Edge> mEdges = new ArrayList<>(); |
65 | 65 |
|
66 | 66 |
private int remainingVert; |
67 |
private int mSideBends; |
|
68 |
private int mEdgeNum; |
|
67 | 69 |
|
68 | 70 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
69 | 71 |
// a Block is split into two triangles along the NE-SW line iff it is in the top-right |
... | ... | |
79 | 81 |
|
80 | 82 |
private int computeDataLength(boolean frontOnly) |
81 | 83 |
{ |
82 |
int frontWalls=0, frontSegments=0, sideWalls=0, sideBends=0, triangleShifts=0, windingShifts=0;
|
|
84 |
int frontWalls=0, frontSegments=0, sideWalls=0, triangleShifts=0, windingShifts=0; |
|
83 | 85 |
int shiftCol = (mCols-1)/2; |
84 | 86 |
|
85 |
//boolean seenLand=false; |
|
86 |
//boolean firstBlockIsNE=false; |
|
87 | 87 |
boolean lastBlockIsNE=false; |
88 | 88 |
boolean thisBlockIsNE; // the block we are currently looking at is split into |
89 | 89 |
// two triangles along the NE-SW line (rather than NW-SE) |
90 |
|
|
91 | 90 |
for(int row=0; row<mRows; row++) |
92 | 91 |
{ |
93 | 92 |
if( mCols>=2 && (mCubes[row][shiftCol]%2 == 1) && (mCubes[row][shiftCol+1]%2 == 1) ) triangleShifts++; |
... | ... | |
99 | 98 |
thisBlockIsNE = isNE(row,col); |
100 | 99 |
if( thisBlockIsNE^lastBlockIsNE ) windingShifts++; |
101 | 100 |
lastBlockIsNE = thisBlockIsNE; |
102 |
/* |
|
103 |
if( !seenLand ) |
|
104 |
{ |
|
105 |
seenLand=true; |
|
106 |
firstBlockIsNE = thisBlockIsNE; |
|
107 |
} |
|
108 |
*/ |
|
109 | 101 |
frontWalls++; |
110 | 102 |
if( col==mCols-1 || mCubes[row][col+1]%2 == 0 ) frontSegments++; |
111 | 103 |
} |
... | ... | |
117 | 109 |
} |
118 | 110 |
} |
119 | 111 |
|
120 |
int edges= mEdges.size(); |
|
121 |
|
|
122 |
for(int i=0; i<edges; i++) |
|
123 |
{ |
|
124 |
Edge curr = mEdges.get(i); |
|
125 |
Edge next = getNextEdge(curr); |
|
126 |
int startX = curr.col; |
|
127 |
int startY = curr.row; |
|
128 |
int startS = curr.side; |
|
129 |
|
|
130 |
do |
|
131 |
{ |
|
132 |
if( next.side != curr.side ) sideBends++; |
|
133 |
curr = next; |
|
134 |
next = getNextEdge(curr); |
|
135 |
} |
|
136 |
while( curr.col!=startX || curr.row!=startY || curr.side!=startS ); |
|
137 |
} |
|
138 |
|
|
139 | 112 |
int frontVert = 2*( frontWalls + 2*frontSegments - 1) +2*triangleShifts + windingShifts; |
140 |
int sideVert = 2*( sideWalls + sideBends + edges -1); |
|
141 |
int firstWinding=0; |
|
142 |
//int secondWinding=0; |
|
143 |
|
|
144 |
if( !frontOnly ) |
|
145 |
{ |
|
146 |
if( (frontVert+1)%2==1 ) firstWinding=1; |
|
147 |
//if( (((frontVert+1)+firstWinding+(1+sideVert+1))%2==1)^firstBlockIsNE ) secondWinding=1; |
|
148 |
} |
|
149 |
|
|
113 |
int sideVert = 2*( sideWalls + mSideBends + mEdgeNum -1); |
|
114 |
int firstWinding= (!frontOnly && (frontVert+1)%2==1 ) ? 1:0; |
|
150 | 115 |
int dataL = frontOnly ? frontVert : (frontVert+1) +firstWinding+ (1+sideVert+1) + (1+frontVert); |
151 |
|
|
152 |
//android.util.Log.e("CUBES","triangleShifts="+triangleShifts+" windingShifts="+windingShifts); |
|
153 |
//android.util.Log.e("CUBES","Winding1="+firstWinding+" Winding2="+secondWinding); |
|
154 |
//android.util.Log.e("CUBES","frontVert="+frontVert+" sideVert="+sideVert); |
|
155 |
//android.util.Log.e("CUBES", "frontW="+frontWalls+" fSegments="+frontSegments+" sWalls="+sideWalls+" sSegments="+edges+" sideBends="+sideBends+" dataLen="+dataL ); |
|
156 |
|
|
116 |
/* |
|
117 |
android.util.Log.e("CUBES","triangleShifts="+triangleShifts+" windingShifts="+windingShifts); |
|
118 |
android.util.Log.e("CUBES","Winding1="+firstWinding+" frontVert="+frontVert+" sideVert="+sideVert); |
|
119 |
android.util.Log.e("CUBES", "frontW="+frontWalls+" fSegments="+frontSegments+" sWalls="+sideWalls+" sSegments="+mEdgeNum+" sideBends="+mSideBends+" dataLen="+dataL ); |
|
120 |
*/ |
|
157 | 121 |
return dataL<0 ? 0:dataL; |
158 | 122 |
} |
159 | 123 |
|
... | ... | |
201 | 165 |
|
202 | 166 |
return d; |
203 | 167 |
} |
204 |
*/
|
|
168 |
*/ |
|
205 | 169 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
206 | 170 |
// desc is guaranteed to be padded with 0s in the end (DistortedCubes constructor does it) |
207 | 171 |
|
... | ... | |
262 | 226 |
// |
263 | 227 |
// This function also creates a list of 'Edges'. Each Edge is a data structure from which later on we |
264 | 228 |
// will start building the side walls of each connected block of land (and sides of holes of water |
265 |
// inside) |
|
229 |
// inside). Each Edge needs to point from Land to Water (thus the '(SOUTH,i-1,j)' below) - otherwise |
|
230 |
// later on setting up normal vectors wouldn't work. |
|
266 | 231 |
|
267 | 232 |
private void markRegions() |
268 | 233 |
{ |
... | ... | |
276 | 241 |
for(i=0; i<mRows; i++) |
277 | 242 |
for(j=0; j<mCols; j++) |
278 | 243 |
{ |
279 |
if( mCubes[i][j] == 0 ) { numWater++; markRegion( (short)(2*numWater ),i,j); mEdges.add(new Edge(NORTH,i,j)); }
|
|
280 |
if( mCubes[i][j] == 1 ) { numLand ++; markRegion( (short)(2*numLand+1),i,j); mEdges.add(new Edge(NORTH,i,j)); } |
|
244 |
if( mCubes[i][j] == 0 ) { numWater++; markRegion( (short)(2*numWater ),i,j); mEdges.add(new Edge(SOUTH,i-1,j)); }
|
|
245 |
if( mCubes[i][j] == 1 ) { numLand ++; markRegion( (short)(2*numLand+1),i,j); mEdges.add(new Edge(NORTH,i ,j)); }
|
|
281 | 246 |
} |
282 | 247 |
|
283 |
// now we potentially need to kick out some Edges - precisely the edges with water inside - |
|
284 |
// which are surrounded by more than one type of land. Otherwise the following does not work: |
|
248 |
// now we potentially need to kick out some Edges . Otherwise the following does not work: |
|
285 | 249 |
// |
286 | 250 |
// 0 1 0 |
287 | 251 |
// 1 0 1 |
288 | 252 |
// 0 1 0 |
289 |
// |
|
290 |
// The 'water inside' edges that did not get kicked out by this procedure need to be transformed |
|
291 |
// with Edge(NORTH,row,col) -> Edge(SOUTH,row-1,col) so that later on normals work correctly |
|
292 |
// (Edge always needs to point out from land to water for that) |
|
293 | 253 |
|
294 |
int numEdges= mEdges.size(); |
|
295 |
short initLand; |
|
296 |
int initCol, initRow; |
|
297 |
boolean kicked; |
|
298 |
Edge e; |
|
254 |
mEdgeNum= mEdges.size(); |
|
255 |
int initCol, initRow, initSide, lastSide; |
|
256 |
Edge e1,e2; |
|
299 | 257 |
|
300 |
for(i=0; i<numEdges; i++)
|
|
258 |
for(i=0; i<mEdgeNum; i++)
|
|
301 | 259 |
{ |
302 |
e = mEdges.get(i); |
|
303 |
initRow= e.row; |
|
304 |
initCol= e.col; |
|
305 |
|
|
306 |
//android.util.Log.e("CUBES", "checking edge "+debug(e)); |
|
307 |
|
|
308 |
if( mCubes[initRow][initCol]%2==0 ) |
|
260 |
e1 = mEdges.get(i); |
|
261 |
initRow= e1.row; |
|
262 |
initCol= e1.col; |
|
263 |
initSide=e1.side; |
|
264 |
|
|
265 |
do |
|
309 | 266 |
{ |
310 |
kicked = false; |
|
311 |
initLand = mCubes[initRow-1][initCol]; |
|
312 |
|
|
313 |
do |
|
267 |
//android.util.Log.d("CUBES", "checking edge "+debug(e1)); |
|
268 |
|
|
269 |
if( e1.side==NORTH || e1.side==SOUTH ) |
|
314 | 270 |
{ |
315 |
e = getNextEdge(e); |
|
316 |
//android.util.Log.e("CUBES", " next edge "+debug(e)); |
|
317 |
|
|
318 |
switch(e.side) |
|
271 |
for(j=i+1;j<mEdgeNum;j++) |
|
319 | 272 |
{ |
320 |
case NORTH: if( initLand!=mCubes[e.row-1][e.col ] ) kicked=true; break; |
|
321 |
case SOUTH: if( initLand!=mCubes[e.row+1][e.col ] ) kicked=true; break; |
|
322 |
case WEST: if( initLand!=mCubes[e.row ][e.col-1] ) kicked=true; break; |
|
323 |
case EAST: if( initLand!=mCubes[e.row ][e.col+1] ) kicked=true; break; |
|
324 |
} |
|
325 |
|
|
326 |
if( kicked ) |
|
327 |
{ |
|
328 |
//android.util.Log.e("CUBES", "kicking out edge!"); |
|
329 |
mEdges.remove(i); |
|
330 |
i--; |
|
331 |
numEdges--; |
|
273 |
e2 = mEdges.get(j); |
|
274 |
|
|
275 |
if( e2.side==e1.side && e2.row==e1.row && e2.col==e1.col ) |
|
276 |
{ |
|
277 |
mEdges.remove(j); |
|
278 |
mEdgeNum--; |
|
279 |
j--; |
|
280 |
|
|
281 |
//android.util.Log.e("CUBES", "removing edge "+debug(e2)); |
|
282 |
} |
|
332 | 283 |
} |
333 | 284 |
} |
334 |
while( kicked==false && (e.col!=initCol || e.row!=initRow || e.side!=NORTH) ); |
|
335 |
|
|
336 |
if( kicked==false ) |
|
337 |
{ |
|
338 |
mEdges.set(i, new Edge(SOUTH,e.row-1,e.col)); |
|
339 |
} |
|
285 |
|
|
286 |
lastSide = e1.side; |
|
287 |
e1 = getNextEdge(e1); |
|
288 |
if( e1.side!=lastSide ) mSideBends++; |
|
340 | 289 |
} |
290 |
while( e1.col!=initCol || e1.row!=initRow || e1.side!=initSide ); |
|
341 | 291 |
} |
342 | 292 |
} |
343 | 293 |
|
... | ... | |
555 | 505 |
{ |
556 | 506 |
//android.util.Log.d("CUBES", "buildSide"); |
557 | 507 |
|
558 |
int edges= mEdges.size(); |
|
559 |
|
|
560 |
for(int i=0; i<edges; i++) |
|
508 |
for(int i=0; i<mEdgeNum; i++) |
|
561 | 509 |
{ |
562 | 510 |
vertex = buildIthSide(mEdges.get(i), vertex, position, normal, texture); |
563 | 511 |
} |
... | ... | |
653 | 601 |
else |
654 | 602 |
return new Edge(SOUTH,row,col); |
655 | 603 |
|
656 |
case WEST : if( row==0 )
|
|
604 |
default : if( row==0 )
|
|
657 | 605 |
return new Edge(NORTH,row,col); |
658 | 606 |
if( col>0 && mCubes[row-1][col-1]==mCubes[row][col] ) |
659 | 607 |
return new Edge(SOUTH,row-1,col-1); |
... | ... | |
662 | 610 |
else |
663 | 611 |
return new Edge(NORTH,row,col); |
664 | 612 |
} |
665 |
|
|
666 |
return null; |
|
667 | 613 |
} |
668 | 614 |
|
669 | 615 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
777 | 723 |
android.util.Log.d("CUBES", "texture: " +debug( textureData,2) ); |
778 | 724 |
*/ |
779 | 725 |
|
726 |
mEdges.clear(); |
|
727 |
mEdges = null; |
|
728 |
mCubes = null; |
|
729 |
|
|
780 | 730 |
if( remainingVert!=0 ) |
781 | 731 |
android.util.Log.d("CUBES", "remainingVert " +remainingVert ); |
782 | 732 |
|
Also available in: Unified diff
Fix a long-standing buf in CubesGrid (incorrect Grid in case of 5x5 11111 11011 10101 11011 11111)