Project

General

Profile

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

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

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.ObjectType;
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, 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
  protected int getResource(int numLayers)
110
    {
111
    switch(numLayers)
112
      {
113
      case 2: return R.raw.cube2;
114
      case 3: return R.raw.cube3;
115
      case 4: return R.raw.cube4;
116
      case 5: return R.raw.cube5;
117
      }
118

    
119
    return 0;
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

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

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

    
141
    return ret;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

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

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

    
168
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
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
         };
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

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

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

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

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

    
203
    double[][] vertices = new double[][]
204
          {
205
              { 0.5, 0.5, 0.5 },
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
          };
214

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

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

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

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

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

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

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

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

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

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

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

    
271
    return mStickers[face/NUM_FACE_COLORS];
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  protected float[][] getCubitPositions(int numLayers)
277
    {
278
    int numCubits = numLayers>1 ? 6*numLayers*numLayers - 12*numLayers + 8 : 1;
279
    float[][] tmp = new float[numCubits][];
280

    
281
    float diff = 0.5f*(numLayers-1);
282
    int currentPosition = 0;
283

    
284
    for(int x = 0; x<numLayers; x++)
285
      for(int y = 0; y<numLayers; y++)
286
        for(int z = 0; z<numLayers; z++)
287
          if( x==0 || x==numLayers-1 || y==0 || y==numLayers-1 || z==0 || z==numLayers-1 )
288
            {
289
            tmp[currentPosition++] = new float[] {x-diff,y-diff,z-diff};
290
            }
291

    
292
    return tmp;
293
    }
294

    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

    
297
  protected Static4D[] getQuats()
298
    {
299
    if( mQuats ==null ) initializeQuats();
300
    return mQuats;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  protected float[][] getCuts(int numLayers)
306
    {
307
    if( numLayers<2 ) return null;
308

    
309
    if( mCuts==null )
310
      {
311
      mCuts = new float[3][numLayers-1];
312

    
313
      for(int i=0; i<numLayers-1; i++)
314
        {
315
        float cut = (2-numLayers)*0.5f + i;
316
        mCuts[0][i] = cut;
317
        mCuts[1][i] = cut;
318
        mCuts[2][i] = cut;
319
        }
320
      }
321

    
322
    return mCuts;
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  private void getLayerRotatable(int numLayers)
328
    {
329
    if( mLayerRotatable==null )
330
      {
331
      int numAxis = ROT_AXIS.length;
332
      boolean[] tmp = new boolean[numLayers];
333
      for(int i=0; i<numLayers; i++) tmp[i] = true;
334
      mLayerRotatable = new boolean[numAxis][];
335
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
336
      }
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  protected int getSolvedFunctionIndex()
342
    {
343
    return 0;
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  protected int getNumStickerTypes(int numLayers)
349
    {
350
    return 1;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  protected int getNumCubitFaces()
356
    {
357
    return 6;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
363
    {
364
    return CUBITS[cubit].getRotRow(cubitface/2) == (cubitface%2==0 ? (1<<(numLayers-1)):1) ? cubitface : NUM_TEXTURES;
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368
// PUBLIC API
369

    
370
  public Static3D[] getRotationAxis()
371
    {
372
    return ROT_AXIS;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  public Movement getMovement()
378
    {
379
    if( mMovement==null )
380
      {
381
      int numLayers = getNumLayers();
382
      if( mCuts==null ) getCuts(numLayers);
383
      getLayerRotatable(numLayers);
384
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
385
      }
386
    return mMovement;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  public int[] getBasicAngle()
392
    {
393
    if( mBasicAngle==null ) mBasicAngle = new int[] { 4,4,4 };
394
    return mBasicAngle;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public ObjectType intGetObjectList(int numLayers)
400
    {
401
    switch(numLayers)
402
      {
403
      case 2: return ObjectType.CUBE_2;
404
      case 3: return ObjectType.CUBE_3;
405
      case 4: return ObjectType.CUBE_4;
406
      case 5: return ObjectType.CUBE_5;
407
      }
408

    
409
    return ObjectType.CUBE_3;
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public int getObjectName(int numLayers)
415
    {
416
    switch(numLayers)
417
      {
418
      case 2: return R.string.cube2;
419
      case 3: return R.string.cube3;
420
      case 4: return R.string.cube4;
421
      case 5: return R.string.cube5;
422
      }
423
    return R.string.cube3;
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  public int getInventor(int numLayers)
429
    {
430
    switch(numLayers)
431
      {
432
      case 2: return R.string.cube2_inventor;
433
      case 3: return R.string.cube3_inventor;
434
      case 4: return R.string.cube4_inventor;
435
      case 5: return R.string.cube5_inventor;
436
      }
437
    return R.string.cube3_inventor;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public int getComplexity(int numLayers)
443
    {
444
    switch(numLayers)
445
      {
446
      case 2: return 4;
447
      case 3: return 6;
448
      case 4: return 8;
449
      case 5: return 10;
450
      }
451
    return 6;
452
    }
453
}
(6-6/25)