Project

General

Profile

« Previous | Next » 

Revision 91cfe462

Added by Leszek Koltunski about 5 years ago

1) new 'Rubik' app (skeleton)
2) MeshCubes: add support for custom texture mappings on each side (Rubik needs that!)

View differences:

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