Project

General

Profile

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

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

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 Static4D[] mQuats;
56
  private float[][] mCuts;
57
  private int[][] mFaceMap;
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

    
68
  public ScrambleState[] getScrambleStates()
69
    {
70
    if( mStates==null )
71
      {
72
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
73

    
74
      mStates = new ScrambleState[]
75
        {
76
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
77
        };
78
      }
79

    
80
    return mStates;
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  private void initializeQuats()
86
    {
87
    mQuats = new Static4D[]
88
         {
89
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
90
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
91
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
92
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
93

    
94
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
95
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
96
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
97
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
98
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
99
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
100
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
101
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
102
         };
103
    }
104

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

    
107
  public int[] getSolvedQuats(int cubit, int[] numLayers)
108
    {
109
    if( mQuats==null ) initializeQuats();
110
    int status = retCubitSolvedStatus(cubit,numLayers);
111
    return status<0 ? null : buildSolvedQuats(TouchControlHexahedron.FACE_AXIS[status],mQuats);
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

    
116
  public Static4D[] getQuats()
117
    {
118
    if( mQuats==null ) initializeQuats();
119
    return mQuats;
120
    }
121

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

    
124
  public int getSolvedFunctionIndex()
125
    {
126
    return 0;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  public float[][] getCuts(int[] numLayers)
132
    {
133
    if( mCuts==null )
134
      {
135
      float[] cut = new float[] {0.0f};
136
      mCuts = new float[][] { cut,cut,cut,cut };
137
      }
138

    
139
    return mCuts;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  public boolean[][] getLayerRotatable(int[] numLayers)
145
    {
146
    int numAxis = ROT_AXIS.length;
147
    boolean[][] layerRotatable = new boolean[numAxis][];
148

    
149
    for(int i=0; i<numAxis; i++)
150
      {
151
      layerRotatable[i] = new boolean[numLayers[i]];
152
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
153
      }
154

    
155
    return layerRotatable;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  public int getTouchControlType()
161
    {
162
    return TC_HEXAHEDRON;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  public int getTouchControlSplit()
168
    {
169
    return TYPE_SPLIT_CORNER;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  public int[][][] getEnabled()
175
    {
176
    return new int[][][]
177
      {
178
          {{0},{3},{3},{0}},
179
          {{2},{1},{1},{2}},
180
          {{2},{0},{0},{2}},
181
          {{1},{3},{3},{1}},
182
          {{0},{0},{1},{1}},
183
          {{2},{2},{3},{3}},
184
      };
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  public float[] getDist3D(int[] numLayers)
190
    {
191
    return TouchControlHexahedron.D3D;
192
    }
193

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

    
196
  public Static3D[] getFaceAxis()
197
    {
198
    return TouchControlHexahedron.FACE_AXIS;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  public float[][] getCubitPositions(int[] numLayers)
204
    {
205
    final float DIST_CORNER = numLayers[0]-1;
206
    final float DIST_CENTER = numLayers[0]-1;
207

    
208
    final float[][] CENTERS = new float[10][];
209

    
210
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
211
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
212
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
213
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
214
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
215
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
216
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
217
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
218
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
219
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
220

    
221
    return CENTERS;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  public Static4D getCubitQuats(int cubit, int[] numLayers)
227
    {
228
    if( mQuats==null ) initializeQuats();
229

    
230
    switch(cubit)
231
      {
232
      case  0: return mQuats[0];
233
      case  1: return mQuats[2];
234
      case  2: return mQuats[3];
235
      case  3: return mQuats[1];
236

    
237
      case  4: return mQuats[8];
238
      case  5: return mQuats[11];
239
      case  6: return mQuats[10];
240
      case  7: return mQuats[9];
241
      case  8: return mQuats[0];
242
      case  9: return mQuats[2];
243
      }
244

    
245
    return mQuats[0];
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
  public ObjectShape getObjectShape(int variant)
251
    {
252
    if( variant==0 )
253
      {
254
      final float angle = (float)Math.PI/(2*IVY_N);
255
      final float CORR  = 1-2*IVY_D;
256
      float[][] vertices= new float[3*(IVY_N+1)+4][3];
257
      int[][] indices   = new int[6][IVY_N+4];
258

    
259
      vertices[0][0] = 0;
260
      vertices[0][1] = 0;
261
      vertices[0][2] = 0;
262
      vertices[1][0] =-2;
263
      vertices[1][1] = 0;
264
      vertices[1][2] = 0;
265
      vertices[2][0] = 0;
266
      vertices[2][1] =-2;
267
      vertices[2][2] = 0;
268
      vertices[3][0] = 0;
269
      vertices[3][1] = 0;
270
      vertices[3][2] =-2;
271

    
272
      indices[0][0] = 2;
273
      indices[0][1] = 0;
274
      indices[0][2] = 1;
275
      indices[3][0] = 2;
276
      indices[3][1] = 0;
277
      indices[3][2] = 1;
278

    
279
      indices[1][0] = 3;
280
      indices[1][1] = 0;
281
      indices[1][2] = 2;
282
      indices[4][0] = 3;
283
      indices[4][1] = 0;
284
      indices[4][2] = 2;
285

    
286
      indices[2][0] = 1;
287
      indices[2][1] = 0;
288
      indices[2][2] = 3;
289
      indices[5][0] = 1;
290
      indices[5][1] = 0;
291
      indices[5][2] = 3;
292

    
293
      int N1 = 4;
294
      int N2 = N1 + IVY_N + 1;
295
      int N3 = N2 + IVY_N + 1;
296

    
297
      for(int i=0; i<=IVY_N; i++)
298
        {
299
        float cos1 = (float)Math.cos((IVY_N-i)*angle);
300
        float sin1 = (float)Math.sin((IVY_N-i)*angle);
301
        float cos2 = (float)Math.cos((      i)*angle);
302
        float sin2 = (float)Math.sin((      i)*angle);
303

    
304
        vertices[N1+i][0] = CORR*(2*cos1-1) - 1;
305
        vertices[N1+i][1] = CORR*(2*sin1-1) - 1;
306
        vertices[N1+i][2] = 0;
307

    
308
        vertices[N2+i][0] = 0;
309
        vertices[N2+i][1] = CORR*(2*sin2-1) - 1;
310
        vertices[N2+i][2] = CORR*(2*cos2-1) - 1;
311

    
312
        vertices[N3+i][0] = CORR*(2*cos2-1) - 1;
313
        vertices[N3+i][1] = 0;
314
        vertices[N3+i][2] = CORR*(2*sin2-1) - 1;
315

    
316
        indices[0][i+3] = N1 + i;
317
        indices[1][i+3] = N2 + i;
318
        indices[2][i+3] = N3 + i;
319
        indices[3][i+3] = N1 + i;
320
        indices[4][i+3] = N2 + i;
321
        indices[5][i+3] = N3 + i;
322
        }
323

    
324
      return new ObjectShape(vertices, indices);
325
      }
326
    else
327
      {
328
      final float angle = (float)Math.PI/(2*IVY_N);
329
      final float CORR  = 1-2*IVY_D;
330
      float[][] vertices= new float[2*IVY_N][3];
331
      int[][] indices   = new int[2][2*IVY_N];
332

    
333
      for(int i=0; i<IVY_N; i++)
334
        {
335
        float sin = (float)Math.sin(i*angle);
336
        float cos = (float)Math.cos(i*angle);
337

    
338
        vertices[i      ][0] = CORR*(1-2*cos);
339
        vertices[i      ][1] = CORR*(1-2*sin);
340
        vertices[i      ][2] = 0;
341
        vertices[i+IVY_N][0] = CORR*(2*cos-1);
342
        vertices[i+IVY_N][1] = CORR*(2*sin-1);
343
        vertices[i+IVY_N][2] = 0;
344
        }
345

    
346
      for(int i=0; i<2*IVY_N; i++)
347
        {
348
        indices[0][i] = i;
349
        indices[1][i] = i;
350
        }
351

    
352
      return new ObjectShape(vertices, indices);
353
      }
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  public ObjectFaceShape getObjectFaceShape(int variant)
359
    {
360
    if( variant==0 )
361
      {
362
      float[][] centers  = { {-1.0f,-1.0f,-1.0f} };
363
      float[][] corners  = { {0.05f,0.20f}, {0.04f,0.20f} };
364
      int[] bandIndices  = { 0,0,0,1,1,1 };
365
      float[][] bands    = { {+0.015f,20,0.2f,0.5f,7,1,2}, {-0.100f,20,0.2f,0.0f,2,1,2} };
366

    
367
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
368
      int[] centerIndices= new int[3*(IVY_N+1)+4];
369

    
370
      for(int i=0; i<3*(IVY_N+1); i++)
371
        {
372
        cornerIndices[i+4] = -1;
373
        centerIndices[i+4] = -1;
374
        }
375

    
376
      cornerIndices[0] = 1;
377
      cornerIndices[1] = 0;
378
      cornerIndices[2] = 0;
379
      cornerIndices[3] = 0;
380

    
381
      centerIndices[0] = 0;
382
      centerIndices[1] = 0;
383
      centerIndices[2] = 0;
384
      centerIndices[3] = 0;
385

    
386
      float C = 1-SQ2/2;
387
      float[] convexCenter = {-C,-C,-C};
388
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,convexCenter);
389
      }
390
    else
391
      {
392
      int[] bandIndices= { 0,1 };
393
      float[][] corners= { {0.05f,0.20f} };
394
      float[][] centers= { {-0.0f,-0.0f,-1.0f} };
395
      float[][] bands  = { {+0.03f,35,0.5f,0.5f,5,0,0}, {-0.10f,45,0.5f,0.0f,2,0,0} };
396

    
397
      int[] indexes = new int[2*IVY_N];
398
      for(int i=0; i<2*IVY_N; i++) indexes[i] = -1;
399
      indexes[0] = indexes[IVY_N] = 0;
400

    
401
      return new ObjectFaceShape(bands,bandIndices,corners,indexes,centers,indexes, null);
402
      }
403
    }
404

    
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

    
407
  public int getNumCubitVariants(int[] numLayers)
408
    {
409
    return 2;
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public int getCubitVariant(int cubit, int[] numLayers)
415
    {
416
    return cubit<4 ? 0:1;
417
    }
418

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

    
421
  public int getCubitFaceColor(int cubit, int face)
422
    {
423
    if( mFaceMap==null )
424
      {
425
      mFaceMap = new int[][]
426
         {
427
           { 4, 0, 2, -1,-1,-1 },
428
           { 5, 1, 2, -1,-1,-1 },
429
           { 4, 1, 3, -1,-1,-1 },
430
           { 5, 0, 3, -1,-1,-1 },
431

    
432
           { 0, -1,-1,-1,-1,-1 },
433
           { 1, -1,-1,-1,-1,-1 },
434
           { 2, -1,-1,-1,-1,-1 },
435
           { 3, -1,-1,-1,-1,-1 },
436
           { 4, -1,-1,-1,-1,-1 },
437
           { 5, -1,-1,-1,-1,-1 },
438
         };
439
      }
440

    
441
    return mFaceMap[cubit][face];
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public void adjustStickerCoords()
447
    {
448
    mStickerCoords = new float[][]
449
          {
450
            { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f },
451
            { -0.5f, 0.5f, 0.5f, -0.5f }
452
          };
453
    }
454

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

    
457
  public float getStickerRadius()
458
    {
459
    return 0.19f;
460
    }
461

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

    
464
  public float getStickerStroke()
465
    {
466
    return ObjectControl.isInIconMode() ? 0.16f : 0.12f;
467
    }
468

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

    
471
  public float[][] getStickerAngles()
472
    {
473
    float D = (float)(Math.PI/4);
474
    return new float[][] { { 0,0,D },{ D,D } };
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478
// PUBLIC API
479

    
480
  public Static3D[] getRotationAxis()
481
    {
482
    return ROT_AXIS;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public int[] getBasicAngle()
488
    {
489
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
490
    return mBasicAngle;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public ObjectType intGetObjectType(int[] numLayers)
496
    {
497
    return ObjectType.IVY_2;
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public String getObjectName()
503
    {
504
    return "Ivy Cube";
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
  public String getInventor()
510
    {
511
    return "Eitan Cher";
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

    
516
  public int getYearOfInvention()
517
    {
518
    return 2009;
519
    }
520

    
521
///////////////////////////////////////////////////////////////////////////////////////////////////
522

    
523
  public int getComplexity()
524
    {
525
    return 0;
526
    }
527
}
(12-12/26)