Project

General

Profile

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

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

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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshBase;
30
import org.distorted.library.mesh.MeshSquare;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33

    
34
import java.util.Random;
35

    
36
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

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

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

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

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

    
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
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
85
         };
86

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

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

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

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

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

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

    
133
  private static MeshBase[] mMeshes;
134

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

    
137
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
138
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
139
    {
140
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  abstract int getCubitVariant(int cubit);
146
  abstract int getNumCubits();
147
  abstract int getQuatIndex(int cubit);
148
  abstract float[] getCubitPosition(int cubit);
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  MeshBase createCubitMesh(int cubit, int numLayers)
153
    {
154
    if( mMeshes==null )
155
      {
156
      int LEN = mDimensions.length;
157
      mMeshes = new MeshBase[LEN];
158

    
159
      for(int i=0; i<LEN; i++)
160
        {
161
        mMeshes[i] = FactoryCubit.getInstance().createCuboidMesh(mDimensions[i]);
162
        }
163
      }
164

    
165
    int variant = getCubitVariant(cubit);
166
    MeshBase mesh = mMeshes[variant].copy(true);
167
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
168
    mesh.apply(quat,0xffffffff,0);
169

    
170
    return mesh;
171
    }
172

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

    
175
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
176
    {
177
    int numFaces = FACE_COLORS.length;
178
    int stickerType = face/numFaces;
179
    int color = face%numFaces;
180
    float X = mStickerDimensions[stickerType][0];
181
    float Y = mStickerDimensions[stickerType][1];
182
    float MAX = Math.max(X,Y);
183
    float R = 0.10f / MAX;
184
    float S = 0.08f / MAX;
185
    X /= (2*MAX);
186
    Y /= (2*MAX);
187

    
188
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
189

    
190
    FactorySticker factory = FactorySticker.getInstance();
191
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[color], R);
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  float[][] getCubitPositions(int size)
197
    {
198
    int numCubits = getNumCubits();
199
    float[][] tmp = new float[numCubits][];
200

    
201
    for(int cubit=0; cubit<numCubits; cubit++)
202
      {
203
      tmp[cubit] = getCubitPosition(cubit);
204
      }
205

    
206
    return tmp;
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  Static4D[] getQuats()
212
    {
213
    return QUATS;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  boolean shouldResetTextureMaps()
219
    {
220
    return false;
221
    }
222

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

    
225
  int getNumFaces()
226
    {
227
    return FACE_COLORS.length;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  float[] getCuts(int numLayers)
233
    {
234
    float[] cuts = new float[numLayers-1];
235

    
236
    for(int i=0; i<numLayers-1; i++)
237
      {
238
      cuts[i] = (2-numLayers)*0.5f + i;
239
      }
240

    
241
    return cuts;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  int getNumStickerTypes(int numLayers)
247
    {
248
    return NUM_STICKERS;
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  int getNumCubitFaces()
254
    {
255
    return FACE_COLORS.length;
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  float getScreenRatio()
261
    {
262
    return 0.5f;
263
    }
264

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

    
267
  private int retStickerIndex(int horzSize, int vertSize)
268
    {
269
    switch(horzSize)
270
      {
271
      case 1: return 0;
272
      case 2: return vertSize==1 ? 1:3;
273
      case 3: return 2;
274
      }
275

    
276
    return 0;
277
    }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

    
281
  private int getStickerIndex(int cubitface, int[] dim)
282
    {
283
    switch(cubitface)
284
      {
285
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
286
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
287
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
288
      }
289

    
290
    return 0;
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  int getFaceColor(int cubit, int cubitface, int numLayers)
296
    {
297
    int variant      = getCubitVariant(cubit);
298
    int[] dim        = mDimensions[variant];
299
    float[] pos      = getCubitPosition(cubit);
300
    int stickerIndex = getStickerIndex(cubitface,dim);
301
    int quatIndex    = getQuatIndex(cubit);
302
    int face         = mFaceMap[cubitface][quatIndex];
303
    int multiplier   = (face%2)==0 ? 1:-1;
304
    int posIndex     = face/2;
305
    int dimIndex     = mAxisMap[posIndex][quatIndex];
306

    
307
    float position = 0.0f;
308
    int len = pos.length/3;
309
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
310
    position /= len;
311

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

    
314
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  int computeBitmapFromRow(int rowBitmap, int axis)
320
    {
321
    int bitmap, initBitmap=0;
322

    
323
    while( initBitmap!=rowBitmap )
324
      {
325
      initBitmap = rowBitmap;
326

    
327
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
328
        {
329
        bitmap = CUBITS[cubit].mRotationRow[axis];
330
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
331
        }
332
      }
333

    
334
    return rowBitmap;
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

    
339
  float returnMultiplier()
340
    {
341
    return getNumLayers();
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  float[] getRowChances(int numLayers)
347
    {
348
    float[] chances = new float[numLayers];
349

    
350
    for(int i=0; i<numLayers; i++)
351
      {
352
      chances[i] = (i+1.0f) / numLayers;
353
      }
354

    
355
    return chances;
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359
// PUBLIC API
360

    
361
  public Static3D[] getRotationAxis()
362
    {
363
    return ROT_AXIS;
364
    }
365

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

    
368
  public int getBasicAngle()
369
    {
370
    return 4;
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374
// TODO
375

    
376
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
377
    {
378
    int numAxis = ROTATION_AXIS.length;
379

    
380
    if( oldRotAxis == START_AXIS )
381
      {
382
      return rnd.nextInt(numAxis);
383
      }
384
    else
385
      {
386
      int newVector = rnd.nextInt(numAxis-1);
387
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
388
      }
389
    }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392
// TODO
393

    
394
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
395
    {
396
    float rowFloat = rnd.nextFloat();
397

    
398
    for(int row=0; row<mRowChances.length; row++)
399
      {
400
      if( rowFloat<=mRowChances[row] ) return row;
401
      }
402

    
403
    return 0;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407
// TODO
408

    
409
  public boolean isSolved()
410
    {
411
    int index = CUBITS[0].mQuatIndex;
412

    
413
    for(int i=1; i<NUM_CUBITS; i++)
414
      {
415
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
416
      }
417

    
418
    return true;
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
// only needed for solvers - there are no Bandaged solvers ATM)
423

    
424
  public String retObjectString()
425
    {
426
    return "";
427
    }
428
}
(18-18/35)