Project

General

Profile

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

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

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
  private static final int FACES_PER_CUBIT =6;
41

    
42
  public static final float REX_D = 0.2f;
43

    
44
  // the four rotation axis of a RubikRex. Must be normalized.
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
48
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
49
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
50
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
51
         };
52

    
53
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
54

    
55
  private static final int[] FACE_COLORS = new int[]
56
         {
57
           COLOR_YELLOW, COLOR_WHITE,
58
           COLOR_BLUE  , COLOR_GREEN,
59
           COLOR_RED   , COLOR_ORANGE
60
         };
61

    
62
  // All legal rotation quats of a RubikRex
63
  private static final Static4D[] QUATS = new Static4D[]
64
         {
65
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
66
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
67
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
68
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
69

    
70
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
71
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
72
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
74
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
75
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
78
         };
79

    
80
  private static final int[][] mFaceMap =
81
         {
82
           {  0, 18,18,18,18,18 },
83
           {  0, 18,18,18,18,18 },
84
           {  0, 18,18,18,18,18 },
85
           {  0, 18,18,18,18,18 },
86
           {  1, 18,18,18,18,18 },
87
           {  1, 18,18,18,18,18 },
88
           {  1, 18,18,18,18,18 },
89
           {  1, 18,18,18,18,18 },
90
           {  2, 18,18,18,18,18 },
91
           {  2, 18,18,18,18,18 },
92
           {  2, 18,18,18,18,18 },
93
           {  2, 18,18,18,18,18 },
94
           {  3, 18,18,18,18,18 },
95
           {  3, 18,18,18,18,18 },
96
           {  3, 18,18,18,18,18 },
97
           {  3, 18,18,18,18,18 },
98
           {  4, 18,18,18,18,18 },
99
           {  4, 18,18,18,18,18 },
100
           {  4, 18,18,18,18,18 },
101
           {  4, 18,18,18,18,18 },
102
           {  5, 18,18,18,18,18 },
103
           {  5, 18,18,18,18,18 },
104
           {  5, 18,18,18,18,18 },
105
           {  5, 18,18,18,18,18 },
106

    
107
           {  6, 18,18,18,18,18 },
108
           {  7, 18,18,18,18,18 },
109
           {  8, 18,18,18,18,18 },
110
           {  9, 18,18,18,18,18 },
111
           { 10, 18,18,18,18,18 },
112
           { 11, 18,18,18,18,18 },
113

    
114
           { 16,14, 18,18,18,18 },
115
           { 16,12, 18,18,18,18 },
116
           { 16,15, 18,18,18,18 },
117
           { 16,13, 18,18,18,18 },
118
           { 12,14, 18,18,18,18 },
119
           { 15,12, 18,18,18,18 },
120
           { 15,13, 18,18,18,18 },
121
           { 13,14, 18,18,18,18 },
122
           { 14,17, 18,18,18,18 },
123
           { 12,17, 18,18,18,18 },
124
           { 17,15, 18,18,18,18 },
125
           { 13,17, 18,18,18,18 },
126
         };
127

    
128
  private static final ObjectSticker[] mStickers;
129

    
130
  private static final float[][] STICKERS = new float[][]
131
          {
132
             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
133
             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
134
             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
135
          };
136
  private static final int NUM_STICKERS = STICKERS.length;
137

    
138
  static
139
    {
140
    mStickers = new ObjectSticker[NUM_STICKERS];
141

    
142
    final float F = (float)(Math.PI/20);
143
    final float R1= 0.02f;
144
    final float R2= 0.09f;
145
    final float R3= 0.06f;
146
    final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
147
    final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
148
    final float[] strokes = { 0.06f, 0.07f, 0.05f };
149

    
150
    for(int s=0; s<NUM_STICKERS; s++)
151
      {
152
      mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
153
      }
154
    }
155

    
156
  private int mCurrState;
157
  private int mIndexExcluded;
158
  private final ScrambleState[] mStates;
159
  private int[][] mScrambleTable;
160
  private int[] mNumOccurences;
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
165
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
166
    {
167
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
168

    
169
    int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
170

    
171
    mStates = new ScrambleState[]
172
      {
173
      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
174
      };
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  int[] getSolvedQuats(int cubit, int numLayers)
180
    {
181
    int status = retCubitSolvedStatus(cubit,numLayers);
182
    return status<0 ? null : buildSolvedQuats(MovementRex.FACE_AXIS[status],QUATS);
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  float getScreenRatio()
188
    {
189
    return 1.5f;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  Static4D[] getQuats()
195
    {
196
    return QUATS;
197
    }
198

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

    
201
  int getNumFaces()
202
    {
203
    return FACE_COLORS.length;
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  boolean shouldResetTextureMaps()
209
    {
210
    return false;
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  int getSolvedFunctionIndex()
216
    {
217
    return 0;
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

    
222
  int getNumStickerTypes(int numLayers)
223
    {
224
    return NUM_STICKERS;
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  float[][] getCuts(int numLayers)
230
    {
231
    float C = SQ3*0.15f; // bit less than 1/6 of the length of the main diagonal
232
    float[] cut = new float[] {-C,+C};
233
    return new float[][] { cut,cut,cut,cut };
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  int getNumCubitFaces()
239
    {
240
    return FACES_PER_CUBIT;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  float[][] getCubitPositions(int numLayers)
246
    {
247
    final float DIST1= 0.50f;
248
    final float DIST2= (1+2*REX_D)/6;
249
    final float DIST3= 0.51f;
250

    
251
    final float[][] CENTERS = new float[24+6+12][];
252

    
253
    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
254
    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
255
    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
256
    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
257
    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
258
    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
259
    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
260
    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
261
    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
262
    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
263
    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
264
    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
265
    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
266
    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
267
    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
268
    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
269
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
270
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
271
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
272
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
273
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
274
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
275
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
276
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
277

    
278
    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
279
    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
280
    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
281
    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
282
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
283
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
284

    
285
    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
286
    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
287
    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
288
    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
289
    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
290
    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
291
    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
292
    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
293
    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
294
    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
295
    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
296
    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
297

    
298
    return CENTERS;
299
    }
300

    
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

    
303
  ObjectShape getObjectShape(int cubit, int numLayers)
304
    {
305
    int variant = getCubitVariant(cubit,numLayers);
306

    
307
    if( variant==0 )
308
      {
309
      float G = (1-REX_D)*SQ2/2;
310

    
311
      double[][] vertices =
312
         {
313
             {  -0.033333f, 0.23333f, 0.0f },
314
             {  -0.233333f, 0.03333f, 0.0f },
315
             {  +0.216666f,-0.23666f, 0.0f },
316
             {  +0.236666f,-0.21666f, 0.0f }
317
         };
318

    
319
      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
320
      float[][] centers= new float[][] { {0.0f,0.0f,-G/3} };
321
      float[][] corners= new float[][] { {0.03f,0.10f} };
322
      int[] indices= {-1,-1,0,0};
323
      int[] bandIndices= new int[] { 0,1 };
324

    
325
      float[][] bands =
326
        {
327
            {+0.016f,10,G/3,0.5f,5,1,1},
328
            {+0.230f,45,G/3,0.0f,2,0,0}
329
        };
330
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
331
      }
332
    else if( variant==1 )
333
      {
334
      double[][] vertices =
335
        {
336
            { -REX_D,   0.0f, 0.0f },
337
            {   0.0f, -REX_D, 0.0f },
338
            { +REX_D,   0.0f, 0.0f },
339
            {   0.0f, +REX_D, 0.0f }
340
        };
341

    
342
      int[][] vertIndexes= { {0,1,2,3},{3,2,1,0} };
343
      int[] indices= {-1,-1,-1,-1};
344
      int[] bandIndices= new int[] { 0,1 };
345

    
346
      float[][] bands =
347
        {
348
            {0.025f,10,REX_D/2,0.5f,5,0,0},
349
            {0.000f,45,REX_D/2,0.0f,2,0,0}
350
        };
351

    
352
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
353
      }
354
    else
355
      {
356
      float E = 0.5f - REX_D;
357
      float F = 0.5f;
358
      float G = (float)Math.sqrt(E*E+F*F);
359

    
360
      double[][] vertices =
361
         {
362
             { -F, 0, 0 },
363
             {  0,-E, 0 },
364
             { +F, 0, 0 },
365
             {  0, 0,-E },
366
         };
367

    
368
      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
369
      float[][] centers= new float[][] { {0.0f,-0.5f,-0.5f} };
370
      float[][] corners= new float[][] { {0.06f,0.10f} };
371
      int[] indices= {0,-1,0,-1};
372
      int[] bandIndices= new int[] { 0,0,1,1 };
373

    
374
      float[][] bands =
375
        {
376
           {0.03f,27,F/3,0.8f,5,2,3},
377
           {0.01f,45,G/3,0.2f,3,1,2}
378
        };
379

    
380
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
381
      }
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  Static4D getQuat(int cubit, int numLayers)
387
    {
388
    switch(cubit)
389
      {
390
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
391
      case  1: return QUATS[5];
392
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
393
      case  3: return QUATS[8];
394
      case  4: return QUATS[6];
395
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
396
      case  6: return QUATS[11];
397
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
398
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
399
      case  9: return QUATS[10];
400
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
401
      case 11: return QUATS[4];
402
      case 12: return QUATS[9];
403
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
404
      case 14: return QUATS[7];
405
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
406
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
407
      case 17: return QUATS[0];
408
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
409
      case 19: return QUATS[3];
410
      case 20: return QUATS[1];
411
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
412
      case 22: return QUATS[2];
413
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
414

    
415
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
416
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
417
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
418
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
419
      case 28: return QUATS[0];
420
      case 29: return QUATS[1];
421

    
422
      case 30: return QUATS[0];
423
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
424
      case 32: return QUATS[3];
425
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
426
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
427
      case 35: return QUATS[7];
428
      case 36: return QUATS[9];
429
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
430
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
431
      case 39: return QUATS[8];
432
      case 40: return QUATS[1];
433
      case 41: return QUATS[6];
434
      }
435

    
436
    return QUATS[0];
437
    }
438

    
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

    
441
  int getNumCubitVariants(int numLayers)
442
    {
443
    return 3;
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  int getCubitVariant(int cubit, int numLayers)
449
    {
450
    return cubit<24 ? 0 : (cubit<30?1:2);
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

    
455
  int getFaceColor(int cubit, int cubitface, int numLayers)
456
    {
457
    return mFaceMap[cubit][cubitface];
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

    
462
  int getColor(int face)
463
    {
464
    return FACE_COLORS[face];
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  ObjectSticker retSticker(int face)
470
    {
471
    return mStickers[face/NUM_FACES];
472
    }
473

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

    
476
  float returnMultiplier()
477
    {
478
    return 2.0f;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  private void initializeScrambling()
484
    {
485
    int numLayers = getNumLayers();
486

    
487
    if( mScrambleTable ==null )
488
      {
489
      mScrambleTable = new int[NUM_AXIS][numLayers];
490
      }
491
    if( mNumOccurences ==null )
492
      {
493
      int max=0;
494

    
495
      for (ScrambleState mState : mStates)
496
        {
497
        int tmp = mState.getTotal(-1);
498
        if (max < tmp) max = tmp;
499
        }
500

    
501
      mNumOccurences = new int[max];
502
      }
503

    
504
    for(int i=0; i<NUM_AXIS; i++)
505
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509
// PUBLIC API
510

    
511
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
512
    {
513
    if( curr==0 )
514
      {
515
      mCurrState     = 0;
516
      mIndexExcluded =-1;
517
      initializeScrambling();
518
      }
519

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

    
522
    scramble[curr][0] = info[0];
523
    scramble[curr][1] = info[1];
524
    scramble[curr][2] = info[2];
525

    
526
    mCurrState     = info[3];
527
    mIndexExcluded = info[0];
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public Static3D[] getRotationAxis()
533
    {
534
    return ROT_AXIS;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int[] getBasicAngle()
540
    {
541
    return BASIC_ANGLE;
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  public int getObjectName(int numLayers)
547
    {
548
    return R.string.rex3;
549
    }
550

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

    
553
  public int getInventor(int numLayers)
554
    {
555
    return R.string.rex3_inventor;
556
    }
557

    
558
///////////////////////////////////////////////////////////////////////////////////////////////////
559

    
560
  public int getComplexity(int numLayers)
561
    {
562
    return 3;
563
    }
564
}
(36-36/41)