Project

General

Profile

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

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

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, Static4D quat, Static3D move, float scale, InputStream stream)
58
    {
59
    super(numL, (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
             {height,35,0.5f,0.7f,  2, num-2,extraV},
260
             {height,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);
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 int getVariantFaceColor(int variant, int face, int[] numLayers)
524
    {
525
    return 0;
526
    }
527

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

    
530
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
531
    {
532
    int variant = getCubitVariant(cubit,numLayers);
533

    
534
    switch(variant)
535
      {
536
      case 0: int axis = face/2;
537
              return CUBITS[cubit].getRotRow(axis) == (face%2==0 ? (1<<(numLayers[axis]-1)):1) ? face : -1;
538
      case 1: if( face!=3 && face !=5 ) return -1;
539
              int edge = getEdgeNum(cubit,numLayers);
540

    
541
              switch(edge)
542
                {
543
                case  0: return face==3 ? 3 : 5;
544
                case  1: return face==3 ? 4 : 3;
545
                case  2: return face==3 ? 5 : 2;
546
                case  3: return face==3 ? 2 : 4;
547
                case  4: return face==3 ? 5 : 1;
548
                case  5: return face==3 ? 1 : 4;
549
                case  6: return face==3 ? 5 : 0;
550
                case  7: return face==3 ? 0 : 4;
551
                case  8: return face==3 ? 1 : 3;
552
                case  9: return face==3 ? 2 : 1;
553
                case 10: return face==3 ? 0 : 3;
554
                case 11: return face==3 ? 2 : 0;
555
                default: return 0;
556
                }
557

    
558
      case 2: return face==4 ? getCenterNum(cubit,numLayers) : -1;
559
      }
560

    
561
    return -1;
562
    }
563

    
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565

    
566
  public ObjectSticker retSticker(int sticker)
567
    {
568
    if( mStickers==null )
569
      {
570
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
571
      final float radius = 0.10f;
572
      final float[] radii = {radius,radius,radius,radius};
573
      mStickers = new ObjectSticker[STICKERS.length];
574
      float stroke = 0.08f;
575

    
576
      if( ObjectControl.isInIconMode() )
577
        {
578
        int[] numLayers = getNumLayers();
579

    
580
        switch(numLayers[0])
581
          {
582
          case 2: stroke*=1.8f; break;
583
          case 3: stroke*=2.0f; break;
584
          case 4: stroke*=2.1f; break;
585
          default:stroke*=2.2f; break;
586
          }
587
        }
588

    
589
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
590
      }
591

    
592
    return mStickers[sticker];
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public Static4D[] getQuats()
598
    {
599
    if( mQuats ==null ) initializeQuats();
600
    return mQuats;
601
    }
602

    
603
///////////////////////////////////////////////////////////////////////////////////////////////////
604

    
605
  public float[][] getCuts(int[] numLayers)
606
    {
607
    if( mCuts==null )
608
      {
609
      mCuts = new float[3][];
610

    
611
      for(int axis=0; axis<3; axis++)
612
        {
613
        int len = numLayers[axis];
614
        float start = (2-len)*0.5f;
615

    
616
        if( len>=2 )
617
          {
618
          mCuts[axis] = new float[len-1];
619
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
620
          }
621
        }
622
      }
623

    
624
    return mCuts;
625
    }
626

    
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628

    
629
  public boolean[][] getLayerRotatable(int[] numLayers)
630
    {
631
    int numAxis = ROT_AXIS.length;
632
    boolean[][] layerRotatable = new boolean[numAxis][];
633

    
634
    for(int i=0; i<numAxis; i++)
635
      {
636
      layerRotatable[i] = new boolean[numLayers[i]];
637
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
638
      }
639

    
640
    return layerRotatable;
641
    }
642

    
643
///////////////////////////////////////////////////////////////////////////////////////////////////
644

    
645
  public int getMovementType()
646
    {
647
    return TC_CUBOID;
648
    }
649

    
650
///////////////////////////////////////////////////////////////////////////////////////////////////
651

    
652
  public int getMovementSplit()
653
    {
654
    return TYPE_NOT_SPLIT;
655
    }
656

    
657
///////////////////////////////////////////////////////////////////////////////////////////////////
658

    
659
  public int[][][] getEnabled()
660
    {
661
    return new int[][][]
662
      {
663
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
664
      };
665
    }
666

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

    
669
  public float[] getDist3D(int[] numLayers)
670
    {
671
    float avg = (numLayers[0]+numLayers[1]+numLayers[2])/3.0f;
672

    
673
    return new float[]
674
        {
675
        0.5f*numLayers[0]/avg,
676
        0.5f*numLayers[0]/avg,
677
        0.5f*numLayers[1]/avg,
678
        0.5f*numLayers[1]/avg,
679
        0.5f*numLayers[2]/avg,
680
        0.5f*numLayers[2]/avg,
681
        };
682
    }
683

    
684
///////////////////////////////////////////////////////////////////////////////////////////////////
685

    
686
  public int getSolvedFunctionIndex()
687
    {
688
    return 0;
689
    }
690

    
691
///////////////////////////////////////////////////////////////////////////////////////////////////
692

    
693
  public int getNumStickerTypes(int[] numLayers)
694
    {
695
    return 1;
696
    }
697

    
698
///////////////////////////////////////////////////////////////////////////////////////////////////
699

    
700
  public int getNumCubitFaces()
701
    {
702
    return 6;
703
    }
704

    
705
///////////////////////////////////////////////////////////////////////////////////////////////////
706
// PUBLIC API
707

    
708
  public Static3D[] getRotationAxis()
709
    {
710
    return ROT_AXIS;
711
    }
712

    
713
///////////////////////////////////////////////////////////////////////////////////////////////////
714

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

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

    
729
///////////////////////////////////////////////////////////////////////////////////////////////////
730

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

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

    
755
    return ObjectType.CUBE_3;
756
    }
757

    
758
///////////////////////////////////////////////////////////////////////////////////////////////////
759

    
760
  public String getObjectName()
761
    {
762
    switch(getNumLayers()[0])
763
      {
764
      case 2: return "Pocket Cube";
765
      case 3: return "Rubik Cube";
766
      case 4: return "Rubik's Revenge";
767
      case 5: return "Professor's Cube";
768
      case 6: return "6x6 Cube";
769
      case 7: return "7x7 Cube";
770
      }
771
    return "Rubik Cube";
772
    }
773

    
774
///////////////////////////////////////////////////////////////////////////////////////////////////
775

    
776
  public String getInventor()
777
    {
778
    switch(getNumLayers()[0])
779
      {
780
      case 2: return "Larry Nichols";
781
      case 3: return "Ernő Rubik";
782
      case 4: return "Péter Sebestény";
783
      case 5: return "Udo Krell";
784
      case 6:
785
      case 7: return "Panagiotis Verdes";
786
      }
787
    return "Ernő Rubik";
788
    }
789

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

    
792
  public int getYearOfInvention()
793
    {
794
    switch(getNumLayers()[0])
795
      {
796
      case 2: return 1970;
797
      case 3: return 1974;
798
      case 4: return 1981;
799
      case 5: return 2002;
800
      case 6:
801
      case 7: return 2008;
802
      }
803
    return 1974;
804
    }
805

    
806
///////////////////////////////////////////////////////////////////////////////////////////////////
807

    
808
  public int getComplexity()
809
    {
810
    switch(getNumLayers()[0])
811
      {
812
      case  2: return 4;
813
      case  3: return 6;
814
      case  4: return 8;
815
      default: return 10;
816
      }
817
    }
818
}
(6-6/25)