Project

General

Profile

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

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

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.ObjectList;
36
import org.distorted.objectlib.main.ObjectShape;
37
import org.distorted.objectlib.main.ObjectSticker;
38
import org.distorted.objectlib.main.ScrambleState;
39
import org.distorted.objectlib.main.Twisty6;
40
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
43
public class TwistyRex extends Twisty6
44
{
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[][][] ENABLED = new int[][][]
54
      {
55
          {{0,1},{3,1},{2,3},{0,2}},
56
          {{2,3},{3,1},{0,1},{0,2}},
57
          {{1,2},{0,1},{0,3},{2,3}},
58
          {{1,2},{2,3},{0,3},{0,1}},
59
          {{0,3},{0,2},{1,2},{1,3}},
60
          {{1,2},{0,2},{0,3},{1,3}},
61
      };
62
63
  public static final float REX_D = 0.2f;
64
65
  private ScrambleState[] mStates;
66
  private int[] mBasicAngle;
67
  private Static4D[] mQuats;
68
  private float[][] mCuts;
69
  private boolean[][] mLayerRotatable;
70
  private int[][] mFaceMap;
71
  private ObjectSticker[] mStickers;
72
  private Movement mMovement;
73
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75
76
  public TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
77
                   DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
78
    {
79
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
80
    }
81
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83
84
  protected ScrambleState[] getScrambleStates()
85
    {
86
    if( mStates==null )
87
      {
88
      int[] tmp = {0,-1,0, 0,1,0, 2,-1,0, 2,1,0 };
89
90
      mStates = new ScrambleState[]
91
        {
92
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
93
        };
94
      }
95
96
    return mStates;
97
    }
98
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100
101
  private void initializeQuats()
102
    {
103
    mQuats = new Static4D[]
104
         {
105
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
106
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
107
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
108
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
109
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
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
116
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
117
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
118
         };
119
    }
120
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122
123
  protected int[] getSolvedQuats(int cubit, int numLayers)
124
    {
125
    if( mQuats==null ) initializeQuats();
126
    int status = retCubitSolvedStatus(cubit,numLayers);
127
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
128
    }
129
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
132
  protected Static4D[] getQuats()
133
    {
134
    if( mQuats==null ) initializeQuats();
135
    return mQuats;
136
    }
137
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140
  protected int getSolvedFunctionIndex()
141
    {
142
    return 0;
143
    }
144
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
147
  protected int getNumStickerTypes(int numLayers)
148
    {
149
    return 3;
150
    }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154
  protected float[][] getCuts(int numLayers)
155
    {
156
    if( mCuts==null )
157
      {
158
      float C = SQ3*0.45f; // bit less than 1/2 of the length of the main diagonal
159
      float[] cut = new float[] {-C,+C};
160
      mCuts = new float[][] { cut,cut,cut,cut };
161
      }
162
163
    return mCuts;
164
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  private void getLayerRotatable(int numLayers)
169
    {
170
    if( mLayerRotatable==null )
171
      {
172
      int numAxis = ROT_AXIS.length;
173
      boolean[] tmp = new boolean[] {true,false,true};
174
      mLayerRotatable = new boolean[numAxis][];
175
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
176
      }
177
    }
178
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
181
  protected int getNumCubitFaces()
182
    {
183
    return 6;
184
    }
185
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187
188
  protected float[][] getCubitPositions(int numLayers)
189
    {
190
    final float DIST1= 1.50f;
191
    final float DIST2= (1+2*REX_D)/2;
192
    final float DIST3= 1.53f;
193
194
    final float[][] CENTERS = new float[24+6+12][];
195
196
    CENTERS[ 0] = new float[] { +DIST3, +DIST2, +DIST2};
197
    CENTERS[ 1] = new float[] { +DIST3, +DIST2, -DIST2};
198
    CENTERS[ 2] = new float[] { +DIST3, -DIST2, -DIST2};
199
    CENTERS[ 3] = new float[] { +DIST3, -DIST2, +DIST2};
200
    CENTERS[ 4] = new float[] { -DIST3, +DIST2, +DIST2};
201
    CENTERS[ 5] = new float[] { -DIST3, +DIST2, -DIST2};
202
    CENTERS[ 6] = new float[] { -DIST3, -DIST2, -DIST2};
203
    CENTERS[ 7] = new float[] { -DIST3, -DIST2, +DIST2};
204
    CENTERS[ 8] = new float[] { +DIST2, +DIST3, +DIST2};
205
    CENTERS[ 9] = new float[] { +DIST2, +DIST3, -DIST2};
206
    CENTERS[10] = new float[] { -DIST2, +DIST3, -DIST2};
207
    CENTERS[11] = new float[] { -DIST2, +DIST3, +DIST2};
208
    CENTERS[12] = new float[] { +DIST2, -DIST3, +DIST2};
209
    CENTERS[13] = new float[] { +DIST2, -DIST3, -DIST2};
210
    CENTERS[14] = new float[] { -DIST2, -DIST3, -DIST2};
211
    CENTERS[15] = new float[] { -DIST2, -DIST3, +DIST2};
212
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST3};
213
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST3};
214
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST3};
215
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST3};
216
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST3};
217
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST3};
218
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST3};
219
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST3};
220
221
    CENTERS[24] = new float[] { +DIST3, +0.00f, +0.00f};
222
    CENTERS[25] = new float[] { -DIST3, +0.00f, +0.00f};
223
    CENTERS[26] = new float[] { +0.00f, +DIST3, +0.00f};
224
    CENTERS[27] = new float[] { +0.00f, -DIST3, +0.00f};
225
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST3};
226
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST3};
227
228
    CENTERS[30] = new float[] { +0.00f, +DIST1, +DIST1};
229
    CENTERS[31] = new float[] { +DIST1, +0.00f, +DIST1};
230
    CENTERS[32] = new float[] { +0.00f, -DIST1, +DIST1};
231
    CENTERS[33] = new float[] { -DIST1, +0.00f, +DIST1};
232
    CENTERS[34] = new float[] { +DIST1, +DIST1, +0.00f};
233
    CENTERS[35] = new float[] { +DIST1, -DIST1, +0.00f};
234
    CENTERS[36] = new float[] { -DIST1, -DIST1, +0.00f};
235
    CENTERS[37] = new float[] { -DIST1, +DIST1, +0.00f};
236
    CENTERS[38] = new float[] { +0.00f, +DIST1, -DIST1};
237
    CENTERS[39] = new float[] { +DIST1, +0.00f, -DIST1};
238
    CENTERS[40] = new float[] { +0.00f, -DIST1, -DIST1};
239
    CENTERS[41] = new float[] { -DIST1, +0.00f, -DIST1};
240
241
    return CENTERS;
242
    }
243
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246
  protected ObjectShape getObjectShape(int cubit, int numLayers)
247
    {
248
    int variant = getCubitVariant(cubit,numLayers);
249
250
    if( variant==0 )
251
      {
252
      float G = (1-REX_D)*SQ2/2;
253
      double[][] vertices ={{-0.10f,0.70f,0},{-0.70f,0.10f,0},{+0.65f,-0.71f,0},{+0.71f,-0.65f,0}};
254
      int[][] vertIndexes = { {0,1,2,3},{3,2,1,0} };
255
      float[][] centers= new float[][] { {0.0f,0.0f,-G} };
256
      float[][] corners= new float[][] { {0.03f,0.30f} };
257
      int[] indices= {-1,-1,0,0};
258
      int[] bandIndices= new int[] { 0,1 };
259
      float[][] bands = { {+0.016f,10,G/3,0.5f,5,1,1},{+0.230f,45,G/3,0.0f,2,0,0} };
260
261
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
262
      }
263
    else if( variant==1 )
264
      {
265
      float G = 3*REX_D;
266
      double[][] vertices= { { -G, 0, 0 },{ 0, -G, 0 },{ +G, 0, 0 },{ 0,+G,0 } };
267
      int[][] vertIndexes= { {0,1,2,3},{3,2,1,0} };
268
      int[] indices= {-1,-1,-1,-1};
269
      int[] bandIndices= new int[] { 0,1 };
270
      float[][] bands = { {0.025f,10,G/2,0.5f,5,0,0},{0.000f,45,G/2,0.0f,2,0,0} };
271
272
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,null,indices,null,indices,getNumCubitFaces(), null);
273
      }
274
    else
275
      {
276
      float E = 1.5f - 3*REX_D;
277
      float F = 1.5f;
278
      float G = (float)Math.sqrt(E*E+F*F);
279
      double[][] vertices = { { -F, 0, 0 },{  0,-E, 0 },{ +F, 0, 0 },{  0, 0,-E } };
280
      int[][] vertIndexes = { {0,1,2}, {0,2,3}, {0,3,1}, {1,3,2} };
281
      float[][] centers= new float[][] { {0.0f,-1.5f,-1.5f} };
282
      float[][] corners= new float[][] { {0.06f,0.20f} };
283
      int[] indices= {0,-1,0,-1};
284
      int[] bandIndices= new int[] { 0,0,1,1 };
285
      float[][] bands = { {0.03f,27,F/3,0.8f,5,2,3},{0.01f,45,G/3,0.2f,3,1,2} };
286
287
      return new ObjectShape(vertices,vertIndexes,bands,bandIndices,corners,indices,centers,indices,getNumCubitFaces(), null);
288
      }
289
    }
290
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293
  protected Static4D getQuat(int cubit, int numLayers)
294
    {
295
    if( mQuats==null ) initializeQuats();
296
297
    switch(cubit)
298
      {
299
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
300
      case  1: return mQuats[5];
301
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
302
      case  3: return mQuats[8];
303
      case  4: return mQuats[6];
304
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
305
      case  6: return mQuats[11];
306
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
307
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
308
      case  9: return mQuats[10];
309
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
310
      case 11: return mQuats[4];
311
      case 12: return mQuats[9];
312
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
313
      case 14: return mQuats[7];
314
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
315
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
316
      case 17: return mQuats[0];
317
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
318
      case 19: return mQuats[3];
319
      case 20: return mQuats[1];
320
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
321
      case 22: return mQuats[2];
322
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
323
324
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
325
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
326
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
327
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
328
      case 28: return mQuats[0];
329
      case 29: return mQuats[1];
330
331
      case 30: return mQuats[0];
332
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
333
      case 32: return mQuats[3];
334
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
335
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
336
      case 35: return mQuats[7];
337
      case 36: return mQuats[9];
338
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
339
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
340
      case 39: return mQuats[8];
341
      case 40: return mQuats[1];
342
      case 41: return mQuats[6];
343
      }
344
345
    return mQuats[0];
346
    }
347
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350
  protected int getNumCubitVariants(int numLayers)
351
    {
352
    return 3;
353
    }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
357
  protected int getCubitVariant(int cubit, int numLayers)
358
    {
359
    return cubit<24 ? 0 : (cubit<30?1:2);
360
    }
361
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
365
    {
366
    if( mFaceMap==null )
367
      {
368
      mFaceMap = new int[][]
369
         {
370
           {  0, 18,18,18,18,18 },
371
           {  0, 18,18,18,18,18 },
372
           {  0, 18,18,18,18,18 },
373
           {  0, 18,18,18,18,18 },
374
           {  1, 18,18,18,18,18 },
375
           {  1, 18,18,18,18,18 },
376
           {  1, 18,18,18,18,18 },
377
           {  1, 18,18,18,18,18 },
378
           {  2, 18,18,18,18,18 },
379
           {  2, 18,18,18,18,18 },
380
           {  2, 18,18,18,18,18 },
381
           {  2, 18,18,18,18,18 },
382
           {  3, 18,18,18,18,18 },
383
           {  3, 18,18,18,18,18 },
384
           {  3, 18,18,18,18,18 },
385
           {  3, 18,18,18,18,18 },
386
           {  4, 18,18,18,18,18 },
387
           {  4, 18,18,18,18,18 },
388
           {  4, 18,18,18,18,18 },
389
           {  4, 18,18,18,18,18 },
390
           {  5, 18,18,18,18,18 },
391
           {  5, 18,18,18,18,18 },
392
           {  5, 18,18,18,18,18 },
393
           {  5, 18,18,18,18,18 },
394
395
           {  6, 18,18,18,18,18 },
396
           {  7, 18,18,18,18,18 },
397
           {  8, 18,18,18,18,18 },
398
           {  9, 18,18,18,18,18 },
399
           { 10, 18,18,18,18,18 },
400
           { 11, 18,18,18,18,18 },
401
402
           { 16,14, 18,18,18,18 },
403
           { 16,12, 18,18,18,18 },
404
           { 16,15, 18,18,18,18 },
405
           { 16,13, 18,18,18,18 },
406
           { 12,14, 18,18,18,18 },
407
           { 15,12, 18,18,18,18 },
408
           { 15,13, 18,18,18,18 },
409
           { 13,14, 18,18,18,18 },
410
           { 14,17, 18,18,18,18 },
411
           { 12,17, 18,18,18,18 },
412
           { 17,15, 18,18,18,18 },
413
           { 13,17, 18,18,18,18 },
414
         };
415
      }
416
417
    return mFaceMap[cubit][cubitface];
418
    }
419
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421
422
  protected ObjectSticker retSticker(int face)
423
    {
424
    if( mStickers==null )
425
      {
426
      float[][] STICKERS = new float[][]
427
          {
428
             { -0.5f, 0.1428f, -0.1428f, 0.5f, 0.35f, -0.35f },
429
             { -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f },
430
             { -0.525f, 0.105f, 0.525f, 0.105f, 0.000f, -0.210f  }
431
          };
432
433
      final float F = (float)(Math.PI/20);
434
      final float R1= 0.02f;
435
      final float R2= 0.09f;
436
      final float R3= 0.06f;
437
      final float[][] angles = { { -F/2,F,F },null,{ F/10,-F,-F } };
438
      final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
439
      final float[] strokes = { 0.06f, 0.07f, 0.05f };
440
441
      mStickers = new ObjectSticker[STICKERS.length];
442
443
      for(int s=0; s<STICKERS.length; s++)
444
        {
445
        mStickers[s] = new ObjectSticker(STICKERS[s],angles[s],radii[s],strokes[s]);
446
        }
447
      }
448
449
    return mStickers[face/NUM_FACE_COLORS];
450
    }
451
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453
// PUBLIC API
454
455
  public Static3D[] getRotationAxis()
456
    {
457
    return ROT_AXIS;
458
    }
459
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461
462
  public Movement getMovement()
463
    {
464
    if( mMovement==null )
465
      {
466
      int numLayers = getNumLayers();
467
      if( mCuts==null ) getCuts(numLayers);
468
      getLayerRotatable(numLayers);
469
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
470
      }
471
    return mMovement;
472
    }
473
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475
476
  public int[] getBasicAngle()
477
    {
478
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
479
    return mBasicAngle;
480
    }
481
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483
484
  public int getObjectName(int numLayers)
485
    {
486
    return R.string.rex3;
487
    }
488
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491
  public int getInventor(int numLayers)
492
    {
493
    return R.string.rex3_inventor;
494
    }
495
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  public int getComplexity(int numLayers)
499
    {
500
    return 3;
501
    }
502
}