Revision 91cfe462
Added by Leszek Koltunski almost 6 years ago
src/main/java/org/distorted/library/mesh/MeshCubes.java | ||
---|---|---|
19 | 19 |
|
20 | 20 |
package org.distorted.library.mesh; |
21 | 21 |
|
22 |
import org.distorted.library.type.Static4D; |
|
23 |
|
|
22 | 24 |
import java.util.ArrayList; |
23 | 25 |
|
24 | 26 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
25 | 27 |
/** |
26 | 28 |
* Create a 3D grid composed of Cubes. |
27 | 29 |
* <p> |
28 |
* Any subset of a MxNx1 cuboid is possible. |
|
30 |
* Any subset of a MxNx1 cuboid is possible. (repeated arbitrary number of times into Z-dir)
|
|
29 | 31 |
*/ |
30 | 32 |
public class MeshCubes extends MeshBase |
31 | 33 |
{ |
32 | 34 |
private static final float R = 0.0f;//0.2f; |
33 | 35 |
|
36 |
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 |
|
|
34 | 43 |
private static final int NORTH = 0; |
35 | 44 |
private static final int WEST = 1; |
36 | 45 |
private static final int EAST = 2; |
... | ... | |
53 | 62 |
col = c; |
54 | 63 |
} |
55 | 64 |
} |
56 |
|
|
65 |
|
|
66 |
private float[] mTexMappingX,mTexMappingY, mTexMappingW, mTexMappingH; |
|
67 |
|
|
57 | 68 |
private int mCols, mRows, mSlices; |
58 | 69 |
private int[][] mCubes; |
59 | 70 |
private byte[][] mInflateX, mInflateY; |
... | ... | |
74 | 85 |
return ( (2*row<mRows)^(2*col<mCols) ); |
75 | 86 |
} |
76 | 87 |
|
88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
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 |
mTexMappingX[FRONT] = front.get1(); |
|
105 |
mTexMappingY[FRONT] = front.get2(); |
|
106 |
mTexMappingW[FRONT] = front.get3() - front.get1(); |
|
107 |
mTexMappingH[FRONT] = front.get4() - front.get2(); |
|
108 |
|
|
109 |
mTexMappingX[BACK] = back.get1(); |
|
110 |
mTexMappingY[BACK] = back.get2(); |
|
111 |
mTexMappingW[BACK] = back.get3() - back.get1(); |
|
112 |
mTexMappingH[BACK] = back.get4() - back.get2(); |
|
113 |
|
|
114 |
mTexMappingX[LEFT] = left.get1(); |
|
115 |
mTexMappingY[LEFT] = left.get2(); |
|
116 |
mTexMappingW[LEFT] = left.get3() - left.get1(); |
|
117 |
mTexMappingH[LEFT] = left.get4() - left.get2(); |
|
118 |
|
|
119 |
mTexMappingX[RIGHT] = right.get1(); |
|
120 |
mTexMappingY[RIGHT] = right.get2(); |
|
121 |
mTexMappingW[RIGHT] = right.get3() - right.get1(); |
|
122 |
mTexMappingH[RIGHT] = right.get4() - right.get2(); |
|
123 |
|
|
124 |
mTexMappingX[TOP] = top.get1(); |
|
125 |
mTexMappingY[TOP] = top.get2(); |
|
126 |
mTexMappingW[TOP] = top.get3() - top.get1(); |
|
127 |
mTexMappingH[TOP] = top.get4() - top.get2(); |
|
128 |
|
|
129 |
mTexMappingX[BOTTOM] = bottom.get1(); |
|
130 |
mTexMappingY[BOTTOM] = bottom.get2(); |
|
131 |
mTexMappingW[BOTTOM] = bottom.get3() - bottom.get1(); |
|
132 |
mTexMappingH[BOTTOM] = bottom.get4() - bottom.get2(); |
|
133 |
} |
|
134 |
|
|
77 | 135 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
78 | 136 |
// return the number of vertices our grid will contain |
79 | 137 |
|
... | ... | |
126 | 184 |
} |
127 | 185 |
*/ |
128 | 186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
129 |
|
|
187 |
/* |
|
130 | 188 |
private static String debug(float[] val, int stop) |
131 | 189 |
{ |
132 | 190 |
String ret=""; |
... | ... | |
156 | 214 |
|
157 | 215 |
return ret; |
158 | 216 |
} |
159 |
|
|
217 |
*/ |
|
160 | 218 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
161 | 219 |
/* |
162 | 220 |
private static String debug(Edge e) |
... | ... | |
251 | 309 |
// |
252 | 310 |
// This function also creates a list of 'Edges'. Each Edge is a data structure from which later on we |
253 | 311 |
// will start building the side walls of each connected block of land (and sides of holes of water |
254 |
// inside). Each Edge needs to point from Land to Water (thus the '(SOUTH,i-1,j)' below) - otherwise
|
|
312 |
// inside). Each Edge needs to point from Land to Water (thus the '(SOUTH,row-1,col)' below) - otherwise
|
|
255 | 313 |
// later on setting up normal vectors wouldn't work. |
256 | 314 |
|
257 | 315 |
private void markRegions() |
258 | 316 |
{ |
259 |
int i, j, numWater=1, numLand=0;
|
|
317 |
int row, col, numWater=1, numLand=0;
|
|
260 | 318 |
|
261 |
for(i=0; i<mRows;i++) if( mCubes[ i][ 0]==0 ) markRegion((short)2, i, 0);
|
|
262 |
for(i=0; i<mRows;i++) if( mCubes[ i][mCols-1]==0 ) markRegion((short)2, i, mCols-1);
|
|
263 |
for(i=0; i<mCols;i++) if( mCubes[0 ][ i]==0 ) markRegion((short)2, 0, i);
|
|
264 |
for(i=0; i<mCols;i++) if( mCubes[mRows-1][ i]==0 ) markRegion((short)2,mRows-1, i);
|
|
319 |
for(row=0; row<mRows; row++) if( mCubes[ row][ 0]==0 ) markRegion((short)2, row, 0);
|
|
320 |
for(row=0; row<mRows; row++) if( mCubes[ row][mCols-1]==0 ) markRegion((short)2, row, mCols-1);
|
|
321 |
for(col=0; col<mCols; col++) if( mCubes[0 ][ col]==0 ) markRegion((short)2, 0, col);
|
|
322 |
for(col=0; col<mCols; col++) if( mCubes[mRows-1][ col]==0 ) markRegion((short)2,mRows-1, col);
|
|
265 | 323 |
|
266 |
for(i=0; i<mRows; i++)
|
|
267 |
for(j=0; j<mCols; j++)
|
|
324 |
for(row=0; row<mRows; row++)
|
|
325 |
for(col=0; col<mCols; col++)
|
|
268 | 326 |
{ |
269 |
if( mCubes[i][j] == 0 ) { numWater++; markRegion( (short)(2*numWater ),i,j); mEdges.add(new Edge(SOUTH,i-1,j)); }
|
|
270 |
if( mCubes[i][j] == 1 ) { numLand ++; markRegion( (short)(2*numLand+1),i,j); mEdges.add(new Edge(NORTH,i ,j)); }
|
|
327 |
if( mCubes[row][col] == 0 ) { numWater++; markRegion( (short)(2*numWater ),row,col); mEdges.add(new Edge(SOUTH,row-1,col)); }
|
|
328 |
if( mCubes[row][col] == 1 ) { numLand ++; markRegion( (short)(2*numLand+1),row,col); mEdges.add(new Edge(NORTH,row ,col)); }
|
|
271 | 329 |
} |
272 | 330 |
|
273 | 331 |
// now we potentially need to kick out some Edges . Otherwise the following does not work: |
... | ... | |
280 | 338 |
int initCol, initRow, initSide, lastSide; |
281 | 339 |
Edge e1,e2; |
282 | 340 |
|
283 |
for(i=0; i<mEdgeNum; i++)
|
|
341 |
for(int edge=0; edge<mEdgeNum; edge++)
|
|
284 | 342 |
{ |
285 |
e1 = mEdges.get(i);
|
|
343 |
e1 = mEdges.get(edge);
|
|
286 | 344 |
initRow= e1.row; |
287 | 345 |
initCol= e1.col; |
288 | 346 |
initSide=e1.side; |
... | ... | |
295 | 353 |
|
296 | 354 |
if( e1.side==NORTH || e1.side==SOUTH ) |
297 | 355 |
{ |
298 |
for(j=i+1;j<mEdgeNum;j++)
|
|
356 |
for(int j=edge+1;j<mEdgeNum;j++)
|
|
299 | 357 |
{ |
300 | 358 |
e2 = mEdges.get(j); |
301 | 359 |
|
... | ... | |
450 | 508 |
if( !lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs); |
451 | 509 |
addFrontVertex( 1, vectZ, col, row+1, attribs); |
452 | 510 |
} |
453 |
addFrontVertex( 2, vectZ, col+1, row, attribs); |
|
511 |
addFrontVertex( 2, vectZ, col+1, row , attribs);
|
|
454 | 512 |
addFrontVertex( 3, vectZ, col+1, row+1, attribs); |
455 | 513 |
} |
456 | 514 |
else |
... | ... | |
660 | 718 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f; |
661 | 719 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = vectZ; |
662 | 720 |
|
663 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = x; |
|
664 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = 1.0f-y; |
|
721 |
if( vectZ>0 ) |
|
722 |
{ |
|
723 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[FRONT] + x * mTexMappingW[FRONT]; |
|
724 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[FRONT] + (1.0f-y) * mTexMappingH[FRONT]; |
|
725 |
} |
|
726 |
else |
|
727 |
{ |
|
728 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[BACK] + x * mTexMappingW[BACK]; |
|
729 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BACK] + (1.0f-y) * mTexMappingH[BACK]; |
|
730 |
} |
|
665 | 731 |
|
666 | 732 |
currVert++; |
667 | 733 |
} |
... | ... | |
672 | 738 |
{ |
673 | 739 |
//android.util.Log.e("CUBES", "adding Side vertex!"); |
674 | 740 |
float x, y, z; |
675 |
int row, col, texX, texY;
|
|
741 |
int row, col; |
|
676 | 742 |
|
677 | 743 |
switch(curr.side) |
678 | 744 |
{ |
... | ... | |
694 | 760 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f; |
695 | 761 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z; |
696 | 762 |
|
697 |
texY = (mRows-row+slice)%(2*mRows); |
|
698 |
if( texY>mRows ) texY = 2*mRows-texY; |
|
699 |
|
|
700 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = x; |
|
701 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = (float)texY/mRows; |
|
763 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[TOP] + x * mTexMappingW[TOP]; |
|
764 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[TOP] + (0.5f-z) * mTexMappingH[TOP]; |
|
702 | 765 |
|
703 | 766 |
break; |
704 | 767 |
case SOUTH: row = curr.row+1; |
... | ... | |
719 | 782 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f; |
720 | 783 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z; |
721 | 784 |
|
722 |
texY = (mRows-row+slice)%(2*mRows); |
|
723 |
if( texY>mRows ) texY = 2*mRows-texY; |
|
724 |
|
|
725 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = x; |
|
726 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = (float)texY/mRows; |
|
785 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[BOTTOM] + x * mTexMappingW[BOTTOM]; |
|
786 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BOTTOM] + (0.5f-z) * mTexMappingH[BOTTOM]; |
|
727 | 787 |
|
728 | 788 |
break; |
729 | 789 |
case WEST : row = (back ? (curr.row+1):(curr.row)); |
... | ... | |
744 | 804 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f; |
745 | 805 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z; |
746 | 806 |
|
747 |
texX = (col+slice)%(2*mCols); |
|
748 |
if( texX>mCols ) texX = 2*mCols-texX; |
|
749 |
|
|
750 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = (float)texX/mCols; |
|
751 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = 1.0f-y; |
|
807 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[LEFT] + (0.5f-z) * mTexMappingW[LEFT]; |
|
808 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[LEFT] + (1.0f-y) * mTexMappingH[LEFT]; |
|
752 | 809 |
|
753 | 810 |
break; |
754 | 811 |
case EAST : row = (back ? (curr.row):(curr.row+1)); |
... | ... | |
769 | 826 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f; |
770 | 827 |
attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z; |
771 | 828 |
|
772 |
texX = (col+slice)%(2*mCols); |
|
773 |
if( texX>mCols ) texX = 2*mCols-texX; |
|
774 |
|
|
775 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = (float)texX/mCols; |
|
776 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = 1.0f-y; |
|
829 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB ] = mTexMappingX[RIGHT] + (0.5f-z) * mTexMappingW[RIGHT]; |
|
830 |
attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[RIGHT] + (1.0f-y) * mTexMappingH[RIGHT]; |
|
777 | 831 |
|
778 | 832 |
break; |
779 | 833 |
} |
... | ... | |
845 | 899 |
* <p></p> |
846 | 900 |
* <p> |
847 | 901 |
* <pre> |
848 |
* For example, (cols=2, desc="111010") describes the following shape: |
|
902 |
* For example, (cols=2, desc="111010", slices=1) describes the following shape:
|
|
849 | 903 |
* |
850 | 904 |
* XX |
851 | 905 |
* X |
852 | 906 |
* X |
853 | 907 |
* |
854 |
* whereas (cols=2,desc="110001") describes |
|
908 |
* whereas (cols=2,desc="110001", slices=1) describes
|
|
855 | 909 |
* |
856 | 910 |
* XX |
857 | 911 |
* |
... | ... | |
863 | 917 |
public MeshCubes(int cols, String desc, int slices) |
864 | 918 |
{ |
865 | 919 |
super( (float)slices/cols); |
920 |
|
|
921 |
Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f); |
|
922 |
fillTexMappings(map,map,map,map,map,map); |
|
923 |
prepareDataStructures(cols,desc,slices); |
|
924 |
build(); |
|
925 |
} |
|
926 |
|
|
927 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
928 |
/** |
|
929 |
* Creates the underlying mesh of vertices, normals, texture coords with custom texture mappings. |
|
930 |
* |
|
931 |
* The mappings decide what part of the texture appears on a given side. Example: |
|
932 |
* front = (0.0,0.5,0.5,1.0) means that the front side of the grid will be textured with the |
|
933 |
* bottom-left quadrant of the texture. |
|
934 |
* |
|
935 |
* Default is: each of the 6 sides maps to the whole texture, i.e. (0.0,0.0,1.0,1.0) |
|
936 |
* |
|
937 |
* @param cols Integer helping to parse the next parameter. |
|
938 |
* @param desc String describing the subset of a MxNx1 cuboid that we want to create. |
|
939 |
* Its MxN characters - all 0 or 1 - decide of appropriate field is taken or not. |
|
940 |
* <p></p> |
|
941 |
* <p> |
|
942 |
* <pre> |
|
943 |
* For example, (cols=2, desc="111010", slices=1) describes the following shape: |
|
944 |
* |
|
945 |
* XX |
|
946 |
* X |
|
947 |
* X |
|
948 |
* |
|
949 |
* whereas (cols=2,desc="110001", slices=1) describes |
|
950 |
* |
|
951 |
* XX |
|
952 |
* |
|
953 |
* X |
|
954 |
* </pre> |
|
955 |
* </p> |
|
956 |
* @param slices Number of slices, i.e. 'depth' of the Mesh. |
|
957 |
* @param front Texture mapping the front side maps to. |
|
958 |
* @param back Texture mapping the back side maps to. |
|
959 |
* @param left Texture mapping the left side maps to. |
|
960 |
* @param right Texture mapping the right side maps to. |
|
961 |
* @param top Texture mapping the top side maps to. |
|
962 |
* @param bottom Texture mapping the bottom side maps to. |
|
963 |
*/ |
|
964 |
public MeshCubes(int cols, String desc, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom) |
|
965 |
{ |
|
966 |
super( (float)slices/cols); |
|
967 |
fillTexMappings(front,back,left,right,top,bottom); |
|
866 | 968 |
prepareDataStructures(cols,desc,slices); |
867 | 969 |
build(); |
868 | 970 |
} |
... | ... | |
878 | 980 |
public MeshCubes(int cols, int rows, int slices) |
879 | 981 |
{ |
880 | 982 |
super( (float)slices/cols); |
983 |
|
|
984 |
Static4D map = new Static4D(0.0f,0.0f,1.0f,1.0f); |
|
985 |
fillTexMappings(map,map,map,map,map,map); |
|
986 |
prepareDataStructures(cols,rows,slices); |
|
987 |
build(); |
|
988 |
} |
|
989 |
|
|
990 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
991 |
/** |
|
992 |
* Creates a full, hole-less underlying mesh of vertices, normals, texture coords and colors with |
|
993 |
* custom texture mappings. |
|
994 |
* |
|
995 |
* The mappings decide what part of the texture appears on a given side. Example: |
|
996 |
* front = (0.0,0.5,0.5,1.0) means that the front side of the grid will be textured with the |
|
997 |
* bottom-left quadrant of the texture. |
|
998 |
* |
|
999 |
* Default is: each of the 6 sides maps to the whole texture, i.e. (0.0,0.0,1.0,1.0) |
|
1000 |
* |
|
1001 |
* @param cols Number of columns, i.e. 'width' of the Mesh. |
|
1002 |
* @param rows Number of rows, i.e. 'height' of the Mesh. |
|
1003 |
* @param slices Number of slices, i.e. 'depth' of the Mesh. |
|
1004 |
* @param front Texture mapping the front side maps to. |
|
1005 |
* @param back Texture mapping the back side maps to. |
|
1006 |
* @param left Texture mapping the left side maps to. |
|
1007 |
* @param right Texture mapping the right side maps to. |
|
1008 |
* @param top Texture mapping the top side maps to. |
|
1009 |
* @param bottom Texture mapping the bottom side maps to. |
|
1010 |
*/ |
|
1011 |
public MeshCubes(int cols, int rows, int slices, Static4D front, Static4D back, Static4D left, Static4D right, Static4D top, Static4D bottom) |
|
1012 |
{ |
|
1013 |
super( (float)slices/cols); |
|
1014 |
fillTexMappings(front,back,left,right,top,bottom); |
|
881 | 1015 |
prepareDataStructures(cols,rows,slices); |
882 | 1016 |
build(); |
883 | 1017 |
} |
Also available in: Unified diff
1) new 'Rubik' app (skeleton)
2) MeshCubes: add support for custom texture mappings on each side (Rubik needs that!)