Project

General

Profile

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

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

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.ObjectType;
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, 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
  protected int getResource(int numLayers)
104
    {
105
    return R.raw.ivy;
106
    }
107

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

    
110
  private void initializeQuats()
111
    {
112
    mQuats = new Static4D[]
113
         {
114
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
115
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
116
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
117
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
118

    
119
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
120
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
121
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
122
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
123
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
124
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
125
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
126
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
127
         };
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  protected int[] getSolvedQuats(int cubit, int numLayers)
133
    {
134
    if( mQuats==null ) initializeQuats();
135
    int status = retCubitSolvedStatus(cubit,numLayers);
136
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
137
    }
138

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

    
141
  protected Static4D[] getQuats()
142
    {
143
    if( mQuats==null ) initializeQuats();
144
    return mQuats;
145
    }
146

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

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

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

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

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

    
163
  protected float[][] getCuts(int numLayers)
164
    {
165
    if( mCuts==null )
166
      {
167
      float[] cut = new float[] {0.0f};
168
      mCuts = new float[][] { cut,cut,cut,cut };
169
      }
170

    
171
    return mCuts;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  private void getLayerRotatable(int numLayers)
177
    {
178
    if( mLayerRotatable==null )
179
      {
180
      int numAxis = ROT_AXIS.length;
181
      boolean[] tmp = new boolean[numLayers];
182
      for(int i=0; i<numLayers; i++) tmp[i] = true;
183
      mLayerRotatable = new boolean[numAxis][];
184
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
185
      }
186
    }
187

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

    
190
  protected int getNumCubitFaces()
191
    {
192
    return 6;
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  protected float[][] getCubitPositions(int numLayers)
198
    {
199
    final float DIST_CORNER = numLayers-1;
200
    final float DIST_CENTER = numLayers-1;
201

    
202
    final float[][] CENTERS = new float[10][];
203

    
204
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
205
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
206
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
207
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
208
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
209
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
210
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
211
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
212
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
213
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
214

    
215
    return CENTERS;
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  protected ObjectShape getObjectShape(int cubit, int numLayers)
221
    {
222
    int variant = getCubitVariant(cubit,numLayers);
223

    
224
    if( variant==0 )
225
      {
226
      final float angle = (float)Math.PI/(2*IVY_N);
227
      final float CORR  = 1.0f - 2*IVY_D;
228

    
229
      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
230
      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
231
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
232
      int[] centerIndices= new int[3*(IVY_N+1)+4];
233
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
234
      int[][] vertIndices= new int[6][IVY_N+4];
235
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
236

    
237
      float[][] bands =
238
        {
239
          {+0.015f,20,0.2f,0.5f,7,1,2},
240
          {-0.100f,20,0.2f,0.0f,2,1,2}
241
        };
242

    
243
      for(int i=0; i<3*(IVY_N+1); i++)
244
        {
245
        cornerIndices[i+4] = -1;
246
        centerIndices[i+4] = -1;
247
        }
248

    
249
      cornerIndices[0] = 1;
250
      cornerIndices[1] = 0;
251
      cornerIndices[2] = 0;
252
      cornerIndices[3] = 0;
253

    
254
      centerIndices[0] = 0;
255
      centerIndices[1] = 0;
256
      centerIndices[2] = 0;
257
      centerIndices[3] = 0;
258

    
259
      vertices[0][0] = 0.0;
260
      vertices[0][1] = 0.0;
261
      vertices[0][2] = 0.0;
262
      vertices[1][0] =-2.0;
263
      vertices[1][1] = 0.0;
264
      vertices[1][2] = 0.0;
265
      vertices[2][0] = 0.0;
266
      vertices[2][1] =-2.0;
267
      vertices[2][2] = 0.0;
268
      vertices[3][0] = 0.0;
269
      vertices[3][1] = 0.0;
270
      vertices[3][2] =-2.0;
271

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

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

    
286
      vertIndices[2][0] = 1;
287
      vertIndices[2][1] = 0;
288
      vertIndices[2][2] = 3;
289
      vertIndices[5][0] = 1;
290
      vertIndices[5][1] = 0;
291
      vertIndices[5][2] = 3;
292

    
293
      int N1 = 4;
294
      int N2 = N1 + IVY_N + 1;
295
      int N3 = N2 + IVY_N + 1;
296

    
297
      for(int i=0; i<=IVY_N; i++)
298
        {
299
        double cos1 = Math.cos((IVY_N-i)*angle);
300
        double sin1 = Math.sin((IVY_N-i)*angle);
301
        double cos2 = Math.cos((      i)*angle);
302
        double sin2 = Math.sin((      i)*angle);
303

    
304
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
305
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
306
        vertices[N1+i][2] = 0.0;
307

    
308
        vertices[N2+i][0] = 0.0;
309
        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
310
        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
311

    
312
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
313
        vertices[N3+i][1] = 0.0;
314
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
315

    
316
        vertIndices[0][i+3] = N1 + i;
317
        vertIndices[1][i+3] = N2 + i;
318
        vertIndices[2][i+3] = N3 + i;
319
        vertIndices[3][i+3] = N1 + i;
320
        vertIndices[4][i+3] = N2 + i;
321
        vertIndices[5][i+3] = N3 + i;
322
        }
323

    
324
      float C = 1.0f - SQ2/2;
325
      float[] convexCenter = new float[] {-C,-C,-C};
326
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
327
      }
328
    else
329
      {
330
      final float angle = (float)Math.PI/(2*IVY_N);
331
      final float CORR  = 1.0f - 2*IVY_D;
332
      double[][] vertices = new double[2*IVY_N][3];
333
      int[][] vert_indices = new int[2][2*IVY_N];
334

    
335
      int[] bandIndices= new int[] { 0,1 };
336
      int[] indexes    = new int[2*IVY_N];
337
      float[][] corners= new float[][] { {0.05f,0.20f} };
338
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
339

    
340
      for(int i=0; i<IVY_N; i++)
341
        {
342
        double sin = Math.sin(i*angle);
343
        double cos = Math.cos(i*angle);
344

    
345
        vertices[i      ][0] = CORR*(1.0f-2*cos);
346
        vertices[i      ][1] = CORR*(1.0f-2*sin);
347
        vertices[i      ][2] = 0;
348
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
349
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
350
        vertices[i+IVY_N][2] = 0;
351
        }
352

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

    
359
      for(int i=0; i<2*IVY_N; i++)
360
        {
361
        indexes[i] = -1;
362
        }
363
      indexes[0] = indexes[IVY_N] = 0;
364

    
365
      float[][] bands =
366
        {
367
          {+0.03f,35,0.5f,0.5f,5,0,0},
368
          {+0.10f,45,0.5f,0.0f,2,0,0}
369
        };
370

    
371
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
372
      }
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  protected Static4D getQuat(int cubit, int numLayers)
378
    {
379
    if( mQuats==null ) initializeQuats();
380

    
381
    switch(cubit)
382
      {
383
      case  0: return mQuats[0];
384
      case  1: return mQuats[2];
385
      case  2: return mQuats[3];
386
      case  3: return mQuats[1];
387

    
388
      case  4: return mQuats[8];
389
      case  5: return mQuats[11];
390
      case  6: return mQuats[10];
391
      case  7: return mQuats[9];
392
      case  8: return mQuats[0];
393
      case  9: return mQuats[2];
394
      }
395

    
396
    return mQuats[0];
397
    }
398

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

    
401
  protected int getNumCubitVariants(int numLayers)
402
    {
403
    return 2;
404
    }
405

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

    
408
  protected int getCubitVariant(int cubit, int numLayers)
409
    {
410
    return cubit<4 ? 0:1;
411
    }
412

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

    
415
  protected int getFaceColor(int cubit, int cubitface, int numLayers)
416
    {
417
    if( mFaceMap==null )
418
      {
419
      mFaceMap = new int[][]
420
         {
421
           {  4, 0, 2, 12,12,12 },
422
           {  5, 1, 2, 12,12,12 },
423
           {  4, 1, 3, 12,12,12 },
424
           {  5, 0, 3, 12,12,12 },
425

    
426
           {  6, 12,12,12,12,12 },
427
           {  7, 12,12,12,12,12 },
428
           {  8, 12,12,12,12,12 },
429
           {  9, 12,12,12,12,12 },
430
           { 10, 12,12,12,12,12 },
431
           { 11, 12,12,12,12,12 },
432
         };
433
      }
434

    
435
    return mFaceMap[cubit][cubitface];
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  protected ObjectSticker retSticker(int face)
441
    {
442
    if( mStickers==null )
443
      {
444
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
445
      mStickers = new ObjectSticker[NUM_STICKERS];
446
      float D = (float)(Math.PI/4);
447
      final float[][] angles = { { 0,0,D },{ D,D } };
448
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
449
      final float[] strokes = { 0.03f, 0.08f };
450
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
451
      }
452

    
453
    return mStickers[face/NUM_FACE_COLORS];
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457
// PUBLIC API
458

    
459
  public Static3D[] getRotationAxis()
460
    {
461
    return ROT_AXIS;
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public Movement getMovement()
467
    {
468
    if( mMovement==null )
469
      {
470
      int numLayers = getNumLayers();
471
      if( mCuts==null ) getCuts(numLayers);
472
      getLayerRotatable(numLayers);
473
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
474
      }
475
    return mMovement;
476
    }
477

    
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479

    
480
  public int[] getBasicAngle()
481
    {
482
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
483
    return mBasicAngle;
484
    }
485

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

    
488
  public ObjectType intGetObjectList(int numLayers)
489
    {
490
    return ObjectType.IVY_2;
491
    }
492

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

    
495
  public int getObjectName(int numLayers)
496
    {
497
    return R.string.ivy2;
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public int getInventor(int numLayers)
503
    {
504
    return R.string.ivy2_inventor;
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
  public int getComplexity(int numLayers)
510
    {
511
    return 1;
512
    }
513
}
(12-12/25)