Project

General

Profile

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

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

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
  protected ObjectSticker retSticker(int face)
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[face/NUM_FACE_COLORS];
300
    }
301

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

    
304
  protected float[][] getCubitPositions(int[] numLayers)
305
    {
306
    int numCubits = getNumCubits();
307
    float[][] tmp = new float[numCubits][];
308

    
309
    for(int cubit=0; cubit<numCubits; cubit++)
310
      {
311
      tmp[cubit] = getCubitPosition(cubit);
312
      }
313

    
314
    return tmp;
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  protected Static4D[] getQuats()
320
    {
321
    if( mQuats==null ) initializeQuats();
322
    return mQuats;
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  protected float[][] getCuts(int[] numLayers)
328
    {
329
    int numL = numLayers[0];
330

    
331
    if( numL<2 ) return null;
332

    
333
    if( mCuts==null )
334
      {
335
      mCuts = new float[3][numL-1];
336

    
337
      for(int i=0; i<numL-1; i++)
338
        {
339
        float cut = (2-numL)*0.5f + i;
340
        mCuts[0][i] = cut;
341
        mCuts[1][i] = cut;
342
        mCuts[2][i] = cut;
343
        }
344
      }
345

    
346
    return mCuts;
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  public boolean[][] getLayerRotatable(int[] numLayers)
352
    {
353
    int numAxis = ROT_AXIS.length;
354
    boolean[][] layerRotatable = new boolean[numAxis][];
355

    
356
    for(int i=0; i<numAxis; i++)
357
      {
358
      layerRotatable[i] = new boolean[numLayers[i]];
359
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
360
      }
361

    
362
    return layerRotatable;
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  public int getMovementType()
368
    {
369
    return MOVEMENT_HEXAHEDRON;
370
    }
371

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

    
374
  public int getMovementSplit()
375
    {
376
    return TYPE_NOT_SPLIT;
377
    }
378

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

    
381
  public int[][][] getEnabled()
382
    {
383
    return new int[][][]
384
      {
385
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
386
      };
387
    }
388

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

    
391
  public float[] getDist3D(int[] numLayers)
392
    {
393
    return null;
394
    }
395

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

    
398
  public int getSolvedFunctionIndex()
399
    {
400
    return 0;
401
    }
402

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

    
405
  protected int getNumStickerTypes(int[] numLayers)
406
    {
407
    return NUM_STICKERS;
408
    }
409

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

    
412
  protected int getNumCubitFaces()
413
    {
414
    return 6;
415
    }
416

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

    
419
  private int retStickerIndex(int horzSize, int vertSize)
420
    {
421
    switch(horzSize)
422
      {
423
      case 1: return 0;
424
      case 2: return vertSize==1 ? 1:3;
425
      case 3: return 2;
426
      }
427

    
428
    return 0;
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  private int getStickerIndex(int cubitface, int[] dim)
434
    {
435
    switch(cubitface)
436
      {
437
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
438
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
439
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
440
      }
441

    
442
    return 0;
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
448
    {
449
    if( mFaceMap==null )
450
      {
451
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
452
      mFaceMap = new int[][]
453
          {
454
              {0,0,5,2,4,2},
455
              {1,1,4,3,5,3},
456
              {2,4,2,1,1,4},
457
              {3,5,3,0,0,5},
458
              {4,3,0,4,3,0},
459
              {5,2,1,5,2,1}
460
          };
461
      }
462

    
463
    if( mAxisMap==null )
464
      {
465
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
466
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
467
      }
468

    
469
    int variant      = getCubitVariant(cubit,numLayers);
470
    int[] dim        = mDimensions[variant];
471
    float[] pos      = getCubitPosition(cubit);
472
    int stickerIndex = getStickerIndex(cubitface,dim);
473
    int quatIndex    = getQuatIndex(cubit);
474
    int face         = mFaceMap[cubitface][quatIndex];
475
    int multiplier   = (face%2)==0 ? 1:-1;
476
    int posIndex     = face/2;
477
    int dimIndex     = mAxisMap[posIndex][quatIndex];
478

    
479
    float position = 0.0f;
480
    int len = pos.length/3;
481
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
482
    position /= len;
483

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

    
486
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490
// PUBLIC API
491

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

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

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