Project

General

Profile

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

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

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