Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIvy.java @ 6a8fb4ec

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.FactoryCubit;
21
import org.distorted.objectlib.helpers.ObjectFaceShape;
22
import org.distorted.objectlib.helpers.ObjectSignature;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitData;
25
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
26
import org.distorted.objectlib.main.ObjectType;
27
import org.distorted.objectlib.helpers.ObjectShape;
28
import org.distorted.objectlib.scrambling.ScrambleState;
29
import org.distorted.objectlib.shape.ShapeHexahedron;
30

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

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

    
43
  public static final float IVY_D = 0.006f;
44
  private static final int  IVY_N = 8;
45

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

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

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

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// ditto, manually provide the sticker coordinates.
60

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

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

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

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

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

    
89
    return mStates;
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

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

    
102
    return mCuts;
103
    }
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

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

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

    
118
    return layerRotatable;
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  public int getTouchControlType()
124
    {
125
    return TC_HEXAHEDRON;
126
    }
127

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

    
130
  public int getTouchControlSplit()
131
    {
132
    return TYPE_SPLIT_CORNER;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

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

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

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

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

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

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

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

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

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

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

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
  private float[][] getVertices(int variant)
199
    {
200
    final float angle = (float)Math.PI/(2*IVY_N);
201
    final float CORR  = 1-2*IVY_D;
202

    
203
    if( variant==0 )
204
      {
205
      final float A = 0.3f;
206
      final int N1 = 4;
207
      final int N2 = N1 + IVY_N + 1;
208
      final int N3 = N2 + IVY_N + 1;
209
      float[][] vertices= new float[3*(IVY_N+1)+5][3];
210

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

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

    
228
      for(int i=0; i<=IVY_N; i++)
229
        {
230
        float cos1 = (float)Math.cos((IVY_N-i)*angle);
231
        float sin1 = (float)Math.sin((IVY_N-i)*angle);
232
        float cos2 = (float)Math.cos((      i)*angle);
233
        float sin2 = (float)Math.sin((      i)*angle);
234

    
235
        vertices[N1+i][0] = CORR*(2*cos1-1) - 1;
236
        vertices[N1+i][1] = CORR*(2*sin1-1) - 1;
237
        vertices[N1+i][2] = 0;
238

    
239
        vertices[N2+i][0] = 0;
240
        vertices[N2+i][1] = CORR*(2*sin2-1) - 1;
241
        vertices[N2+i][2] = CORR*(2*cos2-1) - 1;
242

    
243
        vertices[N3+i][0] = CORR*(2*cos2-1) - 1;
244
        vertices[N3+i][1] = 0;
245
        vertices[N3+i][2] = CORR*(2*sin2-1) - 1;
246
        }
247

    
248
      return vertices;
249
      }
250
    else
251
      {
252
      float[][] vertices= new float[2*IVY_N+1][3];
253

    
254
      for(int i=0; i<IVY_N; i++)
255
        {
256
        float sin = (float)Math.sin(i*angle);
257
        float cos = (float)Math.cos(i*angle);
258

    
259
        vertices[i      ][0] = CORR*(1-2*cos);
260
        vertices[i      ][1] = CORR*(1-2*sin);
261
        vertices[i      ][2] = 0;
262
        vertices[i+IVY_N][0] = CORR*(2*cos-1);
263
        vertices[i+IVY_N][1] = CORR*(2*sin-1);
264
        vertices[i+IVY_N][2] = 0;
265
        }
266

    
267
      vertices[2*IVY_N][0] = 0.0f;
268
      vertices[2*IVY_N][1] = 0.0f;
269
      vertices[2*IVY_N][2] =-0.1f;
270

    
271
      return vertices;
272
      }
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  public ObjectShape getObjectShape(int variant)
278
    {
279
    if( variant==0 )
280
      {
281
      int[][] indices = new int[3*IVY_N+3][];
282

    
283
      indices[0] = new int[IVY_N+4];
284
      indices[1] = new int[IVY_N+4];
285
      indices[2] = new int[IVY_N+4];
286

    
287
      indices[0][0] = 2;
288
      indices[0][1] = 0;
289
      indices[0][2] = 1;
290
      indices[1][0] = 3;
291
      indices[1][1] = 0;
292
      indices[1][2] = 2;
293
      indices[2][0] = 1;
294
      indices[2][1] = 0;
295
      indices[2][2] = 3;
296

    
297
      int N1 = 4;
298
      int N2 = N1 + IVY_N + 1;
299
      int N3 = N2 + IVY_N + 1;
300

    
301
      for(int i=0; i<=IVY_N; i++)
302
        {
303
        indices[0][i+3] = N1 + i;
304
        indices[1][i+3] = N2 + i;
305
        indices[2][i+3] = N3 + i;
306
        }
307

    
308
      for(int i=0; i<IVY_N; i++)
309
        {
310
        indices[3*i+3] = new int[] { N1+i+1, N1+i, 3*(IVY_N+1)+4 };
311
        indices[3*i+4] = new int[] { N2+i+1, N2+i, 3*(IVY_N+1)+4 };
312
        indices[3*i+5] = new int[] { N3+i+1, N3+i, 3*(IVY_N+1)+4 };
313
        }
314

    
315
      return new ObjectShape(getVertices(variant), indices);
316
      }
317
    else
318
      {
319
      int[][] indices= new int[2*IVY_N+1][];
320

    
321
      indices[0] = new int[2*IVY_N+1];
322
      for(int i=0; i<2*IVY_N; i++)
323
        {
324
        indices[0][i] = i;
325
        indices[i+1]  = new int[] {i+1,i,2*IVY_N};
326
        }
327
      indices[2*IVY_N][0] = 0;
328

    
329
      return new ObjectShape(getVertices(variant), indices);
330
      }
331
    }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  public ObjectFaceShape getObjectFaceShape(int variant)
336
    {
337
    if( variant==0 )
338
      {
339
      float height = isInIconMode() ? 0.001f : 0.015f;
340
      float[][] bands = { {height,20,0.2f,0.5f,7,1,2}, {0.001f,1,0.2f,0.0f,2,0,0} };
341

    
342
      int[] indices   = new int[3*(IVY_N+1)];
343
      for(int i=0; i<3*(IVY_N+1); i++) indices[i] = 1;
344
      indices[0] = indices[1] = indices[2] = 0;
345

    
346
      float C = 1-SQ2/2;
347
      float[] convexCenter = {-C,-C,-C};
348
      return new ObjectFaceShape(bands,indices,convexCenter);
349
      }
350
    else
351
      {
352
      float h1 = isInIconMode() ? 0.001f : 0.03f;
353
      float h2 = isInIconMode() ? 0.001f : 0.01f;
354
      float[][] bands = { { h1,35,0.5f,0.5f,5,0,0}, {h2,1,0.5f,0.8f,2,0,0} };
355

    
356
      int[] indices= new int[2*IVY_N+1];
357
      for(int i=0; i<2*IVY_N+1; i++) indices[i] = 1;
358
      indices[0] = 0;
359

    
360
      return new ObjectFaceShape(bands,indices,null);
361
      }
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  public ObjectVertexEffects getVertexEffects(int variant)
367
    {
368
    if( variant==0 )
369
      {
370
      float[][] centers  = { {-1.0f,-1.0f,-1.0f} };
371
      float[][] corners  = { {0.04f,0.20f}, {0.03f,0.20f} };
372

    
373
      int[] cornerIndices= new int[3*(IVY_N+1)+5];
374
      int[] centerIndices= new int[3*(IVY_N+1)+5];
375

    
376
      for(int i=0; i<3*(IVY_N+1); i++)
377
        {
378
        cornerIndices[i+4] = -1;
379
        centerIndices[i+4] = -1;
380
        }
381

    
382
      cornerIndices[3*(IVY_N+1)+4] = -1;
383
      centerIndices[3*(IVY_N+1)+4] = -1;
384

    
385
      cornerIndices[0] = 1;
386
      cornerIndices[1] = 0;
387
      cornerIndices[2] = 0;
388
      cornerIndices[3] = 0;
389

    
390
      centerIndices[0] = 0;
391
      centerIndices[1] = 0;
392
      centerIndices[2] = 0;
393
      centerIndices[3] = 0;
394

    
395
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
396
      }
397
    else
398
      {
399
      float[][] corners= { {0.04f,0.20f} };
400
      float[][] centers= { {-0.0f,-0.0f,-1.0f} };
401
      int[] indices = new int[2*IVY_N+1];
402
      for(int i=0; i<2*IVY_N+1; i++) indices[i] = -1;
403
      indices[0] = indices[IVY_N] = 0;
404
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
405
      }
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  public int getNumCubitVariants(int[] numLayers)
411
    {
412
    return 2;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public int getCubitVariant(int cubit, int[] numLayers)
418
    {
419
    return cubit<4 ? 0:1;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  public float getStickerRadius()
425
    {
426
    return 0.19f;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public float getStickerStroke()
432
    {
433
    return isInIconMode() ? 0.16f : 0.12f;
434
    }
435

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

    
438
  public float[][] getStickerAngles()
439
    {
440
    float D = (float)(Math.PI/4);
441
    return new float[][] { { 0,0,-D },{ D,D } };
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
// PUBLIC API
446

    
447
  public Static3D[] getRotationAxis()
448
    {
449
    return ROT_AXIS;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  public int[][] getBasicAngles()
455
    {
456
    if( mBasicAngle ==null )
457
      {
458
      int num = getNumLayers()[0];
459
      int[] tmp = new int[num];
460
      for(int i=0; i<num; i++) tmp[i] = 3;
461
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
462
      }
463

    
464
    return mBasicAngle;
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  public String getShortName()
470
    {
471
    return ObjectType.IVY_2.name();
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public ObjectSignature getSignature()
477
    {
478
    return new ObjectSignature(ObjectType.IVY_2);
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public String getObjectName()
484
    {
485
    return "Ivy Cube";
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public String getInventor()
491
    {
492
    return "Eitan Cher";
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public int getYearOfInvention()
498
    {
499
    return 2009;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
  public int getComplexity()
505
    {
506
    return 0;
507
    }
508

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

    
511
  public String[][] getTutorials()
512
    {
513
    return new String[][]{
514
                          {"gb","QMzeJobSu1M","How to Solve the Ivy Cube","Z3"},
515
                          {"es","2-Gf2cmEJDs","Resolver Ivy Cube","Cuby"},
516
                          {"ru","pbkfOCnnfsA","Как собрать Иви куб","Алексей Ярыгин"},
517
                          {"fr","mn7YTnYu3Uc","Comment résoudre le Ivy Cube","ValentinoCube"},
518
                          {"de","vaW5fSUG_O8","Ivy Cube","ThomasStadler"},
519
                          {"pl","8s_0VxNvFA8","Jak ułożyć Ivy Cube","DubiCube"},
520
                          {"kr","TmSPgjtSFac","15분만에 아이비큐브 완전정복하기!","초등취미생활"},
521
                          {"vn","Ktx9KQr_8qo","Tutorial N.29 - Ivy Cube","Duy Thích Rubik"},
522
                         };
523
    }
524
}
(14-14/39)