Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyUltimate.java @ 74ffd68e

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[] FACE_COLORS = new int[]
73
         {
74
           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
75
           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
76
           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
77
         };
78

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

    
95
  // Colors of the faces of cubits. TODO
96
  private static final int[][] mFaceMap = new int[][]
97
         {
98
           { 24,24,24, 36,36,36,36,36 },
99
           { 24,24,24, 36,36,36,36,36 },
100
           { 24,24,24, 36,36,36,36,36 },
101
           { 24,24,24, 36,36,36,36,36 },
102
           { 24,24,24, 36,36,36,36,36 },
103
           { 24,24,24, 36,36,36,36,36 },
104
           { 24,24,24, 36,36,36,36,36 },
105
           { 24,24,24, 36,36,36,36,36 },
106

    
107
           {  0, 0,12,12, 36,36,36,36 },
108
           {  0, 0,12,12, 36,36,36,36 },
109
           {  0, 0,12,12, 36,36,36,36 },
110
           {  0, 0,12,12, 36,36,36,36 },
111
           {  0, 0,12,12, 36,36,36,36 },
112
           {  0, 0,12,12, 36,36,36,36 }
113
         };
114

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

    
127
           {        E/2, (E+0.5f)/2,    (E+G)/2 },
128
           {   -(E+G)/2,       -E/2, (E+0.5f)/2 },
129
           { (E+0.5f)/2,   -(E+G)/2,        E/2 },
130
           {       -E/2,-(E+0.5f)/2,   -(E+G)/2 },
131
           {    (E+G)/2,        E/2,-(E+0.5f)/2 },
132
           {-(E+0.5f)/2,    (E+G)/2,       -E/2 }
133
         };
134

    
135
  static final int[] QUAT_INDEX = new int[]
136
         {
137
           0,      11,11,11,11, 6,1,2, // TODO the four middle ones
138
           0,1,4,9,5,2
139
         };
140

    
141
  private static final double[][] VERTICES_SMALL = new double[][]
142
         {
143
           { 0.0       ,  0.0      , 0.0       },
144
           { -0.5*E    , 0.5*E+0.25, -0.25     },
145
           {-0.25      , -E/2      , (-2*E-1)/4},
146
           { 0.5*E+0.25, 0.25      , -E/2      },
147
           { 0.0       , 0.5       , -E-0.5    },
148
           { 0.0       , 0.5       , 0.0       },
149
           { -0.5*E    ,-0.5*E+0.25, -0.25     },
150
           {  0.5*E    ,-0.5*E+0.25, -0.25     }
151
         };
152

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

    
163
  private static final double[][] VERTICES_BIG = new double[][]
164
         {
165
           {-E/2     ,-E/2+0.25,     0.25},
166
           { E/2     , E/2-0.25,    -0.25},
167
           {-E       ,     0.00,     0.00},
168
           {     0.25, E/2     ,-E/2-0.25},
169
           {-E/2     ,-E/2-0.25,     0.25},
170
           { E/2+0.25,    -0.25,-E/2     },
171
           {-E       ,    -0.50,     0.00},
172
           {     0.50,     0.00,-E       },
173
           {-E  +0.25, E/2     ,-E/2-0.25},
174
           {     0.25,-E/2-0.50,-E/2+0.25},
175
           {-E/2     ,-E/2-0.25,-E  -0.25}
176
         };
177

    
178
  private static final int[][] VERT_INDEXES_BIG = new int[][]
179
         {
180
           {0,1,3,8,2},   // counterclockwise!
181
           {0,4,9,5,1},
182
           { 0,2,6,4},
183
           { 1,5,7,3},
184
           {10,9,4,6},
185
           {10,9,5,7},
186
           {10,8,3,7},
187
           {10,8,2,6}
188
         };
189

    
190
  private static final float[][] STICKERS = new float[][]
191
         {
192
           { -0.14400357f, -0.47894150f, 0.50000000f,-0.011045523f, 0.37700626f, 0.36749030f,-0.26699730f, 0.36749026f, -0.46600536f, -0.24499352f }, // Big cubit 1st
193
           {  0.36327127f,  0.26393202f,-0.36327127f, 0.500000000f,-0.36327127f,-0.26393202f, 0.36327127f,-0.50000000f },                             // Big cubit 2nd
194
           { -0.29389262f, -0.50000000f, 0.29389262f,-0.309017000f, 0.29389262f, 0.30901700f,-0.29389262f, 0.50000000f },                             // Small cubit 1st
195
         };
196

    
197
  private static MeshBase[] mMeshes;
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  TwistyUltimate(int size, Static4D quat, DistortedTexture texture,
202
                 MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
203
    {
204
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth);
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  MeshBase createCubitMesh(int cubit, int numLayers)
210
    {
211
    if( mMeshes==null )
212
      {
213
      FactoryCubit factory = FactoryCubit.getInstance();
214
      factory.clear();
215
      mMeshes = new MeshBase[2];
216
      }
217

    
218
    MeshBase mesh;
219

    
220
    if( cubit<8 )
221
      {
222
      if( mMeshes[0]==null )
223
        {
224
        float[][] bands= new float[][]
225
          {
226
             {0.04f,17,0.5f,0.2f,5,  2,2},
227
             {0.01f, 1,0.5f,0.2f,5,  2,2}
228
          };
229
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
230
        float[][] corners   = new float[][] {  { 0.013f, 0.08f } };
231
        int[] cornerIndexes = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
232
        float[][] centers   = new float[][] { { 0.0f,-0.5f, -(SQ5+3)/4 } };
233
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0 };
234

    
235
        FactoryCubit factory = FactoryCubit.getInstance();
236
        factory.createNewFaceTransform(VERTICES_SMALL,VERT_INDEXES_SMALL);
237
        mMeshes[0] = factory.createRoundedSolid(VERTICES_SMALL, VERT_INDEXES_SMALL,
238
                                                bands, bandIndexes,
239
                                                corners, cornerIndexes,
240
                                                centers, centerIndexes,
241
                                                getNumCubitFaces() );
242
        }
243
      mesh = mMeshes[0].copy(true);
244
      }
245
    else
246
      {
247
      if( mMeshes[1]==null )
248
        {
249
        float[][] bands= new float[][]
250
          {
251
            {0.04f,17,0.5f,0.2f,5,  2,2},
252
            {0.04f,17,0.5f,0.2f,5,  2,2},
253
            {0.01f, 1,0.5f,0.2f,5,  2,2}
254
          };
255
        int[] bandIndexes   = new int[] { 0,0,1,1,2,2,2,2 };
256
        float[][] corners   = new float[][] { { 0.013f, 0.08f } };
257
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,-1 };
258
        float[][] centers   = new float[][] { { -(SQ5+1)/8, 0.25f, -(SQ5+5)/8 } };
259
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0 };
260

    
261
        FactoryCubit factory = FactoryCubit.getInstance();
262
        factory.createNewFaceTransform(VERTICES_BIG,VERT_INDEXES_BIG);
263
        mMeshes[1] = factory.createRoundedSolid(VERTICES_BIG, VERT_INDEXES_BIG,
264
                                                bands, bandIndexes,
265
                                                corners, cornerIndexes,
266
                                                centers, centerIndexes,
267
                                                getNumCubitFaces() );
268
        }
269
      mesh = mMeshes[1].copy(true);
270
      }
271

    
272
    Static4D q = QUATS[getQuat(cubit)];
273
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( q, new Static3D(0,0,0) );
274
    mesh.apply(quat,0xffffffff,0);
275

    
276
    return mesh;
277
    }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

    
281
  float[][] getCubitPositions(int numLayers)
282
    {
283
    return CENTERS;
284
    }
285

    
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

    
288
  private int getQuat(int cubit)
289
    {
290
    return QUAT_INDEX[cubit];
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
296
    {
297
    int COLORS = FACE_COLORS.length;
298
    int stickerType = face/COLORS;
299
    float R,S;
300

    
301
    switch(stickerType)
302
      {
303
      case 0:  R = 0.09f; S = 0.08f; break;
304
      case 1:  R = 0.10f; S = 0.08f; break;
305
      case 2:  R = 0.11f; S = 0.08f; break;
306
      default: R = 0.00f; S = 0.00f; break;
307
      }
308

    
309
    FactorySticker factory = FactorySticker.getInstance();
310
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], S, FACE_COLORS[face%COLORS], R);
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  int getFaceColor(int cubit, int cubitface, int size)
316
    {
317
    return mFaceMap[cubit][cubitface];
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  float returnMultiplier()
323
    {
324
    return 1.0f;
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  Static4D[] getQuats()
330
    {
331
    return QUATS;
332
    }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  boolean shouldResetTextureMaps()
337
    {
338
    return false;
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  int getNumFaces()
344
    {
345
    return FACE_COLORS.length;
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
  float[] getCuts(int numLayers)
351
    {
352
    float[] cuts = new float[1];
353
    cuts[0] = 0.0f;
354

    
355
    return cuts;
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

    
360
  int getNumStickerTypes(int numLayers)
361
    {
362
    return STICKERS.length;
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  int getNumCubitFaces()
368
    {
369
    return 8;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  float getScreenRatio()
375
    {
376
    return 0.5f;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  float[] getRowChances(int numLayers)
382
    {
383
    float[] chances = new float[2];
384
    chances[0] = 0.5f;
385
    chances[1] = 1.0f;
386

    
387
    return chances;
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
// PUBLIC API
392

    
393
  public Static3D[] getRotationAxis()
394
    {
395
    return ROT_AXIS;
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

    
400
  public int getBasicAngle()
401
    {
402
    return 3;
403
    }
404

    
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

    
407
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
408
    {
409
    if( num==0 )
410
      {
411
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
412
      }
413
    else
414
      {
415
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
416
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
417
      }
418

    
419
    float rowFloat = rnd.nextFloat();
420

    
421
    for(int row=0; row<mRowChances.length; row++)
422
      {
423
      if( rowFloat<=mRowChances[row] )
424
        {
425
        scramble[num][1] = row;
426
        break;
427
        }
428
      }
429

    
430
    switch( rnd.nextInt(2) )
431
      {
432
      case 0: scramble[num][2] =  1; break;
433
      case 1: scramble[num][2] = -1; break;
434
      }
435
    }
436

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

    
439
  public boolean isSolved()
440
    {
441
    int index = CUBITS[0].mQuatIndex;
442

    
443
    for(int i=1; i<NUM_CUBITS; i++)
444
      {
445
      if( CUBITS[i].mQuatIndex != index ) return false;
446
      }
447

    
448
    return true;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452
// only needed for solvers - there are no Skewb Ultimate solvers ATM)
453

    
454
  public String retObjectString()
455
    {
456
    return "";
457
    }
458

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

    
461
  public int getObjectName(int numLayers)
462
    {
463
    return R.string.ulti2;
464
    }
465

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

    
468
  public int getInventor(int numLayers)
469
    {
470
    return R.string.ulti2_inventor;
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public int getComplexity(int numLayers)
476
    {
477
    return 6;
478
    }
479
}
(35-35/35)