Project

General

Profile

Download (16.2 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyIvy.java @ cc448c54

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

    
22
import static org.distorted.objectlib.main.Movement.TYPE_SPLIT_CORNER;
23

    
24
import android.content.res.Resources;
25

    
26
import org.distorted.library.main.DistortedEffects;
27
import org.distorted.library.main.DistortedTexture;
28
import org.distorted.library.mesh.MeshSquare;
29
import org.distorted.library.type.Static3D;
30
import org.distorted.library.type.Static4D;
31

    
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectList;
36
import org.distorted.objectlib.main.ObjectShape;
37
import org.distorted.objectlib.main.ObjectSticker;
38
import org.distorted.objectlib.main.ScrambleState;
39
import org.distorted.objectlib.main.Twisty6;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
public class TwistyIvy extends Twisty6
44
{
45
  static final Static3D[] ROT_AXIS = new Static3D[]
46
         {
47
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
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
         };
52

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

    
63
  private static final int NUM_STICKERS = 2;
64
  public static final float IVY_D = 0.006f;
65
  private static final int  IVY_N = 8;
66

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

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

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

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  protected ScrambleState[] getScrambleStates()
87
    {
88
    if( mStates==null )
89
      {
90
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
91

    
92
      mStates = new ScrambleState[]
93
        {
94
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
95
        };
96
      }
97

    
98
    return mStates;
99
    }
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

    
103
  private void initializeQuats()
104
    {
105
    mQuats = new Static4D[]
106
         {
107
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
108
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
109
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
110
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
111

    
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
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
118
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
119
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
120
         };
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

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

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

    
134
  protected Static4D[] getQuats()
135
    {
136
    if( mQuats==null ) initializeQuats();
137
    return mQuats;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  protected int getSolvedFunctionIndex()
143
    {
144
    return 0;
145
    }
146

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

    
149
  protected int getNumStickerTypes(int numLayers)
150
    {
151
    return NUM_STICKERS;
152
    }
153

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

    
156
  protected float[][] getCuts(int numLayers)
157
    {
158
    if( mCuts==null )
159
      {
160
      float[] cut = new float[] {0.0f};
161
      mCuts = new float[][] { cut,cut,cut,cut };
162
      }
163

    
164
    return mCuts;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

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

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  protected int getNumCubitFaces()
184
    {
185
    return 6;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  protected float[][] getCubitPositions(int numLayers)
191
    {
192
    final float DIST_CORNER = numLayers-1;
193
    final float DIST_CENTER = numLayers-1;
194

    
195
    final float[][] CENTERS = new float[10][];
196

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

    
208
    return CENTERS;
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  protected ObjectShape getObjectShape(int cubit, int numLayers)
214
    {
215
    int variant = getCubitVariant(cubit,numLayers);
216

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

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

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

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

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

    
247
      centerIndices[0] = 0;
248
      centerIndices[1] = 0;
249
      centerIndices[2] = 0;
250
      centerIndices[3] = 0;
251

    
252
      vertices[0][0] = 0.0;
253
      vertices[0][1] = 0.0;
254
      vertices[0][2] = 0.0;
255
      vertices[1][0] =-2.0;
256
      vertices[1][1] = 0.0;
257
      vertices[1][2] = 0.0;
258
      vertices[2][0] = 0.0;
259
      vertices[2][1] =-2.0;
260
      vertices[2][2] = 0.0;
261
      vertices[3][0] = 0.0;
262
      vertices[3][1] = 0.0;
263
      vertices[3][2] =-2.0;
264

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

    
272
      vertIndices[1][0] = 3;
273
      vertIndices[1][1] = 0;
274
      vertIndices[1][2] = 2;
275
      vertIndices[4][0] = 3;
276
      vertIndices[4][1] = 0;
277
      vertIndices[4][2] = 2;
278

    
279
      vertIndices[2][0] = 1;
280
      vertIndices[2][1] = 0;
281
      vertIndices[2][2] = 3;
282
      vertIndices[5][0] = 1;
283
      vertIndices[5][1] = 0;
284
      vertIndices[5][2] = 3;
285

    
286
      int N1 = 4;
287
      int N2 = N1 + IVY_N + 1;
288
      int N3 = N2 + IVY_N + 1;
289

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

    
297
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
298
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
299
        vertices[N1+i][2] = 0.0;
300

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

    
305
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
306
        vertices[N3+i][1] = 0.0;
307
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
308

    
309
        vertIndices[0][i+3] = N1 + i;
310
        vertIndices[1][i+3] = N2 + i;
311
        vertIndices[2][i+3] = N3 + i;
312
        vertIndices[3][i+3] = N1 + i;
313
        vertIndices[4][i+3] = N2 + i;
314
        vertIndices[5][i+3] = N3 + i;
315
        }
316

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

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

    
333
      for(int i=0; i<IVY_N; i++)
334
        {
335
        double sin = Math.sin(i*angle);
336
        double cos = Math.cos(i*angle);
337

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

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

    
352
      for(int i=0; i<2*IVY_N; i++)
353
        {
354
        indexes[i] = -1;
355
        }
356
      indexes[0] = indexes[IVY_N] = 0;
357

    
358
      float[][] bands =
359
        {
360
          {+0.03f,35,0.5f,0.5f,5,0,0},
361
          {+0.10f,45,0.5f,0.0f,2,0,0}
362
        };
363

    
364
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
365
      }
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  protected Static4D getQuat(int cubit, int numLayers)
371
    {
372
    if( mQuats==null ) initializeQuats();
373

    
374
    switch(cubit)
375
      {
376
      case  0: return mQuats[0];
377
      case  1: return mQuats[2];
378
      case  2: return mQuats[3];
379
      case  3: return mQuats[1];
380

    
381
      case  4: return mQuats[8];
382
      case  5: return mQuats[11];
383
      case  6: return mQuats[10];
384
      case  7: return mQuats[9];
385
      case  8: return mQuats[0];
386
      case  9: return mQuats[2];
387
      }
388

    
389
    return mQuats[0];
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  protected int getNumCubitVariants(int numLayers)
395
    {
396
    return 2;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  protected int getCubitVariant(int cubit, int numLayers)
402
    {
403
    return cubit<4 ? 0:1;
404
    }
405

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

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

    
419
           {  6, 12,12,12,12,12 },
420
           {  7, 12,12,12,12,12 },
421
           {  8, 12,12,12,12,12 },
422
           {  9, 12,12,12,12,12 },
423
           { 10, 12,12,12,12,12 },
424
           { 11, 12,12,12,12,12 },
425
         };
426
      }
427

    
428
    return mFaceMap[cubit][cubitface];
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

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

    
446
    return mStickers[face/NUM_FACE_COLORS];
447
    }
448

    
449
///////////////////////////////////////////////////////////////////////////////////////////////////
450
// PUBLIC API
451

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

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

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

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  public int[] getBasicAngle()
474
    {
475
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
476
    return mBasicAngle;
477
    }
478

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480

    
481
  public int getObjectName(int numLayers)
482
    {
483
    return R.string.ivy2;
484
    }
485

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

    
488
  public int getInventor(int numLayers)
489
    {
490
    return R.string.ivy2_inventor;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public int getComplexity(int numLayers)
496
    {
497
    return 1;
498
    }
499
}
(12-12/25)