Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ 588ace55

1 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 1f9772f3 Leszek Koltunski
package org.distorted.objects;
21 e844c116 Leszek Koltunski
22 588ace55 Leszek Koltunski
import static org.distorted.objectlib.Movement.TYPE_NOT_SPLIT;
23 967c1d17 Leszek Koltunski
24 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
25 e844c116 Leszek Koltunski
26 588ace55 Leszek Koltunski
import org.distorted.objectlib.ObjectShape;
27
import org.distorted.objectlib.ObjectSticker;
28
import org.distorted.objectlib.ScrambleState;
29 e844c116 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31 efa8aa48 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
32 e844c116 Leszek Koltunski
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34 6fd4a72c Leszek Koltunski
import org.distorted.main.R;
35 588ace55 Leszek Koltunski
import org.distorted.objectlib.Movement;
36
import org.distorted.objectlib.Movement4;
37
import org.distorted.objectlib.ObjectList;
38
import org.distorted.objectlib.Twisty4;
39 e844c116 Leszek Koltunski
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 efa81f0c Leszek Koltunski
public class TwistyPyraminx extends Twisty4
43 e844c116 Leszek Koltunski
{
44 ad38d800 Leszek Koltunski
  static final Static3D[] ROT_AXIS = new Static3D[]
45 e844c116 Leszek Koltunski
         {
46 ac940e24 Leszek Koltunski
           new Static3D(     0,-SQ3/3,-SQ6/3),
47
           new Static3D(     0,-SQ3/3,+SQ6/3),
48
           new Static3D(+SQ6/3,+SQ3/3,     0),
49
           new Static3D(-SQ6/3,+SQ3/3,     0),
50 ad38d800 Leszek Koltunski
         };
51
52 967c1d17 Leszek Koltunski
  private static final int[][][] ENABLED = new int[][][]
53
      {
54
          {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}}
55
      };
56
57 bbbfb6af Leszek Koltunski
  private ScrambleState[] mStates;
58 48fec01e Leszek Koltunski
  private int[] mBasicAngle;
59
  private Static4D[] mQuats;
60 ef018c1b Leszek Koltunski
  private float[][] mCuts;
61
  private boolean[][] mLayerRotatable;
62 48fec01e Leszek Koltunski
  private ObjectSticker[] mStickers;
63 e9a87113 Leszek Koltunski
  private Movement mMovement;
64 bbbfb6af Leszek Koltunski
65 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
66
67 bdbbb4c5 Leszek Koltunski
  public TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
68
                        DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
69 e844c116 Leszek Koltunski
    {
70 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
71 91792184 Leszek Koltunski
    }
72 bbbfb6af Leszek Koltunski
73 91792184 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
74
75 bdbbb4c5 Leszek Koltunski
  protected ScrambleState[] getScrambleStates()
76 91792184 Leszek Koltunski
    {
77
    if( mStates==null )
78
      {
79
      int numLayers = getNumLayers();
80
      initializeScrambleStates(numLayers);
81
      }
82
83
    return mStates;
84 e844c116 Leszek Koltunski
    }
85
86 48fec01e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
87
88
  private void initializeQuats()
89
    {
90
    mQuats = new Static4D[]
91
         {
92
         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
93
         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
94
         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
95
         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
96
         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
97
         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
98
         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
99
         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
100
         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
101
         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
102
         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
103
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
104
         };
105
    }
106
107 a480ee80 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
108
109 bbbfb6af Leszek Koltunski
  private int[][] generateState(int start, int end)
110 a480ee80 Leszek Koltunski
    {
111 bbbfb6af Leszek Koltunski
    int len = end-start+1;
112
    int[] tmp = new int[6*len];
113
114
    for(int i=0; i<len; i++)
115
      {
116
      tmp[6*i  ] = start;
117
      tmp[6*i+1] = -1;
118
      tmp[6*i+2] = start;
119
      tmp[6*i+3] = start;
120
      tmp[6*i+4] = +1;
121
      tmp[6*i+5] = start;
122
123
      start++;
124
      }
125
126
    return new int[][] {tmp,tmp,tmp,tmp};
127 a480ee80 Leszek Koltunski
    }
128
129 0203be88 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
130
131 bbbfb6af Leszek Koltunski
  private void initializeScrambleStates(int numLayers)
132 0203be88 Leszek Koltunski
    {
133 bbbfb6af Leszek Koltunski
    mStates = new ScrambleState[numLayers];
134 0203be88 Leszek Koltunski
135 bbbfb6af Leszek Koltunski
    for(int i=0; i<numLayers-1; i++)
136 0203be88 Leszek Koltunski
      {
137 bbbfb6af Leszek Koltunski
      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
138 0203be88 Leszek Koltunski
      }
139
140 bbbfb6af Leszek Koltunski
    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
141
    }
142
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
145 bdbbb4c5 Leszek Koltunski
  protected int[] getSolvedQuats(int cubit, int numLayers)
146 bbbfb6af Leszek Koltunski
    {
147 48fec01e Leszek Koltunski
    if( mQuats==null ) initializeQuats();
148 bbbfb6af Leszek Koltunski
    int status = retCubitSolvedStatus(cubit,numLayers);
149 967c1d17 Leszek Koltunski
    return status<0 ? null : buildSolvedQuats(Movement4.FACE_AXIS[status],mQuats);
150 0203be88 Leszek Koltunski
    }
151
152 e844c116 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154 e6cf7283 Leszek Koltunski
  private void addTetrahedralLattice(int size, int index, float[][] pos)
155 49f67f9b Leszek Koltunski
    {
156 ac940e24 Leszek Koltunski
    final float DX = 1.0f;
157
    final float DY = SQ2/2;
158
    final float DZ = 1.0f;
159 49f67f9b Leszek Koltunski
160 ac940e24 Leszek Koltunski
    float startX = 0.0f;
161
    float startY =-DY*(size-1)/2;
162
    float startZ = DZ*(size-1)/2;
163 769409d2 Leszek Koltunski
164 ac940e24 Leszek Koltunski
    for(int layer=0; layer<size; layer++)
165 49f67f9b Leszek Koltunski
      {
166 ac940e24 Leszek Koltunski
      float currX = startX;
167
      float currY = startY;
168
169
      for(int x=0; x<layer+1; x++)
170
        {
171
        float currZ = startZ;
172
173
        for(int z=0; z<size-layer; z++)
174
          {
175 e6cf7283 Leszek Koltunski
          pos[index] = new float[] {currX,currY,currZ};
176 ac940e24 Leszek Koltunski
          index++;
177
          currZ -= DZ;
178
          }
179
180
        currX += DX;
181
        }
182
183
      startX-=DX/2;
184
      startY+=DY;
185
      startZ-=DZ/2;
186 49f67f9b Leszek Koltunski
      }
187
    }
188
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190 ac940e24 Leszek Koltunski
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
191 49f67f9b Leszek Koltunski
192 bdbbb4c5 Leszek Koltunski
  protected float[][] getCubitPositions(int size)
193 e844c116 Leszek Koltunski
    {
194 ac940e24 Leszek Koltunski
    int numOcta = (size-1)*size*(size+1)/6;
195
    int numTetra= size*(size+1)*(size+2)/6;
196 e6cf7283 Leszek Koltunski
    float[][] ret = new float[numOcta+numTetra][];
197 49f67f9b Leszek Koltunski
198 ac940e24 Leszek Koltunski
    addTetrahedralLattice(size-1,      0,ret);
199
    addTetrahedralLattice(size  ,numOcta,ret);
200 49f67f9b Leszek Koltunski
201 ac940e24 Leszek Koltunski
    return ret;
202 e844c116 Leszek Koltunski
    }
203
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206 bdbbb4c5 Leszek Koltunski
  protected Static4D[] getQuats()
207 e844c116 Leszek Koltunski
    {
208 48fec01e Leszek Koltunski
    if( mQuats==null ) initializeQuats();
209
    return mQuats;
210 e844c116 Leszek Koltunski
    }
211
212 169219a7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
213
214 bdbbb4c5 Leszek Koltunski
  protected int getSolvedFunctionIndex()
215 169219a7 Leszek Koltunski
    {
216
    return 0;
217
    }
218
219 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221 bdbbb4c5 Leszek Koltunski
  protected int getNumStickerTypes(int numLayers)
222 eab9d8f8 Leszek Koltunski
    {
223 48fec01e Leszek Koltunski
    return 1;
224 eab9d8f8 Leszek Koltunski
    }
225
226 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
227
228 bdbbb4c5 Leszek Koltunski
  protected float[][] getCuts(int numLayers)
229 7403cdfa Leszek Koltunski
    {
230 ef018c1b Leszek Koltunski
    if( mCuts==null )
231 a97e02b7 Leszek Koltunski
      {
232 ef018c1b Leszek Koltunski
      mCuts = new float[4][numLayers-1];
233
234
      for(int i=0; i<numLayers-1; i++)
235
        {
236 4946b635 Leszek Koltunski
        float cut = (1.0f+i-numLayers/4.0f)*(SQ6/3);
237 ef018c1b Leszek Koltunski
        mCuts[0][i] = cut;
238
        mCuts[1][i] = cut;
239
        mCuts[2][i] = cut;
240
        mCuts[3][i] = cut;
241
        }
242 a97e02b7 Leszek Koltunski
      }
243
244 ef018c1b Leszek Koltunski
    return mCuts;
245
    }
246
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249
  private void getLayerRotatable(int numLayers)
250
    {
251
    if( mLayerRotatable==null )
252
      {
253
      int numAxis = ROT_AXIS.length;
254
      boolean[] tmp = new boolean[numLayers];
255
      for(int i=0; i<numLayers; i++) tmp[i] = true;
256
      mLayerRotatable = new boolean[numAxis][];
257
      for(int i=0; i<numAxis; i++) mLayerRotatable[i] = tmp;
258
      }
259 7403cdfa Leszek Koltunski
    }
260
261 8f53e513 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
262
263 bdbbb4c5 Leszek Koltunski
  protected int getNumCubitFaces()
264 8f53e513 Leszek Koltunski
    {
265 ac940e24 Leszek Koltunski
    return 8;
266 8f53e513 Leszek Koltunski
    }
267
268 31cd7256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
269
270
  private int getNumOctahedrons(int numLayers)
271
    {
272
    return (numLayers-1)*numLayers*(numLayers+1)/6;
273
    }
274
275 f6d06256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
276
277 ac940e24 Leszek Koltunski
  private int faceColor(int cubit, int axis)
278 f6d06256 Leszek Koltunski
    {
279 bdbbb4c5 Leszek Koltunski
    return CUBITS[cubit].getRotRow(axis) == 1 ? axis : NUM_TEXTURES;
280 f6d06256 Leszek Koltunski
    }
281
282 f0fa83ae Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
283
284 bdbbb4c5 Leszek Koltunski
  protected int getFaceColor(int cubit, int cubitface, int size)
285 e844c116 Leszek Koltunski
    {
286 ac940e24 Leszek Koltunski
    if( cubit< (size-1)*size*(size+1)/6 )
287 40ab026e Leszek Koltunski
      {
288 ac940e24 Leszek Koltunski
      switch( cubitface )
289
        {
290
        case 0: return faceColor(cubit,0);
291
        case 2: return faceColor(cubit,1);
292
        case 5: return faceColor(cubit,3);
293
        case 7: return faceColor(cubit,2);
294 abf36986 Leszek Koltunski
        default:return NUM_TEXTURES;
295 ac940e24 Leszek Koltunski
        }
296 40ab026e Leszek Koltunski
      }
297 ac940e24 Leszek Koltunski
    else
298 89a11f7b Leszek Koltunski
      {
299 abf36986 Leszek Koltunski
      return cubitface<NUM_TEXTURES ? faceColor(cubit,cubitface) : NUM_TEXTURES;
300 89a11f7b Leszek Koltunski
      }
301 e844c116 Leszek Koltunski
    }
302
303 045d8cbd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
304
305 bdbbb4c5 Leszek Koltunski
  protected ObjectShape getObjectShape(int cubit, int numLayers)
306 045d8cbd Leszek Koltunski
    {
307
    int variant = getCubitVariant(cubit,numLayers);
308
309
    if( variant==0 )
310
      {
311 48fec01e Leszek Koltunski
      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} };
312
      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} };
313 045d8cbd Leszek Koltunski
      int N = numLayers==3? 6 : 5;
314
      int E = numLayers==3? 2 : 1;
315
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
316
      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
317
      float[][] corners   = new float[][] { {0.04f,0.20f} };
318
      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
319
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
320
      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
321 48fec01e Leszek Koltunski
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
322 045d8cbd Leszek Koltunski
      }
323
    else
324
      {
325 48fec01e Leszek Koltunski
      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} };
326
      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
327 045d8cbd Leszek Koltunski
      int N = numLayers==3? 6 : 5;
328
      int E = numLayers==3? 2 : 1;
329
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
330
      int[] bandIndices   = new int[] { 0,0,0,0 };
331
      float[][] corners   = new float[][] { {0.06f,0.15f} };
332
      int[] cornerIndices = new int[] { 0,0,0,0 };
333
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
334
      int[] centerIndices = new int[] { 0,0,0,0 };
335 48fec01e Leszek Koltunski
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
336 045d8cbd Leszek Koltunski
      }
337
    }
338
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340
341 bdbbb4c5 Leszek Koltunski
  protected Static4D getQuat(int cubit, int numLayers)
342 045d8cbd Leszek Koltunski
    {
343 48fec01e Leszek Koltunski
    if( mQuats==null ) initializeQuats();
344
    return mQuats[0];
345 045d8cbd Leszek Koltunski
    }
346
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
349 bdbbb4c5 Leszek Koltunski
  protected int getNumCubitVariants(int numLayers)
350 045d8cbd Leszek Koltunski
    {
351
    return 2;
352
    }
353
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
356 bdbbb4c5 Leszek Koltunski
  protected int getCubitVariant(int cubit, int numLayers)
357 045d8cbd Leszek Koltunski
    {
358
    return cubit<getNumOctahedrons(numLayers) ? 0:1;
359
    }
360
361 9c06394a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
362 76c2bd07 Leszek Koltunski
363 bdbbb4c5 Leszek Koltunski
  protected ObjectSticker retSticker(int face)
364 9c06394a Leszek Koltunski
    {
365 48fec01e Leszek Koltunski
    if( mStickers==null )
366
      {
367
      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
368
      final float stroke = 0.08f;
369
      final float radius = 0.06f;
370
      final float[] radii= {radius,radius,radius};
371
      mStickers = new ObjectSticker[STICKERS.length];
372
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
373
      }
374
375 abf36986 Leszek Koltunski
    return mStickers[face/NUM_FACE_COLORS];
376 7289fd6c Leszek Koltunski
    }
377
378 7c969a6d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
379 91792184 Leszek Koltunski
// public API
380 bbbfb6af Leszek Koltunski
381
  public Static3D[] getRotationAxis()
382
    {
383
    return ROT_AXIS;
384
    }
385
386 e9a87113 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
387
388
  public Movement getMovement()
389
    {
390 ef018c1b Leszek Koltunski
    if( mMovement==null )
391
      {
392
      int numLayers = getNumLayers();
393
      if( mCuts==null ) getCuts(numLayers);
394
      getLayerRotatable(numLayers);
395 7ee89540 Leszek Koltunski
      mMovement = new Movement4(ROT_AXIS,mCuts,mLayerRotatable,numLayers,TYPE_NOT_SPLIT,ENABLED);
396 ef018c1b Leszek Koltunski
      }
397 e9a87113 Leszek Koltunski
    return mMovement;
398
    }
399
400 bbbfb6af Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402
  public int[] getBasicAngle()
403
    {
404 48fec01e Leszek Koltunski
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
405
    return mBasicAngle;
406 e46e17fb Leszek Koltunski
    }
407 f0336037 Leszek Koltunski
408 6fd4a72c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
409
410
  public int getObjectName(int numLayers)
411
    {
412
    switch(numLayers)
413
      {
414
      case 3: return R.string.pyra3;
415
      case 4: return R.string.pyra4;
416
      case 5: return R.string.pyra5;
417
      }
418
    return R.string.pyra3;
419
    }
420
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
423
  public int getInventor(int numLayers)
424
    {
425
    switch(numLayers)
426
      {
427
      case 3: return R.string.pyra3_inventor;
428
      case 4: return R.string.pyra4_inventor;
429
      case 5: return R.string.pyra5_inventor;
430
      }
431
    return R.string.pyra3_inventor;
432
    }
433
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435
436
  public int getComplexity(int numLayers)
437
    {
438
    switch(numLayers)
439
      {
440
      case 3: return 4;
441
      case 4: return 6;
442
      case 5: return 8;
443
      }
444
    return 4;
445
    }
446 e844c116 Leszek Koltunski
}