Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedMegaminx.java @ 3a0990b1

1 3739dd53 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.objects;
11
12
import static org.distorted.objectlib.objects.TwistyMegaminx.MEGA_D;
13 6725e537 leszek
import static org.distorted.objectlib.touchcontrol.TouchControlDodecahedron.C2;
14
import static org.distorted.objectlib.touchcontrol.TouchControlDodecahedron.SIN54;
15 3739dd53 leszek
16
import org.distorted.library.main.DistortedLibrary;
17
import org.distorted.library.type.Static3D;
18
import org.distorted.library.type.Static4D;
19
import org.distorted.objectlib.bandaged.FactoryBandagedMegaminx;
20
import org.distorted.objectlib.helpers.ObjectFaceShape;
21
import org.distorted.objectlib.helpers.ObjectShape;
22 ae9d9227 leszek
import org.distorted.objectlib.metadata.Metadata;
23 97a75106 leszek
import org.distorted.objectlib.signature.ObjectSignature;
24 3739dd53 leszek
import org.distorted.objectlib.helpers.ObjectVertexEffects;
25
import org.distorted.objectlib.main.InitAssets;
26
import org.distorted.objectlib.scrambling.ObjectScrambler;
27 97a75106 leszek
import org.distorted.objectlib.signature.ObjectSignatureMegaminx;
28 3739dd53 leszek
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30
31
public class TwistyBandagedMegaminx extends TwistyDodecahedron
32
{
33 3ede7593 leszek
  public static final int KILOMINX3 = 2; // don't change those values
34
  public static final int MEGAMINX3 = 3; // ( see ObjectSignature.areNeighboursMegaminx() )
35
  public static final int KILOMINX5 = 4; // ( and getShortName() here )
36 5829e661 leszek
  public static final int MEGAMINX5 = 5;
37
38 3739dd53 leszek
  public static final String OBJECT_NAME_MEGAMINX = "LOCAL_MEGAMINX";
39 60cc43cc leszek
  public static final char MARKER = 'm'; // keep lowercase
40 3739dd53 leszek
41 60cc43cc leszek
  private static final Static4D QUAT = new Static4D(0,0,0,1);
42 3739dd53 leszek
43 6725e537 leszek
  private static final float[] KILOMINX_CORNER = new float[] {0, 1.00f, 2*C2};
44
  private static final float[] MEGAMINX_CORNER = new float[] {0, 1.50f, 3*C2};
45
  private static final float[] MKILOMINX_CORNER= new float[] {0, 2.00f, 4*C2};
46
  private static final float[] GIGAMINX_CORNER = new float[] {0, 2.50f, 5*C2};
47
  private static final float[] MEGAMINX_EDGE   = new float[] {0, 0.00f, 3*C2};
48
  private static final float[] MKILOMINX_EDGE1 = new float[] {0, 1.00f, 4*C2};
49
  private static final float[] MKILOMINX_EDGE2 = new float[] {0,-1.00f, 4*C2};
50
  private static final float[] GIGAMINX_EDGE1  = new float[] {0, 0.00f, 5*C2};
51
52
  private static final float DB = (2.5f-MEGA_D)/10;
53
  private static final float XB = DB*5*SIN54;
54
  private static final float ZB = (1-DB)*5*C2 + DB*5*SIN54;
55
  private static final float[] GIGAMINX_EDGE2  = new float[] {XB, 0.00f, ZB };
56
57
  private static final float YC = (1.5f+6*C2+6*SIN54)/5;
58
  private static final float ZC = (3*C2+6*SIN54)/5;
59
  private static final float[] MEGAMINX_CENTER = new float[] {0, YC, ZC};
60
  private static final float[] MKILOMINX_CENTER= new float[] {0, 4*YC/3, 4*ZC/3};
61
  private static final float[] GIGAMINX_CENTER = new float[] {0, 5*YC/3, 5*ZC/3};
62
63 60cc43cc leszek
  private static final int KILO_CENT = 0;
64
  private static final int MEGA_CENT = 1;
65
  private static final int CORNER    = 2;
66
  private static final int KILO_EDGE1= 3;
67
  private static final int KILO_EDGE2= 4;
68
  private static final int MEGA_EDGE1= 5;
69
  private static final int MEGA_EDGE2= 6;
70
  private static final int OTHER     = 7;
71
72
  private static final int NUM_TYPES = 7;
73 3739dd53 leszek
74
  private int[] mCubitVariantMap;
75
  private int[] mTypeVariantMap;
76 0d9a2083 leszek
  private boolean[] mIsNonStandard;
77 3739dd53 leszek
  private ObjectShape[] mTmpShapes;
78 0d9a2083 leszek
  private int mNumVariants;
79 60cc43cc leszek
  private int[] mCorrectedNumLayers;
80 3739dd53 leszek
  private float[][] mPosition;
81 5829e661 leszek
  private float[][] mOrigPosition;  // again problem with the (2,3,4,5) numLayersFormat vs the (3,3,5,5) format:
82
                                    // for FactoryBandagedMegaminx we have to keep the original, 'uncorrected' positions;
83 3739dd53 leszek
  private ObjectSignature mSignature;
84
85 5829e661 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87
  private float[][] correctPos(float corr, float[][] pos)
88
    {
89
    int numPos = pos.length;
90
    float[][] ret = new float[numPos][];
91
92
    for(int p=0; p<numPos; p++)
93
      {
94
      float[] po = pos[p];
95
      int len = po.length/3;
96
      ret[p] = new float[3*len];
97
      float[] re = ret[p];
98
99
      for(int i=0; i<len; i++)
100
        {
101
        re[3*i  ] = corr * po[3*i  ];
102
        re[3*i+1] = corr * po[3*i+1];
103
        re[3*i+2] = corr * po[3*i+2];
104
        }
105
      }
106
107
    return ret;
108
    }
109
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111
112
  private void correctVerts(float corr, float[][] verts)
113
    {
114
    for(float[] ve : verts)
115
      {
116
      ve[0] *= corr;
117
      ve[1] *= corr;
118
      ve[2] *= corr;
119
      }
120
    }
121
122 3739dd53 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124
  private float[][] getPositions()
125
    {
126 5829e661 leszek
    if( mPosition==null )
127
      {
128 ae9d9227 leszek
      Metadata meta = getMetadata();
129
      mOrigPosition = meta.getPos();
130
      int param = meta.getParam();
131 5829e661 leszek
132
      switch(param)
133
        {
134
        case KILOMINX3: mPosition = correctPos(1.50f,mOrigPosition); break;
135
        case KILOMINX5: mPosition = correctPos(1.25f,mOrigPosition); break;
136
        case MEGAMINX3:
137
        case MEGAMINX5: mPosition = mOrigPosition;
138
        }
139
      }
140
141 3739dd53 leszek
    return mPosition;
142
    }
143
144 5829e661 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
145
// numLayers that we get here from BandagedObjectMegaminx are in the format (3,3,5,5) - i.e. one
146
// that agrees with the format in the previous TwistyKilominx/TwistyMegaminx classes (and in
147
// TwistyDodecahedron!). But FactoryBandagedMegaminx requires the unified (2,3,4,5) format -
148
// translate here.
149
150
  private int[] correctNumLayers(int param)
151
    {
152
    switch(param)
153
      {
154
      case KILOMINX3: return new int[] {2,2,2,2,2,2};
155
      case MEGAMINX3: return new int[] {3,3,3,3,3,3};
156
      case KILOMINX5: return new int[] {4,4,4,4,4,4};
157
      case MEGAMINX5: return new int[] {5,5,5,5,5,5};
158
      }
159
160
    return null;
161
    }
162
163 3739dd53 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
164
165 6725e537 leszek
  private float[] figureOutCubitPos(int variant, int param)
166 3739dd53 leszek
    {
167 0d9a2083 leszek
    if( mIsNonStandard[variant] )
168 3739dd53 leszek
      {
169 6725e537 leszek
      int numCubits = mPosition.length;
170 3739dd53 leszek
171 6725e537 leszek
      for(int cubit = 0; cubit<numCubits; cubit++)
172
        if( mCubitVariantMap[cubit]==variant ) return mOrigPosition[cubit];
173 3739dd53 leszek
      }
174
    else
175
      {
176 6725e537 leszek
      // cubit is one of the 'standard' shapes. Here we have to statically return a position
177
      // because it may very well happen that a Kilominx' cubit 0 is not a CORNER but one of
178
      // the 'non-standard' shapes and the above procedure would return an improper pos!
179 5829e661 leszek
180
      switch(param)
181
        {
182 6725e537 leszek
        case KILOMINX3: return KILOMINX_CORNER;
183 0d9a2083 leszek
        case MEGAMINX3: int type3 = getType(variant);
184
185
                        switch( type3 )
186 6725e537 leszek
                          {
187 0d9a2083 leszek
                          case  CORNER    : return MEGAMINX_CORNER;
188
                          case  MEGA_EDGE1: return MEGAMINX_EDGE;
189
                          case  MEGA_CENT : return MEGAMINX_CENTER;
190
                          default         : android.util.Log.e("D", "illegal type "+type3);
191 6725e537 leszek
                          }
192
                        break;
193 0d9a2083 leszek
        case KILOMINX5: int type4 = getType(variant);
194
195
                        switch( type4 )
196 6725e537 leszek
                          {
197 0d9a2083 leszek
                          case  CORNER    : return MKILOMINX_CORNER;
198
                          case  KILO_EDGE1: return MKILOMINX_EDGE1;
199
                          case  KILO_EDGE2: return MKILOMINX_EDGE2;
200
                          case  KILO_CENT : return MKILOMINX_CENTER;
201
                          default         : android.util.Log.e("D", "illegal type "+type4);
202 6725e537 leszek
                          }
203
                        break;
204 0d9a2083 leszek
        case MEGAMINX5: int type5 = getType(variant);
205
206
                        switch( type5 )
207 6725e537 leszek
                          {
208 0d9a2083 leszek
                          case  CORNER    : return GIGAMINX_CORNER;
209
                          case  MEGA_EDGE1: return GIGAMINX_EDGE1;
210
                          case  MEGA_EDGE2: return GIGAMINX_EDGE2;
211
                          case  MEGA_CENT : return GIGAMINX_CENTER;
212
                          default         : android.util.Log.e("D", "illegal type "+type5);
213 6725e537 leszek
                          }
214
                        break;
215 5829e661 leszek
        }
216 3739dd53 leszek
      }
217 6725e537 leszek
218
    return null;
219
    }
220
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222
223
  private void produceTmpShape(int variant)
224
    {
225 ae9d9227 leszek
    Metadata meta = getMetadata();
226
    int param = meta.getParam();
227 6725e537 leszek
    float[] pos = figureOutCubitPos(variant,param);
228
229
    FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
230
    mTmpShapes[variant] = factory.createIrregularShape(variant,pos);
231
232
    switch(param)
233
      {
234
      case KILOMINX3: correctVerts(1.50f,mTmpShapes[variant].getVertices()); break;
235
      case KILOMINX5: correctVerts(1.25f,mTmpShapes[variant].getVertices()); break;
236
      }
237 3739dd53 leszek
    }
238
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240
// PUBLIC API
241
242 ae9d9227 leszek
  public TwistyBandagedMegaminx(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
243 3739dd53 leszek
    {
244 ae9d9227 leszek
    super(iconMode, quat, move, scale, meta, asset);
245 3739dd53 leszek
    }
246
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
// Computing scramble states of many a bandaged objects takes way too long time and too much space.
249
// Return null here and turn to construction of scramble tables just-in-time (scrambleType=2)
250
251
  public int[][] getScrambleEdges()
252
    {
253
    return null;
254
    }
255
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
258
  @Override
259
  public int[][] getScrambleAlgorithms()
260
    {
261 5e1b47f8 leszek
    return null;
262 3739dd53 leszek
    }
263
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265
266
  @Override
267
  public int getScrambleType()
268
    {
269
    return ObjectScrambler.SCRAMBLING_BANDAGED;
270
    }
271
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273
274
  public ObjectShape getObjectShape(int variant)
275
    {
276
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
277
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
278
    return mTmpShapes[variant];
279
    }
280
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283 60cc43cc leszek
  public Static4D getCubitQuats(int cubit, int[] numLayers)
284 3739dd53 leszek
    {
285 60cc43cc leszek
    float[] pos = mOrigPosition[cubit];
286
    return pos.length>3 ? QUAT : FactoryBandagedMegaminx.getInstance().getCubitQuat(pos[0],pos[1],pos[2]);
287
    }
288 3739dd53 leszek
289 60cc43cc leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
290 0d9a2083 leszek
291 60cc43cc leszek
  private int getType(int variant)
292
    {
293
    for(int t=0; t<NUM_TYPES; t++)
294
      if( mTypeVariantMap[t]==variant ) return t;
295 5829e661 leszek
296 60cc43cc leszek
    return -1;
297
    }
298 3739dd53 leszek
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300
301
  public ObjectVertexEffects getVertexEffects(int variant)
302
    {
303
    int[] numLayers = getNumLayers();
304
    int size = numLayers[0];
305 7dfaccb3 leszek
    boolean round = (DistortedLibrary.fastCompilationTF() && size<5 && !isInIconMode());
306 3739dd53 leszek
307
    FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
308
    return factory.createVertexEffects(variant,round);
309
    }
310
311 60cc43cc leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
312
313
  public ObjectFaceShape getObjectFaceShape(int variant)
314
    {
315
    FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
316
    return factory.createIrregularFaceShape(variant, isInIconMode() );
317
    }
318
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320
321
  private int translateVariant(int size, int variant)
322 3739dd53 leszek
    {
323 60cc43cc leszek
    switch(size)
324
      {
325
      case 2: return KILO_CENT;
326
      case 3: return variant==0 ? CORNER : variant==1 ? MEGA_EDGE1 : MEGA_CENT;
327
      case 4: switch(variant)
328
                {
329
                case  0: return CORNER;
330
                case  1: return KILO_EDGE1;
331
                case  2: return KILO_EDGE2;
332
                default: return KILO_CENT;
333
                }
334
      case 5: switch(variant)
335
                {
336
                case  0: return CORNER;
337
                case  1: return MEGA_EDGE1;
338
                case  2: return MEGA_EDGE2;
339
                default: return MEGA_CENT;
340
                }
341
      }
342
343
    return -1;
344 3739dd53 leszek
    }
345
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347
348
  public int getNumCubitVariants(int[] numLayers)
349
    {
350
    if( mNumVariants==0 )
351
      {
352 ae9d9227 leszek
      int param = getMetadata().getParam();
353 60cc43cc leszek
      if( mCorrectedNumLayers==null ) mCorrectedNumLayers = correctNumLayers(param);
354
      int size = mCorrectedNumLayers==null ? -1 : mCorrectedNumLayers[0];
355 3739dd53 leszek
      float[][] positions = getPositions();
356 6725e537 leszek
      boolean T0 = false;
357
      boolean T1 = false;
358
      boolean T2 = false;
359
      boolean T3 = false;
360
      boolean T4 = false;
361
      boolean T5 = false;
362
      boolean T6 = false;
363 60cc43cc leszek
364
      float corr=1.0f;
365
      if( size==2 ) corr=2.0f/3;
366
      else if( size==4 ) corr=4.0f/5;
367 3739dd53 leszek
368
      int numCubits = positions.length;
369
      mCubitVariantMap = new int[numCubits];
370 0d9a2083 leszek
      mIsNonStandard = new boolean[numCubits];   // mNumVariants <= numCubits
371 3739dd53 leszek
      mTypeVariantMap = new int[NUM_TYPES];
372
      for(int i=0; i<NUM_TYPES; i++) mTypeVariantMap[i] = -1;
373
374 60cc43cc leszek
      FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
375
376 3739dd53 leszek
      for (int cubit=0; cubit<numCubits; cubit++)
377
        {
378 60cc43cc leszek
        int type = OTHER;
379
        float[] pos = positions[cubit];
380
381
        if( pos.length==3 )
382
          {
383
          int variant = factory.getElementVariant(mCorrectedNumLayers, corr*pos[0], corr*pos[1], corr*pos[2]);
384
          type = translateVariant(size, variant);
385
          }
386 3739dd53 leszek
387
        switch (type)
388
          {
389 0d9a2083 leszek
          case KILO_CENT : if (!T0) { T0 = true; mTypeVariantMap[type]=mNumVariants++; }
390 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
391
                           break;
392 0d9a2083 leszek
          case MEGA_CENT : if (!T1) { T1 = true; mTypeVariantMap[type]=mNumVariants++; }
393 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
394
                           break;
395 0d9a2083 leszek
          case CORNER    : if (!T2) { T2 = true; mTypeVariantMap[type]=mNumVariants++; }
396 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
397
                           break;
398 0d9a2083 leszek
          case KILO_EDGE1: if (!T3) { T3 = true; mTypeVariantMap[type]=mNumVariants++; }
399 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
400
                           break;
401 0d9a2083 leszek
          case KILO_EDGE2: if (!T4) { T4 = true; mTypeVariantMap[type]=mNumVariants++; }
402 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
403
                           break;
404 0d9a2083 leszek
          case MEGA_EDGE1: if (!T5) { T5 = true; mTypeVariantMap[type]=mNumVariants++; }
405 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
406
                           break;
407 0d9a2083 leszek
          case MEGA_EDGE2: if (!T6) { T6 = true; mTypeVariantMap[type]=mNumVariants++; }
408 60cc43cc leszek
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
409
                           break;
410 0d9a2083 leszek
          default        : mIsNonStandard[mNumVariants] = true;
411
                           mCubitVariantMap[cubit] = mNumVariants++;
412 3739dd53 leszek
          }
413
        }
414
415 60cc43cc leszek
      factory.prepare(mNumVariants,mCorrectedNumLayers);
416 3739dd53 leszek
      }
417
418
    return mNumVariants;
419
    }
420
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
423
  public float[][] getCubitPositions(int[] numLayers)
424
    {
425
    return getPositions();
426
    }
427
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429
430
  public float[][] getCuts(int[] numLayers)
431
    {
432 ae9d9227 leszek
    int param = getMetadata().getParam();
433 3739dd53 leszek
    int size = numLayers[0];
434 5829e661 leszek
    float dist = (param==KILOMINX3 || param==KILOMINX5) ? 0.5f : 0.5f-MEGA_D;
435 3739dd53 leszek
    return genericGetCuts(size,dist);
436
    }
437
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public int getCubitVariant(int cubit, int[] numLayers)
441
    {
442
    return mCubitVariantMap[cubit];
443
    }
444
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
447
  public float getStickerRadius()
448
    {
449 5e1b47f8 leszek
    return 0.18f;
450 3739dd53 leszek
    }
451
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453
454
  public float getStickerStroke()
455
    {
456 ae9d9227 leszek
    int param = getMetadata().getParam();
457 5e1b47f8 leszek
458 5829e661 leszek
    switch(param)
459 5e1b47f8 leszek
      {
460 5829e661 leszek
      case KILOMINX3: return isInIconMode() ? 0.38f : 0.27f;
461
      case MEGAMINX3: return isInIconMode() ? 0.27f : 0.18f;
462
      case KILOMINX5: return isInIconMode() ? 0.38f : 0.26f;
463
      case MEGAMINX5: return isInIconMode() ? 0.40f : 0.18f;
464 5e1b47f8 leszek
      }
465
466
    return 0.0f;
467 3739dd53 leszek
    }
468
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470
471
  public float[][][] getStickerAngles()
472
    {
473
    return null;
474
    }
475
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477
478
  public String getShortName()
479
    {
480
    if( mSignature==null ) mSignature = getSignature();
481 ae9d9227 leszek
    int param = getMetadata().getParam();
482 9e79b20f leszek
    return MARKER+(param+"_"+mSignature.getString());
483 3739dd53 leszek
    }
484
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486
487
  public ObjectSignature getSignature()
488
    {
489
    if( mSignature==null )
490
      {
491 ae9d9227 leszek
      int param = getMetadata().getParam();
492 97a75106 leszek
      mSignature = new ObjectSignatureMegaminx(param,mPosition);
493 3739dd53 leszek
      }
494
    return mSignature;
495
    }
496
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498
499
  public String getObjectName()
500
    {
501
    return OBJECT_NAME_MEGAMINX;
502
    }
503
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505
506
  public String getInventor()
507
    {
508
    return "??";
509
    }
510
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512
513
  public int getYearOfInvention()
514
    {
515
    return 0;
516
    }
517
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519
520 da5551f4 leszek
  public float getComplexity()
521 3739dd53 leszek
    {
522
    return 4;
523
    }
524
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526
527
  public String[][] getTutorials()
528
    {
529
    return null;
530
    }
531
}