Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 7ee89540

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 static org.distorted.objects.Movement.TYPE_NOT_SPLIT;
23

    
24
import android.content.res.Resources;
25

    
26
import org.distorted.helpers.ObjectShape;
27
import org.distorted.helpers.ObjectSticker;
28
import org.distorted.helpers.ScrambleState;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshSquare;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

    
37
abstract class TwistyBandagedAbstract extends Twisty6
38
{
39
  // the three rotation axis of a 3x3 Cube. Must be normalized.
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(1,0,0),
43
           new Static3D(0,1,0),
44
           new Static3D(0,0,1)
45
         };
46

    
47
  private static final int[][] mDimensions = new int[][]
48
        {
49
         {1,1,1},  // has to be X>=Z>=Y so that all
50
         {2,1,1},  // the faces are horizontal
51
         {3,1,1},
52
         {2,1,2},
53
         {2,2,2}
54
        };
55

    
56
  private static final int[][][] ENABLED = new int[][][]
57
      {
58
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
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
  private boolean[][] mLayerRotatable;
71
  private Movement mMovement;
72
  ScrambleState[] mStates;
73
  float[][] POSITIONS;
74
  int[] QUAT_INDICES;
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
79
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
80
    {
81
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
82
    }
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  abstract float[][] getPositions();
87
  abstract int[] getQuatIndices();
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  private void initializeQuats()
92
    {
93
    mQuats = new Static4D[]
94
         {
95
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
96
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
97
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
98
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
99

    
100
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
101
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
102
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
103
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
104
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
105
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
106
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
107
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
108
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
109
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
110
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
111
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
112

    
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
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
120
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
121
         };
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  int[] getSolvedQuats(int cubit, int numLayers)
127
    {
128
    if( mQuats==null ) initializeQuats();
129
    int status = retCubitSolvedStatus(cubit,numLayers);
130
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
131
    }
132

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

    
135
  int getNumCubits()
136
    {
137
    return getPositions().length;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  private float[] getCubitPosition(int cubit)
143
    {
144
    float[][] pos = getPositions();
145

    
146
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  private int getQuatIndex(int cubit)
152
    {
153
    int[] indices = getQuatIndices();
154
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  ObjectShape getObjectShape(int cubit, int numLayers)
160
    {
161
    int variant = getCubitVariant(cubit,numLayers);
162

    
163
    final int[][] vert_indices =
164
      {
165
        {2,3,1,0},
166
        {7,6,4,5},
167
        {4,0,1,5},
168
        {7,3,2,6},
169
        {6,2,0,4},
170
        {3,7,5,1},
171
      };
172

    
173
    float defHeight = 0.048f;
174
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
175
    float[][] corners = new float[][] { {0.04f,0.15f} };
176
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
177
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
178

    
179
    int X = mDimensions[variant][0];
180
    int Y = mDimensions[variant][1];
181
    int Z = mDimensions[variant][2];
182

    
183
    int maxXY = Math.max(X,Y);
184
    int maxXZ = Math.max(X,Z);
185
    int maxYZ = Math.max(Y,Z);
186

    
187
    double[][] vertices =
188
      {
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
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
196
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
197
      };
198

    
199
    float[][] bands= new float[][]
200
      {
201
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
202
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
203
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
204
      };
205

    
206
    float[][] centers = new float[][]
207
      {
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
        {-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
      };
217

    
218
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
219
    }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

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

    
238
    return mInitQuats[getQuatIndex(cubit)];
239
    }
240

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

    
243
  int getNumCubitVariants(int numLayers)
244
    {
245
    return mDimensions.length;
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  int getCubitVariant(int cubit, int numLayers)
251
    {
252
    float[][] pos = getPositions();
253

    
254
    if( cubit>=0 && cubit<pos.length )
255
      {
256
      int numPoints = pos[cubit].length/3;
257
      return numPoints==8 ? 4 : numPoints-1;
258
      }
259

    
260
    return 1;
261
    }
262

    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
  ObjectSticker retSticker(int face)
266
    {
267
    if( mStickers==null )
268
      {
269
      mStickers = new ObjectSticker[NUM_STICKERS];
270

    
271
      int[][] stickerDimensions = new int[][]
272
        {
273
         {1,1},  // dimensions of the faces of
274
         {2,1},  // the cuboids defined in mDimensions
275
         {3,1},
276
         {2,2}
277
        };
278

    
279
      for(int s=0; s<NUM_STICKERS; s++)
280
        {
281
        float X = stickerDimensions[s][0];
282
        float Y = stickerDimensions[s][1];
283
        float MAX = Math.max(X,Y);
284
        X /= (2*MAX);
285
        Y /= (2*MAX);
286

    
287
        float R = 0.10f / MAX;
288
        float S = 0.08f / MAX;
289
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
290
        float[] radii = new float[] {R,R,R,R};
291
        mStickers[s] = new ObjectSticker(coords,null,radii,S);
292
        }
293
      }
294

    
295
    return mStickers[face/NUM_FACE_COLORS];
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  float[][] getCubitPositions(int size)
301
    {
302
    int numCubits = getNumCubits();
303
    float[][] tmp = new float[numCubits][];
304

    
305
    for(int cubit=0; cubit<numCubits; cubit++)
306
      {
307
      tmp[cubit] = getCubitPosition(cubit);
308
      }
309

    
310
    return tmp;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  Static4D[] getQuats()
316
    {
317
    if( mQuats==null ) initializeQuats();
318
    return mQuats;
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  float[][] getCuts(int numLayers)
324
    {
325
    if( numLayers<2 ) return null;
326

    
327
    if( mCuts==null )
328
      {
329
      mCuts = new float[3][numLayers-1];
330

    
331
      for(int i=0; i<numLayers-1; i++)
332
        {
333
        float cut = (2-numLayers)*0.5f + i;
334
        mCuts[0][i] = cut;
335
        mCuts[1][i] = cut;
336
        mCuts[2][i] = cut;
337
        }
338
      }
339

    
340
    return mCuts;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  private void getLayerRotatable(int numLayers)
346
    {
347
    if( mLayerRotatable==null )
348
      {
349
      int numAxis = ROT_AXIS.length;
350
      boolean[] tmp = new boolean[numLayers];
351
      for(int i=0; i<numLayers; i++) tmp[i] = true;
352
      mLayerRotatable = new boolean[numAxis][];
353
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
354
      }
355
    }
356

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

    
359
  int getSolvedFunctionIndex()
360
    {
361
    return 0;
362
    }
363

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

    
366
  int getNumStickerTypes(int numLayers)
367
    {
368
    return NUM_STICKERS;
369
    }
370

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

    
373
  int getNumCubitFaces()
374
    {
375
    return 6;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  private int retStickerIndex(int horzSize, int vertSize)
381
    {
382
    switch(horzSize)
383
      {
384
      case 1: return 0;
385
      case 2: return vertSize==1 ? 1:3;
386
      case 3: return 2;
387
      }
388

    
389
    return 0;
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  private int getStickerIndex(int cubitface, int[] dim)
395
    {
396
    switch(cubitface)
397
      {
398
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
399
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
400
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
401
      }
402

    
403
    return 0;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  int getFaceColor(int cubit, int cubitface, int numLayers)
409
    {
410
    if( mFaceMap==null )
411
      {
412
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
413
      mFaceMap = new int[][]
414
          {
415
              {0,0,5,2,4,2},
416
              {1,1,4,3,5,3},
417
              {2,4,2,1,1,4},
418
              {3,5,3,0,0,5},
419
              {4,3,0,4,3,0},
420
              {5,2,1,5,2,1}
421
          };
422
      }
423

    
424
    if( mAxisMap==null )
425
      {
426
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
427
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
428
      }
429

    
430
    int variant      = getCubitVariant(cubit,numLayers);
431
    int[] dim        = mDimensions[variant];
432
    float[] pos      = getCubitPosition(cubit);
433
    int stickerIndex = getStickerIndex(cubitface,dim);
434
    int quatIndex    = getQuatIndex(cubit);
435
    int face         = mFaceMap[cubitface][quatIndex];
436
    int multiplier   = (face%2)==0 ? 1:-1;
437
    int posIndex     = face/2;
438
    int dimIndex     = mAxisMap[posIndex][quatIndex];
439

    
440
    float position = 0.0f;
441
    int len = pos.length/3;
442
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
443
    position /= len;
444

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

    
447
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451
// PUBLIC API
452

    
453
  public Static3D[] getRotationAxis()
454
    {
455
    return ROT_AXIS;
456
    }
457

    
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

    
460
  public Movement getMovement()
461
    {
462
    if( mMovement==null )
463
      {
464
      int numLayers = getNumLayers();
465
      if( mCuts==null ) getCuts(numLayers);
466
      getLayerRotatable(numLayers);
467
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
468
      }
469
    return mMovement;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  public int[] getBasicAngle()
475
    {
476
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
477
    return mBasicAngle;
478
    }
479
}
(14-14/38)