Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyJing.java @ 0faf25f3

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 = (numL==3 ? 0.85f : 0.76f);
72
      int index = (numL==3 ? 3 : 5);
73

    
74
      mStickerCoords[index][0][2][0] *= CENTER_CORR;
75
      mStickerCoords[index][0][2][1] *= CENTER_CORR;
76
      }
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

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

    
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91

    
92
  @Override
93
  public float getPillowCoeff()
94
    {
95
    return 1.25f;
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  public int[][] getScrambleEdges()
101
    {
102
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
103
    return mEdges;
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

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

    
116
      switch( numL )
117
        {
118
        case 2: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3) };
119
                break;
120
        case 3: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), numL*SQ6/18 };
121
                break;
122
        case 4: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), (2*F-numL*0.25f-0.01f)*(SQ6/3) };
123
                break;
124
        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 };
125
                break;
126
        }
127

    
128
      mCuts = new float[][] { cut,cut,cut,cut };
129
      }
130

    
131
    return mCuts;
132
    }
133

    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

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

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

    
146
  public int getTouchControlType()
147
    {
148
    return TC_TETRAHEDRON;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  public int getTouchControlSplit()
154
    {
155
    return TYPE_NOT_SPLIT;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  public int[][][] getEnabled()
161
    {
162
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  public float[] getDist3D(int[] numLayers)
168
    {
169
    return TouchControlTetrahedron.D3D;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  public Static3D[] getFaceAxis()
175
    {
176
    return TouchControlTetrahedron.FACE_AXIS;
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  public float[][] getCubitPositions(int[] numLayers)
182
    {
183
    if( mCenters==null )
184
      {
185
      int numL = numLayers[0];
186

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

    
196
            { 0.000f, -SQ2/2,  0.000f },
197
            {-0.500f, 0.000f,  0.500f },
198
            { 0.500f, 0.000f,  0.500f },
199
            {-0.500f, 0.000f, -0.500f },
200
            { 0.500f, 0.000f, -0.500f },
201
            { 0.000f,  SQ2/2,  0.000f },
202

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

    
218
        mCenters = new float[][]
219
          {
220
            {   0, -SQ2*A,  B },
221
            {   0, -SQ2*A, -B },
222
            {  -B,  SQ2*A,  0 },
223
            {   B,  SQ2*A,  0 },
224

    
225
            {   X, -SQ2*A +Y, B+Z },
226
            {  -X, -SQ2*A +Y, B+Z },
227
            {   0, -SQ2*A   , B-F },
228
            {   X, -SQ2*A +Y,-B-Z },
229
            {  -X, -SQ2*A +Y,-B-Z },
230
            {   0, -SQ2*A   ,-B+F },
231

    
232
            {-B-Z,  SQ2*A -Y,   X },
233
            {-B-Z,  SQ2*A -Y,  -X },
234
            {-B+F,  SQ2*A   ,   0 },
235
            { B+Z,  SQ2*A -Y,   X },
236
            { B+Z,  SQ2*A -Y,  -X },
237
            { B-F,  SQ2*A   ,   0 },
238

    
239
            {      0, -SQ2*A +2*Y,  B +2*Z },
240
            {      X, -SQ2*A +  Y,  B +Z-F },
241
            {     -X, -SQ2*A +  Y,  B +Z-F },
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
            {-B -2*Z,  SQ2*A -2*Y,       0 },
246
            {-B -Z+F,  SQ2*A -  Y,      -X },
247
            {-B -Z+F,  SQ2*A -  Y,       X },
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
          };
252
        }
253
      else if( numL==4 )
254
        {
255
        final float A = numL*0.25f;
256
        final float B = numL*0.50f;
257
        final float C = numL*(1.0f/6);
258
        final float D = numL*(SQ2/12);
259
        final float F = JING_F[numL];
260
        final float X = F/2;
261
        final float Y = F*SQ2/2;
262
        final float Z = -F/2;
263

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

    
274
            {  0, -SQ2*A     , -B      },
275
            {  X, -SQ2*A +  Y, -B -  Z },
276
            { -X, -SQ2*A +  Y, -B -  Z },
277
            {  0, -SQ2*A     , -B +  F },
278
            {  0, -SQ2*A +2*Y, -B -2*Z },
279
            {  X, -SQ2*A +  Y, -B -Z+F },
280
            { -X, -SQ2*A +  Y, -B -Z+F },
281

    
282
            {-B     ,  SQ2*A     ,   0 },
283
            {-B -  Z,  SQ2*A -  Y,   X },
284
            {-B -  Z,  SQ2*A -  Y,  -X },
285
            {-B +  F,  SQ2*A     ,   0 },
286
            {-B -2*Z,  SQ2*A -2*Y,   0 },
287
            {-B -Z+F,  SQ2*A -  Y,  -X },
288
            {-B -Z+F,  SQ2*A -  Y,   X },
289

    
290
            { B     ,  SQ2*A     ,   0 },
291
            { B +  Z,  SQ2*A -  Y,   X },
292
            { B +  Z,  SQ2*A -  Y,  -X },
293
            { B -  F,  SQ2*A     ,   0 },
294
            { B +2*Z,  SQ2*A -2*Y,   0 },
295
            { B +Z-F,  SQ2*A -  Y,  -X },
296
            { B +Z-F,  SQ2*A -  Y,   X },
297

    
298
            { 0,-SQ2*A,  0 },
299
            {-A,     0,  A },
300
            { A,     0,  A },
301
            {-A,     0, -A },
302
            { A,     0, -A },
303
            { 0, SQ2*A,  0 },
304

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

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

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

    
345
            {  0, -SQ2*A     , -B      },
346
            {  X, -SQ2*A +  Y, -B -  Z },
347
            { -X, -SQ2*A +  Y, -B -  Z },
348
            {  0, -SQ2*A     , -B +  F },
349
            {  0, -SQ2*A +2*Y, -B -2*Z },
350
            {  X, -SQ2*A +  Y, -B -Z+F },
351
            { -X, -SQ2*A +  Y, -B -Z+F },
352

    
353
            {-B     ,  SQ2*A     ,   0 },
354
            {-B -  Z,  SQ2*A -  Y,   X },
355
            {-B -  Z,  SQ2*A -  Y,  -X },
356
            {-B +  F,  SQ2*A     ,   0 },
357
            {-B -2*Z,  SQ2*A -2*Y,   0 },
358
            {-B -Z+F,  SQ2*A -  Y,  -X },
359
            {-B -Z+F,  SQ2*A -  Y,   X },
360

    
361
            { B     ,  SQ2*A     ,   0 },
362
            { B +  Z,  SQ2*A -  Y,   X },
363
            { B +  Z,  SQ2*A -  Y,  -X },
364
            { B -  F,  SQ2*A     ,   0 },
365
            { B +2*Z,  SQ2*A -2*Y,   0 },
366
            { B +Z-F,  SQ2*A -  Y,  -X },
367
            { B +Z-F,  SQ2*A -  Y,   X },
368

    
369
            { 2*X, -SQ2*A +2*Y, B+2*Z },
370
            {-2*X, -SQ2*A +2*Y, B+2*Z },
371
            {   0, -SQ2*A     , B-2*F },
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

    
376
            {-B-2*Z, SQ2*A -2*Y,  2*X },
377
            {-B-2*Z, SQ2*A -2*Y, -2*X },
378
            {-B+2*F, SQ2*A     ,    0 },
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

    
383
            {   X, -SQ2*A+3*Y ,  B+3*Z     },
384
            {-2*X, -SQ2*A+2*Y ,  B+4*Z     },
385
            {   X, -SQ2*A+Y   ,  B+5*Z     },
386
            { 2*X, -SQ2*A+2*Y , -B-4*Z     },
387
            {  -X, -SQ2*A+3*Y , -B-3*Z     },
388
            {  -X, -SQ2*A+Y   , -B-5f*Z    },
389
            {  -B+   2*F,  SQ2*A-2*Y ,-2*Z },
390
            {  -B+2.5f*F,  SQ2*A-  Y ,   Z },
391
            {  -B+1.5f*F,  SQ2*A-3*Y ,   Z },
392
            {   B-1.5f*F,  SQ2*A-3*Y ,  -Z },
393
            {   B-   2*F,  SQ2*A-2*Y , 2*Z },
394
            {   B-2.5f*F,  SQ2*A-  Y ,  -Z },
395

    
396
            {  -X, -SQ2*A+3*Y ,  B+3*Z     },
397
            { 2*X, -SQ2*A+2*Y ,  B+4*Z     },
398
            {  -X, -SQ2*A+Y   ,  B+5*Z     },
399
            {-2*X, -SQ2*A+2*Y , -B-4*Z     },
400
            {   X, -SQ2*A+3*Y , -B-3*Z     },
401
            {   X, -SQ2*A+Y   , -B-5*Z     },
402
            {  -B+   2*F,  SQ2*A-2*Y , 2*Z },
403
            {  -B+2.5f*F,  SQ2*A-  Y ,  -Z },
404
            {  -B+1.5f*F,  SQ2*A-3*Y ,  -Z },
405
            {   B-1.5f*F,  SQ2*A-3*Y ,   Z },
406
            {   B-   2*F,  SQ2*A-2*Y ,-2*Z },
407
            {   B-2.5f*F,  SQ2*A-  Y ,   Z },
408

    
409
            {   0, -SQ2*A+4*Y, B+4*Z },
410
            { 2*X, -SQ2*A+2*Y, B+6*Z },
411
            {-2*X, -SQ2*A+2*Y, B+6*Z },
412
            {   0, -SQ2*A+4*Y,-B-4*Z },
413
            { 2*X, -SQ2*A+2*Y,-B-6*Z },
414
            {-2*X, -SQ2*A+2*Y,-B-6*Z },
415
            { -B-4*Z, SQ2*A-4*Y,   0 },
416
            { -B-6*Z, SQ2*A-2*Y, 2*X },
417
            { -B-6*Z, SQ2*A-2*Y,-2*X },
418
            {  B+4*Z, SQ2*A-4*Y,   0 },
419
            {  B+6*Z, SQ2*A-2*Y, 2*X },
420
            {  B+6*Z, SQ2*A-2*Y,-2*X },
421
          };
422
        }
423
      }
424

    
425
    return mCenters;
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  public Static4D getCubitQuats(int cubit, int[] numLayers)
431
    {
432
    if( mQuatIndex==null )
433
      {
434
      int numL = numLayers[0];
435

    
436
      if( numL==2 )
437
        mQuatIndex = new int[] { 0,10,5,8,
438
                                 0,5,8,6,7,9,
439
                                 0,10,7,3 };
440
      else if( numL==3 )
441
        mQuatIndex = new int[] { 0,10,5,8,
442
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
443
                                 0,3,4, 10,6,7, 11,5,2, 9,8,1
444
                               };
445
      else if( numL==4 )
446
        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,
447
                                 0,5,8,6,7,9,
448
                                 0,0,5,5,8,8,6,6,7,7,9,9,
449
                                 0,10,7,3 };
450
      else
451
        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,
452
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
453
                                 4,3,0, 7,6,10, 5,11,2, 8,1,9,
454
                                 5,8,10,2,1,0,  6,9,3,  7,4,11,
455
                                 0,3,4, 10,6,7, 11,2,5, 9,1,8 };
456
      }
457

    
458
    return mObjectQuats[mQuatIndex[cubit]];
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

    
463
  private float[][] getVertices(int variant)
464
    {
465
    int[] numLayers = getNumLayers();
466
    int numL = numLayers[0];
467

    
468
    final float F = JING_F[numL];
469
    final float X = F/2;
470
    final float Y = F*SQ2/2;
471
    final float Z =-F/2;
472

    
473
    final float L = (numL-1.5f*numL*F);
474
    final float X2 = L/2;
475
    final float Y2 = L*SQ2/2;
476
    final float Z2 =-L/2;
477
    final float D = F/L;
478
    final float G1 = 0.5f*numL -(numL/2)*F;
479
    final float G2 = G1 - F/2;
480
    final float X3 = G2/2;
481
    final float Y3 = G2*SQ2/2;
482
    final float Z3 =-G2/2;
483
    final float G3 = G1 - F;
484
    final float X4 = G3/2;
485
    final float Y4 = G3*SQ2/2;
486
    final float Z4 =-G3/2;
487
    final float K  = 0.2f*(1 - F/(2*G2));
488

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

    
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

    
610
  public ObjectShape getObjectShape(int variant)
611
    {
612
    int[] numLayers = getNumLayers();
613
    int numL = numLayers[0];
614

    
615
    if( variant==0 )
616
      {
617
      int[][] indices =
618
          {
619
             {0,1,2,3},
620
             {1,0,4,5},
621
             {7,4,0,3},
622
             {1,5,6,2},
623
             {7,3,2,6},
624
             {4,7,6,5}
625
          };
626

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

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

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

    
670
      return new ObjectShape(getVertices(variant), indices);
671
      }
672
    else if( variant==2 && numL==5 )
673
      {
674
      int[][] indices =
675
          {
676
             {0,3,4,1},
677
             {2,3,0},
678
             {0,1,2},
679
             {4,3,2},
680
             {1,4,2}
681
          };
682

    
683
      return new ObjectShape(getVertices(variant), indices);
684
      }
685
    else if( variant==3 && numL==5 )
686
      {
687
      int[][] indices =
688
          {
689
             {0,2,4,3},
690
             {3,1,0},
691
             {0,1,2},
692
             {3,4,1},
693
             {1,4,2}
694
          };
695

    
696
      return new ObjectShape(getVertices(variant), indices);
697
      }
698
    else
699
      {
700
      int[][] indices =
701
          {
702
             {0,1,2},
703
             {3,5,4},
704
             {0,3,4,1},
705
             {5,3,0,2},
706
             {4,5,2,1}
707
          };
708

    
709
      return new ObjectShape(getVertices(variant), indices);
710
      }
711
    }
712

    
713
///////////////////////////////////////////////////////////////////////////////////////////////////
714

    
715
  public ObjectFaceShape getObjectFaceShape(int variant)
716
    {
717
    int[] numLayers = getNumLayers();
718
    int numL = numLayers[0];
719
    float R = 0.3f;
720
    float S = 0.5f;
721
    float H = 0.015f;
722

    
723
    if( variant==0 )
724
      {
725
      int I = numL<5 ? 1:0;
726
      int V = numL<5 ? 1:0;
727
      float height = isInIconMode() ? 0.001f : H;
728
      float[][] bands = { {height,35,R,S,5,I,V},{0.001f,1,R,S,5,I,V} };
729
      int[] indices   = { 0,0,0,1,1,1 };
730
      return new ObjectFaceShape(bands,indices,null);
731
      }
732
    else if( variant==1 && (numL==2 || numL==4) )
733
      {
734
      int N1 = numL==2 ? 9:7;
735
      int N2 = numL==2 ? 9:4;
736
      float height = isInIconMode() ? 0.001f : H;
737
      float[][] bands = { {height,35,R,S,N1,0,0},{0.001f,1,R,S,N2,0,0} };
738
      int[] indices   = { 0,0,1,1,1,1 };
739
      return new ObjectFaceShape(bands,indices,null);
740
      }
741
    else if( variant==1 && (numL==3 || numL==5) )
742
      {
743
      int N = numL==3 ? 7:5;
744
      float height = isInIconMode() ? 0.001f : H;
745
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
746
      int[] indices   = { 0,0,1,1,1,1,1 };
747
      return new ObjectFaceShape(bands,indices,null);
748
      }
749
    else if( (variant==2 || variant==3) && numL==5 )
750
      {
751
      int N = 5;
752
      float height = isInIconMode() ? 0.001f : H;
753
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
754
      int[] indices   = { 0,1,1,1,1,1,1 };
755
      return new ObjectFaceShape(bands,indices,null);
756
      }
757
    else if( variant==2 && numL==4 )
758
      {
759
      float height = isInIconMode() ? 0.001f : H;
760
      float[][] bands = { {height,35,R,S,6,0,0},{0.001f,1,R,S,4,0,0} };
761
      int[] indices   = { 0,1,1,1,1,1 };
762
      return new ObjectFaceShape(bands,indices,null);
763
      }
764
    else
765
      {
766
      int N = numL==2 ? 5: (numL<4 ? 4:2);
767
      float height = isInIconMode() ? 0.001f : H;
768
      float[][] bands = { {height,35,R,S,N,0,0}, {0.001f,1,R,S,N,0,0} };
769
      int[] indices   = { 0,1,1,1,1,1 };
770
      return new ObjectFaceShape(bands,indices,null);
771
      }
772
    }
773

    
774
///////////////////////////////////////////////////////////////////////////////////////////////////
775

    
776
  public ObjectVertexEffects getVertexEffects(int variant)
777
    {
778
    int[] numLayers = getNumLayers();
779
    int numL = numLayers[0];
780
    final float F = JING_F[numL];
781
    final float Y = F*SQ2/2;
782
    final float Z =-F/2;
783

    
784
    if( variant==0 )
785
      {
786
      float[][] corners   = { {0.08f,0.10f},{0.04f,0.10f} };
787
      int[] cornerIndices = { 0,1,1,1,1,-1,-1,-1 };
788
      float[][] centers   = { { 0.0f, Y, Z-F/2} };
789
      int[] centerIndices = { 0,0,0,0,0,-1,-1,-1 };
790
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
791
      }
792
    else if( variant==1 )
793
      {
794
      float[][] corners   = { { 0.05f,0.10f} };
795
      int[] cornerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
796
      float[][] centers   = { { 0, F*SQ2/2, 0 } };
797
      int[] centerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
798
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
799
      }
800
    else return null;
801
    }
802

    
803
///////////////////////////////////////////////////////////////////////////////////////////////////
804

    
805
  public int getNumCubitVariants(int[] numLayers)
806
    {
807
    return numLayers[0] < 4 ? 3: (numLayers[0] < 5 ? 4 : 5);
808
    }
809

    
810
///////////////////////////////////////////////////////////////////////////////////////////////////
811

    
812
  public int getCubitVariant(int cubit, int[] numLayers)
813
    {
814
    switch( numLayers[0] )
815
      {
816
      case  2: return cubit< 4 ? 0 : (cubit<10 ? 1:2);
817
      case  3: return cubit< 4 ? 0 : (cubit<16 ? 1:2);
818
      case  4: return cubit<28 ? 0 : (cubit<34 ? 1 : (cubit<46 ? 2:3) );
819
      default: return cubit<28 ? 0 : (cubit<40 ? 1 : (cubit<52 ? 2: (cubit<64 ? 3:4)) );
820
      }
821
    }
822

    
823
///////////////////////////////////////////////////////////////////////////////////////////////////
824

    
825
  public float getStickerRadius()
826
    {
827
    int[] numLayers = getNumLayers();
828

    
829
    switch( numLayers[0] )
830
      {
831
      case  2: return 0.05f;
832
      case  3: return 0.06f;
833
      case  4: return 0.08f;
834
      default: return 0.10f;
835
      }
836
    }
837

    
838
///////////////////////////////////////////////////////////////////////////////////////////////////
839

    
840
  public float getStickerStroke()
841
    {
842
    boolean icon = isInIconMode();
843
    int[] numLayers = getNumLayers();
844

    
845
    switch( numLayers[0] )
846
      {
847
      case  2: return icon ? 0.10f : 0.05f;
848
      case  3: return icon ? 0.14f : 0.07f;
849
      case  4: return icon ? 0.16f : 0.08f;
850
      default: return icon ? 0.20f : 0.10f;
851
      }
852
    }
853

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

    
856
  public float[][][] getStickerAngles()
857
    {
858
    return null;
859
    }
860

    
861
///////////////////////////////////////////////////////////////////////////////////////////////////
862
// PUBLIC API
863

    
864
  public Static3D[] getRotationAxis()
865
    {
866
    return ROT_AXIS;
867
    }
868

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

    
871
  public int[][] getBasicAngles()
872
    {
873
    if( mBasicAngle ==null )
874
      {
875
      int num = getNumLayers()[0];
876
      int[] tmp = new int[num];
877
      for(int i=0; i<num; i++) tmp[i] = 3;
878
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
879
      }
880

    
881
    return mBasicAngle;
882
    }
883

    
884
///////////////////////////////////////////////////////////////////////////////////////////////////
885

    
886
  public String getShortName()
887
    {
888
    int[] numLayers = getNumLayers();
889

    
890
    switch( numLayers[0] )
891
      {
892
      case  2: return ObjectType.JING_2.name();
893
      case  3: return ObjectType.JING_3.name();
894
      case  4: return ObjectType.JING_4.name();
895
      default: return ObjectType.JING_5.name();
896
      }
897
    }
898

    
899
///////////////////////////////////////////////////////////////////////////////////////////////////
900

    
901
  public ObjectSignature getSignature()
902
    {
903
    int[] numLayers = getNumLayers();
904
    int sig;
905

    
906
    switch( numLayers[0] )
907
      {
908
      case  2: sig = ObjectSignatures.JING_2; break;
909
      case  3: sig = ObjectSignatures.JING_3; break;
910
      case  4: sig = ObjectSignatures.JING_4; break;
911
      default: sig = ObjectSignatures.JING_5; break;
912
      }
913

    
914
    return new ObjectSignature(sig);
915
    }
916

    
917
///////////////////////////////////////////////////////////////////////////////////////////////////
918

    
919
  public String getObjectName()
920
    {
921
    int[] numLayers = getNumLayers();
922

    
923
    switch( numLayers[0] )
924
      {
925
      case  2: return "Jing Pyraminx";
926
      case  3: return "4x4 Pyramid";
927
      case  4: return "5x5 Pyramid";
928
      default: return "6x6 Pyramid";
929
      }
930
    }
931

    
932
///////////////////////////////////////////////////////////////////////////////////////////////////
933

    
934
  public String getInventor()
935
    {
936
    int[] numLayers = getNumLayers();
937
    return numLayers[0]==2 ? "Tony Fisher" : "Unknown";
938
    }
939

    
940
///////////////////////////////////////////////////////////////////////////////////////////////////
941

    
942
  public int getYearOfInvention()
943
    {
944
    int[] numLayers = getNumLayers();
945
    return numLayers[0]==2 ? 1991 : 0;
946
    }
947

    
948
///////////////////////////////////////////////////////////////////////////////////////////////////
949

    
950
  public int getComplexity()
951
    {
952
    int[] numLayers = getNumLayers();
953

    
954
    switch( numLayers[0] )
955
      {
956
      case  2: return 1;
957
      case  3: return 2;
958
      case  4: return 3;
959
      default: return 4;
960
      }
961
    }
962

    
963
///////////////////////////////////////////////////////////////////////////////////////////////////
964

    
965
  public String[][] getTutorials()
966
    {
967
    int[] numLayers = getNumLayers();
968

    
969
    if( numLayers[0]==2 )
970
      return new String[][]{
971
                          {"gb","0T8Iw6aI2gA","Jing's Pyraminx Tutorial","SuperAntoniovivaldi"},
972
                          {"es","Na27_GUIzqY","Resolver Jing Pyraminx","Cuby"},
973
                          {"ru","rlQXFzjsyAo","Как собрать Jing's pyraminx","Илья Топор-Гилка"},
974
                          {"fr","zC9dGqZRSic","Résolution du Jing's Pyraminx","Asthalis"},
975
                          {"de","6ihN4fdHH6o","Jings Pyraminx - Tutorial","GerCubing"},
976
                          {"pl","nRYoJAy1c_8","Jing's Pyraminx TUTORIAL PL","MrUK"},
977
                          {"vn","yX9KjDpHjws","Tutorial N.50 - Jing's Pyraminx","Duy Thích Rubik"},
978
                         };
979
    else
980
      return null;
981
    }
982
}
(22-22/48)