Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyPyraminx.java @ 7b832206

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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.MOVEMENT_TETRAHEDRON;
23
import static org.distorted.objectlib.main.Movement.TYPE_NOT_SPLIT;
24

    
25
import android.content.res.Resources;
26

    
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

    
33
import org.distorted.objectlib.R;
34
import org.distorted.objectlib.main.Movement4;
35
import org.distorted.objectlib.main.ObjectControl;
36
import org.distorted.objectlib.main.ObjectType;
37
import org.distorted.objectlib.helpers.ObjectShape;
38
import org.distorted.objectlib.helpers.ObjectSticker;
39
import org.distorted.objectlib.helpers.ScrambleState;
40
import org.distorted.objectlib.main.Twisty4;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class TwistyPyraminx extends Twisty4
45
{
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
           new Static3D(     0,-SQ3/3,-SQ6/3),
49
           new Static3D(     0,-SQ3/3,+SQ6/3),
50
           new Static3D(+SQ6/3,+SQ3/3,     0),
51
           new Static3D(-SQ6/3,+SQ3/3,     0),
52
         };
53

    
54
  private ScrambleState[] mStates;
55
  private int[] mBasicAngle;
56
  private Static4D[] mQuats;
57
  private float[][] mCuts;
58
  private ObjectSticker[] mStickers;
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  public TwistyPyraminx(int[] numL, Static4D quat, Static3D move, DistortedTexture texture,
63
                        MeshSquare mesh, DistortedEffects effects, Resources res, int surfaceW, int surfaceH)
64
    {
65
    super(numL, numL[0], quat, move, texture, mesh, effects, res, surfaceW, surfaceH);
66
    }
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  public ScrambleState[] getScrambleStates()
71
    {
72
    if( mStates==null )
73
      {
74
      int[] numLayers = getNumLayers();
75
      initializeScrambleStates(numLayers[0]);
76
      }
77

    
78
    return mStates;
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  protected int getResource(int[] numLayers)
84
    {
85
    switch(numLayers[0])
86
      {
87
      case 3: return R.raw.pyra3;
88
      case 4: return R.raw.pyra4;
89
      case 5: return R.raw.pyra5;
90
      }
91

    
92
    return 0;
93
    }
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  private void initializeQuats()
98
    {
99
    mQuats = new Static4D[]
100
         {
101
         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
102
         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
103
         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
104
         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
105
         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
106
         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
107
         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
108
         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
109
         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
110
         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
111
         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
112
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
113
         };
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  private int[][] generateState(int start, int end)
119
    {
120
    int len = end-start+1;
121
    int[] tmp = new int[6*len];
122

    
123
    for(int i=0; i<len; i++)
124
      {
125
      tmp[6*i  ] = start;
126
      tmp[6*i+1] = -1;
127
      tmp[6*i+2] = start;
128
      tmp[6*i+3] = start;
129
      tmp[6*i+4] = +1;
130
      tmp[6*i+5] = start;
131

    
132
      start++;
133
      }
134

    
135
    return new int[][] {tmp,tmp,tmp,tmp};
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  private void initializeScrambleStates(int numLayers)
141
    {
142
    mStates = new ScrambleState[numLayers];
143

    
144
    for(int i=0; i<numLayers-1; i++)
145
      {
146
      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
147
      }
148

    
149
    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
154
  public int[] getSolvedQuats(int cubit, int[] numLayers)
155
    {
156
    if( mQuats==null ) initializeQuats();
157
    int status = retCubitSolvedStatus(cubit,numLayers);
158
    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  private void addTetrahedralLattice(int size, int index, float[][] pos)
164
    {
165
    final float DX = 1.0f;
166
    final float DY = SQ2/2;
167
    final float DZ = 1.0f;
168

    
169
    float startX = 0.0f;
170
    float startY =-DY*(size-1)/2;
171
    float startZ = DZ*(size-1)/2;
172

    
173
    for(int layer=0; layer<size; layer++)
174
      {
175
      float currX = startX;
176
      float currY = startY;
177

    
178
      for(int x=0; x<layer+1; x++)
179
        {
180
        float currZ = startZ;
181

    
182
        for(int z=0; z<size-layer; z++)
183
          {
184
          pos[index] = new float[] {currX,currY,currZ};
185
          index++;
186
          currZ -= DZ;
187
          }
188

    
189
        currX += DX;
190
        }
191

    
192
      startX-=DX/2;
193
      startY+=DY;
194
      startZ-=DZ/2;
195
      }
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
200

    
201
  public float[][] getCubitPositions(int[] numLayers)
202
    {
203
    int numL = numLayers[0];
204
    int numOcta = (numL-1)*numL*(numL+1)/6;
205
    int numTetra= numL*(numL+1)*(numL+2)/6;
206
    float[][] ret = new float[numOcta+numTetra][];
207

    
208
    addTetrahedralLattice(numL-1,      0,ret);
209
    addTetrahedralLattice(numL  ,numOcta,ret);
210

    
211
    return ret;
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  public Static4D[] getQuats()
217
    {
218
    if( mQuats==null ) initializeQuats();
219
    return mQuats;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  public int getSolvedFunctionIndex()
225
    {
226
    return 0;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  public int getNumStickerTypes(int[] numLayers)
232
    {
233
    return 1;
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  public float[][] getCuts(int[] numLayers)
239
    {
240
    if( mCuts==null )
241
      {
242
      int numL = numLayers[0];
243
      mCuts = new float[4][numL-1];
244

    
245
      for(int i=0; i<numL-1; i++)
246
        {
247
        float cut = (1.0f+i-numL/4.0f)*(SQ6/3);
248
        mCuts[0][i] = cut;
249
        mCuts[1][i] = cut;
250
        mCuts[2][i] = cut;
251
        mCuts[3][i] = cut;
252
        }
253
      }
254

    
255
    return mCuts;
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  public boolean[][] getLayerRotatable(int[] numLayers)
261
    {
262
    int numAxis = ROT_AXIS.length;
263
    boolean[][] layerRotatable = new boolean[numAxis][];
264

    
265
    for(int i=0; i<numAxis; i++)
266
      {
267
      layerRotatable[i] = new boolean[numLayers[i]];
268
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
269
      }
270

    
271
    return layerRotatable;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  public int getMovementType()
277
    {
278
    return MOVEMENT_TETRAHEDRON;
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
  public int getMovementSplit()
284
    {
285
    return TYPE_NOT_SPLIT;
286
    }
287

    
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

    
290
  public int[][][] getEnabled()
291
    {
292
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
293
    }
294

    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296

    
297
  public float[] getDist3D(int[] numLayers)
298
    {
299
    return null;
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  protected int getNumCubitFaces()
305
    {
306
    return 8;
307
    }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
  private int getNumOctahedrons(int numLayers)
312
    {
313
    return (numLayers-1)*numLayers*(numLayers+1)/6;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  private int faceColor(int cubit, int axis)
319
    {
320
    return CUBITS[cubit].getRotRow(axis) == 1 ? axis : NUM_TEXTURES;
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  protected int getFaceColor(int cubit, int cubitface, int[] numLayers)
326
    {
327
    int numL = numLayers[0];
328

    
329
    if( cubit< (numL-1)*numL*(numL+1)/6 )
330
      {
331
      switch( cubitface )
332
        {
333
        case 0: return faceColor(cubit,0);
334
        case 2: return faceColor(cubit,1);
335
        case 5: return faceColor(cubit,3);
336
        case 7: return faceColor(cubit,2);
337
        default:return NUM_TEXTURES;
338
        }
339
      }
340
    else
341
      {
342
      return cubitface<NUM_TEXTURES ? faceColor(cubit,cubitface) : NUM_TEXTURES;
343
      }
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  public ObjectShape getObjectShape(int variant)
349
    {
350
    int numL = getNumLayers()[0];
351

    
352
    if( variant==0 )
353
      {
354
      double[][] vertices = new double[][] { { 0.5,0.0,0.5},{ 0.5,0.0,-0.5},{-0.5,0.0,-0.5},{-0.5,0.0,0.5},{ 0.0,SQ2/2,0.0},{ 0.0,-SQ2/2,0.0} };
355
      int[][] vert_indices = new int[][] { {3,0,4},{0,1,4},{1,2,4},{2,3,4},{5,0,3},{5,1,0},{5,2,1},{5,3,2} };
356
      int N = numL==3? 6 : 5;
357
      int E = numL==3? 2 : 1;
358
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
359
      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
360
      float[][] corners   = new float[][] { {0.04f,0.20f} };
361
      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
362
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
363
      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
364
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
365
      }
366
    else
367
      {
368
      double[][] vertices = new double[][] { {-0.5, SQ2/4, 0.0},{ 0.5, SQ2/4, 0.0},{ 0.0,-SQ2/4, 0.5},{ 0.0,-SQ2/4,-0.5} };
369
      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
370
      int N = numL==3? 6 : 5;
371
      int E = numL==3? 2 : 1;
372
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
373
      int[] bandIndices   = new int[] { 0,0,0,0 };
374
      float[][] corners   = new float[][] { {0.06f,0.15f} };
375
      int[] cornerIndices = new int[] { 0,0,0,0 };
376
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
377
      int[] centerIndices = new int[] { 0,0,0,0 };
378
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
379
      }
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public Static4D getQuat(int cubit, int[] numLayers)
385
    {
386
    if( mQuats==null ) initializeQuats();
387
    return mQuats[0];
388
    }
389

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

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

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

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

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

    
406
  public ObjectSticker retSticker(int sticker)
407
    {
408
    if( mStickers==null )
409
      {
410
      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
411
      final float radius = 0.06f;
412
      final float[] radii= {radius,radius,radius};
413
      mStickers = new ObjectSticker[STICKERS.length];
414

    
415
      float stroke = 0.08f;
416

    
417
      if( ObjectControl.isInIconMode() )
418
        {
419
        int[] numLayers = getNumLayers();
420

    
421
        switch(numLayers[0])
422
          {
423
          case 2: stroke*=1.0f; break;
424
          case 3: stroke*=1.4f; break;
425
          case 4: stroke*=1.7f; break;
426
          default:stroke*=1.9f; break;
427
          }
428
        }
429

    
430
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
431
      }
432

    
433
    return mStickers[sticker];
434
    }
435

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

    
438
  protected int getStickerIndex(int face)
439
    {
440
    return face/NUM_FACE_COLORS;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444
// public API
445

    
446
  public Static3D[] getRotationAxis()
447
    {
448
    return ROT_AXIS;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public int[] getBasicAngle()
454
    {
455
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
456
    return mBasicAngle;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public ObjectType intGetObjectType(int[] numLayers)
462
    {
463
    switch(numLayers[0])
464
      {
465
      case 3: return ObjectType.PYRA_3;
466
      case 4: return ObjectType.PYRA_4;
467
      case 5: return ObjectType.PYRA_5;
468
      }
469

    
470
    return ObjectType.PYRA_3;
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public int getObjectName(int[] numLayers)
476
    {
477
    switch(numLayers[0])
478
      {
479
      case 3: return R.string.pyra3;
480
      case 4: return R.string.pyra4;
481
      case 5: return R.string.pyra5;
482
      }
483
    return R.string.pyra3;
484
    }
485

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

    
488
  public int getInventor(int[] numLayers)
489
    {
490
    switch(numLayers[0])
491
      {
492
      case 3: return R.string.pyra3_inventor;
493
      case 4: return R.string.pyra4_inventor;
494
      case 5: return R.string.pyra5_inventor;
495
      }
496
    return R.string.pyra3_inventor;
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
  public int getYearOfInvention(int[] numLayers)
502
    {
503
    switch(numLayers[0])
504
      {
505
      case 3: return 1970;
506
      case 4: return 2002;
507
      case 5: return 2011;
508
      }
509
    return 1970;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

    
514
  public int getComplexity(int[] numLayers)
515
    {
516
    switch(numLayers[0])
517
      {
518
      case 3: return 4;
519
      case 4: return 6;
520
      case 5: return 8;
521
      }
522
    return 4;
523
    }
524
}
(18-18/25)