Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ 169219a7

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

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

    
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

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

    
44
  private static final int[] BASIC_ANGLE = new int[] { 4,4,4 };
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 final ObjectSticker[] mStickers;
130

    
131
  static
132
    {
133
    mStickers = new ObjectSticker[NUM_STICKERS];
134

    
135
    for(int s=0; s<NUM_STICKERS; s++)
136
      {
137
      float X = mStickerDimensions[s][0];
138
      float Y = mStickerDimensions[s][1];
139
      float MAX = Math.max(X,Y);
140
      X /= (2*MAX);
141
      Y /= (2*MAX);
142

    
143
      float R = 0.10f / MAX;
144
      float S = 0.08f / MAX;
145
      float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
146
      float[] radii = new float[] {R,R,R,R};
147
      mStickers[s] = new ObjectSticker(coords,null,radii,S);
148
      }
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
154
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
155
    {
156
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  abstract float[][] getPositions();
162
  abstract int[] getQuatIndices();
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  int[] getSolvedQuats(int cubit, int numLayers)
167
    {
168
    int status = retCubitSolvedStatus(cubit,numLayers);
169
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],QUATS);
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  int getNumCubits()
175
    {
176
    return getPositions().length;
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  private float[] getCubitPosition(int cubit)
182
    {
183
    float[][] pos = getPositions();
184

    
185
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  private int getQuatIndex(int cubit)
191
    {
192
    int[] indices = getQuatIndices();
193
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
  ObjectShape getObjectShape(int cubit, int numLayers)
199
    {
200
    int variant = getCubitVariant(cubit,numLayers);
201

    
202
    final int[][] vert_indices =
203
      {
204
        {2,3,1,0},
205
        {7,6,4,5},
206
        {4,0,1,5},
207
        {7,3,2,6},
208
        {6,2,0,4},
209
        {3,7,5,1},
210
      };
211

    
212
    float defHeight = 0.048f;
213
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
214
    float[][] corners = new float[][] { {0.04f,0.15f} };
215
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
216
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
217

    
218
    int X = mDimensions[variant][0];
219
    int Y = mDimensions[variant][1];
220
    int Z = mDimensions[variant][2];
221

    
222
    int maxXY = Math.max(X,Y);
223
    int maxXZ = Math.max(X,Z);
224
    int maxYZ = Math.max(Y,Z);
225

    
226
    double[][] vertices =
227
      {
228
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
229
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
230
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
231
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
232
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
233
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
234
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
235
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
236
      };
237

    
238
    float[][] bands= new float[][]
239
      {
240
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
241
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
242
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
243
      };
244

    
245
    float[][] centers = new float[][]
246
      {
247
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
248
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
249
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
250
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
251
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
252
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
253
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
254
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
255
      };
256

    
257
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  Static4D getQuat(int cubit, int numLayers)
263
    {
264
    return INIT_QUATS[getQuatIndex(cubit)];
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  int getNumCubitVariants(int numLayers)
270
    {
271
    return mDimensions.length;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  int getCubitVariant(int cubit, int numLayers)
277
    {
278
    float[][] pos = getPositions();
279

    
280
    if( cubit>=0 && cubit<pos.length )
281
      {
282
      int numPoints = pos[cubit].length/3;
283
      return numPoints==8 ? 4 : numPoints-1;
284
      }
285

    
286
    return 1;
287
    }
288

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

    
291
  int getColor(int face)
292
    {
293
    return FACE_COLORS[face];
294
    }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
  ObjectSticker retSticker(int face)
299
    {
300
    return mStickers[face/NUM_FACES];
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  float[][] getCubitPositions(int size)
306
    {
307
    int numCubits = getNumCubits();
308
    float[][] tmp = new float[numCubits][];
309

    
310
    for(int cubit=0; cubit<numCubits; cubit++)
311
      {
312
      tmp[cubit] = getCubitPosition(cubit);
313
      }
314

    
315
    return tmp;
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  Static4D[] getQuats()
321
    {
322
    return QUATS;
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  boolean shouldResetTextureMaps()
328
    {
329
    return false;
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  int getNumFaces()
335
    {
336
    return FACE_COLORS.length;
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  float[][] getCuts(int numLayers)
342
    {
343
    float[][] cuts = new float[3][numLayers-1];
344

    
345
    for(int i=0; i<numLayers-1; i++)
346
      {
347
      float cut = (2-numLayers)*0.5f + i;
348
      cuts[0][i] = cut;
349
      cuts[1][i] = cut;
350
      cuts[2][i] = cut;
351
      }
352

    
353
    return cuts;
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  int getSolvedFunctionIndex()
359
    {
360
    return 0;
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  int getNumStickerTypes(int numLayers)
366
    {
367
    return NUM_STICKERS;
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  int getNumCubitFaces()
373
    {
374
    return FACE_COLORS.length;
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  float getScreenRatio()
380
    {
381
    return 0.5f;
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  private int retStickerIndex(int horzSize, int vertSize)
387
    {
388
    switch(horzSize)
389
      {
390
      case 1: return 0;
391
      case 2: return vertSize==1 ? 1:3;
392
      case 3: return 2;
393
      }
394

    
395
    return 0;
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

    
400
  private int getStickerIndex(int cubitface, int[] dim)
401
    {
402
    switch(cubitface)
403
      {
404
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
405
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
406
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
407
      }
408

    
409
    return 0;
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  int getFaceColor(int cubit, int cubitface, int numLayers)
415
    {
416
    int variant      = getCubitVariant(cubit,numLayers);
417
    int[] dim        = mDimensions[variant];
418
    float[] pos      = getCubitPosition(cubit);
419
    int stickerIndex = getStickerIndex(cubitface,dim);
420
    int quatIndex    = getQuatIndex(cubit);
421
    int face         = mFaceMap[cubitface][quatIndex];
422
    int multiplier   = (face%2)==0 ? 1:-1;
423
    int posIndex     = face/2;
424
    int dimIndex     = mAxisMap[posIndex][quatIndex];
425

    
426
    float position = 0.0f;
427
    int len = pos.length/3;
428
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
429
    position /= len;
430

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

    
433
    return reaches ? stickerIndex*NUM_FACES + face : NUM_STICKERS*NUM_FACES;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437
// this implements the fact that certain cubits have multiple 'centers' and this means the cubit
438
// might span more than one layer along a given axis - i.e. that this is a bandaged puzzle.
439

    
440
  int computeBitmapFromRow(int rowBitmap, int axis)
441
    {
442
    int bitmap, initBitmap=0;
443

    
444
    while( initBitmap!=rowBitmap )
445
      {
446
      initBitmap = rowBitmap;
447

    
448
      for(int cubit=0; cubit<NUM_CUBITS; cubit++)
449
        {
450
        bitmap = CUBITS[cubit].mRotationRow[axis];
451
        if( (rowBitmap & bitmap) != 0 ) rowBitmap |= bitmap;
452
        }
453
      }
454

    
455
    return rowBitmap;
456
    }
457

    
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459

    
460
  float returnMultiplier()
461
    {
462
    return getNumLayers();
463
    }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466
// PUBLIC API
467

    
468
  public Static3D[] getRotationAxis()
469
    {
470
    return ROT_AXIS;
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public int[] getBasicAngle()
476
    {
477
    return BASIC_ANGLE;
478
    }
479
}
(19-19/41)