Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 7d8cc029

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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
26 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 4c0a6d97 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 538ee7a6 Leszek Koltunski
abstract class TwistyBandagedAbstract extends TwistyObject
39 4c0a6d97 Leszek Koltunski
{
40
  // the three rotation axis of a 3x3 Cube. Must be normalized.
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
43
           new Static3D(1,0,0),
44
           new Static3D(0,1,0),
45
           new Static3D(0,0,1)
46
         };
47
48
  private static final int[] FACE_COLORS = new int[]
49
         {
50
           COLOR_YELLOW, COLOR_WHITE,
51
           COLOR_BLUE  , COLOR_GREEN,
52
           COLOR_RED   , COLOR_ORANGE
53
         };
54
55
  private static final Static4D[] QUATS = new Static4D[]
56
         {
57
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
58
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
59
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
60
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
61
62
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
63
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
64
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
65
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
66
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
67
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
68
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
69
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
70
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
71
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
72
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
73
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
74
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
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
82
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
83
         };
84
85 538ee7a6 Leszek Koltunski
  private static final Static4D[] INIT_QUATS = new Static4D[]
86 4c0a6d97 Leszek Koltunski
        {
87
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
88 538ee7a6 Leszek Koltunski
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
89
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
90
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
91
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
92
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
93
        };
94
95
  private static final int[][] mDimensions = new int[][]
96
        {
97
         {1,1,1},  // has to be X>=Z>=Y so that all
98
         {2,1,1},  // the faces are horizontal
99
         {3,1,1},
100
         {2,1,2},
101
         {2,2,2}
102 4c0a6d97 Leszek Koltunski
        };
103
104 538ee7a6 Leszek Koltunski
  private static final int[][] mStickerDimensions = new int[][]
105
        {
106
         {1,1},  // dimensions of the faces of
107
         {2,1},  // the cuboids defined above
108
         {3,1},
109
         {2,2}
110
        };
111
112
  private static final int[][] mFaceMap = new int[][] // cubitface=2 when rotated by
113
    {                                                 // quatIndex=1 gets moved to
114
        {0,0,5,2,4,2},                                // position mFaceMap[2][1]
115
        {1,1,4,3,5,3},
116
        {2,4,2,1,1,4},
117
        {3,5,3,0,0,5},
118
        {4,3,0,4,3,0},
119
        {5,2,1,5,2,1}
120
    };
121
122
  private static final int[][] mAxisMap = new int[][] // axis=1 when rotated by
123
    {                                                 // quatIndex=2 gets moved to
124
        {0,0,2,1,2,1},                                // axis mAxisMap[1][2]
125
        {1,2,1,0,0,2},
126
        {2,1,0,2,1,0}
127
    };
128
129
  private static final int NUM_STICKERS = mStickerDimensions.length;
130
131 4c0a6d97 Leszek Koltunski
  private static MeshBase[] mMeshes;
132
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134
135 538ee7a6 Leszek Koltunski
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
136
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
137 4c0a6d97 Leszek Koltunski
    {
138
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
139
    }
140
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
143 68ce0d53 Leszek Koltunski
  abstract float[][] getPositions();
144
  abstract int[] getQuatIndices();
145
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147
148
  int getCubitVariant(int cubit)
149
    {
150
    float[][] pos = getPositions();
151
152
    if( cubit>=0 && cubit< pos.length )
153
      {
154
      int numPoints = pos[cubit].length/3;
155 10cd5579 Leszek Koltunski
      return numPoints==8 ? 4 : numPoints-1;
156 68ce0d53 Leszek Koltunski
      }
157
158
    return 1;
159
    }
160
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162
163
  int getNumCubits()
164
    {
165
    return getPositions().length;
166
    }
167
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
170
  float[] getCubitPosition(int cubit)
171
    {
172
    float[][] pos = getPositions();
173
174
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
175
    }
176
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178
179 10cd5579 Leszek Koltunski
  private int getQuatIndex(int cubit)
180 68ce0d53 Leszek Koltunski
    {
181
    int[] indices = getQuatIndices();
182
183
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
184
    }
185 4c0a6d97 Leszek Koltunski
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187
188
  MeshBase createCubitMesh(int cubit, int numLayers)
189
    {
190
    if( mMeshes==null )
191
      {
192 538ee7a6 Leszek Koltunski
      int LEN = mDimensions.length;
193
      mMeshes = new MeshBase[LEN];
194 4c0a6d97 Leszek Koltunski
195 538ee7a6 Leszek Koltunski
      for(int i=0; i<LEN; i++)
196
        {
197
        mMeshes[i] = FactoryCubit.getInstance().createCuboidMesh(mDimensions[i]);
198
        }
199 4c0a6d97 Leszek Koltunski
      }
200
201 538ee7a6 Leszek Koltunski
    int variant = getCubitVariant(cubit);
202 4c0a6d97 Leszek Koltunski
    MeshBase mesh = mMeshes[variant].copy(true);
203
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
204
    mesh.apply(quat,0xffffffff,0);
205
206
    return mesh;
207
    }
208
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
212
    {
213
    int numFaces = FACE_COLORS.length;
214
    int stickerType = face/numFaces;
215 538ee7a6 Leszek Koltunski
    int color = face%numFaces;
216
    float X = mStickerDimensions[stickerType][0];
217
    float Y = mStickerDimensions[stickerType][1];
218
    float MAX = Math.max(X,Y);
219
    float R = 0.10f / MAX;
220
    float S = 0.08f / MAX;
221
    X /= (2*MAX);
222
    Y /= (2*MAX);
223 4c0a6d97 Leszek Koltunski
224
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
225
226
    FactorySticker factory = FactorySticker.getInstance();
227 538ee7a6 Leszek Koltunski
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[color], R);
228 4c0a6d97 Leszek Koltunski
    }
229
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
232 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
233 4c0a6d97 Leszek Koltunski
    {
234
    int numCubits = getNumCubits();
235 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
236 4c0a6d97 Leszek Koltunski
237
    for(int cubit=0; cubit<numCubits; cubit++)
238
      {
239 e6cf7283 Leszek Koltunski
      tmp[cubit] = getCubitPosition(cubit);
240 4c0a6d97 Leszek Koltunski
      }
241
242
    return tmp;
243
    }
244
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  Static4D[] getQuats()
248
    {
249
    return QUATS;
250
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254
  boolean shouldResetTextureMaps()
255
    {
256
    return false;
257
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261
  int getNumFaces()
262
    {
263
    return FACE_COLORS.length;
264
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
268
  float[] getCuts(int numLayers)
269
    {
270
    float[] cuts = new float[numLayers-1];
271
272
    for(int i=0; i<numLayers-1; i++)
273
      {
274
      cuts[i] = (2-numLayers)*0.5f + i;
275
      }
276
277
    return cuts;
278
    }
279
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281
282
  int getNumStickerTypes(int numLayers)
283
    {
284 538ee7a6 Leszek Koltunski
    return NUM_STICKERS;
285 4c0a6d97 Leszek Koltunski
    }
286
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288
289
  int getNumCubitFaces()
290
    {
291
    return FACE_COLORS.length;
292
    }
293
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295
296
  float getScreenRatio()
297
    {
298
    return 0.5f;
299
    }
300
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303 538ee7a6 Leszek Koltunski
  private int retStickerIndex(int horzSize, int vertSize)
304 4c0a6d97 Leszek Koltunski
    {
305 538ee7a6 Leszek Koltunski
    switch(horzSize)
306 4c0a6d97 Leszek Koltunski
      {
307 538ee7a6 Leszek Koltunski
      case 1: return 0;
308
      case 2: return vertSize==1 ? 1:3;
309
      case 3: return 2;
310 4c0a6d97 Leszek Koltunski
      }
311
312 538ee7a6 Leszek Koltunski
    return 0;
313
    }
314 4c0a6d97 Leszek Koltunski
315 538ee7a6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
316
317
  private int getStickerIndex(int cubitface, int[] dim)
318
    {
319 4c0a6d97 Leszek Koltunski
    switch(cubitface)
320
      {
321 538ee7a6 Leszek Koltunski
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
322
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
323
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
324 4c0a6d97 Leszek Koltunski
      }
325
326 538ee7a6 Leszek Koltunski
    return 0;
327
    }
328
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330
331
  int getFaceColor(int cubit, int cubitface, int numLayers)
332
    {
333
    int variant      = getCubitVariant(cubit);
334
    int[] dim        = mDimensions[variant];
335
    float[] pos      = getCubitPosition(cubit);
336
    int stickerIndex = getStickerIndex(cubitface,dim);
337
    int quatIndex    = getQuatIndex(cubit);
338
    int face         = mFaceMap[cubitface][quatIndex];
339
    int multiplier   = (face%2)==0 ? 1:-1;
340
    int posIndex     = face/2;
341
    int dimIndex     = mAxisMap[posIndex][quatIndex];
342 92ec91b9 Leszek Koltunski
343
    float position = 0.0f;
344
    int len = pos.length/3;
345
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
346
    position /= len;
347
348
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
349 538ee7a6 Leszek Koltunski
350 f0450fcc Leszek Koltunski
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
351 4c0a6d97 Leszek Koltunski
    }
352
353 ce366b42 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
354
355
  int computeBitmapFromRow(int rowBitmap, int axis)
356
    {
357
    int bitmap, initBitmap=0;
358
359
    while( initBitmap!=rowBitmap )
360
      {
361
      initBitmap = rowBitmap;
362
363
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
364
        {
365
        bitmap = CUBITS[cubit].mRotationRow[axis];
366
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
367
        }
368
      }
369
370
    return rowBitmap;
371
    }
372
373 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
374
375
  float returnMultiplier()
376
    {
377
    return getNumLayers();
378
    }
379
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381
382
  float[] getRowChances(int numLayers)
383
    {
384
    float[] chances = new float[numLayers];
385
386
    for(int i=0; i<numLayers; i++)
387
      {
388
      chances[i] = (i+1.0f) / numLayers;
389
      }
390
391
    return chances;
392
    }
393
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395
// PUBLIC API
396
397
  public Static3D[] getRotationAxis()
398
    {
399
    return ROT_AXIS;
400
    }
401
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403
404
  public int getBasicAngle()
405
    {
406
    return 4;
407
    }
408
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410
411
  public boolean isSolved()
412
    {
413
    int index = CUBITS[0].mQuatIndex;
414
415
    for(int i=1; i<NUM_CUBITS; i++)
416
      {
417 722b2512 Leszek Koltunski
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
418 4c0a6d97 Leszek Koltunski
      }
419
420
    return true;
421
    }
422
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424 538ee7a6 Leszek Koltunski
// only needed for solvers - there are no Bandaged solvers ATM)
425 4c0a6d97 Leszek Koltunski
426
  public String retObjectString()
427
    {
428
    return "";
429
    }
430
}