Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyIvy.java @ 8db55f55

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.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
import org.distorted.main.R;
32

    
33
import java.util.Random;
34

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

    
37
public class TwistyIvy extends TwistyObject
38
{
39
  public static final float IVY_D = 0.003f;
40
  private static final int  IVY_N = 8;
41

    
42
  private static final int FACES_PER_CUBIT =6;
43

    
44
  // the four rotation axis of a RubikIvy. Must be normalized.
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[] BASIC_ANGLE = new int[] { 3,3,3,3 };
54

    
55
  private static final int[] FACE_COLORS = new int[]
56
         {
57
           COLOR_YELLOW, COLOR_WHITE,
58
           COLOR_BLUE  , COLOR_GREEN,
59
           COLOR_RED   , COLOR_ORANGE
60
         };
61

    
62
  // All legal rotation quats of a RubikIvy
63
  private static final Static4D[] QUATS = new Static4D[]
64
         {
65
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
66
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
67
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
68
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
69

    
70
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
71
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
72
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
73
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
74
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
75
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
76
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
77
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
78
         };
79

    
80
  private static final int[][] mFaceMap =
81
         {
82
           {  4, 0, 2, 12,12,12 },
83
           {  5, 1, 2, 12,12,12 },
84
           {  4, 1, 3, 12,12,12 },
85
           {  5, 0, 3, 12,12,12 },
86

    
87
           {  6, 12,12,12,12,12 },
88
           {  7, 12,12,12,12,12 },
89
           {  8, 12,12,12,12,12 },
90
           {  9, 12,12,12,12,12 },
91
           { 10, 12,12,12,12,12 },
92
           { 11, 12,12,12,12,12 },
93
         };
94

    
95
  private static final ObjectSticker[] mStickers;
96

    
97
  private static final float[][] STICKERS = new float[][]
98
          {
99
             { 0.29258922f, -0.5f, 0.29258922f, 0.29258922f, -0.5f, 0.29258922f },
100
             { -0.5f, 0.5f, 0.5f, -0.5f }
101
          };
102
  private static final int NUM_STICKERS = STICKERS.length;
103

    
104
  static
105
    {
106
    mStickers = new ObjectSticker[NUM_STICKERS];
107

    
108
    float D = (float)(Math.PI/4);
109
    final float[][] angles = { { 0,0,D },{ D,D } };
110
    final float[][] radii  = { { 0,0.04f,0 },{ 0.06f,0.06f } };
111
    final float[] strokes = { 0.03f, 0.08f };
112

    
113
    for(int s=0; s<NUM_STICKERS; s++)
114
      {
115
      mStickers[s] = new ObjectSticker(STICKERS[s], angles[s],radii[s],strokes[s]);
116
      }
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
122
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
123
    {
124
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  int[] getSolvedQuats(int cubit, int numLayers)
130
    {
131
    int status = retCubitSolvedStatus(cubit,numLayers);
132
    return status<0 ? null : buildSolvedQuats(MovementIvy.FACE_AXIS[status],QUATS);
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  float getScreenRatio()
138
    {
139
    return 1.0f;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  Static4D[] getQuats()
145
    {
146
    return QUATS;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  int getNumFaces()
152
    {
153
    return FACE_COLORS.length;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  boolean shouldResetTextureMaps()
159
    {
160
    return false;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  int getSolvedFunctionIndex()
166
    {
167
    return 0;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  int getNumStickerTypes(int numLayers)
173
    {
174
    return NUM_STICKERS;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  float[][] getCuts(int numLayers)
180
    {
181
    float[] cut = new float[] {0.0f};
182
    return new float[][] { cut,cut,cut,cut };
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

    
187
  int getNumCubitFaces()
188
    {
189
    return FACES_PER_CUBIT;
190
    }
191

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

    
194
  float[][] getCubitPositions(int numLayers)
195
    {
196
    final float DIST_CORNER = (numLayers-1)*0.50f;
197
    final float DIST_CENTER = (numLayers-1)*0.50f;
198

    
199
    final float[][] CENTERS = new float[10][];
200

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

    
212
    return CENTERS;
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  ObjectShape getObjectShape(int cubit, int numLayers)
218
    {
219
    int variant = getCubitVariant(cubit,numLayers);
220

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

    
226
      float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
227
      float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
228
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
229
      int[] centerIndices= new int[3*(IVY_N+1)+4];
230
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
231
      int[][] vertIndices= new int[6][IVY_N+4];
232
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
233

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

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

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

    
251
      centerIndices[0] = 0;
252
      centerIndices[1] = 0;
253
      centerIndices[2] = 0;
254
      centerIndices[3] = 0;
255

    
256
      vertices[0][0] = 0.0;
257
      vertices[0][1] = 0.0;
258
      vertices[0][2] = 0.0;
259
      vertices[1][0] =-1.0;
260
      vertices[1][1] = 0.0;
261
      vertices[1][2] = 0.0;
262
      vertices[2][0] = 0.0;
263
      vertices[2][1] =-1.0;
264
      vertices[2][2] = 0.0;
265
      vertices[3][0] = 0.0;
266
      vertices[3][1] = 0.0;
267
      vertices[3][2] =-1.0;
268

    
269
      vertIndices[0][0] = 2;
270
      vertIndices[0][1] = 0;
271
      vertIndices[0][2] = 1;
272
      vertIndices[3][0] = 2;
273
      vertIndices[3][1] = 0;
274
      vertIndices[3][2] = 1;
275

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

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

    
290
      int N1 = 4;
291
      int N2 = N1 + IVY_N + 1;
292
      int N3 = N2 + IVY_N + 1;
293

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

    
301
        vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
302
        vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
303
        vertices[N1+i][2] = 0.0;
304

    
305
        vertices[N2+i][0] = 0.0;
306
        vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
307
        vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
308

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

    
313
        vertIndices[0][i+3] = N1 + i;
314
        vertIndices[1][i+3] = N2 + i;
315
        vertIndices[2][i+3] = N3 + i;
316
        vertIndices[3][i+3] = N1 + i;
317
        vertIndices[4][i+3] = N2 + i;
318
        vertIndices[5][i+3] = N3 + i;
319
        }
320

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

    
332
      int[] bandIndices= new int[] { 0,1 };
333
      int[] indexes    = new int[2*IVY_N];
334
      float[][] corners= new float[][] { {0.03f,0.10f} };
335
      float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
336

    
337
      for(int i=0; i<IVY_N; i++)
338
        {
339
        double sin = Math.sin(i*angle);
340
        double cos = Math.cos(i*angle);
341

    
342
        vertices[i      ][0] = CORR*(0.5f-cos);
343
        vertices[i      ][1] = CORR*(0.5f-sin);
344
        vertices[i      ][2] = 0;
345
        vertices[i+IVY_N][0] = CORR*(cos-0.5f);
346
        vertices[i+IVY_N][1] = CORR*(sin-0.5f);
347
        vertices[i+IVY_N][2] = 0;
348
        }
349

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

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

    
362
      float[][] bands =
363
        {
364
          {+0.03f,35,0.5f,0.5f,5,0,0},
365
          {+0.10f,45,0.5f,0.0f,2,0,0}
366
        };
367

    
368
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,indexes,centers,indexes,getNumCubitFaces(), null);
369
      }
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  Static4D getQuat(int cubit, int numLayers)
375
    {
376
    switch(cubit)
377
      {
378
      case  0: return QUATS[0];
379
      case  1: return QUATS[2];
380
      case  2: return QUATS[3];
381
      case  3: return QUATS[1];
382

    
383
      case  4: return QUATS[8];
384
      case  5: return QUATS[11];
385
      case  6: return QUATS[10];
386
      case  7: return QUATS[9];
387
      case  8: return QUATS[0];
388
      case  9: return QUATS[2];
389
      }
390

    
391
    return QUATS[0];
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

    
396
  int getNumCubitVariants(int numLayers)
397
    {
398
    return 2;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  int getCubitVariant(int cubit, int numLayers)
404
    {
405
    return cubit<4 ? 0:1;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  int getFaceColor(int cubit, int cubitface, int numLayers)
411
    {
412
    return mFaceMap[cubit][cubitface];
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  int getColor(int face)
418
    {
419
    return FACE_COLORS[face];
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  ObjectSticker retSticker(int face)
425
    {
426
    return mStickers[face/NUM_FACES];
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  float returnMultiplier()
432
    {
433
    return 2.0f;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437
// PUBLIC API
438

    
439
  public Static3D[] getRotationAxis()
440
    {
441
    return ROT_AXIS;
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public int[] getBasicAngle()
447
    {
448
    return BASIC_ANGLE;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
454
    {
455
    if( curr==0 )
456
      {
457
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
458
      }
459
    else
460
      {
461
      int newVector = rnd.nextInt(NUM_AXIS -1);
462
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
463
      }
464

    
465
    scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0 : 1;
466

    
467
    switch( rnd.nextInt(2) )
468
      {
469
      case 0: scramble[curr][2] = -1; break;
470
      case 1: scramble[curr][2] =  1; break;
471
      }
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public int getObjectName(int numLayers)
477
    {
478
    return R.string.ivy2;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public int getInventor(int numLayers)
484
    {
485
    return R.string.ivy2_inventor;
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public int getComplexity(int numLayers)
491
    {
492
    return 1;
493
    }
494
}
(28-28/41)