Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedMegaminx.java @ 60cc43cc

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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

    
14
import org.distorted.library.main.DistortedLibrary;
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17
import org.distorted.objectlib.bandaged.FactoryBandagedMegaminx;
18
import org.distorted.objectlib.helpers.ObjectFaceShape;
19
import org.distorted.objectlib.helpers.ObjectShape;
20
import org.distorted.objectlib.helpers.ObjectSignature;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.main.InitData;
24
import org.distorted.objectlib.scrambling.ObjectScrambler;
25

    
26
///////////////////////////////////////////////////////////////////////////////////////////////////
27

    
28
public class TwistyBandagedMegaminx extends TwistyDodecahedron
29
{
30
  public static final int KILOMINX3 = 2; // don't change those values
31
  public static final int MEGAMINX3 = 3; // ( see ObjectSignature.areNeighboursMegaminx() )
32
  public static final int KILOMINX5 = 4; // ( and getShortName() here )
33
  public static final int MEGAMINX5 = 5;
34

    
35
  public static final String OBJECT_NAME_MEGAMINX = "LOCAL_MEGAMINX";
36
  public static final char MARKER = 'm'; // keep lowercase
37

    
38
  private static final Static4D QUAT = new Static4D(0,0,0,1);
39

    
40
  private static final int KILO_CENT = 0;
41
  private static final int MEGA_CENT = 1;
42
  private static final int CORNER    = 2;
43
  private static final int KILO_EDGE1= 3;
44
  private static final int KILO_EDGE2= 4;
45
  private static final int MEGA_EDGE1= 5;
46
  private static final int MEGA_EDGE2= 6;
47
  private static final int OTHER     = 7;
48

    
49
  private static final int NUM_TYPES = 7;
50

    
51
  private int[] mCubitVariantMap;
52
  private int[] mTypeVariantMap;
53
  private ObjectShape[] mTmpShapes;
54
  private int mNumVariants, mNumStandardVariants;
55
  private int[] mCorrectedNumLayers;
56
  private float[][] mPosition;
57
  private float[][] mOrigPosition;  // again problem with the (2,3,4,5) numLayersFormat vs the (3,3,5,5) format:
58
                                    // for FactoryBandagedMegaminx we have to keep the original, 'uncorrected' positions;
59
  private ObjectSignature mSignature;
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  private float[][] correctPos(float corr, float[][] pos)
64
    {
65
    int numPos = pos.length;
66
    float[][] ret = new float[numPos][];
67

    
68
    for(int p=0; p<numPos; p++)
69
      {
70
      float[] po = pos[p];
71
      int len = po.length/3;
72
      ret[p] = new float[3*len];
73
      float[] re = ret[p];
74

    
75
      for(int i=0; i<len; i++)
76
        {
77
        re[3*i  ] = corr * po[3*i  ];
78
        re[3*i+1] = corr * po[3*i+1];
79
        re[3*i+2] = corr * po[3*i+2];
80
        }
81
      }
82

    
83
    return ret;
84
    }
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
  private void correctVerts(float corr, float[][] verts)
89
    {
90
    for(float[] ve : verts)
91
      {
92
      ve[0] *= corr;
93
      ve[1] *= corr;
94
      ve[2] *= corr;
95
      }
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  private float[][] getPositions()
101
    {
102
    if( mPosition==null )
103
      {
104
      InitData data = getInitData();
105
      mOrigPosition = data.getPos();
106
      int param = data.getParam();
107

    
108
      switch(param)
109
        {
110
        case KILOMINX3: mPosition = correctPos(1.50f,mOrigPosition); break;
111
        case KILOMINX5: mPosition = correctPos(1.25f,mOrigPosition); break;
112
        case MEGAMINX3:
113
        case MEGAMINX5: mPosition = mOrigPosition;
114
        }
115
      }
116

    
117
    return mPosition;
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121
// numLayers that we get here from BandagedObjectMegaminx are in the format (3,3,5,5) - i.e. one
122
// that agrees with the format in the previous TwistyKilominx/TwistyMegaminx classes (and in
123
// TwistyDodecahedron!). But FactoryBandagedMegaminx requires the unified (2,3,4,5) format -
124
// translate here.
125

    
126
  private int[] correctNumLayers(int param)
127
    {
128
    switch(param)
129
      {
130
      case KILOMINX3: return new int[] {2,2,2,2,2,2};
131
      case MEGAMINX3: return new int[] {3,3,3,3,3,3};
132
      case KILOMINX5: return new int[] {4,4,4,4,4,4};
133
      case MEGAMINX5: return new int[] {5,5,5,5,5,5};
134
      }
135

    
136
    return null;
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  private void produceTmpShape(int variant)
142
    {
143
    int cubit,numCubits = mPosition.length;
144

    
145
    for(cubit=0; cubit<numCubits; cubit++)
146
      {
147
      if( mCubitVariantMap[cubit]==variant ) break;
148
      }
149

    
150
    if( cubit>=numCubits )
151
      {
152
      android.util.Log.e("D", "unknown variant: "+variant);
153
      }
154
    else
155
      {
156
      FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
157
      mTmpShapes[variant] = factory.createIrregularShape(variant,mOrigPosition[cubit]);
158

    
159
      InitData data = getInitData();
160
      int param = data.getParam();
161

    
162
      switch(param)
163
        {
164
        case KILOMINX3: correctVerts(1.50f,mTmpShapes[variant].getVertices()); break;
165
        case KILOMINX5: correctVerts(1.25f,mTmpShapes[variant].getVertices()); break;
166
        }
167
      }
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
// PUBLIC API
172

    
173
  public TwistyBandagedMegaminx(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
174
    {
175
    super(meshState, iconMode, quat, move, scale, data, asset);
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
// Computing scramble states of many a bandaged objects takes way too long time and too much space.
180
// Return null here and turn to construction of scramble tables just-in-time (scrambleType=2)
181

    
182
  public int[][] getScrambleEdges()
183
    {
184
    return null;
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  @Override
190
  public int[][] getScrambleAlgorithms()
191
    {
192
    return null;
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  @Override
198
  public int getScrambleType()
199
    {
200
    return ObjectScrambler.SCRAMBLING_BANDAGED;
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  public ObjectShape getObjectShape(int variant)
206
    {
207
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
208
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
209
    return mTmpShapes[variant];
210
    }
211

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

    
214
  public Static4D getCubitQuats(int cubit, int[] numLayers)
215
    {
216
    float[] pos = mOrigPosition[cubit];
217
    return pos.length>3 ? QUAT : FactoryBandagedMegaminx.getInstance().getCubitQuat(pos[0],pos[1],pos[2]);
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
/*
222
  private int getType(int variant)
223
    {
224
    for(int t=0; t<NUM_TYPES; t++)
225
      if( mTypeVariantMap[t]==variant ) return t;
226

    
227
    return -1;
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  private float[][] getVertices(int variant)
233
    {
234
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
235
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
236
    return mTmpShapes[variant].getVertices();
237
    }
238
*/
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  public ObjectVertexEffects getVertexEffects(int variant)
242
    {
243
    int[] numLayers = getNumLayers();
244
    int size = numLayers[0];
245
    boolean round = (DistortedLibrary.fastCompilationTF() && size<5 && !isInIconMode());
246
/*
247
    int type = getType(variant);
248

    
249
    if( type>=0 )
250
      {
251
      float[][] vertices = getVertices(variant);
252
      int numV = vertices.length;
253
      float S = -0.04f;
254

    
255
      String name = EffectName.DEFORM.name();
256
      float[] reg = {0,0,0,0.15f};
257

    
258
      float[][] variables = new float[numV][];
259
      String[] names      = new String[numV];
260
      float[][] regions   = new float[numV][];
261
      boolean[] uses      = new boolean[numV];
262

    
263
      for(int i=0; i<numV; i++)
264
        {
265
        float[] v    = vertices[i];
266
        variables[i] = new float[] { 0, S*v[0], S*v[1], S*v[2], 1 };
267
        names[i]     = name;
268
        regions[i]   = reg;
269
        uses[i]      = round;
270
        }
271

    
272
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
273
      }
274
   */
275
    FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
276
    return factory.createVertexEffects(variant,round);
277
    }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280
/*
281
  private int[] createBandIndices(int type)
282
    {
283
    int[] bandIndices = null;
284

    
285
    switch(type)
286
      {
287
      case MEGA_CENT : bandIndices = new int[] {1,0,0,0,0,0};
288
                       break;
289
      case KILO_EDGE1:
290
      case KILO_EDGE2:
291
      case MEGA_EDGE1:
292
      case MEGA_EDGE2: bandIndices = new int[] {1,1,0,0,0,0};
293
                       break;
294
      case KILO_CENT :
295
      case CORNER    : bandIndices = new int[] {1,1,1,0,0,0};
296
                       break;
297
      }
298

    
299
    return new int[] {0,0,0,0,0,0};//bandIndices;
300
    }
301
*/
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  public ObjectFaceShape getObjectFaceShape(int variant)
305
    {
306
    FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
307
/*
308
    int type = getType(variant);
309

    
310
    if( type>=0 )
311
      {
312
      int param = getInitData().getParam();
313
      int[] numLayers = correctNumLayers(param);
314

    
315
      if( numLayers!=null )
316
        {
317
        boolean iconMode = isInIconMode();
318
        float[][] bands = factory.getBands(iconMode,numLayers);
319
        int[] bandIndices = createBandIndices(type);
320
        return new ObjectFaceShape(bands, bandIndices, null);
321
        }
322
      }
323
*/
324
    return factory.createIrregularFaceShape(variant, isInIconMode() );
325
    }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
  private int translateVariant(int size, int variant)
330
    {
331
    switch(size)
332
      {
333
      case 2: return KILO_CENT;
334
      case 3: return variant==0 ? CORNER : variant==1 ? MEGA_EDGE1 : MEGA_CENT;
335
      case 4: switch(variant)
336
                {
337
                case  0: return CORNER;
338
                case  1: return KILO_EDGE1;
339
                case  2: return KILO_EDGE2;
340
                default: return KILO_CENT;
341
                }
342
      case 5: switch(variant)
343
                {
344
                case  0: return CORNER;
345
                case  1: return MEGA_EDGE1;
346
                case  2: return MEGA_EDGE2;
347
                default: return MEGA_CENT;
348
                }
349
      }
350

    
351
    return -1;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  public int getNumCubitVariants(int[] numLayers)
357
    {
358
    if( mNumVariants==0 )
359
      {
360
      int param = getInitData().getParam();
361
      if( mCorrectedNumLayers==null ) mCorrectedNumLayers = correctNumLayers(param);
362
      int size = mCorrectedNumLayers==null ? -1 : mCorrectedNumLayers[0];
363
      float[][] positions = getPositions();
364
      boolean T0=false;
365
      boolean T1=false;
366
      boolean T2=false;
367
      boolean T3=false;
368
      boolean T4=false;
369
      boolean T5=false;
370
      boolean T6=false;
371

    
372
      float corr=1.0f;
373
      if( size==2 ) corr=2.0f/3;
374
      else if( size==4 ) corr=4.0f/5;
375

    
376
      int numSpecial = 0;
377
      int numCubits = positions.length;
378
      mCubitVariantMap = new int[numCubits];
379

    
380
      mTypeVariantMap = new int[NUM_TYPES];
381
      for(int i=0; i<NUM_TYPES; i++) mTypeVariantMap[i] = -1;
382

    
383
      FactoryBandagedMegaminx factory = FactoryBandagedMegaminx.getInstance();
384

    
385
      for (int cubit=0; cubit<numCubits; cubit++)
386
        {
387
        int type = OTHER;
388
        float[] pos = positions[cubit];
389

    
390
        if( pos.length==3 )
391
          {
392
          int variant = factory.getElementVariant(mCorrectedNumLayers, corr*pos[0], corr*pos[1], corr*pos[2]);
393
          type = translateVariant(size, variant);
394
          }
395

    
396
        switch (type)
397
          {
398
          case KILO_CENT : if (!T0) { T0 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
399
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
400
                           break;
401
          case MEGA_CENT : if (!T1) { T1 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
402
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
403
                           break;
404
          case CORNER    : if (!T2) { T2 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
405
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
406
                           break;
407
          case KILO_EDGE1: if (!T3) { T3 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
408
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
409
                           break;
410
          case KILO_EDGE2: if (!T4) { T4 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
411
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
412
                           break;
413
          case MEGA_EDGE1: if (!T5) { T5 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
414
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
415
                           break;
416
          case MEGA_EDGE2: if (!T6) { T6 = true; mTypeVariantMap[type]=mNumStandardVariants++; }
417
                           mCubitVariantMap[cubit] = mTypeVariantMap[type];
418
                           break;
419
          default        : numSpecial++;
420
                           mCubitVariantMap[cubit] = -numSpecial;
421
          }
422
        }
423

    
424
      mNumVariants = mNumStandardVariants + numSpecial;
425

    
426
      android.util.Log.e("D", "numStandard="+mNumStandardVariants+" numSpecial: "+numSpecial+" numTotal: "+mNumVariants);
427

    
428
      numSpecial = mNumStandardVariants;
429

    
430
      for (int cubit=0; cubit<numCubits; cubit++)
431
        if( mCubitVariantMap[cubit]<0 )
432
          mCubitVariantMap[cubit] = numSpecial++;
433

    
434
      factory.prepare(mNumVariants,mCorrectedNumLayers);
435
      }
436

    
437
    return mNumVariants;
438
    }
439

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

    
442
  public float[][] getCubitPositions(int[] numLayers)
443
    {
444
    return getPositions();
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  public float[][] getCuts(int[] numLayers)
450
    {
451
    int param = getInitData().getParam();
452
    int size = numLayers[0];
453
    float dist = (param==KILOMINX3 || param==KILOMINX5) ? 0.5f : 0.5f-MEGA_D;
454
    return genericGetCuts(size,dist);
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  public int getCubitVariant(int cubit, int[] numLayers)
460
    {
461
    return mCubitVariantMap[cubit];
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public float getStickerRadius()
467
    {
468
    return 0.18f;
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  public float getStickerStroke()
474
    {
475
    int param = getInitData().getParam();
476

    
477
    switch(param)
478
      {
479
      case KILOMINX3: return isInIconMode() ? 0.38f : 0.27f;
480
      case MEGAMINX3: return isInIconMode() ? 0.27f : 0.18f;
481
      case KILOMINX5: return isInIconMode() ? 0.38f : 0.26f;
482
      case MEGAMINX5: return isInIconMode() ? 0.40f : 0.18f;
483
      }
484

    
485
    return 0.0f;
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public float[][][] getStickerAngles()
491
    {
492
    return null;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public String getShortName()
498
    {
499
    if( mSignature==null ) mSignature = getSignature();
500
    int param = getInitData().getParam();
501
    return MARKER+(param+"_"+mSignature.getString());
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public ObjectSignature getSignature()
507
    {
508
    if( mSignature==null )
509
      {
510
      int param = getInitData().getParam();
511
      mSignature = new ObjectSignature(mPosition,param);
512
      }
513
    return mSignature;
514
    }
515

    
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517

    
518
  public String getObjectName()
519
    {
520
    return OBJECT_NAME_MEGAMINX;
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  public String getInventor()
526
    {
527
    return "??";
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public int getYearOfInvention()
533
    {
534
    return 0;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public int getComplexity()
540
    {
541
    return 4;
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  public String[][] getTutorials()
547
    {
548
    return null;
549
    }
550
}
(4-4/49)