Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ 5da517d3

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.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
///////////////////////////////////////////////////////////////////////////////////////////////////
35

    
36
public class TwistyPyraminx extends TwistyObject
37
{
38
  static final Static3D[] ROT_AXIS = new Static3D[]
39
         {
40
           new Static3D(     0,-SQ3/3,-SQ6/3),
41
           new Static3D(     0,-SQ3/3,+SQ6/3),
42
           new Static3D(+SQ6/3,+SQ3/3,     0),
43
           new Static3D(-SQ6/3,+SQ3/3,     0),
44
         };
45

    
46
  private static final int[] FACE_COLORS = new int[]
47
         {
48
           COLOR_GREEN , COLOR_YELLOW,
49
           COLOR_BLUE  , COLOR_RED
50
         };
51

    
52
  private ScrambleState[] mStates;
53
  private int[] mBasicAngle;
54
  private Static4D[] mQuats;
55
  private ObjectSticker[] mStickers;
56

    
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

    
59
  TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
60
                 DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
61
    {
62
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.PYRA, res, scrWidth);
63
    }
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  ScrambleState[] getScrambleStates()
68
    {
69
    if( mStates==null )
70
      {
71
      int numLayers = getNumLayers();
72
      initializeScrambleStates(numLayers);
73
      }
74

    
75
    return mStates;
76
    }
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

    
80
  private void initializeQuats()
81
    {
82
    mQuats = new Static4D[]
83
         {
84
         new Static4D(  0.0f,   0.0f,   0.0f,  1.0f),
85
         new Static4D(  0.0f,   1.0f,   0.0f,  0.0f),
86
         new Static4D( SQ2/2,   0.5f,   0.0f,  0.5f),
87
         new Static4D(-SQ2/2,   0.5f,   0.0f,  0.5f),
88
         new Static4D(  0.0f,  -0.5f, -SQ2/2,  0.5f),
89
         new Static4D(  0.0f,  -0.5f,  SQ2/2,  0.5f),
90
         new Static4D( SQ2/2,   0.5f,   0.0f, -0.5f),
91
         new Static4D(-SQ2/2,   0.5f,   0.0f, -0.5f),
92
         new Static4D(  0.0f,  -0.5f, -SQ2/2, -0.5f),
93
         new Static4D(  0.0f,  -0.5f,  SQ2/2, -0.5f),
94
         new Static4D( SQ2/2,   0.0f,  SQ2/2,  0.0f),
95
         new Static4D(-SQ2/2,   0.0f,  SQ2/2,  0.0f)
96
         };
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private int[][] generateState(int start, int end)
102
    {
103
    int len = end-start+1;
104
    int[] tmp = new int[6*len];
105

    
106
    for(int i=0; i<len; i++)
107
      {
108
      tmp[6*i  ] = start;
109
      tmp[6*i+1] = -1;
110
      tmp[6*i+2] = start;
111
      tmp[6*i+3] = start;
112
      tmp[6*i+4] = +1;
113
      tmp[6*i+5] = start;
114

    
115
      start++;
116
      }
117

    
118
    return new int[][] {tmp,tmp,tmp,tmp};
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  private void initializeScrambleStates(int numLayers)
124
    {
125
    mStates = new ScrambleState[numLayers];
126

    
127
    for(int i=0; i<numLayers-1; i++)
128
      {
129
      mStates[i] = new ScrambleState( generateState(0,numLayers-1-i) );
130
      }
131

    
132
    mStates[numLayers-1] = new ScrambleState( generateState(1,numLayers-2) );
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  int[] getSolvedQuats(int cubit, int numLayers)
138
    {
139
    if( mQuats==null ) initializeQuats();
140
    int status = retCubitSolvedStatus(cubit,numLayers);
141
    return status<0 ? null : buildSolvedQuats(MovementPyraminx.FACE_AXIS[status],mQuats);
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  private void addTetrahedralLattice(int size, int index, float[][] pos)
147
    {
148
    final float DX = 1.0f;
149
    final float DY = SQ2/2;
150
    final float DZ = 1.0f;
151

    
152
    float startX = 0.0f;
153
    float startY =-DY*(size-1)/2;
154
    float startZ = DZ*(size-1)/2;
155

    
156
    for(int layer=0; layer<size; layer++)
157
      {
158
      float currX = startX;
159
      float currY = startY;
160

    
161
      for(int x=0; x<layer+1; x++)
162
        {
163
        float currZ = startZ;
164

    
165
        for(int z=0; z<size-layer; z++)
166
          {
167
          pos[index] = new float[] {currX,currY,currZ};
168
          index++;
169
          currZ -= DZ;
170
          }
171

    
172
        currX += DX;
173
        }
174

    
175
      startX-=DX/2;
176
      startY+=DY;
177
      startZ-=DZ/2;
178
      }
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
// there are (n^3-n)/6 octahedrons and ((n+1)^3 - (n+1))/6 tetrahedrons
183

    
184
  float[][] getCubitPositions(int size)
185
    {
186
    int numOcta = (size-1)*size*(size+1)/6;
187
    int numTetra= size*(size+1)*(size+2)/6;
188
    float[][] ret = new float[numOcta+numTetra][];
189

    
190
    addTetrahedralLattice(size-1,      0,ret);
191
    addTetrahedralLattice(size  ,numOcta,ret);
192

    
193
    return ret;
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
  Static4D[] getQuats()
199
    {
200
    if( mQuats==null ) initializeQuats();
201
    return mQuats;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  int getNumFaceColors()
207
    {
208
    return FACE_COLORS.length;
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  int getSolvedFunctionIndex()
214
    {
215
    return 0;
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  int getNumStickerTypes(int numLayers)
221
    {
222
    return 1;
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  float[][] getCuts(int numLayers)
228
    {
229
    float[][] cuts = new float[4][numLayers-1];
230

    
231
    for(int i=0; i<numLayers-1; i++)
232
      {
233
      float cut = (1.0f+i-numLayers/3.0f)*(SQ6/3);
234
      cuts[0][i] = cut;
235
      cuts[1][i] = cut;
236
      cuts[2][i] = cut;
237
      cuts[3][i] = cut;
238
      }
239

    
240
    return cuts;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  int getNumCubitFaces()
246
    {
247
    return 8;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  float getScreenRatio()
253
    {
254
    return 0.88f;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  boolean shouldResetTextureMaps()
260
    {
261
    return false;
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  private int getNumOctahedrons(int numLayers)
267
    {
268
    return (numLayers-1)*numLayers*(numLayers+1)/6;
269
    }
270

    
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

    
273
  private int faceColor(int cubit, int axis)
274
    {
275
    return CUBITS[cubit].mRotationRow[axis] == 1 ? axis : NUM_TEXTURES;
276
    }
277

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

    
280
  int getFaceColor(int cubit, int cubitface, int size)
281
    {
282
    if( cubit< (size-1)*size*(size+1)/6 )
283
      {
284
      switch( cubitface )
285
        {
286
        case 0: return faceColor(cubit,0);
287
        case 2: return faceColor(cubit,1);
288
        case 5: return faceColor(cubit,3);
289
        case 7: return faceColor(cubit,2);
290
        default:return NUM_TEXTURES;
291
        }
292
      }
293
    else
294
      {
295
      return cubitface<NUM_TEXTURES ? faceColor(cubit,cubitface) : NUM_TEXTURES;
296
      }
297
    }
298

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

    
301
  ObjectShape getObjectShape(int cubit, int numLayers)
302
    {
303
    int variant = getCubitVariant(cubit,numLayers);
304

    
305
    if( variant==0 )
306
      {
307
      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} };
308
      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} };
309
      int N = numLayers==3? 6 : 5;
310
      int E = numLayers==3? 2 : 1;
311
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
312
      int[] bandIndices   = new int[] { 0,0,0,0,0,0,0,0 };
313
      float[][] corners   = new float[][] { {0.04f,0.20f} };
314
      int[] cornerIndices = new int[] { 0,0,0,0,0,0 };
315
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
316
      int[] centerIndices = new int[] { 0,0,0,0,0,0 };
317
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
318
      }
319
    else
320
      {
321
      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} };
322
      int[][] vert_indices = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
323
      int N = numLayers==3? 6 : 5;
324
      int E = numLayers==3? 2 : 1;
325
      float[][] bands     = new float[][] { {0.05f,35,0.5f,0.8f,N,E,E} };
326
      int[] bandIndices   = new int[] { 0,0,0,0 };
327
      float[][] corners   = new float[][] { {0.06f,0.15f} };
328
      int[] cornerIndices = new int[] { 0,0,0,0 };
329
      float[][] centers   = new float[][] { {0.0f, 0.0f, 0.0f} };
330
      int[] centerIndices = new int[] { 0,0,0,0 };
331
      return new ObjectShape(vertices,vert_indices,bands,bandIndices,corners,cornerIndices,centers,centerIndices,getNumCubitFaces(), null);
332
      }
333
    }
334

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

    
337
  Static4D getQuat(int cubit, int numLayers)
338
    {
339
    if( mQuats==null ) initializeQuats();
340
    return mQuats[0];
341
    }
342

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

    
345
  int getNumCubitVariants(int numLayers)
346
    {
347
    return 2;
348
    }
349

    
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351

    
352
  int getCubitVariant(int cubit, int numLayers)
353
    {
354
    return cubit<getNumOctahedrons(numLayers) ? 0:1;
355
    }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
  int getColor(int face)
360
    {
361
    return FACE_COLORS[face];
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  ObjectSticker retSticker(int face)
367
    {
368
    if( mStickers==null )
369
      {
370
      float[][] STICKERS = new float[][] { { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f } };
371
      final float stroke = 0.08f;
372
      final float radius = 0.06f;
373
      final float[] radii= {radius,radius,radius};
374
      mStickers = new ObjectSticker[STICKERS.length];
375
      mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
376
      }
377

    
378
    return mStickers[face/NUM_FACE_COLORS];
379
    }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382
// SQ6/3 = height of the tetrahedron
383

    
384
  float returnMultiplier()
385
    {
386
    return getNumLayers()/(SQ6/3);
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390
// public API
391

    
392
  public Static3D[] getRotationAxis()
393
    {
394
    return ROT_AXIS;
395
    }
396

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

    
399
  public int[] getBasicAngle()
400
    {
401
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
402
    return mBasicAngle;
403
    }
404

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

    
407
  public int getObjectName(int numLayers)
408
    {
409
    switch(numLayers)
410
      {
411
      case 3: return R.string.pyra3;
412
      case 4: return R.string.pyra4;
413
      case 5: return R.string.pyra5;
414
      }
415
    return R.string.pyra3;
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  public int getInventor(int numLayers)
421
    {
422
    switch(numLayers)
423
      {
424
      case 3: return R.string.pyra3_inventor;
425
      case 4: return R.string.pyra4_inventor;
426
      case 5: return R.string.pyra5_inventor;
427
      }
428
    return R.string.pyra3_inventor;
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  public int getComplexity(int numLayers)
434
    {
435
    switch(numLayers)
436
      {
437
      case 3: return 4;
438
      case 4: return 6;
439
      case 5: return 8;
440
      }
441
    return 4;
442
    }
443
}
(40-40/47)