Project

General

Profile

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

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

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.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 TwistyCube extends Twisty6
44
{
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(1,0,0),
48
           new Static3D(0,1,0),
49
           new Static3D(0,0,1)
50
         };
51
52
  private static final int[][][] ENABLED = new int[][][]
53
      {
54
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
55
      };
56
57
  private ScrambleState[] mStates;
58
  private Static4D[] mQuats;
59
  private float[][] mCuts;
60
  private boolean[][] mLayerRotatable;
61
  private int[] mBasicAngle;
62
  private ObjectSticker[] mStickers;
63
  private Movement mMovement;
64
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66
67
  public TwistyCube(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
68
                    DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
69
    {
70
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
71
    }
72
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74
75
  protected ScrambleState[] getScrambleStates()
76
    {
77
    if( mStates==null )
78
      {
79
      int size = getNumLayers();
80
      int[][] m = new int[16][];
81
      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
82
83
      mStates = new ScrambleState[]
84
        {
85
        new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  // 0
86
        new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  // x
87
        new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  // y
88
        new ScrambleState( new int[][] { m[ 8], m[ 8],  null } ),  // z
89
        new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  // xy
90
        new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  // xz
91
        new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  // yx
92
        new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  // yz
93
        new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  // zx
94
        new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  // zy
95
        new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // xyx
96
        new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // xzx
97
        new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // yxy
98
        new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // yzy
99
        new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // zxz
100
        new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // zyz
101
        };
102
      }
103
104
    return mStates;
105
    }
106
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108
109
  private int[] createEdges(int size, int vertex)
110
    {
111
    int[] ret = new int[9*size];
112
113
    for(int l=0; l<size; l++)
114
      {
115
      ret[9*l  ] = l;
116
      ret[9*l+1] =-1;
117
      ret[9*l+2] = vertex;
118
      ret[9*l+3] = l;
119
      ret[9*l+4] = 1;
120
      ret[9*l+5] = vertex;
121
      ret[9*l+6] = l;
122
      ret[9*l+7] = 2;
123
      ret[9*l+8] = vertex;
124
      }
125
126
    return ret;
127
    }
128
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
131
  private void initializeQuats()
132
    {
133
    mQuats = new Static4D[]
134
         {
135
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
136
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
137
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
138
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
139
140
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
141
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
142
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
143
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
144
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
145
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
146
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
147
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
148
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
149
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
150
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
151
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
152
153
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
154
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
155
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
156
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
157
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
158
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
159
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
160
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
161
         };
162
    }
163
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165
166
  protected int[] getSolvedQuats(int cubit, int numLayers)
167
    {
168
    if( mQuats ==null ) initializeQuats();
169
    int status = retCubitSolvedStatus(cubit,numLayers);
170
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
171
    }
172
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
  protected ObjectShape getObjectShape(int cubit, int numLayers)
176
    {
177
    int extraI, extraV, num;
178
    float height;
179
180
    switch(numLayers)
181
      {
182
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
183
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
184
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
185
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
186
      }
187
188
    double[][] vertices = new double[][]
189
          {
190
              { 0.5, 0.5, 0.5 },
191
              { 0.5, 0.5,-0.5 },
192
              { 0.5,-0.5, 0.5 },
193
              { 0.5,-0.5,-0.5 },
194
              {-0.5, 0.5, 0.5 },
195
              {-0.5, 0.5,-0.5 },
196
              {-0.5,-0.5, 0.5 },
197
              {-0.5,-0.5,-0.5 },
198
          };
199
200
    int[][] vert_indices = new int[][]
201
          {
202
              {2,3,1,0},
203
              {7,6,4,5},
204
              {4,0,1,5},
205
              {7,3,2,6},
206
              {6,2,0,4},
207
              {3,7,5,1}
208
          };
209
210
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
211
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
212
    float[][] corners   = new float[][] { {0.036f,0.12f} };
213
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
214
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
215
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
216
217
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
218
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  protected Static4D getQuat(int cubit, int numLayers)
223
    {
224
    if( mQuats ==null ) initializeQuats();
225
    return mQuats[0];
226
    }
227
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
230
  protected int getNumCubitVariants(int numLayers)
231
    {
232
    return 1;
233
    }
234
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236
237
  protected int getCubitVariant(int cubit, int numLayers)
238
    {
239
    return 0;
240
    }
241
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243
244
  protected ObjectSticker retSticker(int face)
245
    {
246
    if( mStickers==null )
247
      {
248
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
249
      final float radius = 0.10f;
250
      final float stroke = 0.08f;
251
      final float[] radii = {radius,radius,radius,radius};
252
      mStickers = new ObjectSticker[STICKERS.length];
253
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
254
      }
255
256
    return mStickers[face/NUM_FACE_COLORS];
257
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261
  protected float[][] getCubitPositions(int numLayers)
262
    {
263
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
264
    float[][] tmp = new float[numCubits][];
265
266
    float diff = 0.5f*(numLayers-1);
267
    int currentPosition = 0;
268
269
    for(int x = 0; x<numLayers; x++)
270
      for(int y = 0; y<numLayers; y++)
271
        for(int z = 0; z<numLayers; z++)
272
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
273
            {
274
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
275
            }
276
277
    return tmp;
278
    }
279
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281
282
  protected Static4D[] getQuats()
283
    {
284
    if( mQuats ==null ) initializeQuats();
285
    return mQuats;
286
    }
287
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
290
  protected float[][] getCuts(int numLayers)
291
    {
292
    if( numLayers<2 ) return null;
293
294
    if( mCuts==null )
295
      {
296
      mCuts = new float[3][numLayers-1];
297
298
      for(int i=0; i<numLayers-1; i++)
299
        {
300
        float cut = (2-numLayers)*0.5f + i;
301
        mCuts[0][i] = cut;
302
        mCuts[1][i] = cut;
303
        mCuts[2][i] = cut;
304
        }
305
      }
306
307
    return mCuts;
308
    }
309
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311
312
  private void getLayerRotatable(int numLayers)
313
    {
314
    if( mLayerRotatable==null )
315
      {
316
      int numAxis = ROT_AXIS.length;
317
      boolean[] tmp = new boolean[numLayers];
318
      for(int i=0; i<numLayers; i++) tmp[i] = true;
319
      mLayerRotatable = new boolean[numAxis][];
320
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
321
      }
322
    }
323
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325
326
  protected int getSolvedFunctionIndex()
327
    {
328
    return 0;
329
    }
330
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332
333
  protected int getNumStickerTypes(int numLayers)
334
    {
335
    return 1;
336
    }
337
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
340
  protected int getNumCubitFaces()
341
    {
342
    return 6;
343
    }
344
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346
347
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
348
    {
349
    return CUBITS[cubit].getRotRow(cubitface/2) == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
350
    }
351
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
// PUBLIC API
354
355
  public Static3D[] getRotationAxis()
356
    {
357
    return ROT_AXIS;
358
    }
359
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361
362
  public Movement getMovement()
363
    {
364
    if( mMovement==null )
365
      {
366
      int numLayers = getNumLayers();
367
      if( mCuts==null ) getCuts(numLayers);
368
      getLayerRotatable(numLayers);
369
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
370
      }
371
    return mMovement;
372
    }
373
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375
376
  public int[] getBasicAngle()
377
    {
378
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
379
    return mBasicAngle;
380
    }
381
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
384
  public int getObjectName(int numLayers)
385
    {
386
    switch(numLayers)
387
      {
388
      case 2: return R.string.cube2;
389
      case 3: return R.string.cube3;
390
      case 4: return R.string.cube4;
391
      case 5: return R.string.cube5;
392
      }
393
    return R.string.cube3;
394
    }
395
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397
398
  public int getInventor(int numLayers)
399
    {
400
    switch(numLayers)
401
      {
402
      case 2: return R.string.cube2_inventor;
403
      case 3: return R.string.cube3_inventor;
404
      case 4: return R.string.cube4_inventor;
405
      case 5: return R.string.cube5_inventor;
406
      }
407
    return R.string.cube3_inventor;
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412
  public int getComplexity(int numLayers)
413
    {
414
    switch(numLayers)
415
      {
416
      case 2: return 4;
417
      case 3: return 6;
418
      case 4: return 8;
419
      case 5: return 10;
420
      }
421
    return 6;
422
    }
423
}