Project

General

Profile

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

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

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.helpers.ObjectShape;
35
import org.distorted.objectlib.helpers.ObjectSticker;
36
import org.distorted.objectlib.helpers.ScrambleState;
37
import org.distorted.objectlib.main.ObjectControl;
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[] numL, Static4D quat, Static3D move, DistortedTexture texture,
84
                         MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
85
    {
86
    super(numL, numL[0], quat, move, texture, mesh, effects, 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 radius = 0.10f / MAX;
293
        float stroke = 0.08f / MAX;
294
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
295
        float[] radii = new float[] {radius,radius,radius,radius};
296

    
297
        if( ObjectControl.isInIconMode() )
298
          {
299
          stroke*=2.0f;
300
          }
301

    
302
        mStickers[s] = new ObjectSticker(coords,null,radii,stroke);
303
        }
304
      }
305

    
306
    return mStickers[face/NUM_FACE_COLORS];
307
    }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
  protected float[][] getCubitPositions(int[] numLayers)
312
    {
313
    int numCubits = getNumCubits();
314
    float[][] tmp = new float[numCubits][];
315

    
316
    for(int cubit=0; cubit<numCubits; cubit++)
317
      {
318
      tmp[cubit] = getCubitPosition(cubit);
319
      }
320

    
321
    return tmp;
322
    }
323

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

    
326
  protected Static4D[] getQuats()
327
    {
328
    if( mQuats==null ) initializeQuats();
329
    return mQuats;
330
    }
331

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

    
334
  protected float[][] getCuts(int[] numLayers)
335
    {
336
    int numL = numLayers[0];
337

    
338
    if( numL<2 ) return null;
339

    
340
    if( mCuts==null )
341
      {
342
      mCuts = new float[3][numL-1];
343

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

    
353
    return mCuts;
354
    }
355

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

    
358
  private void getLayerRotatable(int[] numLayers)
359
    {
360
    if( mLayerRotatable==null )
361
      {
362
      int numAxis = ROT_AXIS.length;
363
      mLayerRotatable = new boolean[numAxis][];
364

    
365
      for(int i=0; i<numAxis; i++)
366
        {
367
        mLayerRotatable[i] = new boolean[numLayers[i]];
368
        for(int j=0; j<numLayers[i]; j++) mLayerRotatable[i][j] = true;
369
        }
370
      }
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  protected int getSolvedFunctionIndex()
376
    {
377
    return 0;
378
    }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

    
382
  protected int getNumStickerTypes(int[] numLayers)
383
    {
384
    return NUM_STICKERS;
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  protected int getNumCubitFaces()
390
    {
391
    return 6;
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

    
396
  private int retStickerIndex(int horzSize, int vertSize)
397
    {
398
    switch(horzSize)
399
      {
400
      case 1: return 0;
401
      case 2: return vertSize==1 ? 1:3;
402
      case 3: return 2;
403
      }
404

    
405
    return 0;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  private int getStickerIndex(int cubitface, int[] dim)
411
    {
412
    switch(cubitface)
413
      {
414
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
415
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
416
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
417
      }
418

    
419
    return 0;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
425
    {
426
    if( mFaceMap==null )
427
      {
428
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
429
      mFaceMap = new int[][]
430
          {
431
              {0,0,5,2,4,2},
432
              {1,1,4,3,5,3},
433
              {2,4,2,1,1,4},
434
              {3,5,3,0,0,5},
435
              {4,3,0,4,3,0},
436
              {5,2,1,5,2,1}
437
          };
438
      }
439

    
440
    if( mAxisMap==null )
441
      {
442
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
443
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
444
      }
445

    
446
    int variant      = getCubitVariant(cubit,numLayers);
447
    int[] dim        = mDimensions[variant];
448
    float[] pos      = getCubitPosition(cubit);
449
    int stickerIndex = getStickerIndex(cubitface,dim);
450
    int quatIndex    = getQuatIndex(cubit);
451
    int face         = mFaceMap[cubitface][quatIndex];
452
    int multiplier   = (face%2)==0 ? 1:-1;
453
    int posIndex     = face/2;
454
    int dimIndex     = mAxisMap[posIndex][quatIndex];
455

    
456
    float position = 0.0f;
457
    int len = pos.length/3;
458
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
459
    position /= len;
460

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

    
463
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
// PUBLIC API
468

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

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public Movement getMovement()
477
    {
478
    if( mMovement==null )
479
      {
480
      int[] numLayers = getNumLayers();
481
      if( mCuts==null ) getCuts(numLayers);
482
      getLayerRotatable(numLayers);
483
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers[0],TYPE_NOT_SPLIT,ENABLED);
484
      }
485
    return mMovement;
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public int[] getBasicAngle()
491
    {
492
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
493
    return mBasicAngle;
494
    }
495
}
(3-3/25)