Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 6cf89a3e

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