Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 6cf89a3e

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

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

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

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
  abstract float[][] getPositions();
169
  abstract int[] getQuatIndices();
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

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

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  int getNumCubits()
182
    {
183
    return getPositions().length;
184
    }
185

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

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

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

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

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

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  ObjectShape getObjectShape(int cubit, int numLayers)
206
    {
207
    int variant = getCubitVariant(cubit,numLayers);
208

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

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

    
225
    int X = mDimensions[variant][0];
226
    int Y = mDimensions[variant][1];
227
    int Z = mDimensions[variant][2];
228

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

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

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

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

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

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

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

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  int getNumCubitVariants(int numLayers)
277
    {
278
    return mDimensions.length;
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

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

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

    
293
    return 1;
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  int getColor(int face)
299
    {
300
    return FACE_COLORS[face];
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

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

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

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

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

    
322
    return tmp;
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  Static4D[] getQuats()
328
    {
329
    return QUATS;
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  boolean shouldResetTextureMaps()
335
    {
336
    return false;
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  int getNumFaces()
342
    {
343
    return FACE_COLORS.length;
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

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

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

    
360
    return cuts;
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  int getSolvedFunctionIndex()
366
    {
367
    return 0;
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  int getNumStickerTypes(int numLayers)
373
    {
374
    return NUM_STICKERS;
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  int getNumCubitFaces()
380
    {
381
    return FACE_COLORS.length;
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  float getScreenRatio()
387
    {
388
    return 0.5f;
389
    }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

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

    
402
    return 0;
403
    }
404

    
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

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

    
416
    return 0;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  int getFaceColor(int cubit, int cubitface, int numLayers)
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_FACES + face : NUM_STICKERS*NUM_FACES;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  float returnMultiplier()
446
    {
447
    return getNumLayers();
448
    }
449

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

    
453
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
454
    {
455
    if( curr==0 )
456
      {
457
      mCurrState     = 0;
458
      mIndexExcluded =-1;
459
      }
460

    
461
    int total = mStates[mCurrState].getTotal(mIndexExcluded);
462
    int random= rnd.nextInt(total);
463
    int[] info= mStates[mCurrState].getInfo(random,mIndexExcluded);
464

    
465
    scramble[curr][0] = info[0];
466
    scramble[curr][1] = info[1];
467
    scramble[curr][2] = info[2];
468

    
469
    mCurrState     = info[3];
470
    mIndexExcluded = info[0];
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public Static3D[] getRotationAxis()
476
    {
477
    return ROT_AXIS;
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481

    
482
  public int[] getBasicAngle()
483
    {
484
    return BASIC_ANGLE;
485
    }
486
}
(19-19/41)