Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyJing.java @ 3290a98d

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.objects;
11

    
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_TETRAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14

    
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17

    
18
import org.distorted.objectlib.helpers.FactoryCubit;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectSignature;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.main.ObjectSignatures;
24
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
25
import org.distorted.objectlib.main.InitData;
26
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
27
import org.distorted.objectlib.main.ObjectType;
28
import org.distorted.objectlib.helpers.ObjectShape;
29
import org.distorted.objectlib.shape.ShapeTetrahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class TwistyJing extends ShapeTetrahedron
34
{
35
  static final Static3D[] ROT_AXIS = new Static3D[]
36
         {
37
           new Static3D(     0,-SQ3/3,-SQ6/3),
38
           new Static3D(     0,-SQ3/3, SQ6/3),
39
           new Static3D( SQ6/3, SQ3/3,     0),
40
           new Static3D(-SQ6/3, SQ3/3,     0),
41
         };
42

    
43
  // Length of the edge of the corner cubit -
44
  // assuming the length of the edge of the whole tetrahedron is numLayers[0]
45
  public static final float[] JING_F = { 0.00f, 0.00f, 0.48f, 0.66f, 0.57f, 0.66f };
46

    
47
  private int[][] mEdges;
48
  private int[][] mBasicAngle;
49
  private int[] mQuatIndex;
50
  private float[][] mCuts;
51
  private float[][] mCenters;
52

    
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

    
55
  public TwistyJing(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
56
    {
57
    super(meshState, iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61
// make the 'center' sticker artificially smaller, so that we paint over the area in the center of the face.
62

    
63
  @Override
64
  public void adjustStickerCoords()
65
    {
66
    int[] numLayers = getNumLayers();
67
    int numL = numLayers[0];
68

    
69
    if( numL==3 || numL==5 )
70
      {
71
      float CENTER_CORR = 0.85f;
72
      int index = numL==3 ? 3 : 4;
73

    
74
      if( numL==3 )
75
        {
76
        mStickerCoords[index][0][2][0] *= CENTER_CORR;
77
        mStickerCoords[index][0][2][1] *= CENTER_CORR;
78
        }
79
      }
80
    }
81

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

    
84
  @Override
85
  public float[][] returnRotationFactor()
86
    {
87
    int numL = getNumLayers()[0];
88
    float[] f = new float[numL];
89
    for(int i=0; i<numL; i++) f[i] = 1.3f;
90
    return new float[][] { f,f,f,f };
91
    }
92

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

    
95
  @Override
96
  public float getPillowCoeff()
97
    {
98
    return 1.25f;
99
    }
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

    
103
  public int[][] getScrambleEdges()
104
    {
105
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
106
    return mEdges;
107
    }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

    
111
  public float[][] getCuts(int[] numLayers)
112
    {
113
    if( mCuts==null )
114
      {
115
      float[] cut=null;
116
      int numL = numLayers[0];
117
      final float F = JING_F[numL];
118

    
119
      switch( numL )
120
        {
121
        case 2: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3) };
122
                break;
123
        case 3: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), numL*SQ6/18 };
124
                break;
125
        case 4: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), (2*F-numL*0.25f-0.01f)*(SQ6/3) };
126
                break;
127
        case 5: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), (2*F-numL*0.25f-0.01f)*(SQ6/3), numL*SQ6/18 };
128
                break;
129
        }
130

    
131
      mCuts = new float[][] { cut,cut,cut,cut };
132
      }
133

    
134
    return mCuts;
135
    }
136

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

    
139
  public boolean[][] getLayerRotatable(int[] numLayers)
140
    {
141
    int numL = numLayers[0];
142
    boolean[] tmp = new boolean[numL];
143
    for(int i=0; i<numL; i++) tmp[i] = true;
144
    return new boolean[][] { tmp,tmp,tmp,tmp };
145
    }
146

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

    
149
  public int getTouchControlType()
150
    {
151
    return TC_TETRAHEDRON;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  public int getTouchControlSplit()
157
    {
158
    return TYPE_NOT_SPLIT;
159
    }
160

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

    
163
  public int[][][] getEnabled()
164
    {
165
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
166
    }
167

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

    
170
  public float[] getDist3D(int[] numLayers)
171
    {
172
    return TouchControlTetrahedron.D3D;
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  public Static3D[] getFaceAxis()
178
    {
179
    return TouchControlTetrahedron.FACE_AXIS;
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  public float[][] getCubitPositions(int[] numLayers)
185
    {
186
    if( mCenters==null )
187
      {
188
      int numL = numLayers[0];
189

    
190
      if( numL==2 )
191
        {
192
        mCenters = new float[][]
193
          {
194
            { 0.000f, -SQ2/2,  1.000f },
195
            { 0.000f, -SQ2/2, -1.000f },
196
            {-1.000f,  SQ2/2,  0.000f },
197
            { 1.000f,  SQ2/2,  0.000f },
198

    
199
            { 0.000f, -SQ2/2,  0.000f },
200
            {-0.500f, 0.000f,  0.500f },
201
            { 0.500f, 0.000f,  0.500f },
202
            {-0.500f, 0.000f, -0.500f },
203
            { 0.500f, 0.000f, -0.500f },
204
            { 0.000f,  SQ2/2,  0.000f },
205

    
206
            { 0.000f,  SQ2/6,  1.0f/3 },
207
            { 0.000f,  SQ2/6, -1.0f/3 },
208
            {-1.0f/3, -SQ2/6,  0.000f },
209
            { 1.0f/3, -SQ2/6,  0.000f },
210
          };
211
        }
212
      else if( numL==3 )
213
        {
214
        final float F = JING_F[numL];
215
        final float A = numL*0.25f;
216
        final float B = numL*0.50f;
217
        final float X = F/2;
218
        final float Y = F*SQ2/2;
219
        final float Z = -F/2;
220

    
221
        mCenters = new float[][]
222
          {
223
            {   0, -SQ2*A,  B },
224
            {   0, -SQ2*A, -B },
225
            {  -B,  SQ2*A,  0 },
226
            {   B,  SQ2*A,  0 },
227

    
228
            {   X, -SQ2*A +Y, B+Z },
229
            {  -X, -SQ2*A +Y, B+Z },
230
            {   0, -SQ2*A   , B-F },
231
            {   X, -SQ2*A +Y,-B-Z },
232
            {  -X, -SQ2*A +Y,-B-Z },
233
            {   0, -SQ2*A   ,-B+F },
234

    
235
            {-B-Z,  SQ2*A -Y,   X },
236
            {-B-Z,  SQ2*A -Y,  -X },
237
            {-B+F,  SQ2*A   ,   0 },
238
            { B+Z,  SQ2*A -Y,   X },
239
            { B+Z,  SQ2*A -Y,  -X },
240
            { B-F,  SQ2*A   ,   0 },
241

    
242
            {      0, -SQ2*A +2*Y,  B +2*Z },
243
            {      X, -SQ2*A +  Y,  B +Z-F },
244
            {     -X, -SQ2*A +  Y,  B +Z-F },
245
            {      0, -SQ2*A +2*Y, -B -2*Z },
246
            {      X, -SQ2*A +  Y, -B -Z+F },
247
            {     -X, -SQ2*A +  Y, -B -Z+F },
248
            {-B -2*Z,  SQ2*A -2*Y,       0 },
249
            {-B -Z+F,  SQ2*A -  Y,      -X },
250
            {-B -Z+F,  SQ2*A -  Y,       X },
251
            { B +2*Z,  SQ2*A -2*Y,       0 },
252
            { B +Z-F,  SQ2*A -  Y,      -X },
253
            { B +Z-F,  SQ2*A -  Y,       X },
254
          };
255
        }
256
      else if( numL==4 )
257
        {
258
        final float A = numL*0.25f;
259
        final float B = numL*0.50f;
260
        final float C = numL*(1.0f/6);
261
        final float D = numL*(SQ2/12);
262
        final float F = JING_F[numL];
263
        final float X = F/2;
264
        final float Y = F*SQ2/2;
265
        final float Z = -F/2;
266

    
267
        mCenters = new float[][]
268
          {
269
            {  0, -SQ2*A     ,  B      },
270
            {  X, -SQ2*A +  Y,  B +  Z },
271
            { -X, -SQ2*A +  Y,  B +  Z },
272
            {  0, -SQ2*A     ,  B -  F },
273
            {  0, -SQ2*A +2*Y,  B +2*Z },
274
            {  X, -SQ2*A +  Y,  B +Z-F },
275
            { -X, -SQ2*A +  Y,  B +Z-F },
276

    
277
            {  0, -SQ2*A     , -B      },
278
            {  X, -SQ2*A +  Y, -B -  Z },
279
            { -X, -SQ2*A +  Y, -B -  Z },
280
            {  0, -SQ2*A     , -B +  F },
281
            {  0, -SQ2*A +2*Y, -B -2*Z },
282
            {  X, -SQ2*A +  Y, -B -Z+F },
283
            { -X, -SQ2*A +  Y, -B -Z+F },
284

    
285
            {-B     ,  SQ2*A     ,   0 },
286
            {-B -  Z,  SQ2*A -  Y,   X },
287
            {-B -  Z,  SQ2*A -  Y,  -X },
288
            {-B +  F,  SQ2*A     ,   0 },
289
            {-B -2*Z,  SQ2*A -2*Y,   0 },
290
            {-B -Z+F,  SQ2*A -  Y,  -X },
291
            {-B -Z+F,  SQ2*A -  Y,   X },
292

    
293
            { B     ,  SQ2*A     ,   0 },
294
            { B +  Z,  SQ2*A -  Y,   X },
295
            { B +  Z,  SQ2*A -  Y,  -X },
296
            { B -  F,  SQ2*A     ,   0 },
297
            { B +2*Z,  SQ2*A -2*Y,   0 },
298
            { B +Z-F,  SQ2*A -  Y,  -X },
299
            { B +Z-F,  SQ2*A -  Y,   X },
300

    
301
            { 0,-SQ2*A,  0 },
302
            {-A,     0,  A },
303
            { A,     0,  A },
304
            {-A,     0, -A },
305
            { A,     0, -A },
306
            { 0, SQ2*A,  0 },
307

    
308
            {    0.50f*F, -SQ2*A +F*SQ2/2, 0          },
309
            {   -0.50f*F, -SQ2*A +F*SQ2/2, 0          },
310
            {-A +0.75f*F,         F*SQ2/4, A -0.25f*F },
311
            {-A +0.25f*F,        -F*SQ2/4, A -0.75f*F },
312
            { A -0.75f*F,         F*SQ2/4, A -0.25f*F },
313
            { A -0.25f*F,        -F*SQ2/4, A -0.75f*F },
314
            {-A +0.75f*F,         F*SQ2/4,-A +0.25f*F },
315
            {-A +0.25f*F,        -F*SQ2/4,-A +0.75f*F },
316
            { A -0.75f*F,         F*SQ2/4,-A +0.25f*F },
317
            { A -0.25f*F,        -F*SQ2/4,-A +0.75f*F },
318
            { 0         ,  SQ2*A -F*SQ2/2,    0.50f*F },
319
            { 0         ,  SQ2*A -F*SQ2/2,   -0.50f*F },
320

    
321
            { 0,  D,  C},
322
            { 0,  D, -C},
323
            {-C, -D,  0},
324
            { C, -D,  0},
325
          };
326
        }
327
      else if( numL==5 )
328
        {
329
        final float A = numL*0.25f;
330
        final float B = numL*0.50f;
331
        final float C = numL*(1.0f/6);
332
        final float D = numL*(SQ2/12);
333
        final float F = JING_F[numL];
334
        final float X = F/2;
335
        final float Y = F*SQ2/2;
336
        final float Z = -F/2;
337

    
338
        mCenters = new float[][]
339
          {
340
            {  0, -SQ2*A     ,  B      },
341
            {  X, -SQ2*A +  Y,  B +  Z },
342
            { -X, -SQ2*A +  Y,  B +  Z },
343
            {  0, -SQ2*A     ,  B -  F },
344
            {  0, -SQ2*A +2*Y,  B +2*Z },
345
            {  X, -SQ2*A +  Y,  B +Z-F },
346
            { -X, -SQ2*A +  Y,  B +Z-F },
347

    
348
            {  0, -SQ2*A     , -B      },
349
            {  X, -SQ2*A +  Y, -B -  Z },
350
            { -X, -SQ2*A +  Y, -B -  Z },
351
            {  0, -SQ2*A     , -B +  F },
352
            {  0, -SQ2*A +2*Y, -B -2*Z },
353
            {  X, -SQ2*A +  Y, -B -Z+F },
354
            { -X, -SQ2*A +  Y, -B -Z+F },
355

    
356
            {-B     ,  SQ2*A     ,   0 },
357
            {-B -  Z,  SQ2*A -  Y,   X },
358
            {-B -  Z,  SQ2*A -  Y,  -X },
359
            {-B +  F,  SQ2*A     ,   0 },
360
            {-B -2*Z,  SQ2*A -2*Y,   0 },
361
            {-B -Z+F,  SQ2*A -  Y,  -X },
362
            {-B -Z+F,  SQ2*A -  Y,   X },
363

    
364
            { B     ,  SQ2*A     ,   0 },
365
            { B +  Z,  SQ2*A -  Y,   X },
366
            { B +  Z,  SQ2*A -  Y,  -X },
367
            { B -  F,  SQ2*A     ,   0 },
368
            { B +2*Z,  SQ2*A -2*Y,   0 },
369
            { B +Z-F,  SQ2*A -  Y,  -X },
370
            { B +Z-F,  SQ2*A -  Y,   X },
371

    
372
            { 2*X, -SQ2*A +2*Y, B+2*Z },
373
            {-2*X, -SQ2*A +2*Y, B+2*Z },
374
            {   0, -SQ2*A     , B-2*F },
375
            { 2*X, -SQ2*A +2*Y,-B-2*Z },
376
            {-2*X, -SQ2*A +2*Y,-B-2*Z },
377
            {   0, -SQ2*A     ,-B+2*F },
378

    
379
            {-B-2*Z, SQ2*A -2*Y,  2*X },
380
            {-B-2*Z, SQ2*A -2*Y, -2*X },
381
            {-B+2*F, SQ2*A     ,    0 },
382
            { B+2*Z, SQ2*A -2*Y,  2*X },
383
            { B+2*Z, SQ2*A -2*Y, -2*X },
384
            { B-2*F, SQ2*A     ,    0 },
385

    
386
            {   X, -SQ2*A+3*Y ,  B+3*Z     },
387
            {-2*X, -SQ2*A+2*Y ,  B-2*F     },
388
            {   X, -SQ2*A+Y   ,  B-2.5f*F  },
389
            { 2*X, -SQ2*A+2*Y , -B+2*F     },
390
            {  -X, -SQ2*A+3*Y , -B-3*Z     },
391
            {  -X, -SQ2*A+Y   , -B+2.5f*F  },
392
            {  -B+   2*F,  SQ2*A-2*Y ,-2*Z },
393
            {  -B+2.5f*F,  SQ2*A-  Y ,   Z },
394
            {  -B+1.5f*F,  SQ2*A-3*Y ,   Z },
395
            {   B-1.5f*F,  SQ2*A-3*Y ,  -Z },
396
            {   B-   2*F,  SQ2*A-2*Y , 2*Z },
397
            {   B-2.5f*F,  SQ2*A-  Y ,  -Z },
398

    
399
            {  -X, -SQ2*A+3*Y ,  B+3*Z     },
400
            { 2*X, -SQ2*A+2*Y ,  B-2*F     },
401
            {  -X, -SQ2*A+Y   ,  B-2.5f*F  },
402
            {-2*X, -SQ2*A+2*Y , -B+2*F     },
403
            {   X, -SQ2*A+3*Y , -B-3*Z     },
404
            {   X, -SQ2*A+Y   , -B+2.5f*F  },
405
            {  -B+   2*F,  SQ2*A-2*Y , 2*Z },
406
            {  -B+2.5f*F,  SQ2*A-  Y ,  -Z },
407
            {  -B+1.5f*F,  SQ2*A-3*Y ,  -Z },
408
            {   B-1.5f*F,  SQ2*A-3*Y ,   Z },
409
            {   B-   2*F,  SQ2*A-2*Y ,-2*Z },
410
            {   B-2.5f*F,  SQ2*A-  Y ,   Z },
411

    
412
            {   0, -SQ2*A+4*Y, B+4*Z }
413
          };
414
        }
415
      }
416

    
417
    return mCenters;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  public Static4D getCubitQuats(int cubit, int[] numLayers)
423
    {
424
    if( mQuatIndex==null )
425
      {
426
      int numL = numLayers[0];
427

    
428
      if( numL==2 )
429
        mQuatIndex = new int[] { 0,10,5,8,
430
                                 0,5,8,6,7,9,
431
                                 0,10,7,3 };
432
      else if( numL==3 )
433
        mQuatIndex = new int[] { 0,10,5,8,
434
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
435
                                 0,3,4, 10,6,7, 11,5,2, 9,8,1
436
                               };
437
      else if( numL==4 )
438
        mQuatIndex = new int[] { 0,0,0,0,0,0,0,10,10,10,10,10,10,10,5,5,5,5,5,5,5,8,8,8,8,8,8,8,
439
                                 0,5,8,6,7,9,
440
                                 0,0,5,5,8,8,6,6,7,7,9,9,
441
                                 0,10,7,3 };
442
      else
443
        mQuatIndex = new int[] { 0,0,0,0,0,0,0,10,10,10,10,10,10,10,5,5,5,5,5,5,5,8,8,8,8,8,8,8,
444
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
445
                                 4,3,0, 7,6,10, 5,11,2, 8,1,9,
446
                                 5,8,10,2,1, 0, 6, 9,3, 7,4,11,
447
                                 0, }; // TODO
448
      }
449

    
450
    return mObjectQuats[mQuatIndex[cubit]];
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

    
455
  private float[][] getVertices(int variant)
456
    {
457
    int[] numLayers = getNumLayers();
458
    int numL = numLayers[0];
459

    
460
    final float F = JING_F[numL];
461
    final float X = F/2;
462
    final float Y = F*SQ2/2;
463
    final float Z =-F/2;
464

    
465
    final float L = (numL-1.5f*numL*F);
466
    final float X2 = L/2;
467
    final float Y2 = L*SQ2/2;
468
    final float Z2 =-L/2;
469
    final float D = F/L;
470
    final float G1 = 0.5f*numL -(numL/2)*F;
471
    final float G2 = G1 - F/2;
472
    final float X3 = G2/2;
473
    final float Y3 = G2*SQ2/2;
474
    final float Z3 =-G2/2;
475
    final float G3 = G1 - F;
476
    final float X4 = G3/2;
477
    final float Y4 = G3*SQ2/2;
478
    final float Z4 =-G3/2;
479
    final float K  = 0.2f*(1 - F/(2*G2));
480

    
481
    if( variant==0 )
482
      {
483
      return new float[][]
484
        {
485
            { 0,   0,     0},
486
            { X,   Y,   Z  },
487
            { 0, 2*Y, 2*Z  },
488
            {-X,   Y,   Z  },
489
            { 0,   0,    -F},
490
            { X,   Y,   Z-F},
491
            { 0, 2*Y, 2*Z-F},
492
            {-X,   Y,   Z-F},
493
        };
494
      }
495
    else if( variant==1 && (numL==2 || numL==4) )
496
      {
497
      return new float[][]
498
        {
499
            { 0,   0,     G1 },
500
            { X,   Y,   Z+G1 },
501
            { 0, 2*Y, 2*Z+G1 },
502
            {-X,   Y,   Z+G1 },
503
            { 0,   0,    -G1 },
504
            { X,   Y,  -Z-G1 },
505
            { 0, 2*Y,-2*Z-G1 },
506
            {-X,   Y,  -Z-G1 },
507
        };
508
      }
509
    else if( variant==1 && (numL==3 || numL==5) )
510
      {
511
      return new float[][]
512
        {
513
            { 0,   0,   0 },
514
            { X,   Y,   Z },
515
            { 0, 2*Y, 2*Z },
516
            {-X,   Y,   Z },
517
            { 0,   0, -G1 },
518
            { X,   Y, -G1 },
519
            {-X,   Y, -G1 },
520
        };
521
      }
522
    else if( variant==2 && numL==4 )
523
      {
524
      return new float[][]
525
        {
526
            { 0,   0,     G2},
527
            { X,   Y,   Z+G2},
528
            { 0, 2*Y, 2*Z+G2},
529
            {-X,   Y,   Z+G2},
530
            { 0,   0,    -G2},
531
            { X,   Y,  -Z-G2},
532
            { 0, 2*Y,-2*Z-G2},
533
            {-X,   Y,  -Z-G2},
534
        };
535
      }
536
    else if( variant==2 && numL==5 )
537
      {
538
      return new float[][]
539
        {
540
            { 0,   0,   0 },
541
            { X,   Y,   Z },
542
            { 0, 2*Y, 2*Z },
543
            {-X,   Y,   Z },
544
            { 0,   0, -G2 },
545
            { X,   Y, -G2 },
546
            {-X,   Y, -G2 },
547
        };
548
      }
549
    else if( variant==3 && numL==5 )
550
      {
551
      return new float[][]
552
        {
553
            { 0,   0,   0 },
554
            {-X,   Y,  -Z },
555
            { 0, 2*Y,-2*Z },
556
            { X,   Y,  -Z },
557
            { 0,   0,  G2 },
558
            {-X,   Y,  G2 },
559
            { X,   Y,  G2 },
560
        };
561
      }
562
    else if( variant==2 && numL==3 )
563
      {
564
      return new float[][]
565
        {
566
            {  0,    0,    0 },
567
            { X3,   Y3,   Z3 },
568
            {  0, (2*SQ2/3)*G2, (-2.0f/3)*G2 },
569
            {-X3,   Y3,   Z3 },
570
            {  0,    0,  -G2 },
571
            { K*X3,   K*Y3,  K*Z3-G2 },
572
            {  0, K*(2*SQ2/3)*G2, K*(-2.0f/3)*G2 - G2 },
573
            {-K*X3,   K*Y3,  K*Z3-G2 },
574
        };
575
      }
576
    else if( variant==4 && numL==5 )
577
      {
578
      return new float[][]
579
        {
580
            {  0,    0,    0 },
581
            { X4,   Y4,   Z4 },
582
            {  0, (2*SQ2/3)*G3, (-2.0f/3)*G3 },
583
            {-X4,   Y4,   Z4 },
584
            {  0,    0,  -G3 },
585
            { K*X4,   K*Y4,  K*Z4-G3 },
586
            {  0, K*(2*SQ2/3)*G3, K*(-2.0f/3)*G3 - G3 },
587
            {-K*X4,   K*Y4,  K*Z4-G3 },
588
        };
589
      }
590
    else
591
      {
592
      return new float[][]
593
        {
594
            {  0     , -2*Y2/3     , -2*Z2/3       },
595
            { X2     ,    Y2/3     ,    Z2/3       },
596
            {-X2     ,    Y2/3     ,    Z2/3       },
597
            {  0     , -2*Y2/3     , -2*Z2/3+2*D*Z2},
598
            { X2-D*X2,    Y2/3-D*Y2,    Z2/3+  D*Z2},
599
            {-X2+D*X2,    Y2/3-D*Y2,    Z2/3+  D*Z2},
600
        };
601
      }
602
    }
603

    
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605

    
606
  public ObjectShape getObjectShape(int variant)
607
    {
608
    int[] numLayers = getNumLayers();
609
    int numL = numLayers[0];
610

    
611
    if( variant==0 )
612
      {
613
      int[][] indices =
614
          {
615
             {0,1,2,3},
616
             {1,0,4,5},
617
             {7,4,0,3},
618
             {1,5,6,2},
619
             {7,3,2,6},
620
             {4,7,6,5}
621
          };
622

    
623
      return new ObjectShape(getVertices(variant), indices);
624
      }
625
    else if( (variant==1 && (numL==2 || numL==4)) || (variant==2 && numL==4)  )
626
      {
627
      int[][] indices =
628
          {
629
             {0,4,5,1},
630
             {3,7,4,0},
631
             {0,1,2,3},
632
             {4,7,6,5},
633
             {1,5,6,2},
634
             {2,6,7,3}
635
          };
636

    
637
      return new ObjectShape(getVertices(variant), indices);
638
      }
639
    else if( (variant==2 && numL==3) || (variant==4 && numL==5) )
640
      {
641
      int[][] indices =
642
          {
643
             {0,1,2,3},
644
             {0,4,5,1},
645
             {3,7,4,0},
646
             {4,7,6,5},
647
             {1,5,6,2},
648
             {2,6,7,3}
649
          };
650

    
651
      return new ObjectShape(getVertices(variant), indices);
652
      }
653
    else if( (variant==1 && (numL==3 || numL==5)) || ((variant==2 || variant==3) && numL==5) )
654
      {
655
      int[][] indices =
656
          {
657
             {0,4,5,1},
658
             {3,6,4,0},
659
             {0,1,2,3},
660
             {1,5,2},
661
             {2,6,3},
662
             {4,2,5},
663
             {4,6,2}
664
          };
665

    
666
      return new ObjectShape(getVertices(variant), indices);
667
      }
668
    else
669
      {
670
      int[][] indices =
671
          {
672
             {0,1,2},
673
             {3,5,4},
674
             {0,3,4,1},
675
             {5,3,0,2},
676
             {4,5,2,1}
677
          };
678

    
679
      return new ObjectShape(getVertices(variant), indices);
680
      }
681
    }
682

    
683
///////////////////////////////////////////////////////////////////////////////////////////////////
684

    
685
  public ObjectFaceShape getObjectFaceShape(int variant)
686
    {
687
    int[] numLayers = getNumLayers();
688
    int numL = numLayers[0];
689
    float R = 0.3f;
690
    float S = 0.5f;
691
    float H = 0.015f;
692

    
693
    if( variant==0 )
694
      {
695
      int I = numL<5 ? 1:0;
696
      int V = numL<5 ? 1:0;
697
      float height = isInIconMode() ? 0.001f : H;
698
      float[][] bands = { {height,35,R,S,5,I,V},{0.001f,1,R,S,5,I,V} };
699
      int[] indices   = { 0,0,0,1,1,1 };
700
      return new ObjectFaceShape(bands,indices,null);
701
      }
702
    else if( variant==1 && (numL==2 || numL==4) )
703
      {
704
      int N1 = numL==2 ? 9:7;
705
      int N2 = numL==2 ? 9:4;
706
      float height = isInIconMode() ? 0.001f : H;
707
      float[][] bands = { {height,35,R,S,N1,0,0},{0.001f,1,R,S,N2,0,0} };
708
      int[] indices   = { 0,0,1,1,1,1 };
709
      return new ObjectFaceShape(bands,indices,null);
710
      }
711
    else if( variant==1 && (numL==3 || numL==5) )
712
      {
713
      int N = numL==3 ? 7:6;
714
      float height = isInIconMode() ? 0.001f : H;
715
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
716
      int[] indices   = { 0,0,1,1,1,1,1 };
717
      return new ObjectFaceShape(bands,indices,null);
718
      }
719
    else if( (variant==2 || variant==3) && numL==5 )
720
      {
721
      int N = 5;
722
      float height = isInIconMode() ? 0.001f : H;
723
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
724
      int[] indices   = { 0,1,1,1,1,1,1 };
725
      return new ObjectFaceShape(bands,indices,null);
726
      }
727
    else if( variant==2 && numL==4 )
728
      {
729
      float height = isInIconMode() ? 0.001f : H;
730
      float[][] bands = { {height,35,R,S,6,0,0},{0.001f,1,R,S,4,0,0} };
731
      int[] indices   = { 0,1,1,1,1,1 };
732
      return new ObjectFaceShape(bands,indices,null);
733
      }
734
    else
735
      {
736
      int N = numL==2 ? 5:4;
737
      float height = isInIconMode() ? 0.001f : H;
738
      float[][] bands = { {height,35,R,S,N,0,0}, {0.001f,1,R,S,N,0,0} };
739
      int[] indices   = { 0,1,1,1,1,1 };
740
      return new ObjectFaceShape(bands,indices,null);
741
      }
742
    }
743

    
744
///////////////////////////////////////////////////////////////////////////////////////////////////
745

    
746
  public ObjectVertexEffects getVertexEffects(int variant)
747
    {
748
    int[] numLayers = getNumLayers();
749
    int numL = numLayers[0];
750
    final float F = JING_F[numL];
751
    final float Y = F*SQ2/2;
752
    final float Z =-F/2;
753

    
754
    if( variant==0 )
755
      {
756
      float[][] corners   = { {0.08f,0.10f},{0.04f,0.10f} };
757
      int[] cornerIndices = { 0,1,1,1,1,-1,-1,-1 };
758
      float[][] centers   = { { 0.0f, Y, Z-F/2} };
759
      int[] centerIndices = { 0,0,0,0,0,-1,-1,-1 };
760
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
761
      }
762
    else if( variant==1 )
763
      {
764
      float[][] corners   = { { 0.05f,0.10f} };
765
      int[] cornerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
766
      float[][] centers   = { { 0, F*SQ2/2, 0 } };
767
      int[] centerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
768
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
769
      }
770
    else return null;
771
    }
772

    
773
///////////////////////////////////////////////////////////////////////////////////////////////////
774

    
775
  public int getNumCubitVariants(int[] numLayers)
776
    {
777
    return numLayers[0] < 4 ? 3: (numLayers[0] < 5 ? 4 : 5);
778
    }
779

    
780
///////////////////////////////////////////////////////////////////////////////////////////////////
781

    
782
  public int getCubitVariant(int cubit, int[] numLayers)
783
    {
784
    switch( numLayers[0] )
785
      {
786
      case  2: return cubit< 4 ? 0 : (cubit<10 ? 1:2);
787
      case  3: return cubit< 4 ? 0 : (cubit<16 ? 1:2);
788
      case  4: return cubit<28 ? 0 : (cubit<34 ? 1 : (cubit<46 ? 2:3) );
789
      default: return cubit<28 ? 0 : (cubit<40 ? 1 : (cubit<52 ? 2: (cubit<64 ? 3:4)) );
790
      }
791
    }
792

    
793
///////////////////////////////////////////////////////////////////////////////////////////////////
794

    
795
  public float getStickerRadius()
796
    {
797
    int[] numLayers = getNumLayers();
798

    
799
    switch( numLayers[0] )
800
      {
801
      case  2: return 0.05f;
802
      case  3: return 0.06f;
803
      case  4: return 0.08f;
804
      default: return 0.10f;
805
      }
806
    }
807

    
808
///////////////////////////////////////////////////////////////////////////////////////////////////
809

    
810
  public float getStickerStroke()
811
    {
812
    boolean icon = isInIconMode();
813
    int[] numLayers = getNumLayers();
814

    
815
    switch( numLayers[0] )
816
      {
817
      case  2: return icon ? 0.10f : 0.05f;
818
      case  3: return icon ? 0.14f : 0.07f;
819
      case  4: return icon ? 0.16f : 0.08f;
820
      default: return icon ? 0.20f : 0.10f;
821
      }
822
    }
823

    
824
///////////////////////////////////////////////////////////////////////////////////////////////////
825

    
826
  public float[][][] getStickerAngles()
827
    {
828
    return null;
829
    }
830

    
831
///////////////////////////////////////////////////////////////////////////////////////////////////
832
// PUBLIC API
833

    
834
  public Static3D[] getRotationAxis()
835
    {
836
    return ROT_AXIS;
837
    }
838

    
839
///////////////////////////////////////////////////////////////////////////////////////////////////
840

    
841
  public int[][] getBasicAngles()
842
    {
843
    if( mBasicAngle ==null )
844
      {
845
      int num = getNumLayers()[0];
846
      int[] tmp = new int[num];
847
      for(int i=0; i<num; i++) tmp[i] = 3;
848
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
849
      }
850

    
851
    return mBasicAngle;
852
    }
853

    
854
///////////////////////////////////////////////////////////////////////////////////////////////////
855

    
856
  public String getShortName()
857
    {
858
    int[] numLayers = getNumLayers();
859

    
860
    switch( numLayers[0] )
861
      {
862
      case  2: return ObjectType.JING_2.name();
863
      case  3: return ObjectType.JING_3.name();
864
      case  4: return ObjectType.JING_4.name();
865
      default: return ObjectType.JING_5.name();
866
      }
867
    }
868

    
869
///////////////////////////////////////////////////////////////////////////////////////////////////
870

    
871
  public ObjectSignature getSignature()
872
    {
873
    int[] numLayers = getNumLayers();
874
    int sig;
875

    
876
    switch( numLayers[0] )
877
      {
878
      case  2: sig = ObjectSignatures.JING_2; break;
879
      case  3: sig = ObjectSignatures.JING_3; break;
880
      case  4: sig = ObjectSignatures.JING_4; break;
881
      default: sig = ObjectSignatures.JING_5; break;
882
      }
883

    
884
    return new ObjectSignature(sig);
885
    }
886

    
887
///////////////////////////////////////////////////////////////////////////////////////////////////
888

    
889
  public String getObjectName()
890
    {
891
    int[] numLayers = getNumLayers();
892

    
893
    switch( numLayers[0] )
894
      {
895
      case  2: return "Jing Pyraminx";
896
      case  3: return "4x4 Pyramid";
897
      case  4: return "5x5 Pyramid";
898
      default: return "6x6 Pyramid";
899
      }
900
    }
901

    
902
///////////////////////////////////////////////////////////////////////////////////////////////////
903

    
904
  public String getInventor()
905
    {
906
    int[] numLayers = getNumLayers();
907
    return numLayers[0]==2 ? "Tony Fisher" : "Unknown";
908
    }
909

    
910
///////////////////////////////////////////////////////////////////////////////////////////////////
911

    
912
  public int getYearOfInvention()
913
    {
914
    int[] numLayers = getNumLayers();
915
    return numLayers[0]==2 ? 1991 : 0;
916
    }
917

    
918
///////////////////////////////////////////////////////////////////////////////////////////////////
919

    
920
  public int getComplexity()
921
    {
922
    int[] numLayers = getNumLayers();
923

    
924
    switch( numLayers[0] )
925
      {
926
      case  2: return 1;
927
      case  3: return 2;
928
      case  4: return 3;
929
      default: return 4;
930
      }
931
    }
932

    
933
///////////////////////////////////////////////////////////////////////////////////////////////////
934

    
935
  public String[][] getTutorials()
936
    {
937
    int[] numLayers = getNumLayers();
938

    
939
    if( numLayers[0]==2 )
940
      return new String[][]{
941
                          {"gb","0T8Iw6aI2gA","Jing's Pyraminx Tutorial","SuperAntoniovivaldi"},
942
                          {"es","Na27_GUIzqY","Resolver Jing Pyraminx","Cuby"},
943
                          {"ru","rlQXFzjsyAo","Как собрать Jing's pyraminx","Илья Топор-Гилка"},
944
                          {"fr","zC9dGqZRSic","Résolution du Jing's Pyraminx","Asthalis"},
945
                          {"de","6ihN4fdHH6o","Jings Pyraminx - Tutorial","GerCubing"},
946
                          {"pl","nRYoJAy1c_8","Jing's Pyraminx TUTORIAL PL","MrUK"},
947
                          {"vn","yX9KjDpHjws","Tutorial N.50 - Jing's Pyraminx","Duy Thích Rubik"},
948
                         };
949
    else
950
      return null;
951
    }
952
}
(22-22/48)