Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 7ee89540

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[][][] ENABLED = new int[][][]
49
      {
50
          {{0},{3},{3},{0}},
51
          {{2},{1},{1},{2}},
52
          {{2},{0},{0},{2}},
53
          {{1},{3},{3},{1}},
54
          {{0},{0},{1},{1}},
55
          {{2},{2},{3},{3}},
56
      };
57

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

    
62
  private ScrambleState[] mStates;
63
  private int[] mBasicAngle;
64
  private Static4D[] mQuats;
65
  private float[][] mCuts;
66
  private boolean[][] mLayerRotatable;
67
  private int[][] mFaceMap;
68
  private ObjectSticker[] mStickers;
69
  private Movement mMovement;
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

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

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

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

    
93
    return mStates;
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

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

    
107
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
108
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
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
         };
116
    }
117

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

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

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

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

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  int getSolvedFunctionIndex()
138
    {
139
    return 0;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  int getNumStickerTypes(int numLayers)
145
    {
146
    return NUM_STICKERS;
147
    }
148

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

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

    
159
    return mCuts;
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

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

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

    
178
  int getNumCubitFaces()
179
    {
180
    return 6;
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

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

    
190
    final float[][] CENTERS = new float[10][];
191

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

    
203
    return CENTERS;
204
    }
205

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

    
208
  ObjectShape getObjectShape(int cubit, int numLayers)
209
    {
210
    int variant = getCubitVariant(cubit,numLayers);
211

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

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

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

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

    
237
      cornerIndices[0] = 1;
238
      cornerIndices[1] = 0;
239
      cornerIndices[2] = 0;
240
      cornerIndices[3] = 0;
241

    
242
      centerIndices[0] = 0;
243
      centerIndices[1] = 0;
244
      centerIndices[2] = 0;
245
      centerIndices[3] = 0;
246

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

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

    
267
      vertIndices[1][0] = 3;
268
      vertIndices[1][1] = 0;
269
      vertIndices[1][2] = 2;
270
      vertIndices[4][0] = 3;
271
      vertIndices[4][1] = 0;
272
      vertIndices[4][2] = 2;
273

    
274
      vertIndices[2][0] = 1;
275
      vertIndices[2][1] = 0;
276
      vertIndices[2][2] = 3;
277
      vertIndices[5][0] = 1;
278
      vertIndices[5][1] = 0;
279
      vertIndices[5][2] = 3;
280

    
281
      int N1 = 4;
282
      int N2 = N1 + IVY_N + 1;
283
      int N3 = N2 + IVY_N + 1;
284

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

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

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

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

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

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

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

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

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

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

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

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

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

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

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

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

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

    
384
    return mQuats[0];
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  int getNumCubitVariants(int numLayers)
390
    {
391
    return 2;
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

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

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

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

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

    
423
    return mFaceMap[cubit][cubitface];
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

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

    
441
    return mStickers[face/NUM_FACE_COLORS];
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
// PUBLIC API
446

    
447
  public Static3D[] getRotationAxis()
448
    {
449
    return ROT_AXIS;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

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

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

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

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

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

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

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

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

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