Project

General

Profile

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

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

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.TYPE_NOT_SPLIT;
23
24
import android.content.res.Resources;
25
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31
32
import org.distorted.objectlib.main.Movement;
33
import org.distorted.objectlib.main.Movement6;
34
import org.distorted.objectlib.main.ObjectShape;
35
import org.distorted.objectlib.main.ObjectSticker;
36
import org.distorted.objectlib.main.ScrambleState;
37
import org.distorted.objectlib.main.Twisty6;
38
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41
abstract class TwistyBandagedAbstract extends Twisty6
42
{
43
  // the three rotation axis of a 3x3 Cube. Must be normalized.
44
  static final Static3D[] ROT_AXIS = new Static3D[]
45
         {
46
           new Static3D(1,0,0),
47
           new Static3D(0,1,0),
48
           new Static3D(0,0,1)
49
         };
50
51
  private static final int[][] mDimensions = new int[][]
52
        {
53
         {1,1,1},  // has to be X>=Z>=Y so that all
54
         {2,1,1},  // the faces are horizontal
55
         {3,1,1},
56
         {2,1,2},
57
         {2,2,2}
58
        };
59
60
  private static final int[][][] ENABLED = new int[][][]
61
      {
62
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
63
      };
64
65
  private static final int NUM_STICKERS = 4;
66
67
  private int[] mBasicAngle;
68
  private Static4D[] mQuats;
69
  private ObjectSticker[] mStickers;
70
  private Static4D[] mInitQuats;
71
  private int[][] mAxisMap;
72
  private int[][] mFaceMap;
73
  private float[][] mCuts;
74
  private boolean[][] mLayerRotatable;
75
  private Movement mMovement;
76
  ScrambleState[] mStates;
77
  float[][] POSITIONS;
78
  int[] QUAT_INDICES;
79
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
82
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
83 61aa85e4 Leszek Koltunski
                         DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
84 29b82486 Leszek Koltunski
    {
85 61aa85e4 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, res, scrWidth);
86 29b82486 Leszek Koltunski
    }
87
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90
  abstract float[][] getPositions();
91
  abstract int[] getQuatIndices();
92
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
95
  private void initializeQuats()
96
    {
97
    mQuats = new Static4D[]
98
         {
99
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
100
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
101
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
102
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
103
104
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
105
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
106
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
107
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
108
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
109
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
110
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
111
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
112
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
113
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
114
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
115
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
116
117
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
118
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
119
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
120
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
121
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
122
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
123
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
124
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
125
         };
126
    }
127
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129
130
  protected int[] getSolvedQuats(int cubit, int numLayers)
131
    {
132
    if( mQuats==null ) initializeQuats();
133
    int status = retCubitSolvedStatus(cubit,numLayers);
134
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
135
    }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139
  int getNumCubits()
140
    {
141
    return getPositions().length;
142
    }
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
146
  private float[] getCubitPosition(int cubit)
147
    {
148
    float[][] pos = getPositions();
149
150
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
151
    }
152
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
155
  private int getQuatIndex(int cubit)
156
    {
157
    int[] indices = getQuatIndices();
158
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
159
    }
160
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162
163
  protected ObjectShape getObjectShape(int cubit, int numLayers)
164
    {
165
    int variant = getCubitVariant(cubit,numLayers);
166
167
    final int[][] vert_indices =
168
      {
169
        {2,3,1,0},
170
        {7,6,4,5},
171
        {4,0,1,5},
172
        {7,3,2,6},
173
        {6,2,0,4},
174
        {3,7,5,1},
175
      };
176
177
    float defHeight = 0.048f;
178
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
179
    float[][] corners = new float[][] { {0.04f,0.15f} };
180
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
181
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
182
183
    int X = mDimensions[variant][0];
184
    int Y = mDimensions[variant][1];
185
    int Z = mDimensions[variant][2];
186
187
    int maxXY = Math.max(X,Y);
188
    int maxXZ = Math.max(X,Z);
189
    int maxYZ = Math.max(Y,Z);
190
191
    double[][] vertices =
192
      {
193
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
194
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
195
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
196
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
197
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
198
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
199
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
200
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
201
      };
202
203
    float[][] bands= new float[][]
204
      {
205
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
206
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
207
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
208
      };
209
210
    float[][] centers = new float[][]
211
      {
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
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
215
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
216
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
217
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
218
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
219
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
220
      };
221
222
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
223
    }
224
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226
227
  protected Static4D getQuat(int cubit, int numLayers)
228
    {
229
    if( mInitQuats ==null )
230
      {
231
      mInitQuats = new Static4D[]
232
        {
233
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
234
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
235
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
236
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
237
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
238
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
239
        };
240
      }
241
242
    return mInitQuats[getQuatIndex(cubit)];
243
    }
244
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247
  protected int getNumCubitVariants(int numLayers)
248
    {
249
    return mDimensions.length;
250
    }
251
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
254
  protected int getCubitVariant(int cubit, int numLayers)
255
    {
256
    float[][] pos = getPositions();
257
258
    if( cubit>=0 && cubit<pos.length )
259
      {
260
      int numPoints = pos[cubit].length/3;
261
      return numPoints==8 ? 4 : numPoints-1;
262
      }
263
264
    return 1;
265
    }
266
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268
269
  protected ObjectSticker retSticker(int face)
270
    {
271
    if( mStickers==null )
272
      {
273
      mStickers = new ObjectSticker[NUM_STICKERS];
274
275
      int[][] stickerDimensions = new int[][]
276
        {
277
         {1,1},  // dimensions of the faces of
278
         {2,1},  // the cuboids defined in mDimensions
279
         {3,1},
280
         {2,2}
281
        };
282
283
      for(int s=0; s<NUM_STICKERS; s++)
284
        {
285
        float X = stickerDimensions[s][0];
286
        float Y = stickerDimensions[s][1];
287
        float MAX = Math.max(X,Y);
288
        X /= (2*MAX);
289
        Y /= (2*MAX);
290
291
        float R = 0.10f / MAX;
292
        float S = 0.08f / MAX;
293
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
294
        float[] radii = new float[] {R,R,R,R};
295
        mStickers[s] = new ObjectSticker(coords,null,radii,S);
296
        }
297
      }
298
299
    return mStickers[face/NUM_FACE_COLORS];
300
    }
301
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303
304
  protected float[][] getCubitPositions(int size)
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
    if( numLayers<2 ) return null;
330
331
    if( mCuts==null )
332
      {
333
      mCuts = new float[3][numLayers-1];
334
335
      for(int i=0; i<numLayers-1; i++)
336
        {
337
        float cut = (2-numLayers)*0.5f + i;
338
        mCuts[0][i] = cut;
339
        mCuts[1][i] = cut;
340
        mCuts[2][i] = cut;
341
        }
342
      }
343
344
    return mCuts;
345
    }
346
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
349
  private void getLayerRotatable(int numLayers)
350
    {
351
    if( mLayerRotatable==null )
352
      {
353
      int numAxis = ROT_AXIS.length;
354
      boolean[] tmp = new boolean[numLayers];
355
      for(int i=0; i<numLayers; i++) tmp[i] = true;
356
      mLayerRotatable = new boolean[numAxis][];
357
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
358
      }
359
    }
360
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362
363
  protected int getSolvedFunctionIndex()
364
    {
365
    return 0;
366
    }
367
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
370
  protected int getNumStickerTypes(int numLayers)
371
    {
372
    return NUM_STICKERS;
373
    }
374
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
377
  protected int getNumCubitFaces()
378
    {
379
    return 6;
380
    }
381
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
384
  private int retStickerIndex(int horzSize, int vertSize)
385
    {
386
    switch(horzSize)
387
      {
388
      case 1: return 0;
389
      case 2: return vertSize==1 ? 1:3;
390
      case 3: return 2;
391
      }
392
393
    return 0;
394
    }
395
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397
398
  private int getStickerIndex(int cubitface, int[] dim)
399
    {
400
    switch(cubitface)
401
      {
402
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
403
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
404
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
405
      }
406
407
    return 0;
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
413
    {
414
    if( mFaceMap==null )
415
      {
416
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
417
      mFaceMap = new int[][]
418
          {
419
              {0,0,5,2,4,2},
420
              {1,1,4,3,5,3},
421
              {2,4,2,1,1,4},
422
              {3,5,3,0,0,5},
423
              {4,3,0,4,3,0},
424
              {5,2,1,5,2,1}
425
          };
426
      }
427
428
    if( mAxisMap==null )
429
      {
430
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
431
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
432
      }
433
434
    int variant      = getCubitVariant(cubit,numLayers);
435
    int[] dim        = mDimensions[variant];
436
    float[] pos      = getCubitPosition(cubit);
437
    int stickerIndex = getStickerIndex(cubitface,dim);
438
    int quatIndex    = getQuatIndex(cubit);
439
    int face         = mFaceMap[cubitface][quatIndex];
440
    int multiplier   = (face%2)==0 ? 1:-1;
441
    int posIndex     = face/2;
442
    int dimIndex     = mAxisMap[posIndex][quatIndex];
443
444
    float position = 0.0f;
445
    int len = pos.length/3;
446
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
447
    position /= len;
448
449
    boolean reaches  = multiplier*position + dim[dimIndex]*0.5f > (numLayers-1)*0.5f;
450
451
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
452
    }
453
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455
// PUBLIC API
456
457
  public Static3D[] getRotationAxis()
458
    {
459
    return ROT_AXIS;
460
    }
461
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463
464
  public Movement getMovement()
465
    {
466
    if( mMovement==null )
467
      {
468
      int numLayers = getNumLayers();
469
      if( mCuts==null ) getCuts(numLayers);
470
      getLayerRotatable(numLayers);
471
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
472
      }
473
    return mMovement;
474
    }
475
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477
478
  public int[] getBasicAngle()
479
    {
480
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
481
    return mBasicAngle;
482
    }
483
}