Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 00f4980d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
31
import org.distorted.objectlib.helpers.ObjectShape;
32
import org.distorted.objectlib.helpers.ObjectSticker;
33
import org.distorted.objectlib.helpers.ScrambleState;
34
import org.distorted.objectlib.main.ObjectControl;
35
import org.distorted.objectlib.main.ShapeHexahedron;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
abstract class TwistyBandagedAbstract extends ShapeHexahedron
40
{
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[][] mDims = 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[] mDimPointers;
61
  private int[] mBasicAngle;
62
  private Static4D[] mQuats;
63
  private ObjectSticker[] mStickers;
64
  private Static4D[] mInitQuats;
65
  private int[][] mAxisMap;
66
  private int[][] mFaceMap;
67
  private float[][] mCuts;
68
  ScrambleState[] mStates;
69
  float[][] POSITIONS;
70
  int[] QUAT_INDICES;
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

    
74
  TwistyBandagedAbstract(int[] numL, int meshState, Static4D quat, Static3D move, float scale, InputStream stream)
75
    {
76
    super(numL, meshState, numL[0], quat, move, scale, stream);
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
  abstract float[][] getPositions();
82
  abstract int[] getQuatIndices();
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  private void initializeQuats()
87
    {
88
    mQuats = new Static4D[]
89
         {
90
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
91
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
92
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
93
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
94

    
95
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
96
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
97
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
98
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
99
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
100
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
101
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
102
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
103
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
104
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
105
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
106
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
107

    
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
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
116
         };
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  public int[] getSolvedQuats(int cubit, int[] numLayers)
122
    {
123
    if( mQuats==null ) initializeQuats();
124
    int status = retCubitSolvedStatus(cubit,numLayers);
125
    return status<0 ? null : buildSolvedQuats(TouchControlHexahedron.FACE_AXIS[status],mQuats);
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  private float[] getCubitPosition(int cubit)
131
    {
132
    float[][] pos = getPositions();
133

    
134
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  private int getQuatIndex(int cubit)
140
    {
141
    int[] indices = getQuatIndices();
142
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  public ObjectShape getObjectShape(int variant)
148
    {
149
    final int[][] vert_indices =
150
      {
151
        {2,3,1,0},
152
        {7,6,4,5},
153
        {4,0,1,5},
154
        {7,3,2,6},
155
        {6,2,0,4},
156
        {3,7,5,1},
157
      };
158

    
159
    float defHeight = 0.048f;
160
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
161
    float[][] corners = new float[][] { {0.04f,0.15f} };
162
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
163
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
164

    
165
    int pointer = mDimPointers[variant];
166
    int X = mDims[pointer][0];
167
    int Y = mDims[pointer][1];
168
    int Z = mDims[pointer][2];
169

    
170
    int maxXY = Math.max(X,Y);
171
    int maxXZ = Math.max(X,Z);
172
    int maxYZ = Math.max(Y,Z);
173

    
174
    float[][] vertices =
175
      {
176
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
177
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
178
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
179
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
180
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
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
      };
185

    
186
    float[][] bands= new float[][]
187
      {
188
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
189
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
190
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
191
      };
192

    
193
    float[][] centers = new float[][]
194
      {
195
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
196
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
197
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
198
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
199
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
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
      };
204

    
205
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null, 6);
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  public Static4D getQuat(int cubit, int[] numLayers)
211
    {
212
    if( mInitQuats ==null )
213
      {
214
      mInitQuats = new Static4D[]
215
        {
216
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
217
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
218
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
219
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
220
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
221
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
222
        };
223
      }
224

    
225
    return mInitQuats[getQuatIndex(cubit)];
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
  private void assignDim(int[] table, int index, int len)
231
    {
232
    switch(len)
233
      {
234
      case  3: table[index] = 0; break;
235
      case  6: table[index] = 1; break;
236
      case  9: table[index] = 2; break;
237
      case 12: table[index] = 3; break;
238
      case 24: table[index] = 4; break;
239
      default: android.util.Log.e("D", "ERROR in assignDim: "+len);
240
      }
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  public int getNumCubitVariants(int[] numLayers)
246
    {
247
    float[][] pos = getPositions();
248
    int len = pos.length;
249
    int ret = 1;
250

    
251
    for(int i=0; i<len; i++ )
252
      if( i>0 && pos[i].length!=pos[i-1].length ) ret++;
253

    
254
    mDimPointers = new int[ret];
255
    int index=0;
256

    
257
    for(int i=0; i<len; i++ )
258
      {
259
      if( i==0 || pos[i].length!=pos[i-1].length )
260
        {
261
        assignDim(mDimPointers,index,pos[i].length);
262
        index++;
263
        }
264
      }
265

    
266
    return ret;
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  public int getCubitVariant(int cubit, int[] numLayers)
272
    {
273
    float[][] pos = getPositions();
274
    int len = pos.length;
275

    
276
    if( cubit>=0 && cubit<len )
277
      {
278
      int ret = 0;
279

    
280
      for(int i=1; i<=cubit; i++ )
281
        if( i>0 && pos[i].length!=pos[i-1].length ) ret++;
282

    
283
      return ret;
284
      }
285

    
286
    return 0;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  public float[][] getCubitPositions(int[] numLayers)
292
    {
293
    return getPositions();
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  public Static4D[] getQuats()
299
    {
300
    if( mQuats==null ) initializeQuats();
301
    return mQuats;
302
    }
303

    
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305

    
306
  public float[][] getCuts(int[] numLayers)
307
    {
308
    int numL = numLayers[0];
309

    
310
    if( numL<2 ) return null;
311

    
312
    if( mCuts==null )
313
      {
314
      mCuts = new float[3][numL-1];
315

    
316
      for(int i=0; i<numL-1; i++)
317
        {
318
        float cut = (2-numL)*0.5f + i;
319
        mCuts[0][i] = cut;
320
        mCuts[1][i] = cut;
321
        mCuts[2][i] = cut;
322
        }
323
      }
324

    
325
    return mCuts;
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  public boolean[][] getLayerRotatable(int[] numLayers)
331
    {
332
    int numAxis = ROT_AXIS.length;
333
    boolean[][] layerRotatable = new boolean[numAxis][];
334

    
335
    for(int i=0; i<numAxis; i++)
336
      {
337
      layerRotatable[i] = new boolean[numLayers[i]];
338
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
339
      }
340

    
341
    return layerRotatable;
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  public int getTouchControlType()
347
    {
348
    return TC_HEXAHEDRON;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  public int getTouchControlSplit()
354
    {
355
    return TYPE_NOT_SPLIT;
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

    
360
  public int[][][] getEnabled()
361
    {
362
    return new int[][][]
363
      {
364
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
365
      };
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  public float[] getDist3D(int[] numLayers)
371
    {
372
    return null;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  public int getSolvedFunctionIndex()
378
    {
379
    return 0;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public int getNumCubitFaces()
385
    {
386
    return 6;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  public int getCubitFaceColor(int cubit, int cubitface, int[] numLayers)
392
    {
393
    if( mFaceMap==null )
394
      {
395
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
396
      mFaceMap = new int[][]
397
          {
398
              {0,0,5,2,4,2},
399
              {1,1,4,3,5,3},
400
              {2,4,2,1,1,4},
401
              {3,5,3,0,0,5},
402
              {4,3,0,4,3,0},
403
              {5,2,1,5,2,1}
404
          };
405
      }
406

    
407
    if( mAxisMap==null )
408
      {
409
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
410
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
411
      }
412

    
413
    int variant    = getCubitVariant(cubit,numLayers);
414
    int pointer    = mDimPointers[variant];
415
    int[] dim      = mDims[pointer];
416
    float[] pos    = getCubitPosition(cubit);
417
    int quatIndex  = getQuatIndex(cubit);
418
    int face       = mFaceMap[cubitface][quatIndex];
419
    int multiplier = (face%2)==0 ? 1:-1;
420
    int posIndex   = face/2;
421
    int dimIndex   = mAxisMap[posIndex][quatIndex];
422

    
423
    float position = 0.0f;
424
    int len = pos.length/3;
425
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
426
    position /= len;
427

    
428
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers[0]-1)*0.5f;
429

    
430
    return reaches ? face : -1;
431
    }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
436
    {
437
    return face>=mStickerVariants[variant].length ? -1 : mStickerVariants[variant][face];
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  private float getRadius()
443
    {
444
    return 0.10f;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  private float getStroke()
450
    {
451
    return ObjectControl.isInIconMode() ? 0.16f : 0.08f;
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  private float[][] getAngles()
457
    {
458
    return null;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

    
463
  public ObjectSticker retSticker(int sticker)
464
    {
465
    if( mStickers==null )
466
      {
467
      float rad = getRadius();
468
      float str = getStroke();
469
      float[][] angles = getAngles();
470
      int numStickers = mStickerCoords.length;
471
      mStickers = new ObjectSticker[numStickers];
472

    
473
      for(int s=0; s<numStickers; s++)
474
        {
475
        float scale = mStickerScales[s];
476
        float radius = rad / scale;
477
        float stroke = str / scale;
478
        int len = mStickerCoords[s].length/2;
479
        float[] radii = new float[len];
480
        for(int r=0; r<len; r++) radii[r] = radius*computeRadiusCorrection(mStickerCoords[s],r,len);
481
        mStickers[s] = new ObjectSticker(mStickerCoords[s],angles==null ? null : angles[s],radii,stroke);
482
        }
483
      }
484

    
485
    return mStickers[sticker];
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
// PUBLIC API
490

    
491
  public Static3D[] getRotationAxis()
492
    {
493
    return ROT_AXIS;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public int[] getBasicAngle()
499
    {
500
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
501
    return mBasicAngle;
502
    }
503
}
(3-3/26)