Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIvy.java @ 5d09301e

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.objects;
11

    
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
14

    
15
import java.io.InputStream;
16

    
17
import org.distorted.library.type.Static3D;
18
import org.distorted.library.type.Static4D;
19

    
20
import org.distorted.objectlib.helpers.ObjectFaceShape;
21
import org.distorted.objectlib.helpers.ObjectSignature;
22
import org.distorted.objectlib.main.InitData;
23
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
24
import org.distorted.objectlib.main.ObjectType;
25
import org.distorted.objectlib.helpers.ObjectShape;
26
import org.distorted.objectlib.scrambling.ScrambleState;
27
import org.distorted.objectlib.main.ShapeHexahedron;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
public class TwistyIvy extends ShapeHexahedron
32
{
33
  static final Static3D[] ROT_AXIS = new Static3D[]
34
         {
35
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
36
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
37
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
38
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
39
         };
40

    
41
  public static final float IVY_D = 0.006f;
42
  private static final int  IVY_N = 8;
43

    
44
  private ScrambleState[] mStates;
45
  private int[][] mBasicAngle;
46
  private float[][] mCuts;
47
  private int[] mQuatIndex;
48

    
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

    
51
  public TwistyIvy(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
52
    {
53
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
54
    }
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
// ditto, manually provide the sticker coordinates.
58

    
59
  @Override
60
  public void adjustStickerCoords()
61
    {
62
    float B = 1.08f;
63
    float A1 = B*0.41f;
64
    float A2 = B*0.46f;
65

    
66
    mStickerCoords = new float[][]
67
          {
68
            { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f },
69
            { -A1,A1,A2,-A2 }
70
          };
71
    }
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  public ScrambleState[] getScrambleStates()
76
    {
77
    if( mStates==null )
78
      {
79
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
80

    
81
      mStates = new ScrambleState[]
82
        {
83
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
84
        };
85
      }
86

    
87
    return mStates;
88
    }
89

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

    
92
  public float[][] getCuts(int[] numLayers)
93
    {
94
    if( mCuts==null )
95
      {
96
      float[] cut = new float[] {0.0f};
97
      mCuts = new float[][] { cut,cut,cut,cut };
98
      }
99

    
100
    return mCuts;
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  public boolean[][] getLayerRotatable(int[] numLayers)
106
    {
107
    int numAxis = ROT_AXIS.length;
108
    boolean[][] layerRotatable = new boolean[numAxis][];
109

    
110
    for(int i=0; i<numAxis; i++)
111
      {
112
      layerRotatable[i] = new boolean[numLayers[i]];
113
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
114
      }
115

    
116
    return layerRotatable;
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  public int getTouchControlType()
122
    {
123
    return TC_HEXAHEDRON;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  public int getTouchControlSplit()
129
    {
130
    return TYPE_SPLIT_CORNER;
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  public int[][][] getEnabled()
136
    {
137
    return new int[][][]
138
      {
139
          {{0},{3},{3},{0}},
140
          {{2},{1},{1},{2}},
141
          {{2},{0},{0},{2}},
142
          {{1},{3},{3},{1}},
143
          {{0},{0},{1},{1}},
144
          {{2},{2},{3},{3}},
145
      };
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  public float[] getDist3D(int[] numLayers)
151
    {
152
    return TouchControlHexahedron.D3D;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  public Static3D[] getFaceAxis()
158
    {
159
    return TouchControlHexahedron.FACE_AXIS;
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  public float[][] getCubitPositions(int[] numLayers)
165
    {
166
    final float DIST_CORNER = numLayers[0]-1;
167
    final float DIST_CENTER = numLayers[0]-1;
168

    
169
    return new float[][]
170
      {
171
        { DIST_CORNER, DIST_CORNER, DIST_CORNER },
172
        {-DIST_CORNER, DIST_CORNER,-DIST_CORNER },
173
        {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
174
        { DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
175
        {           0,           0, DIST_CENTER },
176
        {           0,           0,-DIST_CENTER },
177
        {           0, DIST_CENTER,           0 },
178
        {           0,-DIST_CENTER,           0 },
179
        { DIST_CENTER,           0,           0 },
180
        {-DIST_CENTER,           0,           0 },
181
      };
182
    }
183

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

    
186
  public Static4D getCubitQuats(int cubit, int[] numLayers)
187
    {
188
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,11,10, 9,
189
                                                    0,11, 7, 6, 5, 8
190
                                                  };
191
    return mObjectQuats[mQuatIndex[cubit]];
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  public ObjectShape getObjectShape(int variant)
197
    {
198
    if( variant==0 )
199
      {
200
      final float A = 0.3f;
201
      final float angle = (float)Math.PI/(2*IVY_N);
202
      final float CORR  = 1-2*IVY_D;
203
      float[][] vertices= new float[3*(IVY_N+1)+5][3];
204
      int[][] indices   = new int[3*IVY_N+3][];
205

    
206
      indices[0] = new int[IVY_N+4];
207
      indices[1] = new int[IVY_N+4];
208
      indices[2] = new int[IVY_N+4];
209

    
210
      vertices[3*(IVY_N+1)+4][0] = -A;
211
      vertices[3*(IVY_N+1)+4][1] = -A;
212
      vertices[3*(IVY_N+1)+4][2] = -A;
213

    
214
      vertices[0][0] = 0;
215
      vertices[0][1] = 0;
216
      vertices[0][2] = 0;
217
      vertices[1][0] =-2;
218
      vertices[1][1] = 0;
219
      vertices[1][2] = 0;
220
      vertices[2][0] = 0;
221
      vertices[2][1] =-2;
222
      vertices[2][2] = 0;
223
      vertices[3][0] = 0;
224
      vertices[3][1] = 0;
225
      vertices[3][2] =-2;
226

    
227
      indices[0][0] = 2;
228
      indices[0][1] = 0;
229
      indices[0][2] = 1;
230
      indices[1][0] = 3;
231
      indices[1][1] = 0;
232
      indices[1][2] = 2;
233
      indices[2][0] = 1;
234
      indices[2][1] = 0;
235
      indices[2][2] = 3;
236

    
237
      int N1 = 4;
238
      int N2 = N1 + IVY_N + 1;
239
      int N3 = N2 + IVY_N + 1;
240

    
241
      for(int i=0; i<=IVY_N; i++)
242
        {
243
        float cos1 = (float)Math.cos((IVY_N-i)*angle);
244
        float sin1 = (float)Math.sin((IVY_N-i)*angle);
245
        float cos2 = (float)Math.cos((      i)*angle);
246
        float sin2 = (float)Math.sin((      i)*angle);
247

    
248
        vertices[N1+i][0] = CORR*(2*cos1-1) - 1;
249
        vertices[N1+i][1] = CORR*(2*sin1-1) - 1;
250
        vertices[N1+i][2] = 0;
251

    
252
        vertices[N2+i][0] = 0;
253
        vertices[N2+i][1] = CORR*(2*sin2-1) - 1;
254
        vertices[N2+i][2] = CORR*(2*cos2-1) - 1;
255

    
256
        vertices[N3+i][0] = CORR*(2*cos2-1) - 1;
257
        vertices[N3+i][1] = 0;
258
        vertices[N3+i][2] = CORR*(2*sin2-1) - 1;
259

    
260
        indices[0][i+3] = N1 + i;
261
        indices[1][i+3] = N2 + i;
262
        indices[2][i+3] = N3 + i;
263
        }
264

    
265
      for(int i=0; i<IVY_N; i++)
266
        {
267
        indices[3*i+3] = new int[] { N1+i+1, N1+i, 3*(IVY_N+1)+4 };
268
        indices[3*i+4] = new int[] { N2+i+1, N2+i, 3*(IVY_N+1)+4 };
269
        indices[3*i+5] = new int[] { N3+i+1, N3+i, 3*(IVY_N+1)+4 };
270
        }
271

    
272
      return new ObjectShape(vertices, indices);
273
      }
274
    else
275
      {
276
      final float angle = (float)Math.PI/(2*IVY_N);
277
      final float CORR  = 1-2*IVY_D;
278
      float[][] vertices= new float[2*IVY_N+1][3];
279
      int[][] indices   = new int[2*IVY_N+1][];
280

    
281
      for(int i=0; i<IVY_N; i++)
282
        {
283
        float sin = (float)Math.sin(i*angle);
284
        float cos = (float)Math.cos(i*angle);
285

    
286
        vertices[i      ][0] = CORR*(1-2*cos);
287
        vertices[i      ][1] = CORR*(1-2*sin);
288
        vertices[i      ][2] = 0;
289
        vertices[i+IVY_N][0] = CORR*(2*cos-1);
290
        vertices[i+IVY_N][1] = CORR*(2*sin-1);
291
        vertices[i+IVY_N][2] = 0;
292
        }
293

    
294
      vertices[2*IVY_N][0] = 0.0f;
295
      vertices[2*IVY_N][1] = 0.0f;
296
      vertices[2*IVY_N][2] =-0.1f;
297

    
298
      indices[0] = new int[2*IVY_N+1];
299
      for(int i=0; i<2*IVY_N; i++)
300
        {
301
        indices[0][i] = i;
302
        indices[i+1]  = new int[] {i+1,i,2*IVY_N};
303
        }
304
      indices[2*IVY_N][0] = 0;
305

    
306
      return new ObjectShape(vertices, indices);
307
      }
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  public ObjectFaceShape getObjectFaceShape(int variant)
313
    {
314
    if( variant==0 )
315
      {
316
      float height = isInIconMode() ? 0.001f : 0.015f;
317
      float[][] centers  = { {-1.0f,-1.0f,-1.0f} };
318
      float[][] corners  = { {0.04f,0.20f}, {0.03f,0.20f} };
319
      float[][] bands    = { {height,20,0.2f,0.5f,7,1,2}, {0.001f,1,0.2f,0.0f,2,0,0} };
320

    
321
      int[] cornerIndices= new int[3*(IVY_N+1)+5];
322
      int[] centerIndices= new int[3*(IVY_N+1)+5];
323
      int[] bandIndices  = new int[3*(IVY_N+1)  ];
324

    
325
      for(int i=0; i<3*(IVY_N+1); i++)
326
        {
327
        cornerIndices[i+4] = -1;
328
        centerIndices[i+4] = -1;
329
        bandIndices[i] = 1;
330
        }
331

    
332
      cornerIndices[3*(IVY_N+1)+4] = -1;
333
      centerIndices[3*(IVY_N+1)+4] = -1;
334

    
335
      bandIndices[0] = 0;
336
      bandIndices[1] = 0;
337
      bandIndices[2] = 0;
338

    
339
      cornerIndices[0] = 1;
340
      cornerIndices[1] = 0;
341
      cornerIndices[2] = 0;
342
      cornerIndices[3] = 0;
343

    
344
      centerIndices[0] = 0;
345
      centerIndices[1] = 0;
346
      centerIndices[2] = 0;
347
      centerIndices[3] = 0;
348

    
349
      float C = 1-SQ2/2;
350
      float[] convexCenter = {-C,-C,-C};
351
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,convexCenter);
352
      }
353
    else
354
      {
355
      float h1 = isInIconMode() ? 0.001f : 0.03f;
356
      float h2 = isInIconMode() ? 0.001f : 0.01f;
357
      float[][] corners= { {0.04f,0.20f} };
358
      float[][] centers= { {-0.0f,-0.0f,-1.0f} };
359
      float[][] bands  = { { h1,35,0.5f,0.5f,5,0,0}, {h2,1,0.5f,0.8f,2,0,0} };
360

    
361
      int[] bandIndices= new int[2*IVY_N+1];
362
      int[] indexes = new int[2*IVY_N+1];
363
      for(int i=0; i<2*IVY_N+1; i++)
364
        {
365
        indexes[i] = -1;
366
        bandIndices[i] = 1;
367
        }
368
      indexes[0] = indexes[IVY_N] = 0;
369
      bandIndices[0] = 0;
370

    
371
      return new ObjectFaceShape(bands,bandIndices,corners,indexes,centers,indexes, null);
372
      }
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  public int getNumCubitVariants(int[] numLayers)
378
    {
379
    return 2;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public int getCubitVariant(int cubit, int[] numLayers)
385
    {
386
    return cubit<4 ? 0:1;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  public float getStickerRadius()
392
    {
393
    return 0.19f;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  public float getStickerStroke()
399
    {
400
    return isInIconMode() ? 0.16f : 0.12f;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  public float[][] getStickerAngles()
406
    {
407
    float D = (float)(Math.PI/4);
408
    return new float[][] { { 0,0,-D },{ D,D } };
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412
// PUBLIC API
413

    
414
  public Static3D[] getRotationAxis()
415
    {
416
    return ROT_AXIS;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public int[][] getBasicAngles()
422
    {
423
    if( mBasicAngle ==null )
424
      {
425
      int num = getNumLayers()[0];
426
      int[] tmp = new int[num];
427
      for(int i=0; i<num; i++) tmp[i] = 3;
428
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
429
      }
430

    
431
    return mBasicAngle;
432
    }
433

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

    
436
  public String getShortName()
437
    {
438
    return ObjectType.IVY_2.name();
439
    }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442

    
443
  public ObjectSignature getSignature()
444
    {
445
    return new ObjectSignature(ObjectType.IVY_2);
446
    }
447

    
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449

    
450
  public String getObjectName()
451
    {
452
    return "Ivy Cube";
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public String getInventor()
458
    {
459
    return "Eitan Cher";
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  public int getYearOfInvention()
465
    {
466
    return 2009;
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  public int getComplexity()
472
    {
473
    return 0;
474
    }
475

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

    
478
  public String[][] getTutorials()
479
    {
480
    return new String[][]{
481
                          {"gb","QMzeJobSu1M","How to Solve the Ivy Cube","Z3"},
482
                          {"es","2-Gf2cmEJDs","Resolver Ivy Cube","Cuby"},
483
                          {"ru","pbkfOCnnfsA","Как собрать Иви куб","Алексей Ярыгин"},
484
                          {"fr","mn7YTnYu3Uc","Comment résoudre le Ivy Cube","ValentinoCube"},
485
                          {"de","vaW5fSUG_O8","Ivy Cube","ThomasStadler"},
486
                          {"pl","8s_0VxNvFA8","Jak ułożyć Ivy Cube","DubiCube"},
487
                          {"kr","TmSPgjtSFac","15분만에 아이비큐브 완전정복하기!","초등취미생활"},
488
                          {"vn","Ktx9KQr_8qo","Tutorial N.29 - Ivy Cube","Duy Thích Rubik"},
489
                         };
490
    }
491
}
(14-14/36)