Project

General

Profile

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

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

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_CHANGING;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CUBOID;
24
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
25

    
26
import java.io.InputStream;
27

    
28
import org.distorted.library.type.Static3D;
29
import org.distorted.library.type.Static4D;
30

    
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.ObjectSticker;
36
import org.distorted.objectlib.helpers.ScrambleState;
37
import org.distorted.objectlib.main.ShapeHexahedron;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

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

    
50
  private ScrambleState[] mStates;
51
  private Static4D[] mQuats;
52
  private float[][] mCuts;
53
  private int[] mBasicAngle;
54
  private ObjectSticker[] mStickers;
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

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

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

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

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

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

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

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

    
102
      return ret;
103
      }
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

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

    
114
      int X = numLayers[0];
115
      int Y = numLayers[1];
116
      int Z = numLayers[2];
117

    
118
      int[][] mX = new int[16][];
119
      int[][] mY = new int[16][];
120
      int[][] mZ = new int[16][];
121

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

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

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

    
168
      }
169

    
170
    return mStates;
171
    }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

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

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

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

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

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

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  public ObjectShape getObjectShape(int variant)
220
    {
221
    int extraI, extraV, num, numL = getNumLayers()[0];
222
    float height;
223

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

    
232
    float[][] vertices = new float[][]
233
          {
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
              {-0.5f,-0.5f,-0.5f },
242
          };
243

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

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

    
264
    int[] bandIndices;
265

    
266
         if( variant==0 ) bandIndices = new int[] {0,0,0,0,0,0};
267
    else if( variant==1 ) bandIndices = new int[] {1,1,1,0,1,0};
268
    else                  bandIndices = new int[] {2,2,2,2,0,2};
269

    
270
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  private int getEdgeNum(int cubit, int[] numLayers)
276
    {
277
    int x = numLayers[0];
278
    int y = numLayers[1];
279
    int z = numLayers[2];
280

    
281
    if(x==1 || y==1 || z==1 ) return 0;
282

    
283
    int numCorners = getNumCorners(numLayers);
284
    int numEdges   = getNumEdges(numLayers);
285
    int num = cubit - numCorners;
286

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

    
296
      int numTD = (y-2);
297
      if( num<  numTD ) return 4;
298
      if( num<2*numTD ) return 5;
299
      if( num<3*numTD ) return 6;
300
      if( num<4*numTD ) return 7;
301
      num -= 4*numTD;
302

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

    
310
    return -1;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  private int getCenterNum(int cubit, int[] numLayers)
316
    {
317
    int numCorners = getNumCorners(numLayers);
318
    int numEdges   = getNumEdges(numLayers);
319
    int num = cubit - numCorners - numEdges;
320

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

    
328
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
329
      if( num<  numTD ) return 2;
330
      if( num<2*numTD ) return 3;
331
      num -= 2*numTD;
332

    
333
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
334
      if( num<  numFB ) return 4;
335
      if( num<2*numFB ) return 5;
336
      }
337

    
338
    return -1;
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  private int getNumCorners(int[] numLayers)
344
    {
345
    int x = numLayers[0];
346
    int y = numLayers[1];
347
    int z = numLayers[2];
348

    
349
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 8;
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  private int getNumEdges(int[] numLayers)
355
    {
356
    int x = numLayers[0];
357
    int y = numLayers[1];
358
    int z = numLayers[2];
359

    
360
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) );
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  public float[][] getCubitPositions(int[] numLayers)
366
    {
367
    final int X = numLayers[0];
368
    final int Y = numLayers[1];
369
    final int Z = numLayers[2];
370

    
371
    final float lenX = 0.5f*(X-1);
372
    final float lenY = 0.5f*(Y-1);
373
    final float lenZ = 0.5f*(Z-1);
374

    
375
    int curPos = 0;
376

    
377
    if( X==1 )
378
      {
379
      float[][] pos = new float[X*Y*Z][];
380

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

    
384
      return pos;
385
      }
386

    
387
    if( Y==1 )
388
      {
389
      float[][] pos = new float[X*Y*Z][];
390

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

    
394
      return pos;
395
      }
396

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

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

    
404
      return pos;
405
      }
406

    
407
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
408
    float[][] pos = new float[numCubits][];
409

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

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

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

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

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

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

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

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

    
450
    return pos;
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

    
455
  public Static4D getQuat(int cubit, int[] numLayers)
456
    {
457
    if( mQuats ==null ) initializeQuats();
458

    
459
    int variant = getCubitVariant(cubit,numLayers);
460

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

    
493
    return mQuats[0];
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public int getNumCubitVariants(int[] numLayers)
499
    {
500
    final int X = numLayers[0];
501
    final int Y = numLayers[1];
502
    final int Z = numLayers[2];
503

    
504
    if( X==1 || Y==1 || Z==1 ) return 1;
505
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
506

    
507
    return 3;
508
    }
509

    
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

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

    
519
    return 2;
520
    }
521

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
525
    {
526
    return 0;
527
    }
528

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

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

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

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

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

    
562
    return -1;
563
    }
564

    
565
///////////////////////////////////////////////////////////////////////////////////////////////////
566

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

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

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

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

    
593
    return mStickers[sticker];
594
    }
595

    
596
///////////////////////////////////////////////////////////////////////////////////////////////////
597

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

    
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605

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

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

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

    
625
    return mCuts;
626
    }
627

    
628
///////////////////////////////////////////////////////////////////////////////////////////////////
629

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

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

    
641
    return layerRotatable;
642
    }
643

    
644
///////////////////////////////////////////////////////////////////////////////////////////////////
645

    
646
  public int getMovementType()
647
    {
648
    return TC_CHANGING;
649
    }
650

    
651
///////////////////////////////////////////////////////////////////////////////////////////////////
652

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

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

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

    
668
///////////////////////////////////////////////////////////////////////////////////////////////////
669

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

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

    
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686

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

    
692
///////////////////////////////////////////////////////////////////////////////////////////////////
693

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

    
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700

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

    
706
///////////////////////////////////////////////////////////////////////////////////////////////////
707
// PUBLIC API
708

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

    
714
///////////////////////////////////////////////////////////////////////////////////////////////////
715

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

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

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

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

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

    
756
    return ObjectType.CUBE_3;
757
    }
758

    
759
///////////////////////////////////////////////////////////////////////////////////////////////////
760

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

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

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

    
791
///////////////////////////////////////////////////////////////////////////////////////////////////
792

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

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

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