Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 6cf89a3e

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

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

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

    
131
    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
132

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

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

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

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  float getScreenRatio()
150
    {
151
    return 1.0f;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  Static4D[] getQuats()
157
    {
158
    return QUATS;
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  int getNumFaces()
164
    {
165
    return FACE_COLORS.length;
166
    }
167

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

    
170
  boolean shouldResetTextureMaps()
171
    {
172
    return false;
173
    }
174

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

    
177
  int getSolvedFunctionIndex()
178
    {
179
    return 0;
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  int getNumStickerTypes(int numLayers)
185
    {
186
    return NUM_STICKERS;
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

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

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

    
199
  int getNumCubitFaces()
200
    {
201
    return FACES_PER_CUBIT;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

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

    
211
    final float[][] CENTERS = new float[10][];
212

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

    
224
    return CENTERS;
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  ObjectShape getObjectShape(int cubit, int numLayers)
230
    {
231
    int variant = getCubitVariant(cubit,numLayers);
232

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

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

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

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

    
258
      cornerIndices[0] = 1;
259
      cornerIndices[1] = 0;
260
      cornerIndices[2] = 0;
261
      cornerIndices[3] = 0;
262

    
263
      centerIndices[0] = 0;
264
      centerIndices[1] = 0;
265
      centerIndices[2] = 0;
266
      centerIndices[3] = 0;
267

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

    
281
      vertIndices[0][0] = 2;
282
      vertIndices[0][1] = 0;
283
      vertIndices[0][2] = 1;
284
      vertIndices[3][0] = 2;
285
      vertIndices[3][1] = 0;
286
      vertIndices[3][2] = 1;
287

    
288
      vertIndices[1][0] = 3;
289
      vertIndices[1][1] = 0;
290
      vertIndices[1][2] = 2;
291
      vertIndices[4][0] = 3;
292
      vertIndices[4][1] = 0;
293
      vertIndices[4][2] = 2;
294

    
295
      vertIndices[2][0] = 1;
296
      vertIndices[2][1] = 0;
297
      vertIndices[2][2] = 3;
298
      vertIndices[5][0] = 1;
299
      vertIndices[5][1] = 0;
300
      vertIndices[5][2] = 3;
301

    
302
      int N1 = 4;
303
      int N2 = N1 + IVY_N + 1;
304
      int N3 = N2 + IVY_N + 1;
305

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

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

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

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

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

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

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

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

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

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

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

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

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

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

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

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

    
403
    return QUATS[0];
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  int getNumCubitVariants(int numLayers)
409
    {
410
    return 2;
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

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

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

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

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  int getColor(int face)
430
    {
431
    return FACE_COLORS[face];
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

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

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442

    
443
  float returnMultiplier()
444
    {
445
    return 2.0f;
446
    }
447

    
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449
// PUBLIC API
450

    
451
  public Static3D[] getRotationAxis()
452
    {
453
    return ROT_AXIS;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  public int[] getBasicAngle()
459
    {
460
    return BASIC_ANGLE;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
466
    {
467
    if( curr==0 )
468
      {
469
      mCurrState     = 0;
470
      mIndexExcluded =-1;
471
      }
472

    
473
    int total = mStates[mCurrState].getTotal(mIndexExcluded);
474
    int random= rnd.nextInt(total);
475
    int[] info= mStates[mCurrState].getInfo(random,mIndexExcluded);
476

    
477
    scramble[curr][0] = info[0];
478
    scramble[curr][1] = info[1];
479
    scramble[curr][2] = info[2];
480

    
481
    mCurrState     = info[3];
482
    mIndexExcluded = info[0];
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public int getObjectName(int numLayers)
488
    {
489
    return R.string.ivy2;
490
    }
491

    
492
///////////////////////////////////////////////////////////////////////////////////////////////////
493

    
494
  public int getInventor(int numLayers)
495
    {
496
    return R.string.ivy2_inventor;
497
    }
498

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

    
501
  public int getComplexity(int numLayers)
502
    {
503
    return 1;
504
    }
505
}
(28-28/41)