Project

General

Profile

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

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

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
  ScrambleState[] mStates;
157
  private int[][] mScrambleTable;
158
  private int[] mNumOccurences;
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

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

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

    
170
  abstract float[][] getPositions();
171
  abstract int[] getQuatIndices();
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

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

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  int getNumCubits()
184
    {
185
    return getPositions().length;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

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

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

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

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

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  ObjectShape getObjectShape(int cubit, int numLayers)
208
    {
209
    int variant = getCubitVariant(cubit,numLayers);
210

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

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

    
227
    int X = mDimensions[variant][0];
228
    int Y = mDimensions[variant][1];
229
    int Z = mDimensions[variant][2];
230

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

    
235
    double[][] vertices =
236
      {
237
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
238
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
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
      };
246

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

    
254
    float[][] centers = new float[][]
255
      {
256
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
257
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
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
      };
265

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

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

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

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
  int getNumCubitVariants(int numLayers)
279
    {
280
    return mDimensions.length;
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

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

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

    
295
    return 1;
296
    }
297

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

    
300
  int getColor(int face)
301
    {
302
    return FACE_COLORS[face];
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

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

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

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

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

    
324
    return tmp;
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  Static4D[] getQuats()
330
    {
331
    return QUATS;
332
    }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  boolean shouldResetTextureMaps()
337
    {
338
    return false;
339
    }
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  int getNumFaces()
344
    {
345
    return FACE_COLORS.length;
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

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

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

    
362
    return cuts;
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  int getSolvedFunctionIndex()
368
    {
369
    return 0;
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  int getNumStickerTypes(int numLayers)
375
    {
376
    return NUM_STICKERS;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  int getNumCubitFaces()
382
    {
383
    return FACE_COLORS.length;
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  float getScreenRatio()
389
    {
390
    return 0.5f;
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

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

    
404
    return 0;
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

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

    
418
    return 0;
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

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

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

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

    
442
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  float returnMultiplier()
448
    {
449
    return getNumLayers();
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  private void initializeScrambling()
455
    {
456
    int numLayers = getNumLayers();
457

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

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

    
472
      mNumOccurences = new int[max];
473
      }
474

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

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480
// PUBLIC API
481

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

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

    
493
    scramble[curr][0] = info[0];
494
    scramble[curr][1] = info[1];
495
    scramble[curr][2] = info[2];
496

    
497
    mCurrState     = info[3];
498
    mIndexExcluded = info[0];
499
    }
500

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

    
503
  public Static3D[] getRotationAxis()
504
    {
505
    return ROT_AXIS;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

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