Project

General

Profile

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

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

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.main.Movement.MOVEMENT_HEXAHEDRON;
23
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
import org.distorted.objectlib.helpers.ObjectShape;
35
import org.distorted.objectlib.helpers.ObjectSticker;
36
import org.distorted.objectlib.helpers.ScrambleState;
37
import org.distorted.objectlib.main.ObjectControl;
38
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
  TwistyBandagedAbstract(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
77
                         MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
78
    {
79
    super(numL, numL[0], quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
80
    }
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
  protected int[] getSolvedQuats(int cubit, int[] numLayers)
125
    {
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
  protected ObjectShape getObjectShape(int cubit, int[] numLayers)
158
    {
159
    int variant = getCubitVariant(cubit,numLayers);
160

    
161
    final int[][] vert_indices =
162
      {
163
        {2,3,1,0},
164
        {7,6,4,5},
165
        {4,0,1,5},
166
        {7,3,2,6},
167
        {6,2,0,4},
168
        {3,7,5,1},
169
      };
170

    
171
    float defHeight = 0.048f;
172
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
173
    float[][] corners = new float[][] { {0.04f,0.15f} };
174
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
175
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
176

    
177
    int X = mDimensions[variant][0];
178
    int Y = mDimensions[variant][1];
179
    int Z = mDimensions[variant][2];
180

    
181
    int maxXY = Math.max(X,Y);
182
    int maxXZ = Math.max(X,Z);
183
    int maxYZ = Math.max(Y,Z);
184

    
185
    double[][] vertices =
186
      {
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
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
194
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
195
      };
196

    
197
    float[][] bands= new float[][]
198
      {
199
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
200
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
201
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
202
      };
203

    
204
    float[][] centers = new float[][]
205
      {
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
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
213
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
214
      };
215

    
216
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  protected Static4D getQuat(int cubit, int[] numLayers)
222
    {
223
    if( mInitQuats ==null )
224
      {
225
      mInitQuats = new Static4D[]
226
        {
227
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
228
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
229
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
230
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
231
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
232
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
233
        };
234
      }
235

    
236
    return mInitQuats[getQuatIndex(cubit)];
237
    }
238

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

    
241
  protected int getNumCubitVariants(int[] numLayers)
242
    {
243
    return mDimensions.length;
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  protected int getCubitVariant(int cubit, int[] numLayers)
249
    {
250
    float[][] pos = getPositions();
251

    
252
    if( cubit>=0 && cubit<pos.length )
253
      {
254
      int numPoints = pos[cubit].length/3;
255
      return numPoints==8 ? 4 : numPoints-1;
256
      }
257

    
258
    return 1;
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  public ObjectSticker retSticker(int sticker)
264
    {
265
    if( mStickers==null )
266
      {
267
      mStickers = new ObjectSticker[NUM_STICKERS];
268

    
269
      int[][] stickerDimensions = new int[][]
270
        {
271
         {1,1},  // dimensions of the faces of
272
         {2,1},  // the cuboids defined in mDimensions
273
         {3,1},
274
         {2,2}
275
        };
276

    
277
      for(int s=0; s<NUM_STICKERS; s++)
278
        {
279
        float X = stickerDimensions[s][0];
280
        float Y = stickerDimensions[s][1];
281
        float MAX = Math.max(X,Y);
282
        X /= (2*MAX);
283
        Y /= (2*MAX);
284

    
285
        float radius = 0.10f / MAX;
286
        float stroke = 0.08f / MAX;
287
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
288
        float[] radii = new float[] {radius,radius,radius,radius};
289

    
290
        if( ObjectControl.isInIconMode() )
291
          {
292
          stroke*=2.0f;
293
          }
294

    
295
        mStickers[s] = new ObjectSticker(coords,null,radii,stroke);
296
        }
297
      }
298

    
299
    return mStickers[sticker];
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  protected int getStickerIndex(int face)
305
    {
306
    return face/NUM_FACE_COLORS;
307
    }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
  protected float[][] getCubitPositions(int[] numLayers)
312
    {
313
    int numCubits = getNumCubits();
314
    float[][] tmp = new float[numCubits][];
315

    
316
    for(int cubit=0; cubit<numCubits; cubit++)
317
      {
318
      tmp[cubit] = getCubitPosition(cubit);
319
      }
320

    
321
    return tmp;
322
    }
323

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

    
326
  public Static4D[] getQuats()
327
    {
328
    if( mQuats==null ) initializeQuats();
329
    return mQuats;
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  public float[][] getCuts(int[] numLayers)
335
    {
336
    int numL = numLayers[0];
337

    
338
    if( numL<2 ) return null;
339

    
340
    if( mCuts==null )
341
      {
342
      mCuts = new float[3][numL-1];
343

    
344
      for(int i=0; i<numL-1; i++)
345
        {
346
        float cut = (2-numL)*0.5f + i;
347
        mCuts[0][i] = cut;
348
        mCuts[1][i] = cut;
349
        mCuts[2][i] = cut;
350
        }
351
      }
352

    
353
    return mCuts;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  public boolean[][] getLayerRotatable(int[] numLayers)
359
    {
360
    int numAxis = ROT_AXIS.length;
361
    boolean[][] layerRotatable = new boolean[numAxis][];
362

    
363
    for(int i=0; i<numAxis; i++)
364
      {
365
      layerRotatable[i] = new boolean[numLayers[i]];
366
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
367
      }
368

    
369
    return layerRotatable;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  public int getMovementType()
375
    {
376
    return MOVEMENT_HEXAHEDRON;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  public int getMovementSplit()
382
    {
383
    return TYPE_NOT_SPLIT;
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  public int[][][] getEnabled()
389
    {
390
    return new int[][][]
391
      {
392
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
393
      };
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  public float[] getDist3D(int[] numLayers)
399
    {
400
    return null;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  public int getSolvedFunctionIndex()
406
    {
407
    return 0;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  public int getNumStickerTypes(int[] numLayers)
413
    {
414
    return NUM_STICKERS;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

    
419
  protected int getNumCubitFaces()
420
    {
421
    return 6;
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  private int retStickerIndex(int horzSize, int vertSize)
427
    {
428
    switch(horzSize)
429
      {
430
      case 1: return 0;
431
      case 2: return vertSize==1 ? 1:3;
432
      case 3: return 2;
433
      }
434

    
435
    return 0;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  private int getStickerIndex(int cubitface, int[] dim)
441
    {
442
    switch(cubitface)
443
      {
444
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
445
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
446
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
447
      }
448

    
449
    return 0;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
455
    {
456
    if( mFaceMap==null )
457
      {
458
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
459
      mFaceMap = new int[][]
460
          {
461
              {0,0,5,2,4,2},
462
              {1,1,4,3,5,3},
463
              {2,4,2,1,1,4},
464
              {3,5,3,0,0,5},
465
              {4,3,0,4,3,0},
466
              {5,2,1,5,2,1}
467
          };
468
      }
469

    
470
    if( mAxisMap==null )
471
      {
472
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
473
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
474
      }
475

    
476
    int variant      = getCubitVariant(cubit,numLayers);
477
    int[] dim        = mDimensions[variant];
478
    float[] pos      = getCubitPosition(cubit);
479
    int stickerIndex = getStickerIndex(cubitface,dim);
480
    int quatIndex    = getQuatIndex(cubit);
481
    int face         = mFaceMap[cubitface][quatIndex];
482
    int multiplier   = (face%2)==0 ? 1:-1;
483
    int posIndex     = face/2;
484
    int dimIndex     = mAxisMap[posIndex][quatIndex];
485

    
486
    float position = 0.0f;
487
    int len = pos.length/3;
488
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
489
    position /= len;
490

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

    
493
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
// PUBLIC API
498

    
499
  public Static3D[] getRotationAxis()
500
    {
501
    return ROT_AXIS;
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public int[] getBasicAngle()
507
    {
508
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
509
    return mBasicAngle;
510
    }
511
}
(3-3/25)