Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ 7ee89540

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[][][] ENABLED = new int[][][]
49
      {
50
          {{0,1},{3,1},{2,3},{0,2}},
51
          {{2,3},{3,1},{0,1},{0,2}},
52
          {{1,2},{0,1},{0,3},{2,3}},
53
          {{1,2},{2,3},{0,3},{0,1}},
54
          {{0,3},{0,2},{1,2},{1,3}},
55
          {{1,2},{0,2},{0,3},{1,3}},
56
      };
57

    
58
  public static final float REX_D = 0.2f;
59

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

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

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

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

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

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

    
91
    return mStates;
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

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

    
105
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
106
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
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
         };
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

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

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

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

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  int getSolvedFunctionIndex()
136
    {
137
    return 0;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  int getNumStickerTypes(int numLayers)
143
    {
144
    return 3;
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

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

    
158
    return mCuts;
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

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

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

    
176
  int getNumCubitFaces()
177
    {
178
    return 6;
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

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

    
189
    final float[][] CENTERS = new float[24+6+12][];
190

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

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

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

    
236
    return CENTERS;
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  ObjectShape getObjectShape(int cubit, int numLayers)
242
    {
243
    int variant = getCubitVariant(cubit,numLayers);
244

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

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

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

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

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

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

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

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

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

    
340
    return mQuats[0];
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  int getNumCubitVariants(int numLayers)
346
    {
347
    return 3;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

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

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

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

    
390
           {  6, 18,18,18,18,18 },
391
           {  7, 18,18,18,18,18 },
392
           {  8, 18,18,18,18,18 },
393
           {  9, 18,18,18,18,18 },
394
           { 10, 18,18,18,18,18 },
395
           { 11, 18,18,18,18,18 },
396

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

    
412
    return mFaceMap[cubit][cubitface];
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

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

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

    
436
      mStickers = new ObjectSticker[STICKERS.length];
437

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

    
444
    return mStickers[face/NUM_FACE_COLORS];
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
// PUBLIC API
449

    
450
  public Static3D[] getRotationAxis()
451
    {
452
    return ROT_AXIS;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

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

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

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

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

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

    
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485

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

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

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