Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedSkewb.java @ 33ba467a

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.bandaged.FactoryBandaged.QUAT;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_HEXAHEDRON;
14
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_CORNER;
15

    
16
import org.distorted.library.effect.EffectName;
17
import org.distorted.library.main.DistortedLibrary;
18
import org.distorted.library.type.Static3D;
19
import org.distorted.library.type.Static4D;
20
import org.distorted.objectlib.bandaged.FactoryBandagedSkewb;
21
import org.distorted.objectlib.helpers.ObjectFaceShape;
22
import org.distorted.objectlib.helpers.ObjectShape;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitAssets;
25
import org.distorted.objectlib.metadata.Metadata;
26
import org.distorted.objectlib.scrambling.ObjectScrambler;
27
import org.distorted.objectlib.shape.ShapeHexahedron;
28
import org.distorted.objectlib.signature.ObjectSignature;
29
import org.distorted.objectlib.signature.ObjectSignatureSkewb;
30
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
31

    
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

    
34
public class TwistyBandagedSkewb extends ShapeHexahedron
35
{
36
  public static final String OBJECT_NAME_SKEWB = "LOCAL_SKEWB";
37
  public static final char MARKER = 's'; // keep lowercase
38

    
39
  private static final Static3D[] ROT_AXIS = new Static3D[]
40
        {
41
           new Static3D ( SQ3/3, SQ3/3, SQ3/3 ),
42
           new Static3D ( SQ3/3, SQ3/3,-SQ3/3 ),
43
           new Static3D ( SQ3/3,-SQ3/3, SQ3/3 ),
44
           new Static3D ( SQ3/3,-SQ3/3,-SQ3/3 )
45
        };
46

    
47
  private static final float[] CORNER2 = new float[] {1.0f,1.0f,1.0f};
48
  private static final float[] CENTER2 = new float[] {0.0f,0.0f,1.0f};
49
  private static final float[] CORNER3 = new float[] {1.5f,1.5f,1.5f};
50
  private static final float[] CENTER3 = new float[] {0.0f,0.0f,1.5f};
51
  private static final float[] EDGE3   = new float[] {0.0f,1.5f,1.5f};
52

    
53
  private static final int COR = 0;
54
  private static final int CEN = 1;
55
  private static final int EDG = 2;
56
  private static final int OTHER = 3;
57
  private static final int NUM_TYPES = 3;
58

    
59
  private int[] mCubitVariantMap;
60
  private int[] mTypeVariantMap;
61
  private ObjectShape[] mTmpShapes;
62
  private int mNumVariants;
63
  private float[][] mPosition;
64
  private ObjectSignature mSignature;
65
  private float[][] mCuts;
66
  private int[][] mBasicAngle;
67
  private boolean[] mIsNonStandard;
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
  private float[][] getPositions()
72
    {
73
    if( mPosition==null ) mPosition = getMetadata().getPos();
74
    return mPosition;
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  private int getType(int variant)
80
    {
81
    for(int t=0; t<NUM_TYPES; t++)
82
      if( mTypeVariantMap[t]==variant ) return t;
83

    
84
    return -1;
85
    }
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private float[] figureOutCubitPos(int variant)
90
    {
91
    if( mIsNonStandard[variant] )
92
      {
93
      int numCubits = mPosition.length;
94

    
95
      for(int cubit = 0; cubit<numCubits; cubit++)
96
        if( mCubitVariantMap[cubit]==variant ) return mPosition[cubit];
97
      }
98
    else // see TwistyBandagedMegaminx
99
      {
100
      int type = getType(variant);
101
      if(getNumLayers()[0]==2) return type==0 ? CORNER2 : CENTER2;
102
      else return type==0 ? CORNER3 : type==1 ? CENTER3 : EDGE3;
103
      }
104

    
105
    return null;
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  private void produceTmpShape(int variant)
111
    {
112
    float[] pos = figureOutCubitPos(variant);
113
    FactoryBandagedSkewb factory = FactoryBandagedSkewb.getInstance();
114
    mTmpShapes[variant] = factory.createIrregularShape(variant,pos);
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  private float[][] getVertices(int variant)
120
    {
121
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
122
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
123
    return mTmpShapes[variant].getVertices();
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127
// PUBLIC API
128

    
129
  public TwistyBandagedSkewb(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
130
    {
131
    super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
132
    }
133

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

    
138
  public int[][] getScrambleEdges()
139
    {
140
    return null;
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  @Override
146
  public float[][] returnRotationFactor()
147
    {
148
    int numL = getNumLayers()[0];
149
    float[] f = new float[numL];
150
    for(int i=0; i<numL; i++) f[i] = 1.7f;
151
    return new float[][] { f,f,f,f };
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  @Override
157
  public int[][] getScrambleAlgorithms()
158
    {
159
    return null;
160
    }
161

    
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163

    
164
  @Override
165
  public int getScrambleType()
166
    {
167
    return ObjectScrambler.SCRAMBLING_BANDAGED;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  public ObjectShape getObjectShape(int variant)
173
    {
174
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
175
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
176
    return mTmpShapes[variant];
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

    
181
  public ObjectFaceShape getObjectFaceShape(int variant)
182
    {
183
    int type = getType(variant);
184
    FactoryBandagedSkewb factory = FactoryBandagedSkewb.getInstance();
185

    
186
    if( type>=0 )
187
      {
188
      int[] numLayers = getNumLayers();
189
      boolean iconMode = isInIconMode();
190
      float[][] bands = factory.getBands(iconMode,numLayers);
191
      int[] bandIndices = null;
192

    
193
      switch(type)
194
        {
195
        case COR: bandIndices = new int[] {0,0,0,1,1,1}; break;
196
        case CEN: bandIndices = new int[] {0,0,0,1,0}; break;
197
        case EDG: bandIndices = new int[] {0,0,1,1}; break;
198
        }
199

    
200
      return new ObjectFaceShape(bands,bandIndices,null);
201
      }
202

    
203
    return factory.createIrregularFaceShape(variant, isInIconMode() );
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  public ObjectVertexEffects getVertexEffects(int variant)
209
    {
210
    int[] numLayers = getNumLayers();
211
    int size = numLayers[0];
212
    boolean round = (DistortedLibrary.fastCompilationTF() && size<=5 && !isInIconMode());
213
    int type = getType(variant);
214

    
215
    if( type>=0 )
216
      {
217
      float[][] vertices = getVertices(variant);
218
      int numV = vertices.length;
219
      float S = type!=1 ? -0.05f : 0.00f;
220

    
221
      String name = EffectName.DEFORM.name();
222
      float[] reg = {0,0,0,0.15f};
223

    
224
      float[][] variables = new float[numV][];
225
      String[] names      = new String[numV];
226
      float[][] regions   = new float[numV][];
227
      boolean[] uses      = new boolean[numV];
228

    
229
      for(int i=0; i<numV; i++)
230
        {
231
        float[] v    = vertices[i];
232
        variables[i] = new float[] { 0, S*v[0], S*v[1], S*v[2], 1 };
233
        names[i]     = name;
234
        regions[i]   = reg;
235
        uses[i]      = round;
236
        }
237

    
238
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
239
      }
240

    
241
    FactoryBandagedSkewb factory = FactoryBandagedSkewb.getInstance();
242
    return factory.createVertexEffects(variant,round);
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  public Static4D getCubitQuats(int cubit, int[] numLayers)
248
    {
249
    float[] pos = mPosition[cubit];
250
    return pos.length>3 ? QUAT : FactoryBandagedSkewb.getInstance().getCubitQuat(pos[0],pos[1],pos[2]);
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
  private int translateVariant(int variant)
256
    {
257
    return variant==0 ? COR : variant==1 ? CEN : EDG;
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  public int getNumCubitVariants(int[] numLayers)
263
    {
264
    if( mNumVariants==0 )
265
      {
266
      float[][] positions = getPositions();
267
      boolean CO = false;
268
      boolean CE = false;
269
      boolean ED = false;
270

    
271
      int numCubits = positions.length;
272
      mCubitVariantMap = new int[numCubits];
273
      mIsNonStandard = new boolean[numCubits];   // mNumVariants <= numCubits
274
      mTypeVariantMap = new int[NUM_TYPES];
275
      for(int i=0; i<NUM_TYPES; i++) mTypeVariantMap[i] = -1;
276

    
277
      FactoryBandagedSkewb factory = FactoryBandagedSkewb.getInstance();
278

    
279
      for (int cubit=0; cubit<numCubits; cubit++)
280
        {
281
        int type = OTHER;
282
        float[] pos = positions[cubit];
283

    
284
        if( pos.length==3 )
285
          {
286
          int variant = factory.getElementVariant(numLayers, pos[0], pos[1], pos[2]);
287
          type = translateVariant(variant);
288
          }
289

    
290
        switch (type)
291
          {
292
          case COR : if (!CO) { CO = true; mTypeVariantMap[type]=mNumVariants++; }
293
                     mCubitVariantMap[cubit] = mTypeVariantMap[type];
294
                     break;
295
          case CEN : if (!CE) { CE = true; mTypeVariantMap[type]=mNumVariants++; }
296
                     mCubitVariantMap[cubit] = mTypeVariantMap[type];
297
                     break;
298
          case EDG : if (!ED) { ED = true; mTypeVariantMap[type]=mNumVariants++; }
299
                     mCubitVariantMap[cubit] = mTypeVariantMap[type];
300
                     break;
301
          default  : mIsNonStandard[mNumVariants] = true;
302
                     mCubitVariantMap[cubit] = mNumVariants++;
303
          }
304
        }
305

    
306
      factory.prepare(mNumVariants,numLayers);
307
      }
308

    
309
    return mNumVariants;
310
    }
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
  public float[][] getCubitPositions(int[] numLayers)
315
    {
316
    return getPositions();
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  public boolean[][] getLayerRotatable(int[] numLayers)
322
    {
323
    boolean[] tmp = numLayers[0]==2 ? (new boolean[] {true,true}) : (new boolean[] {true,false,true});
324
    return new boolean[][] {tmp,tmp,tmp,tmp};
325
    }
326

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

    
329
  public float[][] getCuts(int[] numLayers)
330
    {
331
    if( mCuts==null )
332
      {
333
      float[] c = numLayers[0]==2 ? (new float[] {0.0f}) : (new float[] {-SQ3/4, SQ3/4});
334
      mCuts = new float[][] {c,c,c,c};
335
      }
336

    
337
    return mCuts;
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  public Static3D[] getFaceAxis()
343
    {
344
    return TouchControlHexahedron.FACE_AXIS;
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  public Static3D[] getRotationAxis()
350
    {
351
    return ROT_AXIS;
352
    }
353

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

    
356
  public int[][][] getEnabled()
357
    {
358
    return new int[][][]
359
      {
360
       {{0,1},{3,1},{2,3},{0,2}},
361
       {{2,3},{3,1},{0,1},{0,2}},
362
       {{1,2},{0,1},{0,3},{2,3}},
363
       {{1,2},{2,3},{0,3},{0,1}},
364
       {{0,3},{0,2},{1,2},{1,3}},
365
       {{1,2},{0,2},{0,3},{1,3}},
366
      };
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public int getTouchControlType()
372
    {
373
    return TC_HEXAHEDRON;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  public int getTouchControlSplit()
379
    {
380
    return TYPE_SPLIT_CORNER;
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public int getCubitVariant(int cubit, int[] numLayers)
386
    {
387
    return mCubitVariantMap[cubit];
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public float[] getDist3D(int[] numLayers)
393
    {
394
    return TouchControlHexahedron.D3D;
395
    }
396

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

    
399
  public int[][] getBasicAngles()
400
    {
401
    if( mBasicAngle ==null )
402
      {
403
      int num = getNumLayers()[0];
404
      int[] tmp = new int[num];
405
      for(int i=0; i<num; i++) tmp[i] = 3;
406
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
407
      }
408

    
409
    return mBasicAngle;
410
    }
411

    
412
///////////////////////////////////////////////////////////////////////////////////////////////////
413

    
414
  public float getStickerRadius()
415
    {
416
    return 0.08f;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public float getStickerStroke()
422
    {
423
    float stroke = 0.08f;
424

    
425
    if( isInIconMode() )
426
      {
427
      int[] numLayers = getNumLayers();
428
      stroke *= (numLayers[0]==2 ? 1.5f : 2.0f);
429
      }
430

    
431
    return stroke;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  public float[][][] getStickerAngles()
437
    {
438
    return null;
439
    }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442

    
443
  public String getShortName()
444
    {
445
    if( mSignature==null ) mSignature = getSignature();
446
    int[] numLayers = getNumLayers();
447
    return MARKER+(numLayers[0]+"_"+mSignature.getString());
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  public ObjectSignature getSignature()
453
    {
454
    if( mSignature==null )
455
      {
456
      int[] numLayers = getNumLayers();
457
      mSignature = new ObjectSignatureSkewb(numLayers[0],mPosition);
458
      }
459
    return mSignature;
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  public String getObjectName()
465
    {
466
    return OBJECT_NAME_SKEWB;
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  public String getInventor()
472
    {
473
    return "??";
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public int getYearOfInvention()
479
    {
480
    return 0;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public float getComplexity()
486
    {
487
    return 4;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  public String[][] getTutorials()
493
    {
494
    return null;
495
    }
496
}
(7-7/59)