Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCrazy.java @ 97d1e3d7

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.ObjectFaceShape;
27
import org.distorted.objectlib.helpers.ObjectShape;
28
import org.distorted.objectlib.helpers.ObjectSignature;
29
import org.distorted.objectlib.main.ObjectType;
30
import org.distorted.objectlib.main.ShapeHexahedron;
31
import org.distorted.objectlib.scrambling.ScrambleState;
32
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
33

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

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

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

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

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

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

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

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

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

    
78
    mStickerCoords = new float[][]
79
      {
80
         { A, 0.5f, -0.5f, 0.5f, -0.5f, -A, -B, -A, A, B },
81
         { 0.5f, -C, 0.5f, D, -0.5f, D, -0.5f, -C },
82
         { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f },
83
         { -0.5f, E, -0.5f, -F, 0.5f, -F, 0.5f, E },
84
         { -G, 0.5f, -G, -G, 0.5f, -G }
85
      };
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
// Normal 3x3
90

    
91
  public ScrambleState[] getScrambleStates()
92
    {
93
    if( mStates==null )
94
      {
95
      int[][] m = new int[16][];
96

    
97
      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};
98

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

    
120
    return mStates;
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
  public float[][] getCuts(int[] numLayers)
126
    {
127
    if( mCuts==null )
128
      {
129
      float C = 0.5f;
130
      float[] cut = new float[] {-C,+C};
131
      mCuts = new float[][] { cut,cut,cut };
132
      }
133

    
134
    return mCuts;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  public boolean[][] getLayerRotatable(int[] numLayers)
140
    {
141
    boolean[] tmp = new boolean[] {true,true,true};
142
    return new boolean[][] { tmp,tmp,tmp };
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  public int getTouchControlType()
148
    {
149
    return TC_HEXAHEDRON;
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

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

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

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

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

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

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

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

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  public float[][] getCubitPositions(int[] numLayers)
183
    {
184
    if( mPositions==null )
185
      {
186
      mPositions = new float[][]
187
         {
188
             { 1.0f, 1.0f, 1.0f},
189
             { 1.0f, 1.0f,-1.0f},
190
             { 1.0f,-1.0f, 1.0f},
191
             { 1.0f,-1.0f,-1.0f},
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

    
197
             { 1.0f, 1.0f, 0.0f},
198
             { 1.0f,-1.0f, 0.0f},
199
             { 1.0f, 0.0f, 1.0f},
200
             { 1.0f, 0.0f,-1.0f},
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
             { 0.0f, 1.0f, 1.0f},
206
             { 0.0f, 1.0f,-1.0f},
207
             { 0.0f,-1.0f, 1.0f},
208
             { 0.0f,-1.0f,-1.0f},
209

    
210
             { 0.0f, 0.0f, 0.0f},
211
             { 0.0f, 0.0f, 0.0f},
212
             { 0.0f, 0.0f, 0.0f},
213
             { 0.0f, 0.0f, 0.0f},
214
             { 0.0f, 0.0f, 0.0f},
215
             { 0.0f, 0.0f, 0.0f},
216

    
217
             { 0.0f, 1.0f, 0.0f},
218
             { 0.0f, 1.0f, 0.0f},
219
             { 0.0f, 1.0f, 0.0f},
220
             { 0.0f, 1.0f, 0.0f},
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, 0.0f, 1.0f},
226
             { 0.0f, 0.0f, 1.0f},
227
             { 0.0f, 0.0f, 1.0f},
228
             { 0.0f, 0.0f, 1.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
             { 1.0f, 0.0f, 0.0f},
234
             { 1.0f, 0.0f, 0.0f},
235
             { 1.0f, 0.0f, 0.0f},
236
             { 1.0f, 0.0f, 0.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

    
242
             { 1.0f, 1.0f, 0.0f},
243
             { 1.0f, 1.0f, 0.0f},
244
             { 1.0f,-1.0f, 0.0f},
245
             { 1.0f,-1.0f, 0.0f},
246
             { 1.0f, 0.0f, 1.0f},
247
             { 1.0f, 0.0f, 1.0f},
248
             { 1.0f, 0.0f,-1.0f},
249
             { 1.0f, 0.0f,-1.0f},
250
             {-1.0f, 1.0f, 0.0f},
251
             {-1.0f, 1.0f, 0.0f},
252
             {-1.0f,-1.0f, 0.0f},
253
             {-1.0f,-1.0f, 0.0f},
254
             {-1.0f, 0.0f, 1.0f},
255
             {-1.0f, 0.0f, 1.0f},
256
             {-1.0f, 0.0f,-1.0f},
257
             {-1.0f, 0.0f,-1.0f},
258
             { 0.0f, 1.0f, 1.0f},
259
             { 0.0f, 1.0f, 1.0f},
260
             { 0.0f, 1.0f,-1.0f},
261
             { 0.0f, 1.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
         };
267
      }
268

    
269
    return mPositions;
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

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

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

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

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

    
302
    float[][] vertices = new float[NUM_VERTICES][];
303

    
304
    vertices[0] = new float[] { +0.5f, +0.5f, +0.5f };
305
    vertices[1] = new float[] { -0.5f, +0.5f, +0.5f };
306
    vertices[2] = new float[] { +0.5f, -0.5f, +0.5f };
307
    vertices[3] = new float[] { +0.5f, +0.5f, -0.5f };
308

    
309
    for(int i=0; i<SINGLE_ARC; i++)
310
      {
311
      float s = tmp[i][0];
312
      float c = tmp[i][1];
313

    
314
      vertices[4             +i] = new float[] {0.5f,+s,+c};
315
      vertices[4+  SINGLE_ARC+i] = new float[] {+c,0.5f,+s};
316
      vertices[4+2*SINGLE_ARC+i] = new float[] {+s,+c,0.5f};
317
      }
318

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

    
324
    for(int i=0; i<SINGLE_INNER_ARC; i++)
325
      {
326
      float s = tmp[i][0];
327
      float c = tmp[i][1];
328

    
329
      vertices[4+3*SINGLE_ARC+1                   +i] = new float[] {s,c,c};
330
      vertices[4+3*SINGLE_ARC+1+  SINGLE_INNER_ARC+i] = new float[] {c,s,c};
331
      vertices[4+3*SINGLE_ARC+1+2*SINGLE_INNER_ARC+i] = new float[] {c,c,s};
332
      }
333

    
334
    final int NUM_FACES = 6 + 3*NUMBER_CORNER_SEGMENTS;
335
    final int NUM_VERTS = 4 +   NUMBER_CORNER_SEGMENTS;
336

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
431
    return new ObjectShape(vertices,indices);
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

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

    
443
    vertices[0] = new float[] {-0.5f,+0.5f,+0.5f};
444
    vertices[1] = new float[] {+0.5f,+0.5f,+0.5f};
445
    vertices[2] = new float[] {-0.5f,    H,+0.5f};
446
    vertices[3] = new float[] {+0.5f,    H,+0.5f};
447
    vertices[4] = new float[] {-0.5f,+0.5f,    H};
448
    vertices[5] = new float[] {+0.5f,+0.5f,    H};
449
    vertices[6] = new float[] {-0.5f,    H,    H};
450
    vertices[7] = new float[] {+0.5f,    H,    H};
451

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

    
463
    final int NUM_FACES = 4 + 2*NUMBER_EDGE_SEGMENTS;
464
    int[][] indices = new int[NUM_FACES][];
465

    
466
    int NUMV = 3+NUMBER_EDGE_SEGMENTS;
467

    
468
    indices[0] = new int[NUMV];
469
    indices[0][0] = 3;
470
    indices[0][1] = 1;
471
    indices[0][2] = 0;
472
    indices[0][3] = 2;
473
    for(int i=0; i<NUM_VERTS; i++) indices[0][4+i] = 8+i;
474

    
475
    indices[1] = new int[NUMV];
476
    indices[1][0] = 4;
477
    indices[1][1] = 0;
478
    indices[1][2] = 1;
479
    indices[1][3] = 5;
480
    for(int i=0; i<NUM_VERTS; i++) indices[1][4+i] = 7+2*NUM_VERTS-i;
481

    
482
    indices[2] = new int[] {5,1,3,7};
483
    indices[3] = new int[] {0,4,6,2};
484
    indices[4] = new int[] {8,2,6,8+2*NUM_VERTS};
485
    indices[5] = new int[] {3,7+NUM_VERTS,7+3*NUM_VERTS,7};
486
    indices[6] = new int[] {6,4,8+NUM_VERTS,8+2*NUM_VERTS};
487
    indices[7] = new int[] {5,7,7+3*NUM_VERTS,7+2*NUM_VERTS};
488

    
489
    int i0,i1,i2,i3;
490

    
491
    for(int i=0; i<NUMBER_EDGE_SEGMENTS-2; i++)
492
      {
493
      i0 = 9+i;
494
      i1 = 8+i;
495
      i2 = 8+2*NUM_VERTS+i;
496
      i3 = 9+2*NUM_VERTS+i;
497

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

    
500
      i0 = 9+2*NUM_VERTS+i;
501
      i1 = 8+2*NUM_VERTS+i;
502
      i2 = 8+NUM_VERTS+i;
503
      i3 = 9+NUM_VERTS+i;
504

    
505
      indices[8+NUMBER_EDGE_SEGMENTS-2+i] = new int[] {i0,i1,i2,i3};
506
      }
507

    
508
    return new ObjectShape(vertices,indices);
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  private ObjectShape getCenterShape(float D)
514
    {
515
    float[][] vertices = new float[][]
516
        {
517
            {-0.5f,-0.5f,-0.5f+D},
518
            {-0.5f,-0.5f,+0.5f+D},
519
            {-0.5f,+0.5f,-0.5f+D},
520
            {-0.5f,+0.5f,+0.5f+D},
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
        };
526

    
527
    int[][] indices = new int[][]
528
        {
529
            {1,5,7,3},
530
            {5,4,6,7},
531
            {0,1,3,2},
532
            {3,7,6,2},
533
            {0,4,5,1},
534
            {4,0,2,6}
535
        };
536

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

    
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541

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

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

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

    
568
    final int NUM_FACES = 5 + NUMBER_EDGE_SEGMENTS;
569
    int[][] indices = new int[NUM_FACES][];
570

    
571
    int NUMV = 4+NUM_VERTS;
572
    indices[0] = new int[NUMV];
573
    indices[0][0] = 4;
574
    indices[0][1] = 0;
575
    indices[0][2] = 2;
576
    indices[0][3] = 6;
577
    for(int i=0; i<NUM_VERTS; i++) indices[0][4+i] = 7+NUM_VERTS-i;
578

    
579
    indices[1] = new int[NUMV];
580
    indices[1][0] = 7;
581
    indices[1][1] = 3;
582
    indices[1][2] = 1;
583
    indices[1][3] = 5;
584
    for(int i=0; i<NUM_VERTS; i++) indices[1][4+i] = 8+NUM_VERTS+i;
585

    
586
    indices[2] = new int[] {7,3,2,6};
587
    indices[3] = new int[] {4,0,1,5};
588
    indices[4] = new int[] {1,3,2,0};
589

    
590
    indices[5] = new int[] {5,4,8,8+NUM_VERTS};
591
    indices[6] = new int[] {7+NUM_VERTS,6,7,7+2*NUM_VERTS};
592

    
593
    for(int i=0; i<NUMBER_EDGE_SEGMENTS-2; i++)
594
      {
595
      int i0 = 8+i;
596
      int i1 = 9+i;
597
      int i2 = 9+NUM_VERTS+i;
598
      int i3 = 8+NUM_VERTS+i;
599

    
600
      indices[7+i] = new int[] {i0,i1,i2,i3};
601
      }
602

    
603
    return new ObjectShape(vertices,indices);
604
    }
605

    
606
///////////////////////////////////////////////////////////////////////////////////////////////////
607

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

    
616
    vertices[0] = new float[] {-0.5f,    H, 0.5f+D};
617
    vertices[1] = new float[] {    H,-0.5f, 0.5f+D};
618
    vertices[2] = new float[] {-0.5f,-0.5f, 0.5f+D};
619
    vertices[3] = new float[] {-0.5f,    H,-0.5f+D};
620
    vertices[4] = new float[] {    H,-0.5f,-0.5f+D};
621
    vertices[5] = new float[] {-0.5f,-0.5f,-0.5f+D};
622

    
623
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-1; i++)
624
      {
625
      float alpha = INIT_ALPHA + (i+1)*STEP_CORNER;
626
      float A = (float)(1.5f*DIAMETER_RATIO*Math.sin(alpha) - 1.0f);
627
      float B = (float)(1.5f*DIAMETER_RATIO*Math.cos(alpha) - 1.0f);
628

    
629
      vertices[6                       +i] = new float[] {A,B, 0.5f+D};
630
      vertices[5+NUMBER_CORNER_SEGMENTS+i] = new float[] {A,B,-0.5f+D};
631
      }
632

    
633
    final int NUM_FACES = 4 + NUMBER_CORNER_SEGMENTS;
634
    int[][] indices = new int[NUM_FACES][];
635

    
636
    int NUMV = 2+NUMBER_CORNER_SEGMENTS;
637
    indices[0] = new int[NUMV];
638
    indices[0][0] = 0;
639
    indices[0][1] = 2;
640
    indices[0][2] = 1;
641
    for(int i=3; i<NUMV; i++) indices[0][i] = 5+(NUMBER_CORNER_SEGMENTS-1)-(i-3);
642

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

    
649
    indices[2] = new int[] {0,3,5,2};
650
    indices[3] = new int[] {1,2,5,4};
651

    
652
    indices[4] = new int[] {5+NUMBER_CORNER_SEGMENTS,3,0,6};
653
    indices[5] = new int[] {1,4,5+2*(NUMBER_CORNER_SEGMENTS-1),5+(NUMBER_CORNER_SEGMENTS-1)};
654

    
655
    for(int i=0; i<NUMBER_CORNER_SEGMENTS-2; i++)
656
      {
657
      int i0 = 6+i;
658
      int i1 = 7+i;
659
      int i2 = 6+NUMBER_CORNER_SEGMENTS+i;
660
      int i3 = 5+NUMBER_CORNER_SEGMENTS+i;
661

    
662
      indices[6+i] = new int[] {i0,i1,i2,i3};
663
      }
664

    
665
    return new ObjectShape(vertices,indices);
666
    }
667

    
668
///////////////////////////////////////////////////////////////////////////////////////////////////
669

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

    
681
    return null;
682
    }
683

    
684
///////////////////////////////////////////////////////////////////////////////////////////////////
685

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

    
772
///////////////////////////////////////////////////////////////////////////////////////////////////
773

    
774
  public int getNumCubitVariants(int[] numLayers)
775
    {
776
    return 5;
777
    }
778

    
779
///////////////////////////////////////////////////////////////////////////////////////////////////
780

    
781
  public int getCubitVariant(int cubit, int[] numLayers)
782
    {
783
    if( cubit< 8 ) return 0;
784
    if( cubit<20 ) return 1;
785
    if( cubit<26 ) return 2;
786
    if( cubit<50 ) return 3;
787

    
788
    return 4;
789
    }
790

    
791
///////////////////////////////////////////////////////////////////////////////////////////////////
792

    
793
  public float getStickerRadius()
794
    {
795
    return 0.05f;
796
    }
797

    
798
///////////////////////////////////////////////////////////////////////////////////////////////////
799

    
800
  public float getStickerStroke()
801
    {
802
    return isInIconMode() ? 0.22f : 0.12f;
803
    }
804

    
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806

    
807
  public float[][] getStickerAngles()
808
    {
809
    float D = (float)(Math.PI/8);
810
    return new float[][] { { 0,0,0,-D,0 },{ 0,0,0,-D },{0,0,0,0},{ 0,0,0,D },{ 0,0,D } };
811
    }
812

    
813
///////////////////////////////////////////////////////////////////////////////////////////////////
814
// PUBLIC API
815

    
816
  public Static3D[] getRotationAxis()
817
    {
818
    return ROT_AXIS;
819
    }
820

    
821
///////////////////////////////////////////////////////////////////////////////////////////////////
822

    
823
  public int[][] getBasicAngles()
824
    {
825
    if( mBasicAngle==null )
826
      {
827
      int[] tmp = new int[] {4,4,4};
828
      mBasicAngle = new int[][] { tmp,tmp,tmp };
829
      }
830

    
831
    return mBasicAngle;
832
    }
833

    
834
///////////////////////////////////////////////////////////////////////////////////////////////////
835

    
836
  public String getShortName()
837
    {
838
    return ObjectType.CRA1_3.name();
839
    }
840

    
841
///////////////////////////////////////////////////////////////////////////////////////////////////
842

    
843
  public ObjectSignature getSignature()
844
    {
845
    return new ObjectSignature(ObjectType.CRA1_3);
846
    }
847

    
848
///////////////////////////////////////////////////////////////////////////////////////////////////
849

    
850
  public String getObjectName()
851
    {
852
    return "Crazy 3x3";
853
    }
854

    
855
///////////////////////////////////////////////////////////////////////////////////////////////////
856

    
857
  public String getInventor()
858
    {
859
    return "Aleh Hladzilin";
860
    }
861

    
862
///////////////////////////////////////////////////////////////////////////////////////////////////
863

    
864
  public int getYearOfInvention()
865
    {
866
    return 2008;
867
    }
868

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

    
871
  public int getComplexity()
872
    {
873
    return 2;
874
    }
875

    
876
///////////////////////////////////////////////////////////////////////////////////////////////////
877

    
878
  public String[][] getTutorials()
879
    {
880
    return new String[][]{
881
                          {"gb","7xUE8ond_Mg","Crazy 3x3x3 Cube Tutorial","SuperAntoniovivaldi"},
882
                         };
883
    }
884
}
(9-9/40)