Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 51a07bb4

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
///////////////////////////////////////////////////////////////////////////////////////////////////
35

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

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

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

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

    
73
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
74
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
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
         };
82

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

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

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

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

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

    
127
  private static final int NUM_STICKERS = mStickerDimensions.length;
128

    
129
  private static MeshBase[] mMeshes;
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

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

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  abstract int getCubitVariant(int cubit);
142
  abstract int getNumCubits();
143
  abstract int getQuatIndex(int cubit);
144
  abstract float[] getCubitPosition(int cubit);
145

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

    
148
  MeshBase createCubitMesh(int cubit, int numLayers)
149
    {
150
    if( mMeshes==null )
151
      {
152
      int LEN = mDimensions.length;
153
      mMeshes = new MeshBase[LEN];
154

    
155
      for(int i=0; i<LEN; i++)
156
        {
157
        mMeshes[i] = FactoryCubit.getInstance().createCuboidMesh(mDimensions[i]);
158
        }
159
      }
160

    
161
    int variant = getCubitVariant(cubit);
162
    MeshBase mesh = mMeshes[variant].copy(true);
163
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( INIT_QUATS[getQuatIndex(cubit)], new Static3D(0,0,0) );
164
    mesh.apply(quat,0xffffffff,0);
165

    
166
    return mesh;
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

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

    
184
    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
185

    
186
    FactorySticker factory = FactorySticker.getInstance();
187
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[color], R);
188
    }
189

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

    
192
  float[][] getCubitPositions(int size)
193
    {
194
    int numCubits = getNumCubits();
195
    float[][] tmp = new float[numCubits][];
196

    
197
    for(int cubit=0; cubit<numCubits; cubit++)
198
      {
199
      tmp[cubit] = getCubitPosition(cubit);
200
      }
201

    
202
    return tmp;
203
    }
204

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

    
207
  Static4D[] getQuats()
208
    {
209
    return QUATS;
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  boolean shouldResetTextureMaps()
215
    {
216
    return false;
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  int getNumFaces()
222
    {
223
    return FACE_COLORS.length;
224
    }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
  float[] getCuts(int numLayers)
229
    {
230
    float[] cuts = new float[numLayers-1];
231

    
232
    for(int i=0; i<numLayers-1; i++)
233
      {
234
      cuts[i] = (2-numLayers)*0.5f + i;
235
      }
236

    
237
    return cuts;
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  int getNumStickerTypes(int numLayers)
243
    {
244
    return NUM_STICKERS;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  int getNumCubitFaces()
250
    {
251
    return FACE_COLORS.length;
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  float getScreenRatio()
257
    {
258
    return 0.5f;
259
    }
260

    
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

    
263
  private int retStickerIndex(int horzSize, int vertSize)
264
    {
265
    switch(horzSize)
266
      {
267
      case 1: return 0;
268
      case 2: return vertSize==1 ? 1:3;
269
      case 3: return 2;
270
      }
271

    
272
    return 0;
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  private int getStickerIndex(int cubitface, int[] dim)
278
    {
279
    switch(cubitface)
280
      {
281
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
282
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
283
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
284
      }
285

    
286
    return 0;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

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

    
303
    float position = 0.0f;
304
    int len = pos.length/3;
305
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
306
    position /= len;
307

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

    
310
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  int computeBitmapFromRow(int rowBitmap, int axis)
316
    {
317
    int bitmap, initBitmap=0;
318

    
319
    while( initBitmap!=rowBitmap )
320
      {
321
      initBitmap = rowBitmap;
322

    
323
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
324
        {
325
        bitmap = CUBITS[cubit].mRotationRow[axis];
326
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
327
        }
328
      }
329

    
330
    return rowBitmap;
331
    }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  float returnMultiplier()
336
    {
337
    return getNumLayers();
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  float[] getRowChances(int numLayers)
343
    {
344
    float[] chances = new float[numLayers];
345

    
346
    for(int i=0; i<numLayers; i++)
347
      {
348
      chances[i] = (i+1.0f) / numLayers;
349
      }
350

    
351
    return chances;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
// PUBLIC API
356

    
357
  public Static3D[] getRotationAxis()
358
    {
359
    return ROT_AXIS;
360
    }
361

    
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

    
364
  public int getBasicAngle()
365
    {
366
    return 4;
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public boolean isSolved()
372
    {
373
    int index = CUBITS[0].mQuatIndex;
374

    
375
    for(int i=1; i<NUM_CUBITS; i++)
376
      {
377
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
378
      }
379

    
380
    return true;
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384
// only needed for solvers - there are no Bandaged solvers ATM)
385

    
386
  public String retObjectString()
387
    {
388
    return "";
389
    }
390
}
(18-18/35)