Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCrazy.java @ 8216df90

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

    
24
import org.distorted.library.type.Static3D;
25
import org.distorted.library.type.Static4D;
26
import org.distorted.objectlib.helpers.FactoryCubit;
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.main.ObjectType;
31
import org.distorted.objectlib.main.ShapeHexahedron;
32
import org.distorted.objectlib.scrambling.ScrambleState;
33
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
34

    
35
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
36
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
public class TwistyCrazy extends ShapeHexahedron
41
{
42
  private static final float DIAMETER_RATIO = 0.75f;
43
  private static final int NUMBER_CORNER_SEGMENTS = 4;
44
  private static final int NUMBER_EDGE_SEGMENTS = 4;
45

    
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(1,0,0),
49
           new Static3D(0,1,0),
50
           new Static3D(0,0,1)
51
         };
52

    
53
  private ScrambleState[] mStates;
54
  private int[][] mBasicAngle;
55
  private float[][] mCuts;
56
  private float[][] mPositions;
57
  private int[] mQuatIndex;
58

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  public TwistyCrazy(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
62
    {
63
    super(numL, meshState, iconMode, numL[0], quat, move, scale, stream);
64

    
65
    FactoryCubit f = FactoryCubit.getInstance();
66
    f.printStickerCoords();
67
    }
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
  @Override
72
  public void adjustStickerCoords()
73
    {
74
    final float A = 0.3645522f;
75
    final float B = 0.0744520f;
76
    final float C = 0.1823852f;
77
    final float D = 0.3098326f;
78
    final float E = 0.1033291f;
79
    final float F = 0.4044531f;
80
    final float G = 0.4103489f;
81

    
82
    mStickerCoords = new float[][]
83
      {
84
         { A, 0.5f, -0.5f, 0.5f, -0.5f, -A, -B, -A, A, B },
85
         { 0.5f, -C, 0.5f, D, -0.5f, D, -0.5f, -C },
86
         { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
87
         { -0.5f, E, -0.5f, -F, 0.5f, -F, 0.5f, E },
88
         { -G, 0.5f, -G, -G, 0.5f, -G }
89
      };
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
// Normal 3x3
94

    
95
  public ScrambleState[] getScrambleStates()
96
    {
97
    if( mStates==null )
98
      {
99
      int[][] m = new int[16][];
100

    
101
      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};
102

    
103
      mStates = new ScrambleState[]
104
          {
105
          new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
106
          new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
107
          new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
108
          new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
109
          new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
110
          new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
111
          new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
112
          new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
113
          new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
114
          new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
115
          new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
116
          new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
117
          new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
118
          new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
119
          new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
120
          new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
121
          };
122
      }
123

    
124
    return mStates;
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  public float[][] getCuts(int[] numLayers)
130
    {
131
    if( mCuts==null )
132
      {
133
      float C = 0.5f;
134
      float[] cut = new float[] {-C,+C};
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,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
      mPositions = new float[][]
191
         {
192
             { 1.0f, 1.0f, 1.0f},
193
             { 1.0f, 1.0f,-1.0f},
194
             { 1.0f,-1.0f, 1.0f},
195
             { 1.0f,-1.0f,-1.0f},
196
             {-1.0f, 1.0f, 1.0f},
197
             {-1.0f, 1.0f,-1.0f},
198
             {-1.0f,-1.0f, 1.0f},
199
             {-1.0f,-1.0f,-1.0f},
200

    
201
             { 1.0f, 1.0f, 0.0f},
202
             { 1.0f,-1.0f, 0.0f},
203
             { 1.0f, 0.0f, 1.0f},
204
             { 1.0f, 0.0f,-1.0f},
205
             {-1.0f, 1.0f, 0.0f},
206
             {-1.0f,-1.0f, 0.0f},
207
             {-1.0f, 0.0f, 1.0f},
208
             {-1.0f, 0.0f,-1.0f},
209
             { 0.0f, 1.0f, 1.0f},
210
             { 0.0f, 1.0f,-1.0f},
211
             { 0.0f,-1.0f, 1.0f},
212
             { 0.0f,-1.0f,-1.0f},
213

    
214
             { 0.0f, 0.0f, 0.0f},
215
             { 0.0f, 0.0f, 0.0f},
216
             { 0.0f, 0.0f, 0.0f},
217
             { 0.0f, 0.0f, 0.0f},
218
             { 0.0f, 0.0f, 0.0f},
219
             { 0.0f, 0.0f, 0.0f},
220

    
221
             { 0.0f, 1.0f, 0.0f},
222
             { 0.0f, 1.0f, 0.0f},
223
             { 0.0f, 1.0f, 0.0f},
224
             { 0.0f, 1.0f, 0.0f},
225
             { 0.0f,-1.0f, 0.0f},
226
             { 0.0f,-1.0f, 0.0f},
227
             { 0.0f,-1.0f, 0.0f},
228
             { 0.0f,-1.0f, 0.0f},
229
             { 0.0f, 0.0f, 1.0f},
230
             { 0.0f, 0.0f, 1.0f},
231
             { 0.0f, 0.0f, 1.0f},
232
             { 0.0f, 0.0f, 1.0f},
233
             { 0.0f, 0.0f,-1.0f},
234
             { 0.0f, 0.0f,-1.0f},
235
             { 0.0f, 0.0f,-1.0f},
236
             { 0.0f, 0.0f,-1.0f},
237
             { 1.0f, 0.0f, 0.0f},
238
             { 1.0f, 0.0f, 0.0f},
239
             { 1.0f, 0.0f, 0.0f},
240
             { 1.0f, 0.0f, 0.0f},
241
             {-1.0f, 0.0f, 0.0f},
242
             {-1.0f, 0.0f, 0.0f},
243
             {-1.0f, 0.0f, 0.0f},
244
             {-1.0f, 0.0f, 0.0f},
245

    
246
             { 1.0f, 1.0f, 0.0f},
247
             { 1.0f, 1.0f, 0.0f},
248
             { 1.0f,-1.0f, 0.0f},
249
             { 1.0f,-1.0f, 0.0f},
250
             { 1.0f, 0.0f, 1.0f},
251
             { 1.0f, 0.0f, 1.0f},
252
             { 1.0f, 0.0f,-1.0f},
253
             { 1.0f, 0.0f,-1.0f},
254
             {-1.0f, 1.0f, 0.0f},
255
             {-1.0f, 1.0f, 0.0f},
256
             {-1.0f,-1.0f, 0.0f},
257
             {-1.0f,-1.0f, 0.0f},
258
             {-1.0f, 0.0f, 1.0f},
259
             {-1.0f, 0.0f, 1.0f},
260
             {-1.0f, 0.0f,-1.0f},
261
             {-1.0f, 0.0f,-1.0f},
262
             { 0.0f, 1.0f, 1.0f},
263
             { 0.0f, 1.0f, 1.0f},
264
             { 0.0f, 1.0f,-1.0f},
265
             { 0.0f, 1.0f,-1.0f},
266
             { 0.0f,-1.0f, 1.0f},
267
             { 0.0f,-1.0f, 1.0f},
268
             { 0.0f,-1.0f,-1.0f},
269
             { 0.0f,-1.0f,-1.0f},
270
         };
271
      }
272

    
273
    return mPositions;
274
    }
275

    
276
///////////////////////////////////////////////////////////////////////////////////////////////////
277

    
278
  public Static4D getCubitQuats(int cubit, int[] numLayers)
279
    {
280
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,1,17,22,4,5,8,19,
281
                                                    6,17,7,12,4,16,9,10,0,5,3,2,
282
                                                    0,2,1,3,6,4,
283
                                                    0,4,5,6, 2,8,16,17, 3,14,20,21, 1,10,11,12, 7,13,18,22, 9,15,19,23,
284
                                                    0,18,2,7, 3,13,1,22, 5,9,8,19, 14,23,11,15, 4,21,6,10, 17,20,12,16 };
285
    return mObjectQuats[mQuatIndex[cubit]];
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  private ObjectShape getCornerShape()
291
    {
292
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
293
    final float STEP_CORNER= (float)((Math.PI/2-2*INIT_ALPHA)/NUMBER_CORNER_SEGMENTS);
294
    final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
295
    final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
296
    final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
297
    float[][] tmp = new float[SINGLE_ARC][2];
298

    
299
    for(int i=0; i<SINGLE_ARC; i++)
300
      {
301
      float alpha = INIT_ALPHA + i*STEP_CORNER;
302
      tmp[i][0] = (float)(1.5f*DIAMETER_RATIO*Math.sin(alpha) - 1.0f);
303
      tmp[i][1] = (float)(1.5f*DIAMETER_RATIO*Math.cos(alpha) - 1.0f);
304
      }
305

    
306
    float[][] vertices = new float[NUM_VERTICES][];
307

    
308
    vertices[0] = new float[] { +0.5f, +0.5f, +0.5f };
309
    vertices[1] = new float[] { -0.5f, +0.5f, +0.5f };
310
    vertices[2] = new float[] { +0.5f, -0.5f, +0.5f };
311
    vertices[3] = new float[] { +0.5f, +0.5f, -0.5f };
312

    
313
    for(int i=0; i<SINGLE_ARC; i++)
314
      {
315
      float s = tmp[i][0];
316
      float c = tmp[i][1];
317

    
318
      vertices[4             +i] = new float[] {0.5f,+s,+c};
319
      vertices[4+  SINGLE_ARC+i] = new float[] {+c,0.5f,+s};
320
      vertices[4+2*SINGLE_ARC+i] = new float[] {+s,+c,0.5f};
321
      }
322

    
323
    final float EXTRA = (NUMBER_CORNER_SEGMENTS%2)==0 ? 1.0f : (float)Math.cos((Math.PI/2-2*INIT_ALPHA)/(2*NUMBER_CORNER_SEGMENTS));
324
    final float LEN = 1.5f*DIAMETER_RATIO*EXTRA;
325
    final float M = (float)(LEN*Math.sin(Math.PI/4) - 1.0f);
326
    vertices[4+3*SINGLE_ARC] = new float[] {M,M,M};
327

    
328
    for(int i=0; i<SINGLE_INNER_ARC; i++)
329
      {
330
      float s = tmp[i][0];
331
      float c = tmp[i][1];
332

    
333
      vertices[4+3*SINGLE_ARC+1                   +i] = new float[] {s,c,c};
334
      vertices[4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC+i] = new float[] {c,s,c};
335
      vertices[4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+i] = new float[] {c,c,s};
336
      }
337

    
338
    final int NUM_FACES = 6 + 3*NUMBER_CORNER_SEGMENTS;
339
    final int NUM_VERTS = 4 +   NUMBER_CORNER_SEGMENTS;
340

    
341
    int[][] indices = new int[NUM_FACES][];
342

    
343
    indices[0] = new int[NUM_VERTS];
344
    indices[1] = new int[NUM_VERTS];
345
    indices[2] = new int[NUM_VERTS];
346

    
347
    indices[0][0] = 3;
348
    indices[0][1] = 0;
349
    indices[0][2] = 2;
350
    indices[1][0] = 1;
351
    indices[1][1] = 0;
352
    indices[1][2] = 3;
353
    indices[2][0] = 2;
354
    indices[2][1] = 0;
355
    indices[2][2] = 1;
356

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

    
364
    indices[3] = new int[] { 1, 4+2*SINGLE_ARC-1, 4+3*SINGLE_ARC+1                   , 4+2*SINGLE_ARC};
365
    indices[4] = new int[] { 2, 4+3*SINGLE_ARC-1, 4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC, 4             };
366
    indices[5] = new int[] { 3, 4+  SINGLE_ARC-1, 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC, 4+  SINGLE_ARC};
367

    
368
    int start,i0,i1,i2,i3;
369
    int MID = (NUMBER_CORNER_SEGMENTS)/2;
370
    int MID2= (NUMBER_CORNER_SEGMENTS+1)/2;
371

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

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

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

    
399
      i0 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j+1;
400
      i1 = 4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+j;
401
      i2 = 4+(SINGLE_ARC-1)-j;
402
      i3 = 4+(SINGLE_ARC-1)-(j+1);
403

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

    
406
      i0 = 4+3*SINGLE_ARC+1+j;
407
      i1 = 4+3*SINGLE_ARC+1+j+1;
408
      i2 = 4+2*SINGLE_ARC+j+1;
409
      i3 = 4+2*SINGLE_ARC+j;
410

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

    
413
      i0 = 4+3*SINGLE_ARC+1+j+1;
414
      i1 = 4+3*SINGLE_ARC+1+j;
415
      i2 = 4+(2*SINGLE_ARC-1)-j;
416
      i3 = 4+(2*SINGLE_ARC-1)-(j+1);
417

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

    
420
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
421
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
422
      i2 = 4+j+1;
423
      i3 = 4+j;
424

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

    
427
      i0 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j+1;
428
      i1 = 4+3*SINGLE_ARC+1+SINGLE_INNER_ARC+j;
429
      i2 = 4+(3*SINGLE_ARC-1)-j;
430
      i3 = 4+(3*SINGLE_ARC-1)-(j+1);
431

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

    
435
    return new ObjectShape(vertices,indices);
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  private ObjectShape getEdgeShape()
441
    {
442
    final int NUM_VERTICES = 8 + 3*(NUMBER_EDGE_SEGMENTS-1);
443
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
444
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
445
    float[][] vertices = new float[NUM_VERTICES][];
446

    
447
    vertices[0] = new float[] {-0.5f,+0.5f,+0.5f};
448
    vertices[1] = new float[] {+0.5f,+0.5f,+0.5f};
449
    vertices[2] = new float[] {-0.5f,    H,+0.5f};
450
    vertices[3] = new float[] {+0.5f,    H,+0.5f};
451
    vertices[4] = new float[] {-0.5f,+0.5f,    H};
452
    vertices[5] = new float[] {+0.5f,+0.5f,    H};
453
    vertices[6] = new float[] {-0.5f,    H,    H};
454
    vertices[7] = new float[] {+0.5f,    H,    H};
455

    
456
    final int NUM_VERTS = NUMBER_EDGE_SEGMENTS-1;
457
    for(int i=0; i<NUM_VERTS; i++)
458
      {
459
      float beta = INIT_ALPHA*((2.0f*(i+1))/NUMBER_EDGE_SEGMENTS -1 );
460
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(beta));
461
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(beta)-1.0f);
462
      vertices[8            +i] = new float[] {A,B,0.5f};
463
      vertices[8+  NUM_VERTS+i] = new float[] {A,0.5f,B};
464
      vertices[8+2*NUM_VERTS+i] = new float[] {A,B,B};
465
      }
466

    
467
    final int NUM_FACES = 4 + 2*NUMBER_EDGE_SEGMENTS;
468
    int[][] indices = new int[NUM_FACES][];
469

    
470
    int NUMV = 3+NUMBER_EDGE_SEGMENTS;
471

    
472
    indices[0] = new int[NUMV];
473
    indices[0][0] = 3;
474
    indices[0][1] = 1;
475
    indices[0][2] = 0;
476
    indices[0][3] = 2;
477
    for(int i=0; i<NUM_VERTS; i++) indices[0][4+i] = 8+i;
478

    
479
    indices[1] = new int[NUMV];
480
    indices[1][0] = 4;
481
    indices[1][1] = 0;
482
    indices[1][2] = 1;
483
    indices[1][3] = 5;
484
    for(int i=0; i<NUM_VERTS; i++) indices[1][4+i] = 7+2*NUM_VERTS-i;
485

    
486
    indices[2] = new int[] {5,1,3,7};
487
    indices[3] = new int[] {0,4,6,2};
488
    indices[4] = new int[] {8,2,6,8+2*NUM_VERTS};
489
    indices[5] = new int[] {3,7+NUM_VERTS,7+3*NUM_VERTS,7};
490
    indices[6] = new int[] {6,4,8+NUM_VERTS,8+2*NUM_VERTS};
491
    indices[7] = new int[] {5,7,7+3*NUM_VERTS,7+2*NUM_VERTS};
492

    
493
    int i0,i1,i2,i3;
494

    
495
    for(int i=0; i<NUMBER_EDGE_SEGMENTS-2; i++)
496
      {
497
      i0 = 9+i;
498
      i1 = 8+i;
499
      i2 = 8+2*NUM_VERTS+i;
500
      i3 = 9+2*NUM_VERTS+i;
501

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

    
504
      i0 = 9+2*NUM_VERTS+i;
505
      i1 = 8+2*NUM_VERTS+i;
506
      i2 = 8+NUM_VERTS+i;
507
      i3 = 9+NUM_VERTS+i;
508

    
509
      indices[8+NUMBER_EDGE_SEGMENTS-2+i] = new int[] {i0,i1,i2,i3};
510
      }
511

    
512
    return new ObjectShape(vertices,indices);
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  private ObjectShape getCenterShape(float D)
518
    {
519
    float[][] vertices = new float[][]
520
        {
521
            {-0.5f,-0.5f,-0.5f+D},
522
            {-0.5f,-0.5f,+0.5f+D},
523
            {-0.5f,+0.5f,-0.5f+D},
524
            {-0.5f,+0.5f,+0.5f+D},
525
            {+0.5f,-0.5f,-0.5f+D},
526
            {+0.5f,-0.5f,+0.5f+D},
527
            {+0.5f,+0.5f,-0.5f+D},
528
            {+0.5f,+0.5f,+0.5f+D},
529
        };
530

    
531
    int[][] indices = new int[][]
532
        {
533
            {1,5,7,3},
534
            {5,4,6,7},
535
            {0,1,3,2},
536
            {3,7,6,2},
537
            {0,4,5,1},
538
            {4,0,2,6}
539
        };
540

    
541
    return new ObjectShape(vertices,indices);
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  private ObjectShape getBigCircleShape(float D)
547
    {
548
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
549
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
550
    final int NUM_VERTICES = 8 + 2*(NUMBER_EDGE_SEGMENTS-1);
551
    float[][] vertices = new float[NUM_VERTICES][];
552

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

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

    
572
    final int NUM_FACES = 5 + NUMBER_EDGE_SEGMENTS;
573
    int[][] indices = new int[NUM_FACES][];
574

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

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

    
590
    indices[2] = new int[] {7,3,2,6};
591
    indices[3] = new int[] {4,0,1,5};
592
    indices[4] = new int[] {1,3,2,0};
593

    
594
    indices[5] = new int[] {5,4,8,8+NUM_VERTS};
595
    indices[6] = new int[] {7+NUM_VERTS,6,7,7+2*NUM_VERTS};
596

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

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

    
607
    return new ObjectShape(vertices,indices);
608
    }
609

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

    
612
  private ObjectShape getSmallCircleShape(float D)
613
    {
614
    final float H = 0.5f*((float)Math.sqrt(9*DIAMETER_RATIO*DIAMETER_RATIO-1))-1.0f;
615
    final float INIT_ALPHA = (float)Math.asin(1/(3*DIAMETER_RATIO));
616
    final float STEP_CORNER= (float)((Math.PI/2-2*INIT_ALPHA)/NUMBER_CORNER_SEGMENTS);
617
    final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
618
    float[][] vertices = new float[NUM_VERTICES][];
619

    
620
    vertices[0] = new float[] {-0.5f,    H, 0.5f+D};
621
    vertices[1] = new float[] {    H,-0.5f, 0.5f+D};
622
    vertices[2] = new float[] {-0.5f,-0.5f, 0.5f+D};
623
    vertices[3] = new float[] {-0.5f,    H,-0.5f+D};
624
    vertices[4] = new float[] {    H,-0.5f,-0.5f+D};
625
    vertices[5] = new float[] {-0.5f,-0.5f,-0.5f+D};
626

    
627
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-1; i++)
628
      {
629
      float alpha = INIT_ALPHA + (i+1)*STEP_CORNER;
630
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(alpha) - 1.0f);
631
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(alpha) - 1.0f);
632

    
633
      vertices[6                       +i] = new float[] {A,B, 0.5f+D};
634
      vertices[5+NUMBER_CORNER_SEGMENTS+i] = new float[] {A,B,-0.5f+D};
635
      }
636

    
637
    final int NUM_FACES = 4 + NUMBER_CORNER_SEGMENTS;
638
    int[][] indices = new int[NUM_FACES][];
639

    
640
    int NUMV = 2+NUMBER_CORNER_SEGMENTS;
641
    indices[0] = new int[NUMV];
642
    indices[0][0] = 0;
643
    indices[0][1] = 2;
644
    indices[0][2] = 1;
645
    for(int i=3; i<NUMV; i++) indices[0][i] = 5+(NUMBER_CORNER_SEGMENTS-1)-(i-3);
646

    
647
    indices[1] = new int[NUMV];
648
    indices[1][0] = 4;
649
    indices[1][1] = 5;
650
    indices[1][2] = 3;
651
    for(int i=3; i<NUMV; i++) indices[1][i] = 5+NUMBER_CORNER_SEGMENTS+(i-3);
652

    
653
    indices[2] = new int[] {0,3,5,2};
654
    indices[3] = new int[] {1,2,5,4};
655

    
656
    indices[4] = new int[] {5+NUMBER_CORNER_SEGMENTS,3,0,6};
657
    indices[5] = new int[] {1,4,5+2*(NUMBER_CORNER_SEGMENTS-1),5+(NUMBER_CORNER_SEGMENTS-1)};
658

    
659
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-2; i++)
660
      {
661
      int i0 = 6+i;
662
      int i1 = 7+i;
663
      int i2 = 6+NUMBER_CORNER_SEGMENTS+i;
664
      int i3 = 5+NUMBER_CORNER_SEGMENTS+i;
665

    
666
      indices[6+i] = new int[] {i0,i1,i2,i3};
667
      }
668

    
669
    return new ObjectShape(vertices,indices);
670
    }
671

    
672
///////////////////////////////////////////////////////////////////////////////////////////////////
673

    
674
  public ObjectShape getObjectShape(int variant)
675
    {
676
    switch(variant)
677
      {
678
      case 0: return getCornerShape();
679
      case 1: return getEdgeShape();
680
      case 2: return getCenterShape(1.0f);
681
      case 3: return getBigCircleShape(1.0f);
682
      case 4: return getSmallCircleShape(1.02f);
683
      }
684

    
685
    return null;
686
    }
687

    
688
///////////////////////////////////////////////////////////////////////////////////////////////////
689

    
690
  public ObjectFaceShape getObjectFaceShape(int variant)
691
    {
692
    if( variant==0 )
693
      {
694
      float h1 = isInIconMode() ? 0.001f : 0.04f;
695
      float h2 = 0.001f;
696
      float[][] bands   = { {h1,45,0.3f,0.7f,5,1,0}, {h2,5,0.3f,0.2f,2,0,0} };
697
      final int NUM_BANDS = 6+3*NUMBER_CORNER_SEGMENTS;
698
      int[] bandIndices = new int[NUM_BANDS];
699
      bandIndices[0] = bandIndices[1] = bandIndices[2] = 0;
700
      for(int i=3; i<NUM_BANDS; i++) bandIndices[i] = 1;
701
      float[][] corners = { {0.02f,0.09f} };
702
      float[][] centers = { { 0.0f, 0.0f, 0.0f } };
703
      final int SINGLE_ARC = NUMBER_CORNER_SEGMENTS+1;
704
      final int SINGLE_INNER_ARC = (NUMBER_CORNER_SEGMENTS+1)/2;
705
      final int NUM_VERTICES = 4 + 3*SINGLE_ARC + 1 + 3*SINGLE_INNER_ARC;
706
      int[] indices = new int[NUM_VERTICES];
707
      indices[0] = indices[1] = indices[2] = indices[3] = 0;
708
      for(int i=4; i<NUM_VERTICES; i++) indices[i] = -1;
709
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
710
      }
711
    if( variant==1 )
712
      {
713
      float h1 = isInIconMode() ? 0.001f : 0.03f;
714
      float[][] bands   = { {h1,45,0.2f,0.4f,5,1,0}, {0.001f,1,0.3f,0.5f,5,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
715
      final int NUM_BANDS = 4 + 2*NUMBER_EDGE_SEGMENTS;
716
      int[] bandIndices = new int[NUM_BANDS];
717
      bandIndices[0] = bandIndices[1] = 0;
718
      bandIndices[2] = bandIndices[3] = 1;
719
      for(int i=4; i<NUM_BANDS; i++) bandIndices[i] = 2;
720
      float[][] corners = { {0.02f,0.09f} };
721
      float[][] centers = { { 0.0f, 0.0f, 0.0f } };
722
      final int NUM_VERTICES = 8 + 3*(NUMBER_EDGE_SEGMENTS-1);
723
      int[] indices = new int[NUM_VERTICES];
724
      indices[0] = indices[1] = indices[2] = indices[3] = indices[4] = indices[5] = 0;
725
      for(int i=6; i<NUM_VERTICES; i++) indices[i] = -1;
726
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
727
      }
728
    if( variant==2 )
729
      {
730
      float h1 = isInIconMode() ? 0.001f : 0.05f;
731
      float[][] bands   = { {h1,45,0.2f,0.4f,5,1,0}, {0.001f,1,0.3f,0.5f,5,0,0} };
732
      int[] bandIndices = new int[] {0,1,1,1,1,1};
733
      float[][] corners = { {0.02f,0.09f} };
734
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
735
      int[] indices = new int[] {0,0,0,0,-1,-1,-1,-1};
736
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
737
      }
738
    if( variant==3 )
739
      {
740
      float h1 = isInIconMode() ? 0.001f : 0.03f;
741
      float[][] bands   = { {h1,45,0.2f,0.4f,5,1,0}, {0.001f,1,0.3f,0.5f,5,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
742
      final int NUM_BANDS = 5 + NUMBER_EDGE_SEGMENTS;
743
      int[] bandIndices = new int[NUM_BANDS];
744
      bandIndices[0] = 0;
745
      bandIndices[1] = 2;
746
      bandIndices[2] = bandIndices[3] = bandIndices[4] = 1;
747
      for(int i=5; i<NUM_BANDS; i++) bandIndices[i] = 2;
748
      float[][] corners = { {0.02f,0.09f} };
749
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
750
      final int NUM_VERTICES = 8 + 2*(NUMBER_EDGE_SEGMENTS-1);
751
      int[] indices = new int[NUM_VERTICES];
752
      for(int i=0; i<NUM_VERTICES; i++) indices[i] = -1;
753
      indices[0] = indices[2] = indices[4] = indices[6] = 0;
754
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
755
      }
756
    else
757
      {
758
      float h1 = isInIconMode() ? 0.001f : 0.02f;
759
      float[][] bands   = { {h1,45,0.2f,0.4f,5,1,0}, {0.001f,1,0.3f,0.5f,5,0,0}, {0.001f,1,0.3f,0.5f,2,0,0} };
760
      final int NUM_BANDS = 4 + NUMBER_CORNER_SEGMENTS;
761
      int[] bandIndices = new int[NUM_BANDS];
762
      bandIndices[0] = 0;
763
      bandIndices[1] = 2;
764
      bandIndices[2] = bandIndices[3] = 1;
765
      for(int i=4; i<NUM_BANDS; i++) bandIndices[i] = 2;
766
      float[][] corners = { {0.02f,0.09f} };
767
      float[][] centers = { { 0.0f, 0.0f, 1.0f } };
768
      final int NUM_VERTICES = 6 + 2*(NUMBER_CORNER_SEGMENTS-1);
769
      int[] indices = new int[NUM_VERTICES];
770
      for(int i=0; i<NUM_VERTICES; i++) indices[i] = -1;
771
      indices[0] = indices[1] = indices[2] = 0;
772
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
773
      }
774
    }
775

    
776
///////////////////////////////////////////////////////////////////////////////////////////////////
777

    
778
  public int getNumCubitVariants(int[] numLayers)
779
    {
780
    return 5;
781
    }
782

    
783
///////////////////////////////////////////////////////////////////////////////////////////////////
784

    
785
  public int getCubitVariant(int cubit, int[] numLayers)
786
    {
787
    if( cubit< 8 ) return 0;
788
    if( cubit<20 ) return 1;
789
    if( cubit<26 ) return 2;
790
    if( cubit<50 ) return 3;
791

    
792
    return 4;
793
    }
794

    
795
///////////////////////////////////////////////////////////////////////////////////////////////////
796

    
797
  public float getStickerRadius()
798
    {
799
    return 0.05f;
800
    }
801

    
802
///////////////////////////////////////////////////////////////////////////////////////////////////
803

    
804
  public float getStickerStroke()
805
    {
806
    return isInIconMode() ? 0.22f : 0.12f;
807
    }
808

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

    
811
  public float[][] getStickerAngles()
812
    {
813
    float D = (float)(Math.PI/8);
814
    return new float[][] { { 0,0,0,-D,0 },{ 0,0,0,-D },{0,0,0,0},{ 0,0,0,D },{ 0,0,D } };
815
    }
816

    
817
///////////////////////////////////////////////////////////////////////////////////////////////////
818
// PUBLIC API
819

    
820
  public Static3D[] getRotationAxis()
821
    {
822
    return ROT_AXIS;
823
    }
824

    
825
///////////////////////////////////////////////////////////////////////////////////////////////////
826

    
827
  public int[][] getBasicAngles()
828
    {
829
    if( mBasicAngle==null )
830
      {
831
      int[] tmp = new int[] {4,4,4};
832
      mBasicAngle = new int[][] { tmp,tmp,tmp };
833
      }
834

    
835
    return mBasicAngle;
836
    }
837

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

    
840
  public String getShortName()
841
    {
842
    return ObjectType.CRA1_3.name();
843
    }
844

    
845
///////////////////////////////////////////////////////////////////////////////////////////////////
846

    
847
  public ObjectSignature getSignature()
848
    {
849
    return new ObjectSignature(ObjectType.CRA1_3);
850
    }
851

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

    
854
  public String getObjectName()
855
    {
856
    return "Crazy 3x3";
857
    }
858

    
859
///////////////////////////////////////////////////////////////////////////////////////////////////
860

    
861
  public String getInventor()
862
    {
863
    return "Aleh Hladzilin";
864
    }
865

    
866
///////////////////////////////////////////////////////////////////////////////////////////////////
867

    
868
  public int getYearOfInvention()
869
    {
870
    return 2008;
871
    }
872

    
873
///////////////////////////////////////////////////////////////////////////////////////////////////
874

    
875
  public int getComplexity()
876
    {
877
    return 2;
878
    }
879

    
880
///////////////////////////////////////////////////////////////////////////////////////////////////
881

    
882
  public String[][] getTutorials()
883
    {
884
    return new String[][]{
885
                          {"gb","7xUE8ond_Mg","Crazy 3x3x3 Cube Tutorial","SuperAntoniovivaldi"},
886
                         };
887
    }
888
}
(9-9/40)