Project

General

Profile

Download (14.8 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / object / RubikCube.java @ 70b76549

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 0c52af30 Leszek Koltunski
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 0c52af30 Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 beb325a0 Leszek Koltunski
package org.distorted.object;
21 0c52af30 Leszek Koltunski
22 5bfc1b49 Leszek Koltunski
import android.content.SharedPreferences;
23 0c52af30 Leszek Koltunski
import android.graphics.Bitmap;
24
import android.graphics.Canvas;
25
import android.graphics.Paint;
26
27 434f2f5a Leszek Koltunski
import org.distorted.library.effect.Effect;
28 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.mesh.MeshCubes;
31 97c012ae Leszek Koltunski
import org.distorted.library.mesh.MeshRectangles;
32 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
36 27a70eae Leszek Koltunski
import static org.distorted.object.RubikObjectList.VECTX;
37
import static org.distorted.object.RubikObjectList.VECTY;
38
import static org.distorted.object.RubikObjectList.VECTZ;
39
40 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 27a70eae Leszek Koltunski
class RubikCube extends RubikObject
43 0c52af30 Leszek Koltunski
{
44
    private static final Static3D VectX = new Static3D(1,0,0);
45
    private static final Static3D VectY = new Static3D(0,1,0);
46
    private static final Static3D VectZ = new Static3D(0,0,1);
47 70b76549 Leszek Koltunski
    private static final Static4D mapFront, mapBack, mapLeft, mapRight, mapTop, mapBottom, mapBlack;
48 0c52af30 Leszek Koltunski
49 70b76549 Leszek Koltunski
    private Cubit[][][] mCubits;
50 0c52af30 Leszek Koltunski
51 70b76549 Leszek Koltunski
    static
52 0c52af30 Leszek Koltunski
      {
53 70b76549 Leszek Koltunski
      // 3x2 bitmap = 6 squares:
54
      //
55
      // RED     GREEN   BLUE
56
      // YELLOW  WHITE   BROWN
57 f16ff19d Leszek Koltunski
58 70b76549 Leszek Koltunski
      final float ze = 0.0f;
59
      final float ot = 1.0f/3.0f;
60
      final float tt = 2.0f/3.0f;
61
      final float oh = 1.0f/2.0f;
62
      final float of = 1.0f/40.0f;
63 f16ff19d Leszek Koltunski
64 70b76549 Leszek Koltunski
      mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
65
      mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
66
      mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
67
      mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
68
      mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
69
      mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
70 f16ff19d Leszek Koltunski
71 70b76549 Leszek Koltunski
      mapBlack = new Static4D(ze,ze, ze+of,ze+of);
72 30b68322 Leszek Koltunski
      }
73 47ba5ddc Leszek Koltunski
74 9208e27b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
75 70b76549 Leszek Koltunski
// All legal rotation quats of a RubikCube of any size must have all four of their components
76
// equal to either 0, 1, -1, 0.5, -0.5 or +-sqrt(2)/2.
77 9208e27b Leszek Koltunski
78 f16ff19d Leszek Koltunski
    float[] getLegalQuats()
79 9208e27b Leszek Koltunski
      {
80 f16ff19d Leszek Koltunski
      final float SQ2 = 0.5f*((float)Math.sqrt(2));
81
      return new float[] { 0.0f , 0.5f , -0.5f , 1.0f , -1.0f , SQ2 , -SQ2 };
82
      }
83
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85
86
    private boolean belongsToRotation( Static3D currentPosition, int vector, int row)
87
      {
88
      switch(vector)
89
        {
90
        case VECTX: return currentPosition.get0()==row;
91
        case VECTY: return currentPosition.get1()==row;
92
        case VECTZ: return currentPosition.get2()==row;
93
        }
94
95
      return false;
96 434f2f5a Leszek Koltunski
      }
97
98 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
99
100 97c012ae Leszek Koltunski
    RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshRectangles mesh, DistortedEffects effects)
101 beb325a0 Leszek Koltunski
      {
102 27a70eae Leszek Koltunski
      super(size,quatCur,quatAcc,texture,mesh,effects);
103 beb325a0 Leszek Koltunski
104
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
105 f16ff19d Leszek Koltunski
      mCubits  = new Cubit[mSize][mSize][mSize];
106 beb325a0 Leszek Koltunski
107
      int vertices = (int)(24.0f/mSize + 2.0f);
108
109
      for(int x = 0; x< mSize; x++)
110
        for(int y = 0; y< mSize; y++)
111
          for(int z = 0; z< mSize; z++)
112
            {
113 70b76549 Leszek Koltunski
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
114 beb325a0 Leszek Koltunski
              {
115 70b76549 Leszek Koltunski
              mCubits[x][y][z] = new Cubit( this,createMesh(vertices,x,y,z),new Static3D(x,y,z) );
116 f16ff19d Leszek Koltunski
              attach(mCubits[x][y][z].mNode);
117 beb325a0 Leszek Koltunski
              }
118
            }
119
      }
120
121 775e675d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
122 27a70eae Leszek Koltunski
// PUBLIC API
123 5bfc1b49 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
124 8e1231ae Leszek Koltunski
// mSize already saved as RubikStatePlay.mButton
125 5bfc1b49 Leszek Koltunski
126
   public void savePreferences(SharedPreferences.Editor editor)
127
     {
128 8e1231ae Leszek Koltunski
     for(int x=0; x<mSize; x++)
129
        for(int y=0; y<mSize; y++)
130
          for(int z=0; z<mSize; z++)
131
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
132
              {
133 f16ff19d Leszek Koltunski
              mCubits[x][y][z].savePreferences(editor);
134 8e1231ae Leszek Koltunski
              }
135 5bfc1b49 Leszek Koltunski
     }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139
   public void restorePreferences(SharedPreferences preferences)
140
     {
141 8e1231ae Leszek Koltunski
     for(int x=0; x<mSize; x++)
142
        for(int y=0; y<mSize; y++)
143
          for(int z=0; z<mSize; z++)
144
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
145
              {
146 f16ff19d Leszek Koltunski
              mCubits[x][y][z].restorePreferences(preferences);
147 8e1231ae Leszek Koltunski
              }
148 5bfc1b49 Leszek Koltunski
     }
149
150 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152 27a70eae Leszek Koltunski
   public long finishRotationNow(EffectListener listener)
153
     {
154
     boolean first = true;
155
     long effectID=0;
156 434f2f5a Leszek Koltunski
157 27a70eae Leszek Koltunski
     for(int x=0; x<mSize; x++)
158
       for(int y=0; y<mSize; y++)
159
         for(int z=0; z<mSize; z++)
160
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
161
             {
162 f16ff19d Leszek Koltunski
             if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,mRotAxis,mRotRow) )
163 27a70eae Leszek Koltunski
               {
164
               if( first )
165
                 {
166
                 first = false;
167 f16ff19d Leszek Koltunski
                 effectID = mCubits[x][y][z].finishRotationNow(listener);
168 27a70eae Leszek Koltunski
                 }
169
170 f16ff19d Leszek Koltunski
               resetRotationAngle(mCubits[x][y][z].mRotationAngle);
171 27a70eae Leszek Koltunski
               }
172
             }
173
174
     return effectID;
175
     }
176 0c52af30 Leszek Koltunski
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178
179 27a70eae Leszek Koltunski
   public void releaseResources()
180
     {
181
     mTexture.markForDeletion();
182 beb325a0 Leszek Koltunski
183 27a70eae Leszek Koltunski
     for(int x=0; x<mSize; x++)
184
       for(int y=0; y<mSize; y++)
185
         for(int z=0; z<mSize; z++)
186
           {
187
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
188
             {
189 f16ff19d Leszek Koltunski
             mCubits[x][y][z].releaseResources();
190 27a70eae Leszek Koltunski
             }
191
           }
192
     }
193 0c52af30 Leszek Koltunski
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195
196 27a70eae Leszek Koltunski
   public void apply(Effect effect, int position)
197
     {
198
     for(int x=0; x<mSize; x++)
199
       for(int y=0; y<mSize; y++)
200
         for(int z=0; z<mSize; z++)
201
           {
202
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
203
             {
204 f16ff19d Leszek Koltunski
             mCubits[x][y][z].mEffect.apply(effect, position);
205 27a70eae Leszek Koltunski
             }
206
           }
207 0c52af30 Leszek Koltunski
      }
208 47ba5ddc Leszek Koltunski
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211 27a70eae Leszek Koltunski
   public void remove(long effectID)
212
     {
213
     for(int x=0; x<mSize; x++)
214
       for(int y=0; y<mSize; y++)
215
         for(int z=0; z<mSize; z++)
216
           {
217
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
218
             {
219 f16ff19d Leszek Koltunski
             mCubits[x][y][z].mEffect.abortById(effectID);
220 27a70eae Leszek Koltunski
             }
221
           }
222 47ba5ddc Leszek Koltunski
      }
223
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225
226 27a70eae Leszek Koltunski
   public void solve()
227
     {
228
     for(int x=0; x<mSize; x++)
229
       for(int y=0; y<mSize; y++)
230
         for(int z=0; z<mSize; z++)
231
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
232
             {
233 f16ff19d Leszek Koltunski
             mCubits[x][y][z].solve();
234 27a70eae Leszek Koltunski
             }
235 47ba5ddc Leszek Koltunski
      }
236
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
239 27a70eae Leszek Koltunski
   public boolean isSolved()
240
     {
241 f16ff19d Leszek Koltunski
     Static4D q = mCubits[0][0][0].mQuatScramble;
242 27a70eae Leszek Koltunski
243
     float x = q.get0();
244
     float y = q.get1();
245
     float z = q.get2();
246
     float w = q.get3();
247
248
     for(int i = 0; i< mSize; i++)
249
       for(int j = 0; j< mSize; j++)
250
         for(int k = 0; k< mSize; k++)
251
           {
252
           if( i==0 || i==mSize-1 || j==0 || j==mSize-1 || k==0 || k==mSize-1 )
253
             {
254 f16ff19d Leszek Koltunski
             q = mCubits[i][j][k].mQuatScramble;
255 27a70eae Leszek Koltunski
256
             if( q.get0()!=x || q.get1()!=y || q.get2()!=z || q.get3()!=w )
257
               {
258
               return false;
259
               }
260
             }
261
           }
262
263
     return true;
264
     }
265 47ba5ddc Leszek Koltunski
266 beb325a0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268 27a70eae Leszek Koltunski
   public void beginNewRotation(int vector, int row )
269
     {
270
     Static3D axis = VectX;
271 beb325a0 Leszek Koltunski
272 27a70eae Leszek Koltunski
     switch(vector)
273
       {
274
       case VECTX: axis = VectX; break;
275
       case VECTY: axis = VectY; break;
276
       case VECTZ: axis = VectZ; break;
277
       }
278 beb325a0 Leszek Koltunski
279 27a70eae Leszek Koltunski
     mRotAxis = vector;
280
     mRotRow  = row;
281 beb325a0 Leszek Koltunski
282 27a70eae Leszek Koltunski
     mRotationAngleStatic.set0(0.0f);
283 47ba5ddc Leszek Koltunski
284 27a70eae Leszek Koltunski
     for(int x=0; x<mSize; x++)
285
       for(int y=0; y<mSize; y++)
286
         for(int z=0; z<mSize; z++)
287
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
288
             {
289 f16ff19d Leszek Koltunski
             if( belongsToRotation( mCubits[x][y][z].mCurrentPosition,vector,mRotRow) )
290 27a70eae Leszek Koltunski
               {
291 f16ff19d Leszek Koltunski
               mCubits[x][y][z].beginNewRotation(axis);
292 27a70eae Leszek Koltunski
               }
293
             }
294
     }
295 47ba5ddc Leszek Koltunski
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297
298 27a70eae Leszek Koltunski
   public long addNewRotation(int vector, int row, int angle, long durationMillis, EffectListener listener )
299 47ba5ddc Leszek Koltunski
      {
300
      Static3D axis = VectX;
301
      long effectID=0;
302
      boolean first = true;
303
304
      switch(vector)
305
        {
306
        case VECTX: axis = VectX; break;
307
        case VECTY: axis = VectY; break;
308
        case VECTZ: axis = VectZ; break;
309
        }
310
311
      mRotAxis = vector;
312
      mRotRow  = row;
313
314 348dfe69 Leszek Koltunski
      mRotationAngleStatic.set0(0.0f);
315 47ba5ddc Leszek Koltunski
316
      for(int x=0; x<mSize; x++)
317
        for(int y=0; y<mSize; y++)
318
          for(int z=0; z<mSize; z++)
319
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
320
              {
321 f16ff19d Leszek Koltunski
              if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,vector,mRotRow) )
322 47ba5ddc Leszek Koltunski
                {
323 f16ff19d Leszek Koltunski
                mCubits[x][y][z].addNewRotation(axis,durationMillis,angle);
324 47ba5ddc Leszek Koltunski
325
                if( first )
326
                  {
327
                  first = false;
328 f16ff19d Leszek Koltunski
                  effectID = mCubits[x][y][z].setUpCallback(listener);
329 47ba5ddc Leszek Koltunski
                  }
330
                }
331
              }
332
333
      return effectID;
334
      }
335
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338 27a70eae Leszek Koltunski
   public void removeRotationNow()
339 47ba5ddc Leszek Koltunski
      {
340
      float qx=0,qy=0,qz=0;
341
      boolean first = true;
342
      Static4D quat = null;
343
344
      switch(mRotAxis)
345
        {
346
        case VECTX: qx=1; break;
347
        case VECTY: qy=1; break;
348
        case VECTZ: qz=1; break;
349
        }
350
351
      for(int x=0; x<mSize; x++)
352
        for(int y=0; y<mSize; y++)
353
          for(int z=0; z<mSize; z++)
354
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
355
              {
356 f16ff19d Leszek Koltunski
              if( belongsToRotation(mCubits[x][y][z].mCurrentPosition,mRotAxis,mRotRow) )
357 47ba5ddc Leszek Koltunski
                {
358
                if( first )
359
                  {
360
                  first = false;
361 f16ff19d Leszek Koltunski
                  quat = mCubits[x][y][z].returnRotationQuat(qx,qy,qz);
362 47ba5ddc Leszek Koltunski
                  }
363
364 f16ff19d Leszek Koltunski
                mCubits[x][y][z].removeRotationNow(quat);
365 47ba5ddc Leszek Koltunski
                }
366
              }
367
368 348dfe69 Leszek Koltunski
      mRotationAngleStatic.set0(0);
369 47ba5ddc Leszek Koltunski
      }
370 70b76549 Leszek Koltunski
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
373
   public void createTexture()
374
     {
375
     Bitmap bitmap;
376
377
     final int S = 128;
378
     final int W = 3*S;
379
     final int H = 2*S;
380
     final int R = S/10;
381
     final int M = S/20;
382
383
     Paint paint = new Paint();
384
     bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
385
     Canvas canvas = new Canvas(bitmap);
386
387
     paint.setAntiAlias(true);
388
     paint.setTextAlign(Paint.Align.CENTER);
389
     paint.setStyle(Paint.Style.FILL);
390
391
     // 3x2 bitmap = 6 squares:
392
     //
393
     // RED     GREEN   BLUE
394
     // YELLOW  WHITE   BROWN
395
396
     paint.setColor(0xff000000);                                  // BLACK BACKGROUND
397
     canvas.drawRect(0, 0, W, H, paint);                          //
398
399
     paint.setColor(0xffff0000);                                  // RED
400
     canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
401
     paint.setColor(0xff00ff00);                                  // GREEN
402
     canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
403
     paint.setColor(0xff0000ff);                                  // BLUE
404
     canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
405
     paint.setColor(0xffffff00);                                  // YELLOW
406
     canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
407
     paint.setColor(0xffffffff);                                  // WHITE
408
     canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
409
     paint.setColor(0xffb5651d);                                  // BROWN
410
     canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
411
412
     mTexture.setTexture(bitmap);
413
     }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
   private MeshCubes createMesh(int vertices,int x, int y, int z)
418
     {
419
     Static4D tmpLeft  = (x==       0 ? mapLeft  :mapBlack);
420
     Static4D tmpRight = (x== mSize-1 ? mapRight :mapBlack);
421
     Static4D tmpFront = (z== mSize-1 ? mapFront :mapBlack);
422
     Static4D tmpBack  = (z==       0 ? mapBack  :mapBlack);
423
     Static4D tmpTop   = (y== mSize-1 ? mapTop   :mapBlack);
424
     Static4D tmpBottom= (y==       0 ? mapBottom:mapBlack);
425
426
     return new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
427
     }
428 0c52af30 Leszek Koltunski
}