Project

General

Profile

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

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

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.ScrambleState;
33
import org.distorted.objectlib.main.ObjectControl;
34
import org.distorted.objectlib.main.ShapeHexahedron;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
abstract class TwistyBandagedAbstract extends ShapeHexahedron
39
{
40
  // the three rotation axis of a 3x3 Cube. Must be normalized.
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
43
           new Static3D(1,0,0),
44
           new Static3D(0,1,0),
45
           new Static3D(0,0,1)
46
         };
47

    
48
  private static final int[][] mDims = new int[][]
49
        {
50
         {1,1,1},  // has to be X>=Z>=Y so that all
51
         {2,1,1},  // the faces are horizontal
52
         {3,1,1},
53
         {2,1,2},
54
         {2,2,2}
55
        };
56

    
57
  private int[] mDimPointers;
58
  private int[] mBasicAngle;
59
  private Static4D[] mQuats;
60
  private Static4D[] mInitQuats;
61
  private int[][] mAxisMap;
62
  private int[][] mFaceMap;
63
  private float[][] mCuts;
64
  ScrambleState[] mStates;
65
  float[][] POSITIONS;
66
  int[] QUAT_INDICES;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  TwistyBandagedAbstract(int[] numL, int meshState, Static4D quat, Static3D move, float scale, InputStream stream)
71
    {
72
    super(numL, meshState, numL[0], quat, move, scale, stream);
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  abstract float[][] getPositions();
78
  abstract int[] getQuatIndices();
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

    
82
  private void initializeQuats()
83
    {
84
    mQuats = new Static4D[]
85
         {
86
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
87
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
88
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
89
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
90

    
91
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
92
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
93
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
94
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
95
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
96
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
97
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
98
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
99
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
100
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
101
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
102
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
103

    
104
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
105
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
106
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
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
         };
113
    }
114

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

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

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  private float[] getCubitPosition(int cubit)
127
    {
128
    float[][] pos = getPositions();
129

    
130
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  private int getQuatIndex(int cubit)
136
    {
137
    int[] indices = getQuatIndices();
138
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

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

    
155
    float defHeight = 0.048f;
156
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
157
    float[][] corners = new float[][] { {0.04f,0.15f} };
158
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
159
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
160

    
161
    int pointer = mDimPointers[variant];
162
    int X = mDims[pointer][0];
163
    int Y = mDims[pointer][1];
164
    int Z = mDims[pointer][2];
165

    
166
    int maxXY = Math.max(X,Y);
167
    int maxXZ = Math.max(X,Z);
168
    int maxYZ = Math.max(Y,Z);
169

    
170
    float[][] vertices =
171
      {
172
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
173
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
174
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
175
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
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
      };
181

    
182
    float[][] bands= new float[][]
183
      {
184
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
185
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
186
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
187
      };
188

    
189
    float[][] centers = new float[][]
190
      {
191
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
192
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
193
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
194
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
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
      };
200

    
201
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null, 6);
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

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

    
221
    return mInitQuats[getQuatIndex(cubit)];
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

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

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  public int getNumCubitVariants(int[] numLayers)
242
    {
243
    float[][] pos = getPositions();
244
    int len = pos.length;
245
    int ret = 1;
246

    
247
    for(int i=0; i<len; i++ )
248
      if( i>0 && pos[i].length!=pos[i-1].length ) ret++;
249

    
250
    mDimPointers = new int[ret];
251
    int index=0;
252

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

    
262
    return ret;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  public int getCubitVariant(int cubit, int[] numLayers)
268
    {
269
    float[][] pos = getPositions();
270
    int len = pos.length;
271

    
272
    if( cubit>=0 && cubit<len )
273
      {
274
      int ret = 0;
275

    
276
      for(int i=1; i<=cubit; i++ )
277
        if( i>0 && pos[i].length!=pos[i-1].length ) ret++;
278

    
279
      return ret;
280
      }
281

    
282
    return 0;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  public float[][] getCubitPositions(int[] numLayers)
288
    {
289
    return getPositions();
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  public Static4D[] getQuats()
295
    {
296
    if( mQuats==null ) initializeQuats();
297
    return mQuats;
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  public float[][] getCuts(int[] numLayers)
303
    {
304
    int numL = numLayers[0];
305

    
306
    if( numL<2 ) return null;
307

    
308
    if( mCuts==null )
309
      {
310
      mCuts = new float[3][numL-1];
311

    
312
      for(int i=0; i<numL-1; i++)
313
        {
314
        float cut = (2-numL)*0.5f + i;
315
        mCuts[0][i] = cut;
316
        mCuts[1][i] = cut;
317
        mCuts[2][i] = cut;
318
        }
319
      }
320

    
321
    return mCuts;
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  public boolean[][] getLayerRotatable(int[] numLayers)
327
    {
328
    int numAxis = ROT_AXIS.length;
329
    boolean[][] layerRotatable = new boolean[numAxis][];
330

    
331
    for(int i=0; i<numAxis; i++)
332
      {
333
      layerRotatable[i] = new boolean[numLayers[i]];
334
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
335
      }
336

    
337
    return layerRotatable;
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  public int getTouchControlType()
343
    {
344
    return TC_HEXAHEDRON;
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  public int getTouchControlSplit()
350
    {
351
    return TYPE_NOT_SPLIT;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  public int[][][] getEnabled()
357
    {
358
    return new int[][][]
359
      {
360
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
361
      };
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  public float[] getDist3D(int[] numLayers)
367
    {
368
    return null;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public int getSolvedFunctionIndex()
374
    {
375
    return 0;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  public int getNumCubitFaces()
381
    {
382
    return 6;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

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

    
403
    if( mAxisMap==null )
404
      {
405
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
406
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
407
      }
408

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

    
419
    float position = 0.0f;
420
    int len = pos.length/3;
421
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
422
    position /= len;
423

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

    
426
    return reaches ? face : -1;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public int getVariantFaceColor(int variant, int face, int[] numLayers)
432
    {
433
    return face>=mStickerVariants[variant].length ? -1 : mStickerVariants[variant][face];
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public float getStickerRadius()
439
    {
440
    return 0.10f;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  public float getStickerStroke()
446
    {
447
    return ObjectControl.isInIconMode() ? 0.16f : 0.08f;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  public float[][] getStickerAngles()
453
    {
454
    return null;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458
// PUBLIC API
459

    
460
  public Static3D[] getRotationAxis()
461
    {
462
    return ROT_AXIS;
463
    }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466

    
467
  public int[] getBasicAngle()
468
    {
469
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
470
    return mBasicAngle;
471
    }
472
}
(3-3/26)