Project

General

Profile

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

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

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