Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 749ef882

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.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

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

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

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

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

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

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

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

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

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

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

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

    
131
  private static MeshBase[] mMeshes;
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

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

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  abstract float[][] getPositions();
144
  abstract int[] getQuatIndices();
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  int getCubitVariant(int cubit)
149
    {
150
    float[][] pos = getPositions();
151

    
152
    if( cubit>=0 && cubit< pos.length )
153
      {
154
      int numPoints = pos[cubit].length/3;
155
      return numPoints==8 ? 4 : numPoints-1;
156
      }
157

    
158
    return 1;
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  int getNumCubits()
164
    {
165
    return getPositions().length;
166
    }
167

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

    
170
  float[] getCubitPosition(int cubit)
171
    {
172
    float[][] pos = getPositions();
173

    
174
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  private int getQuatIndex(int cubit)
180
    {
181
    int[] indices = getQuatIndices();
182

    
183
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
184
    }
185

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

    
188
  MeshBase createCubitMesh(int cubit, int numLayers)
189
    {
190
    if( mMeshes==null )
191
      {
192
      int LEN = mDimensions.length;
193
      mMeshes = new MeshBase[LEN];
194

    
195
      for(int i=0; i<LEN; i++)
196
        {
197
        mMeshes[i] = FactoryCubit.getInstance().createCuboidMesh(mDimensions[i]);
198
        }
199
      }
200

    
201
    int variant = getCubitVariant(cubit);
202
    MeshBase mesh = mMeshes[variant].copy(true);
203
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
204
    mesh.apply(quat,0xffffffff,0);
205

    
206
    return mesh;
207
    }
208

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

    
211
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
212
    {
213
    int numFaces = FACE_COLORS.length;
214
    int stickerType = face/numFaces;
215
    int color = face%numFaces;
216
    float X = mStickerDimensions[stickerType][0];
217
    float Y = mStickerDimensions[stickerType][1];
218
    float MAX = Math.max(X,Y);
219
    float R = 0.10f / MAX;
220
    float S = 0.08f / MAX;
221
    X /= (2*MAX);
222
    Y /= (2*MAX);
223

    
224
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
225

    
226
    FactorySticker factory = FactorySticker.getInstance();
227
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[color], R);
228
    }
229

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

    
232
  float[][] getCubitPositions(int size)
233
    {
234
    int numCubits = getNumCubits();
235
    float[][] tmp = new float[numCubits][];
236

    
237
    for(int cubit=0; cubit<numCubits; cubit++)
238
      {
239
      tmp[cubit] = getCubitPosition(cubit);
240
      }
241

    
242
    return tmp;
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  Static4D[] getQuats()
248
    {
249
    return QUATS;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  boolean shouldResetTextureMaps()
255
    {
256
    return false;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  int getNumFaces()
262
    {
263
    return FACE_COLORS.length;
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

    
268
  float[] getCuts(int numLayers)
269
    {
270
    float[] cuts = new float[numLayers-1];
271

    
272
    for(int i=0; i<numLayers-1; i++)
273
      {
274
      cuts[i] = (2-numLayers)*0.5f + i;
275
      }
276

    
277
    return cuts;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  int getNumStickerTypes(int numLayers)
283
    {
284
    return NUM_STICKERS;
285
    }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
  int getNumCubitFaces()
290
    {
291
    return FACE_COLORS.length;
292
    }
293

    
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

    
296
  float getScreenRatio()
297
    {
298
    return 0.5f;
299
    }
300

    
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

    
303
  private int retStickerIndex(int horzSize, int vertSize)
304
    {
305
    switch(horzSize)
306
      {
307
      case 1: return 0;
308
      case 2: return vertSize==1 ? 1:3;
309
      case 3: return 2;
310
      }
311

    
312
    return 0;
313
    }
314

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

    
317
  private int getStickerIndex(int cubitface, int[] dim)
318
    {
319
    switch(cubitface)
320
      {
321
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
322
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
323
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
324
      }
325

    
326
    return 0;
327
    }
328

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

    
331
  int getFaceColor(int cubit, int cubitface, int numLayers)
332
    {
333
    int variant      = getCubitVariant(cubit);
334
    int[] dim        = mDimensions[variant];
335
    float[] pos      = getCubitPosition(cubit);
336
    int stickerIndex = getStickerIndex(cubitface,dim);
337
    int quatIndex    = getQuatIndex(cubit);
338
    int face         = mFaceMap[cubitface][quatIndex];
339
    int multiplier   = (face%2)==0 ? 1:-1;
340
    int posIndex     = face/2;
341
    int dimIndex     = mAxisMap[posIndex][quatIndex];
342

    
343
    float position = 0.0f;
344
    int len = pos.length/3;
345
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
346
    position /= len;
347

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

    
350
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  int computeBitmapFromRow(int rowBitmap, int axis)
356
    {
357
    int bitmap, initBitmap=0;
358

    
359
    while( initBitmap!=rowBitmap )
360
      {
361
      initBitmap = rowBitmap;
362

    
363
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
364
        {
365
        bitmap = CUBITS[cubit].mRotationRow[axis];
366
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
367
        }
368
      }
369

    
370
    return rowBitmap;
371
    }
372

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

    
375
  float returnMultiplier()
376
    {
377
    return getNumLayers();
378
    }
379

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

    
382
  float[] getRowChances(int numLayers)
383
    {
384
    float[] chances = new float[numLayers];
385

    
386
    for(int i=0; i<numLayers; i++)
387
      {
388
      chances[i] = (i+1.0f) / numLayers;
389
      }
390

    
391
    return chances;
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395
// PUBLIC API
396

    
397
  public Static3D[] getRotationAxis()
398
    {
399
    return ROT_AXIS;
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  public int getBasicAngle()
405
    {
406
    return 4;
407
    }
408

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

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

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

    
420
    return true;
421
    }
422

    
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424
// only needed for solvers - there are no Bandaged solvers ATM)
425

    
426
  public String retObjectString()
427
    {
428
    return "";
429
    }
430
}
(16-16/33)