Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import static org.distorted.objectlib.main.Movement.MOVEMENT_SHAPECHANGE;
23
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

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

    
30
import org.distorted.objectlib.main.MovementC;
31
import org.distorted.objectlib.main.ObjectControl;
32
import org.distorted.objectlib.main.ObjectType;
33
import org.distorted.objectlib.helpers.ObjectShape;
34
import org.distorted.objectlib.helpers.ObjectSticker;
35
import org.distorted.objectlib.helpers.ScrambleState;
36
import org.distorted.objectlib.main.Twisty6;
37

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

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

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

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

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

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

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

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

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

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

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

    
101
      return ret;
102
      }
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

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

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

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

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

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

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

    
167
      }
168

    
169
    return mStates;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

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

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

    
196
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),  // 16
197
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
198
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
199
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
200
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),  // 20
201
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
202
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
203
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
204
         };
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

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

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

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

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

    
231
    double[][] vertices = new double[][]
232
          {
233
              { 0.5, 0.5, 0.5 },
234
              { 0.5, 0.5,-0.5 },
235
              { 0.5,-0.5, 0.5 },
236
              { 0.5,-0.5,-0.5 },
237
              {-0.5, 0.5, 0.5 },
238
              {-0.5, 0.5,-0.5 },
239
              {-0.5,-0.5, 0.5 },
240
              {-0.5,-0.5,-0.5 },
241
          };
242

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

    
253
    float[][] corners   = new float[][] { {0.036f,0.12f} };
254
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
255
    int[] indices = new int[] { 0,0,0,0,0,0,0,0 };
256

    
257
    int extraI2 = numL<=3 ? num-2 : 0;
258

    
259
    float[][] bands   = new float[][]
260
         {
261
             {height,35,0.5f,0.7f,num,extraI ,extraV},
262
             {height,35,0.5f,0.7f,  2,extraI2,     0},
263
             {height,35,0.5f,0.7f,  2,      0,     0},
264
         };
265

    
266
    int[] bandIndices;
267

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

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

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

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

    
283
    if(x==1 || y==1 || z==1 ) return 0;
284

    
285
    int numCorners = getNumCorners(numLayers);
286
    int numEdges   = getNumEdges(numLayers);
287
    int num = cubit - numCorners;
288

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

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

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

    
312
    return -1;
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

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

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

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

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

    
340
    return -1;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

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

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

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

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

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

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

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

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

    
377
    int curPos = 0;
378

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

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

    
386
      return pos;
387
      }
388

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

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

    
396
      return pos;
397
      }
398

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

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

    
406
      return pos;
407
      }
408

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

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

    
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<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<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<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<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
    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

    
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 y=1; y<Y-1; y++)
438
      for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {-lenX,y-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 z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,-lenY,z-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
    for(int x=1; x<X-1; x++)
450
      for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,-lenZ};
451

    
452
    return pos;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

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

    
461
    int variant = getCubitVariant(cubit,numLayers);
462

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

    
495
    return mQuats[0];
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

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

    
506
    if( X==1 || Y==1 || Z==1 ) return 1;
507
    if( X<=2 && Y<=2 && Z<=2 ) return 1;
508

    
509
    return 3;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

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

    
521
    return 2;
522
    }
523

    
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525

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

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532

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

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

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

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

    
564
    return -1;
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

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

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

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

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

    
595
    return mStickers[sticker];
596
    }
597

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

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

    
606
///////////////////////////////////////////////////////////////////////////////////////////////////
607

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

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

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

    
627
    return mCuts;
628
    }
629

    
630
///////////////////////////////////////////////////////////////////////////////////////////////////
631

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

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

    
643
    return layerRotatable;
644
    }
645

    
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647

    
648
  public int getMovementType()
649
    {
650
    return MOVEMENT_SHAPECHANGE;
651
    }
652

    
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654

    
655
  public int getMovementSplit()
656
    {
657
    return TYPE_NOT_SPLIT;
658
    }
659

    
660
///////////////////////////////////////////////////////////////////////////////////////////////////
661

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

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

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

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

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

    
689
  public int getSolvedFunctionIndex()
690
    {
691
    return 0;
692
    }
693

    
694
///////////////////////////////////////////////////////////////////////////////////////////////////
695

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

    
701
///////////////////////////////////////////////////////////////////////////////////////////////////
702

    
703
  public int getNumCubitFaces()
704
    {
705
    return 6;
706
    }
707

    
708
///////////////////////////////////////////////////////////////////////////////////////////////////
709
// PUBLIC API
710

    
711
  public Static3D[] getRotationAxis()
712
    {
713
    return ROT_AXIS;
714
    }
715

    
716
///////////////////////////////////////////////////////////////////////////////////////////////////
717

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

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

    
732
///////////////////////////////////////////////////////////////////////////////////////////////////
733

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

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

    
757
    return ObjectType.CUBE_3;
758
    }
759

    
760
///////////////////////////////////////////////////////////////////////////////////////////////////
761

    
762
  public String getObjectName()
763
    {
764
    switch(getNumLayers()[0])
765
      {
766
      case 2: return "Pocket Cube";
767
      case 3: return "Rubik Cube";
768
      case 4: return "Rubik's Revenge";
769
      case 5: return "Professor's Cube";
770
      case 6: return "6x6 V-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: 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 8: return 2008;
801
      }
802
    return 1974;
803
    }
804

    
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806

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