Project

General

Profile

Download (18.9 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCube.java @ 8da6b1c9

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// 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
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// 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
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.objectlib.objects;
21
22
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
23
24
import android.content.res.Resources;
25
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35 8592461c Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
36 8005e762 Leszek Koltunski
import org.distorted.objectlib.main.ObjectType;
37 198c5bf0 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40 29b82486 Leszek Koltunski
import org.distorted.objectlib.main.Twisty6;
41
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43
44
public class TwistyCube extends Twisty6
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(1,0,0),
49
           new Static3D(0,1,0),
50
           new Static3D(0,0,1)
51
         };
52
53
  private static final int[][][] ENABLED = new int[][][]
54
      {
55
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
56
      };
57
58
  private ScrambleState[] mStates;
59
  private Static4D[] mQuats;
60
  private float[][] mCuts;
61
  private boolean[][] mLayerRotatable;
62
  private int[] mBasicAngle;
63
  private ObjectSticker[] mStickers;
64
  private Movement mMovement;
65
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67
68 ecf3d6e3 Leszek Koltunski
  public TwistyCube(int size, Static4D quat, Static3D move, DistortedTexture texture,
69
                    MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
70 29b82486 Leszek Koltunski
    {
71 ecf3d6e3 Leszek Koltunski
    super(size, size, quat, move, texture, mesh, effects, res, scrWidth);
72 29b82486 Leszek Koltunski
    }
73
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75
76
  protected ScrambleState[] getScrambleStates()
77
    {
78
    if( mStates==null )
79
      {
80
      int size = getNumLayers();
81
      int[][] m = new int[16][];
82
      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
83
84
      mStates = new ScrambleState[]
85
        {
86 7ce20d2a Leszek Koltunski
        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
87
        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
88
        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
89
        new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
90
        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
91
        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
92
        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
93
        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
94
        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
95
        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
96
        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
97
        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
98
        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
99
        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
100
        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
101
        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
102 29b82486 Leszek Koltunski
        };
103
      }
104
105
    return mStates;
106
    }
107
108 4e1dc313 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
109
110
  protected int getResource(int numLayers)
111
    {
112
    switch(numLayers)
113
      {
114
      case 2: return R.raw.cube2;
115
      case 3: return R.raw.cube3;
116
      case 4: return R.raw.cube4;
117
      case 5: return R.raw.cube5;
118
      }
119
120
    return 0;
121
    }
122
123 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125
  private int[] createEdges(int size, int vertex)
126
    {
127
    int[] ret = new int[9*size];
128
129
    for(int l=0; l<size; l++)
130
      {
131
      ret[9*l  ] = l;
132
      ret[9*l+1] =-1;
133
      ret[9*l+2] = vertex;
134
      ret[9*l+3] = l;
135
      ret[9*l+4] = 1;
136
      ret[9*l+5] = vertex;
137
      ret[9*l+6] = l;
138
      ret[9*l+7] = 2;
139
      ret[9*l+8] = vertex;
140
      }
141
142
    return ret;
143
    }
144
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
147
  private void initializeQuats()
148
    {
149
    mQuats = new Static4D[]
150
         {
151
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
152
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
153
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
154
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
155
156
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
157
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
158
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
159
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
160
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
161
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
162
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
163
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
164
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
165
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
166
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
167
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
168
169
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
170
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
171
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
172
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
173
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
174
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
175
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
176
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
177
         };
178
    }
179
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
182
  protected int[] getSolvedQuats(int cubit, int numLayers)
183
    {
184
    if( mQuats ==null ) initializeQuats();
185
    int status = retCubitSolvedStatus(cubit,numLayers);
186
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
187
    }
188
189 8da6b1c9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
190
191
  private int getNumCornersAndEdges(int numLayers)
192
    {
193
    return numLayers==1 ? 1 : 12*(numLayers-2) + 8;
194
    }
195
196 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
197
198
  protected ObjectShape getObjectShape(int cubit, int numLayers)
199
    {
200
    int extraI, extraV, num;
201
    float height;
202
203
    switch(numLayers)
204
      {
205
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
206
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
207
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
208
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
209
      }
210
211
    double[][] vertices = new double[][]
212
          {
213
              { 0.5, 0.5, 0.5 },
214
              { 0.5, 0.5,-0.5 },
215
              { 0.5,-0.5, 0.5 },
216
              { 0.5,-0.5,-0.5 },
217
              {-0.5, 0.5, 0.5 },
218
              {-0.5, 0.5,-0.5 },
219
              {-0.5,-0.5, 0.5 },
220
              {-0.5,-0.5,-0.5 },
221
          };
222
223
    int[][] vert_indices = new int[][]
224
          {
225
              {2,3,1,0},
226
              {7,6,4,5},
227
              {4,0,1,5},
228
              {7,3,2,6},
229
              {6,2,0,4},
230
              {3,7,5,1}
231
          };
232
233
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
234
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
235
    float[][] corners   = new float[][] { {0.036f,0.12f} };
236
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
237
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
238
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
239
240
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
241
    }
242
243 8da6b1c9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
244
245
  protected float[][] getCubitPositions(int numLayers)
246
    {
247
    if( numLayers==1 ) return new float[][] {{ 0.0f, 0.0f, 0.0f }};
248
249
    int numCubits = getNumCornersAndEdges(numLayers) + 6*(numLayers-2)*(numLayers-2);
250
    float[][] tmp = new float[numCubits][];
251
252
    final float LEN = 0.5f*(numLayers-1);
253
    int currentPosition = 0;
254
255
    tmp[currentPosition++] = new float[] {-LEN,-LEN,-LEN};
256
    tmp[currentPosition++] = new float[] {-LEN,-LEN,+LEN};
257
    tmp[currentPosition++] = new float[] {-LEN,+LEN,-LEN};
258
    tmp[currentPosition++] = new float[] {-LEN,+LEN,+LEN};
259
    tmp[currentPosition++] = new float[] {+LEN,-LEN,-LEN};
260
    tmp[currentPosition++] = new float[] {+LEN,-LEN,+LEN};
261
    tmp[currentPosition++] = new float[] {+LEN,+LEN,-LEN};
262
    tmp[currentPosition++] = new float[] {+LEN,+LEN,+LEN};
263
264
    for(int i=1; i<numLayers-1; i++)
265
      tmp[currentPosition++] = new float[] { i-LEN,  -LEN,  -LEN };
266
    for(int i=1; i<numLayers-1; i++)
267
      tmp[currentPosition++] = new float[] { i-LEN,  -LEN,  +LEN };
268
    for(int i=1; i<numLayers-1; i++)
269
      tmp[currentPosition++] = new float[] { i-LEN,  +LEN,  -LEN };
270
    for(int i=1; i<numLayers-1; i++)
271
      tmp[currentPosition++] = new float[] { i-LEN,  +LEN,  +LEN };
272
    for(int i=1; i<numLayers-1; i++)
273
      tmp[currentPosition++] = new float[] {  -LEN, i-LEN,  -LEN };
274
    for(int i=1; i<numLayers-1; i++)
275
      tmp[currentPosition++] = new float[] {  -LEN, i-LEN,  +LEN };
276
    for(int i=1; i<numLayers-1; i++)
277
      tmp[currentPosition++] = new float[] {  +LEN, i-LEN,  -LEN };
278
    for(int i=1; i<numLayers-1; i++)
279
      tmp[currentPosition++] = new float[] {  +LEN, i-LEN,  +LEN };
280
    for(int i=1; i<numLayers-1; i++)
281
      tmp[currentPosition++] = new float[] {  -LEN,  -LEN, i-LEN };
282
    for(int i=1; i<numLayers-1; i++)
283
      tmp[currentPosition++] = new float[] {  -LEN,  +LEN, i-LEN };
284
    for(int i=1; i<numLayers-1; i++)
285
      tmp[currentPosition++] = new float[] {  +LEN,  -LEN, i-LEN };
286
    for(int i=1; i<numLayers-1; i++)
287
      tmp[currentPosition++] = new float[] {  +LEN,  +LEN, i-LEN };
288
289
    for(int y=1; y<numLayers-1; y++)
290
      for(int z=1; z<numLayers-1; z++)
291
        tmp[currentPosition++] = new float[] {+LEN,y-LEN,z-LEN};
292
293
    for(int y=1; y<numLayers-1; y++)
294
      for(int z=1; z<numLayers-1; z++)
295
        tmp[currentPosition++] = new float[] {-LEN,y-LEN,z-LEN};
296
297
    for(int x=1; x<numLayers-1; x++)
298
      for(int z=1; z<numLayers-1; z++)
299
        tmp[currentPosition++] = new float[] {x-LEN,+LEN,z-LEN};
300
301
    for(int x=1; x<numLayers-1; x++)
302
      for(int z=1; z<numLayers-1; z++)
303
        tmp[currentPosition++] = new float[] {x-LEN,-LEN,z-LEN};
304
305
    for(int x=1; x<numLayers-1; x++)
306
      for(int y=1; y<numLayers-1; y++)
307
        tmp[currentPosition++] = new float[] {x-LEN,y-LEN,+LEN};
308
309
    for(int x=1; x<numLayers-1; x++)
310
      for(int y=1; y<numLayers-1; y++)
311
        tmp[currentPosition++] = new float[] {x-LEN,y-LEN,-LEN};
312
313
    return tmp;
314
    }
315
316 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
317
318
  protected Static4D getQuat(int cubit, int numLayers)
319
    {
320
    if( mQuats ==null ) initializeQuats();
321 8da6b1c9 Leszek Koltunski
322
    int num = cubit - getNumCornersAndEdges(numLayers);
323
324
    if( num>=0 )
325
      {
326
      int face = num/((numLayers-2)*(numLayers-2));
327
328
      switch(face)
329
        {
330
        case 0: return mQuats[13];
331
        case 1: return mQuats[12];
332
        case 2: return mQuats[ 8];
333
        case 3: return mQuats[ 9];
334
        case 4: return mQuats[ 0];
335
        case 5: return mQuats[ 1];
336
        }
337
      }
338
339 29b82486 Leszek Koltunski
    return mQuats[0];
340
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344
  protected int getNumCubitVariants(int numLayers)
345
    {
346 8da6b1c9 Leszek Koltunski
    return numLayers>2 ? 2:1;
347 29b82486 Leszek Koltunski
    }
348
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
351
  protected int getCubitVariant(int cubit, int numLayers)
352
    {
353 8da6b1c9 Leszek Koltunski
    return cubit < getNumCornersAndEdges(numLayers) ? 0 : 1;
354
    }
355
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
359
    {
360
    int cornersAndEdges = getNumCornersAndEdges(numLayers);
361
362
    if( cubit<cornersAndEdges )
363
      {
364
      return CUBITS[cubit].getRotRow(cubitface/2) == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
365
      }
366
    else
367
      {
368
      int numCentersPerFace = (numLayers-2)*(numLayers-2);
369
      return cubitface == 4 ? (cubit-cornersAndEdges)/numCentersPerFace : NUM_TEXTURES;
370
      }
371 29b82486 Leszek Koltunski
    }
372
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374
375
  protected ObjectSticker retSticker(int face)
376
    {
377
    if( mStickers==null )
378
      {
379
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
380
      final float radius = 0.10f;
381
      final float[] radii = {radius,radius,radius,radius};
382
      mStickers = new ObjectSticker[STICKERS.length];
383 8592461c Leszek Koltunski
      float stroke = 0.08f;
384
385
      if( ObjectControl.isInIconMode() )
386
        {
387
        switch(getNumLayers())
388
          {
389
          case 2: stroke*=1.8f; break;
390
          case 3: stroke*=2.0f; break;
391
          case 4: stroke*=2.1f; break;
392
          default:stroke*=2.2f; break;
393
          }
394
        }
395
396 29b82486 Leszek Koltunski
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
397
      }
398
399
    return mStickers[face/NUM_FACE_COLORS];
400
    }
401
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403
404
  protected Static4D[] getQuats()
405
    {
406
    if( mQuats ==null ) initializeQuats();
407
    return mQuats;
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412
  protected float[][] getCuts(int numLayers)
413
    {
414
    if( numLayers<2 ) return null;
415
416
    if( mCuts==null )
417
      {
418
      mCuts = new float[3][numLayers-1];
419
420
      for(int i=0; i<numLayers-1; i++)
421
        {
422
        float cut = (2-numLayers)*0.5f + i;
423
        mCuts[0][i] = cut;
424
        mCuts[1][i] = cut;
425
        mCuts[2][i] = cut;
426
        }
427
      }
428
429
    return mCuts;
430
    }
431
432
///////////////////////////////////////////////////////////////////////////////////////////////////
433
434
  private void getLayerRotatable(int numLayers)
435
    {
436
    if( mLayerRotatable==null )
437
      {
438
      int numAxis = ROT_AXIS.length;
439
      boolean[] tmp = new boolean[numLayers];
440
      for(int i=0; i<numLayers; i++) tmp[i] = true;
441
      mLayerRotatable = new boolean[numAxis][];
442
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
443
      }
444
    }
445
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447
448
  protected int getSolvedFunctionIndex()
449
    {
450
    return 0;
451
    }
452
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454
455
  protected int getNumStickerTypes(int numLayers)
456
    {
457
    return 1;
458
    }
459
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461
462
  protected int getNumCubitFaces()
463
    {
464
    return 6;
465
    }
466
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468
// PUBLIC API
469
470
  public Static3D[] getRotationAxis()
471
    {
472
    return ROT_AXIS;
473
    }
474
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476
477
  public Movement getMovement()
478
    {
479
    if( mMovement==null )
480
      {
481
      int numLayers = getNumLayers();
482
      if( mCuts==null ) getCuts(numLayers);
483
      getLayerRotatable(numLayers);
484
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
485
      }
486
    return mMovement;
487
    }
488
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491
  public int[] getBasicAngle()
492
    {
493
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
494
    return mBasicAngle;
495
    }
496
497 61aa85e4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
498
499 c8bc83d9 Leszek Koltunski
  public ObjectType intGetObjectType(int numLayers)
500 61aa85e4 Leszek Koltunski
    {
501
    switch(numLayers)
502
      {
503 8005e762 Leszek Koltunski
      case 2: return ObjectType.CUBE_2;
504
      case 3: return ObjectType.CUBE_3;
505
      case 4: return ObjectType.CUBE_4;
506
      case 5: return ObjectType.CUBE_5;
507 61aa85e4 Leszek Koltunski
      }
508
509 8005e762 Leszek Koltunski
    return ObjectType.CUBE_3;
510 61aa85e4 Leszek Koltunski
    }
511
512 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
513
514
  public int getObjectName(int numLayers)
515
    {
516
    switch(numLayers)
517
      {
518
      case 2: return R.string.cube2;
519
      case 3: return R.string.cube3;
520
      case 4: return R.string.cube4;
521
      case 5: return R.string.cube5;
522
      }
523
    return R.string.cube3;
524
    }
525
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527
528
  public int getInventor(int numLayers)
529
    {
530
    switch(numLayers)
531
      {
532
      case 2: return R.string.cube2_inventor;
533
      case 3: return R.string.cube3_inventor;
534
      case 4: return R.string.cube4_inventor;
535
      case 5: return R.string.cube5_inventor;
536
      }
537
    return R.string.cube3_inventor;
538
    }
539
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541
542
  public int getComplexity(int numLayers)
543
    {
544
    switch(numLayers)
545
      {
546
      case 2: return 4;
547
      case 3: return 6;
548
      case 4: return 8;
549
      case 5: return 10;
550
      }
551
    return 6;
552
    }
553
}