Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedPyraminx.java @ 5e1b47f8

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.helpers.ObjectSignature;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitAssets;
25
import org.distorted.objectlib.main.InitData;
26
import org.distorted.objectlib.scrambling.ObjectScrambler;
27
import org.distorted.objectlib.shape.ShapeTetrahedron;
28
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
public class TwistyBandagedPyraminx extends ShapeTetrahedron
33
{
34
  public static final String OBJECT_NAME_PYRAMINX = "LOCAL_PYRAMINX";
35

    
36
  private static final Static3D[] ROT_AXIS = new Static3D[]
37
        {
38
                new Static3D(     0,-SQ3/3,-SQ6/3),
39
                new Static3D(     0,-SQ3/3, SQ6/3),
40
                new Static3D( SQ6/3, SQ3/3,     0),
41
                new Static3D(-SQ6/3, SQ3/3,     0),
42
        };
43

    
44
  private static final int OCT_1 = 0;
45
  private static final int TET_1 = 1;
46
  private static final int OTHER = 2;
47

    
48
  private static final int NUM_TYPES = 2;  // OCT_1 and TET_1
49

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

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  private float[][] getPositions()
62
    {
63
    if( mPosition==null ) mPosition = getInitData().getPos();
64
    return mPosition;
65
    }
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

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

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

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

    
83
    return -1;
84
    }
85

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

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

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

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

    
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

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

    
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119
// PUBLIC API
120

    
121
  public TwistyBandagedPyraminx(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
122
    {
123
    super(meshState, iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
124
    }
125

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

    
130
  public int[][] getScrambleEdges()
131
    {
132
    return null;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

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

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

    
146
    return factor;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

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

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

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

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

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

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

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

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

    
192
    return factory.createIrregularFaceShape(variant, isInIconMode() );
193
    }
194

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

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

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

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

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

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

    
227
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
228
      }
229

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

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

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

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

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

    
251
      int numCubits = positions.length;
252
      mCubitVariantMap = new int[numCubits];
253

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

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

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

    
273
      FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
274
      factory.prepare(mNumVariants,numLayers);
275
      }
276

    
277
    return mNumVariants;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

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

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

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

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

    
298
    return layerRotatable;
299
    }
300

    
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

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

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

    
320
    return mCuts;
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

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

    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

    
332
  public Static3D[] getRotationAxis()
333
    {
334
    return ROT_AXIS;
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

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

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

    
346
  public int getTouchControlType()
347
    {
348
    return TC_TETRAHEDRON;
349
    }
350

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

    
353
  public int getTouchControlSplit()
354
    {
355
    return TYPE_NOT_SPLIT;
356
    }
357

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

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

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

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

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

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

    
384
    return mBasicAngle;
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  public float getStickerRadius()
390
    {
391
    return 0.10f;
392
    }
393

    
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395

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

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  public float[][][] getStickerAngles()
404
    {
405
    return null;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

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

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

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

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public String getObjectName()
432
    {
433
    return OBJECT_NAME_PYRAMINX;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public String getInventor()
439
    {
440
    return "??";
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  public int getYearOfInvention()
446
    {
447
    return 0;
448
    }
449

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

    
452
  public int getComplexity()
453
    {
454
    return 4;
455
    }
456

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

    
459
  public String[][] getTutorials()
460
    {
461
    return null;
462
    }
463
}
(5-5/49)