Project

General

Profile

« Previous | Next » 

Revision 6e18bd32

Added by Leszek Koltunski about 5 years ago

Turn the Rubik app into a MemoryTest.

View differences:

src/main/java/org/distorted/examples/rubik/RubikCube.java
19 19

  
20 20
package org.distorted.examples.rubik;
21 21

  
22
import java.util.Random;
23

  
22 24
import android.graphics.Bitmap;
23 25
import android.graphics.Canvas;
24 26
import android.graphics.Paint;
......
43 45

  
44 46
class RubikCube
45 47
{
46
    private static final int POST_ROTATION_MILLISEC = 500;
48
    private static final int VECTX = 0;  //
49
    private static final int VECTY = 1;  // don't change this
50
    private static final int VECTZ = 2;  //
51

  
52
    private static final int ROTATION_MILLISEC = 1500;
47 53
    private static final int TEXTURE_SIZE = 100;
48 54

  
49 55
    private static final Static3D VectX = new Static3D(1,0,0);
......
53 59
    private DistortedNode[][][] mNodes;
54 60
    private MeshCubes[][][] mCubes;
55 61
    private DistortedEffects[][][] mEffects;
56
    private Static4D[][][] mQuatScramble;
57 62
    private Static3D[][][] mRotationAxis;
58 63
    private Dynamic1D[][][] mRotationAngle;
59
    private Static3D[][][] mCurrentPosition;
60
    private Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
61 64
    private DistortedTexture mTexture;
62
    private DistortedEffects mEffectsListeningForNow;
63 65

  
64
    private int mRotAxis, mRotRow;
65 66
    private int mSize;
66 67

  
68
    private Random mRnd = new Random(0);
69

  
67 70
///////////////////////////////////////////////////////////////////////////////////////////////////
68 71

  
69
    RubikCube(int size, Static3D move, Static3D scale, Static4D quatC, Static4D quatA)
72
    RubikCube(int size, Static3D move, Static3D scale)
70 73
      {
71 74
      mSize = size;
72 75

  
73
      mRotationAngleStatic = new Static1D(0);
74
      mRotationAngleMiddle = new Static1D(0);
75
      mRotationAngleFinal  = new Static1D(0);
76

  
77
      mRotAxis= RubikSurfaceView.VECTX;
78 76
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
79 77

  
80 78
      mNodes          = new DistortedNode[mSize][mSize][mSize];
81 79
      mCubes          = new MeshCubes[mSize][mSize][mSize];
82 80
      mEffects        = new DistortedEffects[mSize][mSize][mSize];
83
      mQuatScramble   = new Static4D[mSize][mSize][mSize];
84 81
      mRotationAxis   = new Static3D[mSize][mSize][mSize];
85 82
      mRotationAngle  = new Dynamic1D[mSize][mSize][mSize];
86
      mCurrentPosition= new Static3D[mSize][mSize][mSize];
87 83

  
88 84
      Static3D[][][] cubeVectors = new Static3D[mSize][mSize][mSize];
89 85

  
......
93 89
      VertexEffectSink        sinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), center, region );
94 90
      MatrixEffectMove        moveEffect = new MatrixEffectMove(move);
95 91
      MatrixEffectScale      scaleEffect = new MatrixEffectScale(scale);
96
      MatrixEffectQuaternion quatCEffect = new MatrixEffectQuaternion(quatC, center);
97
      MatrixEffectQuaternion quatAEffect = new MatrixEffectQuaternion(quatA, center);
92
      MatrixEffectQuaternion  quatEffect = new MatrixEffectQuaternion( initializeQuat(), center);
98 93

  
99 94
      // 3x2 bitmap = 6 squares:
100 95
      //
......
135 130

  
136 131
              mCubes[x][y][z]           = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
137 132
              cubeVectors[x][y][z]      = new Static3D( TEXTURE_SIZE*(x-nc), TEXTURE_SIZE*(y-nc), TEXTURE_SIZE*(z-nc) );
138
              mQuatScramble[x][y][z]    = new Static4D(0,0,0,1);
139 133
              mRotationAngle[x][y][z]   = new Dynamic1D();
140 134
              mRotationAxis[x][y][z]    = new Static3D(1,0,0);
141
              mCurrentPosition[x][y][z] = new Static3D(x,y,z);
135

  
136
              mRotationAngle[x][y][z].add(new Static1D(0.0f));
137
              mRotationAngle[x][y][z].add(new Static1D(0.0f));
142 138

  
143 139
              mEffects[x][y][z] = new DistortedEffects();
144 140
              mEffects[x][y][z].apply(sinkEffect);
145 141
              mEffects[x][y][z].apply(moveEffect);
146 142
              mEffects[x][y][z].apply(scaleEffect);
147
              mEffects[x][y][z].apply(quatCEffect);
148
              mEffects[x][y][z].apply(quatAEffect);
143
              mEffects[x][y][z].apply(quatEffect);
149 144
              mEffects[x][y][z].apply( new MatrixEffectRotate( mRotationAngle[x][y][z], mRotationAxis[x][y][z], center));
150
              mEffects[x][y][z].apply( new MatrixEffectQuaternion(mQuatScramble[x][y][z], center));
151 145
              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
152 146
              }
153 147
            }
......
192 186

  
193 187
///////////////////////////////////////////////////////////////////////////////////////////////////
194 188

  
195
    void addNewRotation(int vector, float offset )
189
    void addRotation(EffectListener listener)
196 190
      {
191
      mRnd.setSeed(System.currentTimeMillis());
192

  
193
      int vector = mRnd.nextInt(3);
194
      int rotRow = mRnd.nextInt(mSize);
195

  
196
      boolean first = true;
197 197
      Static3D axis = VectX;
198 198

  
199 199
      switch(vector)
200 200
        {
201
        case RubikSurfaceView.VECTX: axis = VectX; break;
202
        case RubikSurfaceView.VECTY: axis = VectY; break;
203
        case RubikSurfaceView.VECTZ: axis = VectZ; break;
201
        case VECTX: axis = VectX; break;
202
        case VECTY: axis = VectY; break;
203
        case VECTZ: axis = VectZ; break;
204 204
        }
205 205

  
206
      mRotAxis = vector;
207
      mRotRow  = (int)(mSize*offset);
208

  
209
      mRotationAngleStatic.set1(0.0f);
210

  
211 206
      for(int x=0; x<mSize; x++)
212 207
        for(int y=0; y<mSize; y++)
213 208
          for(int z=0; z<mSize; z++)
214 209
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
215 210
              {
216
              if( belongsToRotation(x,y,z,vector,mRotRow) )
211
              if( belongsToRotation(x,y,z,vector,rotRow) )
217 212
                {
218 213
                mRotationAxis[x][y][z].set(axis);
219
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
220
                }
221
              }
222
      }
223

  
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

  
226
    void continueRotation(float angleInDegrees)
227
      {
228
      mRotationAngleStatic.set1(angleInDegrees);
229
      }
230

  
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

  
233
    private int computeNearestAngle(float angle)
234
      {
235
      final int NEAREST = 90;
236

  
237
      int tmp = (int)((angle+NEAREST/2)/NEAREST);
238
      if( angle< -(NEAREST/2) ) tmp-=1;
239

  
240
      return NEAREST*tmp;
241
      }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
    void finishRotationNow(EffectListener listener)
246
      {
247
      boolean first = true;
248
      float startingAngle = mRotationAngleStatic.get1();
249
      int nearestAngleInDegrees = computeNearestAngle(startingAngle);
250

  
251
      mRotationAngleFinal.set1(nearestAngleInDegrees);
252
      mRotationAngleMiddle.set1( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f );
253

  
254
      for(int x=0; x<mSize; x++)
255
        for(int y=0; y<mSize; y++)
256
          for(int z=0; z<mSize; z++)
257
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
258
              {
259
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
260
                {
261
                mRotationAngle[x][y][z].makeRunNowFor(POST_ROTATION_MILLISEC);
262
                mRotationAngle[x][y][z].add(mRotationAngleMiddle);
263
                mRotationAngle[x][y][z].add(mRotationAngleFinal);
214
                mRotationAngle[x][y][z].makeRunNowFor(ROTATION_MILLISEC);
215
                mRotationAngle[x][y][z].setPoint(1,90.0f);
264 216

  
265 217
                if( first )
266 218
                  {
267 219
                  first = false;
268
                  mEffectsListeningForNow = mEffects[x][y][z];
269
                  mEffectsListeningForNow.registerForMessages(listener);
220
                  mEffects[x][y][z].registerForMessages(listener);
270 221
                  }
271 222
                }
272 223
              }
273 224
      }
274 225

  
275 226
///////////////////////////////////////////////////////////////////////////////////////////////////
227
// Initial rotation of the cube. Something semi-random that looks good.
276 228

  
277
    void removeRotationNow(EffectListener listener)
278
      {
279
      mEffectsListeningForNow.deregisterForMessages(listener);
280

  
281
      int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1());
282
      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
283
      float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
284
      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
285

  
286
      mRotationAngleStatic.set1(0);
229
   private Static4D initializeQuat()
230
     {
231
     return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
232
     }
287 233

  
288
      float qx=0,qy=0,qz=0;
234
///////////////////////////////////////////////////////////////////////////////////////////////////
289 235

  
290
      switch(mRotAxis)
236
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
237
      {
238
      switch(vector)
291 239
        {
292
        case RubikSurfaceView.VECTX: qx=1; break;
293
        case RubikSurfaceView.VECTY: qy=1; break;
294
        case RubikSurfaceView.VECTZ: qz=1; break;
240
        case VECTX: return x==row;
241
        case VECTY: return y==row;
242
        case VECTZ: return z==row;
295 243
        }
296 244

  
297
      Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
298

  
299
      for(int x=0; x<mSize; x++)
300
        for(int y=0; y<mSize; y++)
301
          for(int z=0; z<mSize; z++)
302
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
303
              {
304
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
305
                {
306
                mRotationAngle[x][y][z].makeRunNowFor(0);
307
                mRotationAngle[x][y][z].removeAll();
308
                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
309
                modifyCurrentPosition(x,y,z,quat);
310
                }
311
              }
245
      return false;
312 246
      }
313 247

  
314 248
///////////////////////////////////////////////////////////////////////////////////////////////////
......
325 259
        }
326 260
      }
327 261

  
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

  
330
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
331
      {
332
      switch(vector)
333
        {
334
        case RubikSurfaceView.VECTX: return mCurrentPosition[x][y][z].get1()==row;
335
        case RubikSurfaceView.VECTY: return mCurrentPosition[x][y][z].get2()==row;
336
        case RubikSurfaceView.VECTZ: return mCurrentPosition[x][y][z].get3()==row;
337
        }
338

  
339
      return false;
340
      }
341

  
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

  
344
    private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
345
      {
346
      Static3D current = mCurrentPosition[x][y][z];
347
      float diff = 0.5f*(mSize-1);
348
      float cubitCenterX = current.get1() - diff;
349
      float cubitCenterY = current.get2() - diff;
350
      float cubitCenterZ = current.get3() - diff;
351

  
352
      Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
353
      Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
354

  
355
      float rotatedX = rotatedCenter.get1() + diff;
356
      float rotatedY = rotatedCenter.get2() + diff;
357
      float rotatedZ = rotatedCenter.get3() + diff;
358

  
359
      int roundedX = (int)(rotatedX+0.1f);
360
      int roundedY = (int)(rotatedY+0.1f);
361
      int roundedZ = (int)(rotatedZ+0.1f);
362

  
363
      mCurrentPosition[x][y][z].set1(roundedX);
364
      mCurrentPosition[x][y][z].set2(roundedY);
365
      mCurrentPosition[x][y][z].set3(roundedZ);
366
      }
367

  
368 262
///////////////////////////////////////////////////////////////////////////////////////////////////
369 263

  
370 264
    void createTexture()

Also available in: Unified diff