Project

General

Profile

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

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

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