Revision adb2661c
Added by Leszek Koltunski almost 8 years ago
src/main/java/org/distorted/library/DistortedBitmapGrid.java | ||
---|---|---|
26 | 26 |
|
27 | 27 |
class DistortedBitmapGrid extends DistortedObjectGrid |
28 | 28 |
{ |
29 |
private int mCols, mRows; |
|
30 |
private int remainingVert; |
|
29 | 31 |
|
30 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
33 |
// create a flat, full grid |
|
31 | 34 |
|
32 |
DistortedBitmapGrid(int xLength, int yLength) |
|
33 |
{ |
|
34 |
float tmpx,tmpy,tmpz; |
|
35 |
float[] bufferData; |
|
35 |
private void computeNumberOfVertices(int cols, int rows) |
|
36 |
{ |
|
37 |
//android.util.Log.e("BITMAP","preparing data structures, cols="+cols+" rows="+rows); |
|
36 | 38 |
|
37 |
dataLength = 2*xLength*(yLength-1) // (yLength-1) strips, 2*xLength triangles in each, |
|
38 |
+2*(yLength-2); // plus 2 degenerate triangles per each of (yLength-2) joins |
|
39 |
mRows =0; |
|
40 |
mCols =0; |
|
41 |
dataLength=0; |
|
39 | 42 |
|
40 |
if( xLength>2 )
|
|
41 |
{ |
|
42 |
dataLength += 3*(yLength-1); // we change direction of triangles midway through each row (+3 triangles per row)
|
|
43 |
dataLength += (yLength-2); // we also need to change direction when pulling back to the left (+1 extra triangle)
|
|
43 |
if( cols>0 )
|
|
44 |
{
|
|
45 |
mCols = cols;
|
|
46 |
mRows = rows;
|
|
44 | 47 |
|
45 |
if( yLength>2 ) |
|
46 |
dataLength -= 1; // but if we do a vertical triangle direction shift as well, then one of the 'pull backs' |
|
47 |
// does not have to add an extra triangle. |
|
48 |
} |
|
48 |
dataLength = 2*( mRows*mCols +2*mRows - 1) +2*(mCols>=2 ? mRows:0) + |
|
49 |
(mCols>=2 && mRows>=2 ? 2*mRows-2 : 1); |
|
49 | 50 |
|
50 |
//////////////////////////////////////////////////////////// |
|
51 |
// vertex indices |
|
51 |
//android.util.Log.e("BITMAP","vertices="+dataLength); |
|
52 | 52 |
|
53 |
int offset=0; |
|
54 |
final short[] indexData = new short[dataLength]; |
|
53 |
remainingVert = dataLength; |
|
54 |
} |
|
55 |
} |
|
55 | 56 |
|
56 |
int changePointX = xLength/2; |
|
57 |
int changePointY = yLength/2; |
|
58 | 57 |
|
59 |
for(int y=0; y<yLength-1; y++) |
|
60 |
{ |
|
61 |
if( y>0 ) |
|
62 |
{ |
|
63 |
if( y<changePointY ) |
|
64 |
{ |
|
65 |
indexData[offset++] = (short) ((y+1)*xLength); |
|
66 |
if( xLength>2 ) |
|
67 |
indexData[offset++] = (short) ((y+1)*xLength); |
|
68 |
} |
|
69 |
else |
|
70 |
{ |
|
71 |
indexData[offset++] = (short) (y*xLength); |
|
72 |
if( xLength>2 && y!=changePointY) |
|
73 |
indexData[offset++] = (short) (y*xLength); |
|
74 |
} |
|
75 |
} |
|
76 |
|
|
77 |
if (y<changePointY) |
|
78 |
{ |
|
79 |
for(int x=0; x<xLength; x++) |
|
80 |
{ |
|
81 |
if( x<=changePointX ) |
|
82 |
{ |
|
83 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
84 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
85 |
} |
|
86 |
else |
|
87 |
{ |
|
88 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
89 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
90 |
} |
|
91 |
|
|
92 |
if( x==changePointX && xLength>2 ) |
|
93 |
{ |
|
94 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
95 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
96 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
97 |
} |
|
98 |
} |
|
99 |
} |
|
100 |
else |
|
101 |
{ |
|
102 |
for(int x=0; x<xLength; x++) |
|
103 |
{ |
|
104 |
if( x<=changePointX ) |
|
105 |
{ |
|
106 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
107 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
108 |
} |
|
109 |
else |
|
110 |
{ |
|
111 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
112 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
113 |
} |
|
114 |
|
|
115 |
if( x==changePointX && xLength>2 ) |
|
116 |
{ |
|
117 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
118 |
indexData[offset++] = (short) (((y+1)*xLength)+x); |
|
119 |
indexData[offset++] = (short) (( y *xLength)+x); |
|
120 |
} |
|
121 |
} |
|
122 |
} |
|
123 |
|
|
124 |
if (y<changePointY && yLength>2 ) |
|
125 |
{ |
|
126 |
indexData[offset++] = (short) (((y+1)*xLength) + (xLength-1)); |
|
127 |
} |
|
128 |
else if(y<yLength-2) |
|
129 |
{ |
|
130 |
indexData[offset++] = (short) ((y *xLength) + (xLength-1)); |
|
131 |
} |
|
132 |
} |
|
58 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
133 | 59 |
|
134 |
//android.util.Log.e("grid", "xLength="+xLength+" yLength="+yLength); |
|
135 |
//for(int g=0; g<dataLength; g++) android.util.Log.e("grid", "index["+g+"]="+indexData[g]); |
|
60 |
private int addVertex(int vertex, int col, int row, float[] position, float[] normal, float[] texture) |
|
61 |
{ |
|
62 |
remainingVert--; |
|
136 | 63 |
|
137 |
////////////////////////////////////////////////////////////
|
|
138 |
// texture
|
|
64 |
float x= (float)col/mCols;
|
|
65 |
float y= (float)row/mRows;
|
|
139 | 66 |
|
140 |
offset=0; |
|
141 |
bufferData = new float[TEX_DATA_SIZE*dataLength]; |
|
67 |
position[3*vertex ] = x-0.5f; |
|
68 |
position[3*vertex+1] = 0.5f-y; |
|
69 |
position[3*vertex+2] = 0; |
|
142 | 70 |
|
143 |
for(int i=0; i<dataLength; i++) |
|
144 |
{ |
|
145 |
tmpx = ((float)(indexData[i]%xLength))/(xLength-1); |
|
146 |
tmpy = ((float)(indexData[i]/xLength))/(yLength-1); |
|
71 |
texture[2*vertex ] = x; |
|
72 |
texture[2*vertex+1] = y; |
|
147 | 73 |
|
148 |
bufferData[offset++] = tmpx; // s=x |
|
149 |
bufferData[offset++] = tmpy; // t=y |
|
150 |
} |
|
151 |
mGridTexture = ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
152 |
mGridTexture.put(bufferData).position(0); |
|
74 |
normal[3*vertex ] = 0.0f; |
|
75 |
normal[3*vertex+1] = 0.0f; |
|
76 |
normal[3*vertex+2] = 1.0f; |
|
153 | 77 |
|
154 |
//for(int g=0; g<dataLength; g++) Log.e("grid", "tex["+g+"]=("+bufferData[2*g]+","+bufferData[2*g+1]+")"); |
|
155 |
//Log.e("grid", "regWidth="+(2*mRegW)+" regHeight="+(2*mRegH)+" xLength="+xLength+" yLength="+yLength); |
|
78 |
return vertex+1; |
|
79 |
} |
|
80 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
156 | 81 |
|
157 |
//////////////////////////////////////////////////////////// |
|
158 |
// vertex positions |
|
82 |
private int repeatLast(int vertex, float[] position, float[] normal, float[] texture) |
|
83 |
{ |
|
84 |
remainingVert--; |
|
159 | 85 |
|
160 |
offset=0; |
|
161 |
bufferData= new float[POSITION_DATA_SIZE*dataLength]; |
|
86 |
//android.util.Log.e("BITMAP", "repeating last vertex!"); |
|
162 | 87 |
|
163 |
for(int i=0; i<dataLength; i++)
|
|
164 |
{ |
|
165 |
tmpx = ((float)(indexData[i]%xLength))/(xLength-1);
|
|
166 |
tmpy = ((float)(indexData[i]/xLength))/(yLength-1);
|
|
167 |
tmpz = 0;
|
|
88 |
if( vertex>0 )
|
|
89 |
{
|
|
90 |
position[3*vertex ] = position[3*vertex-3];
|
|
91 |
position[3*vertex+1] = position[3*vertex-2];
|
|
92 |
position[3*vertex+2] = position[3*vertex-1];
|
|
168 | 93 |
|
169 |
bufferData[offset++] = (tmpx-0.5f); // x
|
|
170 |
bufferData[offset++] = (0.5f-tmpy); // y
|
|
171 |
bufferData[offset++] = tmpz; // z
|
|
172 |
} |
|
173 |
mGridPositions = ByteBuffer.allocateDirect(POSITION_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
174 |
mGridPositions.put(bufferData).position(0);
|
|
94 |
normal[3*vertex ] = normal[3*vertex-3];
|
|
95 |
normal[3*vertex+1] = normal[3*vertex-2];
|
|
96 |
normal[3*vertex+2] = normal[3*vertex-1];
|
|
97 |
|
|
98 |
texture[2*vertex ] = texture[2*vertex-2];
|
|
99 |
texture[2*vertex+1] = texture[2*vertex-1];
|
|
175 | 100 |
|
176 |
//for(int g=0; g<dataLength; g++) android.util.Log.e("grid", "pos["+g+"]=("+bufferData[3*g]+","+bufferData[3*g+1]+")"); |
|
177 |
|
|
178 |
//////////////////////////////////////////////////////////// |
|
179 |
// normals |
|
101 |
vertex++; |
|
102 |
} |
|
180 | 103 |
|
181 |
offset=0;
|
|
182 |
bufferData = new float[NORMAL_DATA_SIZE*dataLength];
|
|
104 |
return vertex;
|
|
105 |
}
|
|
183 | 106 |
|
184 |
for(int i=0; i<dataLength; i++) |
|
107 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
108 |
|
|
109 |
private void buildGrid(float[] position, float[] normal, float[] texture) |
|
110 |
{ |
|
111 |
boolean lastBlockIsNE = false; |
|
112 |
boolean currentBlockIsNE; |
|
113 |
int vertex = 0; |
|
114 |
|
|
115 |
//android.util.Log.d("BITMAP", "buildGrid"); |
|
116 |
|
|
117 |
for(int row=0; row<mRows; row++) |
|
118 |
{ |
|
119 |
for(int col=0; col<mCols; col++) |
|
120 |
{ |
|
121 |
currentBlockIsNE = (2*row<=mRows-1)^(2*col<=mCols-1); |
|
122 |
|
|
123 |
if( col==0 || (lastBlockIsNE^currentBlockIsNE) ) |
|
124 |
{ |
|
125 |
if( row!=0 && col==0 ) vertex = repeatLast(vertex,position,normal,texture); |
|
126 |
vertex= addVertex( vertex, col, row+(currentBlockIsNE?0:1), position, normal, texture); |
|
127 |
if( row!=0 && col==0 ) vertex = repeatLast(vertex,position,normal,texture); |
|
128 |
if( lastBlockIsNE^currentBlockIsNE) vertex = repeatLast(vertex,position,normal,texture); |
|
129 |
vertex= addVertex( vertex, col, row+(currentBlockIsNE?1:0), position, normal, texture); |
|
130 |
} |
|
131 |
vertex= addVertex( vertex, col+1, row+(currentBlockIsNE?0:1), position, normal, texture); |
|
132 |
vertex= addVertex( vertex, col+1, row+(currentBlockIsNE?1:0), position, normal, texture); |
|
133 |
|
|
134 |
lastBlockIsNE = currentBlockIsNE; |
|
135 |
} |
|
136 |
} |
|
137 |
|
|
138 |
//android.util.Log.d("BITMAP", "buildGrid done"); |
|
139 |
} |
|
140 |
|
|
141 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
142 |
|
|
143 |
/** |
|
144 |
* Creates the underlying grid of vertices, normals and texture coords. |
|
145 |
* |
|
146 |
* @param cols Number of columns in the grid. |
|
147 |
* @param rows Number of rows in the grid. |
|
148 |
*/ |
|
149 |
public DistortedBitmapGrid(int cols, int rows) |
|
185 | 150 |
{ |
186 |
bufferData[offset++] = 0.0f; // x |
|
187 |
bufferData[offset++] = 0.0f; // y |
|
188 |
bufferData[offset++] = 1.0f; // z |
|
151 |
computeNumberOfVertices(cols,rows); |
|
152 |
|
|
153 |
float[] positionData= new float[POSITION_DATA_SIZE*dataLength]; |
|
154 |
float[] normalData = new float[NORMAL_DATA_SIZE *dataLength]; |
|
155 |
float[] textureData = new float[TEX_DATA_SIZE *dataLength]; |
|
156 |
|
|
157 |
buildGrid(positionData,normalData,textureData); |
|
158 |
|
|
159 |
/* |
|
160 |
android.util.Log.e("CUBES","dataLen="+dataLength+" vertex="+numVertices); |
|
161 |
android.util.Log.d("CUBES", "position: "+debug(positionData,3) ); |
|
162 |
android.util.Log.d("CUBES", "normal: " +debug( normalData,3) ); |
|
163 |
android.util.Log.d("CUBES", "texture: " +debug( textureData,2) ); |
|
164 |
*/ |
|
165 |
|
|
166 |
android.util.Log.d("BITMAP", "remainingVert " +remainingVert ); |
|
167 |
|
|
168 |
mGridPositions = ByteBuffer.allocateDirect(POSITION_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
169 |
mGridPositions.put(positionData).position(0); |
|
170 |
|
|
171 |
mGridNormals = ByteBuffer.allocateDirect(NORMAL_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
172 |
mGridNormals.put(normalData).position(0); |
|
173 |
|
|
174 |
mGridTexture = ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
175 |
mGridTexture.put(textureData).position(0); |
|
189 | 176 |
} |
190 |
mGridNormals = ByteBuffer.allocateDirect(NORMAL_DATA_SIZE*dataLength*BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
191 |
mGridNormals.put(bufferData).position(0); |
|
192 |
} |
|
193 | 177 |
} |
Also available in: Unified diff
Correctly tesselate the DistortedBitmap target!