Revision 84ee2a6a
Added by Leszek Koltunski over 8 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