Project

General

Profile

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

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

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
  public 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
  public ObjectShape getObjectShape(int variant)
158
    {
159
    final int[][] vert_indices =
160
      {
161
        {2,3,1,0},
162
        {7,6,4,5},
163
        {4,0,1,5},
164
        {7,3,2,6},
165
        {6,2,0,4},
166
        {3,7,5,1},
167
      };
168

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

    
175
    int X = mDimensions[variant][0];
176
    int Y = mDimensions[variant][1];
177
    int Z = mDimensions[variant][2];
178

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

    
183
    double[][] vertices =
184
      {
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
        {-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
      };
194

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

    
202
    float[][] centers = new float[][]
203
      {
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
        {-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
      };
213

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

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

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

    
234
    return mInitQuats[getQuatIndex(cubit)];
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  public int getNumCubitVariants(int[] numLayers)
240
    {
241
    return mDimensions.length;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public int getCubitVariant(int cubit, int[] numLayers)
247
    {
248
    float[][] pos = getPositions();
249

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

    
256
    return 1;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

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

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

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

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

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

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

    
297
    return mStickers[sticker];
298
    }
299

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

    
302
  protected int getStickerIndex(int face)
303
    {
304
    return face/NUM_FACE_COLORS;
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  public float[][] getCubitPositions(int[] numLayers)
310
    {
311
    int numCubits = getNumCubits();
312
    float[][] tmp = new float[numCubits][];
313

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

    
319
    return tmp;
320
    }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

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

    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

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

    
336
    if( numL<2 ) return null;
337

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

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

    
351
    return mCuts;
352
    }
353

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

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

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

    
367
    return layerRotatable;
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  public int getMovementType()
373
    {
374
    return MOVEMENT_HEXAHEDRON;
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  public int getMovementSplit()
380
    {
381
    return TYPE_NOT_SPLIT;
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

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

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

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

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  public int getSolvedFunctionIndex()
404
    {
405
    return 0;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

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

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  protected int getNumCubitFaces()
418
    {
419
    return 6;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

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

    
433
    return 0;
434
    }
435

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

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

    
447
    return 0;
448
    }
449

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

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

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

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

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

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

    
491
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
492
    }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495
// PUBLIC API
496

    
497
  public Static3D[] getRotationAxis()
498
    {
499
    return ROT_AXIS;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

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