Project

General

Profile

Download (14.3 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyBandagedAbstract.java @ efa81f0c

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

    
22
import android.content.res.Resources;
23

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
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
///////////////////////////////////////////////////////////////////////////////////////////////////
34

    
35
abstract class TwistyBandagedAbstract extends Twisty6
36
{
37
  // the three rotation axis of a 3x3 Cube. Must be normalized.
38
  static final Static3D[] ROT_AXIS = new Static3D[]
39
         {
40
           new Static3D(1,0,0),
41
           new Static3D(0,1,0),
42
           new Static3D(0,0,1)
43
         };
44

    
45
  private static final int[][] mDimensions = new int[][]
46
        {
47
         {1,1,1},  // has to be X>=Z>=Y so that all
48
         {2,1,1},  // the faces are horizontal
49
         {3,1,1},
50
         {2,1,2},
51
         {2,2,2}
52
        };
53

    
54
  private static final int NUM_STICKERS = 4;
55

    
56
  private int[] mBasicAngle;
57
  private Static4D[] mQuats;
58
  private ObjectSticker[] mStickers;
59
  private Static4D[] mInitQuats;
60
  private int[][] mAxisMap;
61
  private int[][] mFaceMap;
62
  private Movement mMovement;
63
  ScrambleState[] mStates;
64
  float[][] POSITIONS;
65
  int[] QUAT_INDICES;
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
70
                         DistortedEffects effects, int[][] moves, ObjectList list, Resources res, int scrWidth)
71
    {
72
    super(size, size, quat, texture, mesh, effects, moves, list, res, scrWidth);
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  abstract float[][] getPositions();
78
  abstract int[] getQuatIndices();
79

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

    
82
  private void initializeQuats()
83
    {
84
    mQuats = new Static4D[]
85
         {
86
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),
87
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),
88
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),
89
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),
90

    
91
         new Static4D( SQ2/2,  SQ2/2,  0.0f ,   0.0f),
92
         new Static4D( SQ2/2, -SQ2/2,  0.0f ,   0.0f),
93
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),
94
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,   0.0f),
95
         new Static4D( SQ2/2,   0.0f,   0.0f,  SQ2/2),
96
         new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),
97
         new Static4D(  0.0f,  SQ2/2,  SQ2/2,   0.0f),
98
         new Static4D(  0.0f,  SQ2/2, -SQ2/2,   0.0f),
99
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),
100
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),
101
         new Static4D(  0.0f,   0.0f,  SQ2/2,  SQ2/2),
102
         new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),
103

    
104
         new Static4D(  0.5f,   0.5f,   0.5f,   0.5f),
105
         new Static4D(  0.5f,   0.5f,  -0.5f,   0.5f),
106
         new Static4D(  0.5f,   0.5f,  -0.5f,  -0.5f),
107
         new Static4D(  0.5f,  -0.5f,   0.5f,  -0.5f),
108
         new Static4D( -0.5f,  -0.5f,  -0.5f,   0.5f),
109
         new Static4D( -0.5f,   0.5f,  -0.5f,  -0.5f),
110
         new Static4D( -0.5f,   0.5f,   0.5f,  -0.5f),
111
         new Static4D( -0.5f,   0.5f,   0.5f,   0.5f)
112
         };
113
    }
114

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

    
117
  int[] getSolvedQuats(int cubit, int numLayers)
118
    {
119
    if( mQuats==null ) initializeQuats();
120
    int status = retCubitSolvedStatus(cubit,numLayers);
121
    return status<0 ? null : buildSolvedQuats(MovementCube.FACE_AXIS[status],mQuats);
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  int getNumCubits()
127
    {
128
    return getPositions().length;
129
    }
130

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

    
133
  private float[] getCubitPosition(int cubit)
134
    {
135
    float[][] pos = getPositions();
136

    
137
    return ( cubit>=0 && cubit< pos.length ) ? pos[cubit] : null;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  private int getQuatIndex(int cubit)
143
    {
144
    int[] indices = getQuatIndices();
145
    return ( cubit>=0 && cubit< indices.length ) ? indices[cubit] : 0;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  ObjectShape getObjectShape(int cubit, int numLayers)
151
    {
152
    int variant = getCubitVariant(cubit,numLayers);
153

    
154
    final int[][] vert_indices =
155
      {
156
        {2,3,1,0},
157
        {7,6,4,5},
158
        {4,0,1,5},
159
        {7,3,2,6},
160
        {6,2,0,4},
161
        {3,7,5,1},
162
      };
163

    
164
    float defHeight = 0.048f;
165
    int[] bandIndices = new int[] { 0,0,1,1,2,2 };
166
    float[][] corners = new float[][] { {0.04f,0.15f} };
167
    int[] cornerIndices = new int[] { 0,0,0,0,0,0,0,0 };
168
    int[] centerIndices = new int[] { 0,1,2,3,4,5,6,7 };
169

    
170
    int X = mDimensions[variant][0];
171
    int Y = mDimensions[variant][1];
172
    int Z = mDimensions[variant][2];
173

    
174
    int maxXY = Math.max(X,Y);
175
    int maxXZ = Math.max(X,Z);
176
    int maxYZ = Math.max(Y,Z);
177

    
178
    double[][] vertices =
179
      {
180
        {+0.5f*X,+0.5f*Y,+0.5f*Z},
181
        {+0.5f*X,+0.5f*Y,-0.5f*Z},
182
        {+0.5f*X,-0.5f*Y,+0.5f*Z},
183
        {+0.5f*X,-0.5f*Y,-0.5f*Z},
184
        {-0.5f*X,+0.5f*Y,+0.5f*Z},
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
      };
189

    
190
    float[][] bands= new float[][]
191
      {
192
        {defHeight/maxYZ,65,0.25f,0.5f,5,1,2},
193
        {defHeight/maxXZ,65,0.25f,0.5f,5,1,2},
194
        {defHeight/maxXY,65,0.25f,0.5f,5,1,2}
195
      };
196

    
197
    float[][] centers = new float[][]
198
      {
199
        {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
200
        {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
201
        {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
202
        {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
203
        {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
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
      };
208

    
209
    return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

    
214
  Static4D getQuat(int cubit, int numLayers)
215
    {
216
    if( mInitQuats ==null )
217
      {
218
      mInitQuats = new Static4D[]
219
        {
220
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
221
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
222
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
223
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
224
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
225
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
226
        };
227
      }
228

    
229
    return mInitQuats[getQuatIndex(cubit)];
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  int getNumCubitVariants(int numLayers)
235
    {
236
    return mDimensions.length;
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  int getCubitVariant(int cubit, int numLayers)
242
    {
243
    float[][] pos = getPositions();
244

    
245
    if( cubit>=0 && cubit<pos.length )
246
      {
247
      int numPoints = pos[cubit].length/3;
248
      return numPoints==8 ? 4 : numPoints-1;
249
      }
250

    
251
    return 1;
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  ObjectSticker retSticker(int face)
257
    {
258
    if( mStickers==null )
259
      {
260
      mStickers = new ObjectSticker[NUM_STICKERS];
261

    
262
      int[][] stickerDimensions = new int[][]
263
        {
264
         {1,1},  // dimensions of the faces of
265
         {2,1},  // the cuboids defined in mDimensions
266
         {3,1},
267
         {2,2}
268
        };
269

    
270
      for(int s=0; s<NUM_STICKERS; s++)
271
        {
272
        float X = stickerDimensions[s][0];
273
        float Y = stickerDimensions[s][1];
274
        float MAX = Math.max(X,Y);
275
        X /= (2*MAX);
276
        Y /= (2*MAX);
277

    
278
        float R = 0.10f / MAX;
279
        float S = 0.08f / MAX;
280
        float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
281
        float[] radii = new float[] {R,R,R,R};
282
        mStickers[s] = new ObjectSticker(coords,null,radii,S);
283
        }
284
      }
285

    
286
    return mStickers[face/NUM_FACE_COLORS];
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  float[][] getCubitPositions(int size)
292
    {
293
    int numCubits = getNumCubits();
294
    float[][] tmp = new float[numCubits][];
295

    
296
    for(int cubit=0; cubit<numCubits; cubit++)
297
      {
298
      tmp[cubit] = getCubitPosition(cubit);
299
      }
300

    
301
    return tmp;
302
    }
303

    
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305

    
306
  Static4D[] getQuats()
307
    {
308
    if( mQuats==null ) initializeQuats();
309
    return mQuats;
310
    }
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
  float[][] getCuts(int numLayers)
315
    {
316
    float[][] cuts = new float[3][numLayers-1];
317

    
318
    for(int i=0; i<numLayers-1; i++)
319
      {
320
      float cut = (2-numLayers)*0.5f + i;
321
      cuts[0][i] = cut;
322
      cuts[1][i] = cut;
323
      cuts[2][i] = cut;
324
      }
325

    
326
    return cuts;
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  int getSolvedFunctionIndex()
332
    {
333
    return 0;
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  int getNumStickerTypes(int numLayers)
339
    {
340
    return NUM_STICKERS;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  int getNumCubitFaces()
346
    {
347
    return 6;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  private int retStickerIndex(int horzSize, int vertSize)
353
    {
354
    switch(horzSize)
355
      {
356
      case 1: return 0;
357
      case 2: return vertSize==1 ? 1:3;
358
      case 3: return 2;
359
      }
360

    
361
    return 0;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  private int getStickerIndex(int cubitface, int[] dim)
367
    {
368
    switch(cubitface)
369
      {
370
      case 0: case 1: return retStickerIndex(dim[2],dim[1]);
371
      case 2: case 3: return retStickerIndex(dim[0],dim[2]);
372
      case 4: case 5: return retStickerIndex(dim[0],dim[1]);
373
      }
374

    
375
    return 0;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  int getFaceColor(int cubit, int cubitface, int numLayers)
381
    {
382
    if( mFaceMap==null )
383
      {
384
      // cubitface=2 when rotated by quatIndex=1 gets moved to position mFaceMap[2][1]
385
      mFaceMap = new int[][]
386
          {
387
              {0,0,5,2,4,2},
388
              {1,1,4,3,5,3},
389
              {2,4,2,1,1,4},
390
              {3,5,3,0,0,5},
391
              {4,3,0,4,3,0},
392
              {5,2,1,5,2,1}
393
          };
394
      }
395

    
396
    if( mAxisMap==null )
397
      {
398
      // axis=1 when rotated by quatIndex=2 gets moved to axis mAxisMap[1][2]
399
      mAxisMap = new int[][] { {0,0,2,1,2,1}, {1,2,1,0,0,2}, {2,1,0,2,1,0} };
400
      }
401

    
402
    int variant      = getCubitVariant(cubit,numLayers);
403
    int[] dim        = mDimensions[variant];
404
    float[] pos      = getCubitPosition(cubit);
405
    int stickerIndex = getStickerIndex(cubitface,dim);
406
    int quatIndex    = getQuatIndex(cubit);
407
    int face         = mFaceMap[cubitface][quatIndex];
408
    int multiplier   = (face%2)==0 ? 1:-1;
409
    int posIndex     = face/2;
410
    int dimIndex     = mAxisMap[posIndex][quatIndex];
411

    
412
    float position = 0.0f;
413
    int len = pos.length/3;
414
    for(int i=0; i<len; i++) position += pos[3*i+posIndex];
415
    position /= len;
416

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

    
419
    return reaches ? stickerIndex*NUM_FACE_COLORS + face : NUM_TEXTURES;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
// PUBLIC API
424

    
425
  public Static3D[] getRotationAxis()
426
    {
427
    return ROT_AXIS;
428
    }
429

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  public Movement getMovement()
433
    {
434
    if( mMovement==null ) mMovement = new MovementCube();
435
    return mMovement;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public int[] getBasicAngle()
441
    {
442
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
443
    return mBasicAngle;
444
    }
445
}
(24-24/48)