Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 57ef6378

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