Project

General

Profile

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

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

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 getNumStickerTypes(int numLayers)
166
    {
167
    return NUM_STICKERS;
168
    }
169

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

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

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179

    
180
  int getNumCubitFaces()
181
    {
182
    return FACES_PER_CUBIT;
183
    }
184

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

    
187
  float[][] getCubitPositions(int numLayers)
188
    {
189
    final float DIST_CORNER = (numLayers-1)*0.50f;
190
    final float DIST_CENTER = (numLayers-1)*0.50f;
191

    
192
    final float[][] CENTERS = new float[10][];
193

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

    
205
    return CENTERS;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  ObjectShape getObjectShape(int cubit, int numLayers)
211
    {
212
    int variant = getCubitVariant(cubit,numLayers);
213

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

    
219
      float[][] centers= new float[][] { {-0.5f,-0.5f,-0.5f} };
220
      float[][] corners= new float[][] { {0.03f,0.10f}, {0.02f,0.10f} };
221
      int[] cornerIndices= new int[3*(IVY_N+1)+4];
222
      int[] centerIndices= new int[3*(IVY_N+1)+4];
223
      double[][] vertices= new double[3*(IVY_N+1)+4][3];
224
      int[][] vertIndices= new int[6][IVY_N+4];
225
      int[] bandIndices  = new int[] { 0,0,0,1,1,1 };
226

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

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

    
239
      cornerIndices[0] = 1;
240
      cornerIndices[1] = 0;
241
      cornerIndices[2] = 0;
242
      cornerIndices[3] = 0;
243

    
244
      centerIndices[0] = 0;
245
      centerIndices[1] = 0;
246
      centerIndices[2] = 0;
247
      centerIndices[3] = 0;
248

    
249
      vertices[0][0] = 0.0;
250
      vertices[0][1] = 0.0;
251
      vertices[0][2] = 0.0;
252
      vertices[1][0] =-1.0;
253
      vertices[1][1] = 0.0;
254
      vertices[1][2] = 0.0;
255
      vertices[2][0] = 0.0;
256
      vertices[2][1] =-1.0;
257
      vertices[2][2] = 0.0;
258
      vertices[3][0] = 0.0;
259
      vertices[3][1] = 0.0;
260
      vertices[3][2] =-1.0;
261

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

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

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

    
283
      int N1 = 4;
284
      int N2 = N1 + IVY_N + 1;
285
      int N3 = N2 + IVY_N + 1;
286

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

    
294
        vertices[N1+i][0] = CORR*(cos1-0.5) - 0.5;
295
        vertices[N1+i][1] = CORR*(sin1-0.5) - 0.5;
296
        vertices[N1+i][2] = 0.0;
297

    
298
        vertices[N2+i][0] = 0.0;
299
        vertices[N2+i][1] = CORR*(sin2-0.5) - 0.5;
300
        vertices[N2+i][2] = CORR*(cos2-0.5) - 0.5;
301

    
302
        vertices[N3+i][0] = CORR*(cos2-0.5) - 0.5;
303
        vertices[N3+i][1] = 0.0;
304
        vertices[N3+i][2] = CORR*(sin2-0.5) - 0.5;
305

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

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

    
325
      int[] bandIndices= new int[] { 0,1 };
326
      int[] indexes    = new int[2*IVY_N];
327
      float[][] corners= new float[][] { {0.03f,0.10f} };
328
      float[][] centers= new float[][] { {-0.0f,-0.0f,-0.5f} };
329

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

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

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

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

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

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

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  Static4D getQuat(int cubit, int numLayers)
368
    {
369
    switch(cubit)
370
      {
371
      case  0: return QUATS[0];
372
      case  1: return QUATS[2];
373
      case  2: return QUATS[3];
374
      case  3: return QUATS[1];
375

    
376
      case  4: return QUATS[8];
377
      case  5: return QUATS[11];
378
      case  6: return QUATS[10];
379
      case  7: return QUATS[9];
380
      case  8: return QUATS[0];
381
      case  9: return QUATS[2];
382
      }
383

    
384
    return QUATS[0];
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  int getNumCubitVariants(int numLayers)
390
    {
391
    return 2;
392
    }
393

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

    
396
  int getCubitVariant(int cubit, int numLayers)
397
    {
398
    return cubit<4 ? 0:1;
399
    }
400

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

    
403
  int getFaceColor(int cubit, int cubitface, int numLayers)
404
    {
405
    return mFaceMap[cubit][cubitface];
406
    }
407

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

    
410
  int getColor(int face)
411
    {
412
    return FACE_COLORS[face];
413
    }
414

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

    
417
  ObjectSticker retSticker(int face)
418
    {
419
    return mStickers[face/NUM_FACES];
420
    }
421

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

    
424
  float returnMultiplier()
425
    {
426
    return 2.0f;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430
// PUBLIC API
431

    
432
  public Static3D[] getRotationAxis()
433
    {
434
    return ROT_AXIS;
435
    }
436

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

    
439
  public int[] getBasicAngle()
440
    {
441
    return BASIC_ANGLE;
442
    }
443

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

    
446
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
447
    {
448
    if( curr==0 )
449
      {
450
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
451
      }
452
    else
453
      {
454
      int newVector = rnd.nextInt(NUM_AXIS -1);
455
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
456
      }
457

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

    
460
    switch( rnd.nextInt(2) )
461
      {
462
      case 0: scramble[curr][2] = -1; break;
463
      case 1: scramble[curr][2] =  1; break;
464
      }
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  public int getObjectName(int numLayers)
470
    {
471
    return R.string.ivy2;
472
    }
473

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

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

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

    
483
  public int getComplexity(int numLayers)
484
    {
485
    return 1;
486
    }
487
}
(28-28/41)