Project

General

Profile

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

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

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.objects;
21

    
22
import android.content.res.Resources;
23

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
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
///////////////////////////////////////////////////////////////////////////////////////////////////
34

    
35
abstract class TwistyBandagedAbstract extends Twisty6
36
{
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
  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
        };
53

    
54
  private static final int NUM_STICKERS = 4;
55

    
56
  private int[] mBasicAngle;
57
  private Static4D[] mQuats;
58
  private ObjectSticker[] mStickers;
59
  private Static4D[] mInitQuats;
60
  private int[][] mAxisMap;
61
  private int[][] mFaceMap;
62
  private float[][] mCuts;
63
  private boolean[][] mLayerRotatable;
64
  private Movement mMovement;
65
  ScrambleState[] mStates;
66
  float[][] POSITIONS;
67
  int[] QUAT_INDICES;
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
72
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
73
    {
74
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  abstract float[][] getPositions();
80
  abstract int[] getQuatIndices();
81

    
82
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  int[] getSolvedQuats(int cubit, int numLayers)
120
    {
121
    if( mQuats==null ) initializeQuats();
122
    int status = retCubitSolvedStatus(cubit,numLayers);
123
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],mQuats);
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  int getNumCubits()
129
    {
130
    return getPositions().length;
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  private float[] getCubitPosition(int cubit)
136
    {
137
    float[][] pos = getPositions();
138

    
139
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  private int getQuatIndex(int cubit)
145
    {
146
    int[] indices = getQuatIndices();
147
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  ObjectShape getObjectShape(int cubit, int numLayers)
153
    {
154
    int variant = getCubitVariant(cubit,numLayers);
155

    
156
    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
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  Static4D getQuat(int cubit, int numLayers)
217
    {
218
    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
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
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

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

    
253
    return 1;
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  ObjectSticker retSticker(int face)
259
    {
260
    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
    return mStickers[face/NUM_FACE_COLORS];
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  float[][] getCubitPositions(int size)
294
    {
295
    int numCubits = getNumCubits();
296
    float[][] tmp = new float[numCubits][];
297

    
298
    for(int cubit=0; cubit<numCubits; cubit++)
299
      {
300
      tmp[cubit] = getCubitPosition(cubit);
301
      }
302

    
303
    return tmp;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  Static4D[] getQuats()
309
    {
310
    if( mQuats==null ) initializeQuats();
311
    return mQuats;
312
    }
313

    
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

    
316
  float[][] getCuts(int numLayers)
317
    {
318
    if( numLayers<2 ) return null;
319

    
320
    if( mCuts==null )
321
      {
322
      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
      }
332

    
333
    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
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  int getSolvedFunctionIndex()
353
    {
354
    return 0;
355
    }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
  int getNumStickerTypes(int numLayers)
360
    {
361
    return NUM_STICKERS;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  int getNumCubitFaces()
367
    {
368
    return 6;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  private int retStickerIndex(int horzSize, int vertSize)
374
    {
375
    switch(horzSize)
376
      {
377
      case 1: return 0;
378
      case 2: return vertSize==1 ? 1:3;
379
      case 3: return 2;
380
      }
381

    
382
    return 0;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  private int getStickerIndex(int cubitface, int[] dim)
388
    {
389
    switch(cubitface)
390
      {
391
      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
      }
395

    
396
    return 0;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  int getFaceColor(int cubit, int cubitface, int numLayers)
402
    {
403
    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
    int variant      = getCubitVariant(cubit,numLayers);
424
    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

    
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

    
440
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444
// PUBLIC API
445

    
446
  public Static3D[] getRotationAxis()
447
    {
448
    return ROT_AXIS;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public Movement getMovement()
454
    {
455
    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
    return mMovement;
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

    
468
  public int[] getBasicAngle()
469
    {
470
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
471
    return mBasicAngle;
472
    }
473
}
(24-24/48)