Project

General

Profile

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

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

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.main.Movement.MOVEMENT_SHAPECHANGE;
23
import static org.distorted.objectlib.main.Movement.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.main.MovementC;
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.Twisty6;
37

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

    
40
public class TwistyCuboid extends Twisty6
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, Static4D quat, Static3D move, InputStream stream)
58
    {
59
    super(numL, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, 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(MovementC.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
    double[][] vertices = new double[][]
232
          {
233
              { 0.5, 0.5, 0.5 },
234
              { 0.5, 0.5,-0.5 },
235
              { 0.5,-0.5, 0.5 },
236
              { 0.5,-0.5,-0.5 },
237
              {-0.5, 0.5, 0.5 },
238
              {-0.5, 0.5,-0.5 },
239
              {-0.5,-0.5, 0.5 },
240
              {-0.5,-0.5,-0.5 },
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
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
255
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
256
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
257

    
258
    if( variant==0 )
259
      {
260
      float[][] bands   = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
261
      int[] bandIndices = new int[] {0,0,0,0,0,0};
262
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
263
      }
264
    else if( variant==1 )
265
      {
266
      int extraI2 = numL<=3 ? num-2 : 0;
267

    
268
      float[][] bands   = new float[][]
269
        {
270
          {height,35,0.5f,0.7f,num,extraI,extraV},
271
          {height,35,0.5f,0.7f,  2,extraI2,    0},
272
        };
273

    
274
      int[] bandIndices = new int[] {1,1,1,0,1,0};
275
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
276
      }
277
    else
278
      {
279
      int extraI2 = numL<=3 ? num-2 : 0;
280

    
281
      float[][] bands   = new float[][]
282
        {
283
          {height,35,0.5f,0.7f,num,extraI ,extraV},
284
          {height,35,0.5f,0.7f,  2,extraI2,     0},
285
          {height,35,0.5f,0.7f,  2,      0,     0},
286
        };
287
      int[] bandIndices = new int[] {1,1,1,1,0,2};
288
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
289
      }
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  private int getEdgeNum(int cubit, int[] numLayers)
295
    {
296
    int x = numLayers[0];
297
    int y = numLayers[1];
298
    int z = numLayers[2];
299

    
300
    if(x==1 || y==1 || z==1 ) return 0;
301

    
302
    int numCorners = getNumCorners(numLayers);
303
    int numEdges   = getNumEdges(numLayers);
304
    int num = cubit - numCorners;
305

    
306
    if( num>=0 && num<numEdges )
307
      {
308
      int numLR = (x-2);
309
      if( num<  numLR ) return 0;
310
      if( num<2*numLR ) return 1;
311
      if( num<3*numLR ) return 2;
312
      if( num<4*numLR ) return 3;
313
      num -= 4*numLR;
314

    
315
      int numTD = (y-2);
316
      if( num<  numTD ) return 4;
317
      if( num<2*numTD ) return 5;
318
      if( num<3*numTD ) return 6;
319
      if( num<4*numTD ) return 7;
320
      num -= 4*numTD;
321

    
322
      int numFB = (z-2);
323
      if( num<  numFB ) return 8;
324
      if( num<2*numFB ) return 9;
325
      if( num<3*numFB ) return 10;
326
      if( num<4*numFB ) return 11;
327
      }
328

    
329
    return -1;
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  private int getCenterNum(int cubit, int[] numLayers)
335
    {
336
    int numCorners = getNumCorners(numLayers);
337
    int numEdges   = getNumEdges(numLayers);
338
    int num = cubit - numCorners - numEdges;
339

    
340
    if( num>=0 )
341
      {
342
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
343
      if( num<  numLR ) return 0;
344
      if( num<2*numLR ) return 1;
345
      num -= 2*numLR;
346

    
347
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
348
      if( num<  numTD ) return 2;
349
      if( num<2*numTD ) return 3;
350
      num -= 2*numTD;
351

    
352
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
353
      if( num<  numFB ) return 4;
354
      if( num<2*numFB ) return 5;
355
      }
356

    
357
    return -1;
358
    }
359

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

    
362
  private int getNumCorners(int[] numLayers)
363
    {
364
    int x = numLayers[0];
365
    int y = numLayers[1];
366
    int z = numLayers[2];
367

    
368
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 8;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  private int getNumEdges(int[] numLayers)
374
    {
375
    int x = numLayers[0];
376
    int y = numLayers[1];
377
    int z = numLayers[2];
378

    
379
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) );
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public float[][] getCubitPositions(int[] numLayers)
385
    {
386
    final int X = numLayers[0];
387
    final int Y = numLayers[1];
388
    final int Z = numLayers[2];
389

    
390
    final float lenX = 0.5f*(X-1);
391
    final float lenY = 0.5f*(Y-1);
392
    final float lenZ = 0.5f*(Z-1);
393

    
394
    int curPos = 0;
395

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

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

    
403
      return pos;
404
      }
405

    
406
    if( Y==1 )
407
      {
408
      float[][] pos = new float[X*Y*Z][];
409

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

    
413
      return pos;
414
      }
415

    
416
    if( Z==1 )
417
      {
418
      float[][] pos = new float[X*Y*Z][];
419

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

    
423
      return pos;
424
      }
425

    
426
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
427
    float[][] pos = new float[numCubits][];
428

    
429
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
430
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
431
    pos[curPos++] = new float[] {-lenX,+lenY,-lenZ};
432
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
433
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
434
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
435
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
436
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
437

    
438
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
439
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
440
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
441
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
442
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
443
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
444
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
445
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
446
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
447
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
448
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
449
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
450

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

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

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

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

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

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

    
469
    return pos;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  public Static4D getQuat(int cubit, int[] numLayers)
475
    {
476
    if( mQuats ==null ) initializeQuats();
477

    
478
    int variant = getCubitVariant(cubit,numLayers);
479

    
480
    switch(variant)
481
      {
482
      case 0: return mQuats[0];
483
      case 1: int edgeEdge   = getEdgeNum(cubit,numLayers);
484
              switch(edgeEdge)
485
                {
486
                case  0: return mQuats[ 0];
487
                case  1: return mQuats[ 8];
488
                case  2: return mQuats[ 9];
489
                case  3: return mQuats[ 1];
490
                case  4: return mQuats[20];
491
                case  5: return mQuats[ 4];
492
                case  6: return mQuats[23];
493
                case  7: return mQuats[ 5];
494
                case  8: return mQuats[16];
495
                case  9: return mQuats[ 6];
496
                case 10: return mQuats[22];
497
                case 11: return mQuats[ 7];
498
                }
499
              break;
500
      case 2: int centerFace = getCenterNum(cubit,numLayers);
501
              switch(centerFace)
502
                {
503
                case 0 : return mQuats[13];
504
                case 1 : return mQuats[12];
505
                case 2 : return mQuats[ 8];
506
                case 3 : return mQuats[ 9];
507
                case 4 : return mQuats[ 0];
508
                case 5 : return mQuats[ 1];
509
                }
510
      }
511

    
512
    return mQuats[0];
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public int getNumCubitVariants(int[] numLayers)
518
    {
519
    final int X = numLayers[0];
520
    final int Y = numLayers[1];
521
    final int Z = numLayers[2];
522

    
523
    if( X==1 || Y==1 || Z==1 ) return 1;
524
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
525

    
526
    return 3;
527
    }
528

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

    
531
  public int getCubitVariant(int cubit, int[] numLayers)
532
    {
533
    int numCorners = getNumCorners(numLayers);
534
    if( cubit < numCorners          ) return 0;
535
    int numEdges = getNumEdges(numLayers);
536
    if( cubit < numCorners+numEdges ) return 1;
537

    
538
    return 2;
539
    }
540

    
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

    
543
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
544
    {
545
    return 0;
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549

    
550
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
551
    {
552
    int variant = getCubitVariant(cubit,numLayers);
553

    
554
    switch(variant)
555
      {
556
      case 0: int axis = face/2;
557
              return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
558
      case 1: if( face!=3 && face !=5 ) return -1;
559
              int edge = getEdgeNum(cubit,numLayers);
560

    
561
              switch(edge)
562
                {
563
                case  0: return face==3 ? 3 : 5;
564
                case  1: return face==3 ? 4 : 3;
565
                case  2: return face==3 ? 5 : 2;
566
                case  3: return face==3 ? 2 : 4;
567
                case  4: return face==3 ? 5 : 1;
568
                case  5: return face==3 ? 1 : 4;
569
                case  6: return face==3 ? 5 : 0;
570
                case  7: return face==3 ? 0 : 4;
571
                case  8: return face==3 ? 1 : 3;
572
                case  9: return face==3 ? 2 : 1;
573
                case 10: return face==3 ? 0 : 3;
574
                case 11: return face==3 ? 2 : 0;
575
                default: return 0;
576
                }
577

    
578
      case 2: return face==4 ? getCenterNum(cubit,numLayers) : -1;
579
      }
580

    
581
    return -1;
582
    }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

    
586
  public ObjectSticker retSticker(int sticker)
587
    {
588
    if( mStickers==null )
589
      {
590
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
591
      final float radius = 0.10f;
592
      final float[] radii = {radius,radius,radius,radius};
593
      mStickers = new ObjectSticker[STICKERS.length];
594
      float stroke = 0.08f;
595

    
596
      if( ObjectControl.isInIconMode() )
597
        {
598
        int[] numLayers = getNumLayers();
599

    
600
        switch(numLayers[0])
601
          {
602
          case 2: stroke*=1.8f; break;
603
          case 3: stroke*=2.0f; break;
604
          case 4: stroke*=2.1f; break;
605
          default:stroke*=2.2f; break;
606
          }
607
        }
608

    
609
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
610
      }
611

    
612
    return mStickers[sticker];
613
    }
614

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

    
617
  public Static4D[] getQuats()
618
    {
619
    if( mQuats ==null ) initializeQuats();
620
    return mQuats;
621
    }
622

    
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624

    
625
  public float[][] getCuts(int[] numLayers)
626
    {
627
    if( mCuts==null )
628
      {
629
      mCuts = new float[3][];
630

    
631
      for(int axis=0; axis<3; axis++)
632
        {
633
        int len = numLayers[axis];
634
        float start = (2-len)*0.5f;
635

    
636
        if( len>=2 )
637
          {
638
          mCuts[axis] = new float[len-1];
639
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
640
          }
641
        }
642
      }
643

    
644
    return mCuts;
645
    }
646

    
647
///////////////////////////////////////////////////////////////////////////////////////////////////
648

    
649
  public boolean[][] getLayerRotatable(int[] numLayers)
650
    {
651
    int numAxis = ROT_AXIS.length;
652
    boolean[][] layerRotatable = new boolean[numAxis][];
653

    
654
    for(int i=0; i<numAxis; i++)
655
      {
656
      layerRotatable[i] = new boolean[numLayers[i]];
657
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
658
      }
659

    
660
    return layerRotatable;
661
    }
662

    
663
///////////////////////////////////////////////////////////////////////////////////////////////////
664

    
665
  public int getMovementType()
666
    {
667
    return MOVEMENT_SHAPECHANGE;
668
    }
669

    
670
///////////////////////////////////////////////////////////////////////////////////////////////////
671

    
672
  public int getMovementSplit()
673
    {
674
    return TYPE_NOT_SPLIT;
675
    }
676

    
677
///////////////////////////////////////////////////////////////////////////////////////////////////
678

    
679
  public int[][][] getEnabled()
680
    {
681
    return new int[][][]
682
      {
683
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
684
      };
685
    }
686

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

    
689
  public float[] getDist3D(int[] numLayers)
690
    {
691
    float avg = (numLayers[0]+numLayers[1]+numLayers[2])/3.0f;
692

    
693
    return new float[]
694
        {
695
        0.5f*numLayers[0]/avg,
696
        0.5f*numLayers[0]/avg,
697
        0.5f*numLayers[1]/avg,
698
        0.5f*numLayers[1]/avg,
699
        0.5f*numLayers[2]/avg,
700
        0.5f*numLayers[2]/avg,
701
        };
702
    }
703

    
704
///////////////////////////////////////////////////////////////////////////////////////////////////
705

    
706
  public int getSolvedFunctionIndex()
707
    {
708
    return 0;
709
    }
710

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

    
713
  public int getNumStickerTypes(int[] numLayers)
714
    {
715
    return 1;
716
    }
717

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

    
720
  public int getNumCubitFaces()
721
    {
722
    return 6;
723
    }
724

    
725
///////////////////////////////////////////////////////////////////////////////////////////////////
726
// PUBLIC API
727

    
728
  public Static3D[] getRotationAxis()
729
    {
730
    return ROT_AXIS;
731
    }
732

    
733
///////////////////////////////////////////////////////////////////////////////////////////////////
734

    
735
  public int[] getBasicAngle()
736
    {
737
    if( mBasicAngle==null )
738
      {
739
      int[] num = getNumLayers();
740
      int x = num[1]==num[2] ? 4 : 2;
741
      int y = num[0]==num[2] ? 4 : 2;
742
      int z = num[0]==num[1] ? 4 : 2;
743

    
744
      mBasicAngle = new int[] { x,y,z };
745
      }
746
    return mBasicAngle;
747
    }
748

    
749
///////////////////////////////////////////////////////////////////////////////////////////////////
750

    
751
  public ObjectType intGetObjectType(int[] numLayers)
752
    {
753
    int x = numLayers[0];
754
    int y = numLayers[1];
755

    
756
    switch(x)
757
      {
758
      case 2: switch(y)
759
                {
760
                case 2: return ObjectType.CUBE_2;
761
                case 3: return ObjectType.CU_232;
762
                }
763
      case 3: switch(y)
764
                {
765
                case 2: return ObjectType.CU_323;
766
                case 3: return ObjectType.CUBE_3;
767
                case 4: return ObjectType.CU_343;
768
                }
769
      case 4: return ObjectType.CUBE_4;
770
      case 5: return ObjectType.CUBE_5;
771
      case 6: return ObjectType.CUBE_6;
772
      }
773

    
774
    return ObjectType.CUBE_3;
775
    }
776

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

    
779
  public String getObjectName()
780
    {
781
    switch(getNumLayers()[0])
782
      {
783
      case 2: return "Pocket Cube";
784
      case 3: return "Rubik Cube";
785
      case 4: return "Rubik's Revenge";
786
      case 5: return "Professor's Cube";
787
      case 6: return "6x6 V-Cube";
788
      }
789
    return "Rubik Cube";
790
    }
791

    
792
///////////////////////////////////////////////////////////////////////////////////////////////////
793

    
794
  public String getInventor()
795
    {
796
    switch(getNumLayers()[0])
797
      {
798
      case 2: return "Larry Nichols";
799
      case 3: return "Ernő Rubik";
800
      case 4: return "Péter Sebestény";
801
      case 5: return "Udo Krell";
802
      case 6: return "Panagiotis Verdes";
803
      }
804
    return "Ernő Rubik";
805
    }
806

    
807
///////////////////////////////////////////////////////////////////////////////////////////////////
808

    
809
  public int getYearOfInvention()
810
    {
811
    switch(getNumLayers()[0])
812
      {
813
      case 2: return 1970;
814
      case 3: return 1974;
815
      case 4: return 1981;
816
      case 5: return 2002;
817
      case 8: return 2008;
818
      }
819
    return 1974;
820
    }
821

    
822
///////////////////////////////////////////////////////////////////////////////////////////////////
823

    
824
  public int getComplexity()
825
    {
826
    switch(getNumLayers()[0])
827
      {
828
      case  2: return 4;
829
      case  3: return 6;
830
      case  4: return 8;
831
      default: return 10;
832
      }
833
    }
834
}
(6-6/25)