Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 221a4090

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
  Static3D[] getCubitPositions(int size)
197
    {
198
    int numCubits = getNumCubits();
199
    Static3D[] tmp = new Static3D[numCubits];
200

    
201
    for(int cubit=0; cubit<numCubits; cubit++)
202
      {
203
      float[] pos = getCubitPosition(cubit);
204
      tmp[cubit] = new Static3D(pos[0],pos[1],pos[2]);
205
      }
206

    
207
    return tmp;
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

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

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

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

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

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

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

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

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

    
242
    return cuts;
243
    }
244

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

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

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

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

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

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

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

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

    
277
    return 0;
278
    }
279

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

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

    
291
    return 0;
292
    }
293

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

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

    
309
    int ret=  reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
310

    
311
if( cubit==0 )
312
  {
313
android.util.Log.e("DISTORTED", "cubit="+cubit+" cubitface="+cubitface+" ret="+ret+" stickerIndex="+stickerIndex+" face="+face);
314
android.util.Log.e("DISTORTED", "reaches="+reaches+" border="+((numLayers-1)*0.5f)+" left="+(multiplier*pos[posIndex] + dim[dimIndex]*0.5f));
315
android.util.Log.e("DISTORTED", "posIndex="+posIndex+" dimIndex="+dimIndex);
316

    
317
  }
318
    return ret;
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  float returnMultiplier()
324
    {
325
    return getNumLayers();
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  float[] getRowChances(int numLayers)
331
    {
332
    float[] chances = new float[numLayers];
333

    
334
    for(int i=0; i<numLayers; i++)
335
      {
336
      chances[i] = (i+1.0f) / numLayers;
337
      }
338

    
339
    return chances;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
// PUBLIC API
344

    
345
  public Static3D[] getRotationAxis()
346
    {
347
    return ROT_AXIS;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  public int getBasicAngle()
353
    {
354
    return 4;
355
    }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358
// TODO
359

    
360
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
361
    {
362
    int numAxis = ROTATION_AXIS.length;
363

    
364
    if( oldRotAxis == START_AXIS )
365
      {
366
      return rnd.nextInt(numAxis);
367
      }
368
    else
369
      {
370
      int newVector = rnd.nextInt(numAxis-1);
371
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
372
      }
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
// TODO
377

    
378
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
379
    {
380
    float rowFloat = rnd.nextFloat();
381

    
382
    for(int row=0; row<mRowChances.length; row++)
383
      {
384
      if( rowFloat<=mRowChances[row] ) return row;
385
      }
386

    
387
    return 0;
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
// TODO
392

    
393
  public boolean isSolved()
394
    {
395
    int index = CUBITS[0].mQuatIndex;
396

    
397
    for(int i=1; i<NUM_CUBITS; i++)
398
      {
399
      if( !thereIsNoVisibleDifference(CUBITS[i], index) ) return false;
400
      }
401

    
402
    return true;
403
    }
404

    
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406
// only needed for solvers - there are no Bandaged solvers ATM)
407

    
408
  public String retObjectString()
409
    {
410
    return "";
411
    }
412
}
(18-18/35)