Project

General

Profile

Download (15.1 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ ef018c1b

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