Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyMorphix.java @ b5cc50ae

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.objects;
11

    
12
import org.distorted.library.type.Static3D;
13
import org.distorted.library.type.Static4D;
14
import org.distorted.objectlib.helpers.ObjectFaceShape;
15
import org.distorted.objectlib.helpers.ObjectShape;
16
import org.distorted.objectlib.helpers.ObjectSignature;
17
import org.distorted.objectlib.main.InitData;
18
import org.distorted.objectlib.scrambling.ScrambleState;
19
import org.distorted.objectlib.main.ObjectType;
20
import org.distorted.objectlib.main.ShapeTetrahedron;
21
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
22

    
23
import java.io.InputStream;
24

    
25
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CHANGING_SHAPEMOD;
26
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
27

    
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

    
30
public class TwistyMorphix extends ShapeTetrahedron
31
{
32
  // size>=3: if length of the edge of the whole tetrahedron is = 1.0, then
33
  // length of the edge of the corner cubit is equal to DIST. (separate for size 3 and 4)
34
  private static final float DIST3 = 0.39f;
35
  private static final float DIST4 = 0.365f;
36

    
37
  static final Static3D[] ROT_AXIS = new Static3D[]
38
         {
39
           new Static3D( SQ2/2, 0.0f, SQ2/2),
40
           new Static3D(  0.0f, 1.0f,  0.0f),
41
           new Static3D( SQ2/2, 0.0f,-SQ2/2),
42
         };
43

    
44
  private ScrambleState[] mStates;
45
  private int[][] mBasicAngle;
46
  private float[][] mCuts;
47
  private float[][] mCenters;
48
  private int[] mQuatIndex;
49

    
50
///////////////////////////////////////////////////////////////////////////////////////////////////
51

    
52
  public TwistyMorphix(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
53
    {
54
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
55
    }
56

    
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

    
59
  @Override
60
  public float getPillowCoeff()
61
    {
62
    return 2.0f;
63
    }
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  @Override
68
  public int getInternalColor()
69
    {
70
    return getNumLayers()[0]==2 ? 0xff000000 : 0xff333333;
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74
// same as in cubes
75

    
76
  public ScrambleState[] getScrambleStates()
77
    {
78
    if( mStates==null )
79
      {
80
      int[] numLayers = getNumLayers();
81
      int[][] m = new int[16][];
82
      for(int i=1; i<16; i++) m[i] = createEdges(numLayers[0],i);
83

    
84
      mStates = new ScrambleState[]
85
        {
86
        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
87
        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
88
        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
89
        new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
90
        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
91
        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
92
        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
93
        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
94
        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
95
        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
96
        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
97
        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
98
        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
99
        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
100
        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
101
        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
102
        };
103
      }
104

    
105
    return mStates;
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  private int[] createEdges(int size, int vertex)
111
    {
112
    int[] ret = new int[9*size];
113

    
114
    for(int l=0; l<size; l++)
115
      {
116
      ret[9*l  ] = l;
117
      ret[9*l+1] =-1;
118
      ret[9*l+2] = vertex;
119
      ret[9*l+3] = l;
120
      ret[9*l+4] = 1;
121
      ret[9*l+5] = vertex;
122
      ret[9*l+6] = l;
123
      ret[9*l+7] = 2;
124
      ret[9*l+8] = vertex;
125
      }
126

    
127
    return ret;
128
    }
129

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

    
132
  public float[][] getCuts(int[] numLayers)
133
    {
134
    if( mCuts==null )
135
      {
136
      int numL = numLayers[0];
137
      float[] cut = new float[numL-1];
138
      float DIST = numL==3 ? DIST3:DIST4;
139
      float dist = numL*(SQ2/2)*(0.5f-DIST);
140

    
141
      switch(numL)
142
        {
143
        case 2: cut[0] = 0;
144
                break;
145
        case 3: cut[0] = -dist;
146
                cut[1] = +dist;
147
                break;
148
        case 4: cut[0] = -dist;
149
                cut[1] = 0.0f;
150
                cut[2] = +dist;
151
                break;
152
        }
153

    
154
      mCuts = new float[][] { cut,cut,cut };
155
      }
156

    
157
    return mCuts;
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  public boolean[][] getLayerRotatable(int[] numLayers)
163
    {
164
    int numL = numLayers[0];
165
    boolean[] tmp = new boolean[numL];
166
    for(int i=0; i<numL; i++) tmp[i] = true;
167

    
168
    return new boolean[][] { tmp,tmp,tmp };
169
    }
170

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

    
173
  public int getTouchControlType()
174
    {
175
    return TC_CHANGING_SHAPEMOD;
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  public int getTouchControlSplit()
181
    {
182
    return TYPE_NOT_SPLIT;
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  public int[][][] getEnabled()
188
    {
189
    return null;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  public float[] getDist3D(int[] numLayers)
195
    {
196
    return TouchControlTetrahedron.D3D;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  public Static3D[] getFaceAxis()
202
    {
203
    return TouchControlTetrahedron.FACE_AXIS;
204
    }
205

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

    
208
  public float[][] getCubitPositions(int[] numLayers)
209
    {
210
    if( mCenters==null )
211
      {
212
      int numL = numLayers[0];
213
      float DIST = numL==3 ? DIST3:DIST4;
214
      final float C = numL==2 ? 1.0f : 6*numL*(0.25f-DIST/3);
215
      final float A = C*SQ2/6;
216
      final float B = C/3;
217
      final float D = (SQ2/12)*numL;
218
      final float E = (1.0f/6)*numL;
219

    
220
      if( numL==2 )
221
        {
222
        mCenters = new float[][]
223
           {
224
             {0.0f, -A,   +B},
225
             {0.0f, -A,   -B},
226
             {  +B,  A, 0.0f},
227
             {  -B,  A, 0.0f},
228

    
229
             {0.0f,  D,   +E},
230
             {0.0f,  D,   -E},
231
             {  +E, -D, 0.0f},
232
             {  -E, -D, 0.0f}
233
           };
234
        }
235
      else if( numL==3 )
236
        {
237
        final float X1 = 0.5f*(3*DIST-1)*numL;
238
        final float X2 = 0.5f*DIST*numL;
239
        final float X = 0.25f*numL*(1-DIST);
240
        final float Y = numL*(1-DIST)*(SQ2/4);
241
        final float F = 0.5f*(1-DIST)*numL - X2 + X1/2;
242
        final float G = 0.5f*F;
243
        final float H = (SQ2/2)*F;
244

    
245
        mCenters = new float[][]
246
           {
247
             {0.0f, -A,   +B},
248
             {0.0f, -A,   -B},
249
             {  +B,  A, 0.0f},
250
             {  -B,  A, 0.0f},
251

    
252
             {0.0f,  D,   +E},
253
             {0.0f,  D,   -E},
254
             {  +E, -D, 0.0f},
255
             {  -E, -D, 0.0f},
256

    
257
             {0.0f,  +Y,0.0f},
258
             {0.0f,  -Y,0.0f},
259
             {  +X,0.0f,  +X},
260
             {  +X,0.0f,  -X},
261
             {  -X,0.0f,  +X},
262
             {  -X,0.0f,  -X},
263

    
264
             {0.0f,0.0f,   F},
265
             {   G,   H,   G},
266
             {  -G,   H,   G},
267
             {0.0f,0.0f,  -F},
268
             {   G,   H,  -G},
269
             {  -G,   H,  -G},
270
             {   F,0.0f,0.0f},
271
             {   G,  -H,   G},
272
             {   G,  -H,  -G},
273
             {  -F,0.0f,0.0f},
274
             {  -G,  -H,   G},
275
             {  -G,  -H,  -G},
276
           };
277
        }
278
      else
279
        {
280
        final float X1 = 0.5f*(3*DIST-1)*numL;
281
        final float X2 = 0.5f*DIST*numL;
282
        final float X = 0.25f*numL*(1-DIST);
283
        final float Y = numL*(1-DIST)*(SQ2/4);
284
        final float Z = numL*(1-2*DIST)/(2*numL-4);
285
        final float F = 0.5f*(1-DIST)*numL - X2 + X1/2;
286
        final float G = 0.5f*F;
287
        final float H = (SQ2/2)*F;
288
        final float I = (0.25f-DIST/2)*numL;
289

    
290
        mCenters = new float[][]
291
           {
292
             {0.0f, -A,   +B},
293
             {0.0f, -A,   -B},
294
             {  +B,  A, 0.0f},
295
             {  -B,  A, 0.0f},
296

    
297
             {0.0f,  D,   +E},
298
             {0.0f,  D,   -E},
299
             {  +E, -D, 0.0f},
300
             {  -E, -D, 0.0f},
301

    
302
             {  +Z,  +Y,0.0f},
303
             {  -Z,  +Y,0.0f},
304
             {0.0f,  -Y,  +Z},
305
             {0.0f,  -Y,  -Z},
306
             {  +X-Z/2,-(SQ2/2)*Z,  +X+Z/2},
307
             {  +X+Z/2, (SQ2/2)*Z,  +X-Z/2},
308
             {  +X-Z/2,-(SQ2/2)*Z,  -X-Z/2},
309
             {  +X+Z/2, (SQ2/2)*Z,  -X+Z/2},
310
             {  -X+Z/2,-(SQ2/2)*Z,  +X+Z/2},
311
             {  -X-Z/2, (SQ2/2)*Z,  +X-Z/2},
312
             {  -X+Z/2,-(SQ2/2)*Z,  -X-Z/2},
313
             {  -X-Z/2, (SQ2/2)*Z,  -X+Z/2},
314

    
315
             {0.0f,-I*(SQ2/2),   F+I*0.5f},
316
             {   G+0.75f*I,   H+(SQ2/4)*I,   G-0.25f*I},
317
             {  -G-0.75f*I,   H+(SQ2/4)*I,   G-0.25f*I},
318
             {0.0f,-I*(SQ2/2),  -F-I*0.5f},
319
             {   G+0.75f*I,   H+(SQ2/4)*I,  -G+0.25f*I},
320
             {  -G-0.75f*I,   H+(SQ2/4)*I,  -G+0.25f*I},
321
             {   F+0.5f*I, I*(SQ2/2),0.0f},
322
             {   G-0.25f*I,  -H-(SQ2/4)*I,   G+0.75f*I},
323
             {   G-0.25f*I,  -H-(SQ2/4)*I,  -G-0.75f*I},
324
             {  -F-0.5f*I, I*(SQ2/2),0.0f},
325
             {  -G+0.25f*I,  -H-(SQ2/4)*I,   G+0.75f*I},
326
             {  -G+0.25f*I,  -H-(SQ2/4)*I,  -G-0.75f*I},
327

    
328
             {0.0f,+I*(SQ2/2),   F+I*0.5f},
329
             {   G-0.25f*I,   H+(SQ2/4)*I,   G+0.75f*I},
330
             {  -G+0.25f*I,   H+(SQ2/4)*I,   G+0.75f*I},
331
             {0.0f,+I*(SQ2/2),  -F-I*0.5f},
332
             {   G-0.25f*I,   H+(SQ2/4)*I,  -G-0.75f*I},
333
             {  -G+0.25f*I,   H+(SQ2/4)*I,  -G-0.75f*I},
334
             {   F+0.5f*I,-I*(SQ2/2),0.0f},
335
             {   G+0.75f*I,  -H-(SQ2/4)*I,   G-0.25f*I},
336
             {   G+0.75f*I,  -H-(SQ2/4)*I,  -G+0.25f*I},
337
             {  -F-0.5f*I,-I*(SQ2/2),0.0f},
338
             {  -G-0.75f*I,  -H-(SQ2/4)*I,   G-0.25f*I},
339
             {  -G-0.75f*I,  -H-(SQ2/4)*I,  -G+0.25f*I},
340

    
341
             {0.0f,    Y,   +Z},
342
             {0.0f,    Y,   -Z},
343
             {  +Z,   -Y, 0.0f},
344
             {  -Z,   -Y, 0.0f},
345
             { (SQ2/2)*Y-Z/2, (SQ2/2)*Z, (SQ2/2)*Y+Z/2},
346
             { (SQ2/2)*Y+Z/2,-(SQ2/2)*Z, (SQ2/2)*Y-Z/2},
347
             {-(SQ2/2)*Y+Z/2, (SQ2/2)*Z, (SQ2/2)*Y+Z/2},
348
             {-(SQ2/2)*Y-Z/2,-(SQ2/2)*Z, (SQ2/2)*Y-Z/2},
349
             { (SQ2/2)*Y-Z/2, (SQ2/2)*Z,-(SQ2/2)*Y-Z/2},
350
             { (SQ2/2)*Y+Z/2,-(SQ2/2)*Z,-(SQ2/2)*Y+Z/2},
351
             {-(SQ2/2)*Y+Z/2, (SQ2/2)*Z,-(SQ2/2)*Y-Z/2},
352
             {-(SQ2/2)*Y-Z/2,-(SQ2/2)*Z,-(SQ2/2)*Y+Z/2},
353
           };
354
        }
355
      }
356

    
357
    return mCenters;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public Static4D getCubitQuats(int cubit, int[] numLayers)
363
    {
364
    if( mQuatIndex==null )
365
      {
366
      switch(numLayers[0])
367
        {
368
        case 2: mQuatIndex = new int[] { 0,5,2,8,
369
                                         0,5,2,8
370
                                       };
371
                break;
372
        case 3: mQuatIndex = new int[] { 0,5,2,8,
373
                                         0,5,2,8,
374
                                         0,2,15,10,20,13,
375
                                         0,21,15,5,13,10,2,12,23,8,22,20
376
                                       };
377
                break;
378
        default:mQuatIndex = new int[] { 0,5,2,8,
379
                                         0,5,2,8,
380
                                         0,0,2,2,15,15,10,10,20,20,13,13,
381
                                         0,21,15,5,13,10,2,12,23,8,22,20,
382
                                         0,21,15,5,13,10,2,12,23,8,22,20,
383
                                         0,5,2,8,15,23,21,20,10,12,13,22
384
                                       };
385
        }
386

    
387
      }
388

    
389
    return mObjectQuats[mQuatIndex[cubit]];
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  public ObjectShape getObjectShape(int variant)
395
    {
396
    int numL = getNumLayers()[0];
397
    float DIST = numL==3 ? DIST3:DIST4;
398

    
399
    if( variant==0 )
400
      {
401
      final float Z = numL==2 ? 1.0f : numL*DIST;
402
      final float Y = (SQ2/2)*Z;
403

    
404
      float[][] vertices =
405
          {
406
              {0.0f,-2*Y/3, 2*Z/3 },
407
              {0.0f,-2*Y/3,  -Z/3 },
408
              { Z/2,   Y/3,   Z/6 },
409
              {-Z/2,   Y/3,   Z/6 },
410
              {0.0f,   Y/3,  -Z/3 }
411
          };
412

    
413
      int[][] indices = { {0,2,3},{0,1,2},{0,3,1},{4,2,1},{4,1,3},{4,3,2} };
414

    
415
      return new ObjectShape(vertices, indices);
416
      }
417
    else if( variant==1 )
418
      {
419
      final float X = numL==2 ? 1.0f : numL*(3*DIST-1);
420
      final float Y = (SQ2/2)*X;
421
      final float Z = 0.5f*X;
422

    
423
      float[][] vertices =
424
          {
425
              {-X/2,  -Y/3,   Z/3 },
426
              { X/2,  -Y/3,   Z/3 },
427
              {0.0f, 2*Y/3,-2*Z/3 },
428
              {0.0f,  -Y/3,-2*Z/3 }
429
          };
430

    
431
      int[][] indices = { {1,2,0},{3,1,0},{1,3,2},{3,0,2} };
432

    
433
      return new ObjectShape(vertices, indices);
434
      }
435
    else if( variant==2 )
436
      {
437
      final float X = numL*(1-2*DIST)/(2*numL-4);
438
      final float Y = (SQ2/4)*DIST*numL;
439

    
440
      float[][] vertices =
441
          {
442
              {  +X,     +Y,  0.0f },
443
              {  -X,     +Y,  0.0f },
444
              {0.0f,Y-X*SQ2,    +X },
445
              {0.0f,Y-X*SQ2,    -X },
446
              {  +X,     -Y,  0.0f },
447
              {  -X,     -Y,  0.0f },
448
              {0.0f,     -Y,    +X },
449
              {0.0f,     -Y,    -X },
450
          };
451

    
452
      int[][] indices = { {0,1,2},{0,3,1},{0,2,6,4},{2,1,5,6},{3,0,4,7},{1,3,7,5},{6,5,7,4} };
453

    
454
      return new ObjectShape(vertices, indices);
455
      }
456
    else if( variant==3 )
457
      {
458
      final float C = numL==3 ? 3*DIST-1 : 2*DIST-0.5f;
459
      final float X1 = 0.5f*C*numL;
460
      final float X2 = 0.5f*DIST*numL;
461
      final float Y  = (SQ2/4)*numL*(1-2*DIST)/(numL-2);
462

    
463
      float[][] vertices =
464
          {
465
              {  +X1,+Y,+X1/2 },
466
              {  -X1,+Y,+X1/2 },
467
              { 0.0f,+Y,-X1/2 },
468
              {  +X2,-Y,+X2-X1/2 },
469
              {  -X2,-Y,+X2-X1/2 },
470
              { 0.0f,-Y,-X1/2 },
471
          };
472

    
473
      int[][] indices = { {0,1,4,3},{0,3,5,2},{2,5,4,1},{0,2,1},{5,3,4} };
474

    
475
      return new ObjectShape(vertices, indices);
476
      }
477
    else if( variant==4 )
478
      {
479
      final float X1 = 0.5f*(3*DIST-1)*numL;
480
      final float X2 = 0.5f*(2*DIST-0.5f)*numL;
481
      final float Y  = (SQ2/4)*numL*(1-2*DIST)/(numL-2);
482

    
483
      float[][] vertices =
484
          {
485
              {  +X1,+Y,+X1-X2/2 },
486
              {  -X1,+Y,+X1-X2/2 },
487
              { 0.0f,+Y,-X2/2 },
488
              {  +X2,-Y,+X2/2 },
489
              {  -X2,-Y,+X2/2 },
490
              { 0.0f,-Y,-X2/2 },
491
          };
492

    
493
      int[][] indices = { {0,1,4,3},{0,3,5,2},{2,5,4,1},{0,2,1},{5,3,4} };
494

    
495
      return new ObjectShape(vertices, indices);
496
      }
497
    else
498
      {
499
      final float X = numL*(1-2*DIST)/(2*numL-4);
500
      final float Y = (SQ2/4)*DIST*numL;
501

    
502
      float[][] vertices =
503
          {
504
              {  +X,  Y-X*SQ2,  0.0f },
505
              {  -X,  Y-X*SQ2,  0.0f },
506
              {0.0f,Y-2*X*SQ2,    +X },
507
              {0.0f,Y        ,    -X },
508
              {  +X,       -Y,  0.0f },
509
              {  -X,       -Y,  0.0f },
510
              {0.0f,       -Y,    +X },
511
              {0.0f,       -Y,    -X },
512
          };
513

    
514
      int[][] indices = { {3,1,2,0},{0,2,6,4},{2,1,5,6},{3,0,4,7},{1,3,7,5},{6,5,7,4} };
515

    
516
      return new ObjectShape(vertices, indices);
517
      }
518
    }
519

    
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

    
522
  public ObjectFaceShape getObjectFaceShape(int variant)
523
    {
524
    float height = isInIconMode() ? 0.001f : 0.03f;
525
    float internal = 0.02f;
526
    int numL = getNumLayers()[0];
527
    float DIST = numL==3 ? DIST3:DIST4;
528

    
529
    if( variant==0 )
530
      {
531
      float eV = numL==2 ? 2 : 0;
532
      float push1 = numL<=3 ? 0.07f : 0.06f;
533
      float push2 = numL<=3 ? 0.06f : 0.05f;
534
      float[][] bands   = { {height,30,0.15f,0.5f,5,1,eV}, {internal,30,0.2f,0.4f,5,1,eV} };
535
      int[] bandIndices = { 0,0,0,1,1,1 };
536
      float[][] corners = { {push1,0.025f}, {push2,0.020f} };
537
      int[] indices     = { 0,0,0,0,-1 };
538
      float[][] centers = { { 0.0f,0.0f,0.0f } };
539
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
540
      }
541
    else if( variant==1 )
542
      {
543
      float eI = numL==2 ? 1 : 0;
544
      float eV = numL==2 ? 1 : 0;
545
      int N = numL==2 ? 5 : 4;
546
      final float C = numL==2 ? 1.0f : numL*(3*DIST-1);
547
      final float Y = (SQ2/2)*C;
548
      final float Z = 0.5f*C;
549
      float[][] bands   = { {height,30,0.15f,0.5f,N,eI,eV}, {internal,30,0.25f,0.5f,N,eI,eV} };
550
      int[] bandIndices = { 0,1,1,1 };
551
      float[][] corners = { {0.08f,0.013f} };
552
      int[] indices     = { -1,-1,-1,-1 };
553
      float[][] centers = { { 0.0f,-Y/3,-2*Z/3 } };
554
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
555
      }
556
    else if( variant==2 )
557
      {
558
      float[][] bands   = { {height,30,0.15f,0.5f,5,1,0}, {internal,30,0.25f,0.5f,5,1,0} };
559
      int[] bandIndices = { 0,0,1,1,1,1,1 };
560
      float[][] corners = { {0.07f,0.013f} };
561
      int[] indices     = { 0,0,-1,-1,-1,-1,-1,-1 };
562
      float[][] centers = { { 0.0f,0.0f,0.0f } };
563
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
564
      }
565
    else if( variant==3 || variant==4 )
566
      {
567
      int c = variant==3 ? 0 : -1;
568
      final float Y = (SQ2/4)*numL*(1-2*DIST)/(numL-2);
569
      float[][] bands   = { {height,30,0.15f,0.5f,5,0,0}, {internal,30,0.25f,0.5f,4,0,0} };
570
      int[] bandIndices = { 0,1,1,1,1 };
571
      float[][] corners = { {0.05f,0.023f} };
572
      int[] indices     = { -1,-1,-1,c,c,-1, };
573
      float[][] centers = { { 0.0f,-Y,0.0f } };
574
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
575
      }
576
    else
577
      {
578
      final float Z = numL*(1-2*DIST)/(2*numL-4);
579
      float[][] bands   = { {height,30,0.15f,0.5f,5,0,0}, {internal,30,0.25f,0.5f,3,0,0} };
580
      int[] bandIndices = { 0,1,1,1,1,1 };
581
      float[][] corners = { {0.02f,0.023f} };
582
      int[] indices     = { 0,0,0,0,-1,-1,-1,-1 };
583
      float[][] centers = { { 0.0f,0.0f,-Z } };
584
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
585
      }
586
    }
587

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

    
590
  public int getNumCubitVariants(int[] numLayers)
591
    {
592
    switch(numLayers[0])
593
      {
594
      case 2: return 2;
595
      case 3: return 4;
596
      case 4: return 6;
597
      }
598

    
599
    return 0;
600
    }
601

    
602
///////////////////////////////////////////////////////////////////////////////////////////////////
603

    
604
  public int getCubitVariant(int cubit, int[] numLayers)
605
    {
606
    switch(numLayers[0])
607
      {
608
      case 2: return cubit<4 ? 0 : 1;
609
      case 3: return cubit<4 ? 0 : ( cubit<8 ? 1: (cubit<14 ? 2:3) );
610
      case 4: return cubit<4 ? 0 : ( cubit<8 ? 1: (cubit<20 ? 2: (cubit<32 ? 3: (cubit<44 ? 4:5) ) ) );
611
      }
612

    
613
    return 0;
614
    }
615

    
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617

    
618
  public float getStickerRadius()
619
    {
620
    return 0.10f;
621
    }
622

    
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624

    
625
  public float getStickerStroke()
626
    {
627
    float stroke = 0.07f;
628

    
629
    if( isInIconMode() )
630
      {
631
      int[] numLayers = getNumLayers();
632

    
633
      switch(numLayers[0])
634
        {
635
        case 2: stroke*=1.8f; break;
636
        case 3: stroke*=2.5f; break;
637
        case 4: stroke*=3.0f; break;
638
        default:stroke*=4.0f; break;
639
        }
640
      }
641

    
642
    return stroke;
643
    }
644

    
645
///////////////////////////////////////////////////////////////////////////////////////////////////
646

    
647
  public float[][] getStickerAngles()
648
    {
649
    return null;
650
    }
651

    
652
///////////////////////////////////////////////////////////////////////////////////////////////////
653
// PUBLIC API
654

    
655
  public Static3D[] getRotationAxis()
656
    {
657
    return ROT_AXIS;
658
    }
659

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

    
662
  public int[][] getBasicAngles()
663
    {
664
    if( mBasicAngle==null )
665
      {
666
      int num = getNumLayers()[0];
667
      int[] tmp = new int[num];
668
      for(int i=0; i<num; i++) tmp[i] = 4;
669
      mBasicAngle = new int[][] { tmp,tmp,tmp };
670
      }
671

    
672
    return mBasicAngle;
673
    }
674

    
675
///////////////////////////////////////////////////////////////////////////////////////////////////
676

    
677
  public String getShortName()
678
    {
679
    switch(getNumLayers()[0])
680
      {
681
      case 2: return ObjectType.MORP_2.name();
682
      case 3: return ObjectType.MORP_3.name();
683
      case 4: return ObjectType.MORP_4.name();
684
      }
685
    return null;
686
    }
687

    
688
///////////////////////////////////////////////////////////////////////////////////////////////////
689

    
690
  public ObjectSignature getSignature()
691
    {
692
    switch(getNumLayers()[0])
693
      {
694
      case 2: return new ObjectSignature(ObjectType.MORP_2);
695
      case 3: return new ObjectSignature(ObjectType.MORP_3);
696
      case 4: return new ObjectSignature(ObjectType.MORP_4);
697
      }
698
    return null;
699
    }
700

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

    
703
  public String getObjectName()
704
    {
705
    switch(getNumLayers()[0])
706
      {
707
      case 2: return "Pyramorphix";
708
      case 3: return "Mastermorphix";
709
      case 4: return "Megamorphix";
710
      }
711
    return null;
712
    }
713

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

    
716
  public String getInventor()
717
    {
718
    switch(getNumLayers()[0])
719
      {
720
      case 2: return "Manfred Fritsche";
721
      case 3: return "Tony Fisher";
722
      case 4: return "Adam Zamora";
723
      }
724
    return null;
725
    }
726

    
727
///////////////////////////////////////////////////////////////////////////////////////////////////
728

    
729
  public int getYearOfInvention()
730
    {
731
    switch(getNumLayers()[0])
732
      {
733
      case 2: return 0;
734
      case 3: return 1991;
735
      case 4: return 2004;
736
      }
737
    return 0;
738
    }
739

    
740
///////////////////////////////////////////////////////////////////////////////////////////////////
741

    
742
  public int getComplexity()
743
    {
744
    switch(getNumLayers()[0])
745
      {
746
      case 2: return 1;
747
      case 3: return 2;
748
      case 4: return 3;
749
      }
750
    return 1;
751
    }
752

    
753
///////////////////////////////////////////////////////////////////////////////////////////////////
754

    
755
  public String[][] getTutorials()
756
    {
757
    switch(getNumLayers()[0])
758
      {
759
      case 2: return new String[][] {
760
                          {"gb","dD67B3cRaFw","Pyramorphix Solve Tutorial","SpeedCubeReview"},
761
                          {"es","RA37LhYlEW8","Resolver Pyramorphix","Cuby"},
762
                          {"ru","fTNXLAAuGAI","Как собрать Пираморфикс 2х2","Алексей Ярыгин"},
763
                          {"fr","SfEqoud5KRc","Résolution du Pyramorphix","Asthalis"},
764
                          {"de","1VDGoVJZCug","Pyramorphix - Tutorial","GerCubing"},
765
                          {"pl","b7VpuXloBNU","Mastermorphix 2x2 Tutorial PL","MrUK"},
766
                          {"br","wByfDxTrbC8","Como resolver o Pyramorphix","Rafael Cinoto"},
767
                          {"kr","WIy5ZvTXsOY","피라몰픽스 쉽게 맞추기","큐브놀이터"},
768
                          {"vn","6CuTRLjKHho","Tutorial N.14 - Pyramorphix","Duy Thích Rubik"},
769
                         };
770
      case 3: return new String[][] {
771
                          {"gb","Q1DXmDGyebc","How to Solve the Mastermorphix","Z3"},
772
                          {"es","8kOuV-O4jGA","Resolver Mastermorphix 3x3","Cuby"},
773
                          {"ru","hs5jZee0XUo","Как собрать Мастерморфикс 3х3","Алексей Ярыгин"},
774
                          {"fr","73j0APwbWzc","Résolution du Mastermorphix","Asthalis"},
775
                          {"de","gbo7yTTHx5A","Mastermorphix - Tutorial","GerCubing"},
776
                          {"pl","_ZgduvWVx14","Mastermorphix Tutorial PL","MrUK"},
777
                          {"br","bFJjjWPsDoY","Mastermorphix - tutorial","Cubo da Loucura"},
778
                          {"kr","yKW48BaE91M","마스터 몰픽스 해법","듀나메스 큐브 해법연구소"},
779
                          {"vn","QcJ7E8_Duws","Giải Rubik - Mastermorphix","Duy Thích Rubik"},
780
                         };
781
      case 4: return new String[][] {
782
                          {"gb","su4ELv85wiY","Megamorphix Tutorial","CrazyBadCuber"},
783
                          {"es","riQY9fdspbI","Megamorphix del rubikeo","Tutoriales Rubik"},
784
                          {"ru","ZE_zPegnYTY","Как собрать Мастерморфикс 4х4","Алексей Ярыгин"},
785
                          {"fr","oLjjky1QCaA","Résolution du Megamorphix","Asthalis"},
786
                          {"pl","pF_9SaFI_fg","Mastermorphix 4x4 Tutorial PL","MrUK"},
787
                          {"br","J_V0TNDBc-M","Megamorphix Walkthrough Solve","cubo vicio"},
788
                          {"vn","20T2dIHZWHk","Megamorphix 4x4 tutorial","VĂN CÔNG TÙNG"},
789
                         };
790
      }
791
    return null;
792
    }
793
}
(23-23/36)