Revision 8d9da98a
Added by Leszek Koltunski almost 9 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)