Project

General

Profile

Download (18.9 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyRex.java @ a57e6870

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.objectlib.objects;
21

    
22
import static org.distorted.objectlib.main.Movement.TYPE_SPLIT_CORNER;
23

    
24
import android.content.res.Resources;
25

    
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

    
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40
import org.distorted.objectlib.main.Twisty6;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class TwistyRex extends Twisty6
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
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
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
52
         };
53

    
54
  private static final int[][][] ENABLED = new int[][][]
55
      {
56
          {{0,1},{3,1},{2,3},{0,2}},
57
          {{2,3},{3,1},{0,1},{0,2}},
58
          {{1,2},{0,1},{0,3},{2,3}},
59
          {{1,2},{2,3},{0,3},{0,1}},
60
          {{0,3},{0,2},{1,2},{1,3}},
61
          {{1,2},{0,2},{0,3},{1,3}},
62
      };
63

    
64
  public static final float REX_D = 0.2f;
65

    
66
  private ScrambleState[] mStates;
67
  private int[] mBasicAngle;
68
  private Static4D[] mQuats;
69
  private float[][] mCuts;
70
  private boolean[][] mLayerRotatable;
71
  private int[][] mFaceMap;
72
  private ObjectSticker[] mStickers;
73
  private Movement mMovement;
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  public TwistyRex(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
78
                   MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
79
    {
80
    super(numL, numL[0], quat, move, texture, mesh, effects, res, scrWidth);
81
    }
82

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

    
85
  protected ScrambleState[] getScrambleStates()
86
    {
87
    if( mStates==null )
88
      {
89
      int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
90

    
91
      mStates = new ScrambleState[]
92
        {
93
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
94
        };
95
      }
96

    
97
    return mStates;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  protected int getResource(int[] numLayers)
103
    {
104
    return R.raw.rex;
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
  private void initializeQuats()
110
    {
111
    mQuats = new Static4D[]
112
         {
113
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
114
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
115
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
116
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
117

    
118
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
119
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
120
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
121
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
122
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
123
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
124
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
125
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
126
         };
127
    }
128

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

    
131
  protected int[] getSolvedQuats(int cubit, int[] numLayers)
132
    {
133
    if( mQuats==null ) initializeQuats();
134
    int status = retCubitSolvedStatus(cubit,numLayers);
135
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  protected Static4D[] getQuats()
141
    {
142
    if( mQuats==null ) initializeQuats();
143
    return mQuats;
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  protected int getSolvedFunctionIndex()
149
    {
150
    return 0;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  protected int getNumStickerTypes(int[] numLayers)
156
    {
157
    return 3;
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  protected float[][] getCuts(int[] numLayers)
163
    {
164
    if( mCuts==null )
165
      {
166
      float C = SQ3*0.45f; // bit less than 1/2 of the length of the main diagonal
167
      float[] cut = new float[] {-C,+C};
168
      mCuts = new float[][] { cut,cut,cut,cut };
169
      }
170

    
171
    return mCuts;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  private void getLayerRotatable(int[] numLayers)
177
    {
178
    if( mLayerRotatable==null )
179
      {
180
      int numAxis = ROT_AXIS.length;
181
      boolean[] tmp = new boolean[] {true,false,true};
182
      mLayerRotatable = new boolean[numAxis][];
183
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
184
      }
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  protected int getNumCubitFaces()
190
    {
191
    return 6;
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  protected float[][] getCubitPositions(int[] numLayers)
197
    {
198
    final float DIST1= 1.50f;
199
    final float DIST2= (1+2*REX_D)/2;
200
    final float DIST3= 1.53f;
201

    
202
    final float[][] CENTERS = new float[24+6+12][];
203

    
204
    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
205
    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
206
    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
207
    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
208
    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
209
    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
210
    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
211
    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
212
    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
213
    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
214
    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
215
    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
216
    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
217
    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
218
    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
219
    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
220
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
221
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
222
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
223
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
224
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
225
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
226
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
227
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
228

    
229
    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
230
    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
231
    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
232
    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
233
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
234
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
235

    
236
    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
237
    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
238
    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
239
    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
240
    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
241
    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
242
    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
243
    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
244
    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
245
    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
246
    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
247
    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
248

    
249
    return CENTERS;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  protected ObjectShape getObjectShape(int cubit, int[] numLayers)
255
    {
256
    int variant = getCubitVariant(cubit,numLayers);
257

    
258
    if( variant==0 )
259
      {
260
      float G = (1-REX_D)*SQ2/2;
261
      double[][] vertices ={{-0.10f,0.70f,0},{-0.70f,0.10f,0},{+0.65f,-0.71f,0},{+0.71f,-0.65f,0}};
262
      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
263
      float[][] centers= new float[][] { {0.0f,0.0f,-G} };
264
      float[][] corners= new float[][] { {0.03f,0.30f} };
265
      int[] indices= {-1,-1,0,0};
266
      int[] bandIndices= new int[] { 0,1 };
267
      float[][] bands = { {+0.016f,10,G/3,0.5f,5,1,1},{+0.230f,45,G/3,0.0f,2,0,0} };
268

    
269
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
270
      }
271
    else if( variant==1 )
272
      {
273
      float G = 3*REX_D;
274
      double[][] vertices= { { -G, 0, 0 },{ 0, -G, 0 },{ +G, 0, 0 },{ 0,+G,0 } };
275
      int[][] vertIndexes= { {0,1,2,3},{3,2,1,0} };
276
      int[] indices= {-1,-1,-1,-1};
277
      int[] bandIndices= new int[] { 0,1 };
278
      float[][] bands = { {0.025f,10,G/2,0.5f,5,0,0},{0.000f,45,G/2,0.0f,2,0,0} };
279

    
280
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
281
      }
282
    else
283
      {
284
      float E = 1.5f - 3*REX_D;
285
      float F = 1.5f;
286
      float G = (float)Math.sqrt(E*E+F*F);
287
      double[][] vertices = { { -F, 0, 0 },{  0,-E, 0 },{ +F, 0, 0 },{  0, 0,-E } };
288
      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
289
      float[][] centers= new float[][] { {0.0f,-1.5f,-1.5f} };
290
      float[][] corners= new float[][] { {0.06f,0.20f} };
291
      int[] indices= {0,-1,0,-1};
292
      int[] bandIndices= new int[] { 0,0,1,1 };
293
      float[][] bands = { {0.03f,27,F/3,0.8f,5,2,3},{0.01f,45,G/3,0.2f,3,1,2} };
294

    
295
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
296
      }
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  protected Static4D getQuat(int cubit, int[] numLayers)
302
    {
303
    if( mQuats==null ) initializeQuats();
304

    
305
    switch(cubit)
306
      {
307
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
308
      case  1: return mQuats[5];
309
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
310
      case  3: return mQuats[8];
311
      case  4: return mQuats[6];
312
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
313
      case  6: return mQuats[11];
314
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
315
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
316
      case  9: return mQuats[10];
317
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
318
      case 11: return mQuats[4];
319
      case 12: return mQuats[9];
320
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
321
      case 14: return mQuats[7];
322
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
323
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
324
      case 17: return mQuats[0];
325
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
326
      case 19: return mQuats[3];
327
      case 20: return mQuats[1];
328
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
329
      case 22: return mQuats[2];
330
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
331

    
332
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
333
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
334
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
335
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
336
      case 28: return mQuats[0];
337
      case 29: return mQuats[1];
338

    
339
      case 30: return mQuats[0];
340
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
341
      case 32: return mQuats[3];
342
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
343
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
344
      case 35: return mQuats[7];
345
      case 36: return mQuats[9];
346
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
347
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
348
      case 39: return mQuats[8];
349
      case 40: return mQuats[1];
350
      case 41: return mQuats[6];
351
      }
352

    
353
    return mQuats[0];
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  protected int getNumCubitVariants(int[] numLayers)
359
    {
360
    return 3;
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  protected int getCubitVariant(int cubit, int[] numLayers)
366
    {
367
    return cubit<24 ? 0 : (cubit<30?1:2);
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
373
    {
374
    if( mFaceMap==null )
375
      {
376
      mFaceMap = new int[][]
377
         {
378
           {  0, 18,18,18,18,18 },
379
           {  0, 18,18,18,18,18 },
380
           {  0, 18,18,18,18,18 },
381
           {  0, 18,18,18,18,18 },
382
           {  1, 18,18,18,18,18 },
383
           {  1, 18,18,18,18,18 },
384
           {  1, 18,18,18,18,18 },
385
           {  1, 18,18,18,18,18 },
386
           {  2, 18,18,18,18,18 },
387
           {  2, 18,18,18,18,18 },
388
           {  2, 18,18,18,18,18 },
389
           {  2, 18,18,18,18,18 },
390
           {  3, 18,18,18,18,18 },
391
           {  3, 18,18,18,18,18 },
392
           {  3, 18,18,18,18,18 },
393
           {  3, 18,18,18,18,18 },
394
           {  4, 18,18,18,18,18 },
395
           {  4, 18,18,18,18,18 },
396
           {  4, 18,18,18,18,18 },
397
           {  4, 18,18,18,18,18 },
398
           {  5, 18,18,18,18,18 },
399
           {  5, 18,18,18,18,18 },
400
           {  5, 18,18,18,18,18 },
401
           {  5, 18,18,18,18,18 },
402

    
403
           {  6, 18,18,18,18,18 },
404
           {  7, 18,18,18,18,18 },
405
           {  8, 18,18,18,18,18 },
406
           {  9, 18,18,18,18,18 },
407
           { 10, 18,18,18,18,18 },
408
           { 11, 18,18,18,18,18 },
409

    
410
           { 16,14, 18,18,18,18 },
411
           { 16,12, 18,18,18,18 },
412
           { 16,15, 18,18,18,18 },
413
           { 16,13, 18,18,18,18 },
414
           { 12,14, 18,18,18,18 },
415
           { 15,12, 18,18,18,18 },
416
           { 15,13, 18,18,18,18 },
417
           { 13,14, 18,18,18,18 },
418
           { 14,17, 18,18,18,18 },
419
           { 12,17, 18,18,18,18 },
420
           { 17,15, 18,18,18,18 },
421
           { 13,17, 18,18,18,18 },
422
         };
423
      }
424

    
425
    return mFaceMap[cubit][cubitface];
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  protected ObjectSticker retSticker(int face)
431
    {
432
    if( mStickers==null )
433
      {
434
      float[][] STICKERS = new float[][]
435
          {
436
             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
437
             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
438
             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
439
          };
440

    
441
      final float F = (float)(Math.PI/20);
442
      final float R1= 0.02f;
443
      final float R2= 0.09f;
444
      final float R3= 0.06f;
445
      final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
446
      final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
447
      final float[] strokes = { 0.06f, 0.07f, 0.05f };
448

    
449
      if( ObjectControl.isInIconMode() )
450
        {
451
        float mult = 1.5f;
452
        strokes[0]*=mult;
453
        strokes[1]*=mult;
454
        strokes[2]*=mult;
455
        }
456

    
457
      mStickers = new ObjectSticker[STICKERS.length];
458

    
459
      for(int s=0; s<STICKERS.length; s++)
460
        {
461
        mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
462
        }
463
      }
464

    
465
    return mStickers[face/NUM_FACE_COLORS];
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469
// PUBLIC API
470

    
471
  public Static3D[] getRotationAxis()
472
    {
473
    return ROT_AXIS;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public Movement getMovement()
479
    {
480
    if( mMovement==null )
481
      {
482
      int[] numLayers = getNumLayers();
483
      if( mCuts==null ) getCuts(numLayers);
484
      getLayerRotatable(numLayers);
485
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers[0],TYPE_SPLIT_CORNER,ENABLED);
486
      }
487
    return mMovement;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public int[] getBasicAngle()
493
    {
494
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
495
    return mBasicAngle;
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

    
500
  public ObjectType intGetObjectType(int[] numLayers)
501
    {
502
    return ObjectType.REX_3;
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

    
507
  public int getObjectName(int[] numLayers)
508
    {
509
    return R.string.rex3;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

    
514
  public int getInventor(int[] numLayers)
515
    {
516
    return R.string.rex3_inventor;
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

    
521
  public int getComplexity(int[] numLayers)
522
    {
523
    return 3;
524
    }
525
}
(20-20/25)