Project

General

Profile

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

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

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
import java.util.Random;
34

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

    
37
abstract class TwistyBandagedAbstract extends TwistyObject
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[] BASIC_ANGLE = new int[] { 4,4,4 };
48

    
49
  private static final int[] FACE_COLORS = new int[]
50
         {
51
           COLOR_YELLOW, COLOR_WHITE,
52
           COLOR_BLUE  , COLOR_GREEN,
53
           COLOR_RED   , COLOR_ORANGE
54
         };
55

    
56
  private static final Static4D[] QUATS = new Static4D[]
57
         {
58
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
59
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
60
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
61
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
62

    
63
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
64
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
65
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
66
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
67
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
68
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
69
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
70
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
71
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
72
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
73
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
74
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
75

    
76
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
77
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
78
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
79
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
80
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
81
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
82
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
83
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
84
         };
85

    
86
  private static final Static4D[] INIT_QUATS = new Static4D[]
87
        {
88
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
89
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
90
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
91
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
92
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
93
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
94
        };
95

    
96
  private static final int[][] mDimensions = new int[][]
97
        {
98
         {1,1,1},  // has to be X>=Z>=Y so that all
99
         {2,1,1},  // the faces are horizontal
100
         {3,1,1},
101
         {2,1,2},
102
         {2,2,2}
103
        };
104

    
105
  private static final int[][] mStickerDimensions = new int[][]
106
        {
107
         {1,1},  // dimensions of the faces of
108
         {2,1},  // the cuboids defined above
109
         {3,1},
110
         {2,2}
111
        };
112

    
113
  private static final int[][] mFaceMap = new int[][] // cubitface=2 when rotated by
114
    {                                                 // quatIndex=1 gets moved to
115
        {0,0,5,2,4,2},                                // position mFaceMap[2][1]
116
        {1,1,4,3,5,3},
117
        {2,4,2,1,1,4},
118
        {3,5,3,0,0,5},
119
        {4,3,0,4,3,0},
120
        {5,2,1,5,2,1}
121
    };
122

    
123
  private static final int[][] mAxisMap = new int[][] // axis=1 when rotated by
124
    {                                                 // quatIndex=2 gets moved to
125
        {0,0,2,1,2,1},                                // axis mAxisMap[1][2]
126
        {1,2,1,0,0,2},
127
        {2,1,0,2,1,0}
128
    };
129

    
130
  private static final int NUM_STICKERS = mStickerDimensions.length;
131

    
132
  private static final ObjectSticker[] mStickers;
133

    
134
  static
135
    {
136
    mStickers = new ObjectSticker[NUM_STICKERS];
137

    
138
    for(int s=0; s<NUM_STICKERS; s++)
139
      {
140
      float X = mStickerDimensions[s][0];
141
      float Y = mStickerDimensions[s][1];
142
      float MAX = Math.max(X,Y);
143
      X /= (2*MAX);
144
      Y /= (2*MAX);
145

    
146
      float R = 0.10f / MAX;
147
      float S = 0.08f / MAX;
148
      float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
149
      float[] radii = new float[] {R,R,R,R};
150
      mStickers[s] = new ObjectSticker(coords,null,radii,S);
151
      }
152
    }
153

    
154
  private int mCurrState;
155
  private int mIndexExcluded;
156
  private int[][] mScrambleTable;
157
  private int[] mNumOccurences;
158
  ScrambleState[] mStates;
159
  float[][] POSITIONS;
160
  int[] QUAT_INDICES;
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
165
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
166
    {
167
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  abstract float[][] getPositions();
173
  abstract int[] getQuatIndices();
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  int[] getSolvedQuats(int cubit, int numLayers)
178
    {
179
    int status = retCubitSolvedStatus(cubit,numLayers);
180
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  int getNumCubits()
186
    {
187
    return getPositions().length;
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  private float[] getCubitPosition(int cubit)
193
    {
194
    float[][] pos = getPositions();
195

    
196
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  private int getQuatIndex(int cubit)
202
    {
203
    int[] indices = getQuatIndices();
204
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  ObjectShape getObjectShape(int cubit, int numLayers)
210
    {
211
    int variant = getCubitVariant(cubit,numLayers);
212

    
213
    final int[][] vert_indices =
214
      {
215
        {2,3,1,0},
216
        {7,6,4,5},
217
        {4,0,1,5},
218
        {7,3,2,6},
219
        {6,2,0,4},
220
        {3,7,5,1},
221
      };
222

    
223
    float defHeight = 0.048f;
224
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
225
    float[][] corners = new float[][] { {0.04f,0.15f} };
226
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
227
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
228

    
229
    int X = mDimensions[variant][0];
230
    int Y = mDimensions[variant][1];
231
    int Z = mDimensions[variant][2];
232

    
233
    int maxXY = Math.max(X,Y);
234
    int maxXZ = Math.max(X,Z);
235
    int maxYZ = Math.max(Y,Z);
236

    
237
    double[][] vertices =
238
      {
239
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
240
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
241
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
242
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
243
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
244
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
245
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
246
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
247
      };
248

    
249
    float[][] bands= new float[][]
250
      {
251
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
252
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
253
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
254
      };
255

    
256
    float[][] centers = new float[][]
257
      {
258
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
259
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
260
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
261
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
262
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
263
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
264
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
265
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
266
      };
267

    
268
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  Static4D getQuat(int cubit, int numLayers)
274
    {
275
    return INIT_QUATS[getQuatIndex(cubit)];
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  int getNumCubitVariants(int numLayers)
281
    {
282
    return mDimensions.length;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  int getCubitVariant(int cubit, int numLayers)
288
    {
289
    float[][] pos = getPositions();
290

    
291
    if( cubit>=0 && cubit<pos.length )
292
      {
293
      int numPoints = pos[cubit].length/3;
294
      return numPoints==8 ? 4 : numPoints-1;
295
      }
296

    
297
    return 1;
298
    }
299

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

    
302
  int getColor(int face)
303
    {
304
    return FACE_COLORS[face];
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  ObjectSticker retSticker(int face)
310
    {
311
    return mStickers[face/NUM_FACES];
312
    }
313

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

    
316
  float[][] getCubitPositions(int size)
317
    {
318
    int numCubits = getNumCubits();
319
    float[][] tmp = new float[numCubits][];
320

    
321
    for(int cubit=0; cubit<numCubits; cubit++)
322
      {
323
      tmp[cubit] = getCubitPosition(cubit);
324
      }
325

    
326
    return tmp;
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  Static4D[] getQuats()
332
    {
333
    return QUATS;
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  boolean shouldResetTextureMaps()
339
    {
340
    return false;
341
    }
342

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

    
345
  int getNumFaces()
346
    {
347
    return FACE_COLORS.length;
348
    }
349

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

    
352
  float[][] getCuts(int numLayers)
353
    {
354
    float[][] cuts = new float[3][numLayers-1];
355

    
356
    for(int i=0; i<numLayers-1; i++)
357
      {
358
      float cut = (2-numLayers)*0.5f + i;
359
      cuts[0][i] = cut;
360
      cuts[1][i] = cut;
361
      cuts[2][i] = cut;
362
      }
363

    
364
    return cuts;
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  int getSolvedFunctionIndex()
370
    {
371
    return 0;
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  int getNumStickerTypes(int numLayers)
377
    {
378
    return NUM_STICKERS;
379
    }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

    
383
  int getNumCubitFaces()
384
    {
385
    return FACE_COLORS.length;
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  float getScreenRatio()
391
    {
392
    return 0.5f;
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  private int retStickerIndex(int horzSize, int vertSize)
398
    {
399
    switch(horzSize)
400
      {
401
      case 1: return 0;
402
      case 2: return vertSize==1 ? 1:3;
403
      case 3: return 2;
404
      }
405

    
406
    return 0;
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
  private int getStickerIndex(int cubitface, int[] dim)
412
    {
413
    switch(cubitface)
414
      {
415
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
416
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
417
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
418
      }
419

    
420
    return 0;
421
    }
422

    
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424

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

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

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

    
444
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  float returnMultiplier()
450
    {
451
    return getNumLayers();
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  private void initializeScrambling()
457
    {
458
    int numLayers = getNumLayers();
459

    
460
    if( mScrambleTable ==null )
461
      {
462
      mScrambleTable = new int[NUM_AXIS][numLayers];
463
      }
464
    if( mNumOccurences ==null )
465
      {
466
      int max=0;
467

    
468
      for (ScrambleState mState : mStates)
469
        {
470
        int tmp = mState.getTotal(-1);
471
        if (max < tmp) max = tmp;
472
        }
473

    
474
      mNumOccurences = new int[max];
475
      }
476

    
477
    for(int i=0; i<NUM_AXIS; i++)
478
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482
// PUBLIC API
483

    
484
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
485
    {
486
    if( curr==0 )
487
      {
488
      mCurrState     = 0;
489
      mIndexExcluded =-1;
490
      initializeScrambling();
491
      }
492

    
493
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
494

    
495
    scramble[curr][0] = info[0];
496
    scramble[curr][1] = info[1];
497
    scramble[curr][2] = info[2];
498

    
499
    mCurrState     = info[3];
500
    mIndexExcluded = info[0];
501
    }
502

    
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504

    
505
  public Static3D[] getRotationAxis()
506
    {
507
    return ROT_AXIS;
508
    }
509

    
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

    
512
  public int[] getBasicAngle()
513
    {
514
    return BASIC_ANGLE;
515
    }
516
}
(19-19/41)