Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyHelicopter.java @ 85449b44

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
import java.util.Random;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
public class TwistyHelicopter extends TwistyObject
39
{
40
  // the six rotation axis of a Helicopter. Must be normalized.
41
  static final Static3D[] ROT_AXIS = new Static3D[]
42
         {
43
           new Static3D(     0, +SQ2/2, -SQ2/2),
44
           new Static3D(     0, -SQ2/2, -SQ2/2),
45
           new Static3D(+SQ2/2,      0, -SQ2/2),
46
           new Static3D(-SQ2/2,      0, -SQ2/2),
47
           new Static3D(+SQ2/2, -SQ2/2,      0),
48
           new Static3D(-SQ2/2, -SQ2/2,      0)
49
         };
50

    
51
  private static final int[] FACE_COLORS = new int[]
52
         {
53
           COLOR_YELLOW, COLOR_WHITE,
54
           COLOR_BLUE  , COLOR_GREEN,
55
           COLOR_RED   , COLOR_ORANGE
56
         };
57

    
58
  private static final int FACES_PER_CUBIT =6;
59

    
60
  private int mCurrState;
61
  private int mIndexExcluded;
62
  private final ScrambleState[] mStates;
63
  private int[][] mScrambleTable;
64
  private int[] mNumOccurences;
65
  private int[] mBasicAngle;
66
  private Static4D[] mQuats;
67
  private float[][] mCenters;
68
  private int[] mQuatIndices;
69
  private int[][] mFaceMap;
70
  private ObjectSticker[] mStickers;
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

    
74
  TwistyHelicopter(int size, Static4D quat, DistortedTexture texture,
75
                   MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
76
    {
77
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
78

    
79
    mStates = new ScrambleState[]
80
      {
81
      new ScrambleState( new int[][] { {0,1,1,2,1,2},{0,1,3,2,1,4},{0,1,5,2,1,6},{0,1,7,2,1,8},{0,1,9,2,1,10},{0,1,11,2,1,12} } ),
82
      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
83
      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
84
      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
85
      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
86
      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
87
      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
88
      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
89
      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
90
      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
91
      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
92
      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
93
      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
94
      };
95
    }
96

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

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

    
108
         new Static4D( SQ2/2,  SQ2/2,  0.00f,  0.00f ),
109
         new Static4D( SQ2/2, -SQ2/2,  0.00f,  0.00f ),
110
         new Static4D( SQ2/2,  0.00f,  SQ2/2,  0.00f ),
111
         new Static4D( SQ2/2,  0.00f, -SQ2/2,  0.00f ),
112
         new Static4D( SQ2/2,  0.00f,  0.00f,  SQ2/2 ),
113
         new Static4D( SQ2/2,  0.00f,  0.00f, -SQ2/2 ),
114
         new Static4D( 0.00f,  SQ2/2,  SQ2/2,  0.00f ),
115
         new Static4D( 0.00f,  SQ2/2, -SQ2/2,  0.00f ),
116
         new Static4D( 0.00f,  SQ2/2,  0.00f,  SQ2/2 ),
117
         new Static4D( 0.00f,  SQ2/2,  0.00f, -SQ2/2 ),
118
         new Static4D( 0.00f,  0.00f,  SQ2/2,  SQ2/2 ),
119
         new Static4D( 0.00f,  0.00f,  SQ2/2, -SQ2/2 ),
120

    
121
         new Static4D( 0.50f,  0.50f,  0.50f,  0.50f ),
122
         new Static4D( 0.50f,  0.50f,  0.50f, -0.50f ),
123
         new Static4D( 0.50f,  0.50f, -0.50f,  0.50f ),
124
         new Static4D( 0.50f,  0.50f, -0.50f, -0.50f ),
125
         new Static4D( 0.50f, -0.50f,  0.50f,  0.50f ),
126
         new Static4D( 0.50f, -0.50f,  0.50f, -0.50f ),
127
         new Static4D( 0.50f, -0.50f, -0.50f,  0.50f ),
128
         new Static4D( 0.50f, -0.50f, -0.50f, -0.50f )
129
         };
130
    }
131

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  int[] getSolvedQuats(int cubit, int numLayers)
135
    {
136
    if( mQuats==null ) initializeQuats();
137
    int status = retCubitSolvedStatus(cubit,numLayers);
138
    return status<0 ? null : buildSolvedQuats(MovementHelicopter.FACE_AXIS[status],mQuats);
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  float getScreenRatio()
144
    {
145
    return 1.6f;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  Static4D[] getQuats()
151
    {
152
    if( mQuats==null ) initializeQuats();
153
    return mQuats;
154
    }
155

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

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

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

    
165
  int getNumFaces()
166
    {
167
    return FACE_COLORS.length;
168
    }
169

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

    
172
  int getSolvedFunctionIndex()
173
    {
174
    return 0;
175
    }
176

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

    
179
  int getNumStickerTypes(int numLayers)
180
    {
181
    return 1;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  float[][] getCuts(int size)
187
    {
188
    float[] cut = new float[] { -SQ2/4, +SQ2/4 };
189
    return new float[][] { cut,cut,cut,cut,cut,cut };
190
    }
191

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

    
194
  int getNumCubitFaces()
195
    {
196
    return FACES_PER_CUBIT;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  float[][] getCubitPositions(int size)
202
    {
203
    if( mCenters==null )
204
      {
205
      float DIST_CORNER = 0.50f;
206
      float DIST_CENTER = 0.50f;
207
      float XY_CENTER = DIST_CORNER/3;
208

    
209
      mCenters = new float[][]
210
         {
211
             {   DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
212
             {   DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
213
             {   DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
214
             {   DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
215
             {  -DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
216
             {  -DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
217
             {  -DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
218
             {  -DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
219

    
220
             {   DIST_CENTER,     XY_CENTER,     XY_CENTER },
221
             {   DIST_CENTER,     XY_CENTER,    -XY_CENTER },
222
             {   DIST_CENTER,    -XY_CENTER,     XY_CENTER },
223
             {   DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
224

    
225
             {  -DIST_CENTER,     XY_CENTER,     XY_CENTER },
226
             {  -DIST_CENTER,     XY_CENTER,    -XY_CENTER },
227
             {  -DIST_CENTER,    -XY_CENTER,     XY_CENTER },
228
             {  -DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
229

    
230
             {   XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
231
             {   XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
232
             {  -XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
233
             {  -XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
234

    
235
             {   XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
236
             {   XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
237
             {  -XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
238
             {  -XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
239

    
240
             {   XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
241
             {   XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
242
             {  -XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
243
             {  -XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
244

    
245
             {   XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
246
             {   XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
247
             {  -XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
248
             {  -XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
249
         };
250
      }
251

    
252
    return mCenters;
253
    }
254

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

    
257
  ObjectShape getObjectShape(int cubit, int numLayers)
258
    {
259
    int variant = getCubitVariant(cubit,numLayers);
260

    
261
    if( variant==0 )
262
      {
263
      double[][] vertices = new double[][]
264
          {
265
            {-0.50f, 0.00f, 0.00f},
266
            { 0.00f,-0.50f, 0.00f},
267
            { 0.00f, 0.00f,-0.50f},
268
            {-0.25f,-0.25f,-0.25f},
269
            { 0.00f, 0.00f, 0.00f}
270
          };
271

    
272
      int[][] vert_indices = new int[][]
273
          {
274
            {0,1,4},
275
            {2,0,4},
276
            {1,2,4},
277
            {3,1,0},
278
            {3,2,1},
279
            {3,0,2}
280
          };
281

    
282
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,5} };
283
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
284
      float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
285
      int[] cornerIndices = new int[] { 1,1,1,0,0 };
286
      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
287
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
288
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
289
      }
290
    else
291
      {
292
      float E = 0.1666666f;
293

    
294
      double[][] vertices = new double[][]
295
          {
296
            { 0.00f +E, 0.00f +E, 0.00f },
297
            {-0.50f +E, 0.00f +E, 0.00f },
298
            { 0.00f +E,-0.50f +E, 0.00f },
299
            {-0.25f +E,-0.25f +E,-0.25f },
300
          };
301

    
302
      int[][] vert_indices = new int[][]
303
          {
304
            { 0,1,2 },
305
            { 2,1,3 },
306
            { 0,1,3 },
307
            { 2,0,3 }
308
          };
309

    
310
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,3} };
311
      int[] bandIndices   = new int[] { 0,1,1,1 };
312
      float[][] corners   = new float[][] { {0.06f,0.15f}, {0.06f,0.20f} };
313
      int[] cornerIndices = new int[] { 0,1,1,-1 };
314
      float[][] centers   = new float[][] { {-1.0f/12, -1.0f/12, -1.0f/4} };
315
      int[] centerIndices = new int[] { 0,0,0,-1 };
316
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
317
      }
318
    }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
  Static4D getQuat(int cubit, int numLayers)
323
    {
324
    if( mQuats==null ) initializeQuats();
325
    if( mQuatIndices==null ) mQuatIndices = new int[] { 0,13,14,1,12,2,3,7,20,6,13,17,7,23,18,12,22,10,8,16,11,21,19,9,3,15,14,0,5,2,1,4 };
326
    return mQuats[mQuatIndices[cubit]];
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  int getNumCubitVariants(int numLayers)
332
    {
333
    return 2;
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  int getCubitVariant(int cubit, int numLayers)
339
    {
340
    return cubit<8 ? 0:1;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  int getFaceColor(int cubit, int cubitface, int size)
346
    {
347
    if( mFaceMap==null )
348
      {
349
      mFaceMap = new int[][]
350
         {
351
           { 4,2,0, 6,6,6 },
352
           { 0,2,5, 6,6,6 },
353
           { 4,0,3, 6,6,6 },
354
           { 5,3,0, 6,6,6 },
355
           { 1,2,4, 6,6,6 },
356
           { 5,2,1, 6,6,6 },
357
           { 4,3,1, 6,6,6 },
358
           { 1,3,5, 6,6,6 },
359

    
360
           { 0 , 6,6,6,6,6 },
361
           { 0 , 6,6,6,6,6 },
362
           { 0 , 6,6,6,6,6 },
363
           { 0 , 6,6,6,6,6 },
364

    
365
           { 1 , 6,6,6,6,6 },
366
           { 1 , 6,6,6,6,6 },
367
           { 1 , 6,6,6,6,6 },
368
           { 1 , 6,6,6,6,6 },
369

    
370
           { 2 , 6,6,6,6,6 },
371
           { 2 , 6,6,6,6,6 },
372
           { 2 , 6,6,6,6,6 },
373
           { 2 , 6,6,6,6,6 },
374

    
375
           { 3 , 6,6,6,6,6 },
376
           { 3 , 6,6,6,6,6 },
377
           { 3 , 6,6,6,6,6 },
378
           { 3 , 6,6,6,6,6 },
379

    
380
           { 4 , 6,6,6,6,6 },
381
           { 4 , 6,6,6,6,6 },
382
           { 4 , 6,6,6,6,6 },
383
           { 4 , 6,6,6,6,6 },
384

    
385
           { 5 , 6,6,6,6,6 },
386
           { 5 , 6,6,6,6,6 },
387
           { 5 , 6,6,6,6,6 },
388
           { 5 , 6,6,6,6,6 },
389
         };
390
      }
391

    
392
    return mFaceMap[cubit][cubitface];
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  int getColor(int face)
398
    {
399
    return FACE_COLORS[face];
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  ObjectSticker retSticker(int face)
405
    {
406
    if( mStickers==null )
407
      {
408
      float[][] STICKERS = new float[][] { { -0.5f, 0.25f, 0.25f, -0.5f, 0.25f, 0.25f } };
409
      float radius = 0.03f;
410
      float stroke = 0.05f;
411
      float[] radii = new float[] {radius,radius,radius};
412
      mStickers = new ObjectSticker[STICKERS.length];
413
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
414
      }
415

    
416
    return mStickers[face/NUM_FACES];
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  float returnMultiplier()
422
    {
423
    return 2.0f;
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  private void initializeScrambling()
429
    {
430
    int numLayers = getNumLayers();
431

    
432
    if( mScrambleTable ==null )
433
      {
434
      mScrambleTable = new int[NUM_AXIS][numLayers];
435
      }
436
    if( mNumOccurences ==null )
437
      {
438
      int max=0;
439

    
440
      for (ScrambleState mState : mStates)
441
        {
442
        int tmp = mState.getTotal(-1);
443
        if (max < tmp) max = tmp;
444
        }
445

    
446
      mNumOccurences = new int[max];
447
      }
448

    
449
    for(int i=0; i<NUM_AXIS; i++)
450
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454
// PUBLIC API
455

    
456
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
457
    {
458
    if( curr==0 )
459
      {
460
      mCurrState     = 0;
461
      mIndexExcluded =-1;
462
      initializeScrambling();
463
      }
464

    
465
    int[] info= mStates[mCurrState].getRandom(rnd, mIndexExcluded, mScrambleTable, mNumOccurences);
466

    
467
    scramble[curr][0] = info[0];
468
    scramble[curr][1] = info[1];
469
    scramble[curr][2] = info[2];
470

    
471
    mCurrState     = info[3];
472
    mIndexExcluded = info[0];
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  public Static3D[] getRotationAxis()
478
    {
479
    return ROT_AXIS;
480
    }
481

    
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

    
484
  public int[] getBasicAngle()
485
    {
486
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 2,2,2,2,2,2 };
487
    return mBasicAngle;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public int getObjectName(int numLayers)
493
    {
494
    return R.string.heli3;
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  public int getInventor(int numLayers)
500
    {
501
    return R.string.heli3_inventor;
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public int getComplexity(int numLayers)
507
    {
508
    return 8;
509
    }
510
}
(27-27/41)