Project

General

Profile

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

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

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.helpers.ObjectFaceShape;
31
import org.distorted.objectlib.touchcontrol.TouchControlCuboids;
32
import org.distorted.objectlib.main.ObjectControl;
33
import org.distorted.objectlib.main.ObjectType;
34
import org.distorted.objectlib.helpers.ObjectShape;
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

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

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

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

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

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

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

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

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

    
100
      return ret;
101
      }
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

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

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

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

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

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

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

    
166
      }
167

    
168
    return mStates;
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

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

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

    
195
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),  // 16
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),
199
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),  // 20
200
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
201
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
202
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
203
         };
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

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

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  public ObjectShape getObjectShape(int variant)
218
    {
219
    float[][] vertices =
220
          {
221
              { 0.5f, 0.5f, 0.5f },
222
              { 0.5f, 0.5f,-0.5f },
223
              { 0.5f,-0.5f, 0.5f },
224
              { 0.5f,-0.5f,-0.5f },
225
              {-0.5f, 0.5f, 0.5f },
226
              {-0.5f, 0.5f,-0.5f },
227
              {-0.5f,-0.5f, 0.5f },
228
              {-0.5f,-0.5f,-0.5f },
229
          };
230

    
231
    int[][] indices =
232
          {
233
              {2,3,1,0},
234
              {7,6,4,5},
235
              {4,0,1,5},
236
              {7,3,2,6},
237
              {6,2,0,4},
238
              {3,7,5,1}
239
          };
240

    
241
    return new ObjectShape(vertices, indices, 1);
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public ObjectFaceShape getObjectFaceShape(int variant)
247
    {
248
    int[] bandIndices;
249
    int extraI, extraV, num, numL = getNumLayers()[0];
250
    float height;
251

    
252
    switch(numL)
253
        {
254
        case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
255
        case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
256
        case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
257
        default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
258
        }
259

    
260
    float[][] corners= { {0.036f,0.12f} };
261
    float[][] centers= { {0.0f, 0.0f, 0.0f} };
262
    int[] indices    = { 0,0,0,0,0,0,0,0 };
263
    float[][] bands  =
264
         {
265
             {height,35,0.5f,0.7f,num,extraI,extraV},
266
             {     0,35,0.5f,0.7f,  2, num-2,extraV},
267
             {     0,35,0.5f,0.7f,  2,     0,     0},
268
         };
269

    
270
         if( variant==0 ) bandIndices = new int[] {0,0,0,0,0,0};
271
    else if( variant==1 ) bandIndices = new int[] {1,1,1,0,1,0};
272
    else                  bandIndices = new int[] {2,2,2,2,0,2};
273

    
274
    return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices, null);
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  private int getEdgeNum(int cubit, int[] numLayers)
280
    {
281
    int x = numLayers[0];
282
    int y = numLayers[1];
283
    int z = numLayers[2];
284

    
285
    if(x==1 || y==1 || z==1 ) return 0;
286

    
287
    int numCorners = getNumCorners(numLayers);
288
    int numEdges   = getNumEdges(numLayers);
289
    int num = cubit - numCorners;
290

    
291
    if( num>=0 && num<numEdges )
292
      {
293
      int numLR = (x-2);
294
      if( num<  numLR ) return 0;
295
      if( num<2*numLR ) return 1;
296
      if( num<3*numLR ) return 2;
297
      if( num<4*numLR ) return 3;
298
      num -= 4*numLR;
299

    
300
      int numTD = (y-2);
301
      if( num<  numTD ) return 4;
302
      if( num<2*numTD ) return 5;
303
      if( num<3*numTD ) return 6;
304
      if( num<4*numTD ) return 7;
305
      num -= 4*numTD;
306

    
307
      int numFB = (z-2);
308
      if( num<  numFB ) return 8;
309
      if( num<2*numFB ) return 9;
310
      if( num<3*numFB ) return 10;
311
      if( num<4*numFB ) return 11;
312
      }
313

    
314
    return -1;
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  private int getCenterNum(int cubit, int[] numLayers)
320
    {
321
    int numCorners = getNumCorners(numLayers);
322
    int numEdges   = getNumEdges(numLayers);
323
    int num = cubit - numCorners - numEdges;
324

    
325
    if( num>=0 )
326
      {
327
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
328
      if( num<  numLR ) return 0;
329
      if( num<2*numLR ) return 1;
330
      num -= 2*numLR;
331

    
332
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
333
      if( num<  numTD ) return 2;
334
      if( num<2*numTD ) return 3;
335
      num -= 2*numTD;
336

    
337
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
338
      if( num<  numFB ) return 4;
339
      if( num<2*numFB ) return 5;
340
      }
341

    
342
    return -1;
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  private int getNumCorners(int[] numLayers)
348
    {
349
    int x = numLayers[0];
350
    int y = numLayers[1];
351
    int z = numLayers[2];
352

    
353
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 8;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  private int getNumEdges(int[] numLayers)
359
    {
360
    int x = numLayers[0];
361
    int y = numLayers[1];
362
    int z = numLayers[2];
363

    
364
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) );
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  public float[][] getCubitPositions(int[] numLayers)
370
    {
371
    final int X = numLayers[0];
372
    final int Y = numLayers[1];
373
    final int Z = numLayers[2];
374

    
375
    final float lenX = 0.5f*(X-1);
376
    final float lenY = 0.5f*(Y-1);
377
    final float lenZ = 0.5f*(Z-1);
378

    
379
    int curPos = 0;
380

    
381
    if( X==1 )
382
      {
383
      float[][] pos = new float[X*Y*Z][];
384

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

    
388
      return pos;
389
      }
390

    
391
    if( Y==1 )
392
      {
393
      float[][] pos = new float[X*Y*Z][];
394

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

    
398
      return pos;
399
      }
400

    
401
    if( Z==1 )
402
      {
403
      float[][] pos = new float[X*Y*Z][];
404

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

    
408
      return pos;
409
      }
410

    
411
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
412
    float[][] pos = new float[numCubits][];
413

    
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
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
418
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
419
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
420
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
421
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
422

    
423
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
424
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
425
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
426
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
427
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
428
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
429
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
430
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
431
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
432
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
433
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
434
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
435

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

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

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

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

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

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

    
454
    return pos;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  public Static4D getQuat(int cubit, int[] numLayers)
460
    {
461
    if( mQuats ==null ) initializeQuats();
462

    
463
    int variant = getCubitVariant(cubit,numLayers);
464

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

    
497
    return mQuats[0];
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public int getNumCubitVariants(int[] numLayers)
503
    {
504
    final int X = numLayers[0];
505
    final int Y = numLayers[1];
506
    final int Z = numLayers[2];
507

    
508
    if( X==1 || Y==1 || Z==1 ) return 1;
509
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
510

    
511
    return 3;
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

    
516
  public int getCubitVariant(int cubit, int[] numLayers)
517
    {
518
    int numCorners = getNumCorners(numLayers);
519
    if( cubit < numCorners          ) return 0;
520
    int numEdges = getNumEdges(numLayers);
521
    if( cubit < numCorners+numEdges ) return 1;
522

    
523
    return 2;
524
    }
525

    
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527

    
528
  public Static4D[] getQuats()
529
    {
530
    if( mQuats ==null ) initializeQuats();
531
    return mQuats;
532
    }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
  public float[][] getCuts(int[] numLayers)
537
    {
538
    if( mCuts==null )
539
      {
540
      mCuts = new float[3][];
541

    
542
      for(int axis=0; axis<3; axis++)
543
        {
544
        int len = numLayers[axis];
545
        float start = (2-len)*0.5f;
546

    
547
        if( len>=2 )
548
          {
549
          mCuts[axis] = new float[len-1];
550
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
551
          }
552
        }
553
      }
554

    
555
    return mCuts;
556
    }
557

    
558
///////////////////////////////////////////////////////////////////////////////////////////////////
559

    
560
  public boolean[][] getLayerRotatable(int[] numLayers)
561
    {
562
    int numAxis = ROT_AXIS.length;
563
    boolean[][] layerRotatable = new boolean[numAxis][];
564

    
565
    for(int i=0; i<numAxis; i++)
566
      {
567
      layerRotatable[i] = new boolean[numLayers[i]];
568
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
569
      }
570

    
571
    return layerRotatable;
572
    }
573

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

    
576
  public int getTouchControlType()
577
    {
578
    return TC_CUBOID;
579
    }
580

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

    
583
  public int getTouchControlSplit()
584
    {
585
    return TYPE_NOT_SPLIT;
586
    }
587

    
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589

    
590
  public int[][][] getEnabled()
591
    {
592
    return new int[][][]
593
      {
594
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
595
      };
596
    }
597

    
598
///////////////////////////////////////////////////////////////////////////////////////////////////
599

    
600
  public float[] getDist3D(int[] numLayers)
601
    {
602
    float avg = (numLayers[0]+numLayers[1]+numLayers[2])/3.0f;
603

    
604
    return new float[]
605
        {
606
        0.5f*numLayers[0]/avg,
607
        0.5f*numLayers[0]/avg,
608
        0.5f*numLayers[1]/avg,
609
        0.5f*numLayers[1]/avg,
610
        0.5f*numLayers[2]/avg,
611
        0.5f*numLayers[2]/avg,
612
        };
613
    }
614

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

    
617
  public int getSolvedFunctionIndex()
618
    {
619
    return 0;
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)