Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCrazy3x3.java @ b0c97683

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import java.io.InputStream;
23
import java.util.ArrayList;
24

    
25
import org.distorted.library.type.Static3D;
26
import org.distorted.library.type.Static4D;
27
import org.distorted.objectlib.helpers.ObjectFaceShape;
28
import org.distorted.objectlib.helpers.ObjectShape;
29
import org.distorted.objectlib.helpers.ObjectSignature;
30
import org.distorted.objectlib.helpers.ObjectStickerOverride;
31
import org.distorted.objectlib.main.Cubit;
32
import org.distorted.objectlib.main.InitData;
33
import org.distorted.objectlib.main.ObjectType;
34
import org.distorted.objectlib.main.ShapeHexahedron;
35
import org.distorted.objectlib.scrambling.ScrambleState;
36
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
37

    
38
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
39
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
public class TwistyCrazy3x3 extends ShapeHexahedron
44
{
45
  public static final int CRAZY   = 0x3f;
46
  public static final int MERCURY = 0x2f;
47
  public static final int VENUS   = 0x0f;
48
  public static final int EARTH   = 0x2b;
49
  public static final int MARS    = 0x0b;
50
  public static final int JUPITER = 0x10;
51
  public static final int SATURN  = 0x30;
52
  public static final int URANUS  = 0x14;
53
  public static final int NEPTUNE = 0x16;
54

    
55
  private static final float DIAMETER_RATIO = 0.75f;
56
  private static final float DIFF = 0.6f;
57
  private static final int NUMBER_CORNER_SEGMENTS = 4;
58
  private static final int NUMBER_EDGE_SEGMENTS = 4;
59

    
60
  static final Static3D[] ROT_AXIS = new Static3D[]
61
         {
62
           new Static3D(1,0,0),
63
           new Static3D(0,1,0),
64
           new Static3D(0,0,1)
65
         };
66

    
67
  private ScrambleState[] mStates;
68
  private int[][] mBasicAngle;
69
  private float[][] mCuts;
70
  private float[][] mPositions;
71
  private int[] mQuatIndex;
72
  private float[][] mOffsets;
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  public TwistyCrazy3x3(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
77
    {
78
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  @Override
84
  public void adjustStickerCoords()
85
    {
86
    final float A = 0.3645522f;
87
    final float B = 0.0744520f;
88
    final float C = 0.1823852f;
89
    final float D = 0.3098326f;
90
    final float E = 0.1033291f;
91
    final float F = 0.4044531f;
92
    final float G = 0.4103489f;
93

    
94
    mStickerCoords = new float[][]
95
      {
96
         { A, 0.5f, -0.5f, 0.5f, -0.5f, -A, -B, -A, A, B },
97
         { 0.5f, -C, 0.5f, D, -0.5f, D, -0.5f, -C },
98
         { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
99
         { -0.5f, E, -0.5f, -F, 0.5f, -F, 0.5f, E },
100
         { -G, 0.5f, -G, -G, 0.5f, -G }
101
      };
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  private boolean cubitIsOverriden(int cubit)
107
    {
108
    float[] offset = getCubitRowOffset(cubit);
109
    return offset[0]*offset[0]+offset[1]*offset[1]+offset[2]*offset[2] == 0;
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  @Override
115
  public ObjectStickerOverride[] getStickerOverrides()
116
    {
117
    ArrayList<Integer> cubits = new ArrayList<>();
118

    
119
    for(int i=0; i<6; i++)
120
      if( cubitIsOverriden(20+i) ) cubits.add(20+i);
121

    
122
    int numOverrides = cubits.size();
123

    
124
    if( numOverrides>0 )
125
      {
126
      ObjectStickerOverride[] overrides = new ObjectStickerOverride[1];
127
      int[] cubfac = new int[2*numOverrides];
128
      for(int i=0; i<numOverrides; i++)
129
        {
130
        cubfac[2*i  ] = cubits.get(i);
131
        cubfac[2*i+1] = 6;
132
        }
133
      overrides[0] = new ObjectStickerOverride(cubfac,0x00ffffff);
134
      return overrides;
135
      }
136

    
137
    return null;
138
    }
139

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

    
142
  @Override
143
  public int getCubitRotationType(int cubit)
144
    {
145
    int[] numLayers = getNumLayers();
146
    int variant = getCubitVariant(cubit,numLayers);
147

    
148
    switch(variant)
149
      {
150
      case  2: return Cubit.TYPE_DECIDER;
151
      case  3:
152
      case  4: return Cubit.TYPE_FOLLOWER;
153
      default: return Cubit.TYPE_NORMAL;
154
      }
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  @Override
160
  public float[] getCubitRowOffset(int cubitIndex)
161
    {
162
    if( mOffsets==null )
163
      {
164
      float[] tmp = new float[] {0,0,0};
165
      int numCubits = mPositions.length;
166
      mOffsets = new float[numCubits][];
167

    
168
      int param = getInitData().getParam();
169

    
170
      int R = (param>>5)&0x1;
171
      int L = (param>>4)&0x1;
172
      int U = (param>>3)&0x1;
173
      int D = (param>>2)&0x1;
174
      int F = (param>>1)&0x1;
175
      int B = (param   )&0x1;
176

    
177
      for(int i=0; i<numCubits; i++)
178
        {
179
        switch(i)
180
          {
181
          case 20: mOffsets[i] = new float[] {0,0,-DIFF*F}; break;
182
          case 21: mOffsets[i] = new float[] {0,0,+DIFF*B}; break;
183
          case 22: mOffsets[i] = new float[] {0,-DIFF*U,0}; break;
184
          case 23: mOffsets[i] = new float[] {0,+DIFF*D,0}; break;
185
          case 24: mOffsets[i] = new float[] {-DIFF*R,0,0}; break;
186
          case 25: mOffsets[i] = new float[] {+DIFF*L,0,0}; break;
187
          default: mOffsets[i] = tmp;
188
          }
189
        }
190
      }
191

    
192
    return mOffsets[cubitIndex];
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196
// Normal 3x3
197

    
198
  public ScrambleState[] getScrambleStates()
199
    {
200
    if( mStates==null )
201
      {
202
      int[][] m = new int[16][];
203

    
204
      for(int i=0; i<16; i++) m[i] = new int[] { 0,-1,i,0,1,i,0,2,i, 1,-1,i,1,1,i,1,2,i, 2,-1,i,2,1,i,2,2,i};
205

    
206
      mStates = new ScrambleState[]
207
          {
208
          new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
209
          new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
210
          new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
211
          new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
212
          new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
213
          new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
214
          new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
215
          new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
216
          new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
217
          new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
218
          new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
219
          new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
220
          new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
221
          new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
222
          new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
223
          new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
224
          };
225
      }
226

    
227
    return mStates;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  public float[][] getCuts(int[] numLayers)
233
    {
234
    if( mCuts==null )
235
      {
236
      float C = 0.5f;
237
      float[] cut = new float[] {-C,+C};
238
      mCuts = new float[][] { cut,cut,cut };
239
      }
240

    
241
    return mCuts;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public boolean[][] getLayerRotatable(int[] numLayers)
247
    {
248
    boolean[] tmp = new boolean[] {true,true,true};
249
    return new boolean[][] { tmp,tmp,tmp };
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  public int getTouchControlType()
255
    {
256
    return TC_HEXAHEDRON;
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

    
261
  public int getTouchControlSplit()
262
    {
263
    return TYPE_NOT_SPLIT;
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

    
268
  public int[][][] getEnabled()
269
    {
270
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  public float[] getDist3D(int[] numLayers)
276
    {
277
    return TouchControlHexahedron.D3D;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  public Static3D[] getFaceAxis()
283
    {
284
    return TouchControlHexahedron.FACE_AXIS;
285
    }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
  public float[][] getCubitPositions(int[] numLayers)
290
    {
291
    if( mPositions==null )
292
      {
293
      mPositions = new float[][]
294
         {
295
             { 1.0f, 1.0f, 1.0f},
296
             { 1.0f, 1.0f,-1.0f},
297
             { 1.0f,-1.0f, 1.0f},
298
             { 1.0f,-1.0f,-1.0f},
299
             {-1.0f, 1.0f, 1.0f},
300
             {-1.0f, 1.0f,-1.0f},
301
             {-1.0f,-1.0f, 1.0f},
302
             {-1.0f,-1.0f,-1.0f},
303

    
304
             { 1.0f, 1.0f, 0.0f},
305
             { 1.0f,-1.0f, 0.0f},
306
             { 1.0f, 0.0f, 1.0f},
307
             { 1.0f, 0.0f,-1.0f},
308
             {-1.0f, 1.0f, 0.0f},
309
             {-1.0f,-1.0f, 0.0f},
310
             {-1.0f, 0.0f, 1.0f},
311
             {-1.0f, 0.0f,-1.0f},
312
             { 0.0f, 1.0f, 1.0f},
313
             { 0.0f, 1.0f,-1.0f},
314
             { 0.0f,-1.0f, 1.0f},
315
             { 0.0f,-1.0f,-1.0f},
316

    
317
             { 0.0f, 0.0f, DIFF},
318
             { 0.0f, 0.0f,-DIFF},
319
             { 0.0f, DIFF, 0.0f},
320
             { 0.0f,-DIFF, 0.0f},
321
             { DIFF, 0.0f, 0.0f},
322
             {-DIFF, 0.0f, 0.0f},
323

    
324
             { 0.0f, 1.0f, DIFF},
325
             {-DIFF, 1.0f, 0.0f},
326
             { 0.0f, 1.0f,-DIFF},
327
             { DIFF, 1.0f, 0.0f},
328
             { 0.0f,-1.0f, DIFF},
329
             {-DIFF,-1.0f, 0.0f},
330
             { 0.0f,-1.0f,-DIFF},
331
             { DIFF,-1.0f, 0.0f},
332
             { DIFF, 0.0f, 1.0f},
333
             { 0.0f,-DIFF, 1.0f},
334
             {-DIFF, 0.0f, 1.0f},
335
             { 0.0f, DIFF, 1.0f},
336
             { DIFF, 0.0f,-1.0f},
337
             { 0.0f,-DIFF,-1.0f},
338
             {-DIFF, 0.0f,-1.0f},
339
             { 0.0f, DIFF,-1.0f},
340
             { 1.0f, DIFF, 0.0f},
341
             { 1.0f, 0.0f,-DIFF},
342
             { 1.0f,-DIFF, 0.0f},
343
             { 1.0f, 0.0f, DIFF},
344
             {-1.0f, DIFF, 0.0f},
345
             {-1.0f, 0.0f,-DIFF},
346
             {-1.0f,-DIFF, 0.0f},
347
             {-1.0f, 0.0f, DIFF},
348

    
349
             { 1.0f, 1.0f, DIFF},
350
             { 1.0f, 1.0f,-DIFF},
351
             { 1.0f,-1.0f, DIFF},
352
             { 1.0f,-1.0f,-DIFF},
353
             {-1.0f, 1.0f, DIFF},
354
             {-1.0f, 1.0f,-DIFF},
355
             {-1.0f,-1.0f, DIFF},
356
             {-1.0f,-1.0f,-DIFF},
357
             { 1.0f, DIFF, 1.0f},
358
             { 1.0f,-DIFF, 1.0f},
359
             { 1.0f, DIFF,-1.0f},
360
             { 1.0f,-DIFF,-1.0f},
361
             {-1.0f, DIFF, 1.0f},
362
             {-1.0f,-DIFF, 1.0f},
363
             {-1.0f, DIFF,-1.0f},
364
             {-1.0f,-DIFF,-1.0f},
365
             { DIFF, 1.0f, 1.0f},
366
             {-DIFF, 1.0f, 1.0f},
367
             { DIFF, 1.0f,-1.0f},
368
             {-DIFF, 1.0f,-1.0f},
369
             { DIFF,-1.0f, 1.0f},
370
             {-DIFF,-1.0f, 1.0f},
371
             { DIFF,-1.0f,-1.0f},
372
             {-DIFF,-1.0f,-1.0f},
373
         };
374
      }
375

    
376
    return mPositions;
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  public Static4D getCubitQuats(int cubit, int[] numLayers)
382
    {
383
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,1,17,22,4,5,8,19,
384
                                                    6,17,7,12,4,16,9,10,0,5,3,2,
385
                                                    0,2,1,3,6,4,
386
                                                    0,4,5,6, 8,16,2,17, 21,3,20,14, 12,11,10,1, 13,18,22,7, 15,19,23,9,
387
                                                    0,18,7,2, 9,5,8,19, 13,3,1,22, 14,23,15,11, 21,4,6,10, 17,20,12,16 };
388
    return mObjectQuats[mQuatIndex[cubit]];
389
    }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

    
393
  private ObjectShape getCornerShape()
394
    {
395
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
396
    final float STEP_CORNER= (float)((Math.PI/2-2*INIT_ALPHA)/NUMBER_CORNER_SEGMENTS);
397
    final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
398
    final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
399
    final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
400
    float[][] tmp = new float[SINGLE_ARC][2];
401

    
402
    for(int i=0; i<SINGLE_ARC; i++)
403
      {
404
      float alpha = INIT_ALPHA + i*STEP_CORNER;
405
      tmp[i][0] = (float)(1.5f*DIAMETER_RATIO*Math.sin(alpha) - 1.0f);
406
      tmp[i][1] = (float)(1.5f*DIAMETER_RATIO*Math.cos(alpha) - 1.0f);
407
      }
408

    
409
    float[][] vertices = new float[NUM_VERTICES][];
410

    
411
    vertices[0] = new float[] { +0.5f, +0.5f, +0.5f };
412
    vertices[1] = new float[] { -0.5f, +0.5f, +0.5f };
413
    vertices[2] = new float[] { +0.5f, -0.5f, +0.5f };
414
    vertices[3] = new float[] { +0.5f, +0.5f, -0.5f };
415

    
416
    for(int i=0; i<SINGLE_ARC; i++)
417
      {
418
      float s = tmp[i][0];
419
      float c = tmp[i][1];
420

    
421
      vertices[4             +i] = new float[] {0.5f,+s,+c};
422
      vertices[4+  SINGLE_ARC+i] = new float[] {+c,0.5f,+s};
423
      vertices[4+2*SINGLE_ARC+i] = new float[] {+s,+c,0.5f};
424
      }
425

    
426
    final float EXTRA = (NUMBER_CORNER_SEGMENTS%2)==0 ? 1.0f : (float)Math.cos((Math.PI/2-2*INIT_ALPHA)/(2*NUMBER_CORNER_SEGMENTS));
427
    final float LEN = 1.5f*DIAMETER_RATIO*EXTRA;
428
    final float M = (float)(LEN*Math.sin(Math.PI/4) - 1.0f);
429
    vertices[4+3*SINGLE_ARC] = new float[] {M,M,M};
430

    
431
    for(int i=0; i<SINGLE_INNER_ARC; i++)
432
      {
433
      float s = tmp[i][0];
434
      float c = tmp[i][1];
435

    
436
      vertices[4+3*SINGLE_ARC+1                   +i] = new float[] {s,c,c};
437
      vertices[4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC+i] = new float[] {c,s,c};
438
      vertices[4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+i] = new float[] {c,c,s};
439
      }
440

    
441
    final int NUM_FACES = 6 + 3*NUMBER_CORNER_SEGMENTS;
442
    final int NUM_VERTS = 4 +   NUMBER_CORNER_SEGMENTS;
443

    
444
    int[][] indices = new int[NUM_FACES][];
445

    
446
    indices[0] = new int[NUM_VERTS];
447
    indices[1] = new int[NUM_VERTS];
448
    indices[2] = new int[NUM_VERTS];
449

    
450
    indices[0][0] = 3;
451
    indices[0][1] = 0;
452
    indices[0][2] = 2;
453
    indices[1][0] = 1;
454
    indices[1][1] = 0;
455
    indices[1][2] = 3;
456
    indices[2][0] = 2;
457
    indices[2][1] = 0;
458
    indices[2][2] = 1;
459

    
460
    for(int i=0; i<SINGLE_ARC; i++)
461
      {
462
      indices[0][3+i] = 4+i;
463
      indices[1][3+i] = 4+i+  SINGLE_ARC;
464
      indices[2][3+i] = 4+i+2*SINGLE_ARC;
465
      }
466

    
467
    indices[3] = new int[] { 1, 4+2*SINGLE_ARC-1, 4+3*SINGLE_ARC+1                   , 4+2*SINGLE_ARC};
468
    indices[4] = new int[] { 2, 4+3*SINGLE_ARC-1, 4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC, 4             };
469
    indices[5] = new int[] { 3, 4+  SINGLE_ARC-1, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC, 4+  SINGLE_ARC};
470

    
471
    int start,i0,i1,i2,i3;
472
    int MID = (NUMBER_CORNER_SEGMENTS)/2;
473
    int MID2= (NUMBER_CORNER_SEGMENTS+1)/2;
474

    
475
    if( (NUMBER_CORNER_SEGMENTS%2) == 0 )
476
      {
477
      start = 12;
478
      indices[ 6] = new int[] { 4+3*SINGLE_ARC, 4+SINGLE_ARC+MID, 4+SINGLE_ARC+MID-1, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+MID-1};
479
      indices[ 7] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+MID-1,  4+SINGLE_ARC+MID+1, 4+SINGLE_ARC+MID};
480
      indices[ 8] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+MID-1, 4+MID+1, 4+MID };
481
      indices[ 9] = new int[] { 4+3*SINGLE_ARC, 4+MID, 4+MID-1, 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+MID-1 };
482
      indices[10] = new int[] { 4+3*SINGLE_ARC, 4+2*SINGLE_ARC+MID, 4+2*SINGLE_ARC+MID-1, 4+3*SINGLE_ARC+1+MID-1 };
483
      indices[11] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+MID-1, 4+2*SINGLE_ARC+MID+1, 4+2*SINGLE_ARC+MID };
484
      }
485
    else
486
      {
487
      start = 9;
488
      indices[ 6] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+MID, 4+SINGLE_ARC+MID+1, 4+SINGLE_ARC+MID, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+MID};
489
      indices[ 7] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+MID,  4+MID+1, 4+MID, 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+MID};
490
      indices[ 8] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+MID, 4+2*SINGLE_ARC+MID+1, 4+2*SINGLE_ARC+MID, 4+3*SINGLE_ARC+1+MID};
491
      }
492

    
493
    for(int j=0; j<MID2-1; j++)
494
      {
495
      i0 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j;
496
      i1 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j+1;
497
      i2 = 4+SINGLE_ARC+j+1;
498
      i3 = 4+SINGLE_ARC+j;
499

    
500
      indices[start+j] = new int[] {i0,i1,i2,i3};
501

    
502
      i0 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j+1;
503
      i1 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j;
504
      i2 = 4+(SINGLE_ARC-1)-j;
505
      i3 = 4+(SINGLE_ARC-1)-(j+1);
506

    
507
      indices[start+j+(MID2-1)] = new int[] {i0,i1,i2,i3};
508

    
509
      i0 = 4+3*SINGLE_ARC+1+j;
510
      i1 = 4+3*SINGLE_ARC+1+j+1;
511
      i2 = 4+2*SINGLE_ARC+j+1;
512
      i3 = 4+2*SINGLE_ARC+j;
513

    
514
      indices[start+j+2*(MID2-1)] = new int[] {i0,i1,i2,i3};
515

    
516
      i0 = 4+3*SINGLE_ARC+1+j+1;
517
      i1 = 4+3*SINGLE_ARC+1+j;
518
      i2 = 4+(2*SINGLE_ARC-1)-j;
519
      i3 = 4+(2*SINGLE_ARC-1)-(j+1);
520

    
521
      indices[start+j+3*(MID2-1)] = new int[] {i0,i1,i2,i3};
522

    
523
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
524
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
525
      i2 = 4+j+1;
526
      i3 = 4+j;
527

    
528
      indices[start+j+4*(MID2-1)] = new int[] {i0,i1,i2,i3};
529

    
530
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
531
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
532
      i2 = 4+(3*SINGLE_ARC-1)-j;
533
      i3 = 4+(3*SINGLE_ARC-1)-(j+1);
534

    
535
      indices[start+j+5*(MID2-1)] = new int[] {i0,i1,i2,i3};
536
      }
537

    
538
    return new ObjectShape(vertices,indices);
539
    }
540

    
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

    
543
  private ObjectShape getEdgeShape()
544
    {
545
    final int NUM_VERTICES = 8 + 3*(NUMBER_EDGE_SEGMENTS-1);
546
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
547
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
548
    float[][] vertices = new float[NUM_VERTICES][];
549

    
550
    vertices[0] = new float[] {-0.5f,+0.5f,+0.5f};
551
    vertices[1] = new float[] {+0.5f,+0.5f,+0.5f};
552
    vertices[2] = new float[] {-0.5f,    H,+0.5f};
553
    vertices[3] = new float[] {+0.5f,    H,+0.5f};
554
    vertices[4] = new float[] {-0.5f,+0.5f,    H};
555
    vertices[5] = new float[] {+0.5f,+0.5f,    H};
556
    vertices[6] = new float[] {-0.5f,    H,    H};
557
    vertices[7] = new float[] {+0.5f,    H,    H};
558

    
559
    final int NUM_VERTS = NUMBER_EDGE_SEGMENTS-1;
560
    for(int i=0; i<NUM_VERTS; i++)
561
      {
562
      float beta = INIT_ALPHA*((2.0f*(i+1))/NUMBER_EDGE_SEGMENTS -1 );
563
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(beta));
564
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(beta)-1.0f);
565
      vertices[8            +i] = new float[] {A,B,0.5f};
566
      vertices[8+  NUM_VERTS+i] = new float[] {A,0.5f,B};
567
      vertices[8+2*NUM_VERTS+i] = new float[] {A,B,B};
568
      }
569

    
570
    final int NUM_FACES = 4 + 2*NUMBER_EDGE_SEGMENTS;
571
    int[][] indices = new int[NUM_FACES][];
572

    
573
    int NUMV = 3+NUMBER_EDGE_SEGMENTS;
574

    
575
    indices[0] = new int[NUMV];
576
    indices[0][0] = 3;
577
    indices[0][1] = 1;
578
    indices[0][2] = 0;
579
    indices[0][3] = 2;
580
    for(int i=0; i<NUM_VERTS; i++) indices[0][4+i] = 8+i;
581

    
582
    indices[1] = new int[NUMV];
583
    indices[1][0] = 4;
584
    indices[1][1] = 0;
585
    indices[1][2] = 1;
586
    indices[1][3] = 5;
587
    for(int i=0; i<NUM_VERTS; i++) indices[1][4+i] = 7+2*NUM_VERTS-i;
588

    
589
    indices[2] = new int[] {5,1,3,7};
590
    indices[3] = new int[] {0,4,6,2};
591
    indices[4] = new int[] {8,2,6,8+2*NUM_VERTS};
592
    indices[5] = new int[] {3,7+NUM_VERTS,7+3*NUM_VERTS,7};
593
    indices[6] = new int[] {6,4,8+NUM_VERTS,8+2*NUM_VERTS};
594
    indices[7] = new int[] {5,7,7+3*NUM_VERTS,7+2*NUM_VERTS};
595

    
596
    int i0,i1,i2,i3;
597

    
598
    for(int i=0; i<NUMBER_EDGE_SEGMENTS-2; i++)
599
      {
600
      i0 = 9+i;
601
      i1 = 8+i;
602
      i2 = 8+2*NUM_VERTS+i;
603
      i3 = 9+2*NUM_VERTS+i;
604

    
605
      indices[8+i] = new int[] {i0,i1,i2,i3};
606

    
607
      i0 = 9+2*NUM_VERTS+i;
608
      i1 = 8+2*NUM_VERTS+i;
609
      i2 = 8+NUM_VERTS+i;
610
      i3 = 9+NUM_VERTS+i;
611

    
612
      indices[8+NUMBER_EDGE_SEGMENTS-2+i] = new int[] {i0,i1,i2,i3};
613
      }
614

    
615
    return new ObjectShape(vertices,indices);
616
    }
617

    
618
///////////////////////////////////////////////////////////////////////////////////////////////////
619

    
620
  private ObjectShape getCenterShape(float D)
621
    {
622
    final float A = 0.1f;
623
    final float B = 0.2f;
624
    final float C = 0.55f+D;
625

    
626
    float[][] vertices = new float[][]
627
        {
628
            {-0.5f,-0.5f,-0.5f+D},
629
            {-0.5f,-0.5f,+0.5f+D},
630
            {-0.5f,+0.5f,-0.5f+D},
631
            {-0.5f,+0.5f,+0.5f+D},
632
            {+0.5f,-0.5f,-0.5f+D},
633
            {+0.5f,-0.5f,+0.5f+D},
634
            {+0.5f,+0.5f,-0.5f+D},
635
            {+0.5f,+0.5f,+0.5f+D},
636

    
637
            {   0,-A  , C},
638
            {   B,-A-B, C},
639
            { A+B,  -B, C},
640
            { A  ,   0, C},
641
            { A+B,   B, C},
642
            {   B, A+B, C},
643
            {   0, A  , C},
644
            {  -B, A+B, C},
645
            {-A-B,   B, C},
646
            {-A  ,   0, C},
647
            {-A-B,  -B, C},
648
            {  -B,-A-B, C},
649
        };
650

    
651
    int[][] indices = new int[][]
652
        {
653
            {1,5,7,3},
654
            {5,4,6,7},
655
            {0,1,3,2},
656
            {3,7,6,2},
657
            {0,4,5,1},
658
            {4,0,2,6},
659

    
660
            {8,9,10,11,12,13,14,15,16,17,18,19}
661
        };
662

    
663
    return new ObjectShape(vertices,indices);
664
    }
665

    
666
///////////////////////////////////////////////////////////////////////////////////////////////////
667

    
668
  private ObjectShape getBigCircleShape(float D)
669
    {
670
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
671
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
672
    final int NUM_VERTICES = 8 + 2*(NUMBER_EDGE_SEGMENTS-1);
673
    float[][] vertices = new float[NUM_VERTICES][];
674

    
675
    vertices[0] = new float[] {-0.5f,-0.5f,+0.5f+D};
676
    vertices[1] = new float[] {-0.5f,-0.5f,-0.5f+D};
677
    vertices[2] = new float[] {+0.5f,-0.5f,+0.5f+D};
678
    vertices[3] = new float[] {+0.5f,-0.5f,-0.5f+D};
679
    vertices[4] = new float[] {-0.5f,    H,+0.5f+D};
680
    vertices[5] = new float[] {-0.5f,    H,-0.5f+D};
681
    vertices[6] = new float[] {+0.5f,    H,+0.5f+D};
682
    vertices[7] = new float[] {+0.5f,    H,-0.5f+D};
683

    
684
    final int NUM_VERTS = NUMBER_EDGE_SEGMENTS-1;
685
    for(int i=0; i<NUM_VERTS; i++)
686
      {
687
      float beta = INIT_ALPHA*((2.0f*(i+1))/NUMBER_EDGE_SEGMENTS -1 );
688
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(beta));
689
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(beta)-1.0f);
690
      vertices[8          +i] = new float[] {A,B,+0.5f+D};
691
      vertices[8+NUM_VERTS+i] = new float[] {A,B,-0.5f+D};
692
      }
693

    
694
    final int NUM_FACES = 5 + NUMBER_EDGE_SEGMENTS;
695
    int[][] indices = new int[NUM_FACES][];
696

    
697
    int NUMV = 4+NUM_VERTS;
698
    indices[0] = new int[NUMV];
699
    indices[0][0] = 4;
700
    indices[0][1] = 0;
701
    indices[0][2] = 2;
702
    indices[0][3] = 6;
703
    for(int i=0; i<NUM_VERTS; i++) indices[0][4+i] = 7+NUM_VERTS-i;
704

    
705
    indices[1] = new int[NUMV];
706
    indices[1][0] = 7;
707
    indices[1][1] = 3;
708
    indices[1][2] = 1;
709
    indices[1][3] = 5;
710
    for(int i=0; i<NUM_VERTS; i++) indices[1][4+i] = 8+NUM_VERTS+i;
711

    
712
    indices[2] = new int[] {7,3,2,6};
713
    indices[3] = new int[] {4,0,1,5};
714
    indices[4] = new int[] {1,3,2,0};
715

    
716
    indices[5] = new int[] {5,4,8,8+NUM_VERTS};
717
    indices[6] = new int[] {7+NUM_VERTS,6,7,7+2*NUM_VERTS};
718

    
719
    for(int i=0; i<NUMBER_EDGE_SEGMENTS-2; i++)
720
      {
721
      int i0 = 8+i;
722
      int i1 = 9+i;
723
      int i2 = 9+NUM_VERTS+i;
724
      int i3 = 8+NUM_VERTS+i;
725

    
726
      indices[7+i] = new int[] {i0,i1,i2,i3};
727
      }
728

    
729
    return new ObjectShape(vertices,indices);
730
    }
731

    
732
///////////////////////////////////////////////////////////////////////////////////////////////////
733

    
734
  private ObjectShape getSmallCircleShape(float D)
735
    {
736
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
737
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
738
    final float STEP_CORNER= (float)((Math.PI/2-2*INIT_ALPHA)/NUMBER_CORNER_SEGMENTS);
739
    final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
740
    float[][] vertices = new float[NUM_VERTICES][];
741

    
742
    vertices[0] = new float[] {-0.5f,    H, 0.5f+D};
743
    vertices[1] = new float[] {    H,-0.5f, 0.5f+D};
744
    vertices[2] = new float[] {-0.5f,-0.5f, 0.5f+D};
745
    vertices[3] = new float[] {-0.5f,    H,-0.5f+D};
746
    vertices[4] = new float[] {    H,-0.5f,-0.5f+D};
747
    vertices[5] = new float[] {-0.5f,-0.5f,-0.5f+D};
748

    
749
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-1; i++)
750
      {
751
      float alpha = INIT_ALPHA + (i+1)*STEP_CORNER;
752
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(alpha) - 1.0f);
753
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(alpha) - 1.0f);
754

    
755
      vertices[6                       +i] = new float[] {A,B, 0.5f+D};
756
      vertices[5+NUMBER_CORNER_SEGMENTS+i] = new float[] {A,B,-0.5f+D};
757
      }
758

    
759
    final int NUM_FACES = 4 + NUMBER_CORNER_SEGMENTS;
760
    int[][] indices = new int[NUM_FACES][];
761

    
762
    int NUMV = 2+NUMBER_CORNER_SEGMENTS;
763
    indices[0] = new int[NUMV];
764
    indices[0][0] = 0;
765
    indices[0][1] = 2;
766
    indices[0][2] = 1;
767
    for(int i=3; i<NUMV; i++) indices[0][i] = 5+(NUMBER_CORNER_SEGMENTS-1)-(i-3);
768

    
769
    indices[1] = new int[NUMV];
770
    indices[1][0] = 4;
771
    indices[1][1] = 5;
772
    indices[1][2] = 3;
773
    for(int i=3; i<NUMV; i++) indices[1][i] = 5+NUMBER_CORNER_SEGMENTS+(i-3);
774

    
775
    indices[2] = new int[] {0,3,5,2};
776
    indices[3] = new int[] {1,2,5,4};
777

    
778
    indices[4] = new int[] {5+NUMBER_CORNER_SEGMENTS,3,0,6};
779
    indices[5] = new int[] {1,4,5+2*(NUMBER_CORNER_SEGMENTS-1),5+(NUMBER_CORNER_SEGMENTS-1)};
780

    
781
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-2; i++)
782
      {
783
      int i0 = 6+i;
784
      int i1 = 7+i;
785
      int i2 = 6+NUMBER_CORNER_SEGMENTS+i;
786
      int i3 = 5+NUMBER_CORNER_SEGMENTS+i;
787

    
788
      indices[6+i] = new int[] {i0,i1,i2,i3};
789
      }
790

    
791
    return new ObjectShape(vertices,indices);
792
    }
793

    
794
///////////////////////////////////////////////////////////////////////////////////////////////////
795

    
796
  public ObjectShape getObjectShape(int variant)
797
    {
798
    switch(variant)
799
      {
800
      case 0: return getCornerShape();
801
      case 1: return getEdgeShape();
802
      case 2: return getCenterShape(1.0f-DIFF);
803
      case 3: return getBigCircleShape(1.0f-DIFF);
804
      case 4: return getSmallCircleShape(1.02f-DIFF);
805
      }
806

    
807
    return null;
808
    }
809

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

    
812
  public ObjectFaceShape getObjectFaceShape(int variant)
813
    {
814
    if( variant==0 )
815
      {
816
      float h1 = isInIconMode() ? 0.001f : 0.04f;
817
      float h2 = 0.001f;
818
      float[][] bands   = { {h1,45,0.3f,0.7f,5,0,0}, {h2,5,0.3f,0.2f,5,0,0}, {h2,5,0.3f,0.2f,2,0,0} };
819
      final int NUM_BANDS = 6+3*NUMBER_CORNER_SEGMENTS;
820
      int[] bandIndices = new int[NUM_BANDS];
821
      bandIndices[0] = bandIndices[1] = bandIndices[2] = 0;
822
      bandIndices[3] = bandIndices[4] = bandIndices[5] = 1;
823
      for(int i=6; i<NUM_BANDS; i++) bandIndices[i] = 2;
824
      float[][] corners = { {0.02f,0.09f} };
825
      float[][] centers = { { 0.0f, 0.0f, 0.0f } };
826
      final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
827
      final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
828
      final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
829
      int[] indices = new int[NUM_VERTICES];
830
      indices[0] = indices[1] = indices[2] = indices[3] = 0;
831
      for(int i=4; i<NUM_VERTICES; i++) indices[i] = -1;
832
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
833
      }
834
    if( variant==1 )
835
      {
836
      float h1 = isInIconMode() ? 0.001f : 0.03f;
837
      float[][] bands   = { {h1,45,0.2f,0.4f,5,0,0}, {0.001f,1,0.3f,0.5f,3,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
838
      final int NUM_BANDS = 4 + 2*NUMBER_EDGE_SEGMENTS;
839
      int[] bandIndices = new int[NUM_BANDS];
840
      bandIndices[0] = bandIndices[1] = 0;
841
      bandIndices[2] = bandIndices[3] = 1;
842
      for(int i=4; i<NUM_BANDS; i++) bandIndices[i] = 2;
843
      float[][] corners = { {0.02f,0.09f} };
844
      float[][] centers = { { 0.0f, 0.0f, 0.0f } };
845
      final int NUM_VERTICES = 8 + 3*(NUMBER_EDGE_SEGMENTS-1);
846
      int[] indices = new int[NUM_VERTICES];
847
      indices[0] = indices[1] = indices[2] = indices[3] = indices[4] = indices[5] = 0;
848
      for(int i=6; i<NUM_VERTICES; i++) indices[i] = -1;
849
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
850
      }
851
    if( variant==2 )
852
      {
853
      float h1 = isInIconMode() ? 0.001f : 0.05f;
854
      float[][] bands   = { {h1,45,0.2f,0.4f,5,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
855
      int[] bandIndices = new int[] {0,1,1,1,1,1,1};
856
      float[][] corners = { {0.02f,0.09f} };
857
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
858
      int[] indices = new int[] {0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
859
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
860
      }
861
    if( variant==3 )
862
      {
863
      float h1 = isInIconMode() ? 0.001f : 0.03f;
864
      float[][] bands   = { {h1,45,0.2f,0.4f,5,0,0}, {0.001f,1,0.3f,0.5f,3,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
865
      final int NUM_BANDS = 5 + NUMBER_EDGE_SEGMENTS;
866
      int[] bandIndices = new int[NUM_BANDS];
867
      bandIndices[0] = 0;
868
      bandIndices[1] = 2;
869
      bandIndices[2] = bandIndices[3] = bandIndices[4] = 1;
870
      for(int i=5; i<NUM_BANDS; i++) bandIndices[i] = 2;
871
      float[][] corners = { {0.02f,0.09f} };
872
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
873
      final int NUM_VERTICES = 8 + 2*(NUMBER_EDGE_SEGMENTS-1);
874
      int[] indices = new int[NUM_VERTICES];
875
      for(int i=0; i<NUM_VERTICES; i++) indices[i] = -1;
876
      indices[0] = indices[2] = indices[4] = indices[6] = 0;
877
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
878
      }
879
    else
880
      {
881
      float h1 = isInIconMode() ? 0.001f : 0.02f;
882
      float[][] bands   = { {h1,45,0.2f,0.4f,5,0,0}, {0.001f,1,0.3f,0.5f,3,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
883
      final int NUM_BANDS = 4 + NUMBER_CORNER_SEGMENTS;
884
      int[] bandIndices = new int[NUM_BANDS];
885
      bandIndices[0] = 0;
886
      bandIndices[1] = 2;
887
      bandIndices[2] = bandIndices[3] = 1;
888
      for(int i=4; i<NUM_BANDS; i++) bandIndices[i] = 2;
889
      float[][] corners = { {0.02f,0.09f} };
890
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
891
      final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
892
      int[] indices = new int[NUM_VERTICES];
893
      for(int i=0; i<NUM_VERTICES; i++) indices[i] = -1;
894
      indices[0] = indices[1] = indices[2] = 0;
895
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
896
      }
897
    }
898

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

    
901
  public int getNumCubitVariants(int[] numLayers)
902
    {
903
    return 5;
904
    }
905

    
906
///////////////////////////////////////////////////////////////////////////////////////////////////
907

    
908
  public int getCubitVariant(int cubit, int[] numLayers)
909
    {
910
    if( cubit< 8 ) return 0;
911
    if( cubit<20 ) return 1;
912
    if( cubit<26 ) return 2;
913
    if( cubit<50 ) return 3;
914

    
915
    return 4;
916
    }
917

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

    
920
  public float getStickerRadius()
921
    {
922
    return 0.07f;
923
    }
924

    
925
///////////////////////////////////////////////////////////////////////////////////////////////////
926

    
927
  public float getStickerStroke()
928
    {
929
    return isInIconMode() ? 0.22f : 0.12f;
930
    }
931

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

    
934
  public float[][] getStickerAngles()
935
    {
936
    float D1 = (float)(Math.PI/8);
937
    float D2 = (float)(Math.PI/6);
938
    return new float[][] { { 0,0,0,-D1,0 },{ 0,0,0,-D2 },{0,0,0,0},{ 0,0,0,D2 },{ 0,0,D1 } };
939
    }
940

    
941
///////////////////////////////////////////////////////////////////////////////////////////////////
942
// PUBLIC API
943

    
944
  public Static3D[] getRotationAxis()
945
    {
946
    return ROT_AXIS;
947
    }
948

    
949
///////////////////////////////////////////////////////////////////////////////////////////////////
950

    
951
  public int[][] getBasicAngles()
952
    {
953
    if( mBasicAngle==null )
954
      {
955
      int[] tmp = new int[] {4,4,4};
956
      mBasicAngle = new int[][] { tmp,tmp,tmp };
957
      }
958

    
959
    return mBasicAngle;
960
    }
961

    
962
///////////////////////////////////////////////////////////////////////////////////////////////////
963

    
964
  public String getShortName()
965
    {
966
    int param = getInitData().getParam();
967

    
968
    switch(param)
969
      {
970
      case CRAZY  : return ObjectType.CRA1_3.name();
971
      case MERCURY: return ObjectType.CRA2_3.name();
972
      case VENUS  : return ObjectType.CRA3_3.name();
973
      case EARTH  : return ObjectType.CRA4_3.name();
974
      case MARS   : return ObjectType.CRA5_3.name();
975
      case JUPITER: return ObjectType.CRA6_3.name();
976
      case SATURN : return ObjectType.CRA7_3.name();
977
      case URANUS : return ObjectType.CRA8_3.name();
978
      case NEPTUNE: return ObjectType.CRA9_3.name();
979
      }
980

    
981
    return null;
982
    }
983

    
984
///////////////////////////////////////////////////////////////////////////////////////////////////
985

    
986
  public ObjectSignature getSignature()
987
    {
988
    int param = getInitData().getParam();
989

    
990
    switch(param)
991
      {
992
      case CRAZY  : return new ObjectSignature(ObjectType.CRA1_3);
993
      case MERCURY: return new ObjectSignature(ObjectType.CRA2_3);
994
      case VENUS  : return new ObjectSignature(ObjectType.CRA3_3);
995
      case EARTH  : return new ObjectSignature(ObjectType.CRA4_3);
996
      case MARS   : return new ObjectSignature(ObjectType.CRA5_3);
997
      case JUPITER: return new ObjectSignature(ObjectType.CRA6_3);
998
      case SATURN : return new ObjectSignature(ObjectType.CRA7_3);
999
      case URANUS : return new ObjectSignature(ObjectType.CRA8_3);
1000
      case NEPTUNE: return new ObjectSignature(ObjectType.CRA9_3);
1001
      }
1002

    
1003
    return null;
1004
    }
1005

    
1006
///////////////////////////////////////////////////////////////////////////////////////////////////
1007

    
1008
  public String getObjectName()
1009
    {
1010
    int param = getInitData().getParam();
1011

    
1012
    switch(param)
1013
      {
1014
      case CRAZY  : return "Circle 3x3";
1015
      case MERCURY: return "Crazy Plus Mercury";
1016
      case VENUS  : return "Crazy Plus Venus";
1017
      case EARTH  : return "Crazy Plus Earth";
1018
      case MARS   : return "Crazy Plus Mars";
1019
      case JUPITER: return "Crazy Plus Jupiter";
1020
      case SATURN : return "Crazy Plus Saturn";
1021
      case URANUS : return "Crazy Plus Uranus";
1022
      case NEPTUNE: return "Crazy Plus Neptune";
1023
      }
1024

    
1025
    return null;
1026
    }
1027

    
1028
///////////////////////////////////////////////////////////////////////////////////////////////////
1029

    
1030
  public String getInventor()
1031
    {
1032

    
1033
    return getInitData().getParam()==CRAZY ? "Aleh Hladzilin" : "Daqing Bao";
1034
    }
1035

    
1036
///////////////////////////////////////////////////////////////////////////////////////////////////
1037

    
1038
  public int getYearOfInvention()
1039
    {
1040
    return getInitData().getParam()==CRAZY ? 2008 : 2010;
1041
    }
1042

    
1043
///////////////////////////////////////////////////////////////////////////////////////////////////
1044

    
1045
  public int getComplexity()
1046
    {
1047
    int param = getInitData().getParam();
1048

    
1049
    switch(param)
1050
      {
1051
      case CRAZY  : return 2;
1052
      case MERCURY: return 4;
1053
      case VENUS  : return 4;
1054
      case EARTH  : return 4;
1055
      case MARS   : return 4;
1056
      case JUPITER: return 3;
1057
      case SATURN : return 4;
1058
      case URANUS : return 3;
1059
      case NEPTUNE: return 4;
1060
      }
1061

    
1062
    return 2;
1063
    }
1064

    
1065
///////////////////////////////////////////////////////////////////////////////////////////////////
1066

    
1067
  public String[][] getTutorials()
1068
    {
1069
    int param = getInitData().getParam();
1070

    
1071
    switch(param)
1072
      {
1073
      case CRAZY  : return new String[][]{
1074
                                          {"gb","7xUE8ond_Mg","Crazy 3x3x3 Cube Tutorial","SuperAntoniovivaldi"},
1075
                                          {"vn","N_AWJjHzqk0","Circle Crazy 3x3 Tutorial","VĂN CÔNG TÙNG"},
1076
                                         };
1077
      case MERCURY: return new String[][]{
1078
                                          {"gb","SeLGhxZP0E8","Crazy 3x3 Plus Mercury 1/3","SuperAntoniovivaldi"},
1079
                                          {"gb","nTBabfkdMe8","Crazy 3x3 Plus Mercury 2/3","SuperAntoniovivaldi"},
1080
                                          {"gb","Hd87z-VpTgM","Crazy 3x3 Plus Mercury 3a/3","SuperAntoniovivaldi"},
1081
                                          {"gb","MeMJ21vJLBc","Crazy 3x3 Plus Mercury 3b/3","SuperAntoniovivaldi"},
1082
                                          {"gb","s-kUXY5o5AQ","Crazy Mercury Plus Tutorial","twistypuzzling"},
1083
                                          {"es","LYMTrcGiAho","Crazy 3x3 Plus Mercurio","QBAndo"},
1084
                                          {"ru","2jtTsBwu3WY","Как собрать Crazy Mercury","RBcuber"},
1085
                                          {"fr","uxW652tv3_c","Solution crazy 3x3x3 Mercure 1/4","Laurent Boss"},
1086
                                          {"fr","QKuesX-0DaU","Solution crazy 3x3x3 Mercure 2a/4","Laurent Boss"},
1087
                                          {"fr","vDnAy1qYSCc","Solution crazy 3x3x3 Mercure 2b/4","Laurent Boss"},
1088
                                          {"fr","_eEILlsLurc","Solution crazy 3x3x3 Mercure 3/4","Laurent Boss"},
1089
                                          {"fr","4D3V9c3u7so","Solution crazy 3x3x3 Mercure 4/4","Laurent Boss"},
1090
                                          {"br","bMuDIEemCkI","Resolver Crazy Mercurio 1/5","Rafael Cinoto"},
1091
                                          {"br","FPP_nvOsnIQ","Resolver Crazy Mercurio 2/5","Rafael Cinoto"},
1092
                                          {"br","ouz20eYDlLM","Resolver Crazy Mercurio 3/5","Rafael Cinoto"},
1093
                                          {"br","IDHXszSX-UQ","Resolver Crazy Mercurio 4/5","Rafael Cinoto"},
1094
                                          {"br","Wbq701nq900","Resolver Crazy Mercurio 5/5","Rafael Cinoto"},
1095
                                          {"kr","NYBrUY9ngnc","크레이지 333 수성 1/3","듀나메스 큐브 해법연구소"},
1096
                                          {"kr","snT8xxMb0E0","크레이지 333 수성 2/3","듀나메스 큐브 해법연구소"},
1097
                                          {"kr","Pbfm3FZy_3k","크레이지 333 수성 3/3","듀나메스 큐브 해법연구소"},
1098
                                          {"vn","_1Pn2nqDF3A","Crazy Mercury 3x3 Tutorial","VĂN CÔNG TÙNG"},
1099
                                         };
1100
      case VENUS  : return new String[][]{
1101
                                          {"gb","I4f7UngHofc","Crazy 3x3 Plus Venus 1/3","SuperAntoniovivaldi"},
1102
                                          {"gb","p57W1iBXa0k","Crazy 3x3 Plus Venus 2/3","SuperAntoniovivaldi"},
1103
                                          {"gb","IUQcgfgYW3A","Crazy 3x3 Plus Venus 3/3","SuperAntoniovivaldi"},
1104
                                          {"es","L_o5b6i6iQc","Crazy 3x3 Plus Venus","QBAndo"},
1105
                                          {"ru","e6rFPDlpBoI","Как собрать Crazy Venus","Илья Топор-Гилка"},
1106
                                          {"fr","Ccu2XugYAhw","Solution crazy 3x3x3 Venus 1/6","Laurent Boss"},
1107
                                          {"fr","sz5JjDsBB4c","Solution crazy 3x3x3 Venus 2/6","Laurent Boss"},
1108
                                          {"fr","ap_m3-xY7LU","Solution crazy 3x3x3 Venus 3/6","Laurent Boss"},
1109
                                          {"fr","BkV1dyWIH1Q","Solution crazy 3x3x3 Venus 4/6","Laurent Boss"},
1110
                                          {"fr","spO_rh09h9s","Solution crazy 3x3x3 Venus 5/6","Laurent Boss"},
1111
                                          {"fr","kEmXDJgO0B4","Solution crazy 3x3x3 Venus 6/6","Laurent Boss"},
1112
                                          {"br","i781Mf0Fuag","Resolver Crazy Venus 1/3","Rafael Cinoto"},
1113
                                          {"br","3m0eyKbLaQ4","Resolver Crazy Venus 2/3","Rafael Cinoto"},
1114
                                          {"br","nKamBHo7oxo","Resolver Crazy Venus 3/3","Rafael Cinoto"},
1115
                                          {"kr","hsWfqlOa4_0","크레이지 (Crazy) 333 금성 1/5","듀나메스 큐브 해법연구소"},
1116
                                          {"kr","Z2sJczk29kg","크레이지 (Crazy) 333 금성 2/5","듀나메스 큐브 해법연구소"},
1117
                                          {"kr","8r1la2KEiBo","크레이지 (Crazy) 333 금성 3/5","듀나메스 큐브 해법연구소"},
1118
                                          {"kr","S9IcRa5AQHk","크레이지 (Crazy) 333 금성 4/5","듀나메스 큐브 해법연구소"},
1119
                                          {"kr","fs78ZSlShm0","크레이지 (Crazy) 333 금성 5/5","듀나메스 큐브 해법연구소"},
1120
                                          {"vn","_fG3VIKUwNo","Crazy Venus 3x3 Tutorial","VĂN CÔNG TÙNG"},
1121
                                         };
1122
      case EARTH  : return new String[][]{
1123
                                          {"gb","brNQ6Nl1-Mw","Crazy 3x3 Plus Earth 1/4","SuperAntoniovivaldi"},
1124
                                          {"gb","-3RSoC5OZGc","Crazy 3x3 Plus Earth 2/4","SuperAntoniovivaldi"},
1125
                                          {"gb","ahuXWFLTKRg","Crazy 3x3 Plus Earth 3/4","SuperAntoniovivaldi"},
1126
                                          {"gb","Lwt-7XKesUg","Crazy 3x3 Plus Earth 4/4","SuperAntoniovivaldi"},
1127
                                          {"es","GFHcLpYF620","Crazy 3x3 Plus Tierra","QBAndo"},
1128
                                          {"ru","YmEoI0XI5E4","Как собрать Crazy Earth","Илья Топор-Гилка"},
1129
                                          {"fr","QT4T4JV-L44","Solution crazy 3x3x3 Terre 1/6","Laurent Boss"},
1130
                                          {"fr","8On3fbrG5aA","Solution crazy 3x3x3 Terre 2/6","Laurent Boss"},
1131
                                          {"fr","IPEvUnVumJg","Solution crazy 3x3x3 Terre 3/6","Laurent Boss"},
1132
                                          {"fr","0awyEJmfuMM","Solution crazy 3x3x3 Terre 4/6","Laurent Boss"},
1133
                                          {"fr","xLKGyRXuaGs","Solution crazy 3x3x3 Terre 5/6","Laurent Boss"},
1134
                                          {"fr","CcunFHHhQ7g","Solution crazy 3x3x3 Terre 6/6","Laurent Boss"},
1135
                                          {"kr","4YBV9TnAzlg","크레이지(Crazy) 333 지구 1/5","듀나메스 큐브 해법연구소"},
1136
                                          {"kr","uWbAgUq-IqU","크레이지(Crazy) 333 지구 2/5","듀나메스 큐브 해법연구소"},
1137
                                          {"kr","glZqE9hQXK8","크레이지(Crazy) 333 지구 3/5","듀나메스 큐브 해법연구소"},
1138
                                          {"kr","WF2RGp8E97k","크레이지(Crazy) 333 지구 4/5","듀나메스 큐브 해법연구소"},
1139
                                          {"kr","RC-w26wLtQg","크레이지(Crazy) 333 지구 5/5","듀나메스 큐브 해법연구소"},
1140
                                          {"vn","MsFqHGuWspE","Crazy Earth 3x3 Tutorial","VĂN CÔNG TÙNG"},
1141
                                         };
1142
      case MARS   : return new String[][]{
1143
                                          {"gb","AJC0dZx2T-M","Crazy 3x3 Plus Mars 1/4","SuperAntoniovivaldi"},
1144
                                          {"gb","BcrYXklwEow","Crazy 3x3 Plus Mars 2/4","SuperAntoniovivaldi"},
1145
                                          {"gb","L_Y0qRG8F-0","Crazy 3x3 Plus Mars 3/4","SuperAntoniovivaldi"},
1146
                                          {"gb","PRyeKOV0Pbg","Crazy 3x3 Plus Mars 4/4","SuperAntoniovivaldi"},
1147
                                          {"es","P5NsxqMx9Bo","Crazy 3x3 Plus Marte","QBAndo"},
1148
                                          {"ru","syzb9hOojEs","Как собрать Crazy Mars","Илья Топор-Гилка"},
1149
                                          {"fr","tSqak16XJjw","Solution crazy 3x3x3 Mars 1/6","Laurent Boss"},
1150
                                          {"fr","Dm47WsF8OZg","Solution crazy 3x3x3 Mars 2/6","Laurent Boss"},
1151
                                          {"fr","gl-VL1NAslY","Solution crazy 3x3x3 Mars 3/6","Laurent Boss"},
1152
                                          {"fr","TlgsnVdkNh4","Solution crazy 3x3x3 Mars 4/6","Laurent Boss"},
1153
                                          {"fr","XxVeGY1IYIc","Solution crazy 3x3x3 Mars 5/6","Laurent Boss"},
1154
                                          {"fr","aK9YYEYMsyA","Solution crazy 3x3x3 Mars 6/6","Laurent Boss"},
1155
                                          {"kr","QKu2p9nNxFk","크레이지 333 화성 1/4","듀나메스 큐브 해법연구소"},
1156
                                          {"kr","f5YYqm6PPms","크레이지 333 화성 2a/4","듀나메스 큐브 해법연구소"},
1157
                                          {"kr","nmNxrpvucIg","크레이지 333 화성 2b/4","듀나메스 큐브 해법연구소"},
1158
                                          {"kr","rJLpMPCEc_s","크레이지 333 화성 3/4","듀나메스 큐브 해법연구소"},
1159
                                          {"kr","bBRAfOvUu8M","크레이지 333 화성 4/4","듀나메스 큐브 해법연구소"},
1160
                                          {"vn","lzw0Gfi-dM8","Crazy Mars 3x3 Tutorial","VĂN CÔNG TÙNG"},
1161
                                         };
1162
      case JUPITER: return new String[][]{
1163
                                          {"gb","HMnbVoOPk5E","Crazy 3x3 Plus Jupiter 1/2","SuperAntoniovivaldi"},
1164
                                          {"gb","Nw-LBWVu7yM","Crazy 3x3 Plus Jupiter 2/2","SuperAntoniovivaldi"},
1165
                                          {"es","p2HTOQZNfx4","Crazy 3x3 Plus Jupiter","QBAndo"},
1166
                                          {"ru","PGiYCgJYPAY","Как собрать Crazy Jupiter","RBcuber"},
1167
                                          {"fr","sKi_cXmywVs","Solution crazy 3x3x3 Jupiter 1/3","Laurent Boss"},
1168
                                          {"fr","HYnQCifSzFY","Solution crazy 3x3x3 Jupiter 2/3","Laurent Boss"},
1169
                                          {"fr","DNfV8gnaRXw","Solution crazy 3x3x3 Jupiter 3/3","Laurent Boss"},
1170
                                          {"pl","eJmQ50vcQcU","Crazy 3x3 Jupiter TUTORIAL PL","MrUK"},
1171
                                          {"br","pwYhThiSKLQ","Resolver Crazy Jupiter 1/2","Rafael Cinoto"},
1172
                                          {"br","VhuBtUU866U","Resolver Crazy Jupiter 2/2","Rafael Cinoto"},
1173
                                          {"kr","WQ3ad3DrBwY","크레이지 333 목성 1/2","듀나메스 큐브 해법연구소"},
1174
                                          {"kr","3LLL34HsqUs","크레이지 333 목성 2/2","듀나메스 큐브 해법연구소"},
1175
                                          {"vn","QH4ywmKNGVo","Jupiter Crazy Plus Tutorial","VĂN CÔNG TÙNG"},
1176
                                         };
1177
      case SATURN : return new String[][]{
1178
                                          {"gb","7fPXML8hZ-I","Crazy 3x3 Plus Saturn 1/3","SuperAntoniovivaldi"},
1179
                                          {"gb","ixVVVoxsg4A","Crazy 3x3 Plus Saturn 2/3","SuperAntoniovivaldi"},
1180
                                          {"gb","Dd8ZaGzbvjE","Crazy 3x3 Plus Saturn 3/3","SuperAntoniovivaldi"},
1181
                                          {"es","EyQXl0llt2M","Crazy 3x3 Plus Saturno","QBAndo"},
1182
                                          {"ru","T2uYDHyQZnE","Как собрать Crazy Saturn","Илья Топор-Гилка"},
1183
                                          {"fr","kuSYpTXoXUM","Solution crazy 3x3x3 Saturn 1/6","Laurent Boss"},
1184
                                          {"fr","u1OsRGuBcHA","Solution crazy 3x3x3 Saturn 2/6","Laurent Boss"},
1185
                                          {"fr","ra0MspIkctU","Solution crazy 3x3x3 Saturn 3/6","Laurent Boss"},
1186
                                          {"fr","dm3WBtGdxYA","Solution crazy 3x3x3 Saturn 4/6","Laurent Boss"},
1187
                                          {"fr","jVwPmbYot_U","Solution crazy 3x3x3 Saturn 5/6","Laurent Boss"},
1188
                                          {"fr","raYIoRIZPmc","Solution crazy 3x3x3 Saturn 6/6","Laurent Boss"},
1189
                                          {"br","0oKu1NXiQcY","Resolver Crazy Saturn 1/4","Rafael Cinoto"},
1190
                                          {"br","bRD73Lb1NTw","Resolver Crazy Saturn 2/4","Rafael Cinoto"},
1191
                                          {"br","v9nZrwCyNLs","Resolver Crazy Saturn 3/4","Rafael Cinoto"},
1192
                                          {"br","aipwvc2udbM","Resolver Crazy Saturn 4/4","Rafael Cinoto"},
1193
                                          {"kr","hfogu6lCLvs","크레이지 (Crazy) 333 토성 1/5","듀나메스 큐브 해법연구소"},
1194
                                          {"kr","rKjRzKxXHyA","크레이지 (Crazy) 333 토성 2/5","듀나메스 큐브 해법연구소"},
1195
                                          {"kr","7tKfu5RJCVc","크레이지 (Crazy) 333 토성 3/5","듀나메스 큐브 해법연구소"},
1196
                                          {"kr","L68nVvMhxVc","크레이지 (Crazy) 333 토성 4/5","듀나메스 큐브 해법연구소"},
1197
                                          {"kr","fvOcR9-TQpA","크레이지 (Crazy) 333 토성 5/5","듀나메스 큐브 해법연구소"},
1198
                                          {"vn","jiGMQ9Mn14w","Saturn Crazy Plus Tutorial","VĂN CÔNG TÙNG"},
1199
                                         };
1200
      case URANUS : return new String[][]{
1201
                                          {"gb","wOyVb2TMZlk","Crazy 3x3 Plus Uranus 1/3","SuperAntoniovivaldi"},
1202
                                          {"gb","UbTBBQ-gvk0","Crazy 3x3 Plus Uranus 2/3","SuperAntoniovivaldi"},
1203
                                          {"gb","_7k57cV81BM","Crazy 3x3 Plus Uranus 3/3","SuperAntoniovivaldi"},
1204
                                          {"es","vuPcyvE6EVE","Crazy 3x3 Plus Urano","QBAndo"},
1205
                                          {"ru","tm6sxFSeeBg","Как собрать Crazy Uranus","Илья Топор-Гилка"},
1206
                                          {"fr","i9lU26McP38","Solution crazy 3x3x3 Uranus 1/4","Laurent Boss"},
1207
                                          {"fr","Zr6fTayObJk","Solution crazy 3x3x3 Uranus 2/4","Laurent Boss"},
1208
                                          {"fr","nCmCxrY_QMU","Solution crazy 3x3x3 Uranus 3/4","Laurent Boss"},
1209
                                          {"fr","YNs8IohERKs","Solution crazy 3x3x3 Uranus 4/4","Laurent Boss"},
1210
                                          {"pl","pKPQJoGJtno","Crazy 3x3 Uranus TUTORIAL PL","MrUK"},
1211
                                          {"br","jjcqHXOD9eo","Resolver Crazy Urano 1/2","Rafael Cinoto"},
1212
                                          {"br","1B73Z2XE2ss","Resolver Crazy Urano 2/2","Rafael Cinoto"},
1213
                                          {"kr","_m3S5DiVRMw","크레이지 333 천왕성 1/2","듀나메스 큐브 해법연구소"},
1214
                                          {"kr","z9Wh6FXr0og","크레이지 333 천왕성 2/2","듀나메스 큐브 해법연구소"},
1215
                                          {"vn","bHiQ3YSEb2I","Uranus Crazy Plus Tutorial","VĂN CÔNG TÙNG"},
1216
                                         };
1217
      case NEPTUNE: return new String[][]{
1218
                                          {"gb","1gFmuFpU5-Y","Crazy 3x3 Plus Neptune 1a/4","SuperAntoniovivaldi"},
1219
                                          {"gb","UPRIH0MtmPM","Crazy 3x3 Plus Neptune 1b/4","SuperAntoniovivaldi"},
1220
                                          {"gb","Trqruz1NZ5E","Crazy 3x3 Plus Neptune 2/4","SuperAntoniovivaldi"},
1221
                                          {"gb","1gFmuFpU5-Y","Crazy 3x3 Plus Neptune 3/4","SuperAntoniovivaldi"},
1222
                                          {"gb","Rfa5y8NGqdY","Crazy 3x3 Plus Neptune 4/4","SuperAntoniovivaldi"},
1223
                                          {"es","LOR1cNs4NWM","Crazy 3x3 Plus Neptuno","QBAndo"},
1224
                                          {"ru","qvaRxJJrdi8","Как собрать Crazy Neptune","Илья Топор-Гилка"},
1225
                                          {"kr","6Avdw2zX5XI","크레이지 333 해왕성 1/2","듀나메스 큐브 해법연구소"},
1226
                                          {"kr","YbfWfDDBN9k","크레이지 333 해왕성 2/2","듀나메스 큐브 해법연구소"},
1227
                                          {"vn","hmf1YShJuZg","Neptune Crazy Plus Tutorial","VĂN CÔNG TÙNG"},
1228
                                         };
1229
      }
1230

    
1231
    return null;
1232
    }
1233
}
(5-5/36)