Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ e1dc3366

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 android.content.res.Resources;
23

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

    
34
import java.util.Random;
35

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

    
38
public class TwistyIvy extends TwistyObject
39
{
40
  public static final float IVY_D = 0.003f;
41
  private static final int  IVY_N = 8;
42

    
43
  private static final int FACES_PER_CUBIT =6;
44

    
45
  // the four rotation axis of a RubikIvy. Must be normalized.
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[] BASIC_ANGLE = new int[] { 3,3,3,3 };
55

    
56
  private static final int[] FACE_COLORS = new int[]
57
         {
58
           COLOR_YELLOW, COLOR_WHITE,
59
           COLOR_BLUE  , COLOR_GREEN,
60
           COLOR_RED   , COLOR_ORANGE
61
         };
62

    
63
  // All legal rotation quats of a RubikIvy
64
  private static final Static4D[] QUATS = new Static4D[]
65
         {
66
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
67
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
68
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
69
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
70

    
71
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
72
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
73
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
74
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
75
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
76
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
77
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
78
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
79
         };
80

    
81
  private static final int[][] mFaceMap =
82
         {
83
           {  4, 0, 2, 12,12,12 },
84
           {  5, 1, 2, 12,12,12 },
85
           {  4, 1, 3, 12,12,12 },
86
           {  5, 0, 3, 12,12,12 },
87

    
88
           {  6, 12,12,12,12,12 },
89
           {  7, 12,12,12,12,12 },
90
           {  8, 12,12,12,12,12 },
91
           {  9, 12,12,12,12,12 },
92
           { 10, 12,12,12,12,12 },
93
           { 11, 12,12,12,12,12 },
94
         };
95

    
96
  private static final ObjectSticker[] mStickers;
97

    
98
  private static final float[][] STICKERS = new float[][]
99
          {
100
             { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f },
101
             { -0.5f, 0.5f, 0.5f, -0.5f }
102
          };
103
  private static final int NUM_STICKERS = STICKERS.length;
104

    
105
  static
106
    {
107
    mStickers = new ObjectSticker[NUM_STICKERS];
108

    
109
    float D = (float)(Math.PI/4);
110
    final float[][] angles = { { 0,0,D },{ D,D } };
111
    final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
112
    final float[] strokes = { 0.03f, 0.08f };
113

    
114
    for(int s=0; s<NUM_STICKERS; s++)
115
      {
116
      mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
117
      }
118
    }
119

    
120
  private int mCurrState;
121
  private int mIndexExcluded;
122
  private final ScrambleState[] mStates;
123
  private int[][] mScrambleTable;
124
  private int[] mNumOccurences;
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
129
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
130
    {
131
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
132

    
133
    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
134

    
135
    mStates = new ScrambleState[]
136
      {
137
      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
138
      };
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  int[] getSolvedQuats(int cubit, int numLayers)
144
    {
145
    int status = retCubitSolvedStatus(cubit,numLayers);
146
    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],QUATS);
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  float getScreenRatio()
152
    {
153
    return 1.0f;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  Static4D[] getQuats()
159
    {
160
    return QUATS;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  int getNumFaces()
166
    {
167
    return FACE_COLORS.length;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  boolean shouldResetTextureMaps()
173
    {
174
    return false;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  int getSolvedFunctionIndex()
180
    {
181
    return 0;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  int getNumStickerTypes(int numLayers)
187
    {
188
    return NUM_STICKERS;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  float[][] getCuts(int numLayers)
194
    {
195
    float[] cut = new float[] {0.0f};
196
    return new float[][] { cut,cut,cut,cut };
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  int getNumCubitFaces()
202
    {
203
    return FACES_PER_CUBIT;
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  float[][] getCubitPositions(int numLayers)
209
    {
210
    final float DIST_CORNER = (numLayers-1)*0.50f;
211
    final float DIST_CENTER = (numLayers-1)*0.50f;
212

    
213
    final float[][] CENTERS = new float[10][];
214

    
215
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
216
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
217
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
218
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
219
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
220
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
221
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
222
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
223
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
224
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
225

    
226
    return CENTERS;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  ObjectShape getObjectShape(int cubit, int numLayers)
232
    {
233
    int variant = getCubitVariant(cubit,numLayers);
234

    
235
    if( variant==0 )
236
      {
237
      final float angle = (float)Math.PI/(2*IVY_N);
238
      final float CORR  = 1.0f - 2*IVY_D;
239

    
240
      float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
241
      float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
242
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
243
      int[] centerIndices= new int[3*(IVY_N+1)+4];
244
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
245
      int[][] vertIndices= new int[6][IVY_N+4];
246
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
247

    
248
      float[][] bands =
249
        {
250
          {+0.015f,20,0.2f,0.5f,7,1,2},
251
          {-0.100f,20,0.2f,0.0f,2,1,2}
252
        };
253

    
254
      for(int i=0; i<3*(IVY_N+1); i++)
255
        {
256
        cornerIndices[i+4] = -1;
257
        centerIndices[i+4] = -1;
258
        }
259

    
260
      cornerIndices[0] = 1;
261
      cornerIndices[1] = 0;
262
      cornerIndices[2] = 0;
263
      cornerIndices[3] = 0;
264

    
265
      centerIndices[0] = 0;
266
      centerIndices[1] = 0;
267
      centerIndices[2] = 0;
268
      centerIndices[3] = 0;
269

    
270
      vertices[0][0] = 0.0;
271
      vertices[0][1] = 0.0;
272
      vertices[0][2] = 0.0;
273
      vertices[1][0] =-1.0;
274
      vertices[1][1] = 0.0;
275
      vertices[1][2] = 0.0;
276
      vertices[2][0] = 0.0;
277
      vertices[2][1] =-1.0;
278
      vertices[2][2] = 0.0;
279
      vertices[3][0] = 0.0;
280
      vertices[3][1] = 0.0;
281
      vertices[3][2] =-1.0;
282

    
283
      vertIndices[0][0] = 2;
284
      vertIndices[0][1] = 0;
285
      vertIndices[0][2] = 1;
286
      vertIndices[3][0] = 2;
287
      vertIndices[3][1] = 0;
288
      vertIndices[3][2] = 1;
289

    
290
      vertIndices[1][0] = 3;
291
      vertIndices[1][1] = 0;
292
      vertIndices[1][2] = 2;
293
      vertIndices[4][0] = 3;
294
      vertIndices[4][1] = 0;
295
      vertIndices[4][2] = 2;
296

    
297
      vertIndices[2][0] = 1;
298
      vertIndices[2][1] = 0;
299
      vertIndices[2][2] = 3;
300
      vertIndices[5][0] = 1;
301
      vertIndices[5][1] = 0;
302
      vertIndices[5][2] = 3;
303

    
304
      int N1 = 4;
305
      int N2 = N1 + IVY_N + 1;
306
      int N3 = N2 + IVY_N + 1;
307

    
308
      for(int i=0; i<=IVY_N; i++)
309
        {
310
        double cos1 = Math.cos((IVY_N-i)*angle);
311
        double sin1 = Math.sin((IVY_N-i)*angle);
312
        double cos2 = Math.cos((      i)*angle);
313
        double sin2 = Math.sin((      i)*angle);
314

    
315
        vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
316
        vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
317
        vertices[N1+i][2] = 0.0;
318

    
319
        vertices[N2+i][0] = 0.0;
320
        vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
321
        vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
322

    
323
        vertices[N3+i][0] = CORR*(cos2-0.5) - 0.5;
324
        vertices[N3+i][1] = 0.0;
325
        vertices[N3+i][2] = CORR*(sin2-0.5) - 0.5;
326

    
327
        vertIndices[0][i+3] = N1 + i;
328
        vertIndices[1][i+3] = N2 + i;
329
        vertIndices[2][i+3] = N3 + i;
330
        vertIndices[3][i+3] = N1 + i;
331
        vertIndices[4][i+3] = N2 + i;
332
        vertIndices[5][i+3] = N3 + i;
333
        }
334

    
335
      float C = 0.5f - SQ2/4;
336
      float[] convexCenter = new float[] {-C,-C,-C};
337
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
338
      }
339
    else
340
      {
341
      final float angle = (float)Math.PI/(2*IVY_N);
342
      final float CORR  = 1.0f - 2*IVY_D;
343
      double[][] vertices = new double[2*IVY_N][3];
344
      int[][] vert_indices = new int[2][2*IVY_N];
345

    
346
      int[] bandIndices= new int[] { 0,1 };
347
      int[] indexes    = new int[2*IVY_N];
348
      float[][] corners= new float[][] { {0.03f,0.10f} };
349
      float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
350

    
351
      for(int i=0; i<IVY_N; i++)
352
        {
353
        double sin = Math.sin(i*angle);
354
        double cos = Math.cos(i*angle);
355

    
356
        vertices[i      ][0] = CORR*(0.5f-cos);
357
        vertices[i      ][1] = CORR*(0.5f-sin);
358
        vertices[i      ][2] = 0;
359
        vertices[i+IVY_N][0] = CORR*(cos-0.5f);
360
        vertices[i+IVY_N][1] = CORR*(sin-0.5f);
361
        vertices[i+IVY_N][2] = 0;
362
        }
363

    
364
      for(int i=0; i<2*IVY_N; i++)
365
        {
366
        vert_indices[0][i] = i;
367
        vert_indices[1][i] = 2*IVY_N-1-i;
368
        }
369

    
370
      for(int i=0; i<2*IVY_N; i++)
371
        {
372
        indexes[i] = -1;
373
        }
374
      indexes[0] = indexes[IVY_N] = 0;
375

    
376
      float[][] bands =
377
        {
378
          {+0.03f,35,0.5f,0.5f,5,0,0},
379
          {+0.10f,45,0.5f,0.0f,2,0,0}
380
        };
381

    
382
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
383
      }
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

    
388
  Static4D getQuat(int cubit, int numLayers)
389
    {
390
    switch(cubit)
391
      {
392
      case  0: return QUATS[0];
393
      case  1: return QUATS[2];
394
      case  2: return QUATS[3];
395
      case  3: return QUATS[1];
396

    
397
      case  4: return QUATS[8];
398
      case  5: return QUATS[11];
399
      case  6: return QUATS[10];
400
      case  7: return QUATS[9];
401
      case  8: return QUATS[0];
402
      case  9: return QUATS[2];
403
      }
404

    
405
    return QUATS[0];
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  int getNumCubitVariants(int numLayers)
411
    {
412
    return 2;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  int getCubitVariant(int cubit, int numLayers)
418
    {
419
    return cubit<4 ? 0:1;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  int getFaceColor(int cubit, int cubitface, int numLayers)
425
    {
426
    return mFaceMap[cubit][cubitface];
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  int getColor(int face)
432
    {
433
    return FACE_COLORS[face];
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  ObjectSticker retSticker(int face)
439
    {
440
    return mStickers[face/NUM_FACES];
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  float returnMultiplier()
446
    {
447
    return 2.0f;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  private void initializeScrambling()
453
    {
454
    int numLayers = getNumLayers();
455

    
456
    if( mScrambleTable ==null )
457
      {
458
      mScrambleTable = new int[NUM_AXIS][numLayers];
459
      }
460
    if( mNumOccurences ==null )
461
      {
462
      int max=0;
463

    
464
      for (ScrambleState mState : mStates)
465
        {
466
        int tmp = mState.getTotal(-1);
467
        if (max < tmp) max = tmp;
468
        }
469

    
470
      mNumOccurences = new int[max];
471
      }
472

    
473
    for(int i=0; i<NUM_AXIS; i++)
474
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478
// PUBLIC API
479

    
480
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
481
    {
482
    if( curr==0 )
483
      {
484
      mCurrState     = 0;
485
      mIndexExcluded =-1;
486
      initializeScrambling();
487
      }
488

    
489
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
490

    
491
    scramble[curr][0] = info[0];
492
    scramble[curr][1] = info[1];
493
    scramble[curr][2] = info[2];
494

    
495
    mCurrState     = info[3];
496
    mIndexExcluded = info[0];
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
  public Static3D[] getRotationAxis()
502
    {
503
    return ROT_AXIS;
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  public int[] getBasicAngle()
509
    {
510
    return BASIC_ANGLE;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

    
515
  public int getObjectName(int numLayers)
516
    {
517
    return R.string.ivy2;
518
    }
519

    
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

    
522
  public int getInventor(int numLayers)
523
    {
524
    return R.string.ivy2_inventor;
525
    }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

    
529
  public int getComplexity(int numLayers)
530
    {
531
    return 1;
532
    }
533
}
(28-28/41)