Project

General

Profile

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

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

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 null;
192
    }
193

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

    
196
  public int getNumCubitFaces()
197
    {
198
    return 6;
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 ObjectShape getObjectShape(int variant)
227
    {
228
    if( variant==0 )
229
      {
230
      final float angle = (float)Math.PI/(2*IVY_N);
231
      final float CORR  = 1-2*IVY_D;
232

    
233
      float[][] vertices = new float[3*(IVY_N+1)+4][3];
234
      int[][] vertIndices= new int[6][IVY_N+4];
235

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

    
249
      vertIndices[0][0] = 2;
250
      vertIndices[0][1] = 0;
251
      vertIndices[0][2] = 1;
252
      vertIndices[3][0] = 2;
253
      vertIndices[3][1] = 0;
254
      vertIndices[3][2] = 1;
255

    
256
      vertIndices[1][0] = 3;
257
      vertIndices[1][1] = 0;
258
      vertIndices[1][2] = 2;
259
      vertIndices[4][0] = 3;
260
      vertIndices[4][1] = 0;
261
      vertIndices[4][2] = 2;
262

    
263
      vertIndices[2][0] = 1;
264
      vertIndices[2][1] = 0;
265
      vertIndices[2][2] = 3;
266
      vertIndices[5][0] = 1;
267
      vertIndices[5][1] = 0;
268
      vertIndices[5][2] = 3;
269

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

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

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

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

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

    
293
        vertIndices[0][i+3] = N1 + i;
294
        vertIndices[1][i+3] = N2 + i;
295
        vertIndices[2][i+3] = N3 + i;
296
        vertIndices[3][i+3] = N1 + i;
297
        vertIndices[4][i+3] = N2 + i;
298
        vertIndices[5][i+3] = N3 + i;
299
        }
300

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

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

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

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

    
329
      return new ObjectShape(vertices,vert_indices,getNumCubitFaces(), 1);
330
      }
331
    }
332

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

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

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

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

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

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

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

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

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

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

    
384
  public Static4D getQuat(int cubit, int[] numLayers)
385
    {
386
    if( mQuats==null ) initializeQuats();
387

    
388
    switch(cubit)
389
      {
390
      case  0: return mQuats[0];
391
      case  1: return mQuats[2];
392
      case  2: return mQuats[3];
393
      case  3: return mQuats[1];
394

    
395
      case  4: return mQuats[8];
396
      case  5: return mQuats[11];
397
      case  6: return mQuats[10];
398
      case  7: return mQuats[9];
399
      case  8: return mQuats[0];
400
      case  9: return mQuats[2];
401
      }
402

    
403
    return mQuats[0];
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

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

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

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

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

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

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

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

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

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

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

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

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

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

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

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

    
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479
// PUBLIC API
480

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

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

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

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495

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

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

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

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

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

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

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

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

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