Project

General

Profile

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

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

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.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
}
(6-6/25)