Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ f242ba04

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
import java.util.Random;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
public class TwistyRex extends TwistyObject
39
{
40
  // the four rotation axis of a RubikRex. Must be normalized.
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
43
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
44
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
45
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
47
         };
48

    
49
  private static final int[] FACE_COLORS = new int[]
50
         {
51
           COLOR_YELLOW, COLOR_WHITE,
52
           COLOR_BLUE  , COLOR_GREEN,
53
           COLOR_RED   , COLOR_ORANGE
54
         };
55

    
56
  public static final float REX_D = 0.2f;
57

    
58
  private int mCurrState;
59
  private int mIndexExcluded;
60
  private final ScrambleState[] mStates;
61
  private int[][] mScrambleTable;
62
  private int[] mNumOccurences;
63
  private int[] mBasicAngle;
64
  private Static4D[] mQuats;
65
  private int[][] mFaceMap;
66
  private ObjectSticker[] mStickers;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
71
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
72
    {
73
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
74

    
75
    int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
76

    
77
    mStates = new ScrambleState[]
78
      {
79
      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
80
      };
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  private void initializeQuats()
86
    {
87
    mQuats = new Static4D[]
88
         {
89
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
90
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
91
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
92
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
93

    
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
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
99
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
100
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
101
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
102
         };
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  int[] getSolvedQuats(int cubit, int numLayers)
108
    {
109
    if( mQuats==null ) initializeQuats();
110
    int status = retCubitSolvedStatus(cubit,numLayers);
111
    return status<0 ? null : buildSolvedQuats(MovementRex.FACE_AXIS[status],mQuats);
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

    
116
  float getScreenRatio()
117
    {
118
    return 1.5f;
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  Static4D[] getQuats()
124
    {
125
    if( mQuats==null ) initializeQuats();
126
    return mQuats;
127
    }
128

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

    
131
  int getNumFaces()
132
    {
133
    return FACE_COLORS.length;
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  boolean shouldResetTextureMaps()
139
    {
140
    return false;
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  int getSolvedFunctionIndex()
146
    {
147
    return 0;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  int getNumStickerTypes(int numLayers)
153
    {
154
    return 3;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  float[][] getCuts(int numLayers)
160
    {
161
    float C = SQ3*0.15f; // bit less than 1/6 of the length of the main diagonal
162
    float[] cut = new float[] {-C,+C};
163
    return new float[][] { cut,cut,cut,cut };
164
    }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

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

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

    
175
  float[][] getCubitPositions(int numLayers)
176
    {
177
    final float DIST1= 0.50f;
178
    final float DIST2= (1+2*REX_D)/6;
179
    final float DIST3= 0.51f;
180

    
181
    final float[][] CENTERS = new float[24+6+12][];
182

    
183
    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
184
    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
185
    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
186
    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
187
    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
188
    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
189
    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
190
    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
191
    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
192
    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
193
    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
194
    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
195
    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
196
    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
197
    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
198
    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
199
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
200
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
201
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
202
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
203
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
204
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
205
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
206
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
207

    
208
    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
209
    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
210
    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
211
    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
212
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
213
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
214

    
215
    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
216
    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
217
    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
218
    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
219
    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
220
    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
221
    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
222
    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
223
    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
224
    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
225
    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
226
    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
227

    
228
    return CENTERS;
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  ObjectShape getObjectShape(int cubit, int numLayers)
234
    {
235
    int variant = getCubitVariant(cubit,numLayers);
236

    
237
    if( variant==0 )
238
      {
239
      float G = (1-REX_D)*SQ2/2;
240

    
241
      double[][] vertices =
242
         {
243
             {  -0.033333f, 0.23333f, 0.0f },
244
             {  -0.233333f, 0.03333f, 0.0f },
245
             {  +0.216666f,-0.23666f, 0.0f },
246
             {  +0.236666f,-0.21666f, 0.0f }
247
         };
248

    
249
      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
250
      float[][] centers= new float[][] { {0.0f,0.0f,-G/3} };
251
      float[][] corners= new float[][] { {0.03f,0.10f} };
252
      int[] indices= {-1,-1,0,0};
253
      int[] bandIndices= new int[] { 0,1 };
254

    
255
      float[][] bands =
256
        {
257
            {+0.016f,10,G/3,0.5f,5,1,1},
258
            {+0.230f,45,G/3,0.0f,2,0,0}
259
        };
260
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
261
      }
262
    else if( variant==1 )
263
      {
264
      double[][] vertices =
265
        {
266
            { -REX_D,   0.0f, 0.0f },
267
            {   0.0f, -REX_D, 0.0f },
268
            { +REX_D,   0.0f, 0.0f },
269
            {   0.0f, +REX_D, 0.0f }
270
        };
271

    
272
      int[][] vertIndexes= { {0,1,2,3},{3,2,1,0} };
273
      int[] indices= {-1,-1,-1,-1};
274
      int[] bandIndices= new int[] { 0,1 };
275

    
276
      float[][] bands =
277
        {
278
            {0.025f,10,REX_D/2,0.5f,5,0,0},
279
            {0.000f,45,REX_D/2,0.0f,2,0,0}
280
        };
281

    
282
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
283
      }
284
    else
285
      {
286
      float E = 0.5f - REX_D;
287
      float F = 0.5f;
288
      float G = (float)Math.sqrt(E*E+F*F);
289

    
290
      double[][] vertices =
291
         {
292
             { -F, 0, 0 },
293
             {  0,-E, 0 },
294
             { +F, 0, 0 },
295
             {  0, 0,-E },
296
         };
297

    
298
      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
299
      float[][] centers= new float[][] { {0.0f,-0.5f,-0.5f} };
300
      float[][] corners= new float[][] { {0.06f,0.10f} };
301
      int[] indices= {0,-1,0,-1};
302
      int[] bandIndices= new int[] { 0,0,1,1 };
303

    
304
      float[][] bands =
305
        {
306
           {0.03f,27,F/3,0.8f,5,2,3},
307
           {0.01f,45,G/3,0.2f,3,1,2}
308
        };
309

    
310
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
311
      }
312
    }
313

    
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

    
316
  Static4D getQuat(int cubit, int numLayers)
317
    {
318
    if( mQuats==null ) initializeQuats();
319

    
320
    switch(cubit)
321
      {
322
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
323
      case  1: return mQuats[5];
324
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
325
      case  3: return mQuats[8];
326
      case  4: return mQuats[6];
327
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
328
      case  6: return mQuats[11];
329
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
330
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
331
      case  9: return mQuats[10];
332
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
333
      case 11: return mQuats[4];
334
      case 12: return mQuats[9];
335
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
336
      case 14: return mQuats[7];
337
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
338
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
339
      case 17: return mQuats[0];
340
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
341
      case 19: return mQuats[3];
342
      case 20: return mQuats[1];
343
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
344
      case 22: return mQuats[2];
345
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
346

    
347
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
348
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
349
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
350
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
351
      case 28: return mQuats[0];
352
      case 29: return mQuats[1];
353

    
354
      case 30: return mQuats[0];
355
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
356
      case 32: return mQuats[3];
357
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
358
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
359
      case 35: return mQuats[7];
360
      case 36: return mQuats[9];
361
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
362
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
363
      case 39: return mQuats[8];
364
      case 40: return mQuats[1];
365
      case 41: return mQuats[6];
366
      }
367

    
368
    return mQuats[0];
369
    }
370

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

    
373
  int getNumCubitVariants(int numLayers)
374
    {
375
    return 3;
376
    }
377

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

    
380
  int getCubitVariant(int cubit, int numLayers)
381
    {
382
    return cubit<24 ? 0 : (cubit<30?1:2);
383
    }
384

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

    
387
  int getFaceColor(int cubit, int cubitface, int numLayers)
388
    {
389
    if( mFaceMap==null )
390
      {
391
      mFaceMap = new int[][]
392
         {
393
           {  0, 18,18,18,18,18 },
394
           {  0, 18,18,18,18,18 },
395
           {  0, 18,18,18,18,18 },
396
           {  0, 18,18,18,18,18 },
397
           {  1, 18,18,18,18,18 },
398
           {  1, 18,18,18,18,18 },
399
           {  1, 18,18,18,18,18 },
400
           {  1, 18,18,18,18,18 },
401
           {  2, 18,18,18,18,18 },
402
           {  2, 18,18,18,18,18 },
403
           {  2, 18,18,18,18,18 },
404
           {  2, 18,18,18,18,18 },
405
           {  3, 18,18,18,18,18 },
406
           {  3, 18,18,18,18,18 },
407
           {  3, 18,18,18,18,18 },
408
           {  3, 18,18,18,18,18 },
409
           {  4, 18,18,18,18,18 },
410
           {  4, 18,18,18,18,18 },
411
           {  4, 18,18,18,18,18 },
412
           {  4, 18,18,18,18,18 },
413
           {  5, 18,18,18,18,18 },
414
           {  5, 18,18,18,18,18 },
415
           {  5, 18,18,18,18,18 },
416
           {  5, 18,18,18,18,18 },
417

    
418
           {  6, 18,18,18,18,18 },
419
           {  7, 18,18,18,18,18 },
420
           {  8, 18,18,18,18,18 },
421
           {  9, 18,18,18,18,18 },
422
           { 10, 18,18,18,18,18 },
423
           { 11, 18,18,18,18,18 },
424

    
425
           { 16,14, 18,18,18,18 },
426
           { 16,12, 18,18,18,18 },
427
           { 16,15, 18,18,18,18 },
428
           { 16,13, 18,18,18,18 },
429
           { 12,14, 18,18,18,18 },
430
           { 15,12, 18,18,18,18 },
431
           { 15,13, 18,18,18,18 },
432
           { 13,14, 18,18,18,18 },
433
           { 14,17, 18,18,18,18 },
434
           { 12,17, 18,18,18,18 },
435
           { 17,15, 18,18,18,18 },
436
           { 13,17, 18,18,18,18 },
437
         };
438
      }
439

    
440
    return mFaceMap[cubit][cubitface];
441
    }
442

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

    
445
  int getColor(int face)
446
    {
447
    return FACE_COLORS[face];
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  ObjectSticker retSticker(int face)
453
    {
454
    if( mStickers==null )
455
      {
456
      float[][] STICKERS = new float[][]
457
          {
458
             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
459
             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
460
             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
461
          };
462

    
463
      final float F = (float)(Math.PI/20);
464
      final float R1= 0.02f;
465
      final float R2= 0.09f;
466
      final float R3= 0.06f;
467
      final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
468
      final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
469
      final float[] strokes = { 0.06f, 0.07f, 0.05f };
470

    
471
      mStickers = new ObjectSticker[STICKERS.length];
472

    
473
      for(int s=0; s<STICKERS.length; s++)
474
        {
475
        mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
476
        }
477
      }
478

    
479
    return mStickers[face/NUM_FACES];
480
    }
481

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

    
484
  float returnMultiplier()
485
    {
486
    return 2.0f;
487
    }
488

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

    
491
  private void initializeScrambling()
492
    {
493
    int numLayers = getNumLayers();
494

    
495
    if( mScrambleTable ==null )
496
      {
497
      mScrambleTable = new int[NUM_AXIS][numLayers];
498
      }
499
    if( mNumOccurences ==null )
500
      {
501
      int max=0;
502

    
503
      for (ScrambleState mState : mStates)
504
        {
505
        int tmp = mState.getTotal(-1);
506
        if (max < tmp) max = tmp;
507
        }
508

    
509
      mNumOccurences = new int[max];
510
      }
511

    
512
    for(int i=0; i<NUM_AXIS; i++)
513
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
514
    }
515

    
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517
// PUBLIC API
518

    
519
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
520
    {
521
    if( curr==0 )
522
      {
523
      mCurrState     = 0;
524
      mIndexExcluded =-1;
525
      initializeScrambling();
526
      }
527

    
528
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
529

    
530
    scramble[curr][0] = info[0];
531
    scramble[curr][1] = info[1];
532
    scramble[curr][2] = info[2];
533

    
534
    mCurrState     = info[3];
535
    mIndexExcluded = info[0];
536
    }
537

    
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539

    
540
  public Static3D[] getRotationAxis()
541
    {
542
    return ROT_AXIS;
543
    }
544

    
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546

    
547
  public int[] getBasicAngle()
548
    {
549
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
550
    return mBasicAngle;
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  public int getObjectName(int numLayers)
556
    {
557
    return R.string.rex3;
558
    }
559

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

    
562
  public int getInventor(int numLayers)
563
    {
564
    return R.string.rex3_inventor;
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
  public int getComplexity(int numLayers)
570
    {
571
    return 3;
572
    }
573
}
(36-36/41)