Project

General

Profile

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

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

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
  private float getRadius()
670
    {
671
    return 0.10f;
672
    }
673

    
674
///////////////////////////////////////////////////////////////////////////////////////////////////
675

    
676
  private float getStroke()
677
    {
678
    float stroke = 0.08f;
679

    
680
    if( ObjectControl.isInIconMode() )
681
      {
682
      int[] numLayers = getNumLayers();
683

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

    
693
    return stroke;
694
    }
695

    
696
///////////////////////////////////////////////////////////////////////////////////////////////////
697

    
698
  public ObjectSticker retSticker(int sticker)
699
    {
700
    if( mStickers==null )
701
      {
702
      float rad = getRadius();
703
      float str = getStroke();
704
      int numStickers = mStickerCoords.length;
705
      mStickers = new ObjectSticker[numStickers];
706

    
707
      for(int s=0; s<numStickers; s++)
708
        {
709
        float scale = mStickerScales[s];
710
        float radius = rad / scale;
711
        float stroke = str / scale;
712
        int len = mStickerCoords[s].length;
713
        float[] radii = new float[len];
714
        for(int r=0; r<len; r++) radii[r] = radius;
715
        mStickers[s] = new ObjectSticker(mStickerCoords[s],null,radii,stroke);
716
        }
717
      }
718

    
719
    return mStickers[sticker];
720
    }
721

    
722
///////////////////////////////////////////////////////////////////////////////////////////////////
723
// PUBLIC API
724

    
725
  public Static3D[] getRotationAxis()
726
    {
727
    return ROT_AXIS;
728
    }
729

    
730
///////////////////////////////////////////////////////////////////////////////////////////////////
731

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

    
741
      mBasicAngle = new int[] { x,y,z };
742
      }
743
    return mBasicAngle;
744
    }
745

    
746
///////////////////////////////////////////////////////////////////////////////////////////////////
747

    
748
  public ObjectType intGetObjectType(int[] numLayers)
749
    {
750
    int x = numLayers[0];
751
    int y = numLayers[1];
752

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

    
772
    return ObjectType.CUBE_3;
773
    }
774

    
775
///////////////////////////////////////////////////////////////////////////////////////////////////
776

    
777
  public String getObjectName()
778
    {
779
    int[] numLayers = getNumLayers();
780

    
781
    switch(intGetObjectType(numLayers))
782
      {
783
      case CUBE_2: return "Pocket Cube";
784
      case CU_232: return "Slim Tower";
785
      case CUBE_3: return "Rubik Cube";
786
      case CU_323: return "2x2x3 Cuboid";
787
      case CU_343: return "3x3x4 Cuboid";
788
      case CUBE_4: return "Rubik's Revenge";
789
      case CUBE_5: return "Professor's Cube";
790
      case CUBE_6: return "6x6 Cube";
791
      case CUBE_7: return "7x7 Cube";
792
      }
793
    return "Rubik Cube";
794
    }
795

    
796
///////////////////////////////////////////////////////////////////////////////////////////////////
797

    
798
  public String getInventor()
799
    {
800
    int[] numLayers = getNumLayers();
801

    
802
    switch(intGetObjectType(numLayers))
803
      {
804
      case CUBE_2: return "Larry Nichols";
805
      case CU_232: return "Katsuhiko Okamoto";
806
      case CUBE_3: return "Ernő Rubik";
807
      case CU_323: return "Unknown";
808
      case CU_343: return "Cube4You";
809
      case CUBE_4: return "Péter Sebestény";
810
      case CUBE_5: return "Udo Krell";
811
      case CUBE_6:
812
      case CUBE_7: return "Panagiotis Verdes";
813
      }
814

    
815
    return "Ernő Rubik";
816
    }
817

    
818
///////////////////////////////////////////////////////////////////////////////////////////////////
819

    
820
  public int getYearOfInvention()
821
    {
822
    int[] numLayers = getNumLayers();
823

    
824
    switch(intGetObjectType(numLayers))
825
      {
826
      case CUBE_2: return 1970;
827
      case CU_232: return 2001;
828
      case CUBE_3: return 1974;
829
      case CU_323: return 0;
830
      case CU_343: return 2009;
831
      case CUBE_4: return 1981;
832
      case CUBE_5: return 2002;
833
      case CUBE_6:
834
      case CUBE_7: return 2008;
835
      }
836

    
837
    return 1974;
838
    }
839

    
840
///////////////////////////////////////////////////////////////////////////////////////////////////
841

    
842
  public int getComplexity()
843
    {
844
    int[] numLayers = getNumLayers();
845

    
846
    switch(intGetObjectType(numLayers))
847
      {
848
      case CUBE_2:
849
      case CU_232: return 1;
850
      case CUBE_3:
851
      case CU_323: return 2;
852
      case CU_343:
853
      case CUBE_4: return 3;
854
      case CUBE_5:
855
      case CUBE_6:
856
      case CUBE_7: return 4;
857
      }
858
    return 2;
859
    }
860
}
(6-6/26)