Project

General

Profile

Download (16.1 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 7b832206

1 29b82486 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.objectlib.objects;
21
22 59c20632 Leszek Koltunski
import static org.distorted.objectlib.main.Movement.MOVEMENT_HEXAHEDRON;
23 29b82486 Leszek Koltunski
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
24
25
import android.content.res.Resources;
26
27
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
import org.distorted.objectlib.main.Movement6;
34 198c5bf0 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectShape;
35
import org.distorted.objectlib.helpers.ObjectSticker;
36
import org.distorted.objectlib.helpers.ScrambleState;
37 8592461c Leszek Koltunski
import org.distorted.objectlib.main.ObjectControl;
38 29b82486 Leszek Koltunski
import org.distorted.objectlib.main.Twisty6;
39
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42
abstract class TwistyBandagedAbstract extends Twisty6
43
{
44
  // the three rotation axis of a 3x3 Cube. Must be normalized.
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(1,0,0),
48
           new Static3D(0,1,0),
49
           new Static3D(0,0,1)
50
         };
51
52
  private static final int[][] mDimensions = new int[][]
53
        {
54
         {1,1,1},  // has to be X>=Z>=Y so that all
55
         {2,1,1},  // the faces are horizontal
56
         {3,1,1},
57
         {2,1,2},
58
         {2,2,2}
59
        };
60
61
  private static final int NUM_STICKERS = 4;
62
63
  private int[] mBasicAngle;
64
  private Static4D[] mQuats;
65
  private ObjectSticker[] mStickers;
66
  private Static4D[] mInitQuats;
67
  private int[][] mAxisMap;
68
  private int[][] mFaceMap;
69
  private float[][] mCuts;
70
  ScrambleState[] mStates;
71
  float[][] POSITIONS;
72
  int[] QUAT_INDICES;
73
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75
76 a57e6870 Leszek Koltunski
  TwistyBandagedAbstract(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
77 e7daa161 Leszek Koltunski
                         MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
78 29b82486 Leszek Koltunski
    {
79 e7daa161 Leszek Koltunski
    super(numL, numL[0], quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
80 29b82486 Leszek Koltunski
    }
81
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83
84
  abstract float[][] getPositions();
85
  abstract int[] getQuatIndices();
86
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88
89
  private void initializeQuats()
90
    {
91
    mQuats = new Static4D[]
92
         {
93
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
94
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
95
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
96
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
97
98
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
99
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
100
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
101
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
102
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
103
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
104
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
105
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
106
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
107
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
108
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
109
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
110
111
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
112
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
113
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
114
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
115
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
116
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
117
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
118
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
119
         };
120
    }
121
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124 7b832206 Leszek Koltunski
  public int[] getSolvedQuats(int cubit, int[] numLayers)
125 29b82486 Leszek Koltunski
    {
126
    if( mQuats==null ) initializeQuats();
127
    int status = retCubitSolvedStatus(cubit,numLayers);
128
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
129
    }
130
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132
133
  int getNumCubits()
134
    {
135
    return getPositions().length;
136
    }
137
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140
  private float[] getCubitPosition(int cubit)
141
    {
142
    float[][] pos = getPositions();
143
144
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
145
    }
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  private int getQuatIndex(int cubit)
150
    {
151
    int[] indices = getQuatIndices();
152
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
153
    }
154
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
157 e30c522a Leszek Koltunski
  public ObjectShape getObjectShape(int variant)
158 29b82486 Leszek Koltunski
    {
159
    final int[][] vert_indices =
160
      {
161
        {2,3,1,0},
162
        {7,6,4,5},
163
        {4,0,1,5},
164
        {7,3,2,6},
165
        {6,2,0,4},
166
        {3,7,5,1},
167
      };
168
169
    float defHeight = 0.048f;
170
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
171
    float[][] corners = new float[][] { {0.04f,0.15f} };
172
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
173
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
174
175
    int X = mDimensions[variant][0];
176
    int Y = mDimensions[variant][1];
177
    int Z = mDimensions[variant][2];
178
179
    int maxXY = Math.max(X,Y);
180
    int maxXZ = Math.max(X,Z);
181
    int maxYZ = Math.max(Y,Z);
182
183
    double[][] vertices =
184
      {
185
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
186
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
187
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
188
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
189
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
190
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
191
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
192
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
193
      };
194
195
    float[][] bands= new float[][]
196
      {
197
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
198
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
199
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
200
      };
201
202
    float[][] centers = new float[][]
203
      {
204
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
205
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
206
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
207
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
208
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
209
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
210
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
211
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
212
      };
213
214
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
215
    }
216
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218
219 7b832206 Leszek Koltunski
  public Static4D getQuat(int cubit, int[] numLayers)
220 29b82486 Leszek Koltunski
    {
221
    if( mInitQuats ==null )
222
      {
223
      mInitQuats = new Static4D[]
224
        {
225
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
226
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
227
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
228
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
229
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
230
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
231
        };
232
      }
233
234
    return mInitQuats[getQuatIndex(cubit)];
235
    }
236
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
239 e30c522a Leszek Koltunski
  public int getNumCubitVariants(int[] numLayers)
240 29b82486 Leszek Koltunski
    {
241
    return mDimensions.length;
242
    }
243
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245
246 e30c522a Leszek Koltunski
  public int getCubitVariant(int cubit, int[] numLayers)
247 29b82486 Leszek Koltunski
    {
248
    float[][] pos = getPositions();
249
250
    if( cubit>=0 && cubit<pos.length )
251
      {
252
      int numPoints = pos[cubit].length/3;
253
      return numPoints==8 ? 4 : numPoints-1;
254
      }
255
256
    return 1;
257
    }
258
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
261 1bb09f88 Leszek Koltunski
  public ObjectSticker retSticker(int sticker)
262 29b82486 Leszek Koltunski
    {
263
    if( mStickers==null )
264
      {
265
      mStickers = new ObjectSticker[NUM_STICKERS];
266
267
      int[][] stickerDimensions = new int[][]
268
        {
269
         {1,1},  // dimensions of the faces of
270
         {2,1},  // the cuboids defined in mDimensions
271
         {3,1},
272
         {2,2}
273
        };
274
275
      for(int s=0; s<NUM_STICKERS; s++)
276
        {
277
        float X = stickerDimensions[s][0];
278
        float Y = stickerDimensions[s][1];
279
        float MAX = Math.max(X,Y);
280
        X /= (2*MAX);
281
        Y /= (2*MAX);
282
283 8592461c Leszek Koltunski
        float radius = 0.10f / MAX;
284
        float stroke = 0.08f / MAX;
285 29b82486 Leszek Koltunski
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
286 8592461c Leszek Koltunski
        float[] radii = new float[] {radius,radius,radius,radius};
287
288
        if( ObjectControl.isInIconMode() )
289
          {
290
          stroke*=2.0f;
291
          }
292
293
        mStickers[s] = new ObjectSticker(coords,null,radii,stroke);
294 29b82486 Leszek Koltunski
        }
295
      }
296
297 1bb09f88 Leszek Koltunski
    return mStickers[sticker];
298
    }
299
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301
302
  protected int getStickerIndex(int face)
303
    {
304
    return face/NUM_FACE_COLORS;
305 29b82486 Leszek Koltunski
    }
306
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308
309 7b832206 Leszek Koltunski
  public float[][] getCubitPositions(int[] numLayers)
310 29b82486 Leszek Koltunski
    {
311
    int numCubits = getNumCubits();
312
    float[][] tmp = new float[numCubits][];
313
314
    for(int cubit=0; cubit<numCubits; cubit++)
315
      {
316
      tmp[cubit] = getCubitPosition(cubit);
317
      }
318
319
    return tmp;
320
    }
321
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323
324 1bb09f88 Leszek Koltunski
  public Static4D[] getQuats()
325 29b82486 Leszek Koltunski
    {
326
    if( mQuats==null ) initializeQuats();
327
    return mQuats;
328
    }
329
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332 7bbfc84f Leszek Koltunski
  public float[][] getCuts(int[] numLayers)
333 29b82486 Leszek Koltunski
    {
334 a57e6870 Leszek Koltunski
    int numL = numLayers[0];
335
336
    if( numL<2 ) return null;
337 29b82486 Leszek Koltunski
338
    if( mCuts==null )
339
      {
340 a57e6870 Leszek Koltunski
      mCuts = new float[3][numL-1];
341 29b82486 Leszek Koltunski
342 a57e6870 Leszek Koltunski
      for(int i=0; i<numL-1; i++)
343 29b82486 Leszek Koltunski
        {
344 a57e6870 Leszek Koltunski
        float cut = (2-numL)*0.5f + i;
345 29b82486 Leszek Koltunski
        mCuts[0][i] = cut;
346
        mCuts[1][i] = cut;
347
        mCuts[2][i] = cut;
348
        }
349
      }
350
351
    return mCuts;
352
    }
353
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
356 59c20632 Leszek Koltunski
  public boolean[][] getLayerRotatable(int[] numLayers)
357 29b82486 Leszek Koltunski
    {
358 59c20632 Leszek Koltunski
    int numAxis = ROT_AXIS.length;
359
    boolean[][] layerRotatable = new boolean[numAxis][];
360 a57e6870 Leszek Koltunski
361 59c20632 Leszek Koltunski
    for(int i=0; i<numAxis; i++)
362
      {
363
      layerRotatable[i] = new boolean[numLayers[i]];
364
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
365 29b82486 Leszek Koltunski
      }
366 59c20632 Leszek Koltunski
367
    return layerRotatable;
368
    }
369
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371
372
  public int getMovementType()
373
    {
374
    return MOVEMENT_HEXAHEDRON;
375
    }
376
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378
379
  public int getMovementSplit()
380
    {
381
    return TYPE_NOT_SPLIT;
382 29b82486 Leszek Koltunski
    }
383
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
386 59c20632 Leszek Koltunski
  public int[][][] getEnabled()
387
    {
388
    return new int[][][]
389
      {
390
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
391
      };
392
    }
393
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395
396
  public float[] getDist3D(int[] numLayers)
397
    {
398
    return null;
399
    }
400
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402
403
  public int getSolvedFunctionIndex()
404 29b82486 Leszek Koltunski
    {
405
    return 0;
406
    }
407
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409
410 1bb09f88 Leszek Koltunski
  public int getNumStickerTypes(int[] numLayers)
411 29b82486 Leszek Koltunski
    {
412
    return NUM_STICKERS;
413
    }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
  protected int getNumCubitFaces()
418
    {
419
    return 6;
420
    }
421
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
424
  private int retStickerIndex(int horzSize, int vertSize)
425
    {
426
    switch(horzSize)
427
      {
428
      case 1: return 0;
429
      case 2: return vertSize==1 ? 1:3;
430
      case 3: return 2;
431
      }
432
433
    return 0;
434
    }
435
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437
438
  private int getStickerIndex(int cubitface, int[] dim)
439
    {
440
    switch(cubitface)
441
      {
442
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
443
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
444
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
445
      }
446
447
    return 0;
448
    }
449
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451
452 a57e6870 Leszek Koltunski
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
453 29b82486 Leszek Koltunski
    {
454
    if( mFaceMap==null )
455
      {
456
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
457
      mFaceMap = new int[][]
458
          {
459
              {0,0,5,2,4,2},
460
              {1,1,4,3,5,3},
461
              {2,4,2,1,1,4},
462
              {3,5,3,0,0,5},
463
              {4,3,0,4,3,0},
464
              {5,2,1,5,2,1}
465
          };
466
      }
467
468
    if( mAxisMap==null )
469
      {
470
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
471
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
472
      }
473
474
    int variant      = getCubitVariant(cubit,numLayers);
475
    int[] dim        = mDimensions[variant];
476
    float[] pos      = getCubitPosition(cubit);
477
    int stickerIndex = getStickerIndex(cubitface,dim);
478
    int quatIndex    = getQuatIndex(cubit);
479
    int face         = mFaceMap[cubitface][quatIndex];
480
    int multiplier   = (face%2)==0 ? 1:-1;
481
    int posIndex     = face/2;
482
    int dimIndex     = mAxisMap[posIndex][quatIndex];
483
484
    float position = 0.0f;
485
    int len = pos.length/3;
486
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
487
    position /= len;
488
489 a57e6870 Leszek Koltunski
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers[0]-1)*0.5f;
490 29b82486 Leszek Koltunski
491
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
492
    }
493
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495
// PUBLIC API
496
497
  public Static3D[] getRotationAxis()
498
    {
499
    return ROT_AXIS;
500
    }
501
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503
504
  public int[] getBasicAngle()
505
    {
506
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
507
    return mBasicAngle;
508
    }
509
}