Project

General

Profile

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

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

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 size, Static4D quat, Static3D move, DistortedTexture texture,
80
                   MeshSquare mesh, DistortedEffects effects, Resources res, int scrWidth)
81
    {
82
    super(size, size, 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
      boolean[] tmp = new boolean[numLayers];
183
      for(int i=0; i<numLayers; i++) tmp[i] = true;
184
      mLayerRotatable = new boolean[numAxis][];
185
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
186
      }
187
    }
188

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

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

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

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

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

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

    
216
    return CENTERS;
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

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

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

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

    
397
    return mQuats[0];
398
    }
399

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

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

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

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

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

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

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

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

    
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

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

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

    
459
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
460
      }
461

    
462
    return mStickers[face/NUM_FACE_COLORS];
463
    }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466
// PUBLIC API
467

    
468
  public Static3D[] getRotationAxis()
469
    {
470
    return ROT_AXIS;
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public Movement getMovement()
476
    {
477
    if( mMovement==null )
478
      {
479
      int numLayers = getNumLayers();
480
      if( mCuts==null ) getCuts(numLayers);
481
      getLayerRotatable(numLayers);
482
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_CORNER,ENABLED);
483
      }
484
    return mMovement;
485
    }
486

    
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488

    
489
  public int[] getBasicAngle()
490
    {
491
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
492
    return mBasicAngle;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public ObjectType intGetObjectType(int numLayers)
498
    {
499
    return ObjectType.IVY_2;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
  public int getObjectName(int numLayers)
505
    {
506
    return R.string.ivy2;
507
    }
508

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

    
511
  public int getInventor(int numLayers)
512
    {
513
    return R.string.ivy2_inventor;
514
    }
515

    
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517

    
518
  public int getComplexity(int numLayers)
519
    {
520
    return 1;
521
    }
522
}
(12-12/25)