Project

General

Profile

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

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

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 TwistyObject
37
{
38
  // the four rotation axis of a RubikIvy. Must be normalized.
39
  static final Static3D[] ROT_AXIS = new Static3D[]
40
         {
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
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
45
         };
46

    
47
  private static final int[] FACE_COLORS = new int[]
48
         {
49
           COLOR_YELLOW, COLOR_WHITE,
50
           COLOR_BLUE  , COLOR_GREEN,
51
           COLOR_RED   , COLOR_ORANGE
52
         };
53

    
54
  private static final int NUM_STICKERS = 2;
55
  public static final float IVY_D = 0.006f;
56
  private static final int  IVY_N = 8;
57
  private static final int FACES_PER_CUBIT =6;
58

    
59
  private ScrambleState[] mStates;
60
  private int[] mBasicAngle;
61
  private Static4D[] mQuats;
62
  private int[][] mFaceMap;
63
  private ObjectSticker[] mStickers;
64
  private Movement mMovement;
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
69
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
70
    {
71
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
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
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  ScrambleState[] getScrambleStates()
84
    {
85
    if( mStates==null )
86
      {
87
      int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
88

    
89
      mStates = new ScrambleState[]
90
        {
91
        new ScrambleState( new int[][] {tmp,tmp,tmp,tmp} )
92
        };
93
      }
94

    
95
    return mStates;
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  private void initializeQuats()
101
    {
102
    mQuats = new Static4D[]
103
         {
104
         new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
105
         new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
106
         new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
107
         new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
108

    
109
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
110
         new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
111
         new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
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
         };
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  int[] getSolvedQuats(int cubit, int numLayers)
123
    {
124
    if( mQuats==null ) initializeQuats();
125
    int status = retCubitSolvedStatus(cubit,numLayers);
126
    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],mQuats);
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  float getScreenRatio()
132
    {
133
    return 0.5f;
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  Static4D[] getQuats()
139
    {
140
    if( mQuats==null ) initializeQuats();
141
    return mQuats;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  int getNumFaceColors()
147
    {
148
    return FACE_COLORS.length;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  boolean shouldResetTextureMaps()
154
    {
155
    return false;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  int getSolvedFunctionIndex()
161
    {
162
    return 0;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  int getNumStickerTypes(int numLayers)
168
    {
169
    return NUM_STICKERS;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

    
174
  float[][] getCuts(int numLayers)
175
    {
176
    float[] cut = new float[] {0.0f};
177
    return new float[][] { cut,cut,cut,cut };
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  int getNumCubitFaces()
183
    {
184
    return FACES_PER_CUBIT;
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

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

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

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

    
207
    return CENTERS;
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

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

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

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

    
388
    return mQuats[0];
389
    }
390

    
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

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

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

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

    
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

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

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

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

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  int getColor(int face)
433
    {
434
    return FACE_COLORS[face];
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

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

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

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

    
457
  float returnMultiplier()
458
    {
459
    return 2.0f;
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463
// PUBLIC API
464

    
465
  public Static3D[] getRotationAxis()
466
    {
467
    return ROT_AXIS;
468
    }
469

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

    
472
  public Movement getMovement()
473
    {
474
    if( mMovement==null ) mMovement = new MovementIvy();
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 int getObjectName(int numLayers)
489
    {
490
    return R.string.ivy2;
491
    }
492

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

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

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

    
502
  public int getComplexity(int numLayers)
503
    {
504
    return 1;
505
    }
506
}
(29-29/44)