Project

General

Profile

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

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

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.003f;
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

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  TwistyIvy(int size, Static4D quat, DistortedTexture texture,
68
            MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
69
    {
70
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.IVY, res, scrWidth);
71

    
72
    int[] tmp = {0,-1,0, 0,1,0, 1,-1,0, 1,1,0 };
73

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

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

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

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

    
94
    return mStates;
95
    }
96

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

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

    
108
         new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
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
         };
117
    }
118

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

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

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  float getScreenRatio()
131
    {
132
    return 1.0f;
133
    }
134

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

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

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  int getNumFaces()
146
    {
147
    return FACE_COLORS.length;
148
    }
149

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

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

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

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

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

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

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

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

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

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

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

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

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

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

    
206
    return CENTERS;
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

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

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

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

    
387
    return mQuats[0];
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

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

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

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

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

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

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

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

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

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

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

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

    
451
    return mStickers[face/NUM_FACES];
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

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

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462
// PUBLIC API
463

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

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  public int[] getBasicAngle()
472
    {
473
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
474
    return mBasicAngle;
475
    }
476

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

    
479
  public int getObjectName(int numLayers)
480
    {
481
    return R.string.ivy2;
482
    }
483

    
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485

    
486
  public int getInventor(int numLayers)
487
    {
488
    return R.string.ivy2_inventor;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

    
493
  public int getComplexity(int numLayers)
494
    {
495
    return 1;
496
    }
497
}
(28-28/42)