Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyCube.java @ 967c1d17

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

    
22
import static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
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
class TwistyCube extends Twisty6
39
{
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(1,0,0),
43
           new Static3D(0,1,0),
44
           new Static3D(0,0,1)
45
         };
46

    
47
  private static final int[] NUM_ENABLED = {2,2,2,2,2,2};
48

    
49
  private static final int[][][] ENABLED = new int[][][]
50
      {
51
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
52
      };
53

    
54
  private ScrambleState[] mStates;
55
  private Static4D[] mQuats;
56
  private float[][] mCuts;
57
  private boolean[][] mLayerRotatable;
58
  private int[] mBasicAngle;
59
  private ObjectSticker[] mStickers;
60
  private Movement mMovement;
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  TwistyCube(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
65
             DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
66
    {
67
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.CUBE, res, scrWidth);
68
    }
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  ScrambleState[] getScrambleStates()
73
    {
74
    if( mStates==null )
75
      {
76
      int size = getNumLayers();
77
      int[][] m = new int[16][];
78
      for(int i=1; i<16; i++) m[i] = createEdges(size,i);
79

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

    
101
    return mStates;
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  private int[] createEdges(int size, int vertex)
107
    {
108
    int[] ret = new int[9*size];
109

    
110
    for(int l=0; l<size; l++)
111
      {
112
      ret[9*l  ] = l;
113
      ret[9*l+1] =-1;
114
      ret[9*l+2] = vertex;
115
      ret[9*l+3] = l;
116
      ret[9*l+4] = 1;
117
      ret[9*l+5] = vertex;
118
      ret[9*l+6] = l;
119
      ret[9*l+7] = 2;
120
      ret[9*l+8] = vertex;
121
      }
122

    
123
    return ret;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  private void initializeQuats()
129
    {
130
    mQuats = new Static4D[]
131
         {
132
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
133
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
134
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
135
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
136

    
137
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
138
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
139
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
140
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
141
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
142
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
143
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
144
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
145
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
146
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
147
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
148
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
149

    
150
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
151
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
152
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
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
         };
159
    }
160

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

    
163
  int[] getSolvedQuats(int cubit, int numLayers)
164
    {
165
    if( mQuats ==null ) initializeQuats();
166
    int status = retCubitSolvedStatus(cubit,numLayers);
167
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status], mQuats);
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  ObjectShape getObjectShape(int cubit, int numLayers)
173
    {
174
    int extraI, extraV, num;
175
    float height;
176

    
177
    switch(numLayers)
178
      {
179
      case 2 : num = 6; extraI = 2; extraV = 2; height = 0.045f; break;
180
      case 3 : num = 5; extraI = 2; extraV = 2; height = 0.045f; break;
181
      case 4 : num = 5; extraI = 1; extraV = 1; height = 0.045f; break;
182
      default: num = 5; extraI = 0; extraV = 0; height = 0.045f; break;
183
      }
184

    
185
    double[][] vertices = new double[][]
186
          {
187
              { 0.5, 0.5, 0.5 },
188
              { 0.5, 0.5,-0.5 },
189
              { 0.5,-0.5, 0.5 },
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
          };
196

    
197
    int[][] vert_indices = new int[][]
198
          {
199
              {2,3,1,0},
200
              {7,6,4,5},
201
              {4,0,1,5},
202
              {7,3,2,6},
203
              {6,2,0,4},
204
              {3,7,5,1}
205
          };
206

    
207
    float[][] bands     = new float[][] { {height,35,0.5f,0.7f,num,extraI,extraV} };
208
    int[] bandIndices   = new int[] { 0,0,0,0,0,0};
209
    float[][] corners   = new float[][] { {0.036f,0.12f} };
210
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
211
    float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
212
    int[] centerIndices = new int[] { 0,0,0,0,0,0,0,0 };
213

    
214
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  Static4D getQuat(int cubit, int numLayers)
220
    {
221
    if( mQuats ==null ) initializeQuats();
222
    return mQuats[0];
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  int getNumCubitVariants(int numLayers)
228
    {
229
    return 1;
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  int getCubitVariant(int cubit, int numLayers)
235
    {
236
    return 0;
237
    }
238

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

    
241
  ObjectSticker retSticker(int face)
242
    {
243
    if( mStickers==null )
244
      {
245
      final float[][] STICKERS = new float[][]  { { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f } };
246
      final float radius = 0.10f;
247
      final float stroke = 0.08f;
248
      final float[] radii = {radius,radius,radius,radius};
249
      mStickers = new ObjectSticker[STICKERS.length];
250
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
251
      }
252

    
253
    return mStickers[face/NUM_FACE_COLORS];
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  float[][] getCubitPositions(int numLayers)
259
    {
260
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
261
    float[][] tmp = new float[numCubits][];
262

    
263
    float diff = 0.5f*(numLayers-1);
264
    int currentPosition = 0;
265

    
266
    for(int x = 0; x<numLayers; x++)
267
      for(int y = 0; y<numLayers; y++)
268
        for(int z = 0; z<numLayers; z++)
269
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
270
            {
271
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
272
            }
273

    
274
    return tmp;
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  Static4D[] getQuats()
280
    {
281
    if( mQuats ==null ) initializeQuats();
282
    return mQuats;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  float[][] getCuts(int numLayers)
288
    {
289
    if( numLayers<2 ) return null;
290

    
291
    if( mCuts==null )
292
      {
293
      mCuts = new float[3][numLayers-1];
294

    
295
      for(int i=0; i<numLayers-1; i++)
296
        {
297
        float cut = (2-numLayers)*0.5f + i;
298
        mCuts[0][i] = cut;
299
        mCuts[1][i] = cut;
300
        mCuts[2][i] = cut;
301
        }
302
      }
303

    
304
    return mCuts;
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  private void getLayerRotatable(int numLayers)
310
    {
311
    if( mLayerRotatable==null )
312
      {
313
      int numAxis = ROT_AXIS.length;
314
      boolean[] tmp = new boolean[numLayers];
315
      for(int i=0; i<numLayers; i++) tmp[i] = true;
316
      mLayerRotatable = new boolean[numAxis][];
317
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
318
      }
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  int getSolvedFunctionIndex()
324
    {
325
    return 0;
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  int getNumStickerTypes(int numLayers)
331
    {
332
    return 1;
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  int getNumCubitFaces()
338
    {
339
    return 6;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
  int getFaceColor(int cubit, int cubitface, int numLayers)
345
    {
346
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350
// PUBLIC API
351

    
352
  public Static3D[] getRotationAxis()
353
    {
354
    return ROT_AXIS;
355
    }
356

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

    
359
  public Movement getMovement()
360
    {
361
    if( mMovement==null )
362
      {
363
      int numLayers = getNumLayers();
364
      if( mCuts==null ) getCuts(numLayers);
365
      getLayerRotatable(numLayers);
366
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,NUM_ENABLED,ENABLED);
367
      }
368
    return mMovement;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public int[] getBasicAngle()
374
    {
375
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
376
    return mBasicAngle;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  public int getObjectName(int numLayers)
382
    {
383
    switch(numLayers)
384
      {
385
      case 2: return R.string.cube2;
386
      case 3: return R.string.cube3;
387
      case 4: return R.string.cube4;
388
      case 5: return R.string.cube5;
389
      }
390
    return R.string.cube3;
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  public int getInventor(int numLayers)
396
    {
397
    switch(numLayers)
398
      {
399
      case 2: return R.string.cube2_inventor;
400
      case 3: return R.string.cube3_inventor;
401
      case 4: return R.string.cube4_inventor;
402
      case 5: return R.string.cube5_inventor;
403
      }
404
    return R.string.cube3_inventor;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  public int getComplexity(int numLayers)
410
    {
411
    switch(numLayers)
412
      {
413
      case 2: return 4;
414
      case 3: return 6;
415
      case 4: return 8;
416
      case 5: return 10;
417
      }
418
    return 6;
419
    }
420
}
(17-17/38)