Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistySkewb.java @ 596d62a4

1 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
26 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 fb52fae9 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
36 fb52fae9 Leszek Koltunski
import org.distorted.main.RubikSurfaceView;
37
38
import java.util.Random;
39
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 9c2f0c91 Leszek Koltunski
public class TwistySkewb extends TwistyObject
43 fb52fae9 Leszek Koltunski
{
44
  private static final int FACES_PER_CUBIT =6;
45
46
  // the four rotation axis of a RubikSkewb. Must be normalized.
47
  static final Static3D[] ROT_AXIS = new Static3D[]
48
         {
49
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
50
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
51
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
52
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
53
         };
54
55
  private static final int[] FACE_COLORS = new int[]
56
         {
57 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
58
           COLOR_BLUE  , COLOR_GREEN,
59 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
60 fb52fae9 Leszek Koltunski
         };
61
62
  // All legal rotation quats of a RubikSkewb
63
  private static final Static4D[] QUATS = new Static4D[]
64
         {
65
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
66
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
67
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
68
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
69
70
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
71
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
72
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
74
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
75
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
78
         };
79
80 3f3ff476 Leszek Koltunski
  private static final int[][] mCornerMap =
81
         {
82
           {  4, 2, 0, 18,18,18 },
83
           {  2, 5, 0, 18,18,18 },
84
           {  3, 4, 0, 18,18,18 },
85
           {  5, 3, 0, 18,18,18 },
86
           {  1, 2, 4, 18,18,18 },
87
           {  5, 2, 1, 18,18,18 },
88
           {  4, 3, 1, 18,18,18 },
89
           {  1, 3, 5, 18,18,18 },
90
         };
91 63002261 Leszek Koltunski
92 3f3ff476 Leszek Koltunski
  private static final int[][] mEdgeMap =
93 fb52fae9 Leszek Koltunski
         {
94 3f3ff476 Leszek Koltunski
           { 10, 8, 18,18,18,18 },
95
           {  6,10, 18,18,18,18 },
96
           { 10, 9, 18,18,18,18 },
97
           {  7,10, 18,18,18,18 },
98
           {  8, 6, 18,18,18,18 },
99
           {  9, 6, 18,18,18,18 },
100
           {  9, 7, 18,18,18,18 },
101
           {  8, 7, 18,18,18,18 },
102
           { 11, 8, 18,18,18,18 },
103
           {  6,11, 18,18,18,18 },
104
           { 11, 9, 18,18,18,18 },
105
           {  7,11, 18,18,18,18 }
106 fb52fae9 Leszek Koltunski
         };
107
108 3f3ff476 Leszek Koltunski
  private static final int[][] mCenterMap =
109 fb52fae9 Leszek Koltunski
         {
110 3f3ff476 Leszek Koltunski
           { 12, 18,18,18,18,18 },
111
           { 13, 18,18,18,18,18 },
112
           { 14, 18,18,18,18,18 },
113
           { 15, 18,18,18,18,18 },
114
           { 16, 18,18,18,18,18 },
115
           { 17, 18,18,18,18,18 },
116 fb52fae9 Leszek Koltunski
         };
117
118 596d62a4 Leszek Koltunski
  private static final double[][] VERTICES_CORNER = new double[][]
119
          {
120
             // TODO
121
          };
122
123
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
124
          {
125
             // TODO
126
          };
127
128
  private static final double[][] VERTICES_EDGE = new double[][]
129
          {
130
             {-0.5, 0.0, 0.0},
131
             { 0.5, 0.0, 0.0},
132
             { 0.0,-0.5, 0.0},
133
             { 0.0, 0.0,-0.5}
134
          };
135
136
  private static final int[][] VERT_INDEXES_EDGE = new int[][]
137
          {
138
             {2,1,0},   // counterclockwise!
139
             {3,0,1},
140
             {2,3,1},
141
             {3,2,0},
142
          };
143
144
  private static final double[][] VERTICES_FACE = new double[][]
145
          {
146
             // TODO
147
          };
148
149
  private static final int[][] VERT_INDEXES_FACE = new int[][]
150
          {
151
             // TODO
152
          };
153
154
  private static MeshBase[] mMeshes;
155 fb52fae9 Leszek Koltunski
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
158 9c2f0c91 Leszek Koltunski
  TwistySkewb(int size, Static4D quat, DistortedTexture texture,
159
              MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
160 fb52fae9 Leszek Koltunski
    {
161 db875721 Leszek Koltunski
    super(size, 2*size-2, quat, texture, mesh, effects, moves, ObjectList.SKEW, res, scrWidth);
162 fb52fae9 Leszek Koltunski
    }
163
164 b1f2ccf5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
165
166
  double[][] getVertices(int cubitType)
167
    {
168 596d62a4 Leszek Koltunski
    if( cubitType==0 ) return VERTICES_CORNER;
169
    if( cubitType==1 ) return VERTICES_EDGE;
170
    if( cubitType==2 ) return VERTICES_FACE;
171 b1f2ccf5 Leszek Koltunski
    return null;
172
    }
173
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175
176
  int[][] getVertIndexes(int cubitType)
177
    {
178 596d62a4 Leszek Koltunski
    if( cubitType==0 ) return VERT_INDEXES_CORNER;
179
    if( cubitType==1 ) return VERT_INDEXES_EDGE;
180
    if( cubitType==2 ) return VERT_INDEXES_FACE;
181 b1f2ccf5 Leszek Koltunski
    return null;
182
    }
183
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185
186
  int getNumCubitTypes(int numLayers)
187
    {
188
    return numLayers==2 ? 2 : 3;
189
    }
190
191 3f3ff476 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193 d92030e4 Leszek Koltunski
  private int getNumCorners()
194 3f3ff476 Leszek Koltunski
    {
195
    return 8;
196
    }
197
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
200 b89898c5 Leszek Koltunski
  private int getNumEdges(int layers)
201 3f3ff476 Leszek Koltunski
    {
202 b89898c5 Leszek Koltunski
    return (layers-2)*12;
203 3f3ff476 Leszek Koltunski
    }
204
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
207 d92030e4 Leszek Koltunski
  private int getNumCentersPerFace(int layers)
208 3f3ff476 Leszek Koltunski
    {
209 d92030e4 Leszek Koltunski
    return ((layers-2)*(layers-2) + (layers-1)*(layers-1));
210 3f3ff476 Leszek Koltunski
    }
211
212 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
213
214
  float getScreenRatio()
215
    {
216 d99f3a48 Leszek Koltunski
    return 1.0f;
217 fb52fae9 Leszek Koltunski
    }
218
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221
  Static4D[] getQuats()
222
    {
223
    return QUATS;
224
    }
225
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227
228
  int getNumFaces()
229
    {
230
    return FACE_COLORS.length;
231
    }
232
233 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
234
235
  boolean shouldResetTextureMaps()
236
    {
237
    return false;
238
    }
239
240 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
241
242 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
243 eab9d8f8 Leszek Koltunski
    {
244 3f3ff476 Leszek Koltunski
    return 3;
245 eab9d8f8 Leszek Koltunski
    }
246
247 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249 b89898c5 Leszek Koltunski
  float[] getCuts(int numLayers)
250 7403cdfa Leszek Koltunski
    {
251 b89898c5 Leszek Koltunski
    float[] cuts = new float[numLayers-1];
252 a97e02b7 Leszek Koltunski
253 b89898c5 Leszek Koltunski
    switch(numLayers)
254 a97e02b7 Leszek Koltunski
      {
255
      case 2: cuts[0] = 0;
256
              break;
257
      case 3: cuts[0] = -SQ3/12;
258
              cuts[1] = +SQ3/12;
259
              break;
260 c7e23561 Leszek Koltunski
      case 4: cuts[0] = -SQ3/9;
261
              cuts[1] = 0;
262
              cuts[2] = +SQ3/9;
263
              break;
264 a97e02b7 Leszek Koltunski
      }
265
    return cuts;
266 7403cdfa Leszek Koltunski
    }
267
268 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
269
270
  int getNumCubitFaces()
271
    {
272
    return FACES_PER_CUBIT;
273
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
278 fb52fae9 Leszek Koltunski
    {
279 b89898c5 Leszek Koltunski
    final float DIST_CORNER = (numLayers-1)*0.50f;
280
    final float DIST_EDGE   = (numLayers-1)*0.50f;
281
    final float DIST_CENTER = (numLayers-1)*0.50f;
282 3f3ff476 Leszek Koltunski
283 d92030e4 Leszek Koltunski
    final int numCorners = getNumCorners();
284 b89898c5 Leszek Koltunski
    final int numEdges   = getNumEdges(numLayers);
285 d92030e4 Leszek Koltunski
    final int numCenters = 6*getNumCentersPerFace(numLayers);
286 3f3ff476 Leszek Koltunski
287 e6cf7283 Leszek Koltunski
    final float[][] CENTERS = new float[numCorners+numEdges+numCenters][];
288 3f3ff476 Leszek Koltunski
289
    /// CORNERS //////////////////////////////////////////////
290
291 e6cf7283 Leszek Koltunski
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
292
    CENTERS[1] = new float[] { DIST_CORNER, DIST_CORNER,-DIST_CORNER };
293
    CENTERS[2] = new float[] { DIST_CORNER,-DIST_CORNER, DIST_CORNER };
294
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
295
    CENTERS[4] = new float[] {-DIST_CORNER, DIST_CORNER, DIST_CORNER };
296
    CENTERS[5] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
297
    CENTERS[6] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
298
    CENTERS[7] = new float[] {-DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
299 3f3ff476 Leszek Koltunski
300
    /// EDGES ///////////////////////////////////////////////
301
302
    final float[][]  edgeTable =
303
        {
304
            {0,+DIST_EDGE,+DIST_EDGE},
305
            {+DIST_EDGE,0,+DIST_EDGE},
306
            {0,-DIST_EDGE,+DIST_EDGE},
307
            {-DIST_EDGE,0,+DIST_EDGE},
308
            {+DIST_EDGE,+DIST_EDGE,0},
309
            {+DIST_EDGE,-DIST_EDGE,0},
310
            {-DIST_EDGE,-DIST_EDGE,0},
311
            {-DIST_EDGE,+DIST_EDGE,0},
312
            {0,+DIST_EDGE,-DIST_EDGE},
313
            {+DIST_EDGE,0,-DIST_EDGE},
314
            {0,-DIST_EDGE,-DIST_EDGE},
315
            {-DIST_EDGE,0,-DIST_EDGE}
316
        };
317
318
    int index=8;
319
320
    for (float[] edges : edgeTable)
321
      {
322 b89898c5 Leszek Koltunski
      float c = (3-numLayers)*0.5f;
323 3f3ff476 Leszek Koltunski
324 b89898c5 Leszek Koltunski
      for (int j=0; j<numLayers-2; j++, c+=1.0f, index++)
325 3f3ff476 Leszek Koltunski
        {
326 e6cf7283 Leszek Koltunski
        CENTERS[index] = new float[] { edges[0]==0 ? c : edges[0] ,
327 3f3ff476 Leszek Koltunski
                                       edges[1]==0 ? c : edges[1] ,
328 e6cf7283 Leszek Koltunski
                                       edges[2]==0 ? c : edges[2] };
329 3f3ff476 Leszek Koltunski
        }
330
      }
331
332
    /// CENTERS //////////////////////////////////////////////
333
334
    final float X= -1000.0f;
335
    final float Y= -1001.0f;
336
337
    final float[][]  centerTable =
338
        {
339
            {+DIST_CENTER,X,Y},
340
            {-DIST_CENTER,X,Y},
341
            {X,+DIST_CENTER,Y},
342
            {X,-DIST_CENTER,Y},
343
            {X,Y,+DIST_CENTER},
344
            {X,Y,-DIST_CENTER}
345
        };
346
347
    float x,y, cen0, cen1, cen2;
348
349
    for( float[] centers : centerTable )
350
      {
351 b89898c5 Leszek Koltunski
      x = (2-numLayers)*0.5f;
352 3f3ff476 Leszek Koltunski
353 b89898c5 Leszek Koltunski
      for(int i=0; i<numLayers-1; i++, x+=1.0f)
354 3f3ff476 Leszek Koltunski
        {
355 b89898c5 Leszek Koltunski
        y = (2-numLayers)*0.5f;
356 3f3ff476 Leszek Koltunski
357 b89898c5 Leszek Koltunski
        for(int j=0; j<numLayers-1; j++, y+=1.0f, index++)
358 3f3ff476 Leszek Koltunski
          {
359
               if( centers[0]==Y ) cen0 = y;
360
          else if( centers[0]==X ) cen0 = x;
361
          else                     cen0 = centers[0];
362
363
               if( centers[1]==Y ) cen1 = y;
364
          else if( centers[1]==X ) cen1 = x;
365
          else                     cen1 = centers[1];
366
367
               if( centers[2]==Y ) cen2 = y;
368
          else if( centers[2]==X ) cen2 = x;
369
          else                     cen2 = centers[2];
370
371 e6cf7283 Leszek Koltunski
          CENTERS[index] = new float[] {cen0,cen1,cen2};
372 3f3ff476 Leszek Koltunski
          }
373
        }
374
375 b89898c5 Leszek Koltunski
      x = (3-numLayers)*0.5f;
376 3f3ff476 Leszek Koltunski
377 b89898c5 Leszek Koltunski
      for(int i=0; i<numLayers-2; i++, x+=1.0f)
378 3f3ff476 Leszek Koltunski
        {
379 b89898c5 Leszek Koltunski
        y = (3-numLayers)*0.5f;
380 3f3ff476 Leszek Koltunski
381 b89898c5 Leszek Koltunski
        for(int j=0; j<numLayers-2; j++, y+=1.0f, index++)
382 3f3ff476 Leszek Koltunski
          {
383
               if( centers[0]==Y ) cen0 = y;
384
          else if( centers[0]==X ) cen0 = x;
385
          else                     cen0 = centers[0];
386
387
               if( centers[1]==Y ) cen1 = y;
388
          else if( centers[1]==X ) cen1 = x;
389
          else                     cen1 = centers[1];
390
391
               if( centers[2]==Y ) cen2 = y;
392
          else if( centers[2]==X ) cen2 = x;
393
          else                     cen2 = centers[2];
394
395 e6cf7283 Leszek Koltunski
          CENTERS[index] = new float[] {cen0,cen1,cen2};
396 3f3ff476 Leszek Koltunski
          }
397
        }
398
      }
399
400 fb52fae9 Leszek Koltunski
    return CENTERS;
401
    }
402
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404
405 d92030e4 Leszek Koltunski
  private Static4D getQuat(int cubit, int numLayers)
406 fb52fae9 Leszek Koltunski
    {
407 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
408
    int numEdges   = getNumEdges(numLayers);
409 3f3ff476 Leszek Koltunski
410
    if( cubit<numCorners )
411
      {
412
      switch(cubit)
413
        {
414
        case  0: return QUATS[0];                          //  unit quat
415
        case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
416
        case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
417
        case  3: return QUATS[1];                          // 180 along X
418
        case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
419
        case  5: return QUATS[2];                          // 180 along Y
420
        case  6: return QUATS[3];                          // 180 along Z
421
        case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
422
        }
423
      }
424
    else if( cubit<numCorners+numEdges )
425
      {
426 d92030e4 Leszek Koltunski
      int edge = (cubit-numCorners)/(numLayers-2);
427 3f3ff476 Leszek Koltunski
428
      switch(edge)
429
        {
430
        case  0: return QUATS[ 0];
431
        case  1: return QUATS[ 5];
432
        case  2: return QUATS[ 3];
433
        case  3: return QUATS[11];
434
        case  4: return QUATS[ 4];
435
        case  5: return QUATS[ 7];
436
        case  6: return QUATS[ 9];
437
        case  7: return QUATS[10];
438
        case  8: return QUATS[ 2];
439
        case  9: return QUATS[ 8];
440
        case 10: return QUATS[ 1];
441
        case 11: return QUATS[ 6];
442
        }
443
      }
444
    else
445 fb52fae9 Leszek Koltunski
      {
446 d92030e4 Leszek Koltunski
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
447 3f3ff476 Leszek Koltunski
448
      switch(center)
449
        {
450
        case 0: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
451
        case 1: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
452
        case 2: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
453
        case 3: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
454
        case 4: return QUATS[0];                          //  unit quaternion
455
        case 5: return QUATS[1];                          // 180 along X
456
        }
457 fb52fae9 Leszek Koltunski
      }
458
459
    return null;
460
    }
461
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463
464 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
465 fb52fae9 Leszek Koltunski
    {
466 596d62a4 Leszek Koltunski
    if( mMeshes==null )
467
      {
468
      FactoryCubit factory = FactoryCubit.getInstance();
469
      factory.clear();
470
      mMeshes = new MeshBase[3];
471
      }
472
473 fb52fae9 Leszek Koltunski
    MeshBase mesh;
474
475 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
476 d99f3a48 Leszek Koltunski
    int numEdges   = getNumEdges(numLayers);
477 3f3ff476 Leszek Koltunski
478
    if( cubit<numCorners )
479 fb52fae9 Leszek Koltunski
      {
480 596d62a4 Leszek Koltunski
      if( mMeshes[0]==null )
481
        {
482
        mMeshes[0] = FactoryCubit.getInstance().createSkewbCornerMesh();
483
        }
484
      mesh = mMeshes[0].copy(true);
485 fb52fae9 Leszek Koltunski
      }
486 3f3ff476 Leszek Koltunski
    else if( cubit<numCorners+numEdges )
487
      {
488 596d62a4 Leszek Koltunski
      if( mMeshes[1]==null )
489 3f3ff476 Leszek Koltunski
        {
490 596d62a4 Leszek Koltunski
        float[][] bands= new float[][]
491
          {
492
             {0.035f,30,0.16f,0.8f,7,2,5},
493
             {0.020f,45,0.16f,0.2f,3,1,2}
494
          };
495
        int[] bandIndexes   = new int[] { 0,0,1,1 };
496
        float[][] corners   = new float[][] { {0.07f,0.20f}, {0.02f,0.30f} };
497
        int[] cornerIndexes = new int[] { 0,0,1,1 };
498
499
        FactoryCubit factory = FactoryCubit.getInstance();
500
501
        factory.createNewFaceTransform(VERTICES_EDGE,VERT_INDEXES_EDGE);
502
        mMeshes[1] = factory.createRoundedSolid(VERTICES_EDGE, VERT_INDEXES_EDGE,
503
                                                bands, bandIndexes,
504
                                                corners, cornerIndexes,
505
                                                getNumCubitFaces() );
506 3f3ff476 Leszek Koltunski
        }
507 596d62a4 Leszek Koltunski
      mesh = mMeshes[1].copy(true);
508 3f3ff476 Leszek Koltunski
      }
509 fb52fae9 Leszek Koltunski
    else
510
      {
511 596d62a4 Leszek Koltunski
      if( mMeshes[2]==null )
512
        {
513
        mMeshes[2] = FactoryCubit.getInstance().createSkewbFaceMesh();
514
        }
515
      mesh = mMeshes[2].copy(true);
516 fb52fae9 Leszek Koltunski
      }
517
518 d99f3a48 Leszek Koltunski
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit,numLayers), new Static3D(0,0,0) );
519 fb52fae9 Leszek Koltunski
    mesh.apply(quat,0xffffffff,0);
520
521
    return mesh;
522
    }
523
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525
526 d92030e4 Leszek Koltunski
  int getFaceColor(int cubit, int cubitface, int numLayers)
527 fb52fae9 Leszek Koltunski
    {
528 d92030e4 Leszek Koltunski
    int numCorners = getNumCorners();
529
    int numEdges   = getNumEdges(numLayers);
530 3f3ff476 Leszek Koltunski
531
    if( cubit<numCorners )
532
      {
533
      return mCornerMap[cubit][cubitface];
534
      }
535
    else if( cubit<numCorners+numEdges )
536
      {
537 d92030e4 Leszek Koltunski
      int edge = (cubit-numCorners)/(numLayers-2);
538 3f3ff476 Leszek Koltunski
      return mEdgeMap[edge][cubitface];
539
      }
540
    else
541
      {
542 d92030e4 Leszek Koltunski
      int center = (cubit-numCorners-numEdges)/getNumCentersPerFace(numLayers);
543 3f3ff476 Leszek Koltunski
      return mCenterMap[center][cubitface];
544
      }
545 fb52fae9 Leszek Koltunski
    }
546
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548
549 ae755eda Leszek Koltunski
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
550 fb52fae9 Leszek Koltunski
    {
551 eab9d8f8 Leszek Koltunski
    int COLORS = FACE_COLORS.length;
552 ae755eda Leszek Koltunski
    float R,S;
553
    float[] vertices;
554 eab9d8f8 Leszek Koltunski
555
    if( face<COLORS )
556
      {
557 76c2bd07 Leszek Koltunski
      float E = 0.5f;
558 ae755eda Leszek Koltunski
      R = 0.023f;
559
      S = 0.035f;
560
      vertices = new float[] { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
561 eab9d8f8 Leszek Koltunski
      }
562 3f3ff476 Leszek Koltunski
    else if( face<2*COLORS )
563
      {
564 ae755eda Leszek Koltunski
      float E = 0.5f;
565
      R = 0.025f;
566
      S = 0.05f;
567
      vertices = new float[] { -E,E/3, 0,-2*E/3, +E,E/3 };
568 3f3ff476 Leszek Koltunski
      }
569 eab9d8f8 Leszek Koltunski
    else
570
      {
571 76c2bd07 Leszek Koltunski
      float E = SQ2/4;
572 ae755eda Leszek Koltunski
      R = 0.055f;
573
      S = 0.035f;
574
      vertices = new float[] { -E,-E, +E,-E, +E,+E, -E,+E };
575 eab9d8f8 Leszek Koltunski
      }
576 ae755eda Leszek Koltunski
577
    FactorySticker factory = FactorySticker.getInstance();
578
    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S, FACE_COLORS[face%COLORS], R);
579 fb52fae9 Leszek Koltunski
    }
580
581
///////////////////////////////////////////////////////////////////////////////////////////////////
582
583
  float returnMultiplier()
584
    {
585
    return 2.0f;
586
    }
587
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589
590 a64e07d0 Leszek Koltunski
  float[] getRowChances(int numLayers)
591 fb52fae9 Leszek Koltunski
    {
592 d99f3a48 Leszek Koltunski
    float[] chances = new float[numLayers];
593 fb52fae9 Leszek Koltunski
594 b3da2f16 Leszek Koltunski
    switch(numLayers)
595 3f3ff476 Leszek Koltunski
      {
596 b3da2f16 Leszek Koltunski
      case 2: chances[0] = 0.5f;
597
              chances[1] = 1.0f;
598
              break;
599
      case 3: chances[0] = 0.5f;
600
              chances[1] = 0.5f;
601
              chances[2] = 1.0f;
602
              break;
603
      default:for(int i=0; i<numLayers; i++)
604
                {
605
                chances[i] = (float)(i+1)/numLayers;
606
                }
607 3f3ff476 Leszek Koltunski
      }
608 fb52fae9 Leszek Koltunski
609
    return chances;
610
    }
611
612
///////////////////////////////////////////////////////////////////////////////////////////////////
613
// PUBLIC API
614
615
  public Static3D[] getRotationAxis()
616
    {
617
    return ROT_AXIS;
618
    }
619
620
///////////////////////////////////////////////////////////////////////////////////////////////////
621
622
  public int getBasicAngle()
623
    {
624
    return 3;
625
    }
626
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628
629 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
630 fb52fae9 Leszek Koltunski
    {
631 5043d5d0 Leszek Koltunski
    if( num==0 )
632 fb52fae9 Leszek Koltunski
      {
633 5043d5d0 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
634 fb52fae9 Leszek Koltunski
      }
635
    else
636
      {
637 bbc6471c Leszek Koltunski
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
638 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
639 fb52fae9 Leszek Koltunski
      }
640
641
    float rowFloat = rnd.nextFloat();
642
643
    for(int row=0; row<mRowChances.length; row++)
644
      {
645 bbc6471c Leszek Koltunski
      if( rowFloat<=mRowChances[row] )
646
        {
647 5043d5d0 Leszek Koltunski
        scramble[num][1] = row;
648 bbc6471c Leszek Koltunski
        break;
649
        }
650 fb52fae9 Leszek Koltunski
      }
651
652 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
653
      {
654
      case 0: scramble[num][2] = -1; break;
655
      case 1: scramble[num][2] =  1; break;
656
      }
657 fb52fae9 Leszek Koltunski
    }
658
659
///////////////////////////////////////////////////////////////////////////////////////////////////
660
// remember about the double cover or unit quaternions!
661
662
  private int mulQuat(int q1, int q2)
663
    {
664
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
665
666
    float rX = result.get0();
667
    float rY = result.get1();
668
    float rZ = result.get2();
669
    float rW = result.get3();
670
671
    final float MAX_ERROR = 0.1f;
672
    float dX,dY,dZ,dW;
673
674
    for(int i=0; i<QUATS.length; i++)
675
      {
676
      dX = QUATS[i].get0() - rX;
677
      dY = QUATS[i].get1() - rY;
678
      dZ = QUATS[i].get2() - rZ;
679
      dW = QUATS[i].get3() - rW;
680
681
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
682
          dY<MAX_ERROR && dY>-MAX_ERROR &&
683
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
684
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
685
686
      dX = QUATS[i].get0() + rX;
687
      dY = QUATS[i].get1() + rY;
688
      dZ = QUATS[i].get2() + rZ;
689
      dW = QUATS[i].get3() + rW;
690
691
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
692
          dY<MAX_ERROR && dY>-MAX_ERROR &&
693
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
694
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
695
      }
696
697
    return -1;
698
    }
699
700
///////////////////////////////////////////////////////////////////////////////////////////////////
701
// The Skewb is solved if and only if:
702
//
703 3f3ff476 Leszek Koltunski
// 1) all of its corner and edge cubits are rotated with the same quat
704 fb52fae9 Leszek Koltunski
// 2) all its face cubits are rotated with the same quat like the corner ones,
705
//    and optionally they also might be upside down.
706
//
707
// i.e.
708
// cubits [ 8] and [ 9] - might be extra QUAT[1]
709
// cubits [10] and [11] - might be extra QUAT[2]
710
// cubits [12] and [13] - might be extra QUAT[3]
711
712
  public boolean isSolved()
713
    {
714
    int q = CUBITS[0].mQuatIndex;
715
716 d92030e4 Leszek Koltunski
    int numLayers      = getNumLayers();
717
    int numCorners     = getNumCorners();
718
    int numEdges       = getNumEdges(numLayers);
719
    int cornersAndEdges= numCorners + numEdges;
720
    int centersPerFace = getNumCentersPerFace(numLayers);
721 b89898c5 Leszek Koltunski
    int cubit, q1=q;
722
723
    for(cubit=0; cubit<cornersAndEdges; cubit++)
724 fb52fae9 Leszek Koltunski
      {
725 b89898c5 Leszek Koltunski
      if( CUBITS[cubit].mQuatIndex != q ) return false;
726 fb52fae9 Leszek Koltunski
      }
727
728 b89898c5 Leszek Koltunski
    for(int face=0; face<6; face++)
729
      {
730
      if( face%2==0 ) q1 = mulQuat(q, (face/2)+1);
731
732 d92030e4 Leszek Koltunski
      for(int center=0; center<centersPerFace; center++)
733 b89898c5 Leszek Koltunski
        {
734
        if( CUBITS[cubit].mQuatIndex != q && CUBITS[cubit].mQuatIndex != q1 ) return false;
735
        cubit++;
736
        }
737
      }
738
739
    return true;
740 fb52fae9 Leszek Koltunski
    }
741
742
///////////////////////////////////////////////////////////////////////////////////////////////////
743 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
744 fb52fae9 Leszek Koltunski
745
  public String retObjectString()
746
    {
747
    return "";
748
    }
749 6fd4a72c Leszek Koltunski
750
///////////////////////////////////////////////////////////////////////////////////////////////////
751
752
  public int getObjectName(int numLayers)
753
    {
754
    switch(numLayers)
755
      {
756
      case 2: return R.string.skew2;
757
      case 3: return R.string.skew3;
758
      }
759
    return R.string.skew2;
760
    }
761
762
///////////////////////////////////////////////////////////////////////////////////////////////////
763
764
  public int getInventor(int numLayers)
765
    {
766
    switch(numLayers)
767
      {
768
      case 2: return R.string.skew2_inventor;
769
      case 3: return R.string.skew3_inventor;
770
      }
771
    return R.string.skew2_inventor;
772
    }
773
774
///////////////////////////////////////////////////////////////////////////////////////////////////
775
776
  public int getComplexity(int numLayers)
777
    {
778
    switch(numLayers)
779
      {
780
      case 2: return 5;
781
      case 3: return 9;
782
      }
783
    return 5;
784
    }
785 fb52fae9 Leszek Koltunski
}