Project

General

Profile

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

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

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.touchcontrol.TouchControl.TC_TETRAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14

    
15
import org.distorted.library.effect.EffectName;
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.FactoryBandagedPyraminx;
20
import org.distorted.objectlib.helpers.ObjectFaceShape;
21
import org.distorted.objectlib.helpers.ObjectShape;
22
import org.distorted.objectlib.metadata.Metadata;
23
import org.distorted.objectlib.signature.ObjectSignature;
24
import org.distorted.objectlib.helpers.ObjectVertexEffects;
25
import org.distorted.objectlib.main.InitAssets;
26
import org.distorted.objectlib.scrambling.ObjectScrambler;
27
import org.distorted.objectlib.shape.ShapeTetrahedron;
28
import org.distorted.objectlib.signature.ObjectSignaturePyraminx;
29
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class TwistyBandagedPyraminx extends ShapeTetrahedron
34
{
35
  public static final String OBJECT_NAME_PYRAMINX = "LOCAL_PYRAMINX";
36
  public static final char MARKER = 'p'; // keep lowercase
37

    
38
  private 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 OCT_1 = 0;
47
  private static final int TET_1 = 1;
48
  private static final int OTHER = 2;
49

    
50
  private static final int NUM_TYPES = 2;  // OCT_1 and TET_1
51

    
52
  private int[] mCubitVariantMap;
53
  private int[] mTypeVariantMap;
54
  private ObjectShape[] mTmpShapes;
55
  private int mNumVariants;
56
  private float[][] mPosition;
57
  private ObjectSignature mSignature;
58
  private float[][] mCuts;
59
  private int[][] mBasicAngle;
60

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

    
63
  private float[][] getPositions()
64
    {
65
    if( mPosition==null ) mPosition = getMetadata().getPos();
66
    return mPosition;
67
    }
68

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

    
71
  private int getType(float[] pos, int numLayers)
72
    {
73
    if( pos.length>3 ) return OTHER;
74
    boolean octa = FactoryBandagedPyraminx.isOctahedron(numLayers,pos[1]);
75
    return octa ? OCT_1 : TET_1;
76
    }
77

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

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

    
85
    return -1;
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
  private void produceTmpShape(int variant)
91
    {
92
    float[][] positions = getPositions();
93
    int cubit,numCubits = positions.length;
94

    
95
    for(cubit=0; cubit<numCubits; cubit++)
96
      {
97
      if( mCubitVariantMap[cubit]==variant ) break;
98
      }
99

    
100
    if( cubit>=numCubits )
101
      {
102
      android.util.Log.e("D", "unknown variant: "+variant);
103
      }
104
    else
105
      {
106
      FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
107
      mTmpShapes[variant] = factory.createIrregularShape(variant,positions[cubit]);
108
      }
109
    }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
  private float[][] getVertices(int variant)
114
    {
115
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
116
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
117
    return mTmpShapes[variant].getVertices();
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121
// PUBLIC API
122

    
123
  public TwistyBandagedPyraminx(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
124
    {
125
    super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
126
    }
127

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

    
132
  public int[][] getScrambleEdges()
133
    {
134
    return null;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  @Override
140
  public float[][] returnRotationFactor()
141
    {
142
    int numL= getNumLayers()[0];
143
    float[][] factor = new float[4][numL];
144

    
145
    for(int ax=0; ax<4; ax++)
146
      for(int la=0; la<numL; la++) factor[ax][la] = ((float)numL)/(numL-la);
147

    
148
    return factor;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  @Override
154
  public int[][] getScrambleAlgorithms()
155
    {
156
    return null;
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  @Override
162
  public int getScrambleType()
163
    {
164
    return ObjectScrambler.SCRAMBLING_BANDAGED;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

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

    
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

    
178
  public ObjectFaceShape getObjectFaceShape(int variant)
179
    {
180
    int type = getType(variant);
181
    FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
182

    
183
    if( type>=0 )
184
      {
185
      int[] numLayers = getNumLayers();
186
      boolean iconMode = isInIconMode();
187
      float[][] bands = factory.getBands(iconMode,numLayers);
188
      int numFaces = type==TET_1 ? 4:8;
189
      int[] bandIndices= new int[numFaces];
190
      for(int i=0; i<numFaces; i++) bandIndices[i] = 1;
191
      return new ObjectFaceShape(bands,bandIndices,null);
192
      }
193

    
194
    return factory.createIrregularFaceShape(variant, isInIconMode() );
195
    }
196

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

    
199
  public ObjectVertexEffects getVertexEffects(int variant)
200
    {
201
    int[] numLayers = getNumLayers();
202
    int size = numLayers[0];
203
    boolean round = (DistortedLibrary.fastCompilationTF() && size<=5 && !isInIconMode());
204
    int type = getType(variant);
205

    
206
    if( type>=0 )
207
      {
208
      float[][] vertices = getVertices(variant);
209
      int numV = vertices.length;
210
      float S = -0.04f;
211

    
212
      String name = EffectName.DEFORM.name();
213
      float[] reg = {0,0,0,0.15f};
214

    
215
      float[][] variables = new float[numV][];
216
      String[] names      = new String[numV];
217
      float[][] regions   = new float[numV][];
218
      boolean[] uses      = new boolean[numV];
219

    
220
      for(int i=0; i<numV; i++)
221
        {
222
        float[] v    = vertices[i];
223
        variables[i] = new float[] { 0, S*v[0], S*v[1], S*v[2], 1 };
224
        names[i]     = name;
225
        regions[i]   = reg;
226
        uses[i]      = round;
227
        }
228

    
229
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
230
      }
231

    
232
    FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
233
    return factory.createVertexEffects(variant,round);
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  public Static4D getCubitQuats(int cubit, int[] numLayers)
239
    {
240
    return new Static4D(0,0,0,1);
241
    }
242

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

    
245
  public int getNumCubitVariants(int[] numLayers)
246
    {
247
    if( mNumVariants==0 )
248
      {
249
      float[][] positions = getPositions();
250
      boolean T1=false;
251
      boolean O1=false;
252

    
253
      int numCubits = positions.length;
254
      mCubitVariantMap = new int[numCubits];
255

    
256
      mTypeVariantMap = new int[NUM_TYPES];
257
      for(int i=0; i<NUM_TYPES; i++) mTypeVariantMap[i] = -1;
258

    
259
      for (int cubit=0; cubit<numCubits; cubit++)
260
        {
261
        int type = getType(positions[cubit],numLayers[0]);
262

    
263
        switch (type)
264
          {
265
          case TET_1: if (!T1) { T1 = true; mTypeVariantMap[TET_1]=mNumVariants++; }
266
                      mCubitVariantMap[cubit] = mTypeVariantMap[TET_1];
267
                      break;
268
          case OCT_1: if (!O1) { O1 = true; mTypeVariantMap[OCT_1]=mNumVariants++; }
269
                      mCubitVariantMap[cubit] = mTypeVariantMap[OCT_1];
270
                      break;
271
          default   : mCubitVariantMap[cubit] = mNumVariants++;
272
          }
273
        }
274

    
275
      FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
276
      factory.prepare(mNumVariants,numLayers);
277
      }
278

    
279
    return mNumVariants;
280
    }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
  public float[][] getCubitPositions(int[] numLayers)
285
    {
286
    return getPositions();
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  public boolean[][] getLayerRotatable(int[] numLayers)
292
    {
293
    int numAxis = ROT_AXIS.length;
294
    int size = numLayers[0];
295
    boolean[][] layerRotatable = new boolean[numAxis][size];
296

    
297
    for(int i=0; i<numAxis; i++)
298
      for(int j=0; j<size; j++) layerRotatable[i][j] = true;
299

    
300
    return layerRotatable;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  public float[][] getCuts(int[] numLayers)
306
    {
307
    if( mCuts==null )
308
      {
309
      int numL = numLayers[0];
310
      mCuts = new float[4][numL-1];
311

    
312
      for(int i=0; i<numL-1; i++)
313
        {
314
        float cut = (1.0f+i-numL/4.0f)*(SQ6/3);
315
        mCuts[0][i] = cut;
316
        mCuts[1][i] = cut;
317
        mCuts[2][i] = cut;
318
        mCuts[3][i] = cut;
319
        }
320
      }
321

    
322
    return mCuts;
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  public Static3D[] getFaceAxis()
328
    {
329
    return TouchControlTetrahedron.FACE_AXIS;
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  public Static3D[] getRotationAxis()
335
    {
336
    return ROT_AXIS;
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  public int[][][] getEnabled()
342
    {
343
    return new int[][][] { {{1,2,3}},{{0,2,3}},{{0,1,3}},{{0,1,2}} };
344
    }
345

    
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

    
348
  public int getTouchControlType()
349
    {
350
    return TC_TETRAHEDRON;
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  public int getTouchControlSplit()
356
    {
357
    return TYPE_NOT_SPLIT;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public int getCubitVariant(int cubit, int[] numLayers)
363
    {
364
    return mCubitVariantMap[cubit];
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  public float[] getDist3D(int[] numLayers)
370
    {
371
    return TouchControlTetrahedron.D3D;
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  public int[][] getBasicAngles()
377
    {
378
    if( mBasicAngle ==null )
379
      {
380
      int num = getNumLayers()[0];
381
      int[] tmp = new int[num];
382
      for(int i=0; i<num; i++) tmp[i] = 3;
383
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
384
      }
385

    
386
    return mBasicAngle;
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

    
391
  public float getStickerRadius()
392
    {
393
    return 0.10f;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  public float getStickerStroke()
399
    {
400
    return isInIconMode() ? 0.16f : 0.08f;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  public float[][][] getStickerAngles()
406
    {
407
    return null;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  public String getShortName()
413
    {
414
    if( mSignature==null ) mSignature = getSignature();
415
    int[] numLayers = getNumLayers();
416
    return MARKER+(numLayers[0]+"_"+mSignature.getString());
417
    }
418

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

    
421
  public ObjectSignature getSignature()
422
    {
423
    if( mSignature==null )
424
      {
425
      int[] numLayers = getNumLayers();
426
      mSignature = new ObjectSignaturePyraminx(numLayers[0],mPosition);
427
      }
428
    return mSignature;
429
    }
430

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

    
433
  public String getObjectName()
434
    {
435
    return OBJECT_NAME_PYRAMINX;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public String getInventor()
441
    {
442
    return "??";
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  public int getYearOfInvention()
448
    {
449
    return 0;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  public float getComplexity()
455
    {
456
    return 4;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public String[][] getTutorials()
462
    {
463
    return null;
464
    }
465
}
(6-6/59)