Project

General

Profile

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

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

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.main.Movement.TYPE_SPLIT_CORNER;
23
24
import android.content.res.Resources;
25
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectList;
36
import org.distorted.objectlib.main.ObjectShape;
37
import org.distorted.objectlib.main.ObjectSticker;
38
import org.distorted.objectlib.main.ScrambleState;
39
import org.distorted.objectlib.main.Twisty6;
40
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
43
public class TwistyIvy extends Twisty6
44
{
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
48
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
49
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
50
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
51
         };
52
53
  private static final int[][][] ENABLED = new int[][][]
54
      {
55
          {{0},{3},{3},{0}},
56
          {{2},{1},{1},{2}},
57
          {{2},{0},{0},{2}},
58
          {{1},{3},{3},{1}},
59
          {{0},{0},{1},{1}},
60
          {{2},{2},{3},{3}},
61
      };
62
63
  private static final int NUM_STICKERS = 2;
64
  public static final float IVY_D = 0.006f;
65
  private static final int  IVY_N = 8;
66
67
  private ScrambleState[] mStates;
68
  private int[] mBasicAngle;
69
  private Static4D[] mQuats;
70
  private float[][] mCuts;
71
  private boolean[][] mLayerRotatable;
72
  private int[][] mFaceMap;
73
  private ObjectSticker[] mStickers;
74
  private Movement mMovement;
75
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
78
  public TwistyIvy(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
79
                   DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
80
    {
81
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
82
    }
83
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85
86
  protected ScrambleState[] getScrambleStates()
87
    {
88
    if( mStates==null )
89
      {
90
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
91
92
      mStates = new ScrambleState[]
93
        {
94
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
95
        };
96
      }
97
98
    return mStates;
99
    }
100
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102
103
  private void initializeQuats()
104
    {
105
    mQuats = new Static4D[]
106
         {
107
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
108
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
109
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
110
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
111
112
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
113
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
114
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
115
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
116
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
117
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
118
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
119
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
120
         };
121
    }
122
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125
  protected int[] getSolvedQuats(int cubit, int numLayers)
126
    {
127
    if( mQuats==null ) initializeQuats();
128
    int status = retCubitSolvedStatus(cubit,numLayers);
129
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
130
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134
  protected Static4D[] getQuats()
135
    {
136
    if( mQuats==null ) initializeQuats();
137
    return mQuats;
138
    }
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142
  protected int getSolvedFunctionIndex()
143
    {
144
    return 0;
145
    }
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  protected int getNumStickerTypes(int numLayers)
150
    {
151
    return NUM_STICKERS;
152
    }
153
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
156
  protected float[][] getCuts(int numLayers)
157
    {
158
    if( mCuts==null )
159
      {
160
      float[] cut = new float[] {0.0f};
161
      mCuts = new float[][] { cut,cut,cut,cut };
162
      }
163
164
    return mCuts;
165
    }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
  private void getLayerRotatable(int numLayers)
170
    {
171
    if( mLayerRotatable==null )
172
      {
173
      int numAxis = ROT_AXIS.length;
174
      boolean[] tmp = new boolean[numLayers];
175
      for(int i=0; i<numLayers; i++) tmp[i] = true;
176
      mLayerRotatable = new boolean[numAxis][];
177
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
178
      }
179
    }
180
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
183
  protected int getNumCubitFaces()
184
    {
185
    return 6;
186
    }
187
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190
  protected float[][] getCubitPositions(int numLayers)
191
    {
192
    final float DIST_CORNER = numLayers-1;
193
    final float DIST_CENTER = numLayers-1;
194
195
    final float[][] CENTERS = new float[10][];
196
197
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
198
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
199
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
200
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
201
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
202
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
203
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
204
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
205
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
206
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
207
208
    return CENTERS;
209
    }
210
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
213
  protected ObjectShape getObjectShape(int cubit, int numLayers)
214
    {
215
    int variant = getCubitVariant(cubit,numLayers);
216
217
    if( variant==0 )
218
      {
219
      final float angle = (float)Math.PI/(2*IVY_N);
220
      final float CORR  = 1.0f - 2*IVY_D;
221
222
      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
223
      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
224
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
225
      int[] centerIndices= new int[3*(IVY_N+1)+4];
226
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
227
      int[][] vertIndices= new int[6][IVY_N+4];
228
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
229
230
      float[][] bands =
231
        {
232
          {+0.015f,20,0.2f,0.5f,7,1,2},
233
          {-0.100f,20,0.2f,0.0f,2,1,2}
234
        };
235
236
      for(int i=0; i<3*(IVY_N+1); i++)
237
        {
238
        cornerIndices[i+4] = -1;
239
        centerIndices[i+4] = -1;
240
        }
241
242
      cornerIndices[0] = 1;
243
      cornerIndices[1] = 0;
244
      cornerIndices[2] = 0;
245
      cornerIndices[3] = 0;
246
247
      centerIndices[0] = 0;
248
      centerIndices[1] = 0;
249
      centerIndices[2] = 0;
250
      centerIndices[3] = 0;
251
252
      vertices[0][0] = 0.0;
253
      vertices[0][1] = 0.0;
254
      vertices[0][2] = 0.0;
255
      vertices[1][0] =-2.0;
256
      vertices[1][1] = 0.0;
257
      vertices[1][2] = 0.0;
258
      vertices[2][0] = 0.0;
259
      vertices[2][1] =-2.0;
260
      vertices[2][2] = 0.0;
261
      vertices[3][0] = 0.0;
262
      vertices[3][1] = 0.0;
263
      vertices[3][2] =-2.0;
264
265
      vertIndices[0][0] = 2;
266
      vertIndices[0][1] = 0;
267
      vertIndices[0][2] = 1;
268
      vertIndices[3][0] = 2;
269
      vertIndices[3][1] = 0;
270
      vertIndices[3][2] = 1;
271
272
      vertIndices[1][0] = 3;
273
      vertIndices[1][1] = 0;
274
      vertIndices[1][2] = 2;
275
      vertIndices[4][0] = 3;
276
      vertIndices[4][1] = 0;
277
      vertIndices[4][2] = 2;
278
279
      vertIndices[2][0] = 1;
280
      vertIndices[2][1] = 0;
281
      vertIndices[2][2] = 3;
282
      vertIndices[5][0] = 1;
283
      vertIndices[5][1] = 0;
284
      vertIndices[5][2] = 3;
285
286
      int N1 = 4;
287
      int N2 = N1 + IVY_N + 1;
288
      int N3 = N2 + IVY_N + 1;
289
290
      for(int i=0; i<=IVY_N; i++)
291
        {
292
        double cos1 = Math.cos((IVY_N-i)*angle);
293
        double sin1 = Math.sin((IVY_N-i)*angle);
294
        double cos2 = Math.cos((      i)*angle);
295
        double sin2 = Math.sin((      i)*angle);
296
297
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
298
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
299
        vertices[N1+i][2] = 0.0;
300
301
        vertices[N2+i][0] = 0.0;
302
        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
303
        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
304
305
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
306
        vertices[N3+i][1] = 0.0;
307
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
308
309
        vertIndices[0][i+3] = N1 + i;
310
        vertIndices[1][i+3] = N2 + i;
311
        vertIndices[2][i+3] = N3 + i;
312
        vertIndices[3][i+3] = N1 + i;
313
        vertIndices[4][i+3] = N2 + i;
314
        vertIndices[5][i+3] = N3 + i;
315
        }
316
317
      float C = 1.0f - SQ2/2;
318
      float[] convexCenter = new float[] {-C,-C,-C};
319
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
320
      }
321
    else
322
      {
323
      final float angle = (float)Math.PI/(2*IVY_N);
324
      final float CORR  = 1.0f - 2*IVY_D;
325
      double[][] vertices = new double[2*IVY_N][3];
326
      int[][] vert_indices = new int[2][2*IVY_N];
327
328
      int[] bandIndices= new int[] { 0,1 };
329
      int[] indexes    = new int[2*IVY_N];
330
      float[][] corners= new float[][] { {0.05f,0.20f} };
331
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
332
333
      for(int i=0; i<IVY_N; i++)
334
        {
335
        double sin = Math.sin(i*angle);
336
        double cos = Math.cos(i*angle);
337
338
        vertices[i      ][0] = CORR*(1.0f-2*cos);
339
        vertices[i      ][1] = CORR*(1.0f-2*sin);
340
        vertices[i      ][2] = 0;
341
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
342
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
343
        vertices[i+IVY_N][2] = 0;
344
        }
345
346
      for(int i=0; i<2*IVY_N; i++)
347
        {
348
        vert_indices[0][i] = i;
349
        vert_indices[1][i] = 2*IVY_N-1-i;
350
        }
351
352
      for(int i=0; i<2*IVY_N; i++)
353
        {
354
        indexes[i] = -1;
355
        }
356
      indexes[0] = indexes[IVY_N] = 0;
357
358
      float[][] bands =
359
        {
360
          {+0.03f,35,0.5f,0.5f,5,0,0},
361
          {+0.10f,45,0.5f,0.0f,2,0,0}
362
        };
363
364
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
365
      }
366
    }
367
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
370
  protected Static4D getQuat(int cubit, int numLayers)
371
    {
372
    if( mQuats==null ) initializeQuats();
373
374
    switch(cubit)
375
      {
376
      case  0: return mQuats[0];
377
      case  1: return mQuats[2];
378
      case  2: return mQuats[3];
379
      case  3: return mQuats[1];
380
381
      case  4: return mQuats[8];
382
      case  5: return mQuats[11];
383
      case  6: return mQuats[10];
384
      case  7: return mQuats[9];
385
      case  8: return mQuats[0];
386
      case  9: return mQuats[2];
387
      }
388
389
    return mQuats[0];
390
    }
391
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394
  protected int getNumCubitVariants(int numLayers)
395
    {
396
    return 2;
397
    }
398
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401
  protected int getCubitVariant(int cubit, int numLayers)
402
    {
403
    return cubit<4 ? 0:1;
404
    }
405
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407
408
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
409
    {
410
    if( mFaceMap==null )
411
      {
412
      mFaceMap = new int[][]
413
         {
414
           {  4, 0, 2, 12,12,12 },
415
           {  5, 1, 2, 12,12,12 },
416
           {  4, 1, 3, 12,12,12 },
417
           {  5, 0, 3, 12,12,12 },
418
419
           {  6, 12,12,12,12,12 },
420
           {  7, 12,12,12,12,12 },
421
           {  8, 12,12,12,12,12 },
422
           {  9, 12,12,12,12,12 },
423
           { 10, 12,12,12,12,12 },
424
           { 11, 12,12,12,12,12 },
425
         };
426
      }
427
428
    return mFaceMap[cubit][cubitface];
429
    }
430
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432
433
  protected ObjectSticker retSticker(int face)
434
    {
435
    if( mStickers==null )
436
      {
437
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
438
      mStickers = new ObjectSticker[NUM_STICKERS];
439
      float D = (float)(Math.PI/4);
440
      final float[][] angles = { { 0,0,D },{ D,D } };
441
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
442
      final float[] strokes = { 0.03f, 0.08f };
443
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
444
      }
445
446
    return mStickers[face/NUM_FACE_COLORS];
447
    }
448
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450
// PUBLIC API
451
452
  public Static3D[] getRotationAxis()
453
    {
454
    return ROT_AXIS;
455
    }
456
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458
459
  public Movement getMovement()
460
    {
461
    if( mMovement==null )
462
      {
463
      int numLayers = getNumLayers();
464
      if( mCuts==null ) getCuts(numLayers);
465
      getLayerRotatable(numLayers);
466
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
467
      }
468
    return mMovement;
469
    }
470
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472
473
  public int[] getBasicAngle()
474
    {
475
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
476
    return mBasicAngle;
477
    }
478
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480
481
  public int getObjectName(int numLayers)
482
    {
483
    return R.string.ivy2;
484
    }
485
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487
488
  public int getInventor(int numLayers)
489
    {
490
    return R.string.ivy2_inventor;
491
    }
492
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494
495
  public int getComplexity(int numLayers)
496
    {
497
    return 1;
498
    }
499
}