Revision 27e6c301
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/main/RubikRenderer.java | ||
---|---|---|
24 | 24 |
|
25 | 25 |
import org.distorted.effects.BaseEffect; |
26 | 26 |
import org.distorted.library.effect.EffectType; |
27 |
import org.distorted.library.effect.VertexEffectRotate; |
|
27 | 28 |
import org.distorted.library.main.DistortedLibrary; |
28 | 29 |
import org.distorted.library.main.DistortedScreen; |
29 | 30 |
|
... | ... | |
77 | 78 |
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) |
78 | 79 |
{ |
79 | 80 |
DistortedLibrary.setMax(EffectType.VERTEX,15); |
81 |
VertexEffectRotate.enable(); |
|
80 | 82 |
BaseEffect.Type.enableEffects(); |
81 | 83 |
|
82 | 84 |
try |
src/main/java/org/distorted/objects/Cubit.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import android.content.SharedPreferences; |
23 | 23 |
|
24 |
import com.google.firebase.crashlytics.FirebaseCrashlytics; |
|
25 |
|
|
26 |
import org.distorted.library.effect.MatrixEffectMove; |
|
27 | 24 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
28 |
import org.distorted.library.effect.MatrixEffectRotate; |
|
29 | 25 |
import org.distorted.library.main.DistortedEffects; |
30 |
import org.distorted.library.message.EffectListener; |
|
31 |
import org.distorted.library.type.Dynamic1D; |
|
32 |
import org.distorted.library.type.Static1D; |
|
33 | 26 |
import org.distorted.library.type.Static3D; |
34 | 27 |
import org.distorted.library.type.Static4D; |
35 | 28 |
import org.distorted.main.RubikSurfaceView; |
... | ... | |
38 | 31 |
|
39 | 32 |
class Cubit |
40 | 33 |
{ |
41 |
private static final int POST_ROTATION_MILLISEC = 500; |
|
42 | 34 |
private static final Static3D MATRIX_CENTER = new Static3D(0,0,0); |
43 | 35 |
|
44 | 36 |
private final Static3D mOrigPosition; |
45 | 37 |
|
46 | 38 |
private RubikObject mParent; |
47 |
private Static3D mRotationAxis; |
|
48 |
private MatrixEffectRotate mRotateEffect; |
|
49 | 39 |
private Static3D mCurrentPosition; |
50 | 40 |
private int mNumAxis; |
51 |
private Dynamic1D mRotationAngle; |
|
52 | 41 |
|
53 | 42 |
DistortedEffects mEffect; |
54 | 43 |
Static4D mQuatScramble; |
... | ... | |
62 | 51 |
float y = position.get1(); |
63 | 52 |
float z = position.get2(); |
64 | 53 |
|
65 |
Static3D vector = new Static3D(x,y,z); |
|
66 |
|
|
67 | 54 |
mParent = parent; |
68 | 55 |
mOrigPosition = new Static3D(x,y,z); |
69 | 56 |
mQuatScramble = new Static4D(0,0,0,1); |
70 |
mRotationAngle = new Dynamic1D(); |
|
71 |
mRotationAxis = new Static3D(1,0,0); |
|
57 |
|
|
72 | 58 |
mCurrentPosition = position; |
73 |
mRotateEffect = new MatrixEffectRotate(mRotationAngle, mRotationAxis, MATRIX_CENTER); |
|
74 | 59 |
|
75 | 60 |
mNumAxis = mParent.ROTATION_AXIS.length; |
76 | 61 |
mRotationRow = new float[mNumAxis]; |
77 | 62 |
computeRotationRow(); |
78 | 63 |
|
79 | 64 |
mEffect = new DistortedEffects(); |
80 |
mEffect.apply( new MatrixEffectMove(vector) ); |
|
81 | 65 |
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 | 66 |
} |
87 | 67 |
|
88 | 68 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
190 | 170 |
} |
191 | 171 |
} |
192 | 172 |
|
173 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
174 |
|
|
175 |
int computeAssociation() |
|
176 |
{ |
|
177 |
int row, result = 0, accumulativeShift = 0; |
|
178 |
|
|
179 |
for(int axis=0; axis<mNumAxis; axis++) |
|
180 |
{ |
|
181 |
row = (int)(mRotationRow[axis]+0.5f); |
|
182 |
result += (1<<(row+accumulativeShift)); |
|
183 |
accumulativeShift += RubikObjectList.MAX_SIZE; |
|
184 |
} |
|
185 |
|
|
186 |
return result; |
|
187 |
} |
|
188 |
|
|
193 | 189 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
194 | 190 |
|
195 | 191 |
void savePreferences(SharedPreferences.Editor editor) |
... | ... | |
295 | 291 |
|
296 | 292 |
void removeRotationNow(Static4D quat) |
297 | 293 |
{ |
298 |
mRotationAngle.removeAll(); |
|
299 | 294 |
mQuatScramble.set(RubikSurfaceView.quatMultiply(quat,mQuatScramble)); |
300 | 295 |
normalizeScrambleQuat( mQuatScramble ); |
301 | 296 |
modifyCurrentPosition(quat); |
302 | 297 |
} |
303 | 298 |
|
304 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
305 |
|
|
306 |
void beginNewRotation(int axis) |
|
307 |
{ |
|
308 |
mRotationAxis.set( mParent.ROTATION_AXIS[axis] ); |
|
309 |
mRotationAngle.add(mParent.mRotationAngleStatic); |
|
310 |
} |
|
311 |
|
|
312 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
313 |
|
|
314 |
void addNewRotation(int axis, long durationMillis, int angle) |
|
315 |
{ |
|
316 |
mRotationAxis.set( mParent.ROTATION_AXIS[axis] ); |
|
317 |
mRotationAngle.setDuration(durationMillis); |
|
318 |
mRotationAngle.resetToBeginning(); |
|
319 |
mRotationAngle.add(new Static1D(0)); |
|
320 |
mRotationAngle.add(new Static1D(angle)); |
|
321 |
} |
|
322 |
|
|
323 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
324 |
|
|
325 |
void resetRotationAngle() |
|
326 |
{ |
|
327 |
mRotationAngle.setDuration(POST_ROTATION_MILLISEC); |
|
328 |
mRotationAngle.resetToBeginning(); |
|
329 |
mRotationAngle.removeAll(); |
|
330 |
mRotationAngle.add(mParent.mRotationAngleStatic); |
|
331 |
mRotationAngle.add(mParent.mRotationAngleMiddle); |
|
332 |
mRotationAngle.add(mParent.mRotationAngleFinal); |
|
333 |
} |
|
334 |
|
|
335 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
336 |
|
|
337 |
float getAngle() |
|
338 |
{ |
|
339 |
int pointNum = mRotationAngle.getNumPoints(); |
|
340 |
|
|
341 |
if( pointNum>=1 ) |
|
342 |
{ |
|
343 |
return mRotationAngle.getPoint(pointNum-1).get0(); |
|
344 |
} |
|
345 |
else |
|
346 |
{ |
|
347 |
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); |
|
348 |
crashlytics.log("points in RotationAngle: "+pointNum); |
|
349 |
return 0; |
|
350 |
} |
|
351 |
} |
|
352 |
|
|
353 | 299 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
354 | 300 |
|
355 | 301 |
void solve() |
... | ... | |
359 | 305 |
computeRotationRow(); |
360 | 306 |
} |
361 | 307 |
|
362 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
363 |
|
|
364 |
long setUpCallback(EffectListener listener) |
|
365 |
{ |
|
366 |
mRotateEffect.notifyWhenFinished(listener); |
|
367 |
return mRotateEffect.getID(); |
|
368 |
} |
|
369 |
|
|
370 | 308 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
371 | 309 |
|
372 | 310 |
float getDistSquared(float[] point) |
src/main/java/org/distorted/objects/RubikObject.java | ||
---|---|---|
24 | 24 |
import android.graphics.Canvas; |
25 | 25 |
import android.graphics.Paint; |
26 | 26 |
|
27 |
import com.google.firebase.crashlytics.FirebaseCrashlytics; |
|
28 |
|
|
27 | 29 |
import org.distorted.library.effect.Effect; |
28 | 30 |
import org.distorted.library.effect.MatrixEffectMove; |
29 | 31 |
import org.distorted.library.effect.MatrixEffectQuaternion; |
30 | 32 |
import org.distorted.library.effect.MatrixEffectScale; |
33 |
import org.distorted.library.effect.VertexEffectRotate; |
|
31 | 34 |
import org.distorted.library.main.DistortedEffects; |
32 | 35 |
import org.distorted.library.main.DistortedNode; |
33 | 36 |
import org.distorted.library.main.DistortedTexture; |
... | ... | |
35 | 38 |
import org.distorted.library.mesh.MeshJoined; |
36 | 39 |
import org.distorted.library.mesh.MeshRectangles; |
37 | 40 |
import org.distorted.library.message.EffectListener; |
41 |
import org.distorted.library.type.Dynamic1D; |
|
38 | 42 |
import org.distorted.library.type.Static1D; |
39 | 43 |
import org.distorted.library.type.Static3D; |
40 | 44 |
import org.distorted.library.type.Static4D; |
... | ... | |
43 | 47 |
|
44 | 48 |
public abstract class RubikObject extends DistortedNode |
45 | 49 |
{ |
50 |
private static final Static3D VERTEX_CENTER = new Static3D(0,0,0); |
|
46 | 51 |
static final int INTERIOR_COLOR = 0xff000000; |
47 | 52 |
public static final int NODE_FBO_SIZE = 600; |
48 |
|
|
53 |
private static final int POST_ROTATION_MILLISEC = 500; |
|
49 | 54 |
private static final int TEXTURE_HEIGHT = 128; |
55 |
|
|
50 | 56 |
final float[] LEGAL_QUATS; |
51 | 57 |
final Static3D[] ROTATION_AXIS; |
52 | 58 |
final int NUM_FACES; |
... | ... | |
64 | 70 |
private RubikObjectList mList; |
65 | 71 |
private MeshBase mMesh; |
66 | 72 |
private DistortedEffects mEffects; |
73 |
private VertexEffectRotate mRotateEffect; |
|
74 |
private Dynamic1D mRotationAngle; |
|
75 |
private Static3D mRotationAxis; |
|
67 | 76 |
|
68 | 77 |
float mStart, mStep; |
69 | 78 |
|
... | ... | |
97 | 106 |
mNodeScale= new Static3D(1,1,1); |
98 | 107 |
mQuatAccumulated = quatAcc; |
99 | 108 |
|
109 |
mRotationAngle= new Dynamic1D(); |
|
110 |
mRotationAxis = new Static3D(1,0,0); |
|
111 |
mRotateEffect = new VertexEffectRotate(mRotationAngle, mRotationAxis, VERTEX_CENTER); |
|
112 |
|
|
100 | 113 |
mRotationAngleStatic = new Static1D(0); |
101 | 114 |
mRotationAngleMiddle = new Static1D(0); |
102 | 115 |
mRotationAngleFinal = new Static1D(0); |
... | ... | |
116 | 129 |
|
117 | 130 |
for(int i=0; i<NUM_CUBITS; i++) |
118 | 131 |
{ |
132 |
mCubits[i] = new Cubit(this,mOrigPos[i]); |
|
119 | 133 |
cubitMesh[i] = createCubitMesh(i); |
120 | 134 |
cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0); |
121 |
mCubits[i] = new Cubit(this,mOrigPos[i]);
|
|
135 |
cubitMesh[i].setEffectAssociation(0, mCubits[i].computeAssociation(), i);
|
|
122 | 136 |
} |
123 | 137 |
|
124 | 138 |
mMesh = new MeshJoined(cubitMesh); |
... | ... | |
126 | 140 |
resetAllTextureMaps(); |
127 | 141 |
|
128 | 142 |
mEffects = new DistortedEffects(); |
143 |
mEffects.apply(mRotateEffect); |
|
129 | 144 |
mEffects.apply(mQuatAEffect); |
130 | 145 |
mEffects.apply(mQuatCEffect); |
131 | 146 |
mEffects.apply(mScaleEffect); |
... | ... | |
453 | 468 |
return; |
454 | 469 |
} |
455 | 470 |
|
456 |
mRotAxis = axis; |
|
457 |
mRotRowBitmap = (1<<row); |
|
458 |
|
|
471 |
mRotAxis = axis; |
|
472 |
mRotRowBitmap= (1<<row); |
|
459 | 473 |
mRotationAngleStatic.set0(0.0f); |
460 |
|
|
461 |
for(int i=0; i<NUM_CUBITS; i++) |
|
462 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
|
463 |
{ |
|
464 |
mCubits[i].beginNewRotation(axis); |
|
465 |
} |
|
466 |
} |
|
474 |
mRotationAxis.set( ROTATION_AXIS[axis] ); |
|
475 |
mRotationAngle.add(mRotationAngleStatic); |
|
476 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*RubikObjectList.MAX_SIZE) , -1); |
|
477 |
} |
|
467 | 478 |
|
468 | 479 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
469 | 480 |
|
470 | 481 |
public long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener ) |
471 |
{ |
|
472 |
long effectID=0; |
|
473 |
int firstCubit = -1; |
|
474 |
|
|
475 |
mRotAxis = axis; |
|
476 |
mRotRowBitmap = rowBitmap; |
|
482 |
{ |
|
483 |
mRotAxis = axis; |
|
484 |
mRotRowBitmap= rowBitmap; |
|
477 | 485 |
|
478 |
mRotationAngleStatic.set0(0.0f); |
|
486 |
mRotationAngleStatic.set0(0.0f); |
|
487 |
mRotationAxis.set( ROTATION_AXIS[axis] ); |
|
488 |
mRotationAngle.setDuration(durationMillis); |
|
489 |
mRotationAngle.resetToBeginning(); |
|
490 |
mRotationAngle.add(new Static1D(0)); |
|
491 |
mRotationAngle.add(new Static1D(angle)); |
|
492 |
mRotateEffect.setMeshAssociation( mRotRowBitmap<<(axis*RubikObjectList.MAX_SIZE) , -1); |
|
493 |
mRotateEffect.notifyWhenFinished(listener); |
|
494 |
|
|
495 |
return mRotateEffect.getID(); |
|
496 |
} |
|
479 | 497 |
|
480 |
for(int i=0; i<NUM_CUBITS; i++) |
|
481 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
|
482 |
{ |
|
483 |
mCubits[i].addNewRotation(axis,durationMillis,angle); |
|
484 |
if( firstCubit<0 ) firstCubit = i; |
|
485 |
} |
|
498 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
486 | 499 |
|
487 |
if( firstCubit>=0 ) effectID = mCubits[firstCubit].setUpCallback(listener); |
|
500 |
public long finishRotationNow(EffectListener listener) |
|
501 |
{ |
|
502 |
float angle = getAngle(); |
|
503 |
int nearestAngleInDegrees = computeNearestAngle(angle); |
|
504 |
mRotationAngleStatic.set0(angle); |
|
505 |
mRotationAngleFinal.set0(nearestAngleInDegrees); |
|
506 |
mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f ); |
|
507 |
|
|
508 |
mRotationAngle.setDuration(POST_ROTATION_MILLISEC); |
|
509 |
mRotationAngle.resetToBeginning(); |
|
510 |
mRotationAngle.removeAll(); |
|
511 |
mRotationAngle.add(mRotationAngleStatic); |
|
512 |
mRotationAngle.add(mRotationAngleMiddle); |
|
513 |
mRotationAngle.add(mRotationAngleFinal); |
|
514 |
mRotateEffect.notifyWhenFinished(listener); |
|
515 |
|
|
516 |
return mRotateEffect.getID(); |
|
517 |
} |
|
488 | 518 |
|
489 |
return effectID; |
|
490 |
} |
|
491 | 519 |
|
492 | 520 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
493 | 521 |
|
494 |
public long finishRotationNow(EffectListener listener)
|
|
522 |
private float getAngle()
|
|
495 | 523 |
{ |
496 |
int firstCubit= -1; |
|
497 |
long effectID = 0; |
|
524 |
int pointNum = mRotationAngle.getNumPoints(); |
|
498 | 525 |
|
499 |
for(int i=0; i<NUM_CUBITS; i++)
|
|
526 |
if( pointNum>=1 )
|
|
500 | 527 |
{ |
501 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
|
502 |
{ |
|
503 |
if( firstCubit<0 ) |
|
504 |
{ |
|
505 |
firstCubit=i; |
|
506 |
|
|
507 |
float angle = mCubits[i].getAngle(); |
|
508 |
int nearestAngleInDegrees = computeNearestAngle(angle); |
|
509 |
mRotationAngleStatic.set0(angle); |
|
510 |
mRotationAngleFinal.set0(nearestAngleInDegrees); |
|
511 |
mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-angle)*0.2f ); |
|
512 |
} |
|
513 |
mCubits[i].resetRotationAngle(); |
|
514 |
} |
|
528 |
return mRotationAngle.getPoint(pointNum-1).get0(); |
|
529 |
} |
|
530 |
else |
|
531 |
{ |
|
532 |
FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance(); |
|
533 |
crashlytics.log("points in RotationAngle: "+pointNum); |
|
534 |
return 0; |
|
515 | 535 |
} |
516 |
|
|
517 |
if( firstCubit>=0 ) effectID = mCubits[firstCubit].setUpCallback(listener); |
|
518 |
|
|
519 |
return effectID; |
|
520 | 536 |
} |
521 | 537 |
|
522 | 538 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
523 | 539 |
|
524 | 540 |
public void removeRotationNow() |
525 | 541 |
{ |
526 |
boolean first = true; |
|
527 |
Static4D quat = null; |
|
542 |
float angle = getAngle(); |
|
543 |
int nearestAngleInDegrees = computeNearestAngle(angle); |
|
544 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
|
545 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
546 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
547 |
float axisX = ROTATION_AXIS[mRotAxis].get0(); |
|
548 |
float axisY = ROTATION_AXIS[mRotAxis].get1(); |
|
549 |
float axisZ = ROTATION_AXIS[mRotAxis].get2(); |
|
550 |
Static4D quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA); |
|
551 |
|
|
552 |
mRotationAngle.removeAll(); |
|
553 |
mRotationAngleStatic.set0(0); |
|
528 | 554 |
|
529 | 555 |
for(int i=0; i<NUM_CUBITS; i++) |
530 | 556 |
if( belongsToRotation(i,mRotAxis,mRotRowBitmap) ) |
531 | 557 |
{ |
532 |
if( first ) |
|
533 |
{ |
|
534 |
first = false; |
|
535 |
|
|
536 |
float angle = mCubits[i].getAngle(); |
|
537 |
int nearestAngleInDegrees = computeNearestAngle(angle); |
|
538 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
|
539 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
|
540 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
|
541 |
float axisX = ROTATION_AXIS[mRotAxis].get0(); |
|
542 |
float axisY = ROTATION_AXIS[mRotAxis].get1(); |
|
543 |
float axisZ = ROTATION_AXIS[mRotAxis].get2(); |
|
544 |
quat = new Static4D( axisX*sinA, axisY*sinA, axisZ*sinA, cosA); |
|
545 |
} |
|
546 |
|
|
547 | 558 |
mCubits[i].removeRotationNow(quat); |
548 | 559 |
} |
549 |
|
|
550 |
mRotationAngleStatic.set0(0); |
|
551 | 560 |
} |
552 | 561 |
|
553 | 562 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Progreess porting RubikCube to the new SingleMesh mode.