Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIvy.java @ 169762ac

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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 static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29

    
30
import org.distorted.objectlib.helpers.ObjectFaceShape;
31
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
32
import org.distorted.objectlib.main.ObjectControl;
33
import org.distorted.objectlib.main.ObjectType;
34
import org.distorted.objectlib.helpers.ObjectShape;
35
import org.distorted.objectlib.helpers.ScrambleState;
36
import org.distorted.objectlib.main.ShapeHexahedron;
37

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

    
40
public class TwistyIvy extends ShapeHexahedron
41
{
42
  static final Static3D[] ROT_AXIS = new Static3D[]
43
         {
44
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
45
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
46
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
47
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
48
         };
49

    
50
  public static final float IVY_D = 0.006f;
51
  private static final int  IVY_N = 8;
52

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

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

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

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67
// Back sides of the cubits here have all vertices on the walls and get mis-detected as external
68
// walls by the automatic sticker engine. Manually provide the (cubit face)<->(puzzle face) map.
69

    
70
  @Override
71
  public int getCubitFaceMap(int cubit, int face)
72
    {
73
    if( mFaceMap==null )
74
      {
75
      mFaceMap = new int[][]
76
         {
77
           { 4, 0, 2, -1,-1,-1 },
78
           { 5, 1, 2, -1,-1,-1 },
79
           { 4, 1, 3, -1,-1,-1 },
80
           { 5, 0, 3, -1,-1,-1 },
81

    
82
           { 0, -1,-1,-1,-1,-1 },
83
           { 1, -1,-1,-1,-1,-1 },
84
           { 2, -1,-1,-1,-1,-1 },
85
           { 3, -1,-1,-1,-1,-1 },
86
           { 4, -1,-1,-1,-1,-1 },
87
           { 5, -1,-1,-1,-1,-1 },
88
         };
89
      }
90

    
91
    return mFaceMap[cubit][face];
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95
// ditto, manually provide the sticker coordinates.
96

    
97
  @Override
98
  public void adjustStickerCoords()
99
    {
100
    mStickerCoords = new float[][]
101
          {
102
            { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f },
103
            { -0.5f, 0.5f, 0.5f, -0.5f }
104
          };
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

    
109
  public ScrambleState[] getScrambleStates()
110
    {
111
    if( mStates==null )
112
      {
113
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
114

    
115
      mStates = new ScrambleState[]
116
        {
117
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
118
        };
119
      }
120

    
121
    return mStates;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

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

    
134
    return mCuts;
135
    }
136

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

    
139
  public boolean[][] getLayerRotatable(int[] numLayers)
140
    {
141
    int numAxis = ROT_AXIS.length;
142
    boolean[][] layerRotatable = new boolean[numAxis][];
143

    
144
    for(int i=0; i<numAxis; i++)
145
      {
146
      layerRotatable[i] = new boolean[numLayers[i]];
147
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
148
      }
149

    
150
    return layerRotatable;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  public int getTouchControlType()
156
    {
157
    return TC_HEXAHEDRON;
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  public int getTouchControlSplit()
163
    {
164
    return TYPE_SPLIT_CORNER;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  public int[][][] getEnabled()
170
    {
171
    return new int[][][]
172
      {
173
          {{0},{3},{3},{0}},
174
          {{2},{1},{1},{2}},
175
          {{2},{0},{0},{2}},
176
          {{1},{3},{3},{1}},
177
          {{0},{0},{1},{1}},
178
          {{2},{2},{3},{3}},
179
      };
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  public float[] getDist3D(int[] numLayers)
185
    {
186
    return TouchControlHexahedron.D3D;
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

    
191
  public Static3D[] getFaceAxis()
192
    {
193
    return TouchControlHexahedron.FACE_AXIS;
194
    }
195

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

    
198
  public float[][] getCubitPositions(int[] numLayers)
199
    {
200
    final float DIST_CORNER = numLayers[0]-1;
201
    final float DIST_CENTER = numLayers[0]-1;
202

    
203
    return new float[][]
204
      {
205
        { DIST_CORNER, DIST_CORNER, DIST_CORNER },
206
        {-DIST_CORNER, DIST_CORNER,-DIST_CORNER },
207
        {-DIST_CORNER,-DIST_CORNER, DIST_CORNER },
208
        { DIST_CORNER,-DIST_CORNER,-DIST_CORNER },
209
        { DIST_CENTER,           0,           0 },
210
        {-DIST_CENTER,           0,           0 },
211
        {           0, DIST_CENTER,           0 },
212
        {           0,-DIST_CENTER,           0 },
213
        {           0,           0, DIST_CENTER },
214
        {           0,           0,-DIST_CENTER },
215
      };
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  public Static4D getCubitQuats(int cubit, int[] numLayers)
221
    {
222
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,11,10,9, 5,8,7,6,0,11 };
223
    return mObjectQuats[mQuatIndex[cubit]];
224
    }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
  public ObjectShape getObjectShape(int variant)
229
    {
230
    if( variant==0 )
231
      {
232
      final float angle = (float)Math.PI/(2*IVY_N);
233
      final float CORR  = 1-2*IVY_D;
234
      float[][] vertices= new float[3*(IVY_N+1)+4][3];
235
      int[][] indices   = new int[6][IVY_N+4];
236

    
237
      vertices[0][0] = 0;
238
      vertices[0][1] = 0;
239
      vertices[0][2] = 0;
240
      vertices[1][0] =-2;
241
      vertices[1][1] = 0;
242
      vertices[1][2] = 0;
243
      vertices[2][0] = 0;
244
      vertices[2][1] =-2;
245
      vertices[2][2] = 0;
246
      vertices[3][0] = 0;
247
      vertices[3][1] = 0;
248
      vertices[3][2] =-2;
249

    
250
      indices[0][0] = 2;
251
      indices[0][1] = 0;
252
      indices[0][2] = 1;
253
      indices[3][0] = 1;
254
      indices[3][1] = 0;
255
      indices[3][2] = 2;
256

    
257
      indices[1][0] = 3;
258
      indices[1][1] = 0;
259
      indices[1][2] = 2;
260
      indices[4][0] = 2;
261
      indices[4][1] = 0;
262
      indices[4][2] = 3;
263

    
264
      indices[2][0] = 1;
265
      indices[2][1] = 0;
266
      indices[2][2] = 3;
267
      indices[5][0] = 3;
268
      indices[5][1] = 0;
269
      indices[5][2] = 1;
270

    
271
      int N1 = 4;
272
      int N2 = N1 + IVY_N + 1;
273
      int N3 = N2 + IVY_N + 1;
274

    
275
      for(int i=0; i<=IVY_N; i++)
276
        {
277
        float cos1 = (float)Math.cos((IVY_N-i)*angle);
278
        float sin1 = (float)Math.sin((IVY_N-i)*angle);
279
        float cos2 = (float)Math.cos((      i)*angle);
280
        float sin2 = (float)Math.sin((      i)*angle);
281

    
282
        vertices[N1+i][0] = CORR*(2*cos1-1) - 1;
283
        vertices[N1+i][1] = CORR*(2*sin1-1) - 1;
284
        vertices[N1+i][2] = 0;
285

    
286
        vertices[N2+i][0] = 0;
287
        vertices[N2+i][1] = CORR*(2*sin2-1) - 1;
288
        vertices[N2+i][2] = CORR*(2*cos2-1) - 1;
289

    
290
        vertices[N3+i][0] = CORR*(2*cos2-1) - 1;
291
        vertices[N3+i][1] = 0;
292
        vertices[N3+i][2] = CORR*(2*sin2-1) - 1;
293

    
294
        indices[0][i+3] = N1 + i;
295
        indices[1][i+3] = N2 + i;
296
        indices[2][i+3] = N3 + i;
297
        indices[3][i+3] = N1 + IVY_N-i;
298
        indices[4][i+3] = N2 + IVY_N-i;
299
        indices[5][i+3] = N3 + IVY_N-i;
300
        }
301

    
302
      return new ObjectShape(vertices, indices);
303
      }
304
    else
305
      {
306
      final float angle = (float)Math.PI/(2*IVY_N);
307
      final float CORR  = 1-2*IVY_D;
308
      float[][] vertices= new float[2*IVY_N][3];
309
      int[][] indices   = new int[2][2*IVY_N];
310

    
311
      for(int i=0; i<IVY_N; i++)
312
        {
313
        float sin = (float)Math.sin(i*angle);
314
        float cos = (float)Math.cos(i*angle);
315

    
316
        vertices[i      ][0] = CORR*(1-2*cos);
317
        vertices[i      ][1] = CORR*(1-2*sin);
318
        vertices[i      ][2] = 0;
319
        vertices[i+IVY_N][0] = CORR*(2*cos-1);
320
        vertices[i+IVY_N][1] = CORR*(2*sin-1);
321
        vertices[i+IVY_N][2] = 0;
322
        }
323

    
324
      for(int i=0; i<2*IVY_N; i++)
325
        {
326
        indices[0][i] = i;
327
        indices[1][i] = 2*IVY_N-1-i;
328
        }
329

    
330
      return new ObjectShape(vertices, indices);
331
      }
332
    }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  public ObjectFaceShape getObjectFaceShape(int variant)
337
    {
338
    if( variant==0 )
339
      {
340
      float[][] centers  = { {-1.0f,-1.0f,-1.0f} };
341
      float[][] corners  = { {0.05f,0.20f}, {0.04f,0.20f} };
342
      int[] bandIndices  = { 0,0,0,1,1,1 };
343
      float[][] bands    = { {+0.015f,20,0.2f,0.5f,7,1,2}, {0.100f,20,0.2f,0.0f,2,1,2} };
344

    
345
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
346
      int[] centerIndices= new int[3*(IVY_N+1)+4];
347

    
348
      for(int i=0; i<3*(IVY_N+1); i++)
349
        {
350
        cornerIndices[i+4] = -1;
351
        centerIndices[i+4] = -1;
352
        }
353

    
354
      cornerIndices[0] = 1;
355
      cornerIndices[1] = 0;
356
      cornerIndices[2] = 0;
357
      cornerIndices[3] = 0;
358

    
359
      centerIndices[0] = 0;
360
      centerIndices[1] = 0;
361
      centerIndices[2] = 0;
362
      centerIndices[3] = 0;
363

    
364
      float C = 1-SQ2/2;
365
      float[] convexCenter = {-C,-C,-C};
366
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,convexCenter);
367
      }
368
    else
369
      {
370
      int[] bandIndices= { 0,1 };
371
      float[][] corners= { {0.05f,0.20f} };
372
      float[][] centers= { {-0.0f,-0.0f,-1.0f} };
373
      float[][] bands  = { {+0.03f,35,0.5f,0.5f,5,0,0}, {0.10f,45,0.5f,0.0f,5,0,0} };
374

    
375
      int[] indexes = new int[2*IVY_N];
376
      for(int i=0; i<2*IVY_N; i++) indexes[i] = -1;
377
      indexes[0] = indexes[IVY_N] = 0;
378

    
379
      return new ObjectFaceShape(bands,bandIndices,corners,indexes,centers,indexes, null);
380
      }
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public int getNumCubitVariants(int[] numLayers)
386
    {
387
    return 2;
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public int getCubitVariant(int cubit, int[] numLayers)
393
    {
394
    return cubit<4 ? 0:1;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public float getStickerRadius()
400
    {
401
    return 0.19f;
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public float getStickerStroke()
407
    {
408
    return ObjectControl.isInIconMode() ? 0.16f : 0.12f;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  public float[][] getStickerAngles()
414
    {
415
    float D = (float)(Math.PI/4);
416
    return new float[][] { { 0,0,D },{ D,D } };
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420
// PUBLIC API
421

    
422
  public Static3D[] getRotationAxis()
423
    {
424
    return ROT_AXIS;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public int[] getBasicAngles()
430
    {
431
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
432
    return mBasicAngle;
433
    }
434

    
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

    
437
  public ObjectType intGetObjectType(int[] numLayers)
438
    {
439
    return ObjectType.IVY_2;
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public String getObjectName()
445
    {
446
    return "Ivy Cube";
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450

    
451
  public String getInventor()
452
    {
453
    return "Eitan Cher";
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public int getYearOfInvention()
459
    {
460
    return 2009;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public int getComplexity()
466
    {
467
    return 0;
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

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