Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIcosamate.java @ a0ef8a1d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 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 static org.distorted.objectlib.touchcontrol.TouchControl.TC_ICOSAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14
import static org.distorted.objectlib.touchcontrol.TouchControlIcosahedron.*;
15

    
16
import org.distorted.library.type.Static3D;
17
import org.distorted.library.type.Static4D;
18
import org.distorted.objectlib.helpers.FactoryCubit;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectShape;
21
import org.distorted.objectlib.signature.ObjectSignature;
22
import org.distorted.objectlib.helpers.ObjectVertexEffects;
23
import org.distorted.objectlib.main.InitAssets;
24
import org.distorted.objectlib.main.InitData;
25
import org.distorted.objectlib.signature.ObjectConstants;
26
import org.distorted.objectlib.main.ObjectType;
27
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
28
import org.distorted.objectlib.shape.ShapeIcosahedron;
29
import org.distorted.objectlib.touchcontrol.TouchControlIcosahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class TwistyIcosamate extends ShapeIcosahedron
34
{
35
  static final Static3D[] ROT_AXIS = new Static3D[]
36
         {
37
           new Static3D(                   0,                   1,                   0),
38
           new Static3D(                   0, VEC[1][1]/VEC[0][1], VEC[1][2]/VEC[0][1]),
39
           new Static3D( VEC[2][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[2][2]/VEC[0][1]),
40
           new Static3D( VEC[3][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[3][2]/VEC[0][1]),
41
           new Static3D(-VEC[3][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[3][2]/VEC[0][1]),
42
           new Static3D(-VEC[2][0]/VEC[0][1], VEC[1][1]/VEC[0][1], VEC[2][2]/VEC[0][1])
43
         };
44

    
45
  private int[][] mEdges;
46
  private int[][] mBasicAngle;
47
  private float[][] mCuts;
48
  private float[][] mPosition;
49
  private int[] mQuatIndex;
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

    
53
  public TwistyIcosamate(int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
54
    {
55
    super(iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
56
    }
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
  @Override
61
  public int getInternalColor()
62
    {
63
    return 0xff222222;
64
    }
65

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

    
68
  public int[][] getScrambleEdges()
69
    {
70
    if( mEdges==null )
71
      {
72
      int[][] basicAngle = getBasicAngles();
73
      mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(basicAngle);
74
      }
75

    
76
    return mEdges;
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
  public float[][] getCuts(int[] numLayers)
82
    {
83
    if( mCuts==null )
84
      {
85
      int nL = numLayers[0];
86
      float[] cut = new float[nL-1];
87
      for(int i=0; i<nL-1; i++) cut[i] = VEC[1][1]*(2*i+2-nL);
88
      mCuts = new float[][] { cut,cut,cut,cut,cut,cut };
89
      }
90

    
91
    return mCuts;
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  public boolean[][] getLayerRotatable(int[] numLayers)
97
    {
98
    int nL = numLayers[0];
99
    boolean[] tmp = new boolean[nL];
100
    for(int i=0; i<nL; i++) tmp[i] = true;
101
    return new boolean[][] { tmp,tmp,tmp,tmp,tmp,tmp };
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  public int getTouchControlType()
107
    {
108
    return TC_ICOSAHEDRON;
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  public int getTouchControlSplit()
114
    {
115
    return TYPE_NOT_SPLIT;
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  public int[][][] getEnabled()
121
    {
122
    return new int[][][]
123
      {
124
          {{3,4,5}}, {{1,4,5}}, {{1,2,5}}, {{1,2,3}}, {{2,3,4}},
125
          {{0,2,5}}, {{0,1,3}}, {{0,2,4}}, {{0,3,5}}, {{0,1,4}},
126
          {{0,2,5}}, {{0,1,3}}, {{0,2,4}}, {{0,3,5}}, {{0,1,4}},
127
          {{3,4,5}}, {{1,4,5}}, {{1,2,5}}, {{1,2,3}}, {{2,3,4}},
128
      };
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public float[] getDist3D(int[] numLayers)
134
    {
135
    return TouchControlIcosahedron.D3D;
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  public Static3D[] getFaceAxis()
141
    {
142
    return TouchControlIcosahedron.FACE_AXIS;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  private float[] computeOff(int index, int N)
148
    {
149
    if( N==2 )
150
      {
151
      return new float[] {0,0,0};
152
      }
153
    else
154
      {
155
      switch(index)
156
        {
157
        case 0 : return new float[] {0,SQ3/9,0};
158
        case 1 : return new float[] {-1.0f/6,-SQ3/18,0};
159
        default: return new float[] { 1.0f/6,-SQ3/18,0};
160
        }
161
      }
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165
// Rodrigues
166

    
167
  private void rotateVect(float vx, float vy, float vz, float sin, float cos, float[] vec)
168
    {
169
    float cx = vy*vec[2] - vz*vec[1];
170
    float cy = vz*vec[0] - vx*vec[2];
171
    float cz = vx*vec[1] - vy*vec[0];
172

    
173
    float scalar = vx*vec[0] + vy*vec[1] + vz*vec[2];
174

    
175
    vec[0] = vec[0]*cos + cx*sin + vx*scalar*(1-cos);
176
    vec[1] = vec[1]*cos + cy*sin + vy*scalar*(1-cos);
177
    vec[2] = vec[2]*cos + cz*sin + vz*scalar*(1-cos);
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  private void rotateFacePosition(float x, float y, float z, float[] off)
183
    {
184
    float cosB = (float)Math.sqrt(x*x+z*z);
185
    float sinB = y;
186
    float sinA = x/cosB;
187
    float cosA = z/cosB;
188

    
189
    float vec1X = 0;
190
    float vec1Y = 1;
191
    float vec1Z = 0;
192

    
193
    float vec2X = -z/cosB;
194
    float vec2Y = 0;
195
    float vec2Z = x/cosB;
196

    
197
    rotateVect(vec1X,vec1Y,vec1Z,sinA,cosA,off);
198
    rotateVect(vec2X,vec2Y,vec2Z,sinB,cosB,off);
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  private float[] createFacePosition(float vx, float vy, float vz, float scale, boolean inverted, float[] off)
204
    {
205
    float[] tmp = new float[3];
206
    tmp[0] = off[0];
207
    tmp[1] = off[1];
208
    tmp[2] = off[2];
209

    
210
    rotateFacePosition(vx,vy,vz,tmp);
211

    
212
    if( inverted )
213
      {
214
      tmp[0] = -tmp[0];
215
      tmp[1] = -tmp[1];
216
      tmp[2] = -tmp[2];
217
      }
218

    
219
    float[] ret = new float[3];
220

    
221
    ret[0] = scale*(vx+tmp[0]);
222
    ret[1] = scale*(vy+tmp[1]);
223
    ret[2] = scale*(vz+tmp[2]);
224

    
225
    return ret;
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
  private float[] createEdgePosition(int edge, int index, int N)
231
    {
232
    int[] edgeIndices = EDGE_INDICES[edge];
233
    int i0 = edgeIndices[0];
234
    int i1 = edgeIndices[1];
235

    
236
    float x = N*(VEC[i0][0]+VEC[i1][0])/2;
237
    float y = N*(VEC[i0][1]+VEC[i1][1])/2;
238
    float z = N*(VEC[i0][2]+VEC[i1][2])/2;
239

    
240
    return new float[] { x,y,z };
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  public float[][] getCubitPositions(int[] numLayers)
246
    {
247
    if( mPosition==null )
248
      {
249
      int N = numLayers[0];
250

    
251
      int numV = 12;
252
      int perF = N*(N-1)/2;
253
      int numF = 20*perF;
254
      int perE = N-2;
255
      int numE = 30*perE;
256

    
257
      mPosition = new float[numV+numF+numE][];
258

    
259
      for(int v=0; v<12; v++)
260
        mPosition[v] = new float[] { VEC[v][0]*N, VEC[v][1]*N, VEC[v][2]*N };
261

    
262
      float[][] off = new float[perF][];
263
      for(int i=0; i<perF; i++) off[i] = computeOff(i,N);
264

    
265
      for(int f=0; f<20; f++)
266
        {
267
        Static3D vect = TouchControlIcosahedron.FACE_AXIS[f];
268
        float x = vect.get0();
269
        float y = vect.get1();
270
        float z = vect.get2();
271
        boolean inverted = f>=10;
272

    
273
        for(int i=0; i<perF; i++)
274
          mPosition[12+f*perF+i] = createFacePosition(x,y,z,DIST3D*N,inverted,off[i]);
275
        }
276

    
277
      for(int e=0; e<30; e++)
278
        for(int i=0; i<perE; i++)
279
          mPosition[12+20*perF+e*perE+i] = createEdgePosition(e,i,N);
280
      }
281

    
282
    return mPosition;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  public Static4D getCubitQuats(int cubit, int[] numLayers)
288
    {
289
    if( mQuatIndex==null )
290
      {
291
      switch( numLayers[0] )
292
        {
293
        case 2: mQuatIndex = new int[]
294
                  {
295
                  0,12,5,9,13,8,14,18,7,6,10,55,
296

    
297
                  0,4,3,2,1,
298
                  6,11,32,14,26,
299
                  41,27,7,5,10,
300
                  35,18,45,33,15
301
                  };
302
                break;
303
        case 3: mQuatIndex = new int[]
304
                  {
305
                  0,12,5,9,13,8,14,18,7,6,10,55,
306

    
307
                  0,52,28,4,44,9,3,31,24,2,13,51,1,8,42,
308
                  21,30,6,16,11,49,54,32,39,48,14,23,37,43,26,
309
                  41,50,46,27,40,34,7,25,17,29,5,12,10,20,53,
310
                  56,38,35,58,22,18,57,47,45,55,36,33,59,19,15,
311

    
312
                  0,4,3,2,1,
313
                  5,20,31,13,8,
314
                  6,16,49,10,39,41,23,27,17,7,
315
                  14,22,30,11,19,
316
                  35,18,45,33,15
317
                  };
318
                break;
319
        }
320
      }
321

    
322
    return mObjectQuats[mQuatIndex[cubit]];
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  private float[][] getVertices(int variant)
328
    {
329
    float N = getNumLayers()[0];
330

    
331
    if( variant==0 )
332
      {
333
      float[] pos = mPosition[0];
334
      float[][] ret = new float[7][];
335
      for(int i=0; i<6; i++) ret[i] = new float[] { VEC[i][0]-pos[0], VEC[i][1]+(N-1)*VEC[0][1]-pos[1], VEC[i][2]-pos[2] };
336
      ret[6] = new float[] { -pos[0], -pos[1], -pos[2] };
337
      return ret;
338
      }
339
    else if( variant==1 )
340
      {
341
      float CX = mPosition[12][0];
342
      float CY = mPosition[12][1];
343
      float CZ = mPosition[12][2];
344

    
345
      float v1x = VEC[0][0]*(N-1)+VEC[2][0]; float v1y = VEC[0][1]*(N-1)+          VEC[2][1]; float v1z = VEC[0][2]*(N-1)+VEC[2][2];
346
      float v2x = VEC[2][0];                 float v2y = VEC[0][1]*(N-2)+VEC[1][1]+VEC[2][1]; float v2z = VEC[1][2]+VEC[2][2];
347
      float v3x = VEC[0][0]*(N-1)+VEC[1][0]; float v3y = VEC[0][1]*(N-1)+VEC[1][1]          ; float v3z = VEC[0][2]*(N-1)+VEC[1][2];
348

    
349
      return new float[][] { { v1x-CX, v1y-CY, v1z-CZ },
350
                             { v2x-CX, v2y-CY, v2z-CZ },
351
                             { v3x-CX, v3y-CY, v3z-CZ },
352
                             {    -CX,    -CY,    -CZ }
353
                           };
354
      }
355
    else
356
      {
357
      float[] pos = mPosition[72];
358

    
359
      float v1x = N*(VEC[0][0] + VEC[0][0] + VEC[1][0])/3; float v1y = N*(VEC[0][1] + VEC[0][1] + VEC[1][1])/3; float v1z = N*(VEC[0][2] + VEC[0][2] + VEC[1][2])/3;
360
      float v2x = N*(VEC[0][0] + VEC[1][0] + VEC[1][0])/3; float v2y = N*(VEC[0][1] + VEC[1][1] + VEC[1][1])/3; float v2z = N*(VEC[0][2] + VEC[1][2] + VEC[1][2])/3;
361
      float v3x = N*(VEC[0][0] + VEC[1][0] + VEC[2][0])/3; float v3y = N*(VEC[0][1] + VEC[1][1] + VEC[2][1])/3; float v3z = N*(VEC[0][2] + VEC[1][2] + VEC[2][2])/3;
362
      float v4x =-N*(VEC[0][0] + VEC[1][0] + VEC[2][0])/3; float v4y = N*(VEC[0][1] + VEC[1][1] + VEC[2][1])/3; float v4z = N*(VEC[0][2] + VEC[1][2] + VEC[2][2])/3;
363

    
364
      return new float[][] { { v1x-pos[0], v1y-pos[1], v1z-pos[2] },
365
                             { v2x-pos[0], v2y-pos[1], v2z-pos[2] },
366
                             { v3x-pos[0], v3y-pos[1], v3z-pos[2] },
367
                             { v4x-pos[0], v4y-pos[1], v4z-pos[2] },
368
                             {    -pos[0],    -pos[1],    -pos[2] }
369
                           };
370
      }
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  public ObjectShape getObjectShape(int variant)
376
    {
377
    if( variant==0 )
378
      {
379
      int[][] indices =
380
          {
381
              {1,2,0},{2,3,0},{3,4,0},{4,5,0},{5,1,0}, {6,2,1},{6,3,2},{6,4,3},{6,5,4},{6,1,5}
382
          };
383

    
384
      return new ObjectShape(getVertices(variant), indices);
385
      }
386
    else if( variant==1 )
387
      {
388
      int[][] indices =
389
          {
390
              {0,2,1},{0,1,3},{2,0,3},{1,2,3}
391
          };
392

    
393
      return new ObjectShape(getVertices(variant), indices);
394
      }
395
    else
396
      {
397
      int[][] indices =
398
          {
399
              {0,1,2},{0,3,1},{4,2,1},{4,0,2},{4,3,0},{4,1,3}
400
          };
401

    
402
      return new ObjectShape(getVertices(variant), indices);
403
      }
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public ObjectFaceShape getObjectFaceShape(int variant)
409
    {
410
    float N = getNumLayers()[0];
411
    int angle = 25;
412
    float R = 0.7f;
413
    float S = 0.5f;
414

    
415
    if( variant==0 )
416
      {
417
      int N1 = N==2 ? 5:4;
418
      int N2 = N==2 ? 3:2;
419
      float h1 = isInIconMode() ? 0.001f : 0.04f;
420
      float h2 = 0.001f;
421
      float[][] bands = { {h1,angle,R,S,N1,0,0}, {h2,angle,R,S,N2,0,0} };
422
      int[] indices   = { 0,0,0,0,0, 1,1,1,1,1,1 };
423
      return new ObjectFaceShape(bands,indices,null);
424
      }
425
    else if( variant==1 )
426
      {
427
      int N1 = N==2 ? 5:4;
428
      int N2 = N==2 ? 3:2;
429
      float h1 = isInIconMode() ? 0.001f : 0.04f;
430
      float h2 = 0.001f;
431
      float[][] bands = { {h1,angle,R,S,N1,0,0}, {h2,angle,R,S,N2,0,0} };
432
      int[] indices   = { 0,1,1,1 };
433
      return new ObjectFaceShape(bands,indices,null);
434
      }
435
    else
436
      {
437
      int N1 = N==2 ? 5:4;
438
      int N2 = N==2 ? 3:2;
439
      float h1 = isInIconMode() ? 0.001f : 0.04f;
440
      float h2 = 0.001f;
441
      float[][] bands = { {h1,angle,R,S,N1,0,0}, {h2,angle,R,S,N2,0,0} };
442
      int[] indices   = { 0,0,1,1,1,1 };
443
      return new ObjectFaceShape(bands,indices,null);
444
      }
445
    }
446

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

    
449
  public ObjectVertexEffects getVertexEffects(int variant)
450
    {
451
    if( variant==0 )
452
      {
453
      float[] pos = mPosition[0];
454
      float[][] corners  = { {0.04f,0.12f},{0.04f,0.10f} };
455
      int[] cornerIndices= { 0,1,1,1,1,1,-1 };
456
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
457
      int[] centerIndices= { 0,0,0,0,0,0,-1 };
458
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
459
      }
460
    else if( variant==1 )
461
      {
462
      float[] pos = mPosition[12];
463
      float[][] corners = { {0.04f,0.15f} };
464
      int[] indices     = { 0,0,0,-1 };
465
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
466
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
467
      }
468
    else
469
      {
470
      float[] pos = mPosition[72];
471
      float[][] corners = { {0.04f,0.15f} };
472
      int[] indices     = { 0,0,0,0,-1 };
473
      float[][] centers = { { -pos[0]/2, -pos[1]/2, -pos[2]/2} };
474
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
475
      }
476
    }
477

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

    
480
  public int getNumCubitVariants(int[] numLayers)
481
    {
482
    return getNumLayers()[0]==2 ? 2 : 3;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public int getCubitVariant(int cubit, int[] numLayers)
488
    {
489
    int N = getNumLayers()[0];
490
    return cubit<12 ? 0 : (cubit<10*N*(N-1)+12 ? 1 : 2);
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public float getStickerRadius()
496
    {
497
    return 0.09f;
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public float getStickerStroke()
503
    {
504
    return isInIconMode() ? 0.14f : 0.09f;
505
    }
506

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

    
509
  public float[][][] getStickerAngles()
510
    {
511
    return null;
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515
// PUBLIC API
516

    
517
  public Static3D[] getRotationAxis()
518
    {
519
    return ROT_AXIS;
520
    }
521

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

    
524
  public int[][] getBasicAngles()
525
    {
526
    if( mBasicAngle==null )
527
      {
528
      int num = getNumLayers()[0];
529
      int[] tmp = new int[num];
530
      for(int i=0; i<num; i++) tmp[i] = 5;
531
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp,tmp,tmp };
532
      }
533

    
534
    return mBasicAngle;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public String getShortName()
540
    {
541
    switch(getNumLayers()[0])
542
      {
543
      case 2: return ObjectType.ICOS_2.name();
544
      case 3: return ObjectType.ICOS_3.name();
545
      }
546

    
547
    return null;
548
    }
549

    
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551

    
552
  public ObjectSignature getSignature()
553
    {
554
    switch(getNumLayers()[0])
555
      {
556
      case 2: return new ObjectSignature(ObjectConstants.ICOS_2);
557
      case 3: return new ObjectSignature(ObjectConstants.ICOS_3);
558
      }
559

    
560
    return null;
561
    }
562

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

    
565
  public String getObjectName()
566
    {
567
    switch(getNumLayers()[0])
568
      {
569
      case 2: return "Icosamate";
570
      case 3: return "Master Icosamate";
571
      }
572
    return null;
573
    }
574

    
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576

    
577
  public String getInventor()
578
    {
579
    switch(getNumLayers()[0])
580
      {
581
      case 2: return "Jason Smith";
582
      case 3: return "Keisuke Maruyama";
583
      }
584
    return null;
585
    }
586

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

    
589
  public int getYearOfInvention()
590
    {
591
    switch(getNumLayers()[0])
592
      {
593
      case 2: return 2010;
594
      case 3: return 2018;
595
      }
596
    return 0;
597
    }
598

    
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600

    
601
  public int getComplexity()
602
    {
603
    return getNumLayers()[0]==2 ? 3 : 4;
604
    }
605

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

    
608
  public String[][] getTutorials()
609
    {
610
    int[] numLayers = getNumLayers();
611

    
612
    switch(numLayers[0])
613
      {
614
      case 2: return new String[][] {
615
                            {"gb","e7Es4Zx6Sl4","Icosamate introduction & algorithms","Superantoniovivaldi"},
616
                            {"gb","ZhkklbYfs98","Icosamate solve","Superantoniovivaldi"},
617
                            {"pl","eJTLTeoicWI","Icosamate TUTORIAL PL","MrUK"},
618
                            {"vn","RVjjxj9rPeg","BẠN PHẠM BẢO GIẢI ICOSAMATE","VĂN CÔNG TÙNG"},
619
                          };
620
      case 3: return new String[][] {
621
                            {"gb","77aBjBdfA2Q","Master Icosamate Algorithms","Superantoniovivaldi"},
622
                            {"gb","j6AIwlIofFU","Master Icosamate Tutorial","Superantoniovivaldi"},
623
                            {"gb","5Z1B5r6-CxM","Astrominx Tutorial","Jabberwock Technologies"},
624
                            {"pl","","Icosamate TUTORIAL PL","MrUK"},
625
                            {"vn","C4YO0B4rgTc","Tutorial N.237- Master Icosamate 1/3","Duy Thích Rubik"},
626
                            {"vn","90m_0AoyOHU","Tutorial N.237- Master Icosamate 2/3","Duy Thích Rubik"},
627
                            {"vn","LOd5qBwoP_k","Tutorial N.237- Master Icosamate 3/3","Duy Thích Rubik"},
628
                          };
629
      }
630

    
631
    return null;
632
    }
633
}
(25-25/57)