Project

General

Profile

Download (15.6 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ cc448c54

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.objectlib.objects;
21

    
22
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
23

    
24
import android.content.res.Resources;
25

    
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
import org.distorted.objectlib.main.Movement;
33
import org.distorted.objectlib.main.Movement6;
34
import org.distorted.objectlib.main.ObjectList;
35
import org.distorted.objectlib.main.ObjectShape;
36
import org.distorted.objectlib.main.ObjectSticker;
37
import org.distorted.objectlib.main.ScrambleState;
38
import org.distorted.objectlib.main.Twisty6;
39

    
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

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

    
52
  private static final int[][] mDimensions = new int[][]
53
        {
54
         {1,1,1},  // has to be X>=Z>=Y so that all
55
         {2,1,1},  // the faces are horizontal
56
         {3,1,1},
57
         {2,1,2},
58
         {2,2,2}
59
        };
60

    
61
  private static final int[][][] ENABLED = new int[][][]
62
      {
63
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
64
      };
65

    
66
  private static final int NUM_STICKERS = 4;
67

    
68
  private int[] mBasicAngle;
69
  private Static4D[] mQuats;
70
  private ObjectSticker[] mStickers;
71
  private Static4D[] mInitQuats;
72
  private int[][] mAxisMap;
73
  private int[][] mFaceMap;
74
  private float[][] mCuts;
75
  private boolean[][] mLayerRotatable;
76
  private Movement mMovement;
77
  ScrambleState[] mStates;
78
  float[][] POSITIONS;
79
  int[] QUAT_INDICES;
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
84
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
85
    {
86
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
87
    }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  abstract float[][] getPositions();
92
  abstract int[] getQuatIndices();
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  private void initializeQuats()
97
    {
98
    mQuats = new Static4D[]
99
         {
100
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
101
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
102
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
103
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
104

    
105
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
106
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
107
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
108
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
109
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
110
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
111
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
112
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
113
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
114
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
115
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
116
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
117

    
118
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
119
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
120
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
121
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
122
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
123
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
124
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
125
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
126
         };
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  protected int[] getSolvedQuats(int cubit, int numLayers)
132
    {
133
    if( mQuats==null ) initializeQuats();
134
    int status = retCubitSolvedStatus(cubit,numLayers);
135
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  int getNumCubits()
141
    {
142
    return getPositions().length;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  private float[] getCubitPosition(int cubit)
148
    {
149
    float[][] pos = getPositions();
150

    
151
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  private int getQuatIndex(int cubit)
157
    {
158
    int[] indices = getQuatIndices();
159
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  protected ObjectShape getObjectShape(int cubit, int numLayers)
165
    {
166
    int variant = getCubitVariant(cubit,numLayers);
167

    
168
    final int[][] vert_indices =
169
      {
170
        {2,3,1,0},
171
        {7,6,4,5},
172
        {4,0,1,5},
173
        {7,3,2,6},
174
        {6,2,0,4},
175
        {3,7,5,1},
176
      };
177

    
178
    float defHeight = 0.048f;
179
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
180
    float[][] corners = new float[][] { {0.04f,0.15f} };
181
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
182
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
183

    
184
    int X = mDimensions[variant][0];
185
    int Y = mDimensions[variant][1];
186
    int Z = mDimensions[variant][2];
187

    
188
    int maxXY = Math.max(X,Y);
189
    int maxXZ = Math.max(X,Z);
190
    int maxYZ = Math.max(Y,Z);
191

    
192
    double[][] vertices =
193
      {
194
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
195
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
196
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
197
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
198
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
199
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
200
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
201
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
202
      };
203

    
204
    float[][] bands= new float[][]
205
      {
206
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
207
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
208
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
209
      };
210

    
211
    float[][] centers = new float[][]
212
      {
213
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
214
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
215
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
216
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
217
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
218
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
219
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
220
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
221
      };
222

    
223
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
224
    }
225

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

    
228
  protected Static4D getQuat(int cubit, int numLayers)
229
    {
230
    if( mInitQuats ==null )
231
      {
232
      mInitQuats = new Static4D[]
233
        {
234
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
235
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
236
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
237
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
238
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
239
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
240
        };
241
      }
242

    
243
    return mInitQuats[getQuatIndex(cubit)];
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  protected int getNumCubitVariants(int numLayers)
249
    {
250
    return mDimensions.length;
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
  protected int getCubitVariant(int cubit, int numLayers)
256
    {
257
    float[][] pos = getPositions();
258

    
259
    if( cubit>=0 && cubit<pos.length )
260
      {
261
      int numPoints = pos[cubit].length/3;
262
      return numPoints==8 ? 4 : numPoints-1;
263
      }
264

    
265
    return 1;
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  protected ObjectSticker retSticker(int face)
271
    {
272
    if( mStickers==null )
273
      {
274
      mStickers = new ObjectSticker[NUM_STICKERS];
275

    
276
      int[][] stickerDimensions = new int[][]
277
        {
278
         {1,1},  // dimensions of the faces of
279
         {2,1},  // the cuboids defined in mDimensions
280
         {3,1},
281
         {2,2}
282
        };
283

    
284
      for(int s=0; s<NUM_STICKERS; s++)
285
        {
286
        float X = stickerDimensions[s][0];
287
        float Y = stickerDimensions[s][1];
288
        float MAX = Math.max(X,Y);
289
        X /= (2*MAX);
290
        Y /= (2*MAX);
291

    
292
        float R = 0.10f / MAX;
293
        float S = 0.08f / MAX;
294
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
295
        float[] radii = new float[] {R,R,R,R};
296
        mStickers[s] = new ObjectSticker(coords,null,radii,S);
297
        }
298
      }
299

    
300
    return mStickers[face/NUM_FACE_COLORS];
301
    }
302

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

    
305
  protected 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
  protected Static4D[] getQuats()
321
    {
322
    if( mQuats==null ) initializeQuats();
323
    return mQuats;
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
  protected float[][] getCuts(int numLayers)
329
    {
330
    if( numLayers<2 ) return null;
331

    
332
    if( mCuts==null )
333
      {
334
      mCuts = new float[3][numLayers-1];
335

    
336
      for(int i=0; i<numLayers-1; i++)
337
        {
338
        float cut = (2-numLayers)*0.5f + i;
339
        mCuts[0][i] = cut;
340
        mCuts[1][i] = cut;
341
        mCuts[2][i] = cut;
342
        }
343
      }
344

    
345
    return mCuts;
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
  private void getLayerRotatable(int numLayers)
351
    {
352
    if( mLayerRotatable==null )
353
      {
354
      int numAxis = ROT_AXIS.length;
355
      boolean[] tmp = new boolean[numLayers];
356
      for(int i=0; i<numLayers; i++) tmp[i] = true;
357
      mLayerRotatable = new boolean[numAxis][];
358
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
359
      }
360
    }
361

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

    
364
  protected int getSolvedFunctionIndex()
365
    {
366
    return 0;
367
    }
368

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

    
371
  protected int getNumStickerTypes(int numLayers)
372
    {
373
    return NUM_STICKERS;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  protected int getNumCubitFaces()
379
    {
380
    return 6;
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

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

    
394
    return 0;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

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

    
408
    return 0;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
414
    {
415
    if( mFaceMap==null )
416
      {
417
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
418
      mFaceMap = new int[][]
419
          {
420
              {0,0,5,2,4,2},
421
              {1,1,4,3,5,3},
422
              {2,4,2,1,1,4},
423
              {3,5,3,0,0,5},
424
              {4,3,0,4,3,0},
425
              {5,2,1,5,2,1}
426
          };
427
      }
428

    
429
    if( mAxisMap==null )
430
      {
431
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
432
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
433
      }
434

    
435
    int variant      = getCubitVariant(cubit,numLayers);
436
    int[] dim        = mDimensions[variant];
437
    float[] pos      = getCubitPosition(cubit);
438
    int stickerIndex = getStickerIndex(cubitface,dim);
439
    int quatIndex    = getQuatIndex(cubit);
440
    int face         = mFaceMap[cubitface][quatIndex];
441
    int multiplier   = (face%2)==0 ? 1:-1;
442
    int posIndex     = face/2;
443
    int dimIndex     = mAxisMap[posIndex][quatIndex];
444

    
445
    float position = 0.0f;
446
    int len = pos.length/3;
447
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
448
    position /= len;
449

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

    
452
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456
// PUBLIC API
457

    
458
  public Static3D[] getRotationAxis()
459
    {
460
    return ROT_AXIS;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public Movement getMovement()
466
    {
467
    if( mMovement==null )
468
      {
469
      int numLayers = getNumLayers();
470
      if( mCuts==null ) getCuts(numLayers);
471
      getLayerRotatable(numLayers);
472
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
473
      }
474
    return mMovement;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
  public int[] getBasicAngle()
480
    {
481
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
482
    return mBasicAngle;
483
    }
484
}
(3-3/25)