Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyUltimate.java @ 29bc084f

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.R;
36

    
37
import java.util.Random;
38

    
39
import static org.distorted.objects.TwistyMinx.MINX_DBLUE;
40
import static org.distorted.objects.TwistyMinx.MINX_DGREEN;
41
import static org.distorted.objects.TwistyMinx.MINX_DRED;
42
import static org.distorted.objects.TwistyMinx.MINX_DYELLOW;
43
import static org.distorted.objects.TwistyMinx.MINX_GREY;
44
import static org.distorted.objects.TwistyMinx.MINX_LBLUE;
45
import static org.distorted.objects.TwistyMinx.MINX_LGREEN;
46
import static org.distorted.objects.TwistyMinx.MINX_ORANGE;
47
import static org.distorted.objects.TwistyMinx.MINX_PINK;
48
import static org.distorted.objects.TwistyMinx.MINX_SANDY;
49
import static org.distorted.objects.TwistyMinx.MINX_VIOLET;
50
import static org.distorted.objects.TwistyMinx.MINX_WHITE;
51

    
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

    
54
class TwistyUltimate extends TwistyObject
55
{
56
  private static final float A = (float)Math.sqrt(21*SQ5+47);
57
  private static final float B = SQ6*(5*SQ5+11)/(6*A);
58
  private static final float C = SQ6*(  SQ5+ 2)/(3*A);
59
  private static final float D = SQ3/3;
60
  private static final float E = (SQ5+1)/4;
61
  private static final float F = (SQ5-1)/4;
62
  private static final float G = (SQ5+3)/4;
63

    
64
  static final Static3D[] ROT_AXIS = new Static3D[]
65
         {
66
           new Static3D( B,0,C ),
67
           new Static3D( C,B,0 ),
68
           new Static3D(-D,D,D ),
69
           new Static3D( 0,C,-B)
70
         };
71

    
72
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
73

    
74
  private static final int[] FACE_COLORS = new int[]
75
         {
76
           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
77
           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
78
           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
79
         };
80

    
81
  private static final Static4D[] QUATS = new Static4D[]
82
         {
83
           new Static4D( 0.0f, 0.0f, 0.0f, 1.0f ),
84
           new Static4D(-0.5f, 0.5f, 0.5f, 0.5f ),
85
           new Static4D( 0.5f,-0.5f,-0.5f, 0.5f ),
86
           new Static4D( 0.0f,    F,   -E, 0.5f ),
87
           new Static4D( 0.0f,   -F,    E, 0.5f ),
88
           new Static4D(    E, 0.0f,    F, 0.5f ),
89
           new Static4D(   -E, 0.0f,   -F, 0.5f ),
90
           new Static4D(    F,    E, 0.0f, 0.5f ),
91
           new Static4D(   -F,   -E, 0.0f, 0.5f ),
92
           new Static4D(    E,    F,-0.5f, 0.0f ),
93
           new Static4D( 0.5f,   -E,    F, 0.0f ),
94
           new Static4D(    F, 0.5f,    E, 0.0f )
95
         };
96

    
97
  // Colors of the faces of cubits.
98
  private static final int[][] mFaceMap = new int[][]
99
         {
100
           { 25,24,35, 36,36,36,36,36 },
101
           { 27,28,29, 36,36,36,36,36 },
102
           { 31,26,30, 36,36,36,36,36 },
103
           { 32,34,33, 36,36,36,36,36 },
104

    
105
           { 31,32,25, 36,36,36,36,36 },
106
           { 33,28,24, 36,36,36,36,36 },
107
           { 26,35,27, 36,36,36,36,36 },
108
           { 30,29,34, 36,36,36,36,36 },
109

    
110
           {  8, 0,13,21, 36,36,36,36 },
111
           {  1, 2,19,23, 36,36,36,36 },
112
           {  4,11,12,15, 36,36,36,36 },
113
           {  3, 6,14,17, 36,36,36,36 },
114
           {  5, 9,22,16, 36,36,36,36 },
115
           {  7,10,20,18, 36,36,36,36 }
116
         };
117

    
118
  // centers of the 14 cubits.
119
  static final float[][] CENTERS = new float[][]
120
         {
121
           { 0.0f,-0.5f,    G },
122
           {    E,   -E,   -E },
123
           {   -G, 0.0f,-0.5f },
124
           { 0.5f,    G, 0.0f },
125

    
126
           {   -E,    E,    E },
127
           {    G, 0.0f, 0.5f },
128
           {-0.5f,   -G, 0.0f },
129
           { 0.0f, 0.5f,   -G },
130

    
131
           {        E/2, (E+0.5f)/2,    (E+G)/2 },
132
           {   -(E+G)/2,       -E/2, (E+0.5f)/2 },
133
           { (E+0.5f)/2,   -(E+G)/2,        E/2 },
134
           {       -E/2,-(E+0.5f)/2,   -(E+G)/2 },
135
           {    (E+G)/2,        E/2,-(E+0.5f)/2 },
136
           {-(E+0.5f)/2,    (E+G)/2,       -E/2 }
137
         };
138

    
139
  private static final double[][] VERTICES_SMALL_LEFT = new double[][]
140
         {
141
            {         0.000,         0.000,         0.000},
142
            {       - 0.250,-SQ5/8 - 0.125,-SQ5/8 - 0.375},
143
            { SQ5/8 + 0.125,-SQ5/8 - 0.375,       + 0.250},
144
            { SQ5/8 + 0.375,       + 0.250,-SQ5/8 - 0.125},
145
            { SQ5/4 + 0.250,-SQ5/4 - 0.250,-SQ5/4 - 0.250},
146
            { SQ5/8 - 0.125,       + 0.250,-SQ5/8 - 0.125},
147
            {       - 0.250,-SQ5/8 - 0.125,-SQ5/8 + 0.125},
148
            { SQ5/8 + 0.125,-SQ5/8 + 0.125,       + 0.250}
149
         };
150

    
151
  private static final int[][] VERT_INDEXES_SMALL_LEFT  = new int[][]
152
         {
153
           {6,0,5,1},   // counterclockwise!
154
           {0,7,3,5},
155
           {0,6,2,7},
156
           {1,5,3,4},
157
           {3,7,2,4},
158
           {2,6,1,4},
159
         };
160

    
161
  private static final double[][] VERTICES_SMALL_RIGHT = new double[][]
162
         {
163
           { 0.0       ,  0.0      , 0.0       },
164
           { -0.5*E    , 0.5*E+0.25, -0.25     },
165
           {-0.25      , -E/2      , (-2*E-1)/4},
166
           { 0.5*E+0.25, 0.25      , -E/2      },
167
           { 0.0       , 0.5       , -E-0.5    },
168
           { 0.0       , 0.5       , 0.0       },
169
           { -0.5*E    ,-0.5*E+0.25, -0.25     },
170
           {  0.5*E    ,-0.5*E+0.25, -0.25     }
171
         };
172

    
173
  private static final int[][] VERT_INDEXES_SMALL_RIGHT = new int[][]
174
         {
175
           {6,0,5,1},   // counterclockwise!
176
           {0,7,3,5},
177
           {0,6,2,7},
178
           {4,3,5,1},
179
           {4,2,7,3},
180
           {4,1,6,2},
181
         };
182

    
183
  private static final double[][] VERTICES_BIG = new double[][]
184
         {
185
           {-E/2     ,-E/2+0.25,     0.25},
186
           { E/2     , E/2-0.25,    -0.25},
187
           {-E       ,     0.00,     0.00},
188
           {     0.25, E/2     ,-E/2-0.25},
189
           {-E/2     ,-E/2-0.25,     0.25},
190
           { E/2+0.25,    -0.25,-E/2     },
191
           {-E       ,    -0.50,     0.00},
192
           {     0.50,     0.00,-E       },
193
           {-E  +0.25, E/2     ,-E/2-0.25},
194
           {     0.25,-E/2-0.50,-E/2+0.25},
195
           {-E/2     ,-E/2-0.25,-E  -0.25}
196
         };
197

    
198
  private static final int[][] VERT_INDEXES_BIG = new int[][]
199
         {
200
           {0,1,3,8,2},   // counterclockwise!
201
           {0,4,9,5,1},
202
           { 0,2,6,4},
203
           { 1,5,7,3},
204
           {10,9,4,6},
205
           {10,9,5,7},
206
           {10,8,3,7},
207
           {10,8,2,6}
208
         };
209

    
210
  private static final int[] QUAT_INDEX = new int[]
211
         {
212
           0,6,1,2,0,4,6,5,0,1,4,9,5,2
213
         };
214

    
215
  private static final float[][] STICKERS = new float[][]
216
         {
217
           { -0.14400357f, -0.47894150f, 0.50000000f,-0.011045523f, 0.37700626f, 0.36749030f,-0.26699730f, 0.36749026f, -0.46600536f, -0.24499352f }, // Big cubit 1st
218
           {  0.36327127f,  0.26393202f,-0.36327127f, 0.500000000f,-0.36327127f,-0.26393202f, 0.36327127f,-0.50000000f },                             // Big cubit 2nd
219
           { -0.29389262f, -0.50000000f, 0.29389262f,-0.309017000f, 0.29389262f, 0.30901700f,-0.29389262f, 0.50000000f },                             // Small cubit 1st
220
         };
221

    
222
  private static MeshBase[] mMeshes;
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  TwistyUltimate(int size, Static4D quat, DistortedTexture texture,
227
                 MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
228
    {
229
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth);
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  MeshBase createCubitMesh(int cubit, int numLayers)
235
    {
236
    if( mMeshes==null )
237
      {
238
      FactoryCubit factory = FactoryCubit.getInstance();
239
      factory.clear();
240
      mMeshes = new MeshBase[3];
241
      }
242

    
243
    MeshBase mesh;
244

    
245
    if( cubit<4 )
246
      {
247
      if( mMeshes[0]==null )
248
        {
249
        float[][] bands= new float[][]
250
          {
251
             {0.03f,17,0.5f,0.2f,5,  2,2},
252
             {0.01f, 1,0.5f,0.2f,5,  2,2}
253
          };
254
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
255
        float[][] corners   = new float[][] {  { 0.013f, 0.08f } };
256
        int[] cornerIndexes = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
257
        float[][] centers   = new float[][] { { 0.0f,-0.5f, -(SQ5+3)/4 } };
258
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0 };
259

    
260
        FactoryCubit factory = FactoryCubit.getInstance();
261
        factory.createNewFaceTransform(VERTICES_SMALL_RIGHT,VERT_INDEXES_SMALL_RIGHT);
262
        mMeshes[0] = factory.createRoundedSolid(VERTICES_SMALL_RIGHT, VERT_INDEXES_SMALL_RIGHT,
263
                                                bands, bandIndexes,
264
                                                corners, cornerIndexes,
265
                                                centers, centerIndexes,
266
                                                getNumCubitFaces() );
267
        }
268
      mesh = mMeshes[0].copy(true);
269
      }
270
    else if( cubit<8 )
271
      {
272
      if( mMeshes[1]==null )
273
        {
274
        float[][] bands= new float[][]
275
          {
276
             {0.03f,17,0.5f,0.2f,5,  2,2},
277
             {0.01f, 1,0.5f,0.2f,5,  2,2}
278
          };
279
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
280
        float[][] corners   = new float[][] {  { 0.013f, 0.08f } };
281
        int[] cornerIndexes = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
282
        float[][] centers   = new float[][] { { 0.0f,-0.5f, -(SQ5+3)/4 } };
283
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0 };
284

    
285
        FactoryCubit factory = FactoryCubit.getInstance();
286
        factory.createNewFaceTransform(VERTICES_SMALL_LEFT,VERT_INDEXES_SMALL_LEFT);
287
        mMeshes[1] = factory.createRoundedSolid(VERTICES_SMALL_LEFT, VERT_INDEXES_SMALL_LEFT,
288
                                                bands, bandIndexes,
289
                                                corners, cornerIndexes,
290
                                                centers, centerIndexes,
291
                                                getNumCubitFaces() );
292
        }
293
      mesh = mMeshes[1].copy(true);
294
      }
295
    else
296
      {
297
      if( mMeshes[2]==null )
298
        {
299
        float[][] bands= new float[][]
300
          {
301
            {0.04f,17,0.5f,0.2f,5,  2,2},
302
            {0.03f,17,0.5f,0.2f,5,  2,2},
303
            {0.01f, 1,0.5f,0.2f,5,  2,2}
304
          };
305
        int[] bandIndexes   = new int[] { 0,0,1,1,2,2,2,2 };
306
        float[][] corners   = new float[][] { { 0.013f, 0.08f } };
307
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,-1 };
308
        float[][] centers   = new float[][] { { -(SQ5+1)/8, 0.25f, -(SQ5+5)/8 } };
309
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0 };
310

    
311
        FactoryCubit factory = FactoryCubit.getInstance();
312
        factory.createNewFaceTransform(VERTICES_BIG,VERT_INDEXES_BIG);
313
        mMeshes[2] = factory.createRoundedSolid(VERTICES_BIG, VERT_INDEXES_BIG,
314
                                                bands, bandIndexes,
315
                                                corners, cornerIndexes,
316
                                                centers, centerIndexes,
317
                                                getNumCubitFaces() );
318
        }
319
      mesh = mMeshes[2].copy(true);
320
      }
321

    
322
    Static4D q = QUATS[getQuatIndex(cubit)];
323
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( q, new Static3D(0,0,0) );
324
    mesh.apply(quat,0xffffffff,0);
325

    
326
    return mesh;
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  float[][] getCubitPositions(int numLayers)
332
    {
333
    return CENTERS;
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  private int getQuatIndex(int cubit)
339
    {
340
    return QUAT_INDEX[cubit];
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
346
    {
347
    int COLORS = FACE_COLORS.length;
348
    int stickerType = face/COLORS;
349
    float R,S;
350
    float[] RS;
351

    
352
    switch(stickerType)
353
      {
354
      case 0:  R = 0.08f; S = 0.07f; RS= new float[] {R,R,R,R,R}; break;
355
      case 1:  R = 0.13f; S = 0.09f; RS= new float[] {R,R,R,R  }; break;
356
      case 2:  R = 0.11f; S = 0.08f; RS= new float[] {R,R,R,R  }; break;
357
      default: R = 0.00f; S = 0.00f; RS= new float[] {R,R,R,R  }; break;
358
      }
359

    
360
    FactorySticker factory = FactorySticker.getInstance();
361
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  int getFaceColor(int cubit, int cubitface, int size)
367
    {
368
    return mFaceMap[cubit][cubitface];
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  float returnMultiplier()
374
    {
375
    return 1.0f;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  Static4D[] getQuats()
381
    {
382
    return QUATS;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  boolean shouldResetTextureMaps()
388
    {
389
    return false;
390
    }
391

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

    
394
  int getNumFaces()
395
    {
396
    return FACE_COLORS.length;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  float[][] getCuts(int numLayers)
402
    {
403
    float[] cut = new float[] {0.0f};
404
    return new float[][] { cut,cut,cut,cut };
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  int getNumStickerTypes(int numLayers)
410
    {
411
    return STICKERS.length;
412
    }
413

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
  int getNumCubitFaces()
417
    {
418
    return 8;
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

    
423
  float getScreenRatio()
424
    {
425
    return 0.67f;
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429
// PUBLIC API
430

    
431
  public Static3D[] getRotationAxis()
432
    {
433
    return ROT_AXIS;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public int[] getBasicAngle()
439
    {
440
    return BASIC_ANGLE;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
446
    {
447
    if( curr==0 )
448
      {
449
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
450
      }
451
    else
452
      {
453
      int newVector = rnd.nextInt(NUM_AXIS -1);
454
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
455
      }
456

    
457
    scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0 : 1;
458

    
459
    switch( rnd.nextInt(2) )
460
      {
461
      case 0: scramble[curr][2] =  1; break;
462
      case 1: scramble[curr][2] = -1; break;
463
      }
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

    
468
  public boolean isSolved()
469
    {
470
    int index = CUBITS[0].mQuatIndex;
471

    
472
    for(int i=1; i<NUM_CUBITS; i++)
473
      {
474
      if( CUBITS[i].mQuatIndex != index ) return false;
475
      }
476

    
477
    return true;
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481
// only needed for solvers - there are no Skewb Ultimate solvers ATM)
482

    
483
  public String retObjectString()
484
    {
485
    return "";
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public int getObjectName(int numLayers)
491
    {
492
    return R.string.ulti2;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int getInventor(int numLayers)
498
    {
499
    return R.string.ulti2_inventor;
500
    }
501

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

    
504
  public int getComplexity(int numLayers)
505
    {
506
    return 6;
507
    }
508
}
(41-41/41)