Project

General

Profile

Download (15.9 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 967c1d17

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.objects;
21

    
22
import static org.distorted.objects.Movement.TYPE_SPLIT_CORNER;
23

    
24
import android.content.res.Resources;
25

    
26
import org.distorted.helpers.ObjectShape;
27
import org.distorted.helpers.ObjectSticker;
28
import org.distorted.helpers.ScrambleState;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshSquare;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34
import org.distorted.main.R;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
public class TwistyIvy extends Twisty6
39
{
40
  static final Static3D[] ROT_AXIS = new Static3D[]
41
         {
42
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
43
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
44
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
45
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
46
         };
47

    
48
  private static final int[] NUM_ENABLED = {1,1,1,1,1,1};
49

    
50
  private static final int[][][] ENABLED = new int[][][]
51
      {
52
          {{0},{3},{3},{0}},
53
          {{2},{1},{1},{2}},
54
          {{2},{0},{0},{2}},
55
          {{1},{3},{3},{1}},
56
          {{0},{0},{1},{1}},
57
          {{2},{2},{3},{3}},
58
      };
59

    
60
  private static final int NUM_STICKERS = 2;
61
  public static final float IVY_D = 0.006f;
62
  private static final int  IVY_N = 8;
63

    
64
  private ScrambleState[] mStates;
65
  private int[] mBasicAngle;
66
  private Static4D[] mQuats;
67
  private float[][] mCuts;
68
  private boolean[][] mLayerRotatable;
69
  private int[][] mFaceMap;
70
  private ObjectSticker[] mStickers;
71
  private Movement mMovement;
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
76
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
77
    {
78
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  ScrambleState[] getScrambleStates()
84
    {
85
    if( mStates==null )
86
      {
87
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
88

    
89
      mStates = new ScrambleState[]
90
        {
91
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
92
        };
93
      }
94

    
95
    return mStates;
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  private void initializeQuats()
101
    {
102
    mQuats = new Static4D[]
103
         {
104
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
105
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
106
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
107
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
108

    
109
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
110
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
111
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
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
         };
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  int[] getSolvedQuats(int cubit, int numLayers)
123
    {
124
    if( mQuats==null ) initializeQuats();
125
    int status = retCubitSolvedStatus(cubit,numLayers);
126
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
127
    }
128

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

    
131
  Static4D[] getQuats()
132
    {
133
    if( mQuats==null ) initializeQuats();
134
    return mQuats;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  int getSolvedFunctionIndex()
140
    {
141
    return 0;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  int getNumStickerTypes(int numLayers)
147
    {
148
    return NUM_STICKERS;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  float[][] getCuts(int numLayers)
154
    {
155
    if( mCuts==null )
156
      {
157
      float[] cut = new float[] {0.0f};
158
      mCuts = new float[][] { cut,cut,cut,cut };
159
      }
160

    
161
    return mCuts;
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  private void getLayerRotatable(int numLayers)
167
    {
168
    if( mLayerRotatable==null )
169
      {
170
      int numAxis = ROT_AXIS.length;
171
      boolean[] tmp = new boolean[numLayers];
172
      for(int i=0; i<numLayers; i++) tmp[i] = true;
173
      mLayerRotatable = new boolean[numAxis][];
174
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
175
      }
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  int getNumCubitFaces()
181
    {
182
    return 6;
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  float[][] getCubitPositions(int numLayers)
188
    {
189
    final float DIST_CORNER = numLayers-1;
190
    final float DIST_CENTER = numLayers-1;
191

    
192
    final float[][] CENTERS = new float[10][];
193

    
194
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
195
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
196
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
197
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
198
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
199
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
200
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
201
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
202
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
203
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
204

    
205
    return CENTERS;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  ObjectShape getObjectShape(int cubit, int numLayers)
211
    {
212
    int variant = getCubitVariant(cubit,numLayers);
213

    
214
    if( variant==0 )
215
      {
216
      final float angle = (float)Math.PI/(2*IVY_N);
217
      final float CORR  = 1.0f - 2*IVY_D;
218

    
219
      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
220
      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
221
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
222
      int[] centerIndices= new int[3*(IVY_N+1)+4];
223
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
224
      int[][] vertIndices= new int[6][IVY_N+4];
225
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
226

    
227
      float[][] bands =
228
        {
229
          {+0.015f,20,0.2f,0.5f,7,1,2},
230
          {-0.100f,20,0.2f,0.0f,2,1,2}
231
        };
232

    
233
      for(int i=0; i<3*(IVY_N+1); i++)
234
        {
235
        cornerIndices[i+4] = -1;
236
        centerIndices[i+4] = -1;
237
        }
238

    
239
      cornerIndices[0] = 1;
240
      cornerIndices[1] = 0;
241
      cornerIndices[2] = 0;
242
      cornerIndices[3] = 0;
243

    
244
      centerIndices[0] = 0;
245
      centerIndices[1] = 0;
246
      centerIndices[2] = 0;
247
      centerIndices[3] = 0;
248

    
249
      vertices[0][0] = 0.0;
250
      vertices[0][1] = 0.0;
251
      vertices[0][2] = 0.0;
252
      vertices[1][0] =-2.0;
253
      vertices[1][1] = 0.0;
254
      vertices[1][2] = 0.0;
255
      vertices[2][0] = 0.0;
256
      vertices[2][1] =-2.0;
257
      vertices[2][2] = 0.0;
258
      vertices[3][0] = 0.0;
259
      vertices[3][1] = 0.0;
260
      vertices[3][2] =-2.0;
261

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

    
269
      vertIndices[1][0] = 3;
270
      vertIndices[1][1] = 0;
271
      vertIndices[1][2] = 2;
272
      vertIndices[4][0] = 3;
273
      vertIndices[4][1] = 0;
274
      vertIndices[4][2] = 2;
275

    
276
      vertIndices[2][0] = 1;
277
      vertIndices[2][1] = 0;
278
      vertIndices[2][2] = 3;
279
      vertIndices[5][0] = 1;
280
      vertIndices[5][1] = 0;
281
      vertIndices[5][2] = 3;
282

    
283
      int N1 = 4;
284
      int N2 = N1 + IVY_N + 1;
285
      int N3 = N2 + IVY_N + 1;
286

    
287
      for(int i=0; i<=IVY_N; i++)
288
        {
289
        double cos1 = Math.cos((IVY_N-i)*angle);
290
        double sin1 = Math.sin((IVY_N-i)*angle);
291
        double cos2 = Math.cos((      i)*angle);
292
        double sin2 = Math.sin((      i)*angle);
293

    
294
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
295
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
296
        vertices[N1+i][2] = 0.0;
297

    
298
        vertices[N2+i][0] = 0.0;
299
        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
300
        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
301

    
302
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
303
        vertices[N3+i][1] = 0.0;
304
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
305

    
306
        vertIndices[0][i+3] = N1 + i;
307
        vertIndices[1][i+3] = N2 + i;
308
        vertIndices[2][i+3] = N3 + i;
309
        vertIndices[3][i+3] = N1 + i;
310
        vertIndices[4][i+3] = N2 + i;
311
        vertIndices[5][i+3] = N3 + i;
312
        }
313

    
314
      float C = 1.0f - SQ2/2;
315
      float[] convexCenter = new float[] {-C,-C,-C};
316
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
317
      }
318
    else
319
      {
320
      final float angle = (float)Math.PI/(2*IVY_N);
321
      final float CORR  = 1.0f - 2*IVY_D;
322
      double[][] vertices = new double[2*IVY_N][3];
323
      int[][] vert_indices = new int[2][2*IVY_N];
324

    
325
      int[] bandIndices= new int[] { 0,1 };
326
      int[] indexes    = new int[2*IVY_N];
327
      float[][] corners= new float[][] { {0.05f,0.20f} };
328
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
329

    
330
      for(int i=0; i<IVY_N; i++)
331
        {
332
        double sin = Math.sin(i*angle);
333
        double cos = Math.cos(i*angle);
334

    
335
        vertices[i      ][0] = CORR*(1.0f-2*cos);
336
        vertices[i      ][1] = CORR*(1.0f-2*sin);
337
        vertices[i      ][2] = 0;
338
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
339
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
340
        vertices[i+IVY_N][2] = 0;
341
        }
342

    
343
      for(int i=0; i<2*IVY_N; i++)
344
        {
345
        vert_indices[0][i] = i;
346
        vert_indices[1][i] = 2*IVY_N-1-i;
347
        }
348

    
349
      for(int i=0; i<2*IVY_N; i++)
350
        {
351
        indexes[i] = -1;
352
        }
353
      indexes[0] = indexes[IVY_N] = 0;
354

    
355
      float[][] bands =
356
        {
357
          {+0.03f,35,0.5f,0.5f,5,0,0},
358
          {+0.10f,45,0.5f,0.0f,2,0,0}
359
        };
360

    
361
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
362
      }
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  Static4D getQuat(int cubit, int numLayers)
368
    {
369
    if( mQuats==null ) initializeQuats();
370

    
371
    switch(cubit)
372
      {
373
      case  0: return mQuats[0];
374
      case  1: return mQuats[2];
375
      case  2: return mQuats[3];
376
      case  3: return mQuats[1];
377

    
378
      case  4: return mQuats[8];
379
      case  5: return mQuats[11];
380
      case  6: return mQuats[10];
381
      case  7: return mQuats[9];
382
      case  8: return mQuats[0];
383
      case  9: return mQuats[2];
384
      }
385

    
386
    return mQuats[0];
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  int getNumCubitVariants(int numLayers)
392
    {
393
    return 2;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  int getCubitVariant(int cubit, int numLayers)
399
    {
400
    return cubit<4 ? 0:1;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  int getFaceColor(int cubit, int cubitface, int numLayers)
406
    {
407
    if( mFaceMap==null )
408
      {
409
      mFaceMap = new int[][]
410
         {
411
           {  4, 0, 2, 12,12,12 },
412
           {  5, 1, 2, 12,12,12 },
413
           {  4, 1, 3, 12,12,12 },
414
           {  5, 0, 3, 12,12,12 },
415

    
416
           {  6, 12,12,12,12,12 },
417
           {  7, 12,12,12,12,12 },
418
           {  8, 12,12,12,12,12 },
419
           {  9, 12,12,12,12,12 },
420
           { 10, 12,12,12,12,12 },
421
           { 11, 12,12,12,12,12 },
422
         };
423
      }
424

    
425
    return mFaceMap[cubit][cubitface];
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  ObjectSticker retSticker(int face)
431
    {
432
    if( mStickers==null )
433
      {
434
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
435
      mStickers = new ObjectSticker[NUM_STICKERS];
436
      float D = (float)(Math.PI/4);
437
      final float[][] angles = { { 0,0,D },{ D,D } };
438
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
439
      final float[] strokes = { 0.03f, 0.08f };
440
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
441
      }
442

    
443
    return mStickers[face/NUM_FACE_COLORS];
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447
// PUBLIC API
448

    
449
  public Static3D[] getRotationAxis()
450
    {
451
    return ROT_AXIS;
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  public Movement getMovement()
457
    {
458
    if( mMovement==null )
459
      {
460
      int numLayers = getNumLayers();
461
      if( mCuts==null ) getCuts(numLayers);
462
      getLayerRotatable(numLayers);
463
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,NUM_ENABLED,ENABLED);
464
      }
465
    return mMovement;
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

    
470
  public int[] getBasicAngle()
471
    {
472
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
473
    return mBasicAngle;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public int getObjectName(int numLayers)
479
    {
480
    return R.string.ivy2;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public int getInventor(int numLayers)
486
    {
487
    return R.string.ivy2_inventor;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public int getComplexity(int numLayers)
493
    {
494
    return 1;
495
    }
496
}
(23-23/38)