Project

General

Profile

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

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

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.MOVEMENT_HEXAHEDRON;
23
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
24

    
25
import android.content.res.Resources;
26

    
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32

    
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 NUM_STICKERS = 4;
62

    
63
  private int[] mBasicAngle;
64
  private Static4D[] mQuats;
65
  private ObjectSticker[] mStickers;
66
  private Static4D[] mInitQuats;
67
  private int[][] mAxisMap;
68
  private int[][] mFaceMap;
69
  private float[][] mCuts;
70
  ScrambleState[] mStates;
71
  float[][] POSITIONS;
72
  int[] QUAT_INDICES;
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  TwistyBandagedAbstract(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
77
                         MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
78
    {
79
    super(numL, numL[0], quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
80
    }
81

    
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

    
84
  abstract float[][] getPositions();
85
  abstract int[] getQuatIndices();
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private void initializeQuats()
90
    {
91
    mQuats = new Static4D[]
92
         {
93
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
94
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
95
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
96
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
97

    
98
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
99
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
100
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
101
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
102
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
103
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
104
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
105
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
106
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
107
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
108
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
109
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
110

    
111
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
112
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
113
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
114
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
115
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
116
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
117
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
118
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
119
         };
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  public int[] getSolvedQuats(int cubit, int[] numLayers)
125
    {
126
    if( mQuats==null ) initializeQuats();
127
    int status = retCubitSolvedStatus(cubit,numLayers);
128
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  int getNumCubits()
134
    {
135
    return getPositions().length;
136
    }
137

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

    
140
  private float[] getCubitPosition(int cubit)
141
    {
142
    float[][] pos = getPositions();
143

    
144
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  private int getQuatIndex(int cubit)
150
    {
151
    int[] indices = getQuatIndices();
152
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  public ObjectShape getObjectShape(int variant)
158
    {
159
    final int[][] vert_indices =
160
      {
161
        {2,3,1,0},
162
        {7,6,4,5},
163
        {4,0,1,5},
164
        {7,3,2,6},
165
        {6,2,0,4},
166
        {3,7,5,1},
167
      };
168

    
169
    float defHeight = 0.048f;
170
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
171
    float[][] corners = new float[][] { {0.04f,0.15f} };
172
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
173
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
174

    
175
    int X = mDimensions[variant][0];
176
    int Y = mDimensions[variant][1];
177
    int Z = mDimensions[variant][2];
178

    
179
    int maxXY = Math.max(X,Y);
180
    int maxXZ = Math.max(X,Z);
181
    int maxYZ = Math.max(Y,Z);
182

    
183
    double[][] vertices =
184
      {
185
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
186
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
187
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
188
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
189
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
190
        {-0.5f*X,+0.5f*Y,-0.5f*Z},
191
        {-0.5f*X,-0.5f*Y,+0.5f*Z},
192
        {-0.5f*X,-0.5f*Y,-0.5f*Z}
193
      };
194

    
195
    float[][] bands= new float[][]
196
      {
197
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
198
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
199
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
200
      };
201

    
202
    float[][] centers = new float[][]
203
      {
204
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
205
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
206
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
207
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
208
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
209
        {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
210
        {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
211
        {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
212
      };
213

    
214
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
215
    }
216

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

    
219
  public Static4D getQuat(int cubit, int[] numLayers)
220
    {
221
    if( mInitQuats ==null )
222
      {
223
      mInitQuats = new Static4D[]
224
        {
225
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
226
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
227
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
228
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
229
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
230
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
231
        };
232
      }
233

    
234
    return mInitQuats[getQuatIndex(cubit)];
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  public int getNumCubitVariants(int[] numLayers)
240
    {
241
    return mDimensions.length;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public int getCubitVariant(int cubit, int[] numLayers)
247
    {
248
    float[][] pos = getPositions();
249

    
250
    if( cubit>=0 && cubit<pos.length )
251
      {
252
      int numPoints = pos[cubit].length/3;
253
      return numPoints==8 ? 4 : numPoints-1;
254
      }
255

    
256
    return 1;
257
    }
258

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

    
261
  public ObjectSticker retSticker(int sticker)
262
    {
263
    if( mStickers==null )
264
      {
265
      mStickers = new ObjectSticker[NUM_STICKERS];
266

    
267
      int[][] stickerDimensions = new int[][]
268
        {
269
         {1,1},  // dimensions of the faces of
270
         {2,1},  // the cuboids defined in mDimensions
271
         {3,1},
272
         {2,2}
273
        };
274

    
275
      for(int s=0; s<NUM_STICKERS; s++)
276
        {
277
        float X = stickerDimensions[s][0];
278
        float Y = stickerDimensions[s][1];
279
        float MAX = Math.max(X,Y);
280
        X /= (2*MAX);
281
        Y /= (2*MAX);
282

    
283
        float radius = 0.10f / MAX;
284
        float stroke = 0.08f / MAX;
285
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
286
        float[] radii = new float[] {radius,radius,radius,radius};
287

    
288
        if( ObjectControl.isInIconMode() )
289
          {
290
          stroke*=2.0f;
291
          }
292

    
293
        mStickers[s] = new ObjectSticker(coords,null,radii,stroke);
294
        }
295
      }
296

    
297
    return mStickers[sticker];
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  public float[][] getCubitPositions(int[] numLayers)
303
    {
304
    int numCubits = getNumCubits();
305
    float[][] tmp = new float[numCubits][];
306

    
307
    for(int cubit=0; cubit<numCubits; cubit++)
308
      {
309
      tmp[cubit] = getCubitPosition(cubit);
310
      }
311

    
312
    return tmp;
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

    
317
  public Static4D[] getQuats()
318
    {
319
    if( mQuats==null ) initializeQuats();
320
    return mQuats;
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  public float[][] getCuts(int[] numLayers)
326
    {
327
    int numL = numLayers[0];
328

    
329
    if( numL<2 ) return null;
330

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

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

    
344
    return mCuts;
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  public boolean[][] getLayerRotatable(int[] numLayers)
350
    {
351
    int numAxis = ROT_AXIS.length;
352
    boolean[][] layerRotatable = new boolean[numAxis][];
353

    
354
    for(int i=0; i<numAxis; i++)
355
      {
356
      layerRotatable[i] = new boolean[numLayers[i]];
357
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
358
      }
359

    
360
    return layerRotatable;
361
    }
362

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

    
365
  public int getMovementType()
366
    {
367
    return MOVEMENT_HEXAHEDRON;
368
    }
369

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

    
372
  public int getMovementSplit()
373
    {
374
    return TYPE_NOT_SPLIT;
375
    }
376

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

    
379
  public int[][][] getEnabled()
380
    {
381
    return new int[][][]
382
      {
383
          {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}},
384
      };
385
    }
386

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

    
389
  public float[] getDist3D(int[] numLayers)
390
    {
391
    return null;
392
    }
393

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

    
396
  public int getSolvedFunctionIndex()
397
    {
398
    return 0;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  public int getNumStickerTypes(int[] numLayers)
404
    {
405
    return NUM_STICKERS;
406
    }
407

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

    
410
  protected int getNumCubitFaces()
411
    {
412
    return 6;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  private int retStickerIndex(int horzSize, int vertSize)
418
    {
419
    switch(horzSize)
420
      {
421
      case 1: return 0;
422
      case 2: return vertSize==1 ? 1:3;
423
      case 3: return 2;
424
      }
425

    
426
    return 0;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  private int getStickerIndex(int cubitface, int[] dim)
432
    {
433
    switch(cubitface)
434
      {
435
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
436
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
437
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
438
      }
439

    
440
    return 0;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
446
    {
447
    if( mFaceMap==null )
448
      {
449
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
450
      mFaceMap = new int[][]
451
          {
452
              {0,0,5,2,4,2},
453
              {1,1,4,3,5,3},
454
              {2,4,2,1,1,4},
455
              {3,5,3,0,0,5},
456
              {4,3,0,4,3,0},
457
              {5,2,1,5,2,1}
458
          };
459
      }
460

    
461
    if( mAxisMap==null )
462
      {
463
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
464
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
465
      }
466

    
467
    int variant      = getCubitVariant(cubit,numLayers);
468
    int[] dim        = mDimensions[variant];
469
    float[] pos      = getCubitPosition(cubit);
470
    int stickerIndex = getStickerIndex(cubitface,dim);
471
    int quatIndex    = getQuatIndex(cubit);
472
    int face         = mFaceMap[cubitface][quatIndex];
473
    int multiplier   = (face%2)==0 ? 1:-1;
474
    int posIndex     = face/2;
475
    int dimIndex     = mAxisMap[posIndex][quatIndex];
476

    
477
    float position = 0.0f;
478
    int len = pos.length/3;
479
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
480
    position /= len;
481

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

    
484
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
485
    }
486

    
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488
// PUBLIC API
489

    
490
  public Static3D[] getRotationAxis()
491
    {
492
    return ROT_AXIS;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int[] getBasicAngle()
498
    {
499
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
500
    return mBasicAngle;
501
    }
502
}
(3-3/25)