Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyPyraminx.java @ e9a87113

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
  private Movement mMovement;
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

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

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

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

    
76
    return mStates;
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

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

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

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

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

    
116
      start++;
117
      }
118

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

    
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

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

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

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

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

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

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

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

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

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

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

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

    
173
        currX += DX;
174
        }
175

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

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

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

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

    
194
    return ret;
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

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

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

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

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

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

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

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

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

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

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

    
241
    return cuts;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

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

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

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

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

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

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

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

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

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

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

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

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

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

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

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

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

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

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

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

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

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

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

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

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

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

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

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

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
// public API
392

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

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

    
400
  public Movement getMovement()
401
    {
402
    if( mMovement==null ) mMovement = new MovementPyraminx();
403
    return mMovement;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public int[] getBasicAngle()
409
    {
410
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 3,3,3,3 };
411
    return mBasicAngle;
412
    }
413

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

    
416
  public int getObjectName(int numLayers)
417
    {
418
    switch(numLayers)
419
      {
420
      case 3: return R.string.pyra3;
421
      case 4: return R.string.pyra4;
422
      case 5: return R.string.pyra5;
423
      }
424
    return R.string.pyra3;
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public int getInventor(int numLayers)
430
    {
431
    switch(numLayers)
432
      {
433
      case 3: return R.string.pyra3_inventor;
434
      case 4: return R.string.pyra4_inventor;
435
      case 5: return R.string.pyra5_inventor;
436
      }
437
    return R.string.pyra3_inventor;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

    
442
  public int getComplexity(int numLayers)
443
    {
444
    switch(numLayers)
445
      {
446
      case 3: return 4;
447
      case 4: return 6;
448
      case 5: return 8;
449
      }
450
    return 4;
451
    }
452
}
(37-37/44)