Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistySkewb.java @ 5d09301e

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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_HEXAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
14

    
15
import java.io.InputStream;
16

    
17
import org.distorted.library.type.Static3D;
18
import org.distorted.library.type.Static4D;
19

    
20
import org.distorted.objectlib.helpers.ObjectFaceShape;
21
import org.distorted.objectlib.helpers.ObjectSignature;
22
import org.distorted.objectlib.main.InitData;
23
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
24
import org.distorted.objectlib.main.ObjectType;
25
import org.distorted.objectlib.helpers.ObjectShape;
26
import org.distorted.objectlib.scrambling.ScrambleState;
27
import org.distorted.objectlib.main.ShapeHexahedron;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
public class TwistySkewb extends ShapeHexahedron
32
{
33
  static final Static3D[] ROT_AXIS = new Static3D[]
34
         {
35
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
36
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
37
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
38
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
39
         };
40

    
41
  private ScrambleState[] mStates;
42
  private int[][] mBasicAngle;
43
  private float[][] mCuts;
44
  private float[][] mPositions;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
  public TwistySkewb(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
49
    {
50
    super(data, meshState, iconMode, 2*data.getNumLayers()[0]-2, quat, move, scale, stream);
51
    }
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  public ScrambleState[] getScrambleStates()
56
    {
57
    if( mStates==null )
58
      {
59
      int[] numLayers = getNumLayers();
60
      int numL = numLayers[0];
61

    
62
      int[] tmp = {0,-1,0, 0,1,0, numL-1,-1,0, numL-1,1,0 };
63

    
64
      mStates = new ScrambleState[]
65
        {
66
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
67
        };
68
      }
69

    
70
    return mStates;
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  private int getNumCorners()
76
    {
77
    return 8;
78
    }
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

    
82
  private int getNumEdges(int numLayers)
83
    {
84
    return (numLayers-2)*12;
85
    }
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private int getNumCentersPerFace(int numLayers)
90
    {
91
    return ((numLayers-2)*(numLayers-2) + (numLayers-1)*(numLayers-1));
92
    }
93

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

    
96
  public float[][] getCuts(int[] numLayers)
97
    {
98
    if( mCuts==null )
99
      {
100
      float[] c = numLayers[0]==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/6,+SQ3/6});
101
      mCuts = new float[][] {c,c,c,c};
102
      }
103

    
104
    return mCuts;
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
  public boolean[][] getLayerRotatable(int[] numLayers)
110
    {
111
    boolean[] tmp = numLayers[0]==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
112
    return new boolean[][] { tmp,tmp,tmp,tmp };
113
    }
114

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

    
117
  public int getTouchControlType()
118
    {
119
    return TC_HEXAHEDRON;
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  public int getTouchControlSplit()
125
    {
126
    return TYPE_SPLIT_CORNER;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  public int[][][] getEnabled()
132
    {
133
    return new int[][][]
134
      {
135
          {{0,1},{3,1},{2,3},{0,2}},
136
          {{2,3},{3,1},{0,1},{0,2}},
137
          {{1,2},{0,1},{0,3},{2,3}},
138
          {{1,2},{2,3},{0,3},{0,1}},
139
          {{0,3},{0,2},{1,2},{1,3}},
140
          {{1,2},{0,2},{0,3},{1,3}},
141
      };
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  public float[] getDist3D(int[] numLayers)
147
    {
148
    return TouchControlHexahedron.D3D;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  public Static3D[] getFaceAxis()
154
    {
155
    return TouchControlHexahedron.FACE_AXIS;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  public float[][] getCubitPositions(int[] numLayers)
161
    {
162
    if( mPositions==null )
163
      {
164
      int numL = numLayers[0];
165
      final float DIST_CORNER = numL-1;
166
      final float DIST_EDGE   = numL-1;
167
      final float DIST_CENTER = numL-1;
168

    
169
      final int numCorners = getNumCorners();
170
      final int numEdges   = getNumEdges(numL);
171
      final int numCenters = 6*getNumCentersPerFace(numL);
172

    
173
      mPositions = new float[numCorners+numEdges+numCenters][];
174

    
175
      /// CORNERS //////////////////////////////////////////////
176

    
177
      mPositions[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
178
      mPositions[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
179
      mPositions[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
180
      mPositions[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
181
      mPositions[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
182
      mPositions[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
183
      mPositions[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
184
      mPositions[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
185

    
186
      /// CENTERS //////////////////////////////////////////////
187

    
188
      int index=8;
189
      final float X= -1000.0f;
190
      final float Y= -1001.0f;
191

    
192
      final float[][]  centerTable =
193
        {
194
            {X,Y,+DIST_CENTER},
195
            {X,Y,-DIST_CENTER},
196
            {X,+DIST_CENTER,Y},
197
            {X,-DIST_CENTER,Y},
198
            {+DIST_CENTER,X,Y},
199
            {-DIST_CENTER,X,Y},
200
        };
201

    
202
      float x,y, cen0, cen1, cen2;
203

    
204
      for( float[] centers : centerTable )
205
        {
206
        x = 2-numL;
207

    
208
        for(int i=0; i<numL-1; i++, x+=2)
209
          {
210
          y = 2-numL;
211

    
212
          for(int j=0; j<numL-1; j++, y+=2, index++)
213
            {
214
                 if( centers[0]==Y ) cen0 = y;
215
            else if( centers[0]==X ) cen0 = x;
216
            else                     cen0 = centers[0];
217

    
218
                 if( centers[1]==Y ) cen1 = y;
219
            else if( centers[1]==X ) cen1 = x;
220
            else                     cen1 = centers[1];
221

    
222
                 if( centers[2]==Y ) cen2 = y;
223
            else if( centers[2]==X ) cen2 = x;
224
            else                     cen2 = centers[2];
225

    
226
            mPositions[index] = new float[] {cen0,cen1,cen2};
227
            }
228
          }
229

    
230
        x = 3-numL;
231

    
232
        for(int i=0; i<numL-2; i++, x+=2)
233
          {
234
          y = 3-numL;
235

    
236
          for(int j=0; j<numL-2; j++, y+=2, index++)
237
            {
238
                 if( centers[0]==Y ) cen0 = y;
239
            else if( centers[0]==X ) cen0 = x;
240
            else                     cen0 = centers[0];
241

    
242
                 if( centers[1]==Y ) cen1 = y;
243
            else if( centers[1]==X ) cen1 = x;
244
            else                     cen1 = centers[1];
245

    
246
                 if( centers[2]==Y ) cen2 = y;
247
            else if( centers[2]==X ) cen2 = x;
248
            else                     cen2 = centers[2];
249

    
250
            mPositions[index] = new float[] {cen0,cen1,cen2};
251
            }
252
          }
253
        }
254

    
255
      /// EDGES ///////////////////////////////////////////////
256

    
257
      final float[][]  edgeTable =
258
        {
259
            {0,+DIST_EDGE,+DIST_EDGE},
260
            {+DIST_EDGE,0,+DIST_EDGE},
261
            {0,-DIST_EDGE,+DIST_EDGE},
262
            {-DIST_EDGE,0,+DIST_EDGE},
263
            {+DIST_EDGE,+DIST_EDGE,0},
264
            {+DIST_EDGE,-DIST_EDGE,0},
265
            {-DIST_EDGE,-DIST_EDGE,0},
266
            {-DIST_EDGE,+DIST_EDGE,0},
267
            {0,+DIST_EDGE,-DIST_EDGE},
268
            {+DIST_EDGE,0,-DIST_EDGE},
269
            {0,-DIST_EDGE,-DIST_EDGE},
270
            {-DIST_EDGE,0,-DIST_EDGE}
271
        };
272

    
273
      for (float[] edges : edgeTable)
274
        {
275
        float c = 3-numL;
276

    
277
        for (int j=0; j<numL-2; j++, c+=2, index++)
278
          {
279
          mPositions[index] = new float[] { edges[0]==0 ? c : edges[0] ,
280
                                            edges[1]==0 ? c : edges[1] ,
281
                                            edges[2]==0 ? c : edges[2] };
282
          }
283
        }
284
      }
285

    
286
    return mPositions;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  public Static4D getCubitQuats(int cubit, int[] numLayers)
292
    {
293
    int numL = numLayers[0];
294
    int numCorners = getNumCorners();
295
    int numCentersPerFace = getNumCentersPerFace(numL);
296
    int numCenters = 6*numCentersPerFace;
297

    
298
    if( cubit<numCorners )
299
      {
300
      switch(cubit)
301
        {
302
        case  0: return mObjectQuats[0];                   //  unit quat
303
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
304
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
305
        case  3: return mObjectQuats[9];                   // 180 along X
306
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
307
        case  5: return mObjectQuats[11];                  // 180 along Y
308
        case  6: return mObjectQuats[10];                  // 180 along Z
309
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
310
        }
311
      }
312
    else if( cubit<numCorners+numCenters )
313
      {
314
      int center = (cubit-numCorners)/numCentersPerFace;
315

    
316
      switch(center)
317
        {
318
        case 0: return mObjectQuats[0];
319
        case 1: return mObjectQuats[9];
320
        case 2: return mObjectQuats[1];
321
        case 3: return mObjectQuats[4];
322
        case 4: return mObjectQuats[2];
323
        case 5: return mObjectQuats[3];
324
        }
325
      }
326
    else
327
      {
328
      int edge = (cubit-numCorners-numCenters)/(numL-2);
329

    
330
      switch(edge)
331
        {
332
        case  0: return mObjectQuats[ 0];
333
        case  1: return mObjectQuats[ 2];
334
        case  2: return mObjectQuats[10];
335
        case  3: return mObjectQuats[ 8];
336
        case  4: return mObjectQuats[ 1];
337
        case  5: return mObjectQuats[ 4];
338
        case  6: return mObjectQuats[ 6];
339
        case  7: return mObjectQuats[ 7];
340
        case  8: return mObjectQuats[11];
341
        case  9: return mObjectQuats[ 5];
342
        case 10: return mObjectQuats[ 9];
343
        case 11: return mObjectQuats[ 3];
344
        }
345
      }
346

    
347
    return null;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  public ObjectShape getObjectShape(int variant)
353
    {
354
    if( variant==0 )
355
      {
356
      float[][] vertices= { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
357
      int[][] indices   = { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
358
      return new ObjectShape(vertices, indices);
359
      }
360
    else if( variant==1 )
361
      {
362
      float[][] vertices= { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
363
      int[][] indices   = { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
364
      return new ObjectShape(vertices, indices);
365
      }
366
    else
367
      {
368
      float[][] vertices= { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
369
      int[][] indices   = { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
370
      return new ObjectShape(vertices, indices);
371
      }
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  public ObjectFaceShape getObjectFaceShape(int variant)
377
    {
378
    int numL = getNumLayers()[0];
379

    
380
    if( variant==0 )
381
      {
382
      int N = numL==2 ? 7:5;
383
      int E1= numL==2 ? 3:2;
384
      int E2= numL==2 ? 5:3;
385
      float height = isInIconMode() ? 0.001f : 0.02f;
386
      float[][] bands     = { {height,35,0.16f,0.7f,N,E1,E1}, {0.001f, 35,1.00f,0.0f,3,1,E2} };
387
      int[] bandIndices   = { 0,0,0,1,1,1 };
388
      float[][] corners   = { {0.05f,0.25f}, {0.05f,0.20f} };
389
      int[] cornerIndices = { 1,1,1,0,0 };
390
      float[][] centers   = { {-0.5f, -0.5f, -0.5f} };
391
      int[] centerIndices = { 0,0,0,-1,0 };
392
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
393
      }
394
    else if( variant==1 )
395
      {
396
      int N = numL==2 ? 7:6;
397
      int E = numL==2 ? 3:1;
398
      float height = isInIconMode() ? 0.001f : 0.04f;
399
      float[][] bands     = { {height,35,SQ2/8,0.9f,N,E,E}, {0.001f,35,1,0.0f,3,0,0} };
400
      int[] bandIndices   = { 0,1,1,1,1 };
401
      float[][] corners   = { {0.06f,0.15f} };
402
      int[] cornerIndices = { 0,0,0,0,0 };
403
      float[][] centers   = { {0,0,-0.4f} };
404
      int[] centerIndices = { 0,0,0,0,-1 };
405
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
406
      }
407
    else
408
      {
409
      int N = numL==2 ? 7:5;
410
      int E = numL==2 ? 5:2;
411
      float h1 = isInIconMode() ? 0.001f : 0.035f;
412
      float h2 = isInIconMode() ? 0.001f : 0.020f;
413
      float[][] bands     = { {h1,30,0.16f,0.8f,N,2,E}, {h2,45,0.16f,0.2f,3,1,2} };
414
      int[] bandIndices   = { 0,0,1,1 };
415
      float[][] corners   = { {0.07f,0.20f}, {0.02f,0.30f} };
416
      int[] cornerIndices = { 0,0,1,1 };
417
      float[][] centers   = { {0.0f, -0.5f, -0.5f} };
418
      int[] centerIndices = { 0,0,0,0 };
419
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
420
      }
421
    }
422

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

    
425
  public int getNumCubitVariants(int[] numLayers)
426
    {
427
    return numLayers[0]==2 ? 2:3;
428
    }
429

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

    
432
  public int getCubitVariant(int cubit, int[] numLayers)
433
    {
434
    return cubit<8 ? 0 : (cubit<8+6*getNumCentersPerFace(numLayers[0]) ? 1:2);
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public float getStickerRadius()
440
    {
441
    return 0.08f;
442
    }
443

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

    
446
  public float getStickerStroke()
447
    {
448
    float stroke = 0.08f;
449

    
450
    if( isInIconMode() )
451
      {
452
      int[] numLayers = getNumLayers();
453
      stroke *= (numLayers[0]==2 ? 2.0f : 2.7f);
454
      }
455

    
456
    return stroke;
457
    }
458

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

    
461
  public float[][] getStickerAngles()
462
    {
463
    return null;
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
// PUBLIC API
468

    
469
  public Static3D[] getRotationAxis()
470
    {
471
    return ROT_AXIS;
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public int[][] getBasicAngles()
477
    {
478
    if( mBasicAngle ==null )
479
      {
480
      int num = getNumLayers()[0];
481
      int[] tmp = new int[num];
482
      for(int i=0; i<num; i++) tmp[i] = 3;
483
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
484
      }
485

    
486
    return mBasicAngle;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  public String getShortName()
492
    {
493
    switch(getNumLayers()[0])
494
      {
495
      case 2: return ObjectType.SKEW_2.name();
496
      case 3: return ObjectType.SKEW_3.name();
497
      }
498

    
499
    return ObjectType.SKEW_2.name();
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
  public ObjectSignature getSignature()
505
    {
506
    switch(getNumLayers()[0])
507
      {
508
      case 2: return new ObjectSignature(ObjectType.SKEW_2);
509
      case 3: return new ObjectSignature(ObjectType.SKEW_3);
510
      }
511

    
512
    return null;
513
    }
514

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

    
517
  public String getObjectName()
518
    {
519
    switch(getNumLayers()[0])
520
      {
521
      case 2: return "Skewb";
522
      case 3: return "Master Skewb";
523
      }
524
    return null;
525
    }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

    
529
  public String getInventor()
530
    {
531
    switch(getNumLayers()[0])
532
      {
533
      case 2: return "Tony Durham";
534
      case 3: return "Katsuhiko Okamoto";
535
      }
536
    return null;
537
    }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

    
541
  public int getYearOfInvention()
542
    {
543
    switch(getNumLayers()[0])
544
      {
545
      case 2: return 1982;
546
      case 3: return 2003;
547
      }
548
    return 1982;
549
    }
550

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

    
553
  public int getComplexity()
554
    {
555
    switch(getNumLayers()[0])
556
      {
557
      case 2: return 1;
558
      case 3: return 3;
559
      }
560
    return 5;
561
    }
562

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

    
565
  public String[][] getTutorials()
566
    {
567
    int[] numLayers = getNumLayers();
568

    
569
    switch(numLayers[0])
570
      {
571
      case 2: return new String[][] {
572
                          {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
573
                          {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
574
                          {"ru","EICw3aqn6Bc","Как собрать Скьюб?","Алексей Ярыгин"},
575
                          {"fr","lR-GuIroh4k","Comment réussir le skewb","Rachma Nikov"},
576
                          {"de","7RX6D5pznOk","Skewb lösen","Pezcraft"},
577
                          {"pl","ofRu1fByNpk","Jak ułożyć: Skewb","DżoDżo"},
578
                          {"br","mNycauwshWs","Como resolver o Skewb","Pedro Filho"},
579
                          {"kr","5R3sU-_bMAI","SKEWB 초보 공식","iamzoone"},
580
                          {"vn","Db5mXuqgQP8","Tutorial N.5 - Skewb","Duy Thích Rubik"},
581
                     //   {"tw","8srf9xhsS9k","Skewb斜轉方塊解法","1hrBLD"},
582
                         };
583
      case 3: return new String[][] {
584
                          {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
585
                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
586
                          {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
587
                          {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
588
                          {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
589
                          {"ru","UnsvseFBXmo","часть 3: Как собрать мастер Скьюб","Иван Циков"},
590
                          {"fr","tYMoY4EOHVA","Résolution du Master Skewb","Asthalis"},
591
                          {"de","LSErzqGNElI","Master Skewb lösen","JamesKnopf"},
592
                          {"pl","Y7l3AYFvDJI","Master Skewb TUTORIAL PL","MrUk"},
593
                          {"kr","ycR-WmXJCG0","마스터 스큐브 3번째 해법","듀나메스 큐브 해법연구소"},
594
                          {"vn","uG8H0ZQTZgw","Tutorial N.35 - Master Skewb","Duy Thích Rubik"},
595
                         };
596
      }
597
    return null;
598
    }
599
}
(28-28/36)