Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ 967c1d17

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 static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
23

    
24
import android.content.res.Resources;
25

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

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

    
38
public class TwistyRex extends Twisty6
39
{
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
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
         };
47

    
48
  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
49

    
50
  private static final int[][][] ENABLED = new int[][][]
51
      {
52
          {{0,1},{3,1},{2,3},{0,2}},
53
          {{2,3},{3,1},{0,1},{0,2}},
54
          {{1,2},{0,1},{0,3},{2,3}},
55
          {{1,2},{2,3},{0,3},{0,1}},
56
          {{0,3},{0,2},{1,2},{1,3}},
57
          {{1,2},{0,2},{0,3},{1,3}},
58
      };
59

    
60
  public static final float REX_D = 0.2f;
61

    
62
  private ScrambleState[] mStates;
63
  private int[] mBasicAngle;
64
  private Static4D[] mQuats;
65
  private float[][] mCuts;
66
  private boolean[][] mLayerRotatable;
67
  private int[][] mFaceMap;
68
  private ObjectSticker[] mStickers;
69
  private Movement mMovement;
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
74
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
75
    {
76
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
77
    }
78

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

    
81
  ScrambleState[] getScrambleStates()
82
    {
83
    if( mStates==null )
84
      {
85
      int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
86

    
87
      mStates = new ScrambleState[]
88
        {
89
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
90
        };
91
      }
92

    
93
    return mStates;
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  private void initializeQuats()
99
    {
100
    mQuats = new Static4D[]
101
         {
102
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
103
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
104
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
105
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
106

    
107
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
108
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
109
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
110
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
111
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
112
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
113
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
114
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
115
         };
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

    
120
  int[] getSolvedQuats(int cubit, int numLayers)
121
    {
122
    if( mQuats==null ) initializeQuats();
123
    int status = retCubitSolvedStatus(cubit,numLayers);
124
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  Static4D[] getQuats()
130
    {
131
    if( mQuats==null ) initializeQuats();
132
    return mQuats;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  int getSolvedFunctionIndex()
138
    {
139
    return 0;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  int getNumStickerTypes(int numLayers)
145
    {
146
    return 3;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  float[][] getCuts(int numLayers)
152
    {
153
    if( mCuts==null )
154
      {
155
      float C = SQ3*0.45f; // bit less than 1/2 of the length of the main diagonal
156
      float[] cut = new float[] {-C,+C};
157
      mCuts = new float[][] { cut,cut,cut,cut };
158
      }
159

    
160
    return mCuts;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  private void getLayerRotatable(int numLayers)
166
    {
167
    if( mLayerRotatable==null )
168
      {
169
      int numAxis = ROT_AXIS.length;
170
      boolean[] tmp = new boolean[] {true,false,true};
171
      mLayerRotatable = new boolean[numAxis][];
172
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
173
      }
174
    }
175

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

    
178
  int getNumCubitFaces()
179
    {
180
    return 6;
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  float[][] getCubitPositions(int numLayers)
186
    {
187
    final float DIST1= 1.50f;
188
    final float DIST2= (1+2*REX_D)/2;
189
    final float DIST3= 1.53f;
190

    
191
    final float[][] CENTERS = new float[24+6+12][];
192

    
193
    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
194
    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
195
    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
196
    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
197
    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
198
    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
199
    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
200
    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
201
    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
202
    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
203
    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
204
    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
205
    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
206
    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
207
    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
208
    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
209
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
210
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
211
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
212
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
213
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
214
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
215
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
216
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
217

    
218
    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
219
    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
220
    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
221
    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
222
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
223
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
224

    
225
    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
226
    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
227
    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
228
    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
229
    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
230
    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
231
    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
232
    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
233
    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
234
    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
235
    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
236
    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
237

    
238
    return CENTERS;
239
    }
240

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

    
243
  ObjectShape getObjectShape(int cubit, int numLayers)
244
    {
245
    int variant = getCubitVariant(cubit,numLayers);
246

    
247
    if( variant==0 )
248
      {
249
      float G = (1-REX_D)*SQ2/2;
250
      double[][] vertices ={{-0.10f,0.70f,0},{-0.70f,0.10f,0},{+0.65f,-0.71f,0},{+0.71f,-0.65f,0}};
251
      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
252
      float[][] centers= new float[][] { {0.0f,0.0f,-G} };
253
      float[][] corners= new float[][] { {0.03f,0.30f} };
254
      int[] indices= {-1,-1,0,0};
255
      int[] bandIndices= new int[] { 0,1 };
256
      float[][] bands = { {+0.016f,10,G/3,0.5f,5,1,1},{+0.230f,45,G/3,0.0f,2,0,0} };
257

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

    
269
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
270
      }
271
    else
272
      {
273
      float E = 1.5f - 3*REX_D;
274
      float F = 1.5f;
275
      float G = (float)Math.sqrt(E*E+F*F);
276
      double[][] vertices = { { -F, 0, 0 },{  0,-E, 0 },{ +F, 0, 0 },{  0, 0,-E } };
277
      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
278
      float[][] centers= new float[][] { {0.0f,-1.5f,-1.5f} };
279
      float[][] corners= new float[][] { {0.06f,0.20f} };
280
      int[] indices= {0,-1,0,-1};
281
      int[] bandIndices= new int[] { 0,0,1,1 };
282
      float[][] bands = { {0.03f,27,F/3,0.8f,5,2,3},{0.01f,45,G/3,0.2f,3,1,2} };
283

    
284
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
285
      }
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  Static4D getQuat(int cubit, int numLayers)
291
    {
292
    if( mQuats==null ) initializeQuats();
293

    
294
    switch(cubit)
295
      {
296
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
297
      case  1: return mQuats[5];
298
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
299
      case  3: return mQuats[8];
300
      case  4: return mQuats[6];
301
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
302
      case  6: return mQuats[11];
303
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
304
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
305
      case  9: return mQuats[10];
306
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
307
      case 11: return mQuats[4];
308
      case 12: return mQuats[9];
309
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
310
      case 14: return mQuats[7];
311
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
312
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
313
      case 17: return mQuats[0];
314
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
315
      case 19: return mQuats[3];
316
      case 20: return mQuats[1];
317
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
318
      case 22: return mQuats[2];
319
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
320

    
321
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
322
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
323
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
324
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
325
      case 28: return mQuats[0];
326
      case 29: return mQuats[1];
327

    
328
      case 30: return mQuats[0];
329
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
330
      case 32: return mQuats[3];
331
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
332
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
333
      case 35: return mQuats[7];
334
      case 36: return mQuats[9];
335
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
336
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
337
      case 39: return mQuats[8];
338
      case 40: return mQuats[1];
339
      case 41: return mQuats[6];
340
      }
341

    
342
    return mQuats[0];
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  int getNumCubitVariants(int numLayers)
348
    {
349
    return 3;
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  int getCubitVariant(int cubit, int numLayers)
355
    {
356
    return cubit<24 ? 0 : (cubit<30?1:2);
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  int getFaceColor(int cubit, int cubitface, int numLayers)
362
    {
363
    if( mFaceMap==null )
364
      {
365
      mFaceMap = new int[][]
366
         {
367
           {  0, 18,18,18,18,18 },
368
           {  0, 18,18,18,18,18 },
369
           {  0, 18,18,18,18,18 },
370
           {  0, 18,18,18,18,18 },
371
           {  1, 18,18,18,18,18 },
372
           {  1, 18,18,18,18,18 },
373
           {  1, 18,18,18,18,18 },
374
           {  1, 18,18,18,18,18 },
375
           {  2, 18,18,18,18,18 },
376
           {  2, 18,18,18,18,18 },
377
           {  2, 18,18,18,18,18 },
378
           {  2, 18,18,18,18,18 },
379
           {  3, 18,18,18,18,18 },
380
           {  3, 18,18,18,18,18 },
381
           {  3, 18,18,18,18,18 },
382
           {  3, 18,18,18,18,18 },
383
           {  4, 18,18,18,18,18 },
384
           {  4, 18,18,18,18,18 },
385
           {  4, 18,18,18,18,18 },
386
           {  4, 18,18,18,18,18 },
387
           {  5, 18,18,18,18,18 },
388
           {  5, 18,18,18,18,18 },
389
           {  5, 18,18,18,18,18 },
390
           {  5, 18,18,18,18,18 },
391

    
392
           {  6, 18,18,18,18,18 },
393
           {  7, 18,18,18,18,18 },
394
           {  8, 18,18,18,18,18 },
395
           {  9, 18,18,18,18,18 },
396
           { 10, 18,18,18,18,18 },
397
           { 11, 18,18,18,18,18 },
398

    
399
           { 16,14, 18,18,18,18 },
400
           { 16,12, 18,18,18,18 },
401
           { 16,15, 18,18,18,18 },
402
           { 16,13, 18,18,18,18 },
403
           { 12,14, 18,18,18,18 },
404
           { 15,12, 18,18,18,18 },
405
           { 15,13, 18,18,18,18 },
406
           { 13,14, 18,18,18,18 },
407
           { 14,17, 18,18,18,18 },
408
           { 12,17, 18,18,18,18 },
409
           { 17,15, 18,18,18,18 },
410
           { 13,17, 18,18,18,18 },
411
         };
412
      }
413

    
414
    return mFaceMap[cubit][cubitface];
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

    
419
  ObjectSticker retSticker(int face)
420
    {
421
    if( mStickers==null )
422
      {
423
      float[][] STICKERS = new float[][]
424
          {
425
             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
426
             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
427
             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
428
          };
429

    
430
      final float F = (float)(Math.PI/20);
431
      final float R1= 0.02f;
432
      final float R2= 0.09f;
433
      final float R3= 0.06f;
434
      final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
435
      final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
436
      final float[] strokes = { 0.06f, 0.07f, 0.05f };
437

    
438
      mStickers = new ObjectSticker[STICKERS.length];
439

    
440
      for(int s=0; s<STICKERS.length; s++)
441
        {
442
        mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
443
        }
444
      }
445

    
446
    return mStickers[face/NUM_FACE_COLORS];
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450
// PUBLIC API
451

    
452
  public Static3D[] getRotationAxis()
453
    {
454
    return ROT_AXIS;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  public Movement getMovement()
460
    {
461
    if( mMovement==null )
462
      {
463
      int numLayers = getNumLayers();
464
      if( mCuts==null ) getCuts(numLayers);
465
      getLayerRotatable(numLayers);
466
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
467
      }
468
    return mMovement;
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  public int[] getBasicAngle()
474
    {
475
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
476
    return mBasicAngle;
477
    }
478

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480

    
481
  public int getObjectName(int numLayers)
482
    {
483
    return R.string.rex3;
484
    }
485

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

    
488
  public int getInventor(int numLayers)
489
    {
490
    return R.string.rex3_inventor;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public int getComplexity(int numLayers)
496
    {
497
    return 3;
498
    }
499
}
(33-33/38)