Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 967c1d17

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[] NUM_ENABLED = {2,2,2,2,2,2};
57

    
58
  private static final int[][][] ENABLED = new int[][][]
59
      {
60
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
61
      };
62

    
63
  private static final int NUM_STICKERS = 4;
64

    
65
  private int[] mBasicAngle;
66
  private Static4D[] mQuats;
67
  private ObjectSticker[] mStickers;
68
  private Static4D[] mInitQuats;
69
  private int[][] mAxisMap;
70
  private int[][] mFaceMap;
71
  private float[][] mCuts;
72
  private boolean[][] mLayerRotatable;
73
  private Movement mMovement;
74
  ScrambleState[] mStates;
75
  float[][] POSITIONS;
76
  int[] QUAT_INDICES;
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

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

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
  abstract float[][] getPositions();
89
  abstract int[] getQuatIndices();
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

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

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

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

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

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

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  int getNumCubits()
138
    {
139
    return getPositions().length;
140
    }
141

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

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

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

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

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

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  ObjectShape getObjectShape(int cubit, int numLayers)
162
    {
163
    int variant = getCubitVariant(cubit,numLayers);
164

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

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

    
181
    int X = mDimensions[variant][0];
182
    int Y = mDimensions[variant][1];
183
    int Z = mDimensions[variant][2];
184

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

    
189
    double[][] vertices =
190
      {
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
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
198
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
199
      };
200

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

    
208
    float[][] centers = new float[][]
209
      {
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
        {-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
      };
219

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

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

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

    
240
    return mInitQuats[getQuatIndex(cubit)];
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  int getNumCubitVariants(int numLayers)
246
    {
247
    return mDimensions.length;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

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

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

    
262
    return 1;
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

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

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

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

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

    
297
    return mStickers[face/NUM_FACE_COLORS];
298
    }
299

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

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

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

    
312
    return tmp;
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

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

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

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

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

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

    
342
    return mCuts;
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

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

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  int getSolvedFunctionIndex()
362
    {
363
    return 0;
364
    }
365

    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

    
368
  int getNumStickerTypes(int numLayers)
369
    {
370
    return NUM_STICKERS;
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  int getNumCubitFaces()
376
    {
377
    return 6;
378
    }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

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

    
391
    return 0;
392
    }
393

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

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

    
405
    return 0;
406
    }
407

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

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

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

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

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

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

    
449
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453
// PUBLIC API
454

    
455
  public Static3D[] getRotationAxis()
456
    {
457
    return ROT_AXIS;
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

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

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

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