Project

General

Profile

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

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

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.helpers.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.main.ObjectSignatures;
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 meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
54
    {
55
    super(meshState, 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

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

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

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

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  public int getNumCubitVariants(int[] numLayers)
478
    {
479
    return getNumLayers()[0]==2 ? 2 : 3;
480
    }
481

    
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

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

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public float getStickerRadius()
493
    {
494
    return 0.09f;
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  public float getStickerStroke()
500
    {
501
    return isInIconMode() ? 0.14f : 0.09f;
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public float[][] getStickerAngles()
507
    {
508
    return null;
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512
// PUBLIC API
513

    
514
  public Static3D[] getRotationAxis()
515
    {
516
    return ROT_AXIS;
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

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

    
531
    return mBasicAngle;
532
    }
533

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

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

    
544
    return null;
545
    }
546

    
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548

    
549
  public ObjectSignature getSignature()
550
    {
551
    switch(getNumLayers()[0])
552
      {
553
      case 2: return new ObjectSignature(ObjectSignatures.ICOS_2);
554
      case 3: return new ObjectSignature(ObjectSignatures.ICOS_3);
555
      }
556

    
557
    return null;
558
    }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

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

    
572
///////////////////////////////////////////////////////////////////////////////////////////////////
573

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

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

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

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

    
598
  public int getComplexity()
599
    {
600
    return getNumLayers()[0]==2 ? 3 : 4;
601
    }
602

    
603
///////////////////////////////////////////////////////////////////////////////////////////////////
604

    
605
  public String[][] getTutorials()
606
    {
607
    int[] numLayers = getNumLayers();
608

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

    
628
    return null;
629
    }
630
}
(17-17/42)