Project

General

Profile

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

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

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.signature.ObjectSignature;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.signature.ObjectConstants;
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
  public static final int JING_2 = 0;
36
  public static final int JING_3 = 1;
37
  public static final int JING_4 = 2;
38
  public static final int JING_5 = 3;
39

    
40
  // Length of the edge of the corner cubit -
41
  // assuming the length of the edge of the whole tetrahedron is numLayers[0]
42
  public static final float[] JING_F = { 0.48f, 0.66f, 0.43f, 0.53f };
43

    
44
  static final Static3D[] ROT_AXIS = new Static3D[]
45
         {
46
           new Static3D(     0,-SQ3/3,-SQ6/3),
47
           new Static3D(     0,-SQ3/3, SQ6/3),
48
           new Static3D( SQ6/3, SQ3/3,     0),
49
           new Static3D(-SQ6/3, SQ3/3,     0),
50
         };
51

    
52
  private int[][] mEdges;
53
  private int[][] mBasicAngle;
54
  private int[] mQuatIndex;
55
  private float[][] mCuts;
56
  private float[][] mCenters;
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
  public TwistyJing(int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
61
    {
62
    super(iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
63
    }
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  private int getObjectType()
68
    {
69
    return getInitData().getParam();
70
    }
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
// make the 'center' sticker artificially smaller, so that we paint over the area in the center of the face.
74

    
75
  @Override
76
  public void adjustStickerCoords()
77
    {
78
    int type = getObjectType();
79

    
80
    if( type==JING_3 || type==JING_5 )
81
      {
82
      float CENTER_CORR = (type==JING_3 ? 0.85f : 0.76f);
83
      int index = (type==JING_3 ? 3 : 5);
84

    
85
      mStickerCoords[index][0][2][0] *= CENTER_CORR;
86
      mStickerCoords[index][0][2][1] *= CENTER_CORR;
87
      }
88
    }
89

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

    
92
  @Override
93
  public float[][] returnRotationFactor()
94
    {
95
    int numL = getNumLayers()[0];
96
    float[] f = new float[numL];
97
    for(int i=0; i<numL; i++) f[i] = 1.3f;
98
    return new float[][] { f,f,f,f };
99
    }
100

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

    
103
  @Override
104
  public float getPillowCoeff()
105
    {
106
    return 1.25f;
107
    }
108

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

    
111
  public int[][] getScrambleEdges()
112
    {
113
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
114
    return mEdges;
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  public float[][] getCuts(int[] numLayers)
120
    {
121
    if( mCuts==null )
122
      {
123
      float[] cut=null;
124
      int type = getObjectType();
125
      final float F = JING_F[type];
126
      int numL = 0;
127

    
128
      switch(type)
129
        {
130
        case JING_2: numL = 2; break;
131
        case JING_3:
132
        case JING_4: numL = 3; break;
133
        case JING_5: numL = 4; break;
134
        }
135

    
136
      switch( type )
137
        {
138
        case JING_2: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3) };
139
                     break;
140
        case JING_3: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), numL*SQ6/18 };
141
                     break;
142
        case JING_4: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), (2*F-numL*0.25f-0.01f)*(SQ6/3) };
143
                     break;
144
        case JING_5: cut = new float[] { (F-numL*0.25f-0.01f)*(SQ6/3), (2*F-numL*0.25f-0.01f)*(SQ6/3), numL*SQ6/18 };
145
                     break;
146
        }
147

    
148
      mCuts = new float[][] { cut,cut,cut,cut };
149
      }
150

    
151
    return mCuts;
152
    }
153

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

    
156
  public boolean[][] getLayerRotatable(int[] numLayers)
157
    {
158
    boolean[] tmp = null;
159

    
160
    switch( getObjectType() )
161
      {
162
      case JING_2: tmp = new boolean[] {true,true}; break;
163
      case JING_3:
164
      case JING_4: tmp = new boolean[] {true,true,true}; break;
165
      case JING_5: tmp = new boolean[] {true,true,false,true}; break;
166
      }
167

    
168
    return new boolean[][] { tmp,tmp,tmp,tmp };
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  public int getTouchControlType()
174
    {
175
    return TC_TETRAHEDRON;
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  public int getTouchControlSplit()
181
    {
182
    return TYPE_NOT_SPLIT;
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  public int[][][] getEnabled()
188
    {
189
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  public float[] getDist3D(int[] numLayers)
195
    {
196
    return TouchControlTetrahedron.D3D;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  public Static3D[] getFaceAxis()
202
    {
203
    return TouchControlTetrahedron.FACE_AXIS;
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  public float[][] getCubitPositions(int[] numLayers)
209
    {
210
    if( mCenters==null )
211
      {
212
      int type = getObjectType();
213

    
214
      if( type==JING_2 )
215
        {
216
        mCenters = new float[][]
217
          {
218
            { 0.000f, -SQ2/2,  1.000f },
219
            { 0.000f, -SQ2/2, -1.000f },
220
            {-1.000f,  SQ2/2,  0.000f },
221
            { 1.000f,  SQ2/2,  0.000f },
222

    
223
            { 0.000f, -SQ2/2,  0.000f },
224
            {-0.500f, 0.000f,  0.500f },
225
            { 0.500f, 0.000f,  0.500f },
226
            {-0.500f, 0.000f, -0.500f },
227
            { 0.500f, 0.000f, -0.500f },
228
            { 0.000f,  SQ2/2,  0.000f },
229

    
230
            { 0.000f,  SQ2/6,  1.0f/3 },
231
            { 0.000f,  SQ2/6, -1.0f/3 },
232
            {-1.0f/3, -SQ2/6,  0.000f },
233
            { 1.0f/3, -SQ2/6,  0.000f },
234
          };
235
        }
236
      else if( type==JING_3 )
237
        {
238
        int numL = 3;
239
        final float F = JING_F[JING_3];
240
        final float A = numL*0.25f;
241
        final float B = numL*0.50f;
242
        final float X = F/2;
243
        final float Y = F*SQ2/2;
244
        final float Z = -F/2;
245

    
246
        mCenters = new float[][]
247
          {
248
            {   0, -SQ2*A,  B },
249
            {   0, -SQ2*A, -B },
250
            {  -B,  SQ2*A,  0 },
251
            {   B,  SQ2*A,  0 },
252

    
253
            {   X, -SQ2*A +Y, B+Z },
254
            {  -X, -SQ2*A +Y, B+Z },
255
            {   0, -SQ2*A   , B-F },
256
            {   X, -SQ2*A +Y,-B-Z },
257
            {  -X, -SQ2*A +Y,-B-Z },
258
            {   0, -SQ2*A   ,-B+F },
259

    
260
            {-B-Z,  SQ2*A -Y,   X },
261
            {-B-Z,  SQ2*A -Y,  -X },
262
            {-B+F,  SQ2*A   ,   0 },
263
            { B+Z,  SQ2*A -Y,   X },
264
            { B+Z,  SQ2*A -Y,  -X },
265
            { B-F,  SQ2*A   ,   0 },
266

    
267
            {      0, -SQ2*A +2*Y,  B +2*Z },
268
            {      X, -SQ2*A +  Y,  B +Z-F },
269
            {     -X, -SQ2*A +  Y,  B +Z-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
            {-B -2*Z,  SQ2*A -2*Y,       0 },
274
            {-B -Z+F,  SQ2*A -  Y,      -X },
275
            {-B -Z+F,  SQ2*A -  Y,       X },
276
            { B +2*Z,  SQ2*A -2*Y,       0 },
277
            { B +Z-F,  SQ2*A -  Y,      -X },
278
            { B +Z-F,  SQ2*A -  Y,       X },
279
          };
280
        }
281
      else if( type==JING_4 )
282
        {
283
        int numL = 3;
284
        final float A = numL*0.25f;
285
        final float B = numL*0.50f;
286
        final float C = numL*(1.0f/6);
287
        final float D = numL*(SQ2/12);
288
        final float F = JING_F[type];
289
        final float X = F/2;
290
        final float Y = F*SQ2/2;
291
        final float Z = -F/2;
292

    
293
        mCenters = new float[][]
294
          {
295
            {  0, -SQ2*A     ,  B      },
296
            {  X, -SQ2*A +  Y,  B +  Z },
297
            { -X, -SQ2*A +  Y,  B +  Z },
298
            {  0, -SQ2*A     ,  B -  F },
299
            {  0, -SQ2*A +2*Y,  B +2*Z },
300
            {  X, -SQ2*A +  Y,  B +Z-F },
301
            { -X, -SQ2*A +  Y,  B +Z-F },
302

    
303
            {  0, -SQ2*A     , -B      },
304
            {  X, -SQ2*A +  Y, -B -  Z },
305
            { -X, -SQ2*A +  Y, -B -  Z },
306
            {  0, -SQ2*A     , -B +  F },
307
            {  0, -SQ2*A +2*Y, -B -2*Z },
308
            {  X, -SQ2*A +  Y, -B -Z+F },
309
            { -X, -SQ2*A +  Y, -B -Z+F },
310

    
311
            {-B     ,  SQ2*A     ,   0 },
312
            {-B -  Z,  SQ2*A -  Y,   X },
313
            {-B -  Z,  SQ2*A -  Y,  -X },
314
            {-B +  F,  SQ2*A     ,   0 },
315
            {-B -2*Z,  SQ2*A -2*Y,   0 },
316
            {-B -Z+F,  SQ2*A -  Y,  -X },
317
            {-B -Z+F,  SQ2*A -  Y,   X },
318

    
319
            { B     ,  SQ2*A     ,   0 },
320
            { B +  Z,  SQ2*A -  Y,   X },
321
            { B +  Z,  SQ2*A -  Y,  -X },
322
            { B -  F,  SQ2*A     ,   0 },
323
            { B +2*Z,  SQ2*A -2*Y,   0 },
324
            { B +Z-F,  SQ2*A -  Y,  -X },
325
            { B +Z-F,  SQ2*A -  Y,   X },
326

    
327
            { 0,-SQ2*A,  0 },
328
            {-A,     0,  A },
329
            { A,     0,  A },
330
            {-A,     0, -A },
331
            { A,     0, -A },
332
            { 0, SQ2*A,  0 },
333

    
334
            {    0.50f*F, -SQ2*A +F*SQ2/2, 0          },
335
            {   -0.50f*F, -SQ2*A +F*SQ2/2, 0          },
336
            {-A +0.75f*F,         F*SQ2/4, A -0.25f*F },
337
            {-A +0.25f*F,        -F*SQ2/4, A -0.75f*F },
338
            { A -0.75f*F,         F*SQ2/4, A -0.25f*F },
339
            { A -0.25f*F,        -F*SQ2/4, A -0.75f*F },
340
            {-A +0.75f*F,         F*SQ2/4,-A +0.25f*F },
341
            {-A +0.25f*F,        -F*SQ2/4,-A +0.75f*F },
342
            { A -0.75f*F,         F*SQ2/4,-A +0.25f*F },
343
            { A -0.25f*F,        -F*SQ2/4,-A +0.75f*F },
344
            { 0         ,  SQ2*A -F*SQ2/2,    0.50f*F },
345
            { 0         ,  SQ2*A -F*SQ2/2,   -0.50f*F },
346

    
347
            { 0,  D,  C},
348
            { 0,  D, -C},
349
            {-C, -D,  0},
350
            { C, -D,  0},
351
          };
352
        }
353
      else if( type==JING_5 )
354
        {
355
        int numL = 4;
356
        final float A = numL*0.25f;
357
        final float B = numL*0.50f;
358
        final float F = JING_F[type];
359
        final float X = F/2;
360
        final float Y = F*SQ2/2;
361
        final float Z = -F/2;
362

    
363
        mCenters = new float[][]
364
          {
365
            {  0, -SQ2*A     ,  B      },
366
            {  X, -SQ2*A +  Y,  B +  Z },
367
            { -X, -SQ2*A +  Y,  B +  Z },
368
            {  0, -SQ2*A     ,  B -  F },
369
            {  0, -SQ2*A +2*Y,  B +2*Z },
370
            {  X, -SQ2*A +  Y,  B +Z-F },
371
            { -X, -SQ2*A +  Y,  B +Z-F },
372

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

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

    
389
            { B     ,  SQ2*A     ,   0 },
390
            { B +  Z,  SQ2*A -  Y,   X },
391
            { B +  Z,  SQ2*A -  Y,  -X },
392
            { B -  F,  SQ2*A     ,   0 },
393
            { B +2*Z,  SQ2*A -2*Y,   0 },
394
            { B +Z-F,  SQ2*A -  Y,  -X },
395
            { B +Z-F,  SQ2*A -  Y,   X },
396

    
397
            { 2*X, -SQ2*A +2*Y, B+2*Z },
398
            {-2*X, -SQ2*A +2*Y, B+2*Z },
399
            {   0, -SQ2*A     , B-2*F },
400
            { 2*X, -SQ2*A +2*Y,-B-2*Z },
401
            {-2*X, -SQ2*A +2*Y,-B-2*Z },
402
            {   0, -SQ2*A     ,-B+2*F },
403

    
404
            {-B-2*Z, SQ2*A -2*Y,  2*X },
405
            {-B-2*Z, SQ2*A -2*Y, -2*X },
406
            {-B+2*F, SQ2*A     ,    0 },
407
            { B+2*Z, SQ2*A -2*Y,  2*X },
408
            { B+2*Z, SQ2*A -2*Y, -2*X },
409
            { B-2*F, SQ2*A     ,    0 },
410

    
411
            {   X, -SQ2*A+3*Y ,  B+3*Z     },
412
            {-2*X, -SQ2*A+2*Y ,  B+4*Z     },
413
            {   X, -SQ2*A+Y   ,  B+5*Z     },
414
            { 2*X, -SQ2*A+2*Y , -B-4*Z     },
415
            {  -X, -SQ2*A+3*Y , -B-3*Z     },
416
            {  -X, -SQ2*A+Y   , -B-5f*Z    },
417
            {  -B+   2*F,  SQ2*A-2*Y ,-2*Z },
418
            {  -B+2.5f*F,  SQ2*A-  Y ,   Z },
419
            {  -B+1.5f*F,  SQ2*A-3*Y ,   Z },
420
            {   B-1.5f*F,  SQ2*A-3*Y ,  -Z },
421
            {   B-   2*F,  SQ2*A-2*Y , 2*Z },
422
            {   B-2.5f*F,  SQ2*A-  Y ,  -Z },
423

    
424
            {  -X, -SQ2*A+3*Y ,  B+3*Z     },
425
            { 2*X, -SQ2*A+2*Y ,  B+4*Z     },
426
            {  -X, -SQ2*A+Y   ,  B+5*Z     },
427
            {-2*X, -SQ2*A+2*Y , -B-4*Z     },
428
            {   X, -SQ2*A+3*Y , -B-3*Z     },
429
            {   X, -SQ2*A+Y   , -B-5*Z     },
430
            {  -B+   2*F,  SQ2*A-2*Y , 2*Z },
431
            {  -B+2.5f*F,  SQ2*A-  Y ,  -Z },
432
            {  -B+1.5f*F,  SQ2*A-3*Y ,  -Z },
433
            {   B-1.5f*F,  SQ2*A-3*Y ,   Z },
434
            {   B-   2*F,  SQ2*A-2*Y ,-2*Z },
435
            {   B-2.5f*F,  SQ2*A-  Y ,   Z },
436

    
437
            {   0, -SQ2*A+4*Y, B+4*Z },
438
            { 2*X, -SQ2*A+2*Y, B+6*Z },
439
            {-2*X, -SQ2*A+2*Y, B+6*Z },
440
            {   0, -SQ2*A+4*Y,-B-4*Z },
441
            { 2*X, -SQ2*A+2*Y,-B-6*Z },
442
            {-2*X, -SQ2*A+2*Y,-B-6*Z },
443
            { -B-4*Z, SQ2*A-4*Y,   0 },
444
            { -B-6*Z, SQ2*A-2*Y, 2*X },
445
            { -B-6*Z, SQ2*A-2*Y,-2*X },
446
            {  B+4*Z, SQ2*A-4*Y,   0 },
447
            {  B+6*Z, SQ2*A-2*Y, 2*X },
448
            {  B+6*Z, SQ2*A-2*Y,-2*X },
449
          };
450
        }
451
      }
452

    
453
    return mCenters;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public Static4D getCubitQuats(int cubit, int[] numLayers)
459
    {
460
    if( mQuatIndex==null )
461
      {
462
      int type = getObjectType();
463

    
464
      if( type==JING_2 )
465
        mQuatIndex = new int[] { 0,10,5,8,
466
                                 0,5,8,6,7,9,
467
                                 0,10,7,3 };
468
      else if( type==JING_3 )
469
        mQuatIndex = new int[] { 0,10,5,8,
470
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
471
                                 0,3,4, 10,6,7, 11,5,2, 9,8,1
472
                               };
473
      else if( type==JING_4 )
474
        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,
475
                                 0,5,8,6,7,9,
476
                                 0,0,5,5,8,8,6,6,7,7,9,9,
477
                                 0,10,7,3 };
478
      else
479
        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,
480
                                 4,3,0, 7,6,10, 5,2,11, 8,1,9,
481
                                 4,3,0, 7,6,10, 5,11,2, 8,1,9,
482
                                 5,8,10,2,1,0,  6,9,3,  7,4,11,
483
                                 0,3,4, 10,6,7, 11,2,5, 9,1,8 };
484
      }
485

    
486
    return mObjectQuats[mQuatIndex[cubit]];
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  private float[][] getVertices(int variant)
492
    {
493
    int type = getObjectType();
494
    int numL = 0;
495
    int munL = 0;
496

    
497
    switch(type)
498
      {
499
      case JING_2: numL = 2; munL = 1; break;
500
      case JING_3: numL = 3; munL = 1; break;
501
      case JING_4: numL = 3; munL = 2; break;
502
      case JING_5: numL = 4; munL = 2; break;
503
      }
504

    
505
    final float F = JING_F[type];
506
    final float X = F/2;
507
    final float Y = F*SQ2/2;
508
    final float Z =-F/2;
509

    
510
    final float L = (numL-3*(numL-1)*F);
511
    final float X2 = L/2;
512
    final float Y2 = L*SQ2/2;
513
    final float Z2 =-L/2;
514
    final float D = F/L;
515
    final float G1 = 0.5f*numL - munL*F;
516
    final float G2 = G1 - F/2;
517
    final float X3 = G2/2;
518
    final float Y3 = G2*SQ2/2;
519
    final float Z3 =-G2/2;
520
    final float G3 = G1 - F;
521
    final float X4 = G3/2;
522
    final float Y4 = G3*SQ2/2;
523
    final float Z4 =-G3/2;
524
    final float K  = 0.2f*(1 - F/(2*G2));
525

    
526
    if( variant==0 )
527
      {
528
      return new float[][]
529
        {
530
            { 0,   0,     0},
531
            { X,   Y,   Z  },
532
            { 0, 2*Y, 2*Z  },
533
            {-X,   Y,   Z  },
534
            { 0,   0,    -F},
535
            { X,   Y,   Z-F},
536
            { 0, 2*Y, 2*Z-F},
537
            {-X,   Y,   Z-F},
538
        };
539
      }
540
    else if( variant==1 && (type==JING_2 || type==JING_4) )
541
      {
542
      return new float[][]
543
        {
544
            { 0,   0,     G1 },
545
            { X,   Y,   Z+G1 },
546
            { 0, 2*Y, 2*Z+G1 },
547
            {-X,   Y,   Z+G1 },
548
            { 0,   0,    -G1 },
549
            { X,   Y,  -Z-G1 },
550
            { 0, 2*Y,-2*Z-G1 },
551
            {-X,   Y,  -Z-G1 },
552
        };
553
      }
554
    else if( variant==1 && (type==JING_3 || type==JING_5) )
555
      {
556
      return new float[][]
557
        {
558
            { 0,   0,   0 },
559
            { X,   Y,   Z },
560
            { 0, 2*Y, 2*Z },
561
            {-X,   Y,   Z },
562
            { 0,   0, -G1 },
563
            { X,   Y, -G1 },
564
            {-X,   Y, -G1 },
565
        };
566
      }
567
    else if( variant==2 && type==JING_3 )
568
      {
569
      return new float[][]
570
        {
571
            {  0,    0,    0 },
572
            { X3,   Y3,   Z3 },
573
            {  0, (2*SQ2/3)*G2, (-2.0f/3)*G2 },
574
            {-X3,   Y3,   Z3 },
575
            {  0,    0,  -G2 },
576
            { K*X3,   K*Y3,  K*Z3-G2 },
577
            {  0, K*(2*SQ2/3)*G2, K*(-2.0f/3)*G2 - G2 },
578
            {-K*X3,   K*Y3,  K*Z3-G2 },
579
        };
580
      }
581
    else if( variant==2 && type==JING_4 )
582
      {
583
      return new float[][]
584
        {
585
            { 0,   0,     G2},
586
            { X,   Y,   Z+G2},
587
            { 0, 2*Y, 2*Z+G2},
588
            {-X,   Y,   Z+G2},
589
            { 0,   0,    -G2},
590
            { X,   Y,  -Z-G2},
591
            { 0, 2*Y,-2*Z-G2},
592
            {-X,   Y,  -Z-G2},
593
        };
594
      }
595
    else if( variant==2 && type==JING_5 )
596
      {
597
      return new float[][]
598
        {
599
            { 0,   0,   0 },
600
            { X,   Y,   Z },
601
            {-X,   Y,   Z },
602
            { 0,   0, -G2 },
603
            { X,   Y, -G2 }
604
        };
605
      }
606
    else if( variant==3 && type==JING_5 )
607
      {
608
      return new float[][]
609
        {
610
            { 0,   0,   0 },
611
            {-X,   Y,  -Z },
612
            { X,   Y,  -Z },
613
            { 0,   0,  G2 },
614
            { X,   Y,  G2 },
615
        };
616
      }
617
    else if( variant==4 && type==JING_5 )
618
      {
619
      return new float[][]
620
        {
621
            {  0,    0,    0 },
622
            { X4,   Y4,   Z4 },
623
            {  0, (2*SQ2/3)*G3, (-2.0f/3)*G3 },
624
            {-X4,   Y4,   Z4 },
625
            {  0,    0,  -G3 },
626
            { K*X4,   K*Y4,  K*Z4-G3 },
627
            {  0, K*(2*SQ2/3)*G3, K*(-2.0f/3)*G3 - G3 },
628
            {-K*X4,   K*Y4,  K*Z4-G3 },
629
        };
630
      }
631
    else
632
      {
633
      return new float[][]
634
        {
635
            {  0     , -2*Y2/3     , -2*Z2/3       },
636
            { X2     ,    Y2/3     ,    Z2/3       },
637
            {-X2     ,    Y2/3     ,    Z2/3       },
638
            {  0     , -2*Y2/3     , -2*Z2/3+2*D*Z2},
639
            { X2-D*X2,    Y2/3-D*Y2,    Z2/3+  D*Z2},
640
            {-X2+D*X2,    Y2/3-D*Y2,    Z2/3+  D*Z2},
641
        };
642
      }
643
    }
644

    
645
///////////////////////////////////////////////////////////////////////////////////////////////////
646

    
647
  public ObjectShape getObjectShape(int variant)
648
    {
649
    int type = getObjectType();
650

    
651
    if( variant==0 )
652
      {
653
      int[][] indices =
654
          {
655
             {0,1,2,3},
656
             {1,0,4,5},
657
             {7,4,0,3},
658
             {1,5,6,2},
659
             {7,3,2,6},
660
             {4,7,6,5}
661
          };
662

    
663
      return new ObjectShape(getVertices(variant), indices);
664
      }
665
    else if( (variant==1 && (type==JING_2 || type==JING_4)) || (variant==2 && type==JING_4)  )
666
      {
667
      int[][] indices =
668
          {
669
             {0,4,5,1},
670
             {3,7,4,0},
671
             {0,1,2,3},
672
             {4,7,6,5},
673
             {1,5,6,2},
674
             {2,6,7,3}
675
          };
676

    
677
      return new ObjectShape(getVertices(variant), indices);
678
      }
679
    else if( (variant==2 && type==JING_3) || (variant==4 && type==JING_5) )
680
      {
681
      int[][] indices =
682
          {
683
             {0,1,2,3},
684
             {0,4,5,1},
685
             {3,7,4,0},
686
             {4,7,6,5},
687
             {1,5,6,2},
688
             {2,6,7,3}
689
          };
690

    
691
      return new ObjectShape(getVertices(variant), indices);
692
      }
693
    else if( variant==1 && (type==JING_3 || type==JING_5)  )
694
      {
695
      int[][] indices =
696
          {
697
             {0,4,5,1},
698
             {3,6,4,0},
699
             {0,1,2,3},
700
             {1,5,2},
701
             {2,6,3},
702
             {4,2,5},
703
             {4,6,2}
704
          };
705

    
706
      return new ObjectShape(getVertices(variant), indices);
707
      }
708
    else if( variant==2 && type==JING_5 )
709
      {
710
      int[][] indices =
711
          {
712
             {0,3,4,1},
713
             {2,3,0},
714
             {0,1,2},
715
             {4,3,2},
716
             {1,4,2}
717
          };
718

    
719
      return new ObjectShape(getVertices(variant), indices);
720
      }
721
    else if( variant==3 && type==JING_5 )
722
      {
723
      int[][] indices =
724
          {
725
             {0,2,4,3},
726
             {3,1,0},
727
             {0,1,2},
728
             {3,4,1},
729
             {1,4,2}
730
          };
731

    
732
      return new ObjectShape(getVertices(variant), indices);
733
      }
734
    else
735
      {
736
      int[][] indices =
737
          {
738
             {0,1,2},
739
             {3,5,4},
740
             {0,3,4,1},
741
             {5,3,0,2},
742
             {4,5,2,1}
743
          };
744

    
745
      return new ObjectShape(getVertices(variant), indices);
746
      }
747
    }
748

    
749
///////////////////////////////////////////////////////////////////////////////////////////////////
750

    
751
  public ObjectFaceShape getObjectFaceShape(int variant)
752
    {
753
    int type = getObjectType();
754
    float R = 0.3f;
755
    float S = 0.5f;
756
    float H = 0.015f;
757

    
758
    if( variant==0 )
759
      {
760
      int I = type!=JING_5 ? 1:0;
761
      int V = type!=JING_5 ? 1:0;
762
      float height = isInIconMode() ? 0.001f : H;
763
      float[][] bands = { {height,35,R,S,5,I,V},{0.001f,1,R,S,5,I,V} };
764
      int[] indices   = { 0,0,0,1,1,1 };
765
      return new ObjectFaceShape(bands,indices,null);
766
      }
767
    else if( variant==1 && (type==JING_2 || type==JING_4) )
768
      {
769
      int N1 = type==JING_2 ? 9:7;
770
      int N2 = type==JING_2 ? 9:4;
771
      float height = isInIconMode() ? 0.001f : H;
772
      float[][] bands = { {height,35,R,S,N1,0,0},{0.001f,1,R,S,N2,0,0} };
773
      int[] indices   = { 0,0,1,1,1,1 };
774
      return new ObjectFaceShape(bands,indices,null);
775
      }
776
    else if( variant==1 && (type==JING_3 || type==JING_5) )
777
      {
778
      int N = type==JING_3 ? 7:5;
779
      float height = isInIconMode() ? 0.001f : H;
780
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
781
      int[] indices   = { 0,0,1,1,1,1,1 };
782
      return new ObjectFaceShape(bands,indices,null);
783
      }
784
    else if( (variant==2 || variant==3) && type==JING_5 )
785
      {
786
      int N = 5;
787
      float height = isInIconMode() ? 0.001f : H;
788
      float[][] bands = { {height,35,R,S,N,0,0},{0.001f,1,R,S,4,0,0} };
789
      int[] indices   = { 0,1,1,1,1,1,1 };
790
      return new ObjectFaceShape(bands,indices,null);
791
      }
792
    else if( variant==2 && type==JING_4 )
793
      {
794
      float height = isInIconMode() ? 0.001f : H;
795
      float[][] bands = { {height,35,R,S,6,0,0},{0.001f,1,R,S,4,0,0} };
796
      int[] indices   = { 0,1,1,1,1,1 };
797
      return new ObjectFaceShape(bands,indices,null);
798
      }
799
    else
800
      {
801
      int N = type==JING_2 ? 5: (type==JING_3 ? 4:2);
802
      float height = isInIconMode() ? 0.001f : H;
803
      float[][] bands = { {height,35,R,S,N,0,0}, {0.001f,1,R,S,N,0,0} };
804
      int[] indices   = { 0,1,1,1,1,1 };
805
      return new ObjectFaceShape(bands,indices,null);
806
      }
807
    }
808

    
809
///////////////////////////////////////////////////////////////////////////////////////////////////
810

    
811
  public ObjectVertexEffects getVertexEffects(int variant)
812
    {
813
    int type = getObjectType();
814
    final float F = JING_F[type];
815
    final float Y = F*SQ2/2;
816
    final float Z =-F/2;
817

    
818
    if( variant==0 )
819
      {
820
      float[][] corners   = { {0.08f,0.10f},{0.04f,0.10f} };
821
      int[] cornerIndices = { 0,1,1,1,1,-1,-1,-1 };
822
      float[][] centers   = { { 0.0f, Y, Z-F/2} };
823
      int[] centerIndices = { 0,0,0,0,0,-1,-1,-1 };
824
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
825
      }
826
    else if( variant==1 )
827
      {
828
      float[][] corners   = { { 0.05f,0.10f} };
829
      int[] cornerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
830
      float[][] centers   = { { 0, F*SQ2/2, 0 } };
831
      int[] centerIndices = { 0,-1,-1,-1,0,-1,-1,-1 };
832
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
833
      }
834
    else return null;
835
    }
836

    
837
///////////////////////////////////////////////////////////////////////////////////////////////////
838

    
839
  public int getNumCubitVariants(int[] numLayers)
840
    {
841
    switch(getObjectType())
842
      {
843
      case JING_2:
844
      case JING_3: return 3;
845
      case JING_4: return 4;
846
      case JING_5: return 5;
847
      }
848

    
849
    return 0;
850
    }
851

    
852
///////////////////////////////////////////////////////////////////////////////////////////////////
853

    
854
  public int getCubitVariant(int cubit, int[] numLayers)
855
    {
856
    switch( getObjectType() )
857
      {
858
      case  JING_2: return cubit< 4 ? 0 : (cubit<10 ? 1:2);
859
      case  JING_3: return cubit< 4 ? 0 : (cubit<16 ? 1:2);
860
      case  JING_4: return cubit<28 ? 0 : (cubit<34 ? 1 : (cubit<46 ? 2:3) );
861
      case  JING_5: return cubit<28 ? 0 : (cubit<40 ? 1 : (cubit<52 ? 2: (cubit<64 ? 3:4)) );
862
      }
863

    
864
    return 0;
865
    }
866

    
867
///////////////////////////////////////////////////////////////////////////////////////////////////
868

    
869
  public float getStickerRadius()
870
    {
871
    switch( getObjectType() )
872
      {
873
      case JING_2: return 0.05f;
874
      case JING_3: return 0.06f;
875
      case JING_4: return 0.07f;
876
      case JING_5: return 0.08f;
877
      }
878

    
879
    return 0;
880
    }
881

    
882
///////////////////////////////////////////////////////////////////////////////////////////////////
883

    
884
  public float getStickerStroke()
885
    {
886
    boolean icon = isInIconMode();
887

    
888
    switch( getObjectType() )
889
      {
890
      case JING_2: return icon ? 0.10f : 0.05f;
891
      case JING_3: return icon ? 0.14f : 0.07f;
892
      case JING_4: return icon ? 0.12f : 0.06f;
893
      case JING_5: return icon ? 0.16f : 0.08f;
894
      }
895

    
896
    return 0;
897
    }
898

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

    
901
  public float[][][] getStickerAngles()
902
    {
903
    return null;
904
    }
905

    
906
///////////////////////////////////////////////////////////////////////////////////////////////////
907
// PUBLIC API
908

    
909
  public Static3D[] getRotationAxis()
910
    {
911
    return ROT_AXIS;
912
    }
913

    
914
///////////////////////////////////////////////////////////////////////////////////////////////////
915

    
916
  public int[][] getBasicAngles()
917
    {
918
    if( mBasicAngle==null )
919
      {
920
      int num = getNumLayers()[0];
921
      int[] tmp = new int[num];
922
      for(int i=0; i<num; i++) tmp[i] = 3;
923
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
924
      }
925

    
926
    return mBasicAngle;
927
    }
928

    
929
///////////////////////////////////////////////////////////////////////////////////////////////////
930

    
931
  public String getShortName()
932
    {
933
    switch( getObjectType() )
934
      {
935
      case JING_2: return ObjectType.JING_2.name();
936
      case JING_3: return ObjectType.JING_3.name();
937
      case JING_4: return ObjectType.JING_4.name();
938
      case JING_5: return ObjectType.JING_5.name();
939
      }
940

    
941
    return null;
942
    }
943

    
944
///////////////////////////////////////////////////////////////////////////////////////////////////
945

    
946
  public ObjectSignature getSignature()
947
    {
948
    int sig=0;
949

    
950
    switch( getObjectType() )
951
      {
952
      case JING_2: sig = ObjectConstants.JING_2; break;
953
      case JING_3: sig = ObjectConstants.JING_3; break;
954
      case JING_4: sig = ObjectConstants.JING_4; break;
955
      case JING_5: sig = ObjectConstants.JING_5; break;
956
      }
957

    
958
    return new ObjectSignature(sig);
959
    }
960

    
961
///////////////////////////////////////////////////////////////////////////////////////////////////
962

    
963
  public String getObjectName()
964
    {
965
    switch( getObjectType() )
966
      {
967
      case JING_2: return "Jing Pyraminx";
968
      case JING_3: return "4x4 Pyramid";
969
      case JING_4: return "5x5 Pyramid";
970
      case JING_5: return "6x6 Pyramid";
971
      }
972

    
973
    return null;
974
    }
975

    
976
///////////////////////////////////////////////////////////////////////////////////////////////////
977

    
978
  public String getInventor()
979
    {
980
    return getObjectType()==JING_2 ? "Tony Fisher" : "Unknown";
981
    }
982

    
983
///////////////////////////////////////////////////////////////////////////////////////////////////
984

    
985
  public int getYearOfInvention()
986
    {
987
    return getObjectType()==JING_2 ? 1991 : 0;
988
    }
989

    
990
///////////////////////////////////////////////////////////////////////////////////////////////////
991

    
992
  public int getComplexity()
993
    {
994
    switch( getObjectType() )
995
      {
996
      case JING_2: return 1;
997
      case JING_3: return 2;
998
      case JING_4: return 3;
999
      case JING_5: return 4;
1000
      }
1001

    
1002
    return 0;
1003
    }
1004

    
1005
///////////////////////////////////////////////////////////////////////////////////////////////////
1006

    
1007
  public String[][] getTutorials()
1008
    {
1009
    if( getObjectType()==JING_2 )
1010
      return new String[][]
1011
                         {
1012
                          {"gb","0T8Iw6aI2gA","Jing's Pyraminx Tutorial","SuperAntoniovivaldi"},
1013
                          {"es","Na27_GUIzqY","Resolver Jing Pyraminx","Cuby"},
1014
                          {"ru","rlQXFzjsyAo","Как собрать Jing's pyraminx","Илья Топор-Гилка"},
1015
                          {"fr","zC9dGqZRSic","Résolution du Jing's Pyraminx","Asthalis"},
1016
                          {"de","6ihN4fdHH6o","Jings Pyraminx - Tutorial","GerCubing"},
1017
                          {"pl","nRYoJAy1c_8","Jing's Pyraminx TUTORIAL PL","MrUK"},
1018
                          {"vn","yX9KjDpHjws","Tutorial N.50 - Jing's Pyraminx","Duy Thích Rubik"},
1019
                         };
1020
    else if( getObjectType()==JING_3 )
1021
      return new String[][]
1022
                         {
1023
                          {"gb","FYHdSpeMdqA","Four Layer Tetrahedral Solve","Superantoniovivaldi"},
1024
                          {"es","NH0x_zn8xtU","Tutorial: Magic Tower 4x4","QBAndo"},
1025
                          {"ru","E1O5KauTBeI","Как собрать Magic Tower 4x4","Алексей Ярыгин"},
1026
                          {"tw","DFJ6q11B03Q","四階魔塔 教學","不正常魔術方塊研究中心"},
1027
                         };
1028
    else if( getObjectType()==JING_4 )
1029
      return new String[][]
1030
                         {
1031
                          {"gb","81xWI6iqMAc","Five Layer Tetrahedral Solve","Superantoniovivaldi"},
1032
                          {"es","JRojNv32amY","Tutorial: Magic Tower 5x5","Víctor Martínez"},
1033
                          {"ru","wHwG6dqjwh0","Как собрать Magic Tower 5x5","Алексей Ярыгин"},
1034
                          {"vn","DWZbEydn98E","Tutorial N.143 - 5x5 Pyramid","Duy Thích Rubik"},
1035
                          {"tw","w7rCoRsgsA0","五階魔塔 教學","不正常魔術方塊研究中心"},
1036
                         };
1037
    else if( getObjectType()==JING_5 )
1038
      return new String[][]
1039
                         {
1040
                          {"gb","bNJ-SJ1uUrE","6 Layer Jing Pyraminx Tutorial","Sassy Monk"},
1041
                          {"vn","rP3GPrSs35g","Tutorial N.162 - 6x6 Pyramid","Duy Thích Rubik"},
1042
                          {"tw","eHbvOZDv4D8","六階魔塔 教學","不正常魔術方塊研究中心"},
1043
                         };
1044
    else
1045
      return null;
1046
    }
1047
}
(27-27/57)