Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCrazy2x2.java @ f925d455

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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 java.io.InputStream;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.library.type.Static4D;
16
import org.distorted.objectlib.helpers.FactoryCubit;
17
import org.distorted.objectlib.helpers.ObjectFaceShape;
18
import org.distorted.objectlib.helpers.ObjectShape;
19
import org.distorted.objectlib.helpers.ObjectSignature;
20
import org.distorted.objectlib.helpers.ObjectVertexEffects;
21
import org.distorted.objectlib.main.Cubit;
22
import org.distorted.objectlib.main.InitData;
23
import org.distorted.objectlib.main.ObjectType;
24
import org.distorted.objectlib.shape.ShapeHexahedron;
25
import org.distorted.objectlib.scrambling.ScrambleState;
26
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
27

    
28
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
29
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
30

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

    
33
public class TwistyCrazy2x2 extends ShapeHexahedron
34
{
35
  private static final float DIAMETER_RATIO = 0.60f;
36
  private static final float DIFF = 1.0f;
37
  private static final int NUMBER_CORNER_SEGMENTS = 4;
38

    
39
  static final Static3D[] ROT_AXIS = new Static3D[]
40
         {
41
           new Static3D(1,0,0),
42
           new Static3D(0,1,0),
43
           new Static3D(0,0,1)
44
         };
45

    
46
  private ScrambleState[] mStates;
47
  private int[][] mBasicAngle;
48
  private float[][] mCuts;
49
  private float[][] mPositions;
50
  private int[] mQuatIndex;
51
  private float[][] mOffsets;
52

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

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

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  @Override
63
  public void adjustStickerCoords()
64
    {
65
    final float A = 0.50000f;
66
    final float B = 0.45424f;
67
    final float C = 0.11830f;
68

    
69
    mStickerCoords = new float[][]
70
      {
71
        {  B, A,-A, A,-A,-B,-C,-B, B, C },
72
        { -A, A,-A,-A, A,-A }
73
      };
74
    }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  @Override
79
  public int getCubitRotationType(int cubit)
80
    {
81
    return cubit<8 ? Cubit.TYPE_NORMAL : ( cubit<11 ? Cubit.TYPE_DECIDER : Cubit.TYPE_FOLLOWER);
82
    }
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  @Override
87
  public float[] getCubitRowOffset(int cubitIndex)
88
    {
89
    if( mOffsets==null )
90
      {
91
      float[] tmp = new float[] {0,0,0};
92
      int numCubits = mPositions.length;
93
      mOffsets = new float[numCubits][];
94

    
95
      for(int i=0; i<numCubits; i++)
96
        {
97
        switch(i)
98
          {
99
          case  8: mOffsets[i] = new float[] { 1,0,0}; break;
100
          case  9: mOffsets[i] = new float[] {0, 1,0}; break;
101
          case 10: mOffsets[i] = new float[] {0,0,-1}; break;
102
          default: mOffsets[i] = tmp;
103
          }
104
        }
105
      }
106

    
107
    return mOffsets[cubitIndex];
108
    }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111
// Normal 2x2
112

    
113
  public ScrambleState[] getScrambleStates()
114
    {
115
    if( mStates==null )
116
      {
117
      int[] m = new int[] { 0,-1,0,0,1,0,0,2,0, 1,-1,0,1,1,0,1,2,0 };
118

    
119
      mStates = new ScrambleState[]
120
          {
121
          new ScrambleState( new int[][] { m,m,m } )
122
          };
123
      }
124

    
125
    return mStates;
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  public float[][] getCuts(int[] numLayers)
131
    {
132
    if( mCuts==null )
133
      {
134
      float[] cut = new float[] {0};
135
      mCuts = new float[][] { cut,cut,cut };
136
      }
137

    
138
    return mCuts;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  public boolean[][] getLayerRotatable(int[] numLayers)
144
    {
145
    boolean[] tmp = new boolean[] {true,true};
146
    return new boolean[][] { tmp,tmp,tmp };
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  public int getTouchControlType()
152
    {
153
    return TC_HEXAHEDRON;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  public int getTouchControlSplit()
159
    {
160
    return TYPE_NOT_SPLIT;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  public int[][][] getEnabled()
166
    {
167
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  public float[] getDist3D(int[] numLayers)
173
    {
174
    return TouchControlHexahedron.D3D;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  public Static3D[] getFaceAxis()
180
    {
181
    return TouchControlHexahedron.FACE_AXIS;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  public float[][] getCubitPositions(int[] numLayers)
187
    {
188
    if( mPositions==null )
189
      {
190
      final float E = -DIFF+0.5f;
191

    
192
      mPositions = new float[][]
193
         {
194
             { 0.5f, 0.5f, 0.5f},
195
             { 0.5f, 0.5f,-0.5f},
196
             { 0.5f,-0.5f, 0.5f},
197
             { 0.5f,-0.5f,-0.5f},
198
             {-0.5f, 0.5f, 0.5f},
199
             {-0.5f, 0.5f,-0.5f},
200
             {-0.5f,-0.5f, 0.5f},
201
             {-0.5f,-0.5f,-0.5f},
202

    
203
             { E, 0.5f,-0.5f}, //
204
             { 0.5f, E,-0.5f}, // Deciders first
205
             { 0.5f, 0.5f,-E}, //
206

    
207
             { 0.5f, 0.5f, E},
208

    
209
             { 0.5f,-0.5f, E},
210
             { 0.5f,-0.5f,-E},
211
             {-0.5f, 0.5f, E},
212
             {-0.5f, 0.5f,-E},
213
             {-0.5f,-0.5f, E},
214
             {-0.5f,-0.5f,-E},
215
             { 0.5f, E, 0.5f},
216
             { 0.5f,-E, 0.5f},
217

    
218
             { 0.5f,-E,-0.5f},
219
             {-0.5f, E, 0.5f},
220
             {-0.5f,-E, 0.5f},
221
             {-0.5f, E,-0.5f},
222
             {-0.5f,-E,-0.5f},
223
             { E, 0.5f, 0.5f},
224
             {-E, 0.5f, 0.5f},
225

    
226
             {-E, 0.5f,-0.5f},
227
             { E,-0.5f, 0.5f},
228
             {-E,-0.5f, 0.5f},
229
             { E,-0.5f,-0.5f},
230
             {-E,-0.5f,-0.5f},
231
         };
232
      }
233

    
234
    return mPositions;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  public Static4D getCubitQuats(int cubit, int[] numLayers)
240
    {
241
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,1,17,22,4,5,8,19,
242
                                                    6,1,18,
243
                                                    0,7,2, 9,5,8,19, 13,3,22, 14,23,15,11, 21,4,10, 17,20,12,16 };
244
    return mObjectQuats[mQuatIndex[cubit]];
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  private float[][] getVertices(int variant)
250
    {
251
    if( variant==0 )
252
      {
253
      final float INIT_ALPHA = 0.0f;
254
      final float STEP_CORNER= (float)((Math.PI/2)/NUMBER_CORNER_SEGMENTS);
255
      final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
256
      final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
257
      final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
258
      float[][] tmp = new float[SINGLE_ARC][2];
259

    
260
      for(int i=0; i<SINGLE_ARC; i++)
261
        {
262
        float alpha = INIT_ALPHA + i*STEP_CORNER;
263
        tmp[i][0] = (float)(DIAMETER_RATIO*Math.sin(alpha) - 0.5f);
264
        tmp[i][1] = (float)(DIAMETER_RATIO*Math.cos(alpha) - 0.5f);
265
        }
266

    
267
      float[][] vertices = new float[NUM_VERTICES][];
268

    
269
      vertices[0] = new float[] { +0.5f, +0.5f, +0.5f };
270
      vertices[1] = new float[] { -0.5f, +0.5f, +0.5f };
271
      vertices[2] = new float[] { +0.5f, -0.5f, +0.5f };
272
      vertices[3] = new float[] { +0.5f, +0.5f, -0.5f };
273

    
274
      for(int i=0; i<SINGLE_ARC; i++)
275
        {
276
        float s = tmp[i][0];
277
        float c = tmp[i][1];
278

    
279
        vertices[4             +i] = new float[] {0.5f,+s,+c};
280
        vertices[4+  SINGLE_ARC+i] = new float[] {+c,0.5f,+s};
281
        vertices[4+2*SINGLE_ARC+i] = new float[] {+s,+c,0.5f};
282
        }
283

    
284
      final float EXTRA = (NUMBER_CORNER_SEGMENTS%2)==0 ? 1.0f : (float)Math.cos((Math.PI/2)/(2*NUMBER_CORNER_SEGMENTS));
285
      final float LEN   = DIAMETER_RATIO*EXTRA;
286
      final float M     = (float)(LEN*Math.sin(Math.PI/4) - 0.5f);
287
      vertices[4+3*SINGLE_ARC] = new float[] {M,M,M};
288

    
289
      for(int i=0; i<SINGLE_INNER_ARC; i++)
290
        {
291
        float s = tmp[i][0];
292
        float c = tmp[i][1];
293

    
294
        vertices[4+3*SINGLE_ARC+1                   +i] = new float[] {s,c,c};
295
        vertices[4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC+i] = new float[] {c,s,c};
296
        vertices[4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+i] = new float[] {c,c,s};
297
        }
298
      return vertices;
299
      }
300
    else
301
      {
302
      final float D = DIFF+0.02f;
303
      final float H = DIAMETER_RATIO-0.5f;
304
      final float INIT_ALPHA = 0;
305
      final float STEP_CORNER= (float)((Math.PI/2)/NUMBER_CORNER_SEGMENTS);
306
      final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
307
      float[][] vertices = new float[NUM_VERTICES][];
308

    
309
      vertices[0] = new float[] {-0.5f,    H, 0.5f+D};
310
      vertices[1] = new float[] {    H,-0.5f, 0.5f+D};
311
      vertices[2] = new float[] {-0.5f,-0.5f, 0.5f+D};
312
      vertices[3] = new float[] {-0.5f,    H,-0.5f+D};
313
      vertices[4] = new float[] {    H,-0.5f,-0.5f+D};
314
      vertices[5] = new float[] {-0.5f,-0.5f,-0.5f+D};
315

    
316
      for(int i=0; i<NUMBER_CORNER_SEGMENTS-1; i++)
317
        {
318
        float alpha = INIT_ALPHA + (i+1)*STEP_CORNER;
319
        float A = (float)(DIAMETER_RATIO*Math.sin(alpha) - 0.5f);
320
        float B = (float)(DIAMETER_RATIO*Math.cos(alpha) - 0.5f);
321

    
322
        vertices[6                       +i] = new float[] {A,B, 0.5f+D};
323
        vertices[5+NUMBER_CORNER_SEGMENTS+i] = new float[] {A,B,-0.5f+D};
324
        }
325
      return vertices;
326
      }
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  private ObjectShape getCornerShape()
332
    {
333
    final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
334
    final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
335
    final int NUM_FACES = 6 + 3*NUMBER_CORNER_SEGMENTS;
336
    final int NUM_VERTS = 4 +   NUMBER_CORNER_SEGMENTS;
337

    
338
    int[][] indices = new int[NUM_FACES][];
339

    
340
    indices[0] = new int[NUM_VERTS];
341
    indices[1] = new int[NUM_VERTS];
342
    indices[2] = new int[NUM_VERTS];
343

    
344
    indices[0][0] = 3;
345
    indices[0][1] = 0;
346
    indices[0][2] = 2;
347
    indices[1][0] = 1;
348
    indices[1][1] = 0;
349
    indices[1][2] = 3;
350
    indices[2][0] = 2;
351
    indices[2][1] = 0;
352
    indices[2][2] = 1;
353

    
354
    for(int i=0; i<SINGLE_ARC; i++)
355
      {
356
      indices[0][3+i] = 4+i;
357
      indices[1][3+i] = 4+i+  SINGLE_ARC;
358
      indices[2][3+i] = 4+i+2*SINGLE_ARC;
359
      }
360

    
361
    indices[3] = new int[] { 1, 4+2*SINGLE_ARC-1, 4+3*SINGLE_ARC+1                   , 4+2*SINGLE_ARC};
362
    indices[4] = new int[] { 2, 4+3*SINGLE_ARC-1, 4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC, 4             };
363
    indices[5] = new int[] { 3, 4+  SINGLE_ARC-1, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC, 4+  SINGLE_ARC};
364

    
365
    int start,i0,i1,i2,i3;
366
    int MID = (NUMBER_CORNER_SEGMENTS)/2;
367
    int MID2= (NUMBER_CORNER_SEGMENTS+1)/2;
368

    
369
    if( (NUMBER_CORNER_SEGMENTS%2) == 0 )
370
      {
371
      start = 12;
372
      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};
373
      indices[ 7] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+MID-1,  4+SINGLE_ARC+MID+1, 4+SINGLE_ARC+MID};
374
      indices[ 8] = new int[] { 4+3*SINGLE_ARC, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+MID-1, 4+MID+1, 4+MID };
375
      indices[ 9] = new int[] { 4+3*SINGLE_ARC, 4+MID, 4+MID-1, 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+MID-1 };
376
      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 };
377
      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 };
378
      }
379
    else
380
      {
381
      start = 9;
382
      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};
383
      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};
384
      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};
385
      }
386

    
387
    for(int j=0; j<MID2-1; j++)
388
      {
389
      i0 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j;
390
      i1 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j+1;
391
      i2 = 4+SINGLE_ARC+j+1;
392
      i3 = 4+SINGLE_ARC+j;
393

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

    
396
      i0 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j+1;
397
      i1 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j;
398
      i2 = 4+(SINGLE_ARC-1)-j;
399
      i3 = 4+(SINGLE_ARC-1)-(j+1);
400

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

    
403
      i0 = 4+3*SINGLE_ARC+1+j;
404
      i1 = 4+3*SINGLE_ARC+1+j+1;
405
      i2 = 4+2*SINGLE_ARC+j+1;
406
      i3 = 4+2*SINGLE_ARC+j;
407

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

    
410
      i0 = 4+3*SINGLE_ARC+1+j+1;
411
      i1 = 4+3*SINGLE_ARC+1+j;
412
      i2 = 4+(2*SINGLE_ARC-1)-j;
413
      i3 = 4+(2*SINGLE_ARC-1)-(j+1);
414

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

    
417
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
418
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
419
      i2 = 4+j+1;
420
      i3 = 4+j;
421

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

    
424
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
425
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
426
      i2 = 4+(3*SINGLE_ARC-1)-j;
427
      i3 = 4+(3*SINGLE_ARC-1)-(j+1);
428

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

    
432
    float[][] vertices = getVertices(0);
433
    return new ObjectShape(vertices,indices);
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  private ObjectShape getSmallCircleShape()
439
    {
440
    final int NUM_FACES = 4 + NUMBER_CORNER_SEGMENTS;
441
    int[][] indices = new int[NUM_FACES][];
442

    
443
    int NUMV = 2+NUMBER_CORNER_SEGMENTS;
444
    indices[0] = new int[NUMV];
445
    indices[0][0] = 0;
446
    indices[0][1] = 2;
447
    indices[0][2] = 1;
448
    for(int i=3; i<NUMV; i++) indices[0][i] = 5+(NUMBER_CORNER_SEGMENTS-1)-(i-3);
449

    
450
    indices[1] = new int[NUMV];
451
    indices[1][0] = 4;
452
    indices[1][1] = 5;
453
    indices[1][2] = 3;
454
    for(int i=3; i<NUMV; i++) indices[1][i] = 5+NUMBER_CORNER_SEGMENTS+(i-3);
455

    
456
    indices[2] = new int[] {0,3,5,2};
457
    indices[3] = new int[] {1,2,5,4};
458

    
459
    indices[4] = new int[] {5+NUMBER_CORNER_SEGMENTS,3,0,6};
460
    indices[5] = new int[] {1,4,5+2*(NUMBER_CORNER_SEGMENTS-1),5+(NUMBER_CORNER_SEGMENTS-1)};
461

    
462
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-2; i++)
463
      {
464
      int i0 = 6+i;
465
      int i1 = 7+i;
466
      int i2 = 6+NUMBER_CORNER_SEGMENTS+i;
467
      int i3 = 5+NUMBER_CORNER_SEGMENTS+i;
468

    
469
      indices[6+i] = new int[] {i0,i1,i2,i3};
470
      }
471

    
472
    float[][] vertices = getVertices(1);
473
    return new ObjectShape(vertices,indices);
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public ObjectShape getObjectShape(int variant)
479
    {
480
    switch(variant)
481
      {
482
      case 0: return getCornerShape();
483
      case 1: return getSmallCircleShape();
484
      }
485

    
486
    return null;
487
    }
488

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

    
491
  public ObjectFaceShape getObjectFaceShape(int variant)
492
    {
493
    if( variant==0 )
494
      {
495
      float h1 = isInIconMode() ? 0.001f : 0.04f;
496
      float h2 = 0.001f;
497
      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} };
498
      final int NUM_BANDS = 6+3*NUMBER_CORNER_SEGMENTS;
499
      int[] indices = new int[NUM_BANDS];
500
      indices[0] = indices[1] = indices[2] = indices[3] = indices[4] = indices[5] = 0;
501
      for(int i=6; i<NUM_BANDS; i++) indices[i] = 2;
502
      return new ObjectFaceShape(bands,indices,null);
503
      }
504
    else
505
      {
506
      float h1 = isInIconMode() ? 0.001f : 0.03f;
507
      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} };
508
      final int NUM_BANDS = 4 + NUMBER_CORNER_SEGMENTS;
509
      int[] indices = new int[NUM_BANDS];
510
      indices[0] = 0;
511
      indices[1] = 2;
512
      indices[2] = indices[3] = 1;
513
      for(int i=4; i<NUM_BANDS; i++) indices[i] = 2;
514
      return new ObjectFaceShape(bands,indices,null);
515
      }
516
    }
517

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519

    
520
  public ObjectVertexEffects getVertexEffects(int variant)
521
    {
522
    if( variant==0 )
523
      {
524
      float[][] corners = { {0.02f,0.09f} };
525
      float[][] centers = { { 0.0f, 0.0f, 0.0f } };
526
      final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
527
      final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
528
      final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
529
      int[] indices = new int[NUM_VERTICES];
530
      indices[0] = indices[1] = indices[2] = indices[3] = 0;
531
      for(int i=4; i<NUM_VERTICES; i++) indices[i] = -1;
532
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
533
      }
534
    else
535
      {
536
      float[][] corners = { {0.02f,0.09f} };
537
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
538
      final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
539
      int[] indices = new int[NUM_VERTICES];
540
      for(int i=0; i<NUM_VERTICES; i++) indices[i] = -1;
541
      indices[0] = indices[1] = indices[2] = 0;
542
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
543
      }
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
  public int getNumCubitVariants(int[] numLayers)
549
    {
550
    return 2;
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  public int getCubitVariant(int cubit, int[] numLayers)
556
    {
557
    return cubit<8?0:1;
558
    }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
  public float getStickerRadius()
563
    {
564
    return 0.07f;
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
  public float getStickerStroke()
570
    {
571
    return isInIconMode() ? 0.17f : 0.12f;
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  public float[][] getStickerAngles()
577
    {
578
    float D = (float)(Math.PI/4);
579
    return new float[][] { { 0,0,0,-D,0 },{ 0,0,D } };
580
    }
581

    
582
///////////////////////////////////////////////////////////////////////////////////////////////////
583
// PUBLIC API
584

    
585
  public Static3D[] getRotationAxis()
586
    {
587
    return ROT_AXIS;
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  public int[][] getBasicAngles()
593
    {
594
    if( mBasicAngle==null )
595
      {
596
      int[] tmp = new int[] {4,4,4};
597
      mBasicAngle = new int[][] { tmp,tmp,tmp };
598
      }
599

    
600
    return mBasicAngle;
601
    }
602

    
603
///////////////////////////////////////////////////////////////////////////////////////////////////
604

    
605
  public String getShortName()
606
    {
607
    return ObjectType.CRA1_2.name();
608
    }
609

    
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611

    
612
  public ObjectSignature getSignature()
613
    {
614
    return new ObjectSignature(ObjectType.CRA1_2);
615
    }
616

    
617
///////////////////////////////////////////////////////////////////////////////////////////////////
618

    
619
  public String getObjectName()
620
    {
621
    return "Circle 2x2";
622
    }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
  public String getInventor()
627
    {
628
    return "Aleh Hladzilin";
629
    }
630

    
631
///////////////////////////////////////////////////////////////////////////////////////////////////
632

    
633
  public int getYearOfInvention()
634
    {
635
    return 2007;
636
    }
637

    
638
///////////////////////////////////////////////////////////////////////////////////////////////////
639

    
640
  public int getComplexity()
641
    {
642
    return 2;
643
    }
644

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

    
647
  public String[][] getTutorials()
648
    {
649
     return new String[][] {
650
                            {"gb","DKLIQghl66c","Circle 2x2 Demonstration","SuperAntoniovivaldi"},
651
                            {"es","Wq9lwfDfg4E","Resolucion del 2x2 Crazy","RUBIKworld"},
652
                            {"es","K4bFs4BFdXc","Tutorial Crazy 2x2 de Sengso","Manzacuber"},
653
                            {"vn","TlT5MYiz4RY","Tutorial N.216 Circular 2x2","Duy Thích Rubik"},
654
                           };
655
    }
656
}
(6-6/41)