Project

General

Profile

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

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

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.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40
import org.distorted.objectlib.main.Twisty6;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class TwistyIvy extends Twisty6
45
{
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[][][] ENABLED = new int[][][]
55
      {
56
          {{0},{3},{3},{0}},
57
          {{2},{1},{1},{2}},
58
          {{2},{0},{0},{2}},
59
          {{1},{3},{3},{1}},
60
          {{0},{0},{1},{1}},
61
          {{2},{2},{3},{3}},
62
      };
63

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

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

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  public TwistyIvy(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
80
                   MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
81
    {
82
    super(numL, numL[0], quat, move, texture, mesh, effects, res, scrWidth);
83
    }
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

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

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

    
99
    return mStates;
100
    }
101

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

    
104
  protected int getResource(int[] numLayers)
105
    {
106
    return R.raw.ivy;
107
    }
108

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

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

    
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
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
128
         };
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

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

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

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

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

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

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  protected int getNumStickerTypes(int[] numLayers)
158
    {
159
    return NUM_STICKERS;
160
    }
161

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

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

    
172
    return mCuts;
173
    }
174

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

    
177
  private void getLayerRotatable(int[] numLayers)
178
    {
179
    if( mLayerRotatable==null )
180
      {
181
      int numAxis = ROT_AXIS.length;
182
      mLayerRotatable = new boolean[numAxis][];
183

    
184
      for(int i=0; i<numAxis; i++)
185
        {
186
        mLayerRotatable[i] = new boolean[numLayers[i]];
187
        for(int j=0; j<numLayers[i]; j++) mLayerRotatable[i][j] = true;
188
        }
189
      }
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  protected int getNumCubitFaces()
195
    {
196
    return 6;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  protected float[][] getCubitPositions(int[] numLayers)
202
    {
203
    final float DIST_CORNER = numLayers[0]-1;
204
    final float DIST_CENTER = numLayers[0]-1;
205

    
206
    final float[][] CENTERS = new float[10][];
207

    
208
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
209
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
210
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
211
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
212
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
213
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
214
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
215
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
216
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
217
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
218

    
219
    return CENTERS;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  protected ObjectShape getObjectShape(int cubit, int[] numLayers)
225
    {
226
    int variant = getCubitVariant(cubit,numLayers);
227

    
228
    if( variant==0 )
229
      {
230
      final float angle = (float)Math.PI/(2*IVY_N);
231
      final float CORR  = 1.0f - 2*IVY_D;
232

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

    
241
      float[][] bands =
242
        {
243
          {+0.015f,20,0.2f,0.5f,7,1,2},
244
          {-0.100f,20,0.2f,0.0f,2,1,2}
245
        };
246

    
247
      for(int i=0; i<3*(IVY_N+1); i++)
248
        {
249
        cornerIndices[i+4] = -1;
250
        centerIndices[i+4] = -1;
251
        }
252

    
253
      cornerIndices[0] = 1;
254
      cornerIndices[1] = 0;
255
      cornerIndices[2] = 0;
256
      cornerIndices[3] = 0;
257

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

    
263
      vertices[0][0] = 0.0;
264
      vertices[0][1] = 0.0;
265
      vertices[0][2] = 0.0;
266
      vertices[1][0] =-2.0;
267
      vertices[1][1] = 0.0;
268
      vertices[1][2] = 0.0;
269
      vertices[2][0] = 0.0;
270
      vertices[2][1] =-2.0;
271
      vertices[2][2] = 0.0;
272
      vertices[3][0] = 0.0;
273
      vertices[3][1] = 0.0;
274
      vertices[3][2] =-2.0;
275

    
276
      vertIndices[0][0] = 2;
277
      vertIndices[0][1] = 0;
278
      vertIndices[0][2] = 1;
279
      vertIndices[3][0] = 2;
280
      vertIndices[3][1] = 0;
281
      vertIndices[3][2] = 1;
282

    
283
      vertIndices[1][0] = 3;
284
      vertIndices[1][1] = 0;
285
      vertIndices[1][2] = 2;
286
      vertIndices[4][0] = 3;
287
      vertIndices[4][1] = 0;
288
      vertIndices[4][2] = 2;
289

    
290
      vertIndices[2][0] = 1;
291
      vertIndices[2][1] = 0;
292
      vertIndices[2][2] = 3;
293
      vertIndices[5][0] = 1;
294
      vertIndices[5][1] = 0;
295
      vertIndices[5][2] = 3;
296

    
297
      int N1 = 4;
298
      int N2 = N1 + IVY_N + 1;
299
      int N3 = N2 + IVY_N + 1;
300

    
301
      for(int i=0; i<=IVY_N; i++)
302
        {
303
        double cos1 = Math.cos((IVY_N-i)*angle);
304
        double sin1 = Math.sin((IVY_N-i)*angle);
305
        double cos2 = Math.cos((      i)*angle);
306
        double sin2 = Math.sin((      i)*angle);
307

    
308
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
309
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
310
        vertices[N1+i][2] = 0.0;
311

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

    
316
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
317
        vertices[N3+i][1] = 0.0;
318
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
319

    
320
        vertIndices[0][i+3] = N1 + i;
321
        vertIndices[1][i+3] = N2 + i;
322
        vertIndices[2][i+3] = N3 + i;
323
        vertIndices[3][i+3] = N1 + i;
324
        vertIndices[4][i+3] = N2 + i;
325
        vertIndices[5][i+3] = N3 + i;
326
        }
327

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

    
339
      int[] bandIndices= new int[] { 0,1 };
340
      int[] indexes    = new int[2*IVY_N];
341
      float[][] corners= new float[][] { {0.05f,0.20f} };
342
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
343

    
344
      for(int i=0; i<IVY_N; i++)
345
        {
346
        double sin = Math.sin(i*angle);
347
        double cos = Math.cos(i*angle);
348

    
349
        vertices[i      ][0] = CORR*(1.0f-2*cos);
350
        vertices[i      ][1] = CORR*(1.0f-2*sin);
351
        vertices[i      ][2] = 0;
352
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
353
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
354
        vertices[i+IVY_N][2] = 0;
355
        }
356

    
357
      for(int i=0; i<2*IVY_N; i++)
358
        {
359
        vert_indices[0][i] = i;
360
        vert_indices[1][i] = 2*IVY_N-1-i;
361
        }
362

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

    
369
      float[][] bands =
370
        {
371
          {+0.03f,35,0.5f,0.5f,5,0,0},
372
          {+0.10f,45,0.5f,0.0f,2,0,0}
373
        };
374

    
375
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
376
      }
377
    }
378

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

    
381
  protected Static4D getQuat(int cubit, int[] numLayers)
382
    {
383
    if( mQuats==null ) initializeQuats();
384

    
385
    switch(cubit)
386
      {
387
      case  0: return mQuats[0];
388
      case  1: return mQuats[2];
389
      case  2: return mQuats[3];
390
      case  3: return mQuats[1];
391

    
392
      case  4: return mQuats[8];
393
      case  5: return mQuats[11];
394
      case  6: return mQuats[10];
395
      case  7: return mQuats[9];
396
      case  8: return mQuats[0];
397
      case  9: return mQuats[2];
398
      }
399

    
400
    return mQuats[0];
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  protected int getNumCubitVariants(int[] numLayers)
406
    {
407
    return 2;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  protected int getCubitVariant(int cubit, int[] numLayers)
413
    {
414
    return cubit<4 ? 0:1;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

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

    
430
           {  6, 12,12,12,12,12 },
431
           {  7, 12,12,12,12,12 },
432
           {  8, 12,12,12,12,12 },
433
           {  9, 12,12,12,12,12 },
434
           { 10, 12,12,12,12,12 },
435
           { 11, 12,12,12,12,12 },
436
         };
437
      }
438

    
439
    return mFaceMap[cubit][cubitface];
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

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

    
455
      if( ObjectControl.isInIconMode() )
456
        {
457
        float mult = 1.5f;
458
        strokes[0]*=mult;
459
        strokes[1]*=mult;
460
        }
461

    
462
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
463
      }
464

    
465
    return mStickers[face/NUM_FACE_COLORS];
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469
// PUBLIC API
470

    
471
  public Static3D[] getRotationAxis()
472
    {
473
    return ROT_AXIS;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public Movement getMovement()
479
    {
480
    if( mMovement==null )
481
      {
482
      int[] numLayers = getNumLayers();
483
      if( mCuts==null ) getCuts(numLayers);
484
      getLayerRotatable(numLayers);
485
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers[0],TYPE_SPLIT_CORNER,ENABLED);
486
      }
487
    return mMovement;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public int[] getBasicAngle()
493
    {
494
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
495
    return mBasicAngle;
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

    
500
  public ObjectType intGetObjectType(int[] numLayers)
501
    {
502
    return ObjectType.IVY_2;
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

    
507
  public int getObjectName(int[] numLayers)
508
    {
509
    return R.string.ivy2;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

    
514
  public int getInventor(int[] numLayers)
515
    {
516
    return R.string.ivy2_inventor;
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

    
521
  public int getComplexity(int[] numLayers)
522
    {
523
    return 1;
524
    }
525
}
(12-12/25)