Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedCuboid.java @ 7d41fc84

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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_CUBOID;
13

    
14
import java.io.InputStream;
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

    
21
import org.distorted.objectlib.helpers.FactoryBandagedCubit;
22
import org.distorted.objectlib.helpers.ObjectFaceShape;
23
import org.distorted.objectlib.helpers.ObjectSignature;
24
import org.distorted.objectlib.helpers.ObjectVertexEffects;
25
import org.distorted.objectlib.main.InitData;
26
import org.distorted.objectlib.helpers.ObjectShape;
27
import org.distorted.objectlib.main.ObjectType;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
public class TwistyBandagedCuboid extends TwistyBandagedAbstract
32
{
33
  private static final String OBJECT_NAME = "LOCAL_BANDAGED";
34

    
35
  private static final int CUBIT_111 = 0;
36
  private static final int CUBIT_211 = 1;
37
  private static final int CUBIT_311 = 2;
38
  private static final int CUBIT_221 = 3;
39
  private static final int CUBIT_222 = 4;
40
  private static final int CUBIT_OTH = 5;
41

    
42
  private static final int[][] mDims = new int[][]
43
        {
44
         {1,1,1},  // has to be X>=Z>=Y so that all
45
         {2,1,1},  // the faces are horizontal
46
         {3,1,1},
47
         {2,1,2},
48
         {2,2,2},
49
        };
50

    
51
  // Fused Cube
52
  public static final float[][] POS_1 = new float[][]
53
        {
54
          {-1.0f, -1.0f, +0.0f, -1.0f, -1.0f, +1.0f, -1.0f,  0.0f, +0.0f, -1.0f,  0.0f, +1.0f,
55
            0.0f, -1.0f, +0.0f,  0.0f, -1.0f, +1.0f,  0.0f,  0.0f, +0.0f,  0.0f,  0.0f, +1.0f },
56
          {-1.0f, +1.0f, +1.0f},
57
          {-1.0f, +1.0f, +0.0f},
58
          {-1.0f, +1.0f, -1.0f},
59
          { 0.0f, +1.0f, +1.0f},
60
          { 0.0f, +1.0f, +0.0f},
61
          { 0.0f, +1.0f, -1.0f},
62
          { 1.0f, +1.0f, +1.0f},
63
          { 1.0f, +1.0f, +0.0f},
64
          { 1.0f, +1.0f, -1.0f},
65
          { 1.0f,  0.0f, +1.0f},
66
          { 1.0f,  0.0f, +0.0f},
67
          { 1.0f,  0.0f, -1.0f},
68
          { 1.0f, -1.0f, +1.0f},
69
          { 1.0f, -1.0f, +0.0f},
70
          { 1.0f, -1.0f, -1.0f},
71
          {-1.0f, -1.0f, -1.0f},
72
          {-1.0f,  0.0f, -1.0f},
73
          { 0.0f, -1.0f, -1.0f},
74
          { 0.0f,  0.0f, -1.0f}
75
        };
76

    
77
  // 2-bar cube
78
  public static final float[][] POS_2 = new float[][]
79
        {
80
          { 0.0f, +1.0f,  1.0f, 0.0f, +1.0f,  0.0f, 0.0f, +1.0f, -1.0f},
81
          {-1.0f, -1.0f,  0.0f, 0.0f, -1.0f,  0.0f, 1.0f, -1.0f,  0.0f},
82
          {-1.0f, +1.0f, +1.0f},
83
          {-1.0f, +1.0f,  0.0f},
84
          {-1.0f, +1.0f, -1.0f},
85
          {-1.0f,  0.0f, +1.0f},
86
          {-1.0f,  0.0f,  0.0f},
87
          {-1.0f,  0.0f, -1.0f},
88
          {-1.0f, -1.0f, +1.0f},
89
          {-1.0f, -1.0f, -1.0f},
90
          {+1.0f, +1.0f, +1.0f},
91
          {+1.0f, +1.0f,  0.0f},
92
          {+1.0f, +1.0f, -1.0f},
93
          {+1.0f,  0.0f, +1.0f},
94
          {+1.0f,  0.0f,  0.0f},
95
          {+1.0f,  0.0f, -1.0f},
96
          {+1.0f, -1.0f, +1.0f},
97
          {+1.0f, -1.0f, -1.0f},
98
          { 0.0f,  0.0f, +1.0f},
99
          { 0.0f, -1.0f, +1.0f},
100
          { 0.0f,  0.0f, -1.0f},
101
          { 0.0f, -1.0f, -1.0f}
102
        };
103

    
104
  // 3-plate cube
105
  public static final float[][] POS_3 = new float[][]
106
        {
107
          {-1.0f,  1.0f,  1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
108
          { 1.0f,  0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f,  0.0f},
109
          {-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  0.0f,  0.0f, -1.0f, -1.0f,  0.0f, -1.0f,  0.0f},
110
          { 1.0f,  1.0f,  1.0f},
111
          { 1.0f,  0.0f,  1.0f},
112
          { 1.0f, -1.0f,  1.0f},
113
          {-1.0f, -1.0f,  1.0f},
114
          { 0.0f, -1.0f,  1.0f},
115
          { 1.0f, -1.0f,  0.0f},
116
          { 1.0f, -1.0f, -1.0f},
117
          {-1.0f,  1.0f, -1.0f},
118
          {-1.0f,  1.0f,  0.0f},
119
          { 0.0f,  1.0f, -1.0f},
120
          { 0.0f,  1.0f,  0.0f},
121
          {-1.0f,  0.0f, -1.0f},
122
          {-1.0f,  0.0f,  0.0f},
123
          { 0.0f,  0.0f, -1.0f}
124
        };
125

    
126
  // BiCube
127
  public static final float[][] POS_4 = new float[][]
128
        {
129
          { 1.0f,  1.0f, -1.0f},
130
          {-1.0f, -1.0f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f},
131
          {-1.0f,  1.0f, -1.0f,  0.0f,  1.0f, -1.0f},
132
          {-1.0f,  0.0f, -1.0f,  0.0f,  0.0f, -1.0f},
133
          {-1.0f, -1.0f, -1.0f,  0.0f, -1.0f, -1.0f},
134
          {-1.0f,  1.0f,  0.0f, -1.0f,  1.0f,  1.0f},
135
          { 0.0f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f},
136
          { 1.0f,  1.0f,  0.0f,  1.0f,  1.0f,  1.0f},
137
          {-1.0f, -1.0f,  1.0f, -1.0f,  0.0f,  1.0f},
138
          { 0.0f, -1.0f,  1.0f,  0.0f,  0.0f,  1.0f},
139
          { 1.0f, -1.0f,  1.0f,  1.0f,  0.0f,  1.0f},
140
          { 1.0f, -1.0f,  0.0f,  1.0f,  0.0f,  0.0f},
141
          { 1.0f, -1.0f, -1.0f,  1.0f,  0.0f, -1.0f}
142
        };
143

    
144
  // AI Cube
145
  public static final float[][] POS_5 = new float[][]
146
        {
147
          {-1.5f,-1.5f, 1.5f, -0.5f,-1.5f, 1.5f, -1.5f,-0.5f, 1.5f, -0.5f,-0.5f, 1.5f,
148
           -1.5f,-1.5f, 0.5f, -0.5f,-1.5f, 0.5f, -1.5f,-0.5f, 0.5f, -0.5f,-0.5f, 0.5f, },
149
          { 1.5f, 1.5f, 1.5f,  0.5f, 1.5f, 1.5f,  1.5f, 0.5f, 1.5f,  0.5f, 0.5f, 1.5f,
150
            1.5f, 1.5f, 0.5f,  0.5f, 1.5f, 0.5f,  1.5f, 0.5f, 0.5f,  0.5f, 0.5f, 0.5f, },
151
          {-1.5f, 1.5f,-1.5f, -0.5f, 1.5f,-1.5f, -1.5f, 0.5f,-1.5f, -0.5f, 0.5f,-1.5f,
152
           -1.5f, 1.5f,-0.5f, -0.5f, 1.5f,-0.5f, -1.5f, 0.5f,-0.5f, -0.5f, 0.5f,-0.5f, },
153
          { 1.5f,-1.5f,-1.5f,  0.5f,-1.5f,-1.5f,  1.5f,-0.5f,-1.5f,  0.5f,-0.5f,-1.5f,
154
            1.5f,-1.5f,-0.5f,  0.5f,-1.5f,-0.5f,  1.5f,-0.5f,-0.5f,  0.5f,-0.5f,-0.5f, },
155

    
156
          {-1.5f, 1.5f, 1.5f },
157
          {-1.5f, 1.5f, 0.5f },
158
          {-1.5f, 0.5f, 1.5f },
159
          {-1.5f, 0.5f, 0.5f },
160
          {-0.5f, 1.5f, 1.5f },
161
          {-0.5f, 1.5f, 0.5f },
162
          {-0.5f, 0.5f, 1.5f },
163

    
164
          { 1.5f,-1.5f, 1.5f },
165
          { 1.5f,-1.5f, 0.5f },
166
          { 1.5f,-0.5f, 1.5f },
167
          { 1.5f,-0.5f, 0.5f },
168
          { 0.5f,-1.5f, 1.5f },
169
          { 0.5f,-1.5f, 0.5f },
170
          { 0.5f,-0.5f, 1.5f },
171

    
172
          { 1.5f, 1.5f,-1.5f },
173
          { 1.5f, 1.5f,-0.5f },
174
          { 1.5f, 0.5f,-1.5f },
175
          { 1.5f, 0.5f,-0.5f },
176
          { 0.5f, 1.5f,-1.5f },
177
          { 0.5f, 1.5f,-0.5f },
178
          { 0.5f, 0.5f,-1.5f },
179

    
180
          {-1.5f,-1.5f,-1.5f },
181
          {-1.5f,-1.5f,-0.5f },
182
          {-1.5f,-0.5f,-1.5f },
183
          {-1.5f,-0.5f,-0.5f },
184
          {-0.5f,-1.5f,-1.5f },
185
          {-0.5f,-1.5f,-0.5f },
186
          {-0.5f,-0.5f,-1.5f },
187
        };
188

    
189
  private int[][] mEdges;
190
  private int[] mCubitVariantMap;
191
  private int[] mTypeVariantMap;
192
  private Static4D[] mInitQuats;
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  public static int getType(String shortName, String longName)
197
    {
198
    if( shortName.equals(ObjectType.BAN1_3.name()) ||
199
        shortName.equals(ObjectType.BAN2_3.name()) ||
200
        shortName.equals(ObjectType.BAN3_3.name()) ||
201
        shortName.equals(ObjectType.BAN4_3.name())  ) return 2;
202

    
203
    if( longName.equals(OBJECT_NAME) ) return 1;
204

    
205
    return 0;
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  public TwistyBandagedCuboid(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
211
    {
212
    super(data, meshState, iconMode, (data.getNumLayers()[0]+data.getNumLayers()[1]+data.getNumLayers()[2])/3.0f, quat, move, scale, stream);
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216
// Computing scramble states of many a bandaged cubes takes way too long time and too much space.
217
// Return null here and turn to construction of scramble tables just-in-time (scrambleType=2)
218
// Unless this is AI Cube :)
219

    
220
  public int[][] getScrambleEdges()
221
    {
222
    if( mPosition==null ) mPosition = getInitData().getPos();
223

    
224
    if( mPosition==POS_5 )
225
      {
226
      if( mEdges==null )
227
        {
228
        mEdges = new int[][] { {0,0,1,0} };
229
        }
230

    
231
      return mEdges;
232
      }
233

    
234
    return null;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
// AI Cube is scrambled using algorithms
239

    
240
  @Override
241
  public int[][] getScrambleAlgorithms()
242
    {
243
    if( mPosition==null ) mPosition = getInitData().getPos();
244

    
245
    if( mPosition==POS_5 )
246
      {
247
      return new int[][]
248
          {
249
              { 0,0,1,1,0,1 },
250
              { 2,0,2 }
251
          };
252
      }
253
    else
254
      {
255
      return super.getScrambleAlgorithms();
256
      }
257
    }
258

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260
// AI Cube is scrambled using algorithms
261

    
262
  @Override
263
  public int getScrambleType()
264
    {
265
    if( mPosition==null ) mPosition = getInitData().getPos();
266

    
267
    return mPosition==POS_5 ? 0 : 2;
268
    }
269

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

    
272
  private int getType(float[] pos)
273
    {
274
    switch(pos.length)
275
      {
276
      case  3: return CUBIT_111;
277
      case  6: return CUBIT_211;
278
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
279
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
280
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
281
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
282
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
283
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
284
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
285
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
286
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
287
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
288
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
289
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
290
      case 24: float x3 = pos[0];
291
               float y3 = pos[1];
292
               float z3 = pos[2];
293
               float x4=-10,y4=-10,z4=-10;
294
               int i;
295

    
296
               for(i=0; i<8; i++)
297
                 {
298
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
299
                   {
300
                   x4 = pos[3*i  ];
301
                   y4 = pos[3*i+1];
302
                   z4 = pos[3*i+2];
303
                   break;
304
                   }
305
                 }
306
               if( i==9 ) return CUBIT_OTH;
307

    
308
               float dX = x4-x3;
309
               float dY = y4-y3;
310
               float dZ = z4-z3;
311

    
312
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
313
                 {
314
                 for(i=0; i<8; i++)
315
                   {
316
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
317
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
318
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
319
                   }
320

    
321
                 return CUBIT_222;
322
                 }
323

    
324
      default: return CUBIT_OTH;
325
      }
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  private int getQuatIndex(int cubit)
331
    {
332
    float[][] positions = getPositions();
333
    int len = positions.length;
334

    
335
    if( cubit>=0 && cubit<len )
336
      {
337
      float[] pos = positions[cubit];
338
      int type = getType(pos);
339

    
340
      switch(type)
341
        {
342
        case CUBIT_222:
343
        case CUBIT_111: return 0;
344
        case CUBIT_211:
345
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
346
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
347
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
348
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
349
        }
350
      }
351

    
352
    return 0;
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356

    
357
  private int[] getDim(int variant)
358
    {
359
    int type,numTypes = mDims.length;
360
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
361
    return type<numTypes ? mDims[type] : null;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  private void produceTmpShape(int variant)
367
    {
368
    float[][] positions = getPositions();
369
    int cubit,numCubits = positions.length;
370

    
371
    for(cubit=0; cubit<numCubits; cubit++)
372
      {
373
      if( mCubitVariantMap[cubit]==variant ) break;
374
      }
375

    
376
    if( cubit>=numCubits )
377
      {
378
      android.util.Log.e("D", "unknown variant: "+variant);
379
      }
380
    else
381
      {
382
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
383
      mTmpShapes[variant] = factory.createIrregularShape(variant,positions[cubit]);
384
      }
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388
// PUBLIC API
389

    
390
  public int getTouchControlType()
391
    {
392
    return TC_CUBOID;
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  public ObjectShape getObjectShape(int variant)
398
    {
399
    if( getDim(variant)!=null )
400
      {
401
      int[][] indices =
402
        {
403
          {2,3,1,0},
404
          {7,6,4,5},
405
          {4,0,1,5},
406
          {7,3,2,6},
407
          {6,2,0,4},
408
          {3,7,5,1},
409
        };
410

    
411
      return new ObjectShape( getVertices(variant), indices);
412
      }
413

    
414
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
415
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
416
    return mTmpShapes[variant];
417
    }
418

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

    
421
  public ObjectFaceShape getObjectFaceShape(int variant)
422
    {
423
    int[] numLayers = getNumLayers();
424
    int size = (numLayers[0]+numLayers[1]+numLayers[2])/3;
425
    int[] dim = getDim(variant);
426

    
427
    if( dim!=null )
428
      {
429
      int X = dim[0];
430
      int Y = dim[1];
431
      int Z = dim[2];
432

    
433
      float height     = isInIconMode() ? 0.001f : size<=5 ? 0.048f : 0.020f;
434
      int[] bandIndices= { 0,0,1,1,2,2 };
435

    
436
      int maxXY = Math.max(X,Y);
437
      int maxXZ = Math.max(X,Z);
438
      int maxYZ = Math.max(Y,Z);
439

    
440
      int angle = 45;
441
      float R = 0.25f;
442
      float S = 0.50f;
443
      float N = size<=4 ? 5 : size<=5 ? 4 : 3;
444

    
445
      float[][] bands =
446
        {
447
          {height/maxYZ,angle,R,S,N,0,0},
448
          {height/maxXZ,angle,R,S,N,0,0},
449
          {height/maxXY,angle,R,S,N,0,0}
450
        };
451

    
452
      return new ObjectFaceShape(bands,bandIndices,null);
453
      }
454

    
455
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
456
    return factory.createIrregularFaceShape(variant, isInIconMode() );
457
    }
458

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

    
461
  public ObjectVertexEffects getVertexEffects(int variant)
462
    {
463
    int[] numLayers = getNumLayers();
464
    int size = (numLayers[0]+numLayers[1]+numLayers[2])/3;
465
    boolean round = (DistortedLibrary.fastCompilationTF() && size<=5 && !isInIconMode());
466

    
467
    if( getDim(variant)!=null )
468
      {
469
      float[][] vertices = getVertices(variant);
470
      float strength = -0.04f;
471

    
472
      float[][] variables =
473
        {
474
          { 0, strength*vertices[0][0], strength*vertices[0][1], strength*vertices[0][2], 1  },
475
          { 0, strength*vertices[1][0], strength*vertices[1][1], strength*vertices[1][2], 1  },
476
          { 0, strength*vertices[2][0], strength*vertices[2][1], strength*vertices[2][2], 1  },
477
          { 0, strength*vertices[3][0], strength*vertices[3][1], strength*vertices[3][2], 1  },
478
          { 0, strength*vertices[4][0], strength*vertices[4][1], strength*vertices[4][2], 1  },
479
          { 0, strength*vertices[5][0], strength*vertices[5][1], strength*vertices[5][2], 1  },
480
          { 0, strength*vertices[6][0], strength*vertices[6][1], strength*vertices[6][2], 1  },
481
          { 0, strength*vertices[7][0], strength*vertices[7][1], strength*vertices[7][2], 1  },
482
        };
483

    
484
      String name = EffectName.DEFORM.name();
485
      float[] reg = {0,0,0,0.15f};
486

    
487
      String[] names = {name,name,name,name,name,name,name,name};
488
      float[][] regions = {reg,reg,reg,reg,reg,reg,reg,reg};
489
      boolean[] uses = {round,round,round,round,round,round,round,round};
490

    
491
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
492
      }
493

    
494
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
495
    return factory.createVertexEffects(variant,round);
496
    }
497

    
498
///////////////////////////////////////////////////////////////////////////////////////////////////
499

    
500
  public Static4D getCubitQuats(int cubit, int[] numLayers)
501
    {
502
    if( mInitQuats ==null )
503
      {
504
      mInitQuats = new Static4D[]
505
        {
506
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
507
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
508
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
509
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
510
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
511
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
512
        };
513
      }
514

    
515
    return mInitQuats[getQuatIndex(cubit)];
516
    }
517

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519

    
520
  public int getNumCubitVariants(int[] numLayers)
521
    {
522
    if( mNumVariants==0 )
523
      {
524
      float[][] positions = getPositions();
525
      boolean C111=false;
526
      boolean C211=false;
527
      boolean C311=false;
528
      boolean C221=false;
529
      boolean C222=false;
530

    
531
      int numCubits = positions.length;
532
      mCubitVariantMap = new int[numCubits];
533

    
534
      int numTypes = mDims.length;
535
      mTypeVariantMap = new int[numTypes];
536
      for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
537

    
538
      for (int cubit=0; cubit<numCubits; cubit++)
539
        {
540
        int type = getType(positions[cubit]);
541

    
542
        switch (type)
543
          {
544
          case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=mNumVariants++; }
545
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
546
                          break;
547
          case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=mNumVariants++; }
548
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
549
                          break;
550
          case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=mNumVariants++; }
551
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
552
                          break;
553
          case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=mNumVariants++; }
554
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
555
                          break;
556
          case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=mNumVariants++; }
557
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
558
                          break;
559
          default       : mCubitVariantMap[cubit] = mNumVariants++;
560
          }
561
        }
562

    
563
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
564
      factory.prepare(mNumVariants,numLayers[0],numLayers[1],numLayers[2]);
565
      }
566

    
567
    return mNumVariants;
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

    
572
  public int getCubitVariant(int cubit, int[] numLayers)
573
    {
574
    return mCubitVariantMap[cubit];
575
    }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
  private float[][] getVertices(int variant)
580
    {
581
    int[] dim = getDim(variant);
582

    
583
    if( dim!=null )
584
      {
585
      int X = dim[0];
586
      int Y = dim[1];
587
      int Z = dim[2];
588

    
589
      return new float[][]
590
        {
591
          { 0.5f*X, 0.5f*Y, 0.5f*Z},
592
          { 0.5f*X, 0.5f*Y,-0.5f*Z},
593
          { 0.5f*X,-0.5f*Y, 0.5f*Z},
594
          { 0.5f*X,-0.5f*Y,-0.5f*Z},
595
          {-0.5f*X, 0.5f*Y, 0.5f*Z},
596
          {-0.5f*X, 0.5f*Y,-0.5f*Z},
597
          {-0.5f*X,-0.5f*Y, 0.5f*Z},
598
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
599
        };
600
      }
601

    
602
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
603
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
604
    return mTmpShapes[variant].getVertices();
605
    }
606

    
607
///////////////////////////////////////////////////////////////////////////////////////////////////
608
// PUBLIC API
609

    
610
  public float[] getDist3D(int[] numLayers)
611
    {
612
    float x = numLayers[0];
613
    float y = numLayers[1];
614
    float z = numLayers[2];
615
    float a = (x+y+z)/1.5f;
616

    
617
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
618
    }
619

    
620
///////////////////////////////////////////////////////////////////////////////////////////////////
621

    
622
  public float getStickerRadius()
623
    {
624
    return 0.10f;
625
    }
626

    
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628

    
629
  public float getStickerStroke()
630
    {
631
    return isInIconMode() ? 0.16f : 0.08f;
632
    }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
  public String getShortName()
637
    {
638
    if( mPosition==null ) mPosition = getInitData().getPos();
639

    
640
    if( mPosition==POS_1 ) return ObjectType.BAN1_3.name();
641
    if( mPosition==POS_2 ) return ObjectType.BAN2_3.name();
642
    if( mPosition==POS_3 ) return ObjectType.BAN3_3.name();
643
    if( mPosition==POS_4 ) return ObjectType.BAN4_3.name();
644

    
645
    if( mSignature==null ) mSignature = getSignature();
646
    int[] numLayers = getNumLayers();
647
    int number = 100*numLayers[0]+10*numLayers[1]+numLayers[2];
648

    
649
    return number+"_"+mSignature.getString();
650
    }
651

    
652
///////////////////////////////////////////////////////////////////////////////////////////////////
653

    
654
  public ObjectSignature getSignature()
655
    {
656
    if( mSignature==null )
657
      {
658
      int[] numLayers = getNumLayers();
659
      mSignature = new ObjectSignature(numLayers[0],numLayers[1],numLayers[2],mPosition);
660
      }
661
    return mSignature;
662
    }
663

    
664
///////////////////////////////////////////////////////////////////////////////////////////////////
665

    
666
  public String getObjectName()
667
    {
668
    if( mPosition==null ) mPosition = getInitData().getPos();
669

    
670
    if( mPosition==POS_1 ) return "Fused Cube";
671
    if( mPosition==POS_2 ) return "2Bar Cube";
672
    if( mPosition==POS_3 ) return "Bandaged Cube C";
673
    if( mPosition==POS_4 ) return "BiCube";
674

    
675
    return OBJECT_NAME;
676
    }
677

    
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679

    
680
  public String getInventor()
681
    {
682
    if( mPosition==null ) mPosition = getInitData().getPos();
683

    
684
    if( mPosition==POS_1 ) return "Ting Huang";
685
    if( mPosition==POS_2 ) return "Unknown";
686
    if( mPosition==POS_3 ) return "Andreas Nortmann";
687
    if( mPosition==POS_4 ) return "Uwe Meffert";
688

    
689
    return "??";
690
    }
691

    
692
///////////////////////////////////////////////////////////////////////////////////////////////////
693

    
694
  public int getYearOfInvention()
695
    {
696
    if( mPosition==null ) mPosition = getInitData().getPos();
697

    
698
    if( mPosition==POS_1 ) return 2011;
699
    if( mPosition==POS_2 ) return 0;
700
    if( mPosition==POS_3 ) return 2005;
701
    if( mPosition==POS_4 ) return 1999;
702

    
703
    return 0;
704
    }
705

    
706
///////////////////////////////////////////////////////////////////////////////////////////////////
707

    
708
  public int getComplexity()
709
    {
710
    if( mPosition==null ) mPosition = getInitData().getPos();
711

    
712
    if( mPosition==POS_1 ) return 1;
713
    if( mPosition==POS_2 ) return 2;
714
    if( mPosition==POS_3 ) return 2;
715
    if( mPosition==POS_4 ) return 3;
716

    
717
    return 4;
718
    }
719

    
720
///////////////////////////////////////////////////////////////////////////////////////////////////
721

    
722
  public String[][] getTutorials()
723
    {
724
    if( mPosition==null ) mPosition = getInitData().getPos();
725

    
726
    if( mPosition==POS_1 )
727
      {
728
      return new String[][]{
729
                            {"gb","F_iJk_IvpVo","Bandaged Cube","CanChrisSolve"},
730
                            {"es","_lTgw5aEFOg","Tutorial 3x3 Fuse Cube","QBAndo"},
731
                            {"ru","raYDwFEXIq4","Как собрать Fused Cube","Алексей Ярыгин"},
732
                            {"fr","9Cfi4rhKzIw","Tutoriel: résolution du Fused Cube","Skieur Cubb"},
733
                            {"pl","0PcUoGxQa6s","Bandaged 3x3 v.A cube","MrUK"},
734
                            {"kr","1RePOLrzJNE","밴디지 타입 A 해법","듀나메스 큐브 해법연구소"},
735
                            {"vn","vg4J0U0n1oA","Tutorial N.1 - Bandaged VA","Duy Thích Rubik"},
736
                           };
737
      }
738
    if( mPosition==POS_2 )
739
      {
740
      return new String[][]{
741
                            {"ru","lS_EK0PMWI8","Как собрать 2-bar Cube","Алексей Ярыгин"},
742
                            {"pl","tX8ubTLh6p8","Bandaged 3x3 (Two bar)","MrUK"},
743
                            {"kr","NE6XuC1r8xw","밴디지 큐브","Denzel Washington"},
744
                           };
745
      }
746
    if( mPosition==POS_3 )
747
      {
748
      return new String[][]{
749
                            {"gb","7UiCVGygUT4","Bandage Cube C Tutorial","PolyakB"},
750
                            {"ru","gXenRA92Wdc","Как собрать Bandaged 3x3 Type C","YG Cuber"},
751
                            {"pl","sKfdFLm79Zs","Bandaged 3x3 v.C cube","MrUK"},
752
                            {"kr","BcCFgeFy6Ec","밴디지 타입 C 해법","듀나메스 큐브 해법연구소"},
753
                            {"vn","9674LLkPSog","Tutorial N.2 - Bandaged VC","Duy Thích Rubik"},
754
                           };
755
      }
756
    if( mPosition==POS_4 )
757
      {
758
      return new String[][]{
759
                            {"gb","AnpdIKICBpM","Trying to Solve a Bandaged Cube","RedKB"},
760
                            {"es","cUyo5fycrvI","Tutorial Bandaged Cube en español","Rafa Garcia Benacazon"},
761
                            {"ru","-MTzeEJptsg","Как собрать bandaged Cube B","стратегия знаний"},
762
                            {"fr","3rsfIJ3roT0","Tutoriel: résolution du Bicube","Skieur Cubb"},
763
                            {"de","sqWVRwkXX9w","Bandaged Cube - Tutorial","GerCubing"},
764
                            {"pl","XcHzTvVR6Po","Bandaged 3x3 v.B cube","MrUK"},
765
                            {"kr","1gsoijF_5q0","BiCube Tutorial (해법)","듀나메스 큐브 해법연구소"},
766
                            {"vn","ZCJDaF4jEbc","Tutorial N.3 - BiCube","Duy Thích Rubik"},
767
                           };
768
      }
769

    
770
    return null;
771
    }
772
}
(3-3/41)