Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCuboid.java @ 03ad46a9

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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.touchcontrol.TouchControl.TC_CUBOID;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.touchcontrol.TouchControlCuboids;
31
import org.distorted.objectlib.main.ObjectControl;
32
import org.distorted.objectlib.main.ObjectType;
33
import org.distorted.objectlib.helpers.ObjectShape;
34
import org.distorted.objectlib.helpers.ObjectSticker;
35
import org.distorted.objectlib.helpers.ScrambleState;
36
import org.distorted.objectlib.main.ShapeHexahedron;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
public class TwistyCuboid extends ShapeHexahedron
41
{
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(1,0,0),
45
           new Static3D(0,1,0),
46
           new Static3D(0,0,1)
47
         };
48

    
49
  private ScrambleState[] mStates;
50
  private Static4D[] mQuats;
51
  private float[][] mCuts;
52
  private int[] mBasicAngle;
53
  private ObjectSticker[] mStickers;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
  public TwistyCuboid(int[] numL, int meshState, Static4D quat, Static3D move, float scale, InputStream stream)
58
    {
59
    super(numL, meshState, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, scale, stream);
60
    }
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  private int[] createEdges(int size, boolean full, int vertex)
65
    {
66
    if( size==1 ) return null;
67

    
68
    if( full )
69
      {
70
      int[] ret = new int[9*size];
71

    
72
      for(int l=0; l<size; l++)
73
        {
74
        ret[9*l  ] = l;
75
        ret[9*l+1] =-1;
76
        ret[9*l+2] = vertex;
77
        ret[9*l+3] = l;
78
        ret[9*l+4] = 1;
79
        ret[9*l+5] = vertex;
80
        ret[9*l+6] = l;
81
        ret[9*l+7] = 2;
82
        ret[9*l+8] = vertex;
83
        }
84

    
85
      return ret;
86
      }
87
    else
88
      {
89
      int[] ret = new int[6*size];
90

    
91
      for(int l=0; l<size; l++)
92
        {
93
        ret[6*l  ] = l;
94
        ret[6*l+1] = 1;
95
        ret[6*l+2] = vertex;
96
        ret[6*l+3] = l;
97
        ret[6*l+4] =-1;
98
        ret[6*l+5] = vertex;
99
        }
100

    
101
      return ret;
102
      }
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  public ScrambleState[] getScrambleStates()
108
    {
109
    if( mStates==null )
110
      {
111
      int[] numLayers = getNumLayers();
112

    
113
      int X = numLayers[0];
114
      int Y = numLayers[1];
115
      int Z = numLayers[2];
116

    
117
      int[][] mX = new int[16][];
118
      int[][] mY = new int[16][];
119
      int[][] mZ = new int[16][];
120

    
121
      for(int i=0; i<16; i++)
122
        {
123
        mX[i] = createEdges(X,Y==Z,i);
124
        mY[i] = createEdges(Y,X==Z,i);
125
        mZ[i] = createEdges(Z,X==Y,i);
126
        }
127

    
128
      if( X>1 && Y>1 && Z>1 )
129
        {
130
        mStates = new ScrambleState[]
131
          {
132
          new ScrambleState( new int[][] { mX[ 1], mY[ 2], mZ[ 3] } ),  //  0 0
133
          new ScrambleState( new int[][] {   null, mY[ 4], mZ[ 5] } ),  //  1 x
134
          new ScrambleState( new int[][] { mX[ 6],   null, mZ[ 7] } ),  //  2 y
135
          new ScrambleState( new int[][] { mX[ 8], mY[ 9],   null } ),  //  3 z
136
          new ScrambleState( new int[][] { mX[10],   null, mZ[ 7] } ),  //  4 xy
137
          new ScrambleState( new int[][] { mX[11], mY[ 9],   null } ),  //  5 xz
138
          new ScrambleState( new int[][] {   null, mY[12], mZ[ 5] } ),  //  6 yx
139
          new ScrambleState( new int[][] { mX[ 8], mY[13],   null } ),  //  7 yz
140
          new ScrambleState( new int[][] {   null, mY[ 4], mZ[14] } ),  //  8 zx
141
          new ScrambleState( new int[][] { mX[ 6],   null, mZ[15] } ),  //  9 zy
142
          new ScrambleState( new int[][] {   null,   null, mZ[ 5] } ),  // 10 xyx
143
          new ScrambleState( new int[][] {   null, mY[ 4],   null } ),  // 11 xzx
144
          new ScrambleState( new int[][] {   null,   null, mZ[ 7] } ),  // 12 yxy
145
          new ScrambleState( new int[][] { mX[ 6],   null,   null } ),  // 13 yzy
146
          new ScrambleState( new int[][] {   null, mY[ 9],   null } ),  // 14 zxz
147
          new ScrambleState( new int[][] { mX[ 8],   null,   null } ),  // 15 zyz
148
          };
149
        }
150
      else if( X==1 && Y==1 && Z==1 )
151
        {
152
        int[] state = new int[] {0,-1,0,0,1,0,0,2,0};
153

    
154
        mStates = new ScrambleState[]
155
          {
156
          new ScrambleState( new int[][] { state, state, state } )
157
          };
158
        }
159
      else
160
        {
161
        mStates = new ScrambleState[]
162
          {
163
          new ScrambleState( new int[][] { mX[ 0], mY[ 0], mZ[ 0] } )
164
          };
165
        }
166

    
167
      }
168

    
169
    return mStates;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  private void initializeQuats()
175
    {
176
    mQuats = new Static4D[]
177
         {
178
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
179
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
180
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
181
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
182

    
183
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),  // 4
184
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
185
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
186
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
187
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
188
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
189
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),  // 10
190
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
191
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
192
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
193
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
194
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
195

    
196
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),  // 16
197
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
198
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
199
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
200
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),  // 20
201
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
202
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
203
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
204
         };
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  public int[] getSolvedQuats(int cubit, int[] numLayers)
210
    {
211
    if( mQuats ==null ) initializeQuats();
212
    int status = retCubitSolvedStatus(cubit,numLayers);
213
    return status<0 ? null : buildSolvedQuats(TouchControlCuboids.FACE_AXIS[status], mQuats);
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  public ObjectShape getObjectShape(int variant)
219
    {
220
    int extraI, extraV, num, numL = getNumLayers()[0];
221
    float height;
222

    
223
    switch(numL)
224
        {
225
        case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
226
        case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
227
        case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
228
        default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
229
        }
230

    
231
    float[][] vertices = new float[][]
232
          {
233
              { 0.5f, 0.5f, 0.5f },
234
              { 0.5f, 0.5f,-0.5f },
235
              { 0.5f,-0.5f, 0.5f },
236
              { 0.5f,-0.5f,-0.5f },
237
              {-0.5f, 0.5f, 0.5f },
238
              {-0.5f, 0.5f,-0.5f },
239
              {-0.5f,-0.5f, 0.5f },
240
              {-0.5f,-0.5f,-0.5f },
241
          };
242

    
243
    int[][] vert_indices = new int[][]
244
          {
245
              {2,3,1,0},
246
              {7,6,4,5},
247
              {4,0,1,5},
248
              {7,3,2,6},
249
              {6,2,0,4},
250
              {3,7,5,1}
251
          };
252

    
253
    float[][] corners= new float[][] { {0.036f,0.12f} };
254
    float[][] centers= new float[][] { {0.0f, 0.0f, 0.0f} };
255
    int[] indices    = new int[] { 0,0,0,0,0,0,0,0 };
256
    float[][] bands  = new float[][]
257
         {
258
             {height,35,0.5f,0.7f,num,extraI,extraV},
259
             {     0,35,0.5f,0.7f,  2, num-2,extraV},
260
             {     0,35,0.5f,0.7f,  2,     0,     0},
261
         };
262

    
263
    int[] bandIndices;
264

    
265
         if( variant==0 ) bandIndices = new int[] {0,0,0,0,0,0};
266
    else if( variant==1 ) bandIndices = new int[] {1,1,1,0,1,0};
267
    else                  bandIndices = new int[] {2,2,2,2,0,2};
268

    
269
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null, 1);
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

    
274
  private int getEdgeNum(int cubit, int[] numLayers)
275
    {
276
    int x = numLayers[0];
277
    int y = numLayers[1];
278
    int z = numLayers[2];
279

    
280
    if(x==1 || y==1 || z==1 ) return 0;
281

    
282
    int numCorners = getNumCorners(numLayers);
283
    int numEdges   = getNumEdges(numLayers);
284
    int num = cubit - numCorners;
285

    
286
    if( num>=0 && num<numEdges )
287
      {
288
      int numLR = (x-2);
289
      if( num<  numLR ) return 0;
290
      if( num<2*numLR ) return 1;
291
      if( num<3*numLR ) return 2;
292
      if( num<4*numLR ) return 3;
293
      num -= 4*numLR;
294

    
295
      int numTD = (y-2);
296
      if( num<  numTD ) return 4;
297
      if( num<2*numTD ) return 5;
298
      if( num<3*numTD ) return 6;
299
      if( num<4*numTD ) return 7;
300
      num -= 4*numTD;
301

    
302
      int numFB = (z-2);
303
      if( num<  numFB ) return 8;
304
      if( num<2*numFB ) return 9;
305
      if( num<3*numFB ) return 10;
306
      if( num<4*numFB ) return 11;
307
      }
308

    
309
    return -1;
310
    }
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
  private int getCenterNum(int cubit, int[] numLayers)
315
    {
316
    int numCorners = getNumCorners(numLayers);
317
    int numEdges   = getNumEdges(numLayers);
318
    int num = cubit - numCorners - numEdges;
319

    
320
    if( num>=0 )
321
      {
322
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
323
      if( num<  numLR ) return 0;
324
      if( num<2*numLR ) return 1;
325
      num -= 2*numLR;
326

    
327
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
328
      if( num<  numTD ) return 2;
329
      if( num<2*numTD ) return 3;
330
      num -= 2*numTD;
331

    
332
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
333
      if( num<  numFB ) return 4;
334
      if( num<2*numFB ) return 5;
335
      }
336

    
337
    return -1;
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  private int getNumCorners(int[] numLayers)
343
    {
344
    int x = numLayers[0];
345
    int y = numLayers[1];
346
    int z = numLayers[2];
347

    
348
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 8;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  private int getNumEdges(int[] numLayers)
354
    {
355
    int x = numLayers[0];
356
    int y = numLayers[1];
357
    int z = numLayers[2];
358

    
359
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) );
360
    }
361

    
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

    
364
  public float[][] getCubitPositions(int[] numLayers)
365
    {
366
    final int X = numLayers[0];
367
    final int Y = numLayers[1];
368
    final int Z = numLayers[2];
369

    
370
    final float lenX = 0.5f*(X-1);
371
    final float lenY = 0.5f*(Y-1);
372
    final float lenZ = 0.5f*(Z-1);
373

    
374
    int curPos = 0;
375

    
376
    if( X==1 )
377
      {
378
      float[][] pos = new float[X*Y*Z][];
379

    
380
      for(int y=0; y<Y; y++)
381
        for(int z=0; z<Z; z++) pos[curPos++] = new float[] {+lenX,y-lenY,z-lenZ};
382

    
383
      return pos;
384
      }
385

    
386
    if( Y==1 )
387
      {
388
      float[][] pos = new float[X*Y*Z][];
389

    
390
      for(int x=0; x<X; x++)
391
        for(int z=0; z<Z; z++) pos[curPos++] = new float[] {x-lenX,+lenY,z-lenZ};
392

    
393
      return pos;
394
      }
395

    
396
    if( Z==1 )
397
      {
398
      float[][] pos = new float[X*Y*Z][];
399

    
400
      for(int x=0; x<X; x++)
401
        for(int y=0; y<Y; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,+lenZ};
402

    
403
      return pos;
404
      }
405

    
406
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
407
    float[][] pos = new float[numCubits][];
408

    
409
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
410
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
411
    pos[curPos++] = new float[] {-lenX,+lenY,-lenZ};
412
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
413
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
414
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
415
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
416
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
417

    
418
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
419
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
420
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
421
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
422
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
423
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
424
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
425
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
426
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
427
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
428
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
429
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
430

    
431
    for(int y=1; y<Y-1; y++)
432
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {+lenX,y-lenY,z-lenZ};
433

    
434
    for(int y=1; y<Y-1; y++)
435
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {-lenX,y-lenY,z-lenZ};
436

    
437
    for(int x=1; x<X-1; x++)
438
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,+lenY,z-lenZ};
439

    
440
    for(int x=1; x<X-1; x++)
441
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,-lenY,z-lenZ};
442

    
443
    for(int x=1; x<X-1; x++)
444
      for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,+lenZ};
445

    
446
    for(int x=1; x<X-1; x++)
447
      for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,-lenZ};
448

    
449
    return pos;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  public Static4D getQuat(int cubit, int[] numLayers)
455
    {
456
    if( mQuats ==null ) initializeQuats();
457

    
458
    int variant = getCubitVariant(cubit,numLayers);
459

    
460
    switch(variant)
461
      {
462
      case 0: return mQuats[0];
463
      case 1: int edgeEdge   = getEdgeNum(cubit,numLayers);
464
              switch(edgeEdge)
465
                {
466
                case  0: return mQuats[ 0];
467
                case  1: return mQuats[ 8];
468
                case  2: return mQuats[ 9];
469
                case  3: return mQuats[ 1];
470
                case  4: return mQuats[20];
471
                case  5: return mQuats[ 4];
472
                case  6: return mQuats[23];
473
                case  7: return mQuats[ 5];
474
                case  8: return mQuats[16];
475
                case  9: return mQuats[ 6];
476
                case 10: return mQuats[22];
477
                case 11: return mQuats[ 7];
478
                }
479
              break;
480
      case 2: int centerFace = getCenterNum(cubit,numLayers);
481
              switch(centerFace)
482
                {
483
                case 0 : return mQuats[13];
484
                case 1 : return mQuats[12];
485
                case 2 : return mQuats[ 8];
486
                case 3 : return mQuats[ 9];
487
                case 4 : return mQuats[ 0];
488
                case 5 : return mQuats[ 1];
489
                }
490
      }
491

    
492
    return mQuats[0];
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int getNumCubitVariants(int[] numLayers)
498
    {
499
    final int X = numLayers[0];
500
    final int Y = numLayers[1];
501
    final int Z = numLayers[2];
502

    
503
    if( X==1 || Y==1 || Z==1 ) return 1;
504
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
505

    
506
    return 3;
507
    }
508

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

    
511
  public int getCubitVariant(int cubit, int[] numLayers)
512
    {
513
    int numCorners = getNumCorners(numLayers);
514
    if( cubit < numCorners          ) return 0;
515
    int numEdges = getNumEdges(numLayers);
516
    if( cubit < numCorners+numEdges ) return 1;
517

    
518
    return 2;
519
    }
520

    
521
///////////////////////////////////////////////////////////////////////////////////////////////////
522

    
523
  public Static4D[] getQuats()
524
    {
525
    if( mQuats ==null ) initializeQuats();
526
    return mQuats;
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

    
531
  public float[][] getCuts(int[] numLayers)
532
    {
533
    if( mCuts==null )
534
      {
535
      mCuts = new float[3][];
536

    
537
      for(int axis=0; axis<3; axis++)
538
        {
539
        int len = numLayers[axis];
540
        float start = (2-len)*0.5f;
541

    
542
        if( len>=2 )
543
          {
544
          mCuts[axis] = new float[len-1];
545
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
546
          }
547
        }
548
      }
549

    
550
    return mCuts;
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  public boolean[][] getLayerRotatable(int[] numLayers)
556
    {
557
    int numAxis = ROT_AXIS.length;
558
    boolean[][] layerRotatable = new boolean[numAxis][];
559

    
560
    for(int i=0; i<numAxis; i++)
561
      {
562
      layerRotatable[i] = new boolean[numLayers[i]];
563
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
564
      }
565

    
566
    return layerRotatable;
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570

    
571
  public int getTouchControlType()
572
    {
573
    return TC_CUBOID;
574
    }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577

    
578
  public int getTouchControlSplit()
579
    {
580
    return TYPE_NOT_SPLIT;
581
    }
582

    
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584

    
585
  public int[][][] getEnabled()
586
    {
587
    return new int[][][]
588
      {
589
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
590
      };
591
    }
592

    
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594

    
595
  public float[] getDist3D(int[] numLayers)
596
    {
597
    float avg = (numLayers[0]+numLayers[1]+numLayers[2])/3.0f;
598

    
599
    return new float[]
600
        {
601
        0.5f*numLayers[0]/avg,
602
        0.5f*numLayers[0]/avg,
603
        0.5f*numLayers[1]/avg,
604
        0.5f*numLayers[1]/avg,
605
        0.5f*numLayers[2]/avg,
606
        0.5f*numLayers[2]/avg,
607
        };
608
    }
609

    
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611

    
612
  public int getSolvedFunctionIndex()
613
    {
614
    return 0;
615
    }
616

    
617
///////////////////////////////////////////////////////////////////////////////////////////////////
618

    
619
  public int getNumCubitFaces()
620
    {
621
    return 6;
622
    }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
627
    {
628
    int variant = getCubitVariant(cubit,numLayers);
629

    
630
    switch(variant)
631
      {
632
      case 0: int axis = face/2;
633
              return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
634
      case 1: if( face!=3 && face !=5 ) return -1;
635
              int edge = getEdgeNum(cubit,numLayers);
636

    
637
              switch(edge)
638
                {
639
                case  0: return face==3 ? 3 : 5;
640
                case  1: return face==3 ? 4 : 3;
641
                case  2: return face==3 ? 5 : 2;
642
                case  3: return face==3 ? 2 : 4;
643
                case  4: return face==3 ? 5 : 1;
644
                case  5: return face==3 ? 1 : 4;
645
                case  6: return face==3 ? 5 : 0;
646
                case  7: return face==3 ? 0 : 4;
647
                case  8: return face==3 ? 1 : 3;
648
                case  9: return face==3 ? 2 : 1;
649
                case 10: return face==3 ? 0 : 3;
650
                case 11: return face==3 ? 2 : 0;
651
                default: return 0;
652
                }
653

    
654
      case 2: return face==4 ? getCenterNum(cubit,numLayers) : -1;
655
      }
656

    
657
    return -1;
658
    }
659

    
660
///////////////////////////////////////////////////////////////////////////////////////////////////
661

    
662
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
663
    {
664
    return face>=mStickerVariants[variant].length ? -1 : mStickerVariants[variant][face];
665
    }
666

    
667
///////////////////////////////////////////////////////////////////////////////////////////////////
668

    
669
  public ObjectSticker retSticker(int sticker)
670
    {
671
    if( mStickers==null )
672
      {
673
      int numStickers = mStickerCoords.length;
674
      mStickers = new ObjectSticker[numStickers];
675

    
676
      for(int s=0; s<numStickers; s++)
677
        {
678
        float scale = mStickerScales[s];
679
        float radius = 0.10f / scale;
680
        float stroke = 0.08f / scale;
681
        float[] radii = new float[] {radius,radius,radius,radius};
682

    
683
        if( ObjectControl.isInIconMode() )
684
          {
685
          int[] numLayers = getNumLayers();
686

    
687
          switch(numLayers[0])
688
            {
689
            case 2: stroke*=1.8f; break;
690
            case 3: stroke*=2.0f; break;
691
            case 4: stroke*=2.1f; break;
692
            default:stroke*=2.2f; break;
693
            }
694
          }
695

    
696
        mStickers[s] = new ObjectSticker(mStickerCoords[s],null,radii,stroke);
697
        }
698
      }
699

    
700
    return mStickers[sticker];
701
    }
702

    
703
///////////////////////////////////////////////////////////////////////////////////////////////////
704
// PUBLIC API
705

    
706
  public Static3D[] getRotationAxis()
707
    {
708
    return ROT_AXIS;
709
    }
710

    
711
///////////////////////////////////////////////////////////////////////////////////////////////////
712

    
713
  public int[] getBasicAngle()
714
    {
715
    if( mBasicAngle==null )
716
      {
717
      int[] num = getNumLayers();
718
      int x = num[1]==num[2] ? 4 : 2;
719
      int y = num[0]==num[2] ? 4 : 2;
720
      int z = num[0]==num[1] ? 4 : 2;
721

    
722
      mBasicAngle = new int[] { x,y,z };
723
      }
724
    return mBasicAngle;
725
    }
726

    
727
///////////////////////////////////////////////////////////////////////////////////////////////////
728

    
729
  public ObjectType intGetObjectType(int[] numLayers)
730
    {
731
    int x = numLayers[0];
732
    int y = numLayers[1];
733

    
734
    switch(x)
735
      {
736
      case 2: switch(y)
737
                {
738
                case 2: return ObjectType.CUBE_2;
739
                case 3: return ObjectType.CU_232;
740
                }
741
      case 3: switch(y)
742
                {
743
                case 2: return ObjectType.CU_323;
744
                case 3: return ObjectType.CUBE_3;
745
                case 4: return ObjectType.CU_343;
746
                }
747
      case 4: return ObjectType.CUBE_4;
748
      case 5: return ObjectType.CUBE_5;
749
      case 6: return ObjectType.CUBE_6;
750
      case 7: return ObjectType.CUBE_7;
751
      }
752

    
753
    return ObjectType.CUBE_3;
754
    }
755

    
756
///////////////////////////////////////////////////////////////////////////////////////////////////
757

    
758
  public String getObjectName()
759
    {
760
    int[] numLayers = getNumLayers();
761

    
762
    switch(intGetObjectType(numLayers))
763
      {
764
      case CUBE_2: return "Pocket Cube";
765
      case CU_232: return "Slim Tower";
766
      case CUBE_3: return "Rubik Cube";
767
      case CU_323: return "2x2x3 Cuboid";
768
      case CU_343: return "3x3x4 Cuboid";
769
      case CUBE_4: return "Rubik's Revenge";
770
      case CUBE_5: return "Professor's Cube";
771
      case CUBE_6: return "6x6 Cube";
772
      case CUBE_7: return "7x7 Cube";
773
      }
774
    return "Rubik Cube";
775
    }
776

    
777
///////////////////////////////////////////////////////////////////////////////////////////////////
778

    
779
  public String getInventor()
780
    {
781
    int[] numLayers = getNumLayers();
782

    
783
    switch(intGetObjectType(numLayers))
784
      {
785
      case CUBE_2: return "Larry Nichols";
786
      case CU_232: return "Katsuhiko Okamoto";
787
      case CUBE_3: return "Ernő Rubik";
788
      case CU_323: return "Unknown";
789
      case CU_343: return "Cube4You";
790
      case CUBE_4: return "Péter Sebestény";
791
      case CUBE_5: return "Udo Krell";
792
      case CUBE_6:
793
      case CUBE_7: return "Panagiotis Verdes";
794
      }
795

    
796
    return "Ernő Rubik";
797
    }
798

    
799
///////////////////////////////////////////////////////////////////////////////////////////////////
800

    
801
  public int getYearOfInvention()
802
    {
803
    int[] numLayers = getNumLayers();
804

    
805
    switch(intGetObjectType(numLayers))
806
      {
807
      case CUBE_2: return 1970;
808
      case CU_232: return 2001;
809
      case CUBE_3: return 1974;
810
      case CU_323: return 0;
811
      case CU_343: return 2009;
812
      case CUBE_4: return 1981;
813
      case CUBE_5: return 2002;
814
      case CUBE_6:
815
      case CUBE_7: return 2008;
816
      }
817

    
818
    return 1974;
819
    }
820

    
821
///////////////////////////////////////////////////////////////////////////////////////////////////
822

    
823
  public int getComplexity()
824
    {
825
    int[] numLayers = getNumLayers();
826

    
827
    switch(intGetObjectType(numLayers))
828
      {
829
      case CUBE_2:
830
      case CU_232: return 1;
831
      case CUBE_3:
832
      case CU_323: return 2;
833
      case CU_343:
834
      case CUBE_4: return 3;
835
      case CUBE_5:
836
      case CUBE_6:
837
      case CUBE_7: return 4;
838
      }
839
    return 2;
840
    }
841
}
(6-6/26)