Revision 84ee2a6a
Added by Leszek Koltunski about 9 years ago
| src/main/java/org/distorted/library/DistortedCubesGrid.java | ||
|---|---|---|
| 68 | 68 |
private short[][] mCubes; |
| 69 | 69 |
private ArrayList<Edge> mEdges = new ArrayList<>(); |
| 70 | 70 |
|
| 71 |
private boolean addEmpty1; // add an initial empty vertex? ( that would be because the initial block |
|
| 72 |
// of land is in the top-right quarter (or bottom-left) and thus the very |
|
| 73 |
// first triangle is counter-clockwise) |
|
| 74 |
private boolean addEmpty2; // add an empty vertex when shifting from front to the side (that happens |
|
| 75 |
// iff the last front block is in the front-left or bottom-right quarter) |
|
| 76 |
private boolean addEmpty3; // add an empty vertex when shifting from the side to the back. (that |
|
| 77 |
// happens iff the first back block is in the top right or bottom-left |
|
| 78 |
// quarter, i.e. actually addEmpty3 = addEmpty1. |
|
| 71 |
private int remainingVert; |
|
| 79 | 72 |
|
| 80 | 73 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 81 | 74 |
// a Block is split into two triangles along the NE-SW line iff it is in the top-right |
| ... | ... | |
| 87 | 80 |
} |
| 88 | 81 |
|
| 89 | 82 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 83 |
// return the number of vertices our grid will contain |
|
| 90 | 84 |
|
| 91 | 85 |
private int computeDataLength(boolean frontOnly) |
| 92 | 86 |
{
|
| 93 |
int frontWalls=0, frontSegments=0, sideWalls=0, sideBends=0, triangleShifts=0, rowJumpShifts=0;
|
|
| 87 |
int frontWalls=0, frontSegments=0, sideWalls=0, sideBends=0, triangleShifts=0, windingShifts=0;
|
|
| 94 | 88 |
int shiftCol = (mCols-1)/2; |
| 95 | 89 |
|
| 96 |
boolean seenLand=false; |
|
| 90 |
//boolean seenLand=false; |
|
| 91 |
//boolean firstBlockIsNE=false; |
|
| 97 | 92 |
boolean lastBlockIsNE=false; |
| 98 |
boolean seenBlockInRow; |
|
| 99 | 93 |
boolean thisBlockIsNE; // the block we are currently looking at is split into |
| 100 | 94 |
// two triangles along the NE-SW line (rather than NW-SE) |
| 101 | 95 |
|
| ... | ... | |
| 103 | 97 |
{
|
| 104 | 98 |
if( mCols>=2 && (mCubes[i][shiftCol]%2 == 1) && (mCubes[i][shiftCol+1]%2 == 1) ) triangleShifts++; |
| 105 | 99 |
|
| 106 |
seenBlockInRow=false; |
|
| 107 |
|
|
| 108 | 100 |
for(int j=0; j<mCols; j++) |
| 109 | 101 |
{
|
| 110 | 102 |
if( mCubes[i][j]%2 == 1 ) // land |
| 111 | 103 |
{
|
| 112 | 104 |
thisBlockIsNE = isNE(i,j); |
| 113 |
|
|
| 114 |
if( !seenBlockInRow ) |
|
| 115 |
{
|
|
| 116 |
if( thisBlockIsNE^lastBlockIsNE ) rowJumpShifts++; |
|
| 117 |
seenBlockInRow=true; |
|
| 118 |
} |
|
| 119 |
|
|
| 105 |
if( thisBlockIsNE^lastBlockIsNE ) windingShifts++; |
|
| 120 | 106 |
lastBlockIsNE = thisBlockIsNE; |
| 121 |
|
|
| 107 |
/* |
|
| 122 | 108 |
if( !seenLand ) |
| 123 | 109 |
{
|
| 124 |
addEmpty1 = addEmpty3 = lastBlockIsNE; |
|
| 125 | 110 |
seenLand=true; |
| 111 |
firstBlockIsNE = thisBlockIsNE; |
|
| 126 | 112 |
} |
| 127 |
|
|
| 113 |
*/ |
|
| 128 | 114 |
frontWalls++; |
| 129 | 115 |
if( j==mCols-1 || mCubes[i][j+1]%2 == 0 ) frontSegments++; |
| 130 | 116 |
} |
| ... | ... | |
| 136 | 122 |
} |
| 137 | 123 |
} |
| 138 | 124 |
|
| 139 |
addEmpty2 = !lastBlockIsNE; |
|
| 140 |
|
|
| 141 | 125 |
int edges= mEdges.size(); |
| 142 | 126 |
|
| 143 | 127 |
for(int i=0; i<edges; i++) |
| ... | ... | |
| 157 | 141 |
while( curr.col!=startX || curr.row!=startY || curr.side!=startS ); |
| 158 | 142 |
} |
| 159 | 143 |
|
| 160 |
int frontVert = 2*( frontWalls + 2*frontSegments - 1) +3*triangleShifts + rowJumpShifts;
|
|
| 144 |
int frontVert = 2*( frontWalls + 2*frontSegments - 1) +2*triangleShifts + windingShifts;
|
|
| 161 | 145 |
int sideVert = 2*( sideWalls + sideBends + edges -1); |
| 146 |
int firstWinding=0; |
|
| 147 |
//int secondWinding=0; |
|
| 162 | 148 |
|
| 163 |
// no we don't add addEmpty1 because this is already included in the rowJumpShifts |
|
| 164 |
int dataL = frontOnly ? frontVert : (frontVert+1) + (1+sideVert+1) + (1+frontVert) +(addEmpty2?1:0) + (addEmpty3?1:0); |
|
| 149 |
if( !frontOnly ) |
|
| 150 |
{
|
|
| 151 |
if( (frontVert+1)%2==1 ) firstWinding=1; |
|
| 152 |
//if( (((frontVert+1)+firstWinding+(1+sideVert+1))%2==1)^firstBlockIsNE ) secondWinding=1; |
|
| 153 |
} |
|
| 165 | 154 |
|
| 166 |
android.util.Log.e("CUBES","triangleShifts="+triangleShifts+" rowJumpShifts="+rowJumpShifts);
|
|
| 167 |
android.util.Log.e("CUBES","addEmpty1="+addEmpty1+" addEmpty2="+addEmpty2+" addEmpty3="+addEmpty3);
|
|
| 168 |
android.util.Log.e("CUBES","frontVert="+frontVert+" sideVert="+sideVert);
|
|
| 169 |
android.util.Log.e("CUBES", "frontW="+frontWalls+" fSegments="+frontSegments+" sWalls="+sideWalls+" sSegments="+edges+" sideBends="+sideBends+" dataLen="+dataL );
|
|
| 155 |
int dataL = frontOnly ? frontVert : (frontVert+1) +firstWinding+ (1+sideVert+1) + (1+frontVert); |
|
| 156 |
|
|
| 157 |
//android.util.Log.e("CUBES","triangleShifts="+triangleShifts+" windingShifts="+windingShifts);
|
|
| 158 |
//android.util.Log.e("CUBES","Winding1="+firstWinding+" Winding2="+secondWinding);
|
|
| 159 |
//android.util.Log.e("CUBES","frontVert="+frontVert+" sideVert="+sideVert);
|
|
| 160 |
//android.util.Log.e("CUBES", "frontW="+frontWalls+" fSegments="+frontSegments+" sWalls="+sideWalls+" sSegments="+edges+" sideBends="+sideBends+" dataLen="+dataL );
|
|
| 170 | 161 |
|
| 171 | 162 |
return dataL<0 ? 0:dataL; |
| 172 | 163 |
} |
| ... | ... | |
| 238 | 229 |
|
| 239 | 230 |
markRegions(); |
| 240 | 231 |
dataLength = computeDataLength(frontOnly); |
| 232 |
|
|
| 233 |
remainingVert = dataLength; |
|
| 241 | 234 |
} |
| 242 | 235 |
} |
| 243 | 236 |
|
| ... | ... | |
| 422 | 415 |
|
| 423 | 416 |
private int addFrontVertex(int corner, int vertex, float centerX, float centerY, float vectZ, int col, int row, float[] position, float[] normal, float[] texture) |
| 424 | 417 |
{
|
| 418 |
remainingVert--; |
|
| 419 |
/* |
|
| 420 |
switch(corner) |
|
| 421 |
{
|
|
| 422 |
case NW: android.util.Log.e("CUBES", "adding NW vertex!");
|
|
| 423 |
break; |
|
| 424 |
case SW: android.util.Log.e("CUBES", "adding SW vertex!");
|
|
| 425 |
break; |
|
| 426 |
case SE: android.util.Log.e("CUBES", "adding SE vertex!");
|
|
| 427 |
break; |
|
| 428 |
case NE: android.util.Log.e("CUBES", "adding NE vertex!");
|
|
| 429 |
break; |
|
| 430 |
} |
|
| 431 |
*/ |
|
| 425 | 432 |
switch(corner) |
| 426 | 433 |
{
|
| 427 | 434 |
case NW: position[3*vertex ] = (centerX-0.5f)/mCols; |
| ... | ... | |
| 459 | 466 |
normal[3*vertex+2] = mNormalZ[3]; |
| 460 | 467 |
texture[2*vertex ] = (float)(col+1)/mCols; |
| 461 | 468 |
texture[2*vertex+1] = (float)(row+1)/mRows; |
| 469 |
return vertex+1; |
|
| 462 | 470 |
} |
| 463 | 471 |
|
| 464 | 472 |
return vertex; |
| ... | ... | |
| 475 | 483 |
float centerX, centerY; |
| 476 | 484 |
float vectZ = front?FRONTZ:BACKZ; |
| 477 | 485 |
|
| 486 |
//android.util.Log.d("CUBES", "buildFrontBack");
|
|
| 487 |
|
|
| 478 | 488 |
for(int i=0; i<mRows; i++) |
| 479 | 489 |
{
|
| 480 | 490 |
last =0; |
| ... | ... | |
| 488 | 498 |
currentBlockIsNE = isNE(i,j); |
| 489 | 499 |
centerX = j-(mCols-1.0f)/2.0f; |
| 490 | 500 |
centerY = (mRows-1.0f)/2.0f-i; |
| 491 |
|
|
| 501 |
|
|
| 502 |
if( !seenLand && !front && ((vertex%2==1)^currentBlockIsNE) ) |
|
| 503 |
{
|
|
| 504 |
//android.util.Log.d("CUBES","repeating winding2 vertex");
|
|
| 505 |
|
|
| 506 |
vertex = repeatLast(vertex,position,normal,texture); |
|
| 507 |
} |
|
| 508 |
|
|
| 492 | 509 |
createNormals(front,i,j); |
| 493 | 510 |
|
| 494 | 511 |
if( (last!=current) || (lastBlockIsNE^currentBlockIsNE) ) |
| ... | ... | |
| 496 | 513 |
if( seenLand && (last != current) ) vertex = repeatLast(vertex,position,normal,texture); |
| 497 | 514 |
vertex= addFrontVertex( currentBlockIsNE ? NW:SW, vertex, centerX, centerY, vectZ, j, i, position, normal, texture); |
| 498 | 515 |
if( seenLand && (last != current) ) vertex = repeatLast(vertex,position,normal,texture); |
| 499 |
if( lastBlockIsNE^currentBlockIsNE ) vertex = repeatLast(vertex,position,normal,texture); |
|
| 516 |
if( (lastBlockIsNE^currentBlockIsNE) |
|
| 517 |
|| (!front && !seenLand) ) vertex = repeatLast(vertex,position,normal,texture); |
|
| 500 | 518 |
vertex= addFrontVertex( currentBlockIsNE ? SW:NW, vertex, centerX, centerY, vectZ, j, i, position, normal, texture); |
| 501 | 519 |
} |
| 502 | 520 |
vertex= addFrontVertex( currentBlockIsNE ? NE:SE, vertex, centerX, centerY, vectZ, j, i, position, normal, texture); |
| ... | ... | |
| 517 | 535 |
|
| 518 | 536 |
private int repeatLast(int vertex, float[] position, float[] normal, float[] texture) |
| 519 | 537 |
{
|
| 538 |
remainingVert--; |
|
| 539 |
|
|
| 540 |
//android.util.Log.e("CUBES", "repeating last vertex!");
|
|
| 541 |
|
|
| 520 | 542 |
if( vertex>0 ) |
| 521 | 543 |
{
|
| 522 | 544 |
position[3*vertex ] = position[3*vertex-3]; |
| ... | ... | |
| 540 | 562 |
|
| 541 | 563 |
private int buildSideGrid(int vertex, float[] position, float[] normal, float[] texture) |
| 542 | 564 |
{
|
| 543 |
int edges= mEdges.size();
|
|
| 565 |
//android.util.Log.d("CUBES", "buildSide");
|
|
| 544 | 566 |
|
| 545 |
if( addEmpty2 ) vertex = repeatLast(vertex,position,normal,texture);
|
|
| 567 |
int edges= mEdges.size();
|
|
| 546 | 568 |
|
| 547 | 569 |
for(int i=0; i<edges; i++) |
| 548 | 570 |
{
|
| ... | ... | |
| 573 | 595 |
int side= curr.side; |
| 574 | 596 |
Edge next = getNextEdge(curr); |
| 575 | 597 |
|
| 576 |
addVertex(curr,BACK,LOWER,prev.side,vertex,position,normal,texture); |
|
| 598 |
addSideVertex(curr,BACK,LOWER,prev.side,vertex,position,normal,texture);
|
|
| 577 | 599 |
vertex++; |
| 578 | 600 |
|
| 579 | 601 |
do |
| 580 | 602 |
{
|
| 581 | 603 |
if( prev.side!=curr.side ) |
| 582 | 604 |
{
|
| 583 |
addVertex(curr,BACK,LOWER,prev.side,vertex,position,normal,texture); |
|
| 605 |
addSideVertex(curr,BACK,LOWER,prev.side,vertex,position,normal,texture);
|
|
| 584 | 606 |
vertex++; |
| 585 |
addVertex(curr,BACK,UPPER,prev.side,vertex,position,normal,texture); |
|
| 607 |
addSideVertex(curr,BACK,UPPER,prev.side,vertex,position,normal,texture);
|
|
| 586 | 608 |
vertex++; |
| 587 | 609 |
} |
| 588 | 610 |
|
| 589 |
addVertex(curr,FRONT,LOWER,next.side,vertex,position,normal,texture); |
|
| 611 |
addSideVertex(curr,FRONT,LOWER,next.side,vertex,position,normal,texture);
|
|
| 590 | 612 |
vertex++; |
| 591 |
addVertex(curr,FRONT,UPPER,next.side,vertex,position,normal,texture); |
|
| 613 |
addSideVertex(curr,FRONT,UPPER,next.side,vertex,position,normal,texture);
|
|
| 592 | 614 |
vertex++; |
| 593 | 615 |
|
| 594 | 616 |
prev = curr; |
| ... | ... | |
| 655 | 677 |
|
| 656 | 678 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 657 | 679 |
|
| 658 |
private void addVertex(Edge curr, boolean back, boolean lower,int side, int vertex, float[] position, float[] normal, float[] texture) |
|
| 680 |
private void addSideVertex(Edge curr, boolean back, boolean lower,int side, int vertex, float[] position, float[] normal, float[] texture)
|
|
| 659 | 681 |
{
|
| 682 |
//android.util.Log.e("CUBES", "adding Side vertex!");
|
|
| 683 |
|
|
| 684 |
remainingVert--; |
|
| 685 |
|
|
| 660 | 686 |
float centerX = curr.col-(mCols-1.0f)/2.0f; |
| 661 | 687 |
float centerY = (mRows-1.0f)/2.0f-curr.row; |
| 662 | 688 |
|
| ... | ... | |
| 739 | 765 |
if( !frontOnly ) |
| 740 | 766 |
{
|
| 741 | 767 |
numVertices = repeatLast(numVertices,positionData,normalData,textureData); |
| 768 |
if( numVertices%2==1 ) |
|
| 769 |
{
|
|
| 770 |
//android.util.Log.d("CUBES","repeating winding1 vertex");
|
|
| 771 |
|
|
| 772 |
numVertices = repeatLast(numVertices,positionData,normalData,textureData); |
|
| 773 |
} |
|
| 742 | 774 |
numVertices = buildSideGrid (numVertices,positionData,normalData,textureData); |
| 743 | 775 |
numVertices = buildFrontBackGrid (false,numVertices,positionData,normalData,textureData); |
| 744 | 776 |
} |
| ... | ... | |
| 749 | 781 |
android.util.Log.d("CUBES", "normal: " +debug( normalData,3) );
|
| 750 | 782 |
android.util.Log.d("CUBES", "texture: " +debug( textureData,2) );
|
| 751 | 783 |
*/ |
| 784 |
android.util.Log.d("CUBES", "remainingVert " +remainingVert );
|
|
| 752 | 785 |
|
| 753 | 786 |
mGridPositions = ByteBuffer.allocateDirect(POSITION_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
| 754 | 787 |
mGridPositions.put(positionData).position(0); |
Also available in: Unified diff
Advanced tesselation of DistortedCubes should be done! This fixes Bug #22