Project

General

Profile

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

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

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
  // the four rotation axis of a RubikIvy. Must be normalized.
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
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
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
47
         };
48

    
49
  private static final int[] FACE_COLORS = new int[]
50
         {
51
           COLOR_YELLOW, COLOR_WHITE,
52
           COLOR_BLUE  , COLOR_GREEN,
53
           COLOR_RED   , COLOR_ORANGE
54
         };
55

    
56
  private static final int NUM_STICKERS = 2;
57
  public static final float IVY_D = 0.003f;
58
  private static final int  IVY_N = 8;
59
  private static final int FACES_PER_CUBIT =6;
60

    
61
  private int mCurrState;
62
  private int mIndexExcluded;
63
  private final ScrambleState[] mStates;
64
  private int[][] mScrambleTable;
65
  private int[] mNumOccurences;
66
  private int[] mBasicAngle;
67
  private Static4D[] mQuats;
68
  private int[][] mFaceMap;
69
  private ObjectSticker[] mStickers;
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

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

    
78
    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
79

    
80
    mStates = new ScrambleState[]
81
      {
82
      new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
83
      };
84
    }
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
  private void initializeQuats()
89
    {
90
    mQuats = new Static4D[]
91
         {
92
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
93
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
94
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
95
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
96

    
97
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
98
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
99
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
100
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
101
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
102
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
103
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
104
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
105
         };
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  int[] getSolvedQuats(int cubit, int numLayers)
111
    {
112
    if( mQuats==null ) initializeQuats();
113
    int status = retCubitSolvedStatus(cubit,numLayers);
114
    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],mQuats);
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  float getScreenRatio()
120
    {
121
    return 1.0f;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  Static4D[] getQuats()
127
    {
128
    if( mQuats==null ) initializeQuats();
129
    return mQuats;
130
    }
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  int getNumFaces()
135
    {
136
    return FACE_COLORS.length;
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  boolean shouldResetTextureMaps()
142
    {
143
    return false;
144
    }
145

    
146
///////////////////////////////////////////////////////////////////////////////////////////////////
147

    
148
  int getSolvedFunctionIndex()
149
    {
150
    return 0;
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  int getNumStickerTypes(int numLayers)
156
    {
157
    return NUM_STICKERS;
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  float[][] getCuts(int numLayers)
163
    {
164
    float[] cut = new float[] {0.0f};
165
    return new float[][] { cut,cut,cut,cut };
166
    }
167

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

    
170
  int getNumCubitFaces()
171
    {
172
    return FACES_PER_CUBIT;
173
    }
174

    
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

    
177
  float[][] getCubitPositions(int numLayers)
178
    {
179
    final float DIST_CORNER = (numLayers-1)*0.50f;
180
    final float DIST_CENTER = (numLayers-1)*0.50f;
181

    
182
    final float[][] CENTERS = new float[10][];
183

    
184
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
185
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
186
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
187
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
188
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
189
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
190
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
191
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
192
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
193
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
194

    
195
    return CENTERS;
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  ObjectShape getObjectShape(int cubit, int numLayers)
201
    {
202
    int variant = getCubitVariant(cubit,numLayers);
203

    
204
    if( variant==0 )
205
      {
206
      final float angle = (float)Math.PI/(2*IVY_N);
207
      final float CORR  = 1.0f - 2*IVY_D;
208

    
209
      float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
210
      float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
211
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
212
      int[] centerIndices= new int[3*(IVY_N+1)+4];
213
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
214
      int[][] vertIndices= new int[6][IVY_N+4];
215
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
216

    
217
      float[][] bands =
218
        {
219
          {+0.015f,20,0.2f,0.5f,7,1,2},
220
          {-0.100f,20,0.2f,0.0f,2,1,2}
221
        };
222

    
223
      for(int i=0; i<3*(IVY_N+1); i++)
224
        {
225
        cornerIndices[i+4] = -1;
226
        centerIndices[i+4] = -1;
227
        }
228

    
229
      cornerIndices[0] = 1;
230
      cornerIndices[1] = 0;
231
      cornerIndices[2] = 0;
232
      cornerIndices[3] = 0;
233

    
234
      centerIndices[0] = 0;
235
      centerIndices[1] = 0;
236
      centerIndices[2] = 0;
237
      centerIndices[3] = 0;
238

    
239
      vertices[0][0] = 0.0;
240
      vertices[0][1] = 0.0;
241
      vertices[0][2] = 0.0;
242
      vertices[1][0] =-1.0;
243
      vertices[1][1] = 0.0;
244
      vertices[1][2] = 0.0;
245
      vertices[2][0] = 0.0;
246
      vertices[2][1] =-1.0;
247
      vertices[2][2] = 0.0;
248
      vertices[3][0] = 0.0;
249
      vertices[3][1] = 0.0;
250
      vertices[3][2] =-1.0;
251

    
252
      vertIndices[0][0] = 2;
253
      vertIndices[0][1] = 0;
254
      vertIndices[0][2] = 1;
255
      vertIndices[3][0] = 2;
256
      vertIndices[3][1] = 0;
257
      vertIndices[3][2] = 1;
258

    
259
      vertIndices[1][0] = 3;
260
      vertIndices[1][1] = 0;
261
      vertIndices[1][2] = 2;
262
      vertIndices[4][0] = 3;
263
      vertIndices[4][1] = 0;
264
      vertIndices[4][2] = 2;
265

    
266
      vertIndices[2][0] = 1;
267
      vertIndices[2][1] = 0;
268
      vertIndices[2][2] = 3;
269
      vertIndices[5][0] = 1;
270
      vertIndices[5][1] = 0;
271
      vertIndices[5][2] = 3;
272

    
273
      int N1 = 4;
274
      int N2 = N1 + IVY_N + 1;
275
      int N3 = N2 + IVY_N + 1;
276

    
277
      for(int i=0; i<=IVY_N; i++)
278
        {
279
        double cos1 = Math.cos((IVY_N-i)*angle);
280
        double sin1 = Math.sin((IVY_N-i)*angle);
281
        double cos2 = Math.cos((      i)*angle);
282
        double sin2 = Math.sin((      i)*angle);
283

    
284
        vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
285
        vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
286
        vertices[N1+i][2] = 0.0;
287

    
288
        vertices[N2+i][0] = 0.0;
289
        vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
290
        vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
291

    
292
        vertices[N3+i][0] = CORR*(cos2-0.5) - 0.5;
293
        vertices[N3+i][1] = 0.0;
294
        vertices[N3+i][2] = CORR*(sin2-0.5) - 0.5;
295

    
296
        vertIndices[0][i+3] = N1 + i;
297
        vertIndices[1][i+3] = N2 + i;
298
        vertIndices[2][i+3] = N3 + i;
299
        vertIndices[3][i+3] = N1 + i;
300
        vertIndices[4][i+3] = N2 + i;
301
        vertIndices[5][i+3] = N3 + i;
302
        }
303

    
304
      float C = 0.5f - SQ2/4;
305
      float[] convexCenter = new float[] {-C,-C,-C};
306
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
307
      }
308
    else
309
      {
310
      final float angle = (float)Math.PI/(2*IVY_N);
311
      final float CORR  = 1.0f - 2*IVY_D;
312
      double[][] vertices = new double[2*IVY_N][3];
313
      int[][] vert_indices = new int[2][2*IVY_N];
314

    
315
      int[] bandIndices= new int[] { 0,1 };
316
      int[] indexes    = new int[2*IVY_N];
317
      float[][] corners= new float[][] { {0.03f,0.10f} };
318
      float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
319

    
320
      for(int i=0; i<IVY_N; i++)
321
        {
322
        double sin = Math.sin(i*angle);
323
        double cos = Math.cos(i*angle);
324

    
325
        vertices[i      ][0] = CORR*(0.5f-cos);
326
        vertices[i      ][1] = CORR*(0.5f-sin);
327
        vertices[i      ][2] = 0;
328
        vertices[i+IVY_N][0] = CORR*(cos-0.5f);
329
        vertices[i+IVY_N][1] = CORR*(sin-0.5f);
330
        vertices[i+IVY_N][2] = 0;
331
        }
332

    
333
      for(int i=0; i<2*IVY_N; i++)
334
        {
335
        vert_indices[0][i] = i;
336
        vert_indices[1][i] = 2*IVY_N-1-i;
337
        }
338

    
339
      for(int i=0; i<2*IVY_N; i++)
340
        {
341
        indexes[i] = -1;
342
        }
343
      indexes[0] = indexes[IVY_N] = 0;
344

    
345
      float[][] bands =
346
        {
347
          {+0.03f,35,0.5f,0.5f,5,0,0},
348
          {+0.10f,45,0.5f,0.0f,2,0,0}
349
        };
350

    
351
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
352
      }
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356

    
357
  Static4D getQuat(int cubit, int numLayers)
358
    {
359
    if( mQuats==null ) initializeQuats();
360

    
361
    switch(cubit)
362
      {
363
      case  0: return mQuats[0];
364
      case  1: return mQuats[2];
365
      case  2: return mQuats[3];
366
      case  3: return mQuats[1];
367

    
368
      case  4: return mQuats[8];
369
      case  5: return mQuats[11];
370
      case  6: return mQuats[10];
371
      case  7: return mQuats[9];
372
      case  8: return mQuats[0];
373
      case  9: return mQuats[2];
374
      }
375

    
376
    return mQuats[0];
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  int getNumCubitVariants(int numLayers)
382
    {
383
    return 2;
384
    }
385

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

    
388
  int getCubitVariant(int cubit, int numLayers)
389
    {
390
    return cubit<4 ? 0:1;
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  int getFaceColor(int cubit, int cubitface, int numLayers)
396
    {
397
    if( mFaceMap==null )
398
      {
399
      mFaceMap = new int[][]
400
         {
401
           {  4, 0, 2, 12,12,12 },
402
           {  5, 1, 2, 12,12,12 },
403
           {  4, 1, 3, 12,12,12 },
404
           {  5, 0, 3, 12,12,12 },
405

    
406
           {  6, 12,12,12,12,12 },
407
           {  7, 12,12,12,12,12 },
408
           {  8, 12,12,12,12,12 },
409
           {  9, 12,12,12,12,12 },
410
           { 10, 12,12,12,12,12 },
411
           { 11, 12,12,12,12,12 },
412
         };
413
      }
414

    
415
    return mFaceMap[cubit][cubitface];
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  int getColor(int face)
421
    {
422
    return FACE_COLORS[face];
423
    }
424

    
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

    
427
  ObjectSticker retSticker(int face)
428
    {
429
    if( mStickers==null )
430
      {
431
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
432
      mStickers = new ObjectSticker[NUM_STICKERS];
433
      float D = (float)(Math.PI/4);
434
      final float[][] angles = { { 0,0,D },{ D,D } };
435
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
436
      final float[] strokes = { 0.03f, 0.08f };
437
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
438
      }
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
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
511
    return mBasicAngle;
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

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

    
521
///////////////////////////////////////////////////////////////////////////////////////////////////
522

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

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

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