Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ ef018c1b

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 android.content.res.Resources;
23

    
24
import org.distorted.helpers.ObjectShape;
25
import org.distorted.helpers.ObjectSticker;
26
import org.distorted.helpers.ScrambleState;
27
import org.distorted.library.main.DistortedEffects;
28
import org.distorted.library.main.DistortedTexture;
29
import org.distorted.library.mesh.MeshSquare;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32
import org.distorted.main.R;
33

    
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

    
36
public class TwistyIvy extends Twisty6
37
{
38
  static final Static3D[] ROT_AXIS = new Static3D[]
39
         {
40
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
41
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
42
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
43
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
44
         };
45

    
46
  private static final int NUM_STICKERS = 2;
47
  public static final float IVY_D = 0.006f;
48
  private static final int  IVY_N = 8;
49

    
50
  private ScrambleState[] mStates;
51
  private int[] mBasicAngle;
52
  private Static4D[] mQuats;
53
  private float[][] mCuts;
54
  private boolean[][] mLayerRotatable;
55
  private int[][] mFaceMap;
56
  private ObjectSticker[] mStickers;
57
  private Movement mMovement;
58

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
62
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
63
    {
64
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
65
    }
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  ScrambleState[] getScrambleStates()
70
    {
71
    if( mStates==null )
72
      {
73
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
74

    
75
      mStates = new ScrambleState[]
76
        {
77
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
78
        };
79
      }
80

    
81
    return mStates;
82
    }
83

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

    
86
  private void initializeQuats()
87
    {
88
    mQuats = new Static4D[]
89
         {
90
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
91
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
92
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
93
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
94

    
95
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
96
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
97
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
98
         new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
99
         new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
100
         new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
101
         new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
102
         new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
103
         };
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

    
108
  int[] getSolvedQuats(int cubit, int numLayers)
109
    {
110
    if( mQuats==null ) initializeQuats();
111
    int status = retCubitSolvedStatus(cubit,numLayers);
112
    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],mQuats);
113
    }
114

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

    
117
  Static4D[] getQuats()
118
    {
119
    if( mQuats==null ) initializeQuats();
120
    return mQuats;
121
    }
122

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

    
125
  int getSolvedFunctionIndex()
126
    {
127
    return 0;
128
    }
129

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

    
132
  int getNumStickerTypes(int numLayers)
133
    {
134
    return NUM_STICKERS;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  float[][] getCuts(int numLayers)
140
    {
141
    if( mCuts==null )
142
      {
143
      float[] cut = new float[] {0.0f};
144
      mCuts = new float[][] { cut,cut,cut,cut };
145
      }
146

    
147
    return mCuts;
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

    
152
  private void getLayerRotatable(int numLayers)
153
    {
154
    if( mLayerRotatable==null )
155
      {
156
      int numAxis = ROT_AXIS.length;
157
      boolean[] tmp = new boolean[numLayers];
158
      for(int i=0; i<numLayers; i++) tmp[i] = true;
159
      mLayerRotatable = new boolean[numAxis][];
160
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
161
      }
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  int getNumCubitFaces()
167
    {
168
    return 6;
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  float[][] getCubitPositions(int numLayers)
174
    {
175
    final float DIST_CORNER = numLayers-1;
176
    final float DIST_CENTER = numLayers-1;
177

    
178
    final float[][] CENTERS = new float[10][];
179

    
180
    CENTERS[0] = new float[] { DIST_CORNER, DIST_CORNER, DIST_CORNER };
181
    CENTERS[1] = new float[] {-DIST_CORNER, DIST_CORNER,-DIST_CORNER };
182
    CENTERS[2] = new float[] {-DIST_CORNER,-DIST_CORNER, DIST_CORNER };
183
    CENTERS[3] = new float[] { DIST_CORNER,-DIST_CORNER,-DIST_CORNER };
184
    CENTERS[4] = new float[] { DIST_CENTER,           0,           0 };
185
    CENTERS[5] = new float[] {-DIST_CENTER,           0,           0 };
186
    CENTERS[6] = new float[] {           0, DIST_CENTER,           0 };
187
    CENTERS[7] = new float[] {           0,-DIST_CENTER,           0 };
188
    CENTERS[8] = new float[] {           0,           0, DIST_CENTER };
189
    CENTERS[9] = new float[] {           0,           0,-DIST_CENTER };
190

    
191
    return CENTERS;
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  ObjectShape getObjectShape(int cubit, int numLayers)
197
    {
198
    int variant = getCubitVariant(cubit,numLayers);
199

    
200
    if( variant==0 )
201
      {
202
      final float angle = (float)Math.PI/(2*IVY_N);
203
      final float CORR  = 1.0f - 2*IVY_D;
204

    
205
      float[][] centers= new float[][] { {-1.0f,-1.0f,-1.0f} };
206
      float[][] corners= new float[][] { {0.05f,0.20f}, {0.04f,0.20f} };
207
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
208
      int[] centerIndices= new int[3*(IVY_N+1)+4];
209
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
210
      int[][] vertIndices= new int[6][IVY_N+4];
211
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
212

    
213
      float[][] bands =
214
        {
215
          {+0.015f,20,0.2f,0.5f,7,1,2},
216
          {-0.100f,20,0.2f,0.0f,2,1,2}
217
        };
218

    
219
      for(int i=0; i<3*(IVY_N+1); i++)
220
        {
221
        cornerIndices[i+4] = -1;
222
        centerIndices[i+4] = -1;
223
        }
224

    
225
      cornerIndices[0] = 1;
226
      cornerIndices[1] = 0;
227
      cornerIndices[2] = 0;
228
      cornerIndices[3] = 0;
229

    
230
      centerIndices[0] = 0;
231
      centerIndices[1] = 0;
232
      centerIndices[2] = 0;
233
      centerIndices[3] = 0;
234

    
235
      vertices[0][0] = 0.0;
236
      vertices[0][1] = 0.0;
237
      vertices[0][2] = 0.0;
238
      vertices[1][0] =-2.0;
239
      vertices[1][1] = 0.0;
240
      vertices[1][2] = 0.0;
241
      vertices[2][0] = 0.0;
242
      vertices[2][1] =-2.0;
243
      vertices[2][2] = 0.0;
244
      vertices[3][0] = 0.0;
245
      vertices[3][1] = 0.0;
246
      vertices[3][2] =-2.0;
247

    
248
      vertIndices[0][0] = 2;
249
      vertIndices[0][1] = 0;
250
      vertIndices[0][2] = 1;
251
      vertIndices[3][0] = 2;
252
      vertIndices[3][1] = 0;
253
      vertIndices[3][2] = 1;
254

    
255
      vertIndices[1][0] = 3;
256
      vertIndices[1][1] = 0;
257
      vertIndices[1][2] = 2;
258
      vertIndices[4][0] = 3;
259
      vertIndices[4][1] = 0;
260
      vertIndices[4][2] = 2;
261

    
262
      vertIndices[2][0] = 1;
263
      vertIndices[2][1] = 0;
264
      vertIndices[2][2] = 3;
265
      vertIndices[5][0] = 1;
266
      vertIndices[5][1] = 0;
267
      vertIndices[5][2] = 3;
268

    
269
      int N1 = 4;
270
      int N2 = N1 + IVY_N + 1;
271
      int N3 = N2 + IVY_N + 1;
272

    
273
      for(int i=0; i<=IVY_N; i++)
274
        {
275
        double cos1 = Math.cos((IVY_N-i)*angle);
276
        double sin1 = Math.sin((IVY_N-i)*angle);
277
        double cos2 = Math.cos((      i)*angle);
278
        double sin2 = Math.sin((      i)*angle);
279

    
280
        vertices[N1+i][0] = CORR*(2*cos1-1.0) - 1.0;
281
        vertices[N1+i][1] = CORR*(2*sin1-1.0) - 1.0;
282
        vertices[N1+i][2] = 0.0;
283

    
284
        vertices[N2+i][0] = 0.0;
285
        vertices[N2+i][1] = CORR*(2*sin2-1.0) - 1.0;
286
        vertices[N2+i][2] = CORR*(2*cos2-1.0) - 1.0;
287

    
288
        vertices[N3+i][0] = CORR*(2*cos2-1.0) - 1.0;
289
        vertices[N3+i][1] = 0.0;
290
        vertices[N3+i][2] = CORR*(2*sin2-1.0) - 1.0;
291

    
292
        vertIndices[0][i+3] = N1 + i;
293
        vertIndices[1][i+3] = N2 + i;
294
        vertIndices[2][i+3] = N3 + i;
295
        vertIndices[3][i+3] = N1 + i;
296
        vertIndices[4][i+3] = N2 + i;
297
        vertIndices[5][i+3] = N3 + i;
298
        }
299

    
300
      float C = 1.0f - SQ2/2;
301
      float[] convexCenter = new float[] {-C,-C,-C};
302
      return new ObjectShape(vertices,vertIndices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), convexCenter);
303
      }
304
    else
305
      {
306
      final float angle = (float)Math.PI/(2*IVY_N);
307
      final float CORR  = 1.0f - 2*IVY_D;
308
      double[][] vertices = new double[2*IVY_N][3];
309
      int[][] vert_indices = new int[2][2*IVY_N];
310

    
311
      int[] bandIndices= new int[] { 0,1 };
312
      int[] indexes    = new int[2*IVY_N];
313
      float[][] corners= new float[][] { {0.05f,0.20f} };
314
      float[][] centers= new float[][] { {-0.0f,-0.0f,-1.0f} };
315

    
316
      for(int i=0; i<IVY_N; i++)
317
        {
318
        double sin = Math.sin(i*angle);
319
        double cos = Math.cos(i*angle);
320

    
321
        vertices[i      ][0] = CORR*(1.0f-2*cos);
322
        vertices[i      ][1] = CORR*(1.0f-2*sin);
323
        vertices[i      ][2] = 0;
324
        vertices[i+IVY_N][0] = CORR*(2*cos-1.0f);
325
        vertices[i+IVY_N][1] = CORR*(2*sin-1.0f);
326
        vertices[i+IVY_N][2] = 0;
327
        }
328

    
329
      for(int i=0; i<2*IVY_N; i++)
330
        {
331
        vert_indices[0][i] = i;
332
        vert_indices[1][i] = 2*IVY_N-1-i;
333
        }
334

    
335
      for(int i=0; i<2*IVY_N; i++)
336
        {
337
        indexes[i] = -1;
338
        }
339
      indexes[0] = indexes[IVY_N] = 0;
340

    
341
      float[][] bands =
342
        {
343
          {+0.03f,35,0.5f,0.5f,5,0,0},
344
          {+0.10f,45,0.5f,0.0f,2,0,0}
345
        };
346

    
347
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
348
      }
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  Static4D getQuat(int cubit, int numLayers)
354
    {
355
    if( mQuats==null ) initializeQuats();
356

    
357
    switch(cubit)
358
      {
359
      case  0: return mQuats[0];
360
      case  1: return mQuats[2];
361
      case  2: return mQuats[3];
362
      case  3: return mQuats[1];
363

    
364
      case  4: return mQuats[8];
365
      case  5: return mQuats[11];
366
      case  6: return mQuats[10];
367
      case  7: return mQuats[9];
368
      case  8: return mQuats[0];
369
      case  9: return mQuats[2];
370
      }
371

    
372
    return mQuats[0];
373
    }
374

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

    
377
  int getNumCubitVariants(int numLayers)
378
    {
379
    return 2;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  int getCubitVariant(int cubit, int numLayers)
385
    {
386
    return cubit<4 ? 0:1;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  int getFaceColor(int cubit, int cubitface, int numLayers)
392
    {
393
    if( mFaceMap==null )
394
      {
395
      mFaceMap = new int[][]
396
         {
397
           {  4, 0, 2, 12,12,12 },
398
           {  5, 1, 2, 12,12,12 },
399
           {  4, 1, 3, 12,12,12 },
400
           {  5, 0, 3, 12,12,12 },
401

    
402
           {  6, 12,12,12,12,12 },
403
           {  7, 12,12,12,12,12 },
404
           {  8, 12,12,12,12,12 },
405
           {  9, 12,12,12,12,12 },
406
           { 10, 12,12,12,12,12 },
407
           { 11, 12,12,12,12,12 },
408
         };
409
      }
410

    
411
    return mFaceMap[cubit][cubitface];
412
    }
413

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

    
416
  ObjectSticker retSticker(int face)
417
    {
418
    if( mStickers==null )
419
      {
420
      float[][] STICKERS = new float[][] { { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f }, { -0.5f, 0.5f, 0.5f, -0.5f } };
421
      mStickers = new ObjectSticker[NUM_STICKERS];
422
      float D = (float)(Math.PI/4);
423
      final float[][] angles = { { 0,0,D },{ D,D } };
424
      final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
425
      final float[] strokes = { 0.03f, 0.08f };
426
      for(int s=0; s<NUM_STICKERS; s++) mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
427
      }
428

    
429
    return mStickers[face/NUM_FACE_COLORS];
430
    }
431

    
432
///////////////////////////////////////////////////////////////////////////////////////////////////
433
// PUBLIC API
434

    
435
  public Static3D[] getRotationAxis()
436
    {
437
    return ROT_AXIS;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public Movement getMovement()
443
    {
444
    if( mMovement==null )
445
      {
446
      int numLayers = getNumLayers();
447
      if( mCuts==null ) getCuts(numLayers);
448
      getLayerRotatable(numLayers);
449

    
450
      mMovement = new MovementIvy(mCuts,mLayerRotatable,numLayers);
451
      }
452
    return mMovement;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public int[] getBasicAngle()
458
    {
459
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
460
    return mBasicAngle;
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  public int getObjectName(int numLayers)
466
    {
467
    return R.string.ivy2;
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  public int getInventor(int numLayers)
473
    {
474
    return R.string.ivy2_inventor;
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
  public int getComplexity(int numLayers)
480
    {
481
    return 1;
482
    }
483
}
(33-33/48)