Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 92ec91b9

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
  float returnMultiplier()
320
    {
321
    return getNumLayers();
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  float[] getRowChances(int numLayers)
327
    {
328
    float[] chances = new float[numLayers];
329

    
330
    for(int i=0; i<numLayers; i++)
331
      {
332
      chances[i] = (i+1.0f) / numLayers;
333
      }
334

    
335
    return chances;
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339
// PUBLIC API
340

    
341
  public Static3D[] getRotationAxis()
342
    {
343
    return ROT_AXIS;
344
    }
345

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

    
348
  public int getBasicAngle()
349
    {
350
    return 4;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354
// TODO
355

    
356
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
357
    {
358
    int numAxis = ROTATION_AXIS.length;
359

    
360
    if( oldRotAxis == START_AXIS )
361
      {
362
      return rnd.nextInt(numAxis);
363
      }
364
    else
365
      {
366
      int newVector = rnd.nextInt(numAxis-1);
367
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
368
      }
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
// TODO
373

    
374
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
375
    {
376
    float rowFloat = rnd.nextFloat();
377

    
378
    for(int row=0; row<mRowChances.length; row++)
379
      {
380
      if( rowFloat<=mRowChances[row] ) return row;
381
      }
382

    
383
    return 0;
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
// TODO
388

    
389
  public boolean isSolved()
390
    {
391
    int index = CUBITS[0].mQuatIndex;
392

    
393
    for(int i=1; i<NUM_CUBITS; i++)
394
      {
395
      if( thereIsVisibleDifference(CUBITS[i], index) ) return false;
396
      }
397

    
398
    return true;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402
// only needed for solvers - there are no Bandaged solvers ATM)
403

    
404
  public String retObjectString()
405
    {
406
    return "";
407
    }
408
}
(18-18/35)