Project

General

Profile

Download (19.6 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ efa81f0c

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objects;
21

    
22
import android.content.res.Resources;
23

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
import org.distorted.main.R;
33

    
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

    
36
public class TwistySkewb extends Twisty6
37
{
38
  static final Static3D[] ROT_AXIS = new Static3D[]
39
         {
40
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
41
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
42
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
43
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
44
         };
45

    
46
  private ScrambleState[] mStates;
47
  private int[] mBasicAngle;
48
  private Static4D[] mQuats;
49
  private int[][] mCornerMap,mEdgeMap,mCenterMap;
50
  private ObjectSticker[] mStickers;
51
  private Movement mMovement;
52

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

    
55
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
56
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
57
    {
58
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
59
    }
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  ScrambleState[] getScrambleStates()
64
    {
65
    if( mStates==null )
66
      {
67
      int size = getNumLayers();
68
      int[] tmp = {0,-1,0, 0,1,0, size-1,-1,0, size-1,1,0 };
69

    
70
      mStates = new ScrambleState[]
71
        {
72
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
73
        };
74
      }
75

    
76
    return mStates;
77
    }
78

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

    
81
  private void initializeQuats()
82
    {
83
    mQuats = new Static4D[]
84
         {
85
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
86
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
87
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
88
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
89

    
90
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
91
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
92
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
93
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
94
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
95
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
96
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
97
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
98
         };
99
    }
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

    
103
  int[] getSolvedQuats(int cubit, int numLayers)
104
    {
105
    if( mQuats==null ) initializeQuats();
106
    int status = retCubitSolvedStatus(cubit,numLayers);
107
    return status<0 ? null : buildSolvedQuats(MovementCornerTwisting.FACE_AXIS[status],mQuats);
108
    }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
  private int getNumCorners()
113
    {
114
    return 8;
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  private int getNumEdges(int layers)
120
    {
121
    return (layers-2)*12;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  private int getNumCentersPerFace(int layers)
127
    {
128
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
129
    }
130

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

    
133
  Static4D[] getQuats()
134
    {
135
    if( mQuats==null ) initializeQuats();
136
    return mQuats;
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  int getSolvedFunctionIndex()
142
    {
143
    return 0;
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  int getNumStickerTypes(int numLayers)
149
    {
150
    return 3;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  float[][] getCuts(int numLayers)
156
    {
157
    switch(numLayers)
158
      {
159
      case 2: float[] c2 = new float[] {0.0f};
160
              return new float[][] { c2,c2,c2,c2 };
161
      case 3: float[] c3 = new float[] {-SQ3/6,+SQ3/6};
162
              return new float[][] { c3,c3,c3,c3 };
163
      }
164
    return null;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  int getNumCubitFaces()
170
    {
171
    return 6;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  float[][] getCubitPositions(int numLayers)
177
    {
178
    final float DIST_CORNER = numLayers-1;
179
    final float DIST_EDGE   = numLayers-1;
180
    final float DIST_CENTER = numLayers-1;
181

    
182
    final int numCorners = getNumCorners();
183
    final int numEdges   = getNumEdges(numLayers);
184
    final int numCenters = 6*getNumCentersPerFace(numLayers);
185

    
186
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
187

    
188
    /// CORNERS //////////////////////////////////////////////
189

    
190
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
191
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
192
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
193
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
194
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
195
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
196
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
197
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
198

    
199
    /// EDGES ///////////////////////////////////////////////
200

    
201
    final float[][]  edgeTable =
202
        {
203
            {0,+DIST_EDGE,+DIST_EDGE},
204
            {+DIST_EDGE,0,+DIST_EDGE},
205
            {0,-DIST_EDGE,+DIST_EDGE},
206
            {-DIST_EDGE,0,+DIST_EDGE},
207
            {+DIST_EDGE,+DIST_EDGE,0},
208
            {+DIST_EDGE,-DIST_EDGE,0},
209
            {-DIST_EDGE,-DIST_EDGE,0},
210
            {-DIST_EDGE,+DIST_EDGE,0},
211
            {0,+DIST_EDGE,-DIST_EDGE},
212
            {+DIST_EDGE,0,-DIST_EDGE},
213
            {0,-DIST_EDGE,-DIST_EDGE},
214
            {-DIST_EDGE,0,-DIST_EDGE}
215
        };
216

    
217
    int index=8;
218

    
219
    for (float[] edges : edgeTable)
220
      {
221
      float c = 3-numLayers;
222

    
223
      for (int j=0; j<numLayers-2; j++, c+=2, index++)
224
        {
225
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
226
                                       edges[1]==0 ? c : edges[1] ,
227
                                       edges[2]==0 ? c : edges[2] };
228
        }
229
      }
230

    
231
    /// CENTERS //////////////////////////////////////////////
232

    
233
    final float X= -1000.0f;
234
    final float Y= -1001.0f;
235

    
236
    final float[][]  centerTable =
237
        {
238
            {+DIST_CENTER,X,Y},
239
            {-DIST_CENTER,X,Y},
240
            {X,+DIST_CENTER,Y},
241
            {X,-DIST_CENTER,Y},
242
            {X,Y,+DIST_CENTER},
243
            {X,Y,-DIST_CENTER}
244
        };
245

    
246
    float x,y, cen0, cen1, cen2;
247

    
248
    for( float[] centers : centerTable )
249
      {
250
      x = 2-numLayers;
251

    
252
      for(int i=0; i<numLayers-1; i++, x+=2)
253
        {
254
        y = 2-numLayers;
255

    
256
        for(int j=0; j<numLayers-1; j++, y+=2, index++)
257
          {
258
               if( centers[0]==Y ) cen0 = y;
259
          else if( centers[0]==X ) cen0 = x;
260
          else                     cen0 = centers[0];
261

    
262
               if( centers[1]==Y ) cen1 = y;
263
          else if( centers[1]==X ) cen1 = x;
264
          else                     cen1 = centers[1];
265

    
266
               if( centers[2]==Y ) cen2 = y;
267
          else if( centers[2]==X ) cen2 = x;
268
          else                     cen2 = centers[2];
269

    
270
          CENTERS[index] = new float[] {cen0,cen1,cen2};
271
          }
272
        }
273

    
274
      x = 3-numLayers;
275

    
276
      for(int i=0; i<numLayers-2; i++, x+=2)
277
        {
278
        y = 3-numLayers;
279

    
280
        for(int j=0; j<numLayers-2; j++, y+=2, index++)
281
          {
282
               if( centers[0]==Y ) cen0 = y;
283
          else if( centers[0]==X ) cen0 = x;
284
          else                     cen0 = centers[0];
285

    
286
               if( centers[1]==Y ) cen1 = y;
287
          else if( centers[1]==X ) cen1 = x;
288
          else                     cen1 = centers[1];
289

    
290
               if( centers[2]==Y ) cen2 = y;
291
          else if( centers[2]==X ) cen2 = x;
292
          else                     cen2 = centers[2];
293

    
294
          CENTERS[index] = new float[] {cen0,cen1,cen2};
295
          }
296
        }
297
      }
298

    
299
    return CENTERS;
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  Static4D getQuat(int cubit, int numLayers)
305
    {
306
    if( mQuats==null ) initializeQuats();
307
    int numCorners = getNumCorners();
308
    int numEdges   = getNumEdges(numLayers);
309

    
310
    if( cubit<numCorners )
311
      {
312
      switch(cubit)
313
        {
314
        case  0: return mQuats[0];                         //  unit quat
315
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
316
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
317
        case  3: return mQuats[1];                         // 180 along X
318
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
319
        case  5: return mQuats[2];                         // 180 along Y
320
        case  6: return mQuats[3];                         // 180 along Z
321
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
322
        }
323
      }
324
    else if( cubit<numCorners+numEdges )
325
      {
326
      int edge = (cubit-numCorners)/(numLayers-2);
327

    
328
      switch(edge)
329
        {
330
        case  0: return mQuats[ 0];
331
        case  1: return mQuats[ 5];
332
        case  2: return mQuats[ 3];
333
        case  3: return mQuats[11];
334
        case  4: return mQuats[ 4];
335
        case  5: return mQuats[ 7];
336
        case  6: return mQuats[ 9];
337
        case  7: return mQuats[10];
338
        case  8: return mQuats[ 2];
339
        case  9: return mQuats[ 8];
340
        case 10: return mQuats[ 1];
341
        case 11: return mQuats[ 6];
342
        }
343
      }
344
    else
345
      {
346
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
347

    
348
      switch(center)
349
        {
350
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
351
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
352
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
353
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
354
        case 4: return mQuats[0];                         //  unit quaternion
355
        case 5: return mQuats[1];                         // 180 along X
356
        }
357
      }
358

    
359
    return null;
360
    }
361

    
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

    
364
  ObjectShape getObjectShape(int cubit, int numLayers)
365
    {
366
    int variant = getCubitVariant(cubit,numLayers);
367

    
368
    if( variant==0 )
369
      {
370
      double[][] vertices = new double[][] { {-1,0,0},{0,-1,0},{0,0,-1},{-1,-1,-1},{0,0,0} };
371
      int[][] vert_indices = new int[][] { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
372
      int N = numLayers==2 ? 7:5;
373
      int E1= numLayers==2 ? 3:2;
374
      int E2= numLayers==2 ? 5:3;
375
      float[][] bands     = new float[][] { {0.020f,35,0.16f,0.7f,N,E1,E1}, {0.000f, 0,1.00f,0.0f,3,1,E2} };
376
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
377
      float[][] corners   = new float[][] { {0.05f,0.25f}, {0.05f,0.20f} };
378
      int[] cornerIndices = new int[] { 1,1,1,0,0 };
379
      float[][] centers   = new float[][] { {-0.5f, -0.5f, -0.5f} };
380
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
381
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
382
      }
383
    else if( variant==1 )
384
      {
385
      double[][] vertices = new double[][] { {-1,0,0},{1,0,0},{0,-1,0},{0,0,-1} };
386
      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
387
      int N = numLayers==2 ? 7:5;
388
      int E = numLayers==2 ? 5:2;
389
      float[][] bands     = new float[][] { {0.035f,30,0.16f,0.8f,N,2,E}, {0.020f,45,0.16f,0.2f,3,1,2} };
390
      int[] bandIndices   = new int[] { 0,0,1,1 };
391
      float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
392
      int[] cornerIndices = new int[] { 0,0,1,1 };
393
      float[][] centers   = new float[][] { {0.0f, -0.5f, -0.5f} };
394
      int[] centerIndices = new int[] { 0,0,0,0 };
395
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
396
      }
397
    else
398
      {
399
      double[][] vertices = new double[][] { {-1,0,0},{0,-1,0},{1,0,0},{0,1,0},{0,0,-1} };
400
      int[][] vert_indices = new int[][] { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
401
      int N = numLayers==2 ? 7:6;
402
      int E = numLayers==2 ? 3:1;
403
      float[][] bands     = new float[][] { {0.04f,35,SQ2/8,0.9f,N,E,E}, {0.000f,0,1,0.0f,3,0,0} };
404
      int[] bandIndices   = new int[] { 0,1,1,1,1 };
405
      float[][] corners   = new float[][] { {0.06f,0.15f} };
406
      int[] cornerIndices = new int[] { 0,0,0,0,0 };
407
      float[][] centers   = new float[][] { {0,0,-0.4f} };
408
      int[] centerIndices = new int[] { 0,0,0,0,-1 };
409
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
410
      }
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  int getNumCubitVariants(int numLayers)
416
    {
417
    return 3;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  int getCubitVariant(int cubit, int numLayers)
423
    {
424
    int numCorners = getNumCorners();
425
    if( cubit<numCorners ) return 0;
426
    int numEdges = getNumEdges(numLayers);
427
    return cubit<numCorners+numEdges ? 1:2;
428
    }
429

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

    
432
  int getFaceColor(int cubit, int cubitface, int numLayers)
433
    {
434
    if( mCornerMap==null || mEdgeMap==null || mCenterMap==null )
435
      {
436
      mCornerMap = new int[][]
437
         {
438
           {  4, 2, 0, 18,18,18 },
439
           {  2, 5, 0, 18,18,18 },
440
           {  3, 4, 0, 18,18,18 },
441
           {  5, 3, 0, 18,18,18 },
442
           {  1, 2, 4, 18,18,18 },
443
           {  5, 2, 1, 18,18,18 },
444
           {  4, 3, 1, 18,18,18 },
445
           {  1, 3, 5, 18,18,18 },
446
         };
447

    
448
      mEdgeMap = new int[][]
449
         {
450
           { 10, 8, 18,18,18,18 },
451
           {  6,10, 18,18,18,18 },
452
           { 10, 9, 18,18,18,18 },
453
           {  7,10, 18,18,18,18 },
454
           {  8, 6, 18,18,18,18 },
455
           {  9, 6, 18,18,18,18 },
456
           {  9, 7, 18,18,18,18 },
457
           {  8, 7, 18,18,18,18 },
458
           { 11, 8, 18,18,18,18 },
459
           {  6,11, 18,18,18,18 },
460
           { 11, 9, 18,18,18,18 },
461
           {  7,11, 18,18,18,18 }
462
         };
463

    
464
      mCenterMap = new int[][]
465
         {
466
           { 12, 18,18,18,18,18 },
467
           { 13, 18,18,18,18,18 },
468
           { 14, 18,18,18,18,18 },
469
           { 15, 18,18,18,18,18 },
470
           { 16, 18,18,18,18,18 },
471
           { 17, 18,18,18,18,18 },
472
         };
473
      }
474

    
475
    int numCorners = getNumCorners();
476
    int numEdges   = getNumEdges(numLayers);
477

    
478
    if( cubit<numCorners )
479
      {
480
      return mCornerMap[cubit][cubitface];
481
      }
482
    else if( cubit<numCorners+numEdges )
483
      {
484
      int edge = (cubit-numCorners)/(numLayers-2);
485
      return mEdgeMap[edge][cubitface];
486
      }
487
    else
488
      {
489
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
490
      return mCenterMap[center][cubitface];
491
      }
492
    }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495

    
496
  ObjectSticker retSticker(int face)
497
    {
498
    if( mStickers==null )
499
      {
500
      float[][] STICKERS = new float[][]
501
          {
502
             { -0.5f, 0.25f, 0.25f,  -0.5f, 0.25f, 0.25f  },
503
             { -0.5f, 0.00f, 0.00f,  -0.5f, 0.50f, 0.0f, 0.0f, 0.5f }
504
          };
505

    
506
      final float R1 = 0.025f;
507
      final float R2 = 0.025f;
508
      final float R3 = 0.055f;
509
      final float[][] radii  = { { R1,R1,R1 },{ R2,R2,R2 },{ R3,R3,R3,R3 } };
510
      final float[] strokes = { 0.045f, 0.035f, 0.035f };
511

    
512
      mStickers = new ObjectSticker[STICKERS.length+1];
513

    
514
      for(int s=0; s<STICKERS.length+1; s++)
515
        {
516
        int index = s<2 ? 0:1;
517
        mStickers[s] = new ObjectSticker(STICKERS[index],null,radii[s],strokes[s]);
518
        }
519
      }
520

    
521
    return mStickers[face/NUM_FACE_COLORS];
522
    }
523

    
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525
// PUBLIC API
526

    
527
  public Static3D[] getRotationAxis()
528
    {
529
    return ROT_AXIS;
530
    }
531

    
532
///////////////////////////////////////////////////////////////////////////////////////////////////
533

    
534
  public Movement getMovement()
535
    {
536
    if( mMovement==null ) mMovement = new MovementCornerTwisting();
537
    return mMovement;
538
    }
539

    
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541

    
542
  public int[] getBasicAngle()
543
    {
544
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
545
    return mBasicAngle;
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549

    
550
  public int getObjectName(int numLayers)
551
    {
552
    switch(numLayers)
553
      {
554
      case 2: return R.string.skew2;
555
      case 3: return R.string.skew3;
556
      }
557
    return R.string.skew2;
558
    }
559

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

    
562
  public int getInventor(int numLayers)
563
    {
564
    switch(numLayers)
565
      {
566
      case 2: return R.string.skew2_inventor;
567
      case 3: return R.string.skew3_inventor;
568
      }
569
    return R.string.skew2_inventor;
570
    }
571

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

    
574
  public int getComplexity(int numLayers)
575
    {
576
    switch(numLayers)
577
      {
578
      case 2: return 4;
579
      case 3: return 8;
580
      }
581
    return 5;
582
    }
583
}
(44-44/48)