Project

General

Profile

« Previous | Next » 

Revision d6998705

Added by Leszek Koltunski over 2 years ago

Improve rotations of a Cuboid.

View differences:

src/main/java/org/distorted/objectlib/main/ObjectType.java
184 184
      case  0:
185 185
      case  1:
186 186
      case  2:
187
      case  3: return new TwistyCube          (numL, quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
187
      case  3: return new TwistyCuboid(numL, quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
188 188
      case  4: return new TwistyJing          (numL, quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
189 189
      case  5:
190 190
      case  6:
src/main/java/org/distorted/objectlib/objects/TwistyCube.java
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.TYPE_NOT_SPLIT;
23

  
24
import android.content.res.Resources;
25

  
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

  
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40
import org.distorted.objectlib.main.Twisty6;
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
public class TwistyCube extends Twisty6
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(1,0,0),
49
           new Static3D(0,1,0),
50
           new Static3D(0,0,1)
51
         };
52

  
53
  private static final int[][][] ENABLED = new int[][][]
54
      {
55
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
56
      };
57

  
58
  private ScrambleState[] mStates;
59
  private Static4D[] mQuats;
60
  private float[][] mCuts;
61
  private boolean[][] mLayerRotatable;
62
  private int[] mBasicAngle;
63
  private ObjectSticker[] mStickers;
64
  private Movement mMovement;
65

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

  
68
  public TwistyCube(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
69
                    MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
70
    {
71
    super(numL, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
72
    }
73

  
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

  
76
  private int[] createEdges(int size, int vertex)
77
    {
78
    int[] ret = new int[9*size];
79

  
80
    for(int l=0; l<size; l++)
81
      {
82
      ret[9*l  ] = l;
83
      ret[9*l+1] =-1;
84
      ret[9*l+2] = vertex;
85
      ret[9*l+3] = l;
86
      ret[9*l+4] = 1;
87
      ret[9*l+5] = vertex;
88
      ret[9*l+6] = l;
89
      ret[9*l+7] = 2;
90
      ret[9*l+8] = vertex;
91
      }
92

  
93
    return ret;
94
    }
95

  
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

  
98
  protected ScrambleState[] getScrambleStates()
99
    {
100
    if( mStates==null )
101
      {
102
      int[] numL = getNumLayers();
103
      int[][] m = new int[16][];
104
      for(int i=1; i<16; i++) m[i] = createEdges(numL[0],i);
105

  
106
      mStates = new ScrambleState[]
107
        {
108
        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
109
        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
110
        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
111
        new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
112
        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
113
        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
114
        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
115
        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
116
        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
117
        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
118
        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
119
        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
120
        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
121
        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
122
        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
123
        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
124
        };
125
      }
126

  
127
    return mStates;
128
    }
129

  
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

  
132
  protected int getResource(int[] numLayers)
133
    {
134
    int x = numLayers[0];
135
    int y = numLayers[1];
136
    int z = numLayers[2];
137

  
138
    if( x==y && x==z )
139
      {
140
      switch(x)
141
        {
142
        case 2: return R.raw.cube2;
143
        case 3: return R.raw.cube3;
144
        case 4: return R.raw.cube4;
145
        case 5: return R.raw.cube5;
146
        }
147
      }
148

  
149
    return 0;
150
    }
151

  
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

  
154
  private void initializeQuats()
155
    {
156
    mQuats = new Static4D[]
157
         {
158
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
159
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
160
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
161
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
162

  
163
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
164
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
165
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
166
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
167
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
168
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
169
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
170
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
171
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
172
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
173
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
174
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
175

  
176
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
177
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
178
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
179
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
180
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
181
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
182
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
183
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
184
         };
185
    }
186

  
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

  
189
  protected int[] getSolvedQuats(int cubit, int[] numLayers)
190
    {
191
    if( mQuats ==null ) initializeQuats();
192
    int status = retCubitSolvedStatus(cubit,numLayers);
193
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
194
    }
195

  
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

  
198
  protected ObjectShape getObjectShape(int cubit, int[] numLayers)
199
    {
200
    int extraI, extraV, num;
201
    float height;
202
    int variant = getCubitVariant(cubit,numLayers);
203
    int numL = numLayers[0];
204

  
205
    switch(numL)
206
        {
207
        case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
208
        case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
209
        case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
210
        default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
211
        }
212

  
213
    double[][] vertices = new double[][]
214
          {
215
              { 0.5, 0.5, 0.5 },
216
              { 0.5, 0.5,-0.5 },
217
              { 0.5,-0.5, 0.5 },
218
              { 0.5,-0.5,-0.5 },
219
              {-0.5, 0.5, 0.5 },
220
              {-0.5, 0.5,-0.5 },
221
              {-0.5,-0.5, 0.5 },
222
              {-0.5,-0.5,-0.5 },
223
          };
224

  
225
    int[][] vert_indices = new int[][]
226
          {
227
              {2,3,1,0},
228
              {7,6,4,5},
229
              {4,0,1,5},
230
              {7,3,2,6},
231
              {6,2,0,4},
232
              {3,7,5,1}
233
          };
234

  
235
    float[][] corners   = new float[][] { {0.036f,0.12f} };
236
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
237
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
238
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
239

  
240
    if( variant==0 )
241
      {
242
      float[][] bands   = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
243
      int[] bandIndices = new int[] { 0,0,0,0,0,0};
244
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
245
      }
246
    else
247
      {
248
      int extraI2, extraV2, num2;
249

  
250
      switch(numL)
251
        {
252
        case 2 : num2 = 6; extraI2 = 2; extraV2 = 2; break;
253
        case 3 : num2 = 5; extraI2 = 1; extraV2 = 0; break;
254
        case 4 : num2 = 4; extraI2 = 0; extraV2 = 0; break;
255
        default: num2 = 3; extraI2 = 0; extraV2 = 0; break;
256
        }
257

  
258
      float[][] bands   = new float[][]
259
        {
260
          {height,35,0.5f,0.7f,num ,extraI ,extraV },
261
          {height,35,0.5f,0.7f,num2,extraI2,extraV2},
262
          {height,35,0.5f,0.7f,   2,      0,      0},
263
        };
264
      int[] bandIndices = new int[] { 1,1,1,1,0,2};
265
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
266
      }
267
    }
268

  
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

  
271
  private int getCenterNum(int cubit, int[] numLayers)
272
    {
273
    int num = cubit - getNumCornersAndEdges(numLayers);
274

  
275
    if( num>=0 )
276
      {
277
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
278
      if( num<  numLR ) return 0;
279
      if( num<2*numLR ) return 1;
280
      num -= 2*numLR;
281

  
282
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
283
      if( num<  numTD ) return 2;
284
      if( num<2*numTD ) return 3;
285
      num -= 2*numTD;
286

  
287
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
288
      if( num<  numFB ) return 4;
289
      if( num<2*numFB ) return 5;
290
      }
291

  
292
    return -1;
293
    }
294

  
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

  
297
  private int getNumCornersAndEdges(int[] numLayers)
298
    {
299
    int x = numLayers[0];
300
    int y = numLayers[1];
301
    int z = numLayers[2];
302

  
303
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) ) + 8;
304
    }
305

  
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

  
308
  protected float[][] getCubitPositions(int[] numLayers)
309
    {
310
    final int X = numLayers[0];
311
    final int Y = numLayers[1];
312
    final int Z = numLayers[2];
313

  
314
    final float lenX = 0.5f*(X-1);
315
    final float lenY = 0.5f*(Y-1);
316
    final float lenZ = 0.5f*(Z-1);
317

  
318
    int curPos = 0;
319

  
320
    if( X==1 )
321
      {
322
      float[][] pos = new float[X*Y*Z][];
323

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

  
327
      return pos;
328
      }
329

  
330
    if( Y==1 )
331
      {
332
      float[][] pos = new float[X*Y*Z][];
333

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

  
337
      return pos;
338
      }
339

  
340
    if( Z==1 )
341
      {
342
      float[][] pos = new float[X*Y*Z][];
343

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

  
347
      return pos;
348
      }
349

  
350
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
351
    float[][] pos = new float[numCubits][];
352

  
353
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
354
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
355
    pos[curPos++] = new float[] {-lenX,+lenY,-lenZ};
356
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
357
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
358
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
359
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
360
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
361

  
362
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
363
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
364
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
365
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
366
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
367
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
368
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
369
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
370
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
371
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
372
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
373
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
374

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

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

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

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

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

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

  
393
    return pos;
394
    }
395

  
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

  
398
  protected Static4D getQuat(int cubit, int[] numLayers)
399
    {
400
    if( mQuats ==null ) initializeQuats();
401

  
402
    int centerNum = getCenterNum(cubit,numLayers);
403

  
404
    switch(centerNum)
405
      {
406
      case 0 : return mQuats[13];
407
      case 1 : return mQuats[12];
408
      case 2 : return mQuats[ 8];
409
      case 3 : return mQuats[ 9];
410
      case 4 : return mQuats[ 0];
411
      case 5 : return mQuats[ 1];
412
      default: return mQuats[ 0];
413
      }
414
    }
415

  
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

  
418
  protected int getNumCubitVariants(int[] numLayers)
419
    {
420
    return numLayers[0]>2 ? 2:1;
421
    }
422

  
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424

  
425
  protected int getCubitVariant(int cubit, int[] numLayers)
426
    {
427
    return cubit < getNumCornersAndEdges(numLayers) ? 0 : 1;
428
    }
429

  
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

  
432
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
433
    {
434
    int centerNum = getCenterNum(cubit,numLayers);
435

  
436
    if( centerNum<0 )
437
      {
438
      int axis = cubitface/2;
439
      return CUBITS[cubit].getRotRow(axis) == (cubitface%2==0 ? (1<<(numLayers[axis]-1)):1) ? cubitface : NUM_TEXTURES;
440
      }
441
    else
442
      {
443
      return cubitface == 4 ? centerNum : NUM_TEXTURES;
444
      }
445
    }
446

  
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

  
449
  protected ObjectSticker retSticker(int face)
450
    {
451
    if( mStickers==null )
452
      {
453
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
454
      final float radius = 0.10f;
455
      final float[] radii = {radius,radius,radius,radius};
456
      mStickers = new ObjectSticker[STICKERS.length];
457
      float stroke = 0.08f;
458

  
459
      if( ObjectControl.isInIconMode() )
460
        {
461
        int[] numLayers = getNumLayers();
462

  
463
        switch(numLayers[0])
464
          {
465
          case 2: stroke*=1.8f; break;
466
          case 3: stroke*=2.0f; break;
467
          case 4: stroke*=2.1f; break;
468
          default:stroke*=2.2f; break;
469
          }
470
        }
471

  
472
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
473
      }
474

  
475
    return mStickers[face/NUM_FACE_COLORS];
476
    }
477

  
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479

  
480
  protected Static4D[] getQuats()
481
    {
482
    if( mQuats ==null ) initializeQuats();
483
    return mQuats;
484
    }
485

  
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

  
488
  protected float[][] getCuts(int[] numLayers)
489
    {
490
    if( mCuts==null )
491
      {
492
      mCuts = new float[3][];
493

  
494
      int lenX = numLayers[0];
495

  
496
      if( lenX>=2 )
497
        {
498
        mCuts[0] = new float[lenX-1];
499
        for(int i=0; i<lenX-1; i++) mCuts[0][i] = (2-lenX)*0.5f + i;
500
        }
501
      else
502
        {
503
        mCuts[0] = null;
504
        }
505

  
506
      int lenY = numLayers[1];
507

  
508
      if( lenY>=2 )
509
        {
510
        mCuts[1] = new float[lenY-1];
511
        for(int i=0; i<lenY-1; i++) mCuts[1][i] = (2-lenY)*0.5f + i;
512
        }
513
      else
514
        {
515
        mCuts[1] = null;
516
        }
517

  
518
      int lenZ = numLayers[2];
519

  
520
      if( lenZ>=2 )
521
        {
522
        mCuts[2] = new float[lenZ-1];
523
        for(int i=0; i<lenZ-1; i++) mCuts[2][i] = (2-lenZ)*0.5f + i;
524
        }
525
      else
526
        {
527
        mCuts[2] = null;
528
        }
529
      }
530

  
531
    return mCuts;
532
    }
533

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

  
536
  private void getLayerRotatable(int[] numLayers)
537
    {
538
    if( mLayerRotatable==null )
539
      {
540
      int numAxis = ROT_AXIS.length;
541
      mLayerRotatable = new boolean[numAxis][];
542

  
543
      for(int i=0; i<numAxis; i++)
544
        {
545
        mLayerRotatable[i] = new boolean[numLayers[i]];
546
        for(int j=0; j<numLayers[i]; j++) mLayerRotatable[i][j] = true;
547
        }
548
      }
549
    }
550

  
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

  
553
  protected int getSolvedFunctionIndex()
554
    {
555
    return 0;
556
    }
557

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

  
560
  protected int getNumStickerTypes(int[] numLayers)
561
    {
562
    return 1;
563
    }
564

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

  
567
  protected int getNumCubitFaces()
568
    {
569
    return 6;
570
    }
571

  
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573
// PUBLIC API
574

  
575
  public Static3D[] getRotationAxis()
576
    {
577
    return ROT_AXIS;
578
    }
579

  
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581
// TODO
582

  
583
  public Movement getMovement()
584
    {
585
    if( mMovement==null )
586
      {
587
      int[] numLayers = getNumLayers();
588
      if( mCuts==null ) getCuts(numLayers);
589
      getLayerRotatable(numLayers);
590
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers[0],TYPE_NOT_SPLIT,ENABLED);
591
      }
592
    return mMovement;
593
    }
594

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

  
597
  public int[] getBasicAngle()
598
    {
599
    if( mBasicAngle==null )
600
      {
601
      int[] num = getNumLayers();
602
      int x = num[1]==num[2] ? 4 : 2;
603
      int y = num[0]==num[2] ? 4 : 2;
604
      int z = num[0]==num[1] ? 4 : 2;
605

  
606
      mBasicAngle = new int[] { x,y,z };
607
      }
608
    return mBasicAngle;
609
    }
610

  
611
///////////////////////////////////////////////////////////////////////////////////////////////////
612
// TODO
613

  
614
  public ObjectType intGetObjectType(int[] numLayers)
615
    {
616
    switch(numLayers[0])
617
      {
618
      case 2: return numLayers[1]==2 ? ObjectType.CUBE_2 : ObjectType.CU_223;
619
      case 3: return numLayers[1]==3 ? ObjectType.CUBE_3 : ObjectType.CU_334;
620
      case 4: return ObjectType.CUBE_4;
621
      case 5: return ObjectType.CUBE_5;
622
      }
623

  
624
    return ObjectType.CUBE_3;
625
    }
626

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

  
629
  public int getObjectName(int[] numLayers)
630
    {
631
    switch(numLayers[0])
632
      {
633
      case 2: return R.string.cube2;
634
      case 3: return R.string.cube3;
635
      case 4: return R.string.cube4;
636
      case 5: return R.string.cube5;
637
      }
638
    return R.string.cube3;
639
    }
640

  
641
///////////////////////////////////////////////////////////////////////////////////////////////////
642

  
643
  public int getInventor(int[] numLayers)
644
    {
645
    switch(numLayers[0])
646
      {
647
      case 2: return R.string.cube2_inventor;
648
      case 3: return R.string.cube3_inventor;
649
      case 4: return R.string.cube4_inventor;
650
      case 5: return R.string.cube5_inventor;
651
      }
652
    return R.string.cube3_inventor;
653
    }
654

  
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656

  
657
  public int getComplexity(int[] numLayers)
658
    {
659
    switch(numLayers[0])
660
      {
661
      case 2: return 4;
662
      case 3: return 6;
663
      case 4: return 8;
664
      case 5: return 10;
665
      }
666
    return 6;
667
    }
668
}
src/main/java/org/distorted/objectlib/objects/TwistyCuboid.java
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.TYPE_NOT_SPLIT;
23

  
24
import android.content.res.Resources;
25

  
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

  
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40
import org.distorted.objectlib.main.Twisty6;
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
public class TwistyCuboid extends Twisty6
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(1,0,0),
49
           new Static3D(0,1,0),
50
           new Static3D(0,0,1)
51
         };
52

  
53
  private static final int[][][] ENABLED = new int[][][]
54
      {
55
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
56
      };
57

  
58
  private ScrambleState[] mStates;
59
  private Static4D[] mQuats;
60
  private float[][] mCuts;
61
  private boolean[][] mLayerRotatable;
62
  private int[] mBasicAngle;
63
  private ObjectSticker[] mStickers;
64
  private Movement mMovement;
65

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

  
68
  public TwistyCuboid(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
69
                      MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
70
    {
71
    super(numL, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
72
    }
73

  
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

  
76
  private int[] createEdges(int size, boolean full, int vertex)
77
    {
78
    if( full )
79
      {
80
      int[] ret = new int[9*size];
81

  
82
      for(int l=0; l<size; l++)
83
        {
84
        ret[9*l  ] = l;
85
        ret[9*l+1] =-1;
86
        ret[9*l+2] = vertex;
87
        ret[9*l+3] = l;
88
        ret[9*l+4] = 1;
89
        ret[9*l+5] = vertex;
90
        ret[9*l+6] = l;
91
        ret[9*l+7] = 2;
92
        ret[9*l+8] = vertex;
93
        }
94

  
95
      return ret;
96
      }
97
    else
98
      {
99
      int[] ret = new int[6*size];
100

  
101
      for(int l=0; l<size; l++)
102
        {
103
        ret[6*l  ] = l;
104
        ret[6*l+1] = 1;
105
        ret[6*l+2] = vertex;
106
        ret[6*l+3] = l;
107
        ret[6*l+4] =-1;
108
        ret[6*l+5] = vertex;
109
        }
110

  
111
      return ret;
112
      }
113
    }
114

  
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

  
117
  protected ScrambleState[] getScrambleStates()
118
    {
119
    if( mStates==null )
120
      {
121
      int[] numLayers = getNumLayers();
122

  
123
      int X = numLayers[0];
124
      int Y = numLayers[1];
125
      int Z = numLayers[2];
126

  
127
      int[][] mX = new int[16][];
128
      int[][] mY = new int[16][];
129
      int[][] mZ = new int[16][];
130

  
131
      for(int i=1; i<16; i++) mX[i] = createEdges(X,Y==Z,i);
132
      for(int i=1; i<16; i++) mY[i] = createEdges(Y,X==Z,i);
133
      for(int i=1; i<16; i++) mZ[i] = createEdges(Z,X==Y,i);
134

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

  
156
    return mStates;
157
    }
158

  
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

  
161
  protected int getResource(int[] numLayers)
162
    {
163
    int x = numLayers[0];
164
    int y = numLayers[1];
165
    int z = numLayers[2];
166

  
167
    if( x==y && x==z )
168
      {
169
      switch(x)
170
        {
171
        case 2: return R.raw.cube2;
172
        case 3: return R.raw.cube3;
173
        case 4: return R.raw.cube4;
174
        case 5: return R.raw.cube5;
175
        }
176
      }
177

  
178
    return 0;
179
    }
180

  
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

  
183
  private void initializeQuats()
184
    {
185
    mQuats = new Static4D[]
186
         {
187
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
188
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
189
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
190
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
191

  
192
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
193
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
194
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
195
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
196
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
197
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
198
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
199
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
200
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
201
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
202
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
203
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
204

  
205
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
206
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
207
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
208
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
209
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
210
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
211
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
212
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
213
         };
214
    }
215

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

  
218
  protected int[] getSolvedQuats(int cubit, int[] numLayers)
219
    {
220
    if( mQuats ==null ) initializeQuats();
221
    int status = retCubitSolvedStatus(cubit,numLayers);
222
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
223
    }
224

  
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

  
227
  protected ObjectShape getObjectShape(int cubit, int[] numLayers)
228
    {
229
    int extraI, extraV, num;
230
    float height;
231
    int variant = getCubitVariant(cubit,numLayers);
232
    int numL = numLayers[0];
233

  
234
    switch(numL)
235
        {
236
        case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
237
        case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
238
        case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
239
        default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
240
        }
241

  
242
    double[][] vertices = new double[][]
243
          {
244
              { 0.5, 0.5, 0.5 },
245
              { 0.5, 0.5,-0.5 },
246
              { 0.5,-0.5, 0.5 },
247
              { 0.5,-0.5,-0.5 },
248
              {-0.5, 0.5, 0.5 },
249
              {-0.5, 0.5,-0.5 },
250
              {-0.5,-0.5, 0.5 },
251
              {-0.5,-0.5,-0.5 },
252
          };
253

  
254
    int[][] vert_indices = new int[][]
255
          {
256
              {2,3,1,0},
257
              {7,6,4,5},
258
              {4,0,1,5},
259
              {7,3,2,6},
260
              {6,2,0,4},
261
              {3,7,5,1}
262
          };
263

  
264
    float[][] corners   = new float[][] { {0.036f,0.12f} };
265
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
266
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
267
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
268

  
269
    if( variant==0 )
270
      {
271
      float[][] bands   = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
272
      int[] bandIndices = new int[] { 0,0,0,0,0,0};
273
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
274
      }
275
    else
276
      {
277
      int extraI2, extraV2, num2;
278

  
279
      switch(numL)
280
        {
281
        case 2 : num2 = 6; extraI2 = 2; extraV2 = 2; break;
282
        case 3 : num2 = 5; extraI2 = 1; extraV2 = 0; break;
283
        case 4 : num2 = 4; extraI2 = 0; extraV2 = 0; break;
284
        default: num2 = 3; extraI2 = 0; extraV2 = 0; break;
285
        }
286

  
287
      float[][] bands   = new float[][]
288
        {
289
          {height,35,0.5f,0.7f,num ,extraI ,extraV },
290
          {height,35,0.5f,0.7f,num2,extraI2,extraV2},
291
          {height,35,0.5f,0.7f,   2,      0,      0},
292
        };
293
      int[] bandIndices = new int[] { 1,1,1,1,0,2};
294
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
295
      }
296
    }
297

  
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

  
300
  private int getCenterNum(int cubit, int[] numLayers)
301
    {
302
    int num = cubit - getNumCornersAndEdges(numLayers);
303

  
304
    if( num>=0 )
305
      {
306
      int numLR = (numLayers[1]-2)*(numLayers[2]-2);
307
      if( num<  numLR ) return 0;
308
      if( num<2*numLR ) return 1;
309
      num -= 2*numLR;
310

  
311
      int numTD = (numLayers[0]-2)*(numLayers[2]-2);
312
      if( num<  numTD ) return 2;
313
      if( num<2*numTD ) return 3;
314
      num -= 2*numTD;
315

  
316
      int numFB = (numLayers[0]-2)*(numLayers[1]-2);
317
      if( num<  numFB ) return 4;
318
      if( num<2*numFB ) return 5;
319
      }
320

  
321
    return -1;
322
    }
323

  
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

  
326
  private int getNumCornersAndEdges(int[] numLayers)
327
    {
328
    int x = numLayers[0];
329
    int y = numLayers[1];
330
    int z = numLayers[2];
331

  
332
    return ( x==1 || y==1 || z==1 ) ? x*y*z : 4*( (x-2)+(y-2)+(z-2) ) + 8;
333
    }
334

  
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

  
337
  protected float[][] getCubitPositions(int[] numLayers)
338
    {
339
    final int X = numLayers[0];
340
    final int Y = numLayers[1];
341
    final int Z = numLayers[2];
342

  
343
    final float lenX = 0.5f*(X-1);
344
    final float lenY = 0.5f*(Y-1);
345
    final float lenZ = 0.5f*(Z-1);
346

  
347
    int curPos = 0;
348

  
349
    if( X==1 )
350
      {
351
      float[][] pos = new float[X*Y*Z][];
352

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

  
356
      return pos;
357
      }
358

  
359
    if( Y==1 )
360
      {
361
      float[][] pos = new float[X*Y*Z][];
362

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

  
366
      return pos;
367
      }
368

  
369
    if( Z==1 )
370
      {
371
      float[][] pos = new float[X*Y*Z][];
372

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

  
376
      return pos;
377
      }
378

  
379
    int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
380
    float[][] pos = new float[numCubits][];
381

  
382
    pos[curPos++] = new float[] {-lenX,-lenY,-lenZ};
383
    pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
384
    pos[curPos++] = new float[] {-lenX,+lenY,-lenZ};
385
    pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
386
    pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
387
    pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
388
    pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
389
    pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
390

  
391
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  -lenZ };
392
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  -lenY,  +lenZ };
393
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  -lenZ };
394
    for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX,  +lenY,  +lenZ };
395
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  -lenZ };
396
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  -lenX, i-lenY,  +lenZ };
397
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  -lenZ };
398
    for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] {  +lenX, i-lenY,  +lenZ };
399
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  -lenY, i-lenZ };
400
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  -lenX,  +lenY, i-lenZ };
401
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  -lenY, i-lenZ };
402
    for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] {  +lenX,  +lenY, i-lenZ };
403

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

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

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

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

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

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

  
422
    return pos;
423
    }
424

  
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

  
427
  protected Static4D getQuat(int cubit, int[] numLayers)
428
    {
429
    if( mQuats ==null ) initializeQuats();
430

  
431
    int centerNum = getCenterNum(cubit,numLayers);
432

  
433
    switch(centerNum)
434
      {
435
      case 0 : return mQuats[13];
436
      case 1 : return mQuats[12];
437
      case 2 : return mQuats[ 8];
438
      case 3 : return mQuats[ 9];
439
      case 4 : return mQuats[ 0];
440
      case 5 : return mQuats[ 1];
441
      default: return mQuats[ 0];
442
      }
443
    }
444

  
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

  
447
  protected int getNumCubitVariants(int[] numLayers)
448
    {
449
    return numLayers[0]>2 ? 2:1;
450
    }
451

  
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

  
454
  protected int getCubitVariant(int cubit, int[] numLayers)
455
    {
456
    return cubit < getNumCornersAndEdges(numLayers) ? 0 : 1;
457
    }
458

  
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

  
461
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
462
    {
463
    int centerNum = getCenterNum(cubit,numLayers);
464

  
465
    if( centerNum<0 )
466
      {
467
      int axis = cubitface/2;
468
      return CUBITS[cubit].getRotRow(axis) == (cubitface%2==0 ? (1<<(numLayers[axis]-1)):1) ? cubitface : NUM_TEXTURES;
469
      }
470
    else
471
      {
472
      return cubitface == 4 ? centerNum : NUM_TEXTURES;
473
      }
474
    }
475

  
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

  
478
  protected ObjectSticker retSticker(int face)
479
    {
480
    if( mStickers==null )
481
      {
482
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
483
      final float radius = 0.10f;
484
      final float[] radii = {radius,radius,radius,radius};
485
      mStickers = new ObjectSticker[STICKERS.length];
486
      float stroke = 0.08f;
487

  
488
      if( ObjectControl.isInIconMode() )
489
        {
490
        int[] numLayers = getNumLayers();
491

  
492
        switch(numLayers[0])
493
          {
494
          case 2: stroke*=1.8f; break;
495
          case 3: stroke*=2.0f; break;
496
          case 4: stroke*=2.1f; break;
497
          default:stroke*=2.2f; break;
498
          }
499
        }
500

  
501
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
502
      }
503

  
504
    return mStickers[face/NUM_FACE_COLORS];
505
    }
506

  
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

  
509
  protected Static4D[] getQuats()
510
    {
511
    if( mQuats ==null ) initializeQuats();
512
    return mQuats;
513
    }
514

  
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

  
517
  protected float[][] getCuts(int[] numLayers)
518
    {
519
    if( mCuts==null )
520
      {
521
      mCuts = new float[3][];
522

  
523
      int lenX = numLayers[0];
524

  
525
      if( lenX>=2 )
526
        {
527
        mCuts[0] = new float[lenX-1];
528
        for(int i=0; i<lenX-1; i++) mCuts[0][i] = (2-lenX)*0.5f + i;
529
        }
530
      else
531
        {
532
        mCuts[0] = null;
533
        }
534

  
535
      int lenY = numLayers[1];
536

  
537
      if( lenY>=2 )
538
        {
539
        mCuts[1] = new float[lenY-1];
540
        for(int i=0; i<lenY-1; i++) mCuts[1][i] = (2-lenY)*0.5f + i;
541
        }
542
      else
543
        {
544
        mCuts[1] = null;
545
        }
546

  
547
      int lenZ = numLayers[2];
548

  
549
      if( lenZ>=2 )
550
        {
551
        mCuts[2] = new float[lenZ-1];
552
        for(int i=0; i<lenZ-1; i++) mCuts[2][i] = (2-lenZ)*0.5f + i;
553
        }
554
      else
555
        {
556
        mCuts[2] = null;
557
        }
558
      }
559

  
560
    return mCuts;
561
    }
562

  
563
///////////////////////////////////////////////////////////////////////////////////////////////////
564

  
565
  private void getLayerRotatable(int[] numLayers)
566
    {
567
    if( mLayerRotatable==null )
568
      {
569
      int numAxis = ROT_AXIS.length;
570
      mLayerRotatable = new boolean[numAxis][];
571

  
572
      for(int i=0; i<numAxis; i++)
573
        {
574
        mLayerRotatable[i] = new boolean[numLayers[i]];
575
        for(int j=0; j<numLayers[i]; j++) mLayerRotatable[i][j] = true;
576
        }
577
      }
578
    }
579

  
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581

  
582
  protected int getSolvedFunctionIndex()
583
    {
584
    return 0;
585
    }
586

  
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588

  
589
  protected int getNumStickerTypes(int[] numLayers)
590
    {
591
    return 1;
592
    }
593

  
594
///////////////////////////////////////////////////////////////////////////////////////////////////
595

  
596
  protected int getNumCubitFaces()
597
    {
598
    return 6;
599
    }
600

  
601
///////////////////////////////////////////////////////////////////////////////////////////////////
602
// PUBLIC API
603

  
604
  public Static3D[] getRotationAxis()
605
    {
606
    return ROT_AXIS;
607
    }
608

  
609
///////////////////////////////////////////////////////////////////////////////////////////////////
610
// TODO
611

  
612
  public Movement getMovement()
613
    {
614
    if( mMovement==null )
615
      {
616
      int[] numLayers = getNumLayers();
617
      if( mCuts==null ) getCuts(numLayers);
618
      getLayerRotatable(numLayers);
619
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers[0],TYPE_NOT_SPLIT,ENABLED);
620
      }
621
    return mMovement;
622
    }
623

  
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

  
626
  public int[] getBasicAngle()
627
    {
628
    if( mBasicAngle==null )
629
      {
630
      int[] num = getNumLayers();
631
      int x = num[1]==num[2] ? 4 : 2;
632
      int y = num[0]==num[2] ? 4 : 2;
633
      int z = num[0]==num[1] ? 4 : 2;
634

  
635
      mBasicAngle = new int[] { x,y,z };
636
      }
637
    return mBasicAngle;
638
    }
639

  
640
///////////////////////////////////////////////////////////////////////////////////////////////////
641
// TODO
642

  
643
  public ObjectType intGetObjectType(int[] numLayers)
644
    {
645
    switch(numLayers[0])
646
      {
647
      case 2: return numLayers[1]==2 ? ObjectType.CUBE_2 : ObjectType.CU_223;
648
      case 3: return numLayers[1]==3 ? ObjectType.CUBE_3 : ObjectType.CU_334;
649
      case 4: return ObjectType.CUBE_4;
650
      case 5: return ObjectType.CUBE_5;
651
      }
652

  
653
    return ObjectType.CUBE_3;
654
    }
655

  
656
///////////////////////////////////////////////////////////////////////////////////////////////////
657

  
658
  public int getObjectName(int[] numLayers)
659
    {
660
    switch(numLayers[0])
661
      {
662
      case 2: return R.string.cube2;
663
      case 3: return R.string.cube3;
664
      case 4: return R.string.cube4;
665
      case 5: return R.string.cube5;
666
      }
667
    return R.string.cube3;
668
    }
669

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

  
672
  public int getInventor(int[] numLayers)
673
    {
674
    switch(numLayers[0])
675
      {
676
      case 2: return R.string.cube2_inventor;
677
      case 3: return R.string.cube3_inventor;
678
      case 4: return R.string.cube4_inventor;
679
      case 5: return R.string.cube5_inventor;
680
      }
681
    return R.string.cube3_inventor;
682
    }
683

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

  
686
  public int getComplexity(int[] numLayers)
687
    {
688
    switch(numLayers[0])
689
      {
690
      case 2: return 4;
691
      case 3: return 6;
692
      case 4: return 8;
693
      case 5: return 10;
694
      }
695
    return 6;
696
    }
697
}

Also available in: Unified diff