Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyHelicopter.java @ e1dc3366

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
  private static final int FACES_PER_CUBIT =6;
41

    
42
  // the six rotation axis of a Helicopter. Must be normalized.
43
  static final Static3D[] ROT_AXIS = new Static3D[]
44
         {
45
           new Static3D(     0, +SQ2/2, -SQ2/2),
46
           new Static3D(     0, -SQ2/2, -SQ2/2),
47
           new Static3D(+SQ2/2,      0, -SQ2/2),
48
           new Static3D(-SQ2/2,      0, -SQ2/2),
49
           new Static3D(+SQ2/2, -SQ2/2,      0),
50
           new Static3D(-SQ2/2, -SQ2/2,      0)
51
         };
52

    
53
  private static final int[] BASIC_ANGLE = new int[] { 2,2,2,2,2,2 };
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 HELICOPTER (same as the Cube!)
63
  private static final Static4D[] QUATS = new Static4D[]
64
         {
65
           new Static4D( 0.00f,  0.00f,  0.00f,  1.00f ),
66
           new Static4D( 1.00f,  0.00f,  0.00f,  0.00f ),
67
           new Static4D( 0.00f,  1.00f,  0.00f,  0.00f ),
68
           new Static4D( 0.00f,  0.00f,  1.00f,  0.00f ),
69

    
70
           new Static4D( SQ2/2,  SQ2/2,  0.00f,  0.00f ),
71
           new Static4D( SQ2/2, -SQ2/2,  0.00f,  0.00f ),
72
           new Static4D( SQ2/2,  0.00f,  SQ2/2,  0.00f ),
73
           new Static4D( SQ2/2,  0.00f, -SQ2/2,  0.00f ),
74
           new Static4D( SQ2/2,  0.00f,  0.00f,  SQ2/2 ),
75
           new Static4D( SQ2/2,  0.00f,  0.00f, -SQ2/2 ),
76
           new Static4D( 0.00f,  SQ2/2,  SQ2/2,  0.00f ),
77
           new Static4D( 0.00f,  SQ2/2, -SQ2/2,  0.00f ),
78
           new Static4D( 0.00f,  SQ2/2,  0.00f,  SQ2/2 ),
79
           new Static4D( 0.00f,  SQ2/2,  0.00f, -SQ2/2 ),
80
           new Static4D( 0.00f,  0.00f,  SQ2/2,  SQ2/2 ),
81
           new Static4D( 0.00f,  0.00f,  SQ2/2, -SQ2/2 ),
82

    
83
           new Static4D( 0.50f,  0.50f,  0.50f,  0.50f ),
84
           new Static4D( 0.50f,  0.50f,  0.50f, -0.50f ),
85
           new Static4D( 0.50f,  0.50f, -0.50f,  0.50f ),
86
           new Static4D( 0.50f,  0.50f, -0.50f, -0.50f ),
87
           new Static4D( 0.50f, -0.50f,  0.50f,  0.50f ),
88
           new Static4D( 0.50f, -0.50f,  0.50f, -0.50f ),
89
           new Static4D( 0.50f, -0.50f, -0.50f,  0.50f ),
90
           new Static4D( 0.50f, -0.50f, -0.50f, -0.50f )
91
         };
92

    
93
  private static final float DIST_CORNER = 0.50f;
94
  private static final float DIST_CENTER = 0.50f;
95
  private static final float XY_CENTER   = DIST_CORNER/3;
96

    
97
  // centers of the 8 corners + 6*4 face triangles ( i.e. of the all 32 cubits)
98
  private static final float[][] CENTERS = new float[][]
99
         {
100
             {   DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
101
             {   DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
102
             {   DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
103
             {   DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
104
             {  -DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
105
             {  -DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
106
             {  -DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
107
             {  -DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
108

    
109
             {   DIST_CENTER,     XY_CENTER,     XY_CENTER },
110
             {   DIST_CENTER,     XY_CENTER,    -XY_CENTER },
111
             {   DIST_CENTER,    -XY_CENTER,     XY_CENTER },
112
             {   DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
113

    
114
             {  -DIST_CENTER,     XY_CENTER,     XY_CENTER },
115
             {  -DIST_CENTER,     XY_CENTER,    -XY_CENTER },
116
             {  -DIST_CENTER,    -XY_CENTER,     XY_CENTER },
117
             {  -DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
118

    
119
             {   XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
120
             {   XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
121
             {  -XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
122
             {  -XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
123

    
124
             {   XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
125
             {   XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
126
             {  -XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
127
             {  -XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
128

    
129
             {   XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
130
             {   XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
131
             {  -XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
132
             {  -XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
133

    
134
             {   XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
135
             {   XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
136
             {  -XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
137
             {  -XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
138
         };
139

    
140
  // Colors of the faces of cubits. Each cubit has 6 faces
141
  private static final int[][] mFaceMap = new int[][]
142
         {
143
           { 4,2,0, 6,6,6 },
144
           { 0,2,5, 6,6,6 },
145
           { 4,0,3, 6,6,6 },
146
           { 5,3,0, 6,6,6 },
147
           { 1,2,4, 6,6,6 },
148
           { 5,2,1, 6,6,6 },
149
           { 4,3,1, 6,6,6 },
150
           { 1,3,5, 6,6,6 },
151

    
152
           { 0 , 6,6,6,6,6 },
153
           { 0 , 6,6,6,6,6 },
154
           { 0 , 6,6,6,6,6 },
155
           { 0 , 6,6,6,6,6 },
156

    
157
           { 1 , 6,6,6,6,6 },
158
           { 1 , 6,6,6,6,6 },
159
           { 1 , 6,6,6,6,6 },
160
           { 1 , 6,6,6,6,6 },
161

    
162
           { 2 , 6,6,6,6,6 },
163
           { 2 , 6,6,6,6,6 },
164
           { 2 , 6,6,6,6,6 },
165
           { 2 , 6,6,6,6,6 },
166

    
167
           { 3 , 6,6,6,6,6 },
168
           { 3 , 6,6,6,6,6 },
169
           { 3 , 6,6,6,6,6 },
170
           { 3 , 6,6,6,6,6 },
171

    
172
           { 4 , 6,6,6,6,6 },
173
           { 4 , 6,6,6,6,6 },
174
           { 4 , 6,6,6,6,6 },
175
           { 4 , 6,6,6,6,6 },
176

    
177
           { 5 , 6,6,6,6,6 },
178
           { 5 , 6,6,6,6,6 },
179
           { 5 , 6,6,6,6,6 },
180
           { 5 , 6,6,6,6,6 },
181
         };
182

    
183
  private static final int[] QUAT_INDICES =
184
      { 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 };
185

    
186
  private static final double[][] VERTICES_CORNER = new double[][]
187
          {
188
            {-0.50f, 0.00f, 0.00f},
189
            { 0.00f,-0.50f, 0.00f},
190
            { 0.00f, 0.00f,-0.50f},
191
            {-0.25f,-0.25f,-0.25f},
192
            { 0.00f, 0.00f, 0.00f}
193
          };
194

    
195
  private static final int[][] VERT_INDEXES_CORNER = new int[][]
196
          {
197
            {0,1,4},
198
            {2,0,4},
199
            {1,2,4},
200
            {3,1,0},
201
            {3,2,1},
202
            {3,0,2}
203
          };
204

    
205
  private static final float E = 0.1666666f;
206

    
207
  private static final double[][] VERTICES_FACE = new double[][]
208
          {
209
            { 0.00f +E, 0.00f +E, 0.00f },
210
            {-0.50f +E, 0.00f +E, 0.00f },
211
            { 0.00f +E,-0.50f +E, 0.00f },
212
            {-0.25f +E,-0.25f +E,-0.25f },
213
          };
214

    
215
  private static final int[][] VERT_INDEXES_FACE = new int[][]
216
          {
217
            { 0,1,2 },
218
            { 2,1,3 },
219
            { 0,1,3 },
220
            { 2,0,3 }
221
          };
222

    
223
  private static final float[][] STICKERS = new float[][]
224
          {
225
            { -0.5f, 0.25f, 0.25f, -0.5f, 0.25f, 0.25f }
226
          };
227

    
228
  private static final ObjectSticker[] mStickers;
229

    
230
  static
231
    {
232
    float radius = 0.03f;
233
    float stroke = 0.05f;
234
    float[] radii = new float[] {radius,radius,radius};
235
    mStickers = new ObjectSticker[STICKERS.length];
236
    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
237
    }
238

    
239
  private int mCurrState;
240
  private int mIndexExcluded;
241
  private final ScrambleState[] mStates;
242
  private int[][] mScrambleTable;
243
  private int[] mNumOccurences;
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  TwistyHelicopter(int size, Static4D quat, DistortedTexture texture,
248
                   MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
249
    {
250
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
251

    
252
    mStates = new ScrambleState[]
253
      {
254
      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} } ),
255
      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
256
      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
257
      new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
258
      new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
259
      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
260
      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
261
      new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
262
      new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
263
      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
264
      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
265
      new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
266
      new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
267
      };
268
    }
269

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

    
272
  int[] getSolvedQuats(int cubit, int numLayers)
273
    {
274
    int status = retCubitSolvedStatus(cubit,numLayers);
275
    return status<0 ? null : buildSolvedQuats(MovementHelicopter.FACE_AXIS[status],QUATS);
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  float getScreenRatio()
281
    {
282
    return 1.6f;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  Static4D[] getQuats()
288
    {
289
    return QUATS;
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  boolean shouldResetTextureMaps()
295
    {
296
    return false;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  int getNumFaces()
302
    {
303
    return FACE_COLORS.length;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  int getSolvedFunctionIndex()
309
    {
310
    return 0;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  int getNumStickerTypes(int numLayers)
316
    {
317
    return STICKERS.length;
318
    }
319

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

    
322
  float[][] getCuts(int size)
323
    {
324
    float[] cut = new float[] { -SQ2/4, +SQ2/4 };
325
    return new float[][] { cut,cut,cut,cut,cut,cut };
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  int getNumCubitFaces()
331
    {
332
    return FACES_PER_CUBIT;
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  float[][] getCubitPositions(int size)
338
    {
339
    return CENTERS;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
  ObjectShape getObjectShape(int cubit, int numLayers)
345
    {
346
    int variant = getCubitVariant(cubit,numLayers);
347

    
348
    if( variant==0 )
349
      {
350
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,5} };
351
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
352
      float[][] corners   = new float[][] { {0.08f,0.15f}, {0.08f,0.20f} };
353
      int[] cornerIndices = new int[] { 1,1,1,0,0 };
354
      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.25f} };
355
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
356
      return new ObjectShape(VERTICES_CORNER,VERT_INDEXES_CORNER,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
357
      }
358
    else
359
      {
360
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,3} };
361
      int[] bandIndices   = new int[] { 0,1,1,1 };
362
      float[][] corners   = new float[][] { {0.06f,0.15f}, {0.06f,0.20f} };
363
      int[] cornerIndices = new int[] { 0,1,1,-1 };
364
      float[][] centers   = new float[][] { {-1.0f/12, -1.0f/12, -1.0f/4} };
365
      int[] centerIndices = new int[] { 0,0,0,-1 };
366
      return new ObjectShape(VERTICES_FACE,VERT_INDEXES_FACE,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
367
      }
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  Static4D getQuat(int cubit, int numLayers)
373
    {
374
    return QUATS[QUAT_INDICES[cubit]];
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  int getNumCubitVariants(int numLayers)
380
    {
381
    return 2;
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  int getCubitVariant(int cubit, int numLayers)
387
    {
388
    return cubit<8 ? 0:1;
389
    }
390

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

    
393
  int getFaceColor(int cubit, int cubitface, int size)
394
    {
395
    return mFaceMap[cubit][cubitface];
396
    }
397

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

    
400
  int getColor(int face)
401
    {
402
    return FACE_COLORS[face];
403
    }
404

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

    
407
  ObjectSticker retSticker(int face)
408
    {
409
    return mStickers[face/NUM_FACES];
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  float returnMultiplier()
415
    {
416
    return 2.0f;
417
    }
418

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

    
421
  private void initializeScrambling()
422
    {
423
    int numLayers = getNumLayers();
424

    
425
    if( mScrambleTable ==null )
426
      {
427
      mScrambleTable = new int[NUM_AXIS][numLayers];
428
      }
429
    if( mNumOccurences ==null )
430
      {
431
      int max=0;
432

    
433
      for (ScrambleState mState : mStates)
434
        {
435
        int tmp = mState.getTotal(-1);
436
        if (max < tmp) max = tmp;
437
        }
438

    
439
      mNumOccurences = new int[max];
440
      }
441

    
442
    for(int i=0; i<NUM_AXIS; i++)
443
      for(int j=0; j<numLayers; j++) mScrambleTable[i][j] = 0;
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447
// PUBLIC API
448

    
449
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int totalScrambles)
450
    {
451
    if( curr==0 )
452
      {
453
      mCurrState     = 0;
454
      mIndexExcluded =-1;
455
      initializeScrambling();
456
      }
457

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

    
460
    scramble[curr][0] = info[0];
461
    scramble[curr][1] = info[1];
462
    scramble[curr][2] = info[2];
463

    
464
    mCurrState     = info[3];
465
    mIndexExcluded = info[0];
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

    
470
  public Static3D[] getRotationAxis()
471
    {
472
    return ROT_AXIS;
473
    }
474

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

    
477
  public int[] getBasicAngle()
478
    {
479
    return BASIC_ANGLE;
480
    }
481

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

    
484
  public int getObjectName(int numLayers)
485
    {
486
    return R.string.heli3;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  public int getInventor(int numLayers)
492
    {
493
    return R.string.heli3_inventor;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public int getComplexity(int numLayers)
499
    {
500
    return 8;
501
    }
502
}
(27-27/41)