Project

General

Profile

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

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

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.ScrambleState;
35
import org.distorted.objectlib.main.ShapeHexahedron;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

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

    
48
  private ScrambleState[] mStates;
49
  private Static4D[] mQuats;
50
  private float[][] mCuts;
51
  private int[] mBasicAngle;
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

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

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

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

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

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

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

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

    
99
      return ret;
100
      }
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

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

    
111
      int X = numLayers[0];
112
      int Y = numLayers[1];
113
      int Z = numLayers[2];
114

    
115
      int[][] mX = new int[16][];
116
      int[][] mY = new int[16][];
117
      int[][] mZ = new int[16][];
118

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

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

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

    
165
      }
166

    
167
    return mStates;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

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

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

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

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

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

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

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

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

    
229
    float[][] vertices = new float[][]
230
          {
231
              { 0.5f, 0.5f, 0.5f },
232
              { 0.5f, 0.5f,-0.5f },
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
          };
240

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

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

    
261
    int[] bandIndices;
262

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

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

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

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

    
278
    if(x==1 || y==1 || z==1 ) return 0;
279

    
280
    int numCorners = getNumCorners(numLayers);
281
    int numEdges   = getNumEdges(numLayers);
282
    int num = cubit - numCorners;
283

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

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

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

    
307
    return -1;
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

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

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

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

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

    
335
    return -1;
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

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

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

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

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

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

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

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

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

    
372
    int curPos = 0;
373

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

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

    
381
      return pos;
382
      }
383

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

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

    
391
      return pos;
392
      }
393

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

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

    
401
      return pos;
402
      }
403

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

    
407
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
408
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
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

    
416
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
417
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
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<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
421
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-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<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
425
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-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

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

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

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

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

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

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

    
447
    return pos;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

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

    
456
    int variant = getCubitVariant(cubit,numLayers);
457

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

    
490
    return mQuats[0];
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

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

    
501
    if( X==1 || Y==1 || Z==1 ) return 1;
502
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
503

    
504
    return 3;
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

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

    
516
    return 2;
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

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

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

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

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

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

    
548
    return mCuts;
549
    }
550

    
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

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

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

    
564
    return layerRotatable;
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
  public int getTouchControlType()
570
    {
571
    return TC_CUBOID;
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  public int getTouchControlSplit()
577
    {
578
    return TYPE_NOT_SPLIT;
579
    }
580

    
581
///////////////////////////////////////////////////////////////////////////////////////////////////
582

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

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592

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

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

    
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

    
610
  public int getSolvedFunctionIndex()
611
    {
612
    return 0;
613
    }
614

    
615
///////////////////////////////////////////////////////////////////////////////////////////////////
616

    
617
  public int getNumCubitFaces()
618
    {
619
    return 6;
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

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

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

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

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

    
655
    return -1;
656
    }
657

    
658
///////////////////////////////////////////////////////////////////////////////////////////////////
659

    
660
  public float getStickerRadius()
661
    {
662
    return 0.10f;
663
    }
664

    
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666

    
667
  public float getStickerStroke()
668
    {
669
    float stroke = 0.08f;
670

    
671
    if( ObjectControl.isInIconMode() )
672
      {
673
      int[] numLayers = getNumLayers();
674

    
675
      switch(numLayers[0])
676
        {
677
        case 2: stroke*=1.8f; break;
678
        case 3: stroke*=2.0f; break;
679
        case 4: stroke*=2.1f; break;
680
        default:stroke*=2.2f; break;
681
        }
682
      }
683

    
684
    return stroke;
685
    }
686

    
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

    
689
  public float[][] getStickerAngles()
690
    {
691
    return null;
692
    }
693

    
694
///////////////////////////////////////////////////////////////////////////////////////////////////
695
// PUBLIC API
696

    
697
  public Static3D[] getRotationAxis()
698
    {
699
    return ROT_AXIS;
700
    }
701

    
702
///////////////////////////////////////////////////////////////////////////////////////////////////
703

    
704
  public int[] getBasicAngle()
705
    {
706
    if( mBasicAngle==null )
707
      {
708
      int[] num = getNumLayers();
709
      int x = num[1]==num[2] ? 4 : 2;
710
      int y = num[0]==num[2] ? 4 : 2;
711
      int z = num[0]==num[1] ? 4 : 2;
712

    
713
      mBasicAngle = new int[] { x,y,z };
714
      }
715
    return mBasicAngle;
716
    }
717

    
718
///////////////////////////////////////////////////////////////////////////////////////////////////
719

    
720
  public ObjectType intGetObjectType(int[] numLayers)
721
    {
722
    int x = numLayers[0];
723
    int y = numLayers[1];
724

    
725
    switch(x)
726
      {
727
      case 2: switch(y)
728
                {
729
                case 2: return ObjectType.CUBE_2;
730
                case 3: return ObjectType.CU_232;
731
                }
732
      case 3: switch(y)
733
                {
734
                case 2: return ObjectType.CU_323;
735
                case 3: return ObjectType.CUBE_3;
736
                case 4: return ObjectType.CU_343;
737
                }
738
      case 4: return ObjectType.CUBE_4;
739
      case 5: return ObjectType.CUBE_5;
740
      case 6: return ObjectType.CUBE_6;
741
      case 7: return ObjectType.CUBE_7;
742
      }
743

    
744
    return ObjectType.CUBE_3;
745
    }
746

    
747
///////////////////////////////////////////////////////////////////////////////////////////////////
748

    
749
  public String getObjectName()
750
    {
751
    int[] numLayers = getNumLayers();
752

    
753
    switch(intGetObjectType(numLayers))
754
      {
755
      case CUBE_2: return "Pocket Cube";
756
      case CU_232: return "Slim Tower";
757
      case CUBE_3: return "Rubik Cube";
758
      case CU_323: return "2x2x3 Cuboid";
759
      case CU_343: return "3x3x4 Cuboid";
760
      case CUBE_4: return "Rubik's Revenge";
761
      case CUBE_5: return "Professor's Cube";
762
      case CUBE_6: return "6x6 Cube";
763
      case CUBE_7: return "7x7 Cube";
764
      }
765
    return "Rubik Cube";
766
    }
767

    
768
///////////////////////////////////////////////////////////////////////////////////////////////////
769

    
770
  public String getInventor()
771
    {
772
    int[] numLayers = getNumLayers();
773

    
774
    switch(intGetObjectType(numLayers))
775
      {
776
      case CUBE_2: return "Larry Nichols";
777
      case CU_232: return "Katsuhiko Okamoto";
778
      case CUBE_3: return "Ernő Rubik";
779
      case CU_323: return "Unknown";
780
      case CU_343: return "Cube4You";
781
      case CUBE_4: return "Péter Sebestény";
782
      case CUBE_5: return "Udo Krell";
783
      case CUBE_6:
784
      case CUBE_7: return "Panagiotis Verdes";
785
      }
786

    
787
    return "Ernő Rubik";
788
    }
789

    
790
///////////////////////////////////////////////////////////////////////////////////////////////////
791

    
792
  public int getYearOfInvention()
793
    {
794
    int[] numLayers = getNumLayers();
795

    
796
    switch(intGetObjectType(numLayers))
797
      {
798
      case CUBE_2: return 1970;
799
      case CU_232: return 2001;
800
      case CUBE_3: return 1974;
801
      case CU_323: return 0;
802
      case CU_343: return 2009;
803
      case CUBE_4: return 1981;
804
      case CUBE_5: return 2002;
805
      case CUBE_6:
806
      case CUBE_7: return 2008;
807
      }
808

    
809
    return 1974;
810
    }
811

    
812
///////////////////////////////////////////////////////////////////////////////////////////////////
813

    
814
  public int getComplexity()
815
    {
816
    int[] numLayers = getNumLayers();
817

    
818
    switch(intGetObjectType(numLayers))
819
      {
820
      case CUBE_2:
821
      case CU_232: return 1;
822
      case CUBE_3:
823
      case CU_323: return 2;
824
      case CU_343:
825
      case CUBE_4: return 3;
826
      case CUBE_5:
827
      case CUBE_6:
828
      case CUBE_7: return 4;
829
      }
830
    return 2;
831
    }
832
}
(6-6/26)