Project

General

Profile

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

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

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 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
25 f10a88a8 Leszek Koltunski
import org.distorted.helpers.ObjectShape;
26 9c06394a Leszek Koltunski
import org.distorted.helpers.ObjectSticker;
27 4c0a6d97 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
28
import org.distorted.library.main.DistortedEffects;
29
import org.distorted.library.main.DistortedTexture;
30
import org.distorted.library.mesh.MeshBase;
31
import org.distorted.library.mesh.MeshSquare;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34
35
///////////////////////////////////////////////////////////////////////////////////////////////////
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 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
155
156 538ee7a6 Leszek Koltunski
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
157
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
158 4c0a6d97 Leszek Koltunski
    {
159
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
160
    }
161
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
164 68ce0d53 Leszek Koltunski
  abstract float[][] getPositions();
165
  abstract int[] getQuatIndices();
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169 f10a88a8 Leszek Koltunski
  int getNumCubits()
170
    {
171
    return getPositions().length;
172
    }
173
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175
176
  private float[] getCubitPosition(int cubit)
177 68ce0d53 Leszek Koltunski
    {
178
    float[][] pos = getPositions();
179
180 f10a88a8 Leszek Koltunski
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
181
    }
182 68ce0d53 Leszek Koltunski
183 f10a88a8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
184
185
  private int getQuatIndex(int cubit)
186
    {
187
    int[] indices = getQuatIndices();
188
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
189 68ce0d53 Leszek Koltunski
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193 f10a88a8 Leszek Koltunski
  private Static4D getQuat(int cubit, int numLayers)
194 68ce0d53 Leszek Koltunski
    {
195 f10a88a8 Leszek Koltunski
    return INIT_QUATS[getQuatIndex(cubit)];
196 68ce0d53 Leszek Koltunski
    }
197
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
200 f10a88a8 Leszek Koltunski
  private int getNumCubitVariants(int numLayers)
201
    {
202
    return mDimensions.length;
203
    }
204
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
207
  int getCubitVariant(int cubit, int numLayers)
208 68ce0d53 Leszek Koltunski
    {
209
    float[][] pos = getPositions();
210
211 f10a88a8 Leszek Koltunski
    if( cubit>=0 && cubit<pos.length )
212
      {
213
      int numPoints = pos[cubit].length/3;
214
      return numPoints==8 ? 4 : numPoints-1;
215
      }
216
217
    return 1;
218 68ce0d53 Leszek Koltunski
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222 f10a88a8 Leszek Koltunski
  ObjectShape getObjectShape(int cubit, int numLayers)
223 68ce0d53 Leszek Koltunski
    {
224 f10a88a8 Leszek Koltunski
    int variant = getCubitVariant(cubit,numLayers);
225 68ce0d53 Leszek Koltunski
226 f10a88a8 Leszek Koltunski
    final int[][] vert_indices =
227
      {
228
        {2,3,1,0},
229
        {7,6,4,5},
230
        {4,0,1,5},
231
        {7,3,2,6},
232
        {6,2,0,4},
233
        {3,7,5,1},
234
      };
235
236
    float defHeight = 0.048f;
237
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
238
    float[][] corners = new float[][] { {0.04f,0.15f} };
239
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
240
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
241
242
    int X = mDimensions[variant][0];
243
    int Y = mDimensions[variant][1];
244
    int Z = mDimensions[variant][2];
245
246
    int maxXY = Math.max(X,Y);
247
    int maxXZ = Math.max(X,Z);
248
    int maxYZ = Math.max(Y,Z);
249
250
    double[][] vertices =
251
      {
252
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
253
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
254
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
255
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
256
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
257
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
258
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
259
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
260
      };
261
262
    float[][] bands= new float[][]
263
      {
264
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
265
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
266
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
267
      };
268
269
    float[][] centers = new float[][]
270
      {
271
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
272
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
273
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
274
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
275
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
276
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
277
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
278
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
279
      };
280
281
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
282 68ce0d53 Leszek Koltunski
    }
283 4c0a6d97 Leszek Koltunski
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285
286
  MeshBase createCubitMesh(int cubit, int numLayers)
287
    {
288 f10a88a8 Leszek Koltunski
    int variant = getCubitVariant(cubit,numLayers);
289
290 4c0a6d97 Leszek Koltunski
    if( mMeshes==null )
291
      {
292 ad7907b0 Leszek Koltunski
      FactoryCubit factory = FactoryCubit.getInstance();
293
      factory.clear();
294 f10a88a8 Leszek Koltunski
      mMeshes = new MeshBase[getNumCubitVariants(numLayers)];
295
      }
296
297
    if( mMeshes[variant]==null )
298
      {
299
      ObjectShape shape = getObjectShape(cubit,numLayers);
300
      FactoryCubit factory = FactoryCubit.getInstance();
301
      factory.createNewFaceTransform(shape);
302
      mMeshes[variant] = factory.createRoundedSolid(shape);
303 4c0a6d97 Leszek Koltunski
      }
304
305
    MeshBase mesh = mMeshes[variant].copy(true);
306 f10a88a8 Leszek Koltunski
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
307 4c0a6d97 Leszek Koltunski
    mesh.apply(quat,0xffffffff,0);
308
309
    return mesh;
310
    }
311
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314 9c06394a Leszek Koltunski
  int getColor(int face)
315
    {
316
    return FACE_COLORS[face];
317
    }
318
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320
321
  ObjectSticker retSticker(int face)
322 4c0a6d97 Leszek Koltunski
    {
323 9c06394a Leszek Koltunski
    return mStickers[face/NUM_FACES];
324 4c0a6d97 Leszek Koltunski
    }
325
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327
328 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int size)
329 4c0a6d97 Leszek Koltunski
    {
330
    int numCubits = getNumCubits();
331 e6cf7283 Leszek Koltunski
    float[][] tmp = new float[numCubits][];
332 4c0a6d97 Leszek Koltunski
333
    for(int cubit=0; cubit<numCubits; cubit++)
334
      {
335 e6cf7283 Leszek Koltunski
      tmp[cubit] = getCubitPosition(cubit);
336 4c0a6d97 Leszek Koltunski
      }
337
338
    return tmp;
339
    }
340
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342
343
  Static4D[] getQuats()
344
    {
345
    return QUATS;
346
    }
347
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
350
  boolean shouldResetTextureMaps()
351
    {
352
    return false;
353
    }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
357
  int getNumFaces()
358
    {
359
    return FACE_COLORS.length;
360
    }
361
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
365 4c0a6d97 Leszek Koltunski
    {
366 e6734aa9 Leszek Koltunski
    float[][] cuts = new float[3][numLayers-1];
367 4c0a6d97 Leszek Koltunski
368
    for(int i=0; i<numLayers-1; i++)
369
      {
370 e6734aa9 Leszek Koltunski
      float cut = (2-numLayers)*0.5f + i;
371
      cuts[0][i] = cut;
372
      cuts[1][i] = cut;
373
      cuts[2][i] = cut;
374 4c0a6d97 Leszek Koltunski
      }
375
376
    return cuts;
377
    }
378
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  int getNumStickerTypes(int numLayers)
382
    {
383 538ee7a6 Leszek Koltunski
    return NUM_STICKERS;
384 4c0a6d97 Leszek Koltunski
    }
385
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
388
  int getNumCubitFaces()
389
    {
390
    return FACE_COLORS.length;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395
  float getScreenRatio()
396
    {
397
    return 0.5f;
398
    }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402 538ee7a6 Leszek Koltunski
  private int retStickerIndex(int horzSize, int vertSize)
403 4c0a6d97 Leszek Koltunski
    {
404 538ee7a6 Leszek Koltunski
    switch(horzSize)
405 4c0a6d97 Leszek Koltunski
      {
406 538ee7a6 Leszek Koltunski
      case 1: return 0;
407
      case 2: return vertSize==1 ? 1:3;
408
      case 3: return 2;
409 4c0a6d97 Leszek Koltunski
      }
410
411 538ee7a6 Leszek Koltunski
    return 0;
412
    }
413 4c0a6d97 Leszek Koltunski
414 538ee7a6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
415
416
  private int getStickerIndex(int cubitface, int[] dim)
417
    {
418 4c0a6d97 Leszek Koltunski
    switch(cubitface)
419
      {
420 538ee7a6 Leszek Koltunski
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
421
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
422
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
423 4c0a6d97 Leszek Koltunski
      }
424
425 538ee7a6 Leszek Koltunski
    return 0;
426
    }
427
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429
430
  int getFaceColor(int cubit, int cubitface, int numLayers)
431
    {
432 f10a88a8 Leszek Koltunski
    int variant      = getCubitVariant(cubit,numLayers);
433 538ee7a6 Leszek Koltunski
    int[] dim        = mDimensions[variant];
434
    float[] pos      = getCubitPosition(cubit);
435
    int stickerIndex = getStickerIndex(cubitface,dim);
436
    int quatIndex    = getQuatIndex(cubit);
437
    int face         = mFaceMap[cubitface][quatIndex];
438
    int multiplier   = (face%2)==0 ? 1:-1;
439
    int posIndex     = face/2;
440
    int dimIndex     = mAxisMap[posIndex][quatIndex];
441 92ec91b9 Leszek Koltunski
442
    float position = 0.0f;
443
    int len = pos.length/3;
444
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
445
    position /= len;
446
447
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
448 538ee7a6 Leszek Koltunski
449 f0450fcc Leszek Koltunski
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
450 4c0a6d97 Leszek Koltunski
    }
451
452 ce366b42 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
453 f20119c6 Leszek Koltunski
// this implements the fact that certain cubits have multiple 'centers' and this means the cubit
454
// might span more than one layer along a given axis - i.e. that this is a bandaged puzzle.
455 ce366b42 Leszek Koltunski
456
  int computeBitmapFromRow(int rowBitmap, int axis)
457
    {
458
    int bitmap, initBitmap=0;
459
460
    while( initBitmap!=rowBitmap )
461
      {
462
      initBitmap = rowBitmap;
463
464
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
465
        {
466
        bitmap = CUBITS[cubit].mRotationRow[axis];
467
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
468
        }
469
      }
470
471
    return rowBitmap;
472
    }
473
474 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
475
476
  float returnMultiplier()
477
    {
478
    return getNumLayers();
479
    }
480
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482
// PUBLIC API
483
484
  public Static3D[] getRotationAxis()
485
    {
486
    return ROT_AXIS;
487
    }
488
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
491 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
492 4c0a6d97 Leszek Koltunski
    {
493 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
494 4c0a6d97 Leszek Koltunski
    }
495
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  public boolean isSolved()
499
    {
500
    int index = CUBITS[0].mQuatIndex;
501
502
    for(int i=1; i<NUM_CUBITS; i++)
503
      {
504 722b2512 Leszek Koltunski
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
505 4c0a6d97 Leszek Koltunski
      }
506
507
    return true;
508
    }
509
}