Project

General

Profile

Download (17.7 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyHelicopter.java @ cc448c54

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.objectlib.objects;
21
22
import static org.distorted.objectlib.main.Movement.TYPE_SPLIT_EDGE;
23
24
import android.content.res.Resources;
25
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
32
import org.distorted.objectlib.R;
33
import org.distorted.objectlib.main.Movement;
34
import org.distorted.objectlib.main.Movement6;
35
import org.distorted.objectlib.main.ObjectList;
36
import org.distorted.objectlib.main.ObjectShape;
37
import org.distorted.objectlib.main.ObjectSticker;
38
import org.distorted.objectlib.main.ScrambleState;
39
import org.distorted.objectlib.main.Twisty6;
40
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
43
public class TwistyHelicopter extends Twisty6
44
{
45
  // the six rotation axis of a Helicopter. Must be normalized.
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(     0, +SQ2/2, -SQ2/2),
49
           new Static3D(     0, -SQ2/2, -SQ2/2),
50
           new Static3D(+SQ2/2,      0, -SQ2/2),
51
           new Static3D(-SQ2/2,      0, -SQ2/2),
52
           new Static3D(+SQ2/2, -SQ2/2,      0),
53
           new Static3D(-SQ2/2, -SQ2/2,      0)
54
         };
55
56
  private static final int[][][] ENABLED = new int[][][]
57
      {
58
          {{2,5},{2,4},{3,4},{3,5}},
59
          {{2,4},{2,5},{3,5},{3,4}},
60
          {{0,5},{1,5},{1,4},{0,4}},
61
          {{0,4},{1,4},{1,5},{0,5}},
62
          {{1,3},{0,3},{0,2},{1,2}},
63
          {{0,3},{1,3},{1,2},{0,2}},
64
      };
65
66
  private ScrambleState[] mStates;
67
  private int[] mBasicAngle;
68
  private Static4D[] mQuats;
69
  private float[][] mCuts;
70
  private boolean[][] mLayerRotatable;
71
  private float[][] mCenters;
72
  private int[] mQuatIndices;
73
  private int[][] mFaceMap;
74
  private ObjectSticker[] mStickers;
75
  private Movement mMovement;
76
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78
79
  public TwistyHelicopter(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
80
                          DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
81
    {
82
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.HELI, res, scrWidth);
83
    }
84
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87
  protected ScrambleState[] getScrambleStates()
88
    {
89
    if( mStates==null )
90
      {
91
      mStates = new ScrambleState[]
92
        {
93
        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} } ),
94
        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{      2,1,10},{       2,1,12} } ),
95
        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{0,1,9       },{0,1,11       } } ),
96
        new ScrambleState( new int[][] { {           },{           },{0,1,5      },{0,1,7      },{0,1,9       },{0,1,11       } } ),
97
        new ScrambleState( new int[][] { {           },{           },{      2,1,6},{      2,1,8},{      2,1,10},{       2,1,12} } ),
98
        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{0,1,9       },{       2,1,12} } ),
99
        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{      2,1,10},{0,1,11       } } ),
100
        new ScrambleState( new int[][] { {0,1,1      },{0,1,3      },{           },{           },{      2,1,10},{0,1,11       } } ),
101
        new ScrambleState( new int[][] { {      2,1,2},{      2,1,4},{           },{           },{0,1,9       },{       2,1,12} } ),
102
        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{0,1,5      },{      2,1,8},{            },{             } } ),
103
        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{      2,1,6},{0,1,7      },{            },{             } } ),
104
        new ScrambleState( new int[][] { {      2,1,2},{0,1,3      },{      2,1,6},{0,1,7      },{            },{             } } ),
105
        new ScrambleState( new int[][] { {0,1,1      },{      2,1,4},{0,1,5      },{      2,1,8},{            },{             } } ),
106
        };
107
      }
108
109
    return mStates;
110
    }
111
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113
114
  private void initializeQuats()
115
    {
116
    mQuats = new Static4D[]
117
         {
118
         new Static4D( 0.00f,  0.00f,  0.00f,  1.00f ),
119
         new Static4D( 1.00f,  0.00f,  0.00f,  0.00f ),
120
         new Static4D( 0.00f,  1.00f,  0.00f,  0.00f ),
121
         new Static4D( 0.00f,  0.00f,  1.00f,  0.00f ),
122
123
         new Static4D( SQ2/2,  SQ2/2,  0.00f,  0.00f ),
124
         new Static4D( SQ2/2, -SQ2/2,  0.00f,  0.00f ),
125
         new Static4D( SQ2/2,  0.00f,  SQ2/2,  0.00f ),
126
         new Static4D( SQ2/2,  0.00f, -SQ2/2,  0.00f ),
127
         new Static4D( SQ2/2,  0.00f,  0.00f,  SQ2/2 ),
128
         new Static4D( SQ2/2,  0.00f,  0.00f, -SQ2/2 ),
129
         new Static4D( 0.00f,  SQ2/2,  SQ2/2,  0.00f ),
130
         new Static4D( 0.00f,  SQ2/2, -SQ2/2,  0.00f ),
131
         new Static4D( 0.00f,  SQ2/2,  0.00f,  SQ2/2 ),
132
         new Static4D( 0.00f,  SQ2/2,  0.00f, -SQ2/2 ),
133
         new Static4D( 0.00f,  0.00f,  SQ2/2,  SQ2/2 ),
134
         new Static4D( 0.00f,  0.00f,  SQ2/2, -SQ2/2 ),
135
136
         new Static4D( 0.50f,  0.50f,  0.50f,  0.50f ),
137
         new Static4D( 0.50f,  0.50f,  0.50f, -0.50f ),
138
         new Static4D( 0.50f,  0.50f, -0.50f,  0.50f ),
139
         new Static4D( 0.50f,  0.50f, -0.50f, -0.50f ),
140
         new Static4D( 0.50f, -0.50f,  0.50f,  0.50f ),
141
         new Static4D( 0.50f, -0.50f,  0.50f, -0.50f ),
142
         new Static4D( 0.50f, -0.50f, -0.50f,  0.50f ),
143
         new Static4D( 0.50f, -0.50f, -0.50f, -0.50f )
144
         };
145
    }
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  protected int[] getSolvedQuats(int cubit, int numLayers)
150
    {
151
    if( mQuats==null ) initializeQuats();
152
    int status = retCubitSolvedStatus(cubit,numLayers);
153
    return status<0 ? null : buildSolvedQuats(Movement6.FACE_AXIS[status],mQuats);
154
    }
155
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
158
  protected Static4D[] getQuats()
159
    {
160
    if( mQuats==null ) initializeQuats();
161
    return mQuats;
162
    }
163
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165
166
  protected int getSolvedFunctionIndex()
167
    {
168
    return 0;
169
    }
170
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172
173
  protected int getNumStickerTypes(int numLayers)
174
    {
175
    return 1;
176
    }
177
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180
  protected float[][] getCuts(int size)
181
    {
182
    if( mCuts==null )
183
      {
184
      float[] cut = new float[] { -3*SQ2/4, +3*SQ2/4 };
185
      mCuts = new float[][] { cut,cut,cut,cut,cut,cut };
186
      }
187
188
    return mCuts;
189
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
  private void getLayerRotatable(int numLayers)
194
    {
195
    if( mLayerRotatable==null )
196
      {
197
      int numAxis = ROT_AXIS.length;
198
      boolean[] tmp = new boolean[] {true,false,true};
199
      mLayerRotatable = new boolean[numAxis][];
200
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
201
      }
202
    }
203
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206
  protected int getNumCubitFaces()
207
    {
208
    return 4;
209
    }
210
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
213
  protected float[][] getCubitPositions(int size)
214
    {
215
    if( mCenters==null )
216
      {
217
      float DIST_CORNER = 1.50f;
218
      float DIST_CENTER = 1.50f;
219
      float XY_CENTER = DIST_CORNER/3;
220
221
      mCenters = new float[][]
222
         {
223
             {   DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
224
             {   DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
225
             {   DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
226
             {   DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
227
             {  -DIST_CORNER,   DIST_CORNER,   DIST_CORNER },
228
             {  -DIST_CORNER,   DIST_CORNER,  -DIST_CORNER },
229
             {  -DIST_CORNER,  -DIST_CORNER,   DIST_CORNER },
230
             {  -DIST_CORNER,  -DIST_CORNER,  -DIST_CORNER },
231
232
             {   DIST_CENTER,     XY_CENTER,     XY_CENTER },
233
             {   DIST_CENTER,     XY_CENTER,    -XY_CENTER },
234
             {   DIST_CENTER,    -XY_CENTER,     XY_CENTER },
235
             {   DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
236
237
             {  -DIST_CENTER,     XY_CENTER,     XY_CENTER },
238
             {  -DIST_CENTER,     XY_CENTER,    -XY_CENTER },
239
             {  -DIST_CENTER,    -XY_CENTER,     XY_CENTER },
240
             {  -DIST_CENTER,    -XY_CENTER,    -XY_CENTER },
241
242
             {   XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
243
             {   XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
244
             {  -XY_CENTER  ,   DIST_CENTER,     XY_CENTER },
245
             {  -XY_CENTER  ,   DIST_CENTER,    -XY_CENTER },
246
247
             {   XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
248
             {   XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
249
             {  -XY_CENTER  ,  -DIST_CENTER,     XY_CENTER },
250
             {  -XY_CENTER  ,  -DIST_CENTER,    -XY_CENTER },
251
252
             {   XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
253
             {   XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
254
             {  -XY_CENTER  ,     XY_CENTER,   DIST_CENTER },
255
             {  -XY_CENTER  ,    -XY_CENTER,   DIST_CENTER },
256
257
             {   XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
258
             {   XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
259
             {  -XY_CENTER  ,     XY_CENTER,  -DIST_CENTER },
260
             {  -XY_CENTER  ,    -XY_CENTER,  -DIST_CENTER },
261
         };
262
      }
263
264
    return mCenters;
265
    }
266
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268
269
  protected ObjectShape getObjectShape(int cubit, int numLayers)
270
    {
271
    int variant = getCubitVariant(cubit,numLayers);
272
273
    if( variant==0 )
274
      {
275
      double[][] vertices = new double[][]
276
          {
277
            {-1.50f, 0.00f, 0.00f},
278
            { 0.00f,-1.50f, 0.00f},
279
            { 0.00f, 0.00f,-1.50f},
280
            {-0.75f,-0.75f,-0.75f},
281
            { 0.00f, 0.00f, 0.00f}
282
          };
283
284
      int[][] vert_indices = new int[][]
285
          {
286
            {0,1,4},
287
            {2,0,4},
288
            {1,2,4},
289
            {3,1,0},
290
            {3,2,1},
291
            {3,0,2}
292
          };
293
294
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,5} };
295
      int[] bandIndices   = new int[] { 0,0,0,1,1,1 };
296
      float[][] corners   = new float[][] { {0.08f,0.20f} };
297
      int[] cornerIndices = new int[] { 0,0,0,0,0 };
298
      float[][] centers   = new float[][] { {-0.75f, -0.75f, -0.75f} };
299
      int[] centerIndices = new int[] { 0,0,0,-1,0 };
300
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
301
      }
302
    else
303
      {
304
      double[][] vertices = new double[][]
305
          {
306
            { 0.50f, 0.50f, 0.00f },
307
            {-1.00f, 0.50f, 0.00f },
308
            { 0.50f,-1.00f, 0.00f },
309
            {-0.25f,-0.25f,-0.75f },
310
          };
311
312
      int[][] vert_indices = new int[][]
313
          {
314
            { 0,1,2 },
315
            { 2,1,3 },
316
            { 0,1,3 },
317
            { 2,0,3 }
318
          };
319
320
      float[][] bands     = new float[][] { {0.028f,35,0.16f,0.7f,7,3,3}, {0.000f, 0,1.00f,0.0f,3,1,3} };
321
      int[] bandIndices   = new int[] { 0,1,1,1 };
322
      float[][] corners   = new float[][] { {0.06f,0.20f} };
323
      int[] cornerIndices = new int[] { 0,0,0,-1 };
324
      float[][] centers   = new float[][] { {-0.25f, -0.25f, -0.75f} };
325
      int[] centerIndices = new int[] { 0,0,0,-1 };
326
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
327
      }
328
    }
329
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332
  protected Static4D getQuat(int cubit, int numLayers)
333
    {
334
    if( mQuats==null ) initializeQuats();
335
    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 };
336
    return mQuats[mQuatIndices[cubit]];
337
    }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341
  protected int getNumCubitVariants(int numLayers)
342
    {
343
    return 2;
344
    }
345
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347
348
  protected int getCubitVariant(int cubit, int numLayers)
349
    {
350
    return cubit<8 ? 0:1;
351
    }
352
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354
355
  protected int getFaceColor(int cubit, int cubitface, int size)
356
    {
357
    if( mFaceMap==null )
358
      {
359
      mFaceMap = new int[][]
360
         {
361
           { 4,2,0, 6,6,6 },
362
           { 0,2,5, 6,6,6 },
363
           { 4,0,3, 6,6,6 },
364
           { 5,3,0, 6,6,6 },
365
           { 1,2,4, 6,6,6 },
366
           { 5,2,1, 6,6,6 },
367
           { 4,3,1, 6,6,6 },
368
           { 1,3,5, 6,6,6 },
369
370
           { 0 , 6,6,6,6,6 },
371
           { 0 , 6,6,6,6,6 },
372
           { 0 , 6,6,6,6,6 },
373
           { 0 , 6,6,6,6,6 },
374
375
           { 1 , 6,6,6,6,6 },
376
           { 1 , 6,6,6,6,6 },
377
           { 1 , 6,6,6,6,6 },
378
           { 1 , 6,6,6,6,6 },
379
380
           { 2 , 6,6,6,6,6 },
381
           { 2 , 6,6,6,6,6 },
382
           { 2 , 6,6,6,6,6 },
383
           { 2 , 6,6,6,6,6 },
384
385
           { 3 , 6,6,6,6,6 },
386
           { 3 , 6,6,6,6,6 },
387
           { 3 , 6,6,6,6,6 },
388
           { 3 , 6,6,6,6,6 },
389
390
           { 4 , 6,6,6,6,6 },
391
           { 4 , 6,6,6,6,6 },
392
           { 4 , 6,6,6,6,6 },
393
           { 4 , 6,6,6,6,6 },
394
395
           { 5 , 6,6,6,6,6 },
396
           { 5 , 6,6,6,6,6 },
397
           { 5 , 6,6,6,6,6 },
398
           { 5 , 6,6,6,6,6 },
399
         };
400
      }
401
402
    return mFaceMap[cubit][cubitface];
403
    }
404
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406
407
  protected ObjectSticker retSticker(int face)
408
    {
409
    if( mStickers==null )
410
      {
411
      float[][] STICKERS = new float[][] { { -0.5f, 0.25f, 0.25f, -0.5f, 0.25f, 0.25f } };
412
      float radius = 0.03f;
413
      float stroke = 0.05f;
414
      float[] radii = new float[] {radius,radius,radius};
415
      mStickers = new ObjectSticker[STICKERS.length];
416
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
417
      }
418
419
    return mStickers[face/NUM_FACE_COLORS];
420
    }
421
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
// PUBLIC API
424
425
  public Static3D[] getRotationAxis()
426
    {
427
    return ROT_AXIS;
428
    }
429
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431
432
  public Movement getMovement()
433
    {
434
    if( mMovement==null )
435
      {
436
      int numLayers = getNumLayers();
437
      if( mCuts==null ) getCuts(numLayers);
438
      getLayerRotatable(numLayers);
439
      mMovement = new Movement6(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_SPLIT_EDGE,ENABLED);
440
      }
441
    return mMovement;
442
    }
443
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
446
  public int[] getBasicAngle()
447
    {
448
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 2,2,2,2,2,2 };
449
    return mBasicAngle;
450
    }
451
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453
454
  public int getObjectName(int numLayers)
455
    {
456
    return R.string.heli3;
457
    }
458
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
461
  public int getInventor(int numLayers)
462
    {
463
    return R.string.heli3_inventor;
464
    }
465
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
468
  public int getComplexity(int numLayers)
469
    {
470
    return 8;
471
    }
472
}