Revision 470820a7
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/objects/Cubit.java | ||
---|---|---|
27 | 27 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
28 | 28 |
import org.distorted.library.effect.MatrixEffectRotate; |
29 | 29 |
import org.distorted.library.main.DistortedEffects; |
30 |
import org.distorted.library.main.DistortedNode; |
|
31 |
import org.distorted.library.mesh.MeshBase; |
|
32 | 30 |
import org.distorted.library.message.EffectListener; |
33 | 31 |
import org.distorted.library.type.Dynamic1D; |
34 | 32 |
import org.distorted.library.type.Static1D; |
... | ... | |
41 | 39 |
class Cubit |
42 | 40 |
{ |
43 | 41 |
private static final int POST_ROTATION_MILLISEC = 500; |
44 |
private static final Static3D matrCenter = new Static3D(0,0,0);
|
|
42 |
private static final Static3D MATRIX_CENTER = new Static3D(0,0,0);
|
|
45 | 43 |
|
46 | 44 |
private final Static3D mOrigPosition; |
47 | 45 |
|
48 | 46 |
private RubikObject mParent; |
49 |
private MeshBase mMesh; |
|
50 | 47 |
private Static3D mRotationAxis; |
51 | 48 |
private MatrixEffectRotate mRotateEffect; |
52 | 49 |
private Static3D mCurrentPosition; |
53 | 50 |
private int mNumAxis; |
54 | 51 |
private Dynamic1D mRotationAngle; |
55 | 52 |
|
56 |
DistortedNode mNode; |
|
57 | 53 |
DistortedEffects mEffect; |
58 | 54 |
Static4D mQuatScramble; |
59 | 55 |
float[] mRotationRow; |
60 | 56 |
|
57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
58 |
|
|
59 |
Cubit(RubikObject parent, Static3D position) |
|
60 |
{ |
|
61 |
float x = position.get0(); |
|
62 |
float y = position.get1(); |
|
63 |
float z = position.get2(); |
|
64 |
|
|
65 |
Static3D vector = new Static3D(x,y,z); |
|
66 |
|
|
67 |
mParent = parent; |
|
68 |
mOrigPosition = new Static3D(x,y,z); |
|
69 |
mQuatScramble = new Static4D(0,0,0,1); |
|
70 |
mRotationAngle = new Dynamic1D(); |
|
71 |
mRotationAxis = new Static3D(1,0,0); |
|
72 |
mCurrentPosition = position; |
|
73 |
mRotateEffect = new MatrixEffectRotate(mRotationAngle, mRotationAxis, MATRIX_CENTER); |
|
74 |
|
|
75 |
mNumAxis = mParent.ROTATION_AXIS.length; |
|
76 |
mRotationRow = new float[mNumAxis]; |
|
77 |
computeRotationRow(); |
|
78 |
|
|
79 |
mEffect = new DistortedEffects(); |
|
80 |
mEffect.apply( new MatrixEffectMove(vector) ); |
|
81 |
mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, MATRIX_CENTER)); |
|
82 |
mEffect.apply(mRotateEffect); |
|
83 |
mEffect.apply(mParent.mQuatAEffect); |
|
84 |
mEffect.apply(mParent.mQuatCEffect); |
|
85 |
mEffect.apply(mParent.mScaleEffect); |
|
86 |
} |
|
87 |
|
|
61 | 88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
62 | 89 |
// Because of quatMultiplication, errors can accumulate - so to avoid this, we |
63 | 90 |
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the |
... | ... | |
163 | 190 |
} |
164 | 191 |
} |
165 | 192 |
|
166 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
167 |
|
|
168 |
Cubit(RubikObject parent, MeshBase mesh, Static3D position) |
|
169 |
{ |
|
170 |
float x = position.get0(); |
|
171 |
float y = position.get1(); |
|
172 |
float z = position.get2(); |
|
173 |
|
|
174 |
Static3D vector = new Static3D(x,y,z); |
|
175 |
|
|
176 |
mParent = parent; |
|
177 |
mMesh = mesh; |
|
178 |
mOrigPosition = new Static3D(x,y,z); |
|
179 |
mQuatScramble = new Static4D(0,0,0,1); |
|
180 |
mRotationAngle = new Dynamic1D(); |
|
181 |
mRotationAxis = new Static3D(1,0,0); |
|
182 |
mCurrentPosition = position; |
|
183 |
mRotateEffect = new MatrixEffectRotate(mRotationAngle, mRotationAxis, matrCenter); |
|
184 |
|
|
185 |
mNumAxis = mParent.ROTATION_AXIS.length; |
|
186 |
mRotationRow = new float[mNumAxis]; |
|
187 |
computeRotationRow(); |
|
188 |
|
|
189 |
mEffect = new DistortedEffects(); |
|
190 |
mEffect.apply( new MatrixEffectMove(vector) ); |
|
191 |
mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, matrCenter)); |
|
192 |
mEffect.apply(mRotateEffect); |
|
193 |
mEffect.apply(mParent.mQuatAEffect); |
|
194 |
mEffect.apply(mParent.mQuatCEffect); |
|
195 |
mEffect.apply(mParent.mScaleEffect); |
|
196 |
|
|
197 |
mNode = new DistortedNode(mParent.mTexture,mEffect,mMesh); |
|
198 |
} |
|
199 |
|
|
200 | 193 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
201 | 194 |
|
202 | 195 |
void savePreferences(SharedPreferences.Editor editor) |
... | ... | |
357 | 350 |
} |
358 | 351 |
} |
359 | 352 |
|
360 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
361 |
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of |
|
362 |
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major |
|
363 |
// memory leak. |
|
364 |
|
|
365 |
void releaseResources() |
|
366 |
{ |
|
367 |
mMesh.markForDeletion(); |
|
368 |
mNode.markForDeletion(); |
|
369 |
} |
|
370 |
|
|
371 | 353 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
372 | 354 |
|
373 | 355 |
void solve() |
... | ... | |
395 | 377 |
|
396 | 378 |
return dx*dx + dy*dy + dz*dz; |
397 | 379 |
} |
398 |
|
|
399 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
400 |
|
|
401 |
int getColorIndex(int face) |
|
402 |
{ |
|
403 |
Static4D texMap = mMesh.getTextureMap(face); |
|
404 |
return (int)(texMap.get0() / texMap.get2()); |
|
405 |
} |
|
406 |
|
|
407 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
408 |
|
|
409 |
MeshBase getMesh() |
|
410 |
{ |
|
411 |
return mMesh; |
|
412 |
} |
|
413 | 380 |
} |
src/main/java/org/distorted/objects/RubikCube.java | ||
---|---|---|
232 | 232 |
mMesh.apply(effect12); |
233 | 233 |
mMesh.apply(effect13); |
234 | 234 |
mMesh.apply(effect14); |
235 |
|
|
236 |
mMesh.mergeEffComponents(); |
|
235 | 237 |
} |
236 | 238 |
|
237 |
return mMesh.copy(false);
|
|
239 |
return mMesh.copy(true);
|
|
238 | 240 |
} |
239 | 241 |
|
240 | 242 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/objects/RubikObject.java | ||
---|---|---|
25 | 25 |
import android.graphics.Paint; |
26 | 26 |
|
27 | 27 |
import org.distorted.library.effect.Effect; |
28 |
import org.distorted.library.effect.MatrixEffectMove; |
|
28 | 29 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
29 | 30 |
import org.distorted.library.effect.MatrixEffectScale; |
30 | 31 |
import org.distorted.library.main.DistortedEffects; |
31 | 32 |
import org.distorted.library.main.DistortedNode; |
32 | 33 |
import org.distorted.library.main.DistortedTexture; |
33 | 34 |
import org.distorted.library.mesh.MeshBase; |
35 |
import org.distorted.library.mesh.MeshJoined; |
|
34 | 36 |
import org.distorted.library.mesh.MeshRectangles; |
35 | 37 |
import org.distorted.library.message.EffectListener; |
36 | 38 |
import org.distorted.library.type.Static1D; |
... | ... | |
47 | 49 |
private static final int TEXTURE_HEIGHT = 128; |
48 | 50 |
final float[] LEGAL_QUATS; |
49 | 51 |
final Static3D[] ROTATION_AXIS; |
52 |
final int NUM_FACES; |
|
50 | 53 |
|
51 | 54 |
static float OBJECT_SCREEN_RATIO; |
52 | 55 |
|
... | ... | |
59 | 62 |
private Cubit[] mCubits; |
60 | 63 |
private int mSize; |
61 | 64 |
private RubikObjectList mList; |
65 |
private MeshBase mMesh; |
|
66 |
private DistortedEffects mEffects; |
|
62 | 67 |
|
63 | 68 |
float mStart, mStep; |
64 | 69 |
|
... | ... | |
85 | 90 |
NUM_CUBITS = mOrigPos.length; |
86 | 91 |
ROTATION_AXIS = getRotationAxis(); |
87 | 92 |
OBJECT_SCREEN_RATIO = getScreenRatio(); |
93 |
NUM_FACES = getNumFaces(); |
|
88 | 94 |
|
89 | 95 |
mSize = size; |
90 | 96 |
computeStartAndStep(mOrigPos); |
... | ... | |
106 | 112 |
|
107 | 113 |
mCubits = new Cubit[NUM_CUBITS]; |
108 | 114 |
mTexture = new DistortedTexture(); |
115 |
MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS]; |
|
109 | 116 |
|
110 | 117 |
for(int i=0; i<NUM_CUBITS; i++) |
111 | 118 |
{ |
112 |
MeshBase cubitMesh = createCubitMesh(i); |
|
113 |
mCubits[i] = new Cubit(this,cubitMesh,mOrigPos[i]); |
|
114 |
textureCubitMesh(cubitMesh,i); |
|
115 |
|
|
116 |
attach(mCubits[i].mNode); |
|
119 |
cubitMesh[i] = createCubitMesh(i); |
|
120 |
cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0); |
|
121 |
mCubits[i] = new Cubit(this,mOrigPos[i]); |
|
117 | 122 |
} |
118 | 123 |
|
124 |
mMesh = new MeshJoined(cubitMesh); |
|
125 |
|
|
126 |
resetAllTextureMaps(); |
|
127 |
|
|
128 |
mEffects = new DistortedEffects(); |
|
129 |
mEffects.apply(mQuatAEffect); |
|
130 |
mEffects.apply(mQuatCEffect); |
|
131 |
mEffects.apply(mScaleEffect); |
|
132 |
|
|
133 |
attach( new DistortedNode(mTexture,mEffects,mMesh) ); |
|
134 |
|
|
119 | 135 |
setupPosition(moves); |
120 | 136 |
|
121 | 137 |
setProjection(fov, 0.1f); |
... | ... | |
126 | 142 |
private void textureCubitMesh(MeshBase mesh, int cubit) |
127 | 143 |
{ |
128 | 144 |
boolean belongs; |
129 |
final int numFaces = getNumFaces(); |
|
130 |
final Static4D[] maps = new Static4D[numFaces]; |
|
131 |
final float ratio = 1.0f/(numFaces+1); |
|
145 |
final Static4D[] maps = new Static4D[NUM_FACES]; |
|
146 |
final float ratio = 1.0f/(NUM_FACES+1); |
|
132 | 147 |
|
133 |
if( 2*ROTATION_AXIS.length == numFaces ) // i.e. there are faces on both ends of the axis (cube)
|
|
148 |
if( 2*ROTATION_AXIS.length == NUM_FACES ) // i.e. there are faces on both ends of the axis (cube)
|
|
134 | 149 |
{ |
135 |
for(int i=0; i<numFaces; i++)
|
|
150 |
for(int i=0; i<NUM_FACES; i++)
|
|
136 | 151 |
{ |
137 | 152 |
belongs = isOnFace(cubit, i/2, i%2==0 ? mSize-1:0 ); |
138 |
maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
|
|
153 |
maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
|
|
139 | 154 |
} |
140 | 155 |
} |
141 |
else if( ROTATION_AXIS.length == numFaces ) // just a single face on the right end of an axis (pyraminx)
|
|
156 |
else if( ROTATION_AXIS.length == NUM_FACES ) // just a single face on the right end of an axis (pyraminx)
|
|
142 | 157 |
{ |
143 |
for(int i=0; i<numFaces; i++)
|
|
158 |
for(int i=0; i<NUM_FACES; i++)
|
|
144 | 159 |
{ |
145 | 160 |
belongs = isOnFace(cubit, i, 0 ); |
146 |
maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
|
|
161 |
maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
|
|
147 | 162 |
} |
148 | 163 |
} |
149 | 164 |
|
150 |
mesh.setTextureMap(maps); |
|
165 |
mesh.setTextureMap(maps,NUM_FACES*cubit);
|
|
151 | 166 |
} |
152 | 167 |
|
153 | 168 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
246 | 261 |
|
247 | 262 |
int getCubitFaceColorIndex(int cubit, int face) |
248 | 263 |
{ |
249 |
return mCubits[cubit].getColorIndex(face); |
|
264 |
Static4D texMap = mMesh.getTextureMap(NUM_FACES*cubit + face); |
|
265 |
return (int)(texMap.get0() / texMap.get2()); |
|
250 | 266 |
} |
251 | 267 |
|
252 | 268 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
286 | 302 |
{ |
287 | 303 |
Bitmap bitmap; |
288 | 304 |
|
289 |
final int numColors = getNumFaces(); |
|
290 |
|
|
291 | 305 |
Paint paint = new Paint(); |
292 |
bitmap = Bitmap.createBitmap( (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
|
306 |
bitmap = Bitmap.createBitmap( (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
|
|
293 | 307 |
Canvas canvas = new Canvas(bitmap); |
294 | 308 |
|
295 | 309 |
paint.setAntiAlias(true); |
... | ... | |
297 | 311 |
paint.setStyle(Paint.Style.FILL); |
298 | 312 |
|
299 | 313 |
paint.setColor(INTERIOR_COLOR); |
300 |
canvas.drawRect(0, 0, (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
|
|
314 |
canvas.drawRect(0, 0, (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
|
|
301 | 315 |
|
302 |
for(int i=0; i<numColors; i++)
|
|
316 |
for(int i=0; i<NUM_FACES; i++)
|
|
303 | 317 |
{ |
304 | 318 |
createFaceTexture(canvas, paint, i, i*TEXTURE_HEIGHT, 0, TEXTURE_HEIGHT); |
305 | 319 |
} |
... | ... | |
356 | 370 |
{ |
357 | 371 |
mTexture.markForDeletion(); |
358 | 372 |
|
359 |
for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
|
|
373 |
// TODO ?
|
|
360 | 374 |
} |
361 | 375 |
|
362 | 376 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
400 | 414 |
{ |
401 | 415 |
for(int i=0; i<NUM_CUBITS; i++) |
402 | 416 |
{ |
403 |
textureCubitMesh( mCubits[i].getMesh() , i );
|
|
417 |
textureCubitMesh( mMesh , i );
|
|
404 | 418 |
} |
405 | 419 |
} |
406 | 420 |
|
... | ... | |
408 | 422 |
|
409 | 423 |
public void setTextureMap(int cubit, int face, int newColor) |
410 | 424 |
{ |
411 |
final int numFaces = getNumFaces(); |
|
412 |
final float ratio = 1.0f/(numFaces+1); |
|
413 |
final Static4D[] maps = new Static4D[numFaces]; |
|
425 |
final float ratio = 1.0f/(NUM_FACES+1); |
|
426 |
final Static4D[] maps = new Static4D[NUM_FACES]; |
|
414 | 427 |
|
415 | 428 |
try |
416 | 429 |
{ |
417 | 430 |
maps[face] = new Static4D( newColor*ratio, 0.0f, ratio, 1.0f); |
418 |
mCubits[cubit].getMesh().setTextureMap(maps);
|
|
431 |
mMesh.setTextureMap(maps,NUM_FACES*cubit);
|
|
419 | 432 |
} |
420 | 433 |
catch(ArrayIndexOutOfBoundsException ignored) |
421 | 434 |
{ |
src/main/java/org/distorted/objects/RubikPyraminx.java | ||
---|---|---|
225 | 225 |
meshes[i].setEffectAssociation(0,association,0); |
226 | 226 |
} |
227 | 227 |
|
228 |
Static4D[] textureMaps = new Static4D[MESHES]; |
|
229 |
for(int i=0; i<MESHES; i++) textureMaps[i] = new Static4D(i*0.25f,0.0f,0.25f,1.0f); |
|
230 | 228 |
MeshBase result = new MeshJoined(meshes); |
231 |
result.setTextureMap(textureMaps); |
|
232 | 229 |
|
233 | 230 |
Static3D a0 = new Static3D( 0, 1, 0 ); |
234 | 231 |
Static3D a1 = new Static3D( 0, -1.0f/3, 2*SQ2/3 ); |
... | ... | |
301 | 298 |
result.apply( ROTATION[mRotArray[cubit]] ); |
302 | 299 |
} |
303 | 300 |
|
301 |
result.mergeEffComponents(); |
|
302 |
|
|
304 | 303 |
return result; |
305 | 304 |
} |
306 | 305 |
|
... | ... | |
313 | 312 |
if( kind>=0 ) |
314 | 313 |
{ |
315 | 314 |
if( mMeshRotated[kind]==null ) mMeshRotated[kind] = createStaticMesh(cubit); |
316 |
return mMeshRotated[kind].copy(false);
|
|
315 |
return mMeshRotated[kind].copy(true);
|
|
317 | 316 |
} |
318 | 317 |
else |
319 | 318 |
{ |
320 | 319 |
if( mMesh==null ) mMesh = createStaticMesh(cubit); |
321 |
return mMesh.copy(false);
|
|
320 |
return mMesh.copy(true);
|
|
322 | 321 |
} |
323 | 322 |
} |
324 | 323 |
|
Also available in: Unified diff
Begin porting RubikCube to the new SingleMesh library. This will make rendering much faster - e.g. in case of Cube 5, instead of 98 renders of individual Cubits, there will be one render of the whole Mesh.