Project

General

Profile

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

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

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 6cf89a3e Leszek Koltunski
  ScrambleState[] mStates;
157 e1dc3366 Leszek Koltunski
  private int[][] mScrambleTable;
158
  private int[] mNumOccurences;
159 38589947 Leszek Koltunski
160 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
161
162 538ee7a6 Leszek Koltunski
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
163
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
164 4c0a6d97 Leszek Koltunski
    {
165
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
166
    }
167
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
170 68ce0d53 Leszek Koltunski
  abstract float[][] getPositions();
171
  abstract int[] getQuatIndices();
172
173 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
174
175
  int[] getSolvedQuats(int cubit, int numLayers)
176
    {
177
    int status = retCubitSolvedStatus(cubit,numLayers);
178
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
179
    }
180
181 68ce0d53 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
182
183 f10a88a8 Leszek Koltunski
  int getNumCubits()
184
    {
185
    return getPositions().length;
186
    }
187
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190
  private float[] getCubitPosition(int cubit)
191 68ce0d53 Leszek Koltunski
    {
192
    float[][] pos = getPositions();
193
194 f10a88a8 Leszek Koltunski
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
195
    }
196 68ce0d53 Leszek Koltunski
197 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
198
199
  private int getQuatIndex(int cubit)
200
    {
201
    int[] indices = getQuatIndices();
202
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
203 68ce0d53 Leszek Koltunski
    }
204
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
207 f10a88a8 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
208 68ce0d53 Leszek Koltunski
    {
209 f10a88a8 Leszek Koltunski
    int variant = getCubitVariant(cubit,numLayers);
210 68ce0d53 Leszek Koltunski
211 f10a88a8 Leszek Koltunski
    final int[][] vert_indices =
212
      {
213
        {2,3,1,0},
214
        {7,6,4,5},
215
        {4,0,1,5},
216
        {7,3,2,6},
217
        {6,2,0,4},
218
        {3,7,5,1},
219
      };
220
221
    float defHeight = 0.048f;
222
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
223
    float[][] corners = new float[][] { {0.04f,0.15f} };
224
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
225
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
226
227
    int X = mDimensions[variant][0];
228
    int Y = mDimensions[variant][1];
229
    int Z = mDimensions[variant][2];
230
231
    int maxXY = Math.max(X,Y);
232
    int maxXZ = Math.max(X,Z);
233
    int maxYZ = Math.max(Y,Z);
234
235
    double[][] vertices =
236
      {
237
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
238
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
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
      };
246
247
    float[][] bands= new float[][]
248
      {
249
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
250
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
251
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
252
      };
253
254
    float[][] centers = new float[][]
255
      {
256
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
257
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
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
      };
265
266
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
267 68ce0d53 Leszek Koltunski
    }
268 4c0a6d97 Leszek Koltunski
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
271 3e605536 Leszek Koltunski
  Static4D getQuat(int cubit, int numLayers)
272 4c0a6d97 Leszek Koltunski
    {
273 3e605536 Leszek Koltunski
    return INIT_QUATS[getQuatIndex(cubit)];
274
    }
275 f10a88a8 Leszek Koltunski
276 3e605536 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
277
278
  int getNumCubitVariants(int numLayers)
279
    {
280
    return mDimensions.length;
281
    }
282
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284
285
  int getCubitVariant(int cubit, int numLayers)
286
    {
287
    float[][] pos = getPositions();
288 f10a88a8 Leszek Koltunski
289 3e605536 Leszek Koltunski
    if( cubit>=0 && cubit<pos.length )
290 f10a88a8 Leszek Koltunski
      {
291 3e605536 Leszek Koltunski
      int numPoints = pos[cubit].length/3;
292
      return numPoints==8 ? 4 : numPoints-1;
293 4c0a6d97 Leszek Koltunski
      }
294
295 3e605536 Leszek Koltunski
    return 1;
296 4c0a6d97 Leszek Koltunski
    }
297
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299
300 9c06394a Leszek Koltunski
  int getColor(int face)
301
    {
302
    return FACE_COLORS[face];
303
    }
304
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306
307
  ObjectSticker retSticker(int face)
308 4c0a6d97 Leszek Koltunski
    {
309 9c06394a Leszek Koltunski
    return mStickers[face/NUM_FACES];
310 4c0a6d97 Leszek Koltunski
    }
311
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
315 4c0a6d97 Leszek Koltunski
    {
316
    int numCubits = getNumCubits();
317 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
318 4c0a6d97 Leszek Koltunski
319
    for(int cubit=0; cubit<numCubits; cubit++)
320
      {
321 e6cf7283 Leszek Koltunski
      tmp[cubit] = getCubitPosition(cubit);
322 4c0a6d97 Leszek Koltunski
      }
323
324
    return tmp;
325
    }
326
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328
329
  Static4D[] getQuats()
330
    {
331
    return QUATS;
332
    }
333
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
336
  boolean shouldResetTextureMaps()
337
    {
338
    return false;
339
    }
340
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342
343
  int getNumFaces()
344
    {
345
    return FACE_COLORS.length;
346
    }
347
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
351 4c0a6d97 Leszek Koltunski
    {
352 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
353 4c0a6d97 Leszek Koltunski
354
    for(int i=0; i<numLayers-1; i++)
355
      {
356 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
357
      cuts[0][i] = cut;
358
      cuts[1][i] = cut;
359
      cuts[2][i] = cut;
360 4c0a6d97 Leszek Koltunski
      }
361
362
    return cuts;
363
    }
364
365 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
366
367
  int getSolvedFunctionIndex()
368
    {
369
    return 0;
370
    }
371
372 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374
  int getNumStickerTypes(int numLayers)
375
    {
376 538ee7a6 Leszek Koltunski
    return NUM_STICKERS;
377 4c0a6d97 Leszek Koltunski
    }
378
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  int getNumCubitFaces()
382
    {
383
    return FACE_COLORS.length;
384
    }
385
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
388
  float getScreenRatio()
389
    {
390
    return 0.5f;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395 538ee7a6 Leszek Koltunski
  private int retStickerIndex(int horzSize, int vertSize)
396 4c0a6d97 Leszek Koltunski
    {
397 538ee7a6 Leszek Koltunski
    switch(horzSize)
398 4c0a6d97 Leszek Koltunski
      {
399 538ee7a6 Leszek Koltunski
      case 1: return 0;
400
      case 2: return vertSize==1 ? 1:3;
401
      case 3: return 2;
402 4c0a6d97 Leszek Koltunski
      }
403
404 538ee7a6 Leszek Koltunski
    return 0;
405
    }
406 4c0a6d97 Leszek Koltunski
407 538ee7a6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
408
409
  private int getStickerIndex(int cubitface, int[] dim)
410
    {
411 4c0a6d97 Leszek Koltunski
    switch(cubitface)
412
      {
413 538ee7a6 Leszek Koltunski
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
414
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
415
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
416 4c0a6d97 Leszek Koltunski
      }
417
418 538ee7a6 Leszek Koltunski
    return 0;
419
    }
420
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
423
  int getFaceColor(int cubit, int cubitface, int numLayers)
424
    {
425 f10a88a8 Leszek Koltunski
    int variant      = getCubitVariant(cubit,numLayers);
426 538ee7a6 Leszek Koltunski
    int[] dim        = mDimensions[variant];
427
    float[] pos      = getCubitPosition(cubit);
428
    int stickerIndex = getStickerIndex(cubitface,dim);
429
    int quatIndex    = getQuatIndex(cubit);
430
    int face         = mFaceMap[cubitface][quatIndex];
431
    int multiplier   = (face%2)==0 ? 1:-1;
432
    int posIndex     = face/2;
433
    int dimIndex     = mAxisMap[posIndex][quatIndex];
434 92ec91b9 Leszek Koltunski
435
    float position = 0.0f;
436
    int len = pos.length/3;
437
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
438
    position /= len;
439
440
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
441 538ee7a6 Leszek Koltunski
442 f0450fcc Leszek Koltunski
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
443 4c0a6d97 Leszek Koltunski
    }
444
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
447
  float returnMultiplier()
448
    {
449
    return getNumLayers();
450
    }
451
452 e1dc3366 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
453
454
  private void initializeScrambling()
455
    {
456
    int numLayers = getNumLayers();
457
458
    if( mScrambleTable ==null )
459
      {
460
      mScrambleTable = new int[NUM_AXIS][numLayers];
461
      }
462
    if( mNumOccurences ==null )
463
      {
464
      int max=0;
465
466
      for (ScrambleState mState : mStates)
467
        {
468
        int tmp = mState.getTotal(-1);
469
        if (max < tmp) max = tmp;
470
        }
471
472
      mNumOccurences = new int[max];
473
      }
474
475
    for(int i=0; i<NUM_AXIS; i++)
476
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
477
    }
478
479 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
480
// PUBLIC API
481
482 38589947 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
483
    {
484
    if( curr==0 )
485
      {
486
      mCurrState     = 0;
487
      mIndexExcluded =-1;
488 e1dc3366 Leszek Koltunski
      initializeScrambling();
489 38589947 Leszek Koltunski
      }
490
491 e1dc3366 Leszek Koltunski
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
492 38589947 Leszek Koltunski
493
    scramble[curr][0] = info[0];
494
    scramble[curr][1] = info[1];
495
    scramble[curr][2] = info[2];
496
497
    mCurrState     = info[3];
498
    mIndexExcluded = info[0];
499
    }
500
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502
503 4c0a6d97 Leszek Koltunski
  public Static3D[] getRotationAxis()
504
    {
505
    return ROT_AXIS;
506
    }
507
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509
510 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
511 4c0a6d97 Leszek Koltunski
    {
512 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
513 4c0a6d97 Leszek Koltunski
    }
514
}