Project

General

Profile

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

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

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 size, Static4D quat, Static3D move, DistortedTexture texture,
84
                         MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
85
    {
86
    super(size, size, 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 size)
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
    if( numLayers<2 ) return null;
337

    
338
    if( mCuts==null )
339
      {
340
      mCuts = new float[3][numLayers-1];
341

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

    
351
    return mCuts;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  private void getLayerRotatable(int numLayers)
357
    {
358
    if( mLayerRotatable==null )
359
      {
360
      int numAxis = ROT_AXIS.length;
361
      boolean[] tmp = new boolean[numLayers];
362
      for(int i=0; i<numLayers; i++) tmp[i] = true;
363
      mLayerRotatable = new boolean[numAxis][];
364
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
365
      }
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  protected int getSolvedFunctionIndex()
371
    {
372
    return 0;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  protected int getNumStickerTypes(int numLayers)
378
    {
379
    return NUM_STICKERS;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  protected int getNumCubitFaces()
385
    {
386
    return 6;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  private int retStickerIndex(int horzSize, int vertSize)
392
    {
393
    switch(horzSize)
394
      {
395
      case 1: return 0;
396
      case 2: return vertSize==1 ? 1:3;
397
      case 3: return 2;
398
      }
399

    
400
    return 0;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  private int getStickerIndex(int cubitface, int[] dim)
406
    {
407
    switch(cubitface)
408
      {
409
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
410
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
411
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
412
      }
413

    
414
    return 0;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

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

    
435
    if( mAxisMap==null )
436
      {
437
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
438
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
439
      }
440

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

    
451
    float position = 0.0f;
452
    int len = pos.length/3;
453
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
454
    position /= len;
455

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

    
458
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462
// PUBLIC API
463

    
464
  public Static3D[] getRotationAxis()
465
    {
466
    return ROT_AXIS;
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  public Movement getMovement()
472
    {
473
    if( mMovement==null )
474
      {
475
      int numLayers = getNumLayers();
476
      if( mCuts==null ) getCuts(numLayers);
477
      getLayerRotatable(numLayers);
478
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
479
      }
480
    return mMovement;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public int[] getBasicAngle()
486
    {
487
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
488
    return mBasicAngle;
489
    }
490
}
(3-3/25)