Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ f2d0d23e

1 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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 android.content.res.Resources;
23
24 f10a88a8 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
25 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
26 6cf89a3e Leszek Koltunski
import org.distorted.helpers.ScrambleState;
27 4c0a6d97 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
33 38589947 Leszek Koltunski
import java.util.Random;
34
35 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37 538ee7a6 Leszek Koltunski
abstract class TwistyBandagedAbstract extends TwistyObject
38 4c0a6d97 Leszek Koltunski
{
39
  // the three rotation axis of a 3x3 Cube. Must be normalized.
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 925ed78f Leszek Koltunski
  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
48
49 4c0a6d97 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
50
         {
51
           COLOR_YELLOW, COLOR_WHITE,
52
           COLOR_BLUE  , COLOR_GREEN,
53
           COLOR_RED   , COLOR_ORANGE
54
         };
55
56
  private static final Static4D[] QUATS = new Static4D[]
57
         {
58
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
59
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
60
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
61
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
62
63
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
64
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
65
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
66
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
67
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
68
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
69
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
70
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
71
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
72
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
73
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
74
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
75
76
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
77
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
78
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
79
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
80
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
81
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
82
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
83
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
84
         };
85
86 538ee7a6 Leszek Koltunski
  private static final Static4D[] INIT_QUATS = new Static4D[]
87 4c0a6d97 Leszek Koltunski
        {
88
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
89 538ee7a6 Leszek Koltunski
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
90
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
91
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
92
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
93
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
94
        };
95
96
  private static final int[][] mDimensions = new int[][]
97
        {
98
         {1,1,1},  // has to be X>=Z>=Y so that all
99
         {2,1,1},  // the faces are horizontal
100
         {3,1,1},
101
         {2,1,2},
102
         {2,2,2}
103 4c0a6d97 Leszek Koltunski
        };
104
105 538ee7a6 Leszek Koltunski
  private static final int[][] mStickerDimensions = new int[][]
106
        {
107
         {1,1},  // dimensions of the faces of
108
         {2,1},  // the cuboids defined above
109
         {3,1},
110
         {2,2}
111
        };
112
113
  private static final int[][] mFaceMap = new int[][] // cubitface=2 when rotated by
114
    {                                                 // quatIndex=1 gets moved to
115
        {0,0,5,2,4,2},                                // position mFaceMap[2][1]
116
        {1,1,4,3,5,3},
117
        {2,4,2,1,1,4},
118
        {3,5,3,0,0,5},
119
        {4,3,0,4,3,0},
120
        {5,2,1,5,2,1}
121
    };
122
123
  private static final int[][] mAxisMap = new int[][] // axis=1 when rotated by
124
    {                                                 // quatIndex=2 gets moved to
125
        {0,0,2,1,2,1},                                // axis mAxisMap[1][2]
126
        {1,2,1,0,0,2},
127
        {2,1,0,2,1,0}
128
    };
129
130
  private static final int NUM_STICKERS = mStickerDimensions.length;
131
132 9c06394a Leszek Koltunski
  private static final ObjectSticker[] mStickers;
133
134
  static
135
    {
136
    mStickers = new ObjectSticker[NUM_STICKERS];
137
138
    for(int s=0; s<NUM_STICKERS; s++)
139
      {
140
      float X = mStickerDimensions[s][0];
141
      float Y = mStickerDimensions[s][1];
142
      float MAX = Math.max(X,Y);
143
      X /= (2*MAX);
144
      Y /= (2*MAX);
145
146
      float R = 0.10f / MAX;
147
      float S = 0.08f / MAX;
148
      float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
149
      float[] radii = new float[] {R,R,R,R};
150
      mStickers[s] = new ObjectSticker(coords,null,radii,S);
151
      }
152
    }
153
154 38589947 Leszek Koltunski
  private int mCurrState;
155
  private int mIndexExcluded;
156 e1dc3366 Leszek Koltunski
  private int[][] mScrambleTable;
157
  private int[] mNumOccurences;
158 f2d0d23e Leszek Koltunski
  ScrambleState[] mStates;
159
  float[][] POSITIONS;
160
  int[] QUAT_INDICES;
161 38589947 Leszek Koltunski
162 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
163
164 538ee7a6 Leszek Koltunski
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
165
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
166 4c0a6d97 Leszek Koltunski
    {
167
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
168
    }
169
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
172 68ce0d53 Leszek Koltunski
  abstract float[][] getPositions();
173
  abstract int[] getQuatIndices();
174
175 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177
  int[] getSolvedQuats(int cubit, int numLayers)
178
    {
179
    int status = retCubitSolvedStatus(cubit,numLayers);
180
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
181
    }
182
183 68ce0d53 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
184
185 f10a88a8 Leszek Koltunski
  int getNumCubits()
186
    {
187
    return getPositions().length;
188
    }
189
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
192
  private float[] getCubitPosition(int cubit)
193 68ce0d53 Leszek Koltunski
    {
194
    float[][] pos = getPositions();
195
196 f10a88a8 Leszek Koltunski
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
197
    }
198 68ce0d53 Leszek Koltunski
199 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
200
201
  private int getQuatIndex(int cubit)
202
    {
203
    int[] indices = getQuatIndices();
204
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
205 68ce0d53 Leszek Koltunski
    }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209 f10a88a8 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
210 68ce0d53 Leszek Koltunski
    {
211 f10a88a8 Leszek Koltunski
    int variant = getCubitVariant(cubit,numLayers);
212 68ce0d53 Leszek Koltunski
213 f10a88a8 Leszek Koltunski
    final int[][] vert_indices =
214
      {
215
        {2,3,1,0},
216
        {7,6,4,5},
217
        {4,0,1,5},
218
        {7,3,2,6},
219
        {6,2,0,4},
220
        {3,7,5,1},
221
      };
222
223
    float defHeight = 0.048f;
224
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
225
    float[][] corners = new float[][] { {0.04f,0.15f} };
226
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
227
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
228
229
    int X = mDimensions[variant][0];
230
    int Y = mDimensions[variant][1];
231
    int Z = mDimensions[variant][2];
232
233
    int maxXY = Math.max(X,Y);
234
    int maxXZ = Math.max(X,Z);
235
    int maxYZ = Math.max(Y,Z);
236
237
    double[][] vertices =
238
      {
239
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
240
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
241
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
242
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
243
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
244
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
245
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
246
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
247
      };
248
249
    float[][] bands= new float[][]
250
      {
251
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
252
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
253
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
254
      };
255
256
    float[][] centers = new float[][]
257
      {
258
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
259
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
260
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
261
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
262
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
263
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
264
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
265
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
266
      };
267
268
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
269 68ce0d53 Leszek Koltunski
    }
270 4c0a6d97 Leszek Koltunski
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272
273 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
274 4c0a6d97 Leszek Koltunski
    {
275 3e605536 Leszek Koltunski
    return INIT_QUATS[getQuatIndex(cubit)];
276
    }
277 f10a88a8 Leszek Koltunski
278 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
279
280
  int getNumCubitVariants(int numLayers)
281
    {
282
    return mDimensions.length;
283
    }
284
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287
  int getCubitVariant(int cubit, int numLayers)
288
    {
289
    float[][] pos = getPositions();
290 f10a88a8 Leszek Koltunski
291 3e605536 Leszek Koltunski
    if( cubit>=0 && cubit<pos.length )
292 f10a88a8 Leszek Koltunski
      {
293 3e605536 Leszek Koltunski
      int numPoints = pos[cubit].length/3;
294
      return numPoints==8 ? 4 : numPoints-1;
295 4c0a6d97 Leszek Koltunski
      }
296
297 3e605536 Leszek Koltunski
    return 1;
298 4c0a6d97 Leszek Koltunski
    }
299
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301
302 9c06394a Leszek Koltunski
  int getColor(int face)
303
    {
304
    return FACE_COLORS[face];
305
    }
306
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308
309
  ObjectSticker retSticker(int face)
310 4c0a6d97 Leszek Koltunski
    {
311 9c06394a Leszek Koltunski
    return mStickers[face/NUM_FACES];
312 4c0a6d97 Leszek Koltunski
    }
313
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315
316 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
317 4c0a6d97 Leszek Koltunski
    {
318
    int numCubits = getNumCubits();
319 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
320 4c0a6d97 Leszek Koltunski
321
    for(int cubit=0; cubit<numCubits; cubit++)
322
      {
323 e6cf7283 Leszek Koltunski
      tmp[cubit] = getCubitPosition(cubit);
324 4c0a6d97 Leszek Koltunski
      }
325
326
    return tmp;
327
    }
328
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330
331
  Static4D[] getQuats()
332
    {
333
    return QUATS;
334
    }
335
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338
  boolean shouldResetTextureMaps()
339
    {
340
    return false;
341
    }
342
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344
345
  int getNumFaces()
346
    {
347
    return FACE_COLORS.length;
348
    }
349
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
353 4c0a6d97 Leszek Koltunski
    {
354 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
355 4c0a6d97 Leszek Koltunski
356
    for(int i=0; i<numLayers-1; i++)
357
      {
358 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
359
      cuts[0][i] = cut;
360
      cuts[1][i] = cut;
361
      cuts[2][i] = cut;
362 4c0a6d97 Leszek Koltunski
      }
363
364
    return cuts;
365
    }
366
367 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
368
369
  int getSolvedFunctionIndex()
370
    {
371
    return 0;
372
    }
373
374 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
375
376
  int getNumStickerTypes(int numLayers)
377
    {
378 538ee7a6 Leszek Koltunski
    return NUM_STICKERS;
379 4c0a6d97 Leszek Koltunski
    }
380
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382
383
  int getNumCubitFaces()
384
    {
385
    return FACE_COLORS.length;
386
    }
387
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389
390
  float getScreenRatio()
391
    {
392
    return 0.5f;
393
    }
394
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396
397 538ee7a6 Leszek Koltunski
  private int retStickerIndex(int horzSize, int vertSize)
398 4c0a6d97 Leszek Koltunski
    {
399 538ee7a6 Leszek Koltunski
    switch(horzSize)
400 4c0a6d97 Leszek Koltunski
      {
401 538ee7a6 Leszek Koltunski
      case 1: return 0;
402
      case 2: return vertSize==1 ? 1:3;
403
      case 3: return 2;
404 4c0a6d97 Leszek Koltunski
      }
405
406 538ee7a6 Leszek Koltunski
    return 0;
407
    }
408 4c0a6d97 Leszek Koltunski
409 538ee7a6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411
  private int getStickerIndex(int cubitface, int[] dim)
412
    {
413 4c0a6d97 Leszek Koltunski
    switch(cubitface)
414
      {
415 538ee7a6 Leszek Koltunski
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
416
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
417
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
418 4c0a6d97 Leszek Koltunski
      }
419
420 538ee7a6 Leszek Koltunski
    return 0;
421
    }
422
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424
425
  int getFaceColor(int cubit, int cubitface, int numLayers)
426
    {
427 f10a88a8 Leszek Koltunski
    int variant      = getCubitVariant(cubit,numLayers);
428 538ee7a6 Leszek Koltunski
    int[] dim        = mDimensions[variant];
429
    float[] pos      = getCubitPosition(cubit);
430
    int stickerIndex = getStickerIndex(cubitface,dim);
431
    int quatIndex    = getQuatIndex(cubit);
432
    int face         = mFaceMap[cubitface][quatIndex];
433
    int multiplier   = (face%2)==0 ? 1:-1;
434
    int posIndex     = face/2;
435
    int dimIndex     = mAxisMap[posIndex][quatIndex];
436 92ec91b9 Leszek Koltunski
437
    float position = 0.0f;
438
    int len = pos.length/3;
439
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
440
    position /= len;
441
442
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
443 538ee7a6 Leszek Koltunski
444 f0450fcc Leszek Koltunski
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
445 4c0a6d97 Leszek Koltunski
    }
446
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448
449
  float returnMultiplier()
450
    {
451
    return getNumLayers();
452
    }
453
454 e1dc3366 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
455
456
  private void initializeScrambling()
457
    {
458
    int numLayers = getNumLayers();
459
460
    if( mScrambleTable ==null )
461
      {
462
      mScrambleTable = new int[NUM_AXIS][numLayers];
463
      }
464
    if( mNumOccurences ==null )
465
      {
466
      int max=0;
467
468
      for (ScrambleState mState : mStates)
469
        {
470
        int tmp = mState.getTotal(-1);
471
        if (max < tmp) max = tmp;
472
        }
473
474
      mNumOccurences = new int[max];
475
      }
476
477
    for(int i=0; i<NUM_AXIS; i++)
478
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
479
    }
480
481 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
482
// PUBLIC API
483
484 38589947 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
485
    {
486
    if( curr==0 )
487
      {
488
      mCurrState     = 0;
489
      mIndexExcluded =-1;
490 e1dc3366 Leszek Koltunski
      initializeScrambling();
491 38589947 Leszek Koltunski
      }
492
493 e1dc3366 Leszek Koltunski
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
494 38589947 Leszek Koltunski
495
    scramble[curr][0] = info[0];
496
    scramble[curr][1] = info[1];
497
    scramble[curr][2] = info[2];
498
499
    mCurrState     = info[3];
500
    mIndexExcluded = info[0];
501
    }
502
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504
505 4c0a6d97 Leszek Koltunski
  public Static3D[] getRotationAxis()
506
    {
507
    return ROT_AXIS;
508
    }
509
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511
512 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
513 4c0a6d97 Leszek Koltunski
    {
514 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
515 4c0a6d97 Leszek Koltunski
    }
516
}