Project

General

Profile

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

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

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.Twisty6;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

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

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

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

    
65
  private static final int NUM_STICKERS = 4;
66

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

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

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

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

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

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94

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

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

    
117
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
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
         };
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

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

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

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

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

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

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

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

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

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

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

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

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

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

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

    
191
    double[][] vertices =
192
      {
193
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
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
      };
202

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

    
210
    float[][] centers = new float[][]
211
      {
212
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
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
      };
221

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

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

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

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

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

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

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

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

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

    
264
    return 1;
265
    }
266

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

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

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

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

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

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

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

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

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

    
314
    return tmp;
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  protected Static4D[] getQuats()
320
    {
321
    if( mQuats==null ) initializeQuats();
322
    return mQuats;
323
    }
324

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

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

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

    
335
      for(int i=0; i<numLayers-1; i++)
336
        {
337
        float cut = (2-numLayers)*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
  private void getLayerRotatable(int numLayers)
350
    {
351
    if( mLayerRotatable==null )
352
      {
353
      int numAxis = ROT_AXIS.length;
354
      boolean[] tmp = new boolean[numLayers];
355
      for(int i=0; i<numLayers; i++) tmp[i] = true;
356
      mLayerRotatable = new boolean[numAxis][];
357
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
358
      }
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

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

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

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

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

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

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

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

    
393
    return 0;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

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

    
407
    return 0;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

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

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

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

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

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

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

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455
// PUBLIC API
456

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

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

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

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

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