Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCube.java @ 7ce20d2a

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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_NOT_SPLIT;
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 TwistyCube extends Twisty6
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(1,0,0),
49
           new Static3D(0,1,0),
50
           new Static3D(0,0,1)
51
         };
52

    
53
  private static final int[][][] ENABLED = new int[][][]
54
      {
55
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
56
      };
57

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

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  public TwistyCube(int size, Static4D quat, Static3D move, DistortedTexture texture,
69
                    MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
70
    {
71
    super(size, size, quat, move, texture, mesh, effects, res, scrWidth);
72
    }
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  protected ScrambleState[] getScrambleStates()
77
    {
78
    if( mStates==null )
79
      {
80
      int size = getNumLayers();
81
      int[][] m = new int[16][];
82
      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
83

    
84
      mStates = new ScrambleState[]
85
        {
86
        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
87
        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
88
        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
89
        new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
90
        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
91
        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
92
        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
93
        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
94
        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
95
        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
96
        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
97
        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
98
        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
99
        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
100
        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
101
        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
102
        };
103
      }
104

    
105
    return mStates;
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  protected int getResource(int numLayers)
111
    {
112
    switch(numLayers)
113
      {
114
      case 2: return R.raw.cube2;
115
      case 3: return R.raw.cube3;
116
      case 4: return R.raw.cube4;
117
      case 5: return R.raw.cube5;
118
      }
119

    
120
    return 0;
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
  private int[] createEdges(int size, int vertex)
126
    {
127
    int[] ret = new int[9*size];
128

    
129
    for(int l=0; l<size; l++)
130
      {
131
      ret[9*l  ] = l;
132
      ret[9*l+1] =-1;
133
      ret[9*l+2] = vertex;
134
      ret[9*l+3] = l;
135
      ret[9*l+4] = 1;
136
      ret[9*l+5] = vertex;
137
      ret[9*l+6] = l;
138
      ret[9*l+7] = 2;
139
      ret[9*l+8] = vertex;
140
      }
141

    
142
    return ret;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  private void initializeQuats()
148
    {
149
    mQuats = new Static4D[]
150
         {
151
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
152
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
153
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
154
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
155

    
156
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
157
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
158
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
159
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
160
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
161
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
162
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
163
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
164
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
165
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
166
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
167
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
168

    
169
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
170
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
171
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
172
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
173
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
174
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
175
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
176
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
177
         };
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  protected int[] getSolvedQuats(int cubit, int numLayers)
183
    {
184
    if( mQuats ==null ) initializeQuats();
185
    int status = retCubitSolvedStatus(cubit,numLayers);
186
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

    
191
  protected ObjectShape getObjectShape(int cubit, int numLayers)
192
    {
193
    int extraI, extraV, num;
194
    float height;
195

    
196
    switch(numLayers)
197
      {
198
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
199
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
200
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
201
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
202
      }
203

    
204
    double[][] vertices = new double[][]
205
          {
206
              { 0.5, 0.5, 0.5 },
207
              { 0.5, 0.5,-0.5 },
208
              { 0.5,-0.5, 0.5 },
209
              { 0.5,-0.5,-0.5 },
210
              {-0.5, 0.5, 0.5 },
211
              {-0.5, 0.5,-0.5 },
212
              {-0.5,-0.5, 0.5 },
213
              {-0.5,-0.5,-0.5 },
214
          };
215

    
216
    int[][] vert_indices = new int[][]
217
          {
218
              {2,3,1,0},
219
              {7,6,4,5},
220
              {4,0,1,5},
221
              {7,3,2,6},
222
              {6,2,0,4},
223
              {3,7,5,1}
224
          };
225

    
226
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
227
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
228
    float[][] corners   = new float[][] { {0.036f,0.12f} };
229
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
230
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
231
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
232

    
233
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
234
    }
235

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

    
238
  protected Static4D getQuat(int cubit, int numLayers)
239
    {
240
    if( mQuats ==null ) initializeQuats();
241
    return mQuats[0];
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  protected int getNumCubitVariants(int numLayers)
247
    {
248
    return 1;
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  protected int getCubitVariant(int cubit, int numLayers)
254
    {
255
    return 0;
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  protected ObjectSticker retSticker(int face)
261
    {
262
    if( mStickers==null )
263
      {
264
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
265
      final float radius = 0.10f;
266
      final float[] radii = {radius,radius,radius,radius};
267
      mStickers = new ObjectSticker[STICKERS.length];
268
      float stroke = 0.08f;
269

    
270
      if( ObjectControl.isInIconMode() )
271
        {
272
        switch(getNumLayers())
273
          {
274
          case 2: stroke*=1.8f; break;
275
          case 3: stroke*=2.0f; break;
276
          case 4: stroke*=2.1f; break;
277
          default:stroke*=2.2f; break;
278
          }
279
        }
280

    
281
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
282
      }
283

    
284
    return mStickers[face/NUM_FACE_COLORS];
285
    }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
  protected float[][] getCubitPositions(int numLayers)
290
    {
291
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
292
    float[][] tmp = new float[numCubits][];
293

    
294
    float diff = 0.5f*(numLayers-1);
295
    int currentPosition = 0;
296

    
297
    for(int x = 0; x<numLayers; x++)
298
      for(int y = 0; y<numLayers; y++)
299
        for(int z = 0; z<numLayers; z++)
300
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
301
            {
302
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
303
            }
304

    
305
    return tmp;
306
    }
307

    
308
///////////////////////////////////////////////////////////////////////////////////////////////////
309

    
310
  protected Static4D[] getQuats()
311
    {
312
    if( mQuats ==null ) initializeQuats();
313
    return mQuats;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  protected float[][] getCuts(int numLayers)
319
    {
320
    if( numLayers<2 ) return null;
321

    
322
    if( mCuts==null )
323
      {
324
      mCuts = new float[3][numLayers-1];
325

    
326
      for(int i=0; i<numLayers-1; i++)
327
        {
328
        float cut = (2-numLayers)*0.5f + i;
329
        mCuts[0][i] = cut;
330
        mCuts[1][i] = cut;
331
        mCuts[2][i] = cut;
332
        }
333
      }
334

    
335
    return mCuts;
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
  private void getLayerRotatable(int numLayers)
341
    {
342
    if( mLayerRotatable==null )
343
      {
344
      int numAxis = ROT_AXIS.length;
345
      boolean[] tmp = new boolean[numLayers];
346
      for(int i=0; i<numLayers; i++) tmp[i] = true;
347
      mLayerRotatable = new boolean[numAxis][];
348
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
349
      }
350
    }
351

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

    
354
  protected int getSolvedFunctionIndex()
355
    {
356
    return 0;
357
    }
358

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

    
361
  protected int getNumStickerTypes(int numLayers)
362
    {
363
    return 1;
364
    }
365

    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

    
368
  protected int getNumCubitFaces()
369
    {
370
    return 6;
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
376
    {
377
    return CUBITS[cubit].getRotRow(cubitface/2) == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
378
    }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381
// PUBLIC API
382

    
383
  public Static3D[] getRotationAxis()
384
    {
385
    return ROT_AXIS;
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  public Movement getMovement()
391
    {
392
    if( mMovement==null )
393
      {
394
      int numLayers = getNumLayers();
395
      if( mCuts==null ) getCuts(numLayers);
396
      getLayerRotatable(numLayers);
397
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
398
      }
399
    return mMovement;
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  public int[] getBasicAngle()
405
    {
406
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
407
    return mBasicAngle;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  public ObjectType intGetObjectType(int numLayers)
413
    {
414
    switch(numLayers)
415
      {
416
      case 2: return ObjectType.CUBE_2;
417
      case 3: return ObjectType.CUBE_3;
418
      case 4: return ObjectType.CUBE_4;
419
      case 5: return ObjectType.CUBE_5;
420
      }
421

    
422
    return ObjectType.CUBE_3;
423
    }
424

    
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

    
427
  public int getObjectName(int numLayers)
428
    {
429
    switch(numLayers)
430
      {
431
      case 2: return R.string.cube2;
432
      case 3: return R.string.cube3;
433
      case 4: return R.string.cube4;
434
      case 5: return R.string.cube5;
435
      }
436
    return R.string.cube3;
437
    }
438

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

    
441
  public int getInventor(int numLayers)
442
    {
443
    switch(numLayers)
444
      {
445
      case 2: return R.string.cube2_inventor;
446
      case 3: return R.string.cube3_inventor;
447
      case 4: return R.string.cube4_inventor;
448
      case 5: return R.string.cube5_inventor;
449
      }
450
    return R.string.cube3_inventor;
451
    }
452

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

    
455
  public int getComplexity(int numLayers)
456
    {
457
    switch(numLayers)
458
      {
459
      case 2: return 4;
460
      case 3: return 6;
461
      case 4: return 8;
462
      case 5: return 10;
463
      }
464
    return 6;
465
    }
466
}
(6-6/25)