Project

General

Profile

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

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

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