Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedCuboid.java @ 68823ce3

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[][]
229
          {
230
            { 36, 1,37, 2,38, 3,39, 4,40, 5,41, 6 },  // 0: beg
231
            {  6, 7, 7, 7, 8, 7, 9, 7,10, 7,11, 7 },  // 1: R before
232
            {  0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8 },  // 2: L before
233
            { 12, 9,13, 9,14, 9,15, 9,16, 9,17, 9 },  // 3: D before
234
            { 18,10,19,10,20,10,21,10,22,10,23,10 },  // 4: U before
235
            { 24,11,25,11,26,11,27,11,28,11,29,11 },  // 5: B before
236
            { 30,12,31,12,32,12,33,12,34,12,35,12 },  // 6: F before
237
            { 42, 3,43, 4,44, 5,45, 6 }, // 7: R after
238
            { 46, 3,47, 4,48, 5,49, 6 }, // 8: L after
239
            { 50, 1,51, 2,52, 5,53, 6 }, // 9: D after
240
            { 54, 1,55, 2,56, 5,57, 6 }, //10: U after
241
            { 58, 1,59, 2,60, 3,61, 4 }, //11: B after
242
            { 62, 1,63, 2,64, 3,65, 4 }, //12: F after
243
          };
244
        }
245

    
246
      return mEdges;
247
      }
248

    
249
    return null;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
// AI Cube is scrambled using algorithms
254

    
255
  @Override
256
  public int[][] getScrambleAlgorithms()
257
    {
258
    if( mPosition==null ) mPosition = getInitData().getPos();
259

    
260
    if( mPosition==POS_5 )
261
      {
262
      return new int[][]
263
          {
264
              { 0,0,-1 }, { 0,0, 1 }, { 0,0, 2 }, { 0,1,-1 }, { 0,1, 1 }, { 0,1, 2 },  //  0-5 : L
265
              { 0,2,-1 }, { 0,2, 1 }, { 0,2, 2 }, { 0,3,-1 }, { 0,3, 1 }, { 0,3, 2 },  //  6-11: R
266
              { 1,0,-1 }, { 1,0, 1 }, { 1,0, 2 }, { 1,1,-1 }, { 1,1, 1 }, { 1,1, 2 },  // 12-17: D
267
              { 1,2,-1 }, { 1,2, 1 }, { 1,2, 2 }, { 1,3,-1 }, { 1,3, 1 }, { 1,3, 2 },  // 18-23: U
268
              { 2,0,-1 }, { 2,0, 1 }, { 2,0, 2 }, { 2,1,-1 }, { 2,1, 1 }, { 2,1, 2 },  // 24-29: B
269
              { 2,2,-1 }, { 2,2, 1 }, { 2,2, 2 }, { 2,3,-1 }, { 2,3, 1 }, { 2,3, 2 },  // 30-35: F
270

    
271
              { 1,3,1, 2,0,2 },  // 36: BEG->R
272
              { 1,0,1, 2,0,2 },  // 37: BEG->L
273
              { 2,3,1, 0,3,2 },  // 38: BEG->D
274
              { 2,0,1, 0,3,2 },  // 39: BEG->U
275
              { 0,3,1, 1,3,2 },  // 40: BEG->B
276
              { 0,0,1, 1,3,2 },  // 41: BEG->F
277

    
278
              { 1,0,-1, 0,3,2, 2,0,-1 }, // 42: R->D
279
              { 1,3, 1, 0,3,2, 2,3, 1 }, // 43: R->U
280
              { 2,0, 1, 0,3,2, 1,0, 1 }, // 44: R->B
281
              { 2,3,-1, 0,3,2, 1,3,-1 }, // 45: R->F
282

    
283
              { 1,0,-1, 0,0,2, 2,3, 1 }, // 46: L->D
284
              { 1,3, 1, 0,0,2, 2,0,-1 }, // 47: L->U
285
              { 2,0, 1, 0,0,2, 1,3,-1 }, // 48: L->B
286
              { 2,3,-1, 0,0,2, 1,0, 1 }, // 49: L->F
287

    
288
              { 0,3,-1, 1,0,2, 2,0, 1 }, // 50: D->R
289
              { 0,0, 1, 1,0,2, 2,3,-1 }, // 51: D->L
290
              { 2,0,-1, 1,0,2, 0,3, 1 }, // 52: D->B
291
              { 2,3, 1, 1,0,2, 0,0,-1 }, // 53: D->F
292

    
293
              { 0,3,-1, 1,3,2, 2,3,-1 }, // 54: U->R
294
              { 0,0, 1, 1,3,2, 2,0, 1 }, // 55: U->L
295
              { 2,0,-1, 1,3,2, 0,0,-1 }, // 56: U->B
296
              { 2,3, 1, 1,3,2, 0,3, 1 }, // 57: U->F
297

    
298
              { 0,3, 1, 2,0,2, 1,0,-1 }, // 58: B->R
299
              { 0,0,-1, 2,0,2, 1,3, 1 }, // 59: B->L
300
              { 1,0, 1, 2,0,2, 0,3,-1 }, // 60: B->D
301
              { 1,3,-1, 2,0,2, 0,0, 1 }, // 61: B->U
302

    
303
              { 0,3, 1, 2,3,2, 1,3, 1 }, // 62: F->R
304
              { 0,0,-1, 2,3,2, 1,0,-1 }, // 63: F->L
305
              { 1,0, 1, 2,3,2, 0,0, 1 }, // 64: F->D
306
              { 1,3,-1, 2,3,2, 0,3,-1 }, // 65: F->U
307
          };
308
      }
309
    else
310
      {
311
      return super.getScrambleAlgorithms();
312
      }
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316
// AI Cube is scrambled using algorithms
317

    
318
  @Override
319
  public int getScrambleType()
320
    {
321
    if( mPosition==null ) mPosition = getInitData().getPos();
322

    
323
    return mPosition==POS_5 ? 0 : 2;
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
  private int getType(float[] pos)
329
    {
330
    switch(pos.length)
331
      {
332
      case  3: return CUBIT_111;
333
      case  6: return CUBIT_211;
334
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
335
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
336
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
337
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
338
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
339
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
340
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
341
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
342
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
343
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
344
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
345
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
346
      case 24: float x3 = pos[0];
347
               float y3 = pos[1];
348
               float z3 = pos[2];
349
               float x4=-10,y4=-10,z4=-10;
350
               int i;
351

    
352
               for(i=0; i<8; i++)
353
                 {
354
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
355
                   {
356
                   x4 = pos[3*i  ];
357
                   y4 = pos[3*i+1];
358
                   z4 = pos[3*i+2];
359
                   break;
360
                   }
361
                 }
362
               if( i==9 ) return CUBIT_OTH;
363

    
364
               float dX = x4-x3;
365
               float dY = y4-y3;
366
               float dZ = z4-z3;
367

    
368
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
369
                 {
370
                 for(i=0; i<8; i++)
371
                   {
372
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
373
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
374
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
375
                   }
376

    
377
                 return CUBIT_222;
378
                 }
379

    
380
      default: return CUBIT_OTH;
381
      }
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  private int getQuatIndex(int cubit)
387
    {
388
    float[][] positions = getPositions();
389
    int len = positions.length;
390

    
391
    if( cubit>=0 && cubit<len )
392
      {
393
      float[] pos = positions[cubit];
394
      int type = getType(pos);
395

    
396
      switch(type)
397
        {
398
        case CUBIT_222:
399
        case CUBIT_111: return 0;
400
        case CUBIT_211:
401
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
402
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
403
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
404
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
405
        }
406
      }
407

    
408
    return 0;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  private int[] getDim(int variant)
414
    {
415
    int type,numTypes = mDims.length;
416
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
417
    return type<numTypes ? mDims[type] : null;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  private void produceTmpShape(int variant)
423
    {
424
    float[][] positions = getPositions();
425
    int cubit,numCubits = positions.length;
426

    
427
    for(cubit=0; cubit<numCubits; cubit++)
428
      {
429
      if( mCubitVariantMap[cubit]==variant ) break;
430
      }
431

    
432
    if( cubit>=numCubits )
433
      {
434
      android.util.Log.e("D", "unknown variant: "+variant);
435
      }
436
    else
437
      {
438
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
439
      mTmpShapes[variant] = factory.createIrregularShape(variant,positions[cubit]);
440
      }
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444
// PUBLIC API
445

    
446
  public int getTouchControlType()
447
    {
448
    return TC_CUBOID;
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public ObjectShape getObjectShape(int variant)
454
    {
455
    if( getDim(variant)!=null )
456
      {
457
      int[][] indices =
458
        {
459
          {2,3,1,0},
460
          {7,6,4,5},
461
          {4,0,1,5},
462
          {7,3,2,6},
463
          {6,2,0,4},
464
          {3,7,5,1},
465
        };
466

    
467
      return new ObjectShape( getVertices(variant), indices);
468
      }
469

    
470
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
471
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
472
    return mTmpShapes[variant];
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  public ObjectFaceShape getObjectFaceShape(int variant)
478
    {
479
    int[] numLayers = getNumLayers();
480
    int size = (numLayers[0]+numLayers[1]+numLayers[2])/3;
481
    int[] dim = getDim(variant);
482

    
483
    if( dim!=null )
484
      {
485
      int X = dim[0];
486
      int Y = dim[1];
487
      int Z = dim[2];
488

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

    
492
      int maxXY = Math.max(X,Y);
493
      int maxXZ = Math.max(X,Z);
494
      int maxYZ = Math.max(Y,Z);
495

    
496
      int angle = 45;
497
      float R = 0.25f;
498
      float S = 0.50f;
499
      float N = size<=4 ? 5 : size<=5 ? 4 : 3;
500

    
501
      float[][] bands =
502
        {
503
          {height/maxYZ,angle,R,S,N,0,0},
504
          {height/maxXZ,angle,R,S,N,0,0},
505
          {height/maxXY,angle,R,S,N,0,0}
506
        };
507

    
508
      return new ObjectFaceShape(bands,bandIndices,null);
509
      }
510

    
511
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
512
    return factory.createIrregularFaceShape(variant, isInIconMode() );
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public ObjectVertexEffects getVertexEffects(int variant)
518
    {
519
    int[] numLayers = getNumLayers();
520
    int size = (numLayers[0]+numLayers[1]+numLayers[2])/3;
521
    boolean round = (DistortedLibrary.fastCompilationTF() && size<=5 && !isInIconMode());
522

    
523
    if( getDim(variant)!=null )
524
      {
525
      float[][] vertices = getVertices(variant);
526
      float strength = -0.04f;
527

    
528
      float[][] variables =
529
        {
530
          { 0, strength*vertices[0][0], strength*vertices[0][1], strength*vertices[0][2], 1  },
531
          { 0, strength*vertices[1][0], strength*vertices[1][1], strength*vertices[1][2], 1  },
532
          { 0, strength*vertices[2][0], strength*vertices[2][1], strength*vertices[2][2], 1  },
533
          { 0, strength*vertices[3][0], strength*vertices[3][1], strength*vertices[3][2], 1  },
534
          { 0, strength*vertices[4][0], strength*vertices[4][1], strength*vertices[4][2], 1  },
535
          { 0, strength*vertices[5][0], strength*vertices[5][1], strength*vertices[5][2], 1  },
536
          { 0, strength*vertices[6][0], strength*vertices[6][1], strength*vertices[6][2], 1  },
537
          { 0, strength*vertices[7][0], strength*vertices[7][1], strength*vertices[7][2], 1  },
538
        };
539

    
540
      String name = EffectName.DEFORM.name();
541
      float[] reg = {0,0,0,0.15f};
542

    
543
      String[] names = {name,name,name,name,name,name,name,name};
544
      float[][] regions = {reg,reg,reg,reg,reg,reg,reg,reg};
545
      boolean[] uses = {round,round,round,round,round,round,round,round};
546

    
547
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
548
      }
549

    
550
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
551
    return factory.createVertexEffects(variant,round);
552
    }
553

    
554
///////////////////////////////////////////////////////////////////////////////////////////////////
555

    
556
  public Static4D getCubitQuats(int cubit, int[] numLayers)
557
    {
558
    if( mInitQuats ==null )
559
      {
560
      mInitQuats = new Static4D[]
561
        {
562
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
563
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
564
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
565
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
566
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
567
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
568
        };
569
      }
570

    
571
    return mInitQuats[getQuatIndex(cubit)];
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  public int getNumCubitVariants(int[] numLayers)
577
    {
578
    if( mNumVariants==0 )
579
      {
580
      float[][] positions = getPositions();
581
      boolean C111=false;
582
      boolean C211=false;
583
      boolean C311=false;
584
      boolean C221=false;
585
      boolean C222=false;
586

    
587
      int numCubits = positions.length;
588
      mCubitVariantMap = new int[numCubits];
589

    
590
      int numTypes = mDims.length;
591
      mTypeVariantMap = new int[numTypes];
592
      for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
593

    
594
      for (int cubit=0; cubit<numCubits; cubit++)
595
        {
596
        int type = getType(positions[cubit]);
597

    
598
        switch (type)
599
          {
600
          case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=mNumVariants++; }
601
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
602
                          break;
603
          case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=mNumVariants++; }
604
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
605
                          break;
606
          case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=mNumVariants++; }
607
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
608
                          break;
609
          case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=mNumVariants++; }
610
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
611
                          break;
612
          case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=mNumVariants++; }
613
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
614
                          break;
615
          default       : mCubitVariantMap[cubit] = mNumVariants++;
616
          }
617
        }
618

    
619
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
620
      factory.prepare(mNumVariants,numLayers[0],numLayers[1],numLayers[2]);
621
      }
622

    
623
    return mNumVariants;
624
    }
625

    
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627

    
628
  public int getCubitVariant(int cubit, int[] numLayers)
629
    {
630
    return mCubitVariantMap[cubit];
631
    }
632

    
633
///////////////////////////////////////////////////////////////////////////////////////////////////
634

    
635
  private float[][] getVertices(int variant)
636
    {
637
    int[] dim = getDim(variant);
638

    
639
    if( dim!=null )
640
      {
641
      int X = dim[0];
642
      int Y = dim[1];
643
      int Z = dim[2];
644

    
645
      return new float[][]
646
        {
647
          { 0.5f*X, 0.5f*Y, 0.5f*Z},
648
          { 0.5f*X, 0.5f*Y,-0.5f*Z},
649
          { 0.5f*X,-0.5f*Y, 0.5f*Z},
650
          { 0.5f*X,-0.5f*Y,-0.5f*Z},
651
          {-0.5f*X, 0.5f*Y, 0.5f*Z},
652
          {-0.5f*X, 0.5f*Y,-0.5f*Z},
653
          {-0.5f*X,-0.5f*Y, 0.5f*Z},
654
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
655
        };
656
      }
657

    
658
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
659
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
660
    return mTmpShapes[variant].getVertices();
661
    }
662

    
663
///////////////////////////////////////////////////////////////////////////////////////////////////
664
// PUBLIC API
665

    
666
  public float[] getDist3D(int[] numLayers)
667
    {
668
    float x = numLayers[0];
669
    float y = numLayers[1];
670
    float z = numLayers[2];
671
    float a = (x+y+z)/1.5f;
672

    
673
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
674
    }
675

    
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677

    
678
  public float getStickerRadius()
679
    {
680
    return 0.10f;
681
    }
682

    
683
///////////////////////////////////////////////////////////////////////////////////////////////////
684

    
685
  public float getStickerStroke()
686
    {
687
    if( mPosition==null ) mPosition = getInitData().getPos();
688
    boolean icon = isInIconMode();
689

    
690
    if( mPosition==POS_5 ) return icon ? 0.30f : 0.11f;
691

    
692
    return icon ? 0.16f : 0.08f;
693
    }
694

    
695
///////////////////////////////////////////////////////////////////////////////////////////////////
696

    
697
  public String getShortName()
698
    {
699
    if( mPosition==null ) mPosition = getInitData().getPos();
700

    
701
    if( mPosition==POS_1 ) return ObjectType.BAN1_3.name();
702
    if( mPosition==POS_2 ) return ObjectType.BAN2_3.name();
703
    if( mPosition==POS_3 ) return ObjectType.BAN3_3.name();
704
    if( mPosition==POS_4 ) return ObjectType.BAN4_3.name();
705
    if( mPosition==POS_5 ) return ObjectType.BAN5_4.name();
706

    
707
    if( mSignature==null ) mSignature = getSignature();
708
    int[] numLayers = getNumLayers();
709
    int number = 100*numLayers[0]+10*numLayers[1]+numLayers[2];
710

    
711
    return number+"_"+mSignature.getString();
712
    }
713

    
714
///////////////////////////////////////////////////////////////////////////////////////////////////
715

    
716
  public ObjectSignature getSignature()
717
    {
718
    if( mSignature==null )
719
      {
720
      int[] numLayers = getNumLayers();
721
      mSignature = new ObjectSignature(numLayers[0],numLayers[1],numLayers[2],mPosition);
722
      }
723
    return mSignature;
724
    }
725

    
726
///////////////////////////////////////////////////////////////////////////////////////////////////
727

    
728
  public String getObjectName()
729
    {
730
    if( mPosition==null ) mPosition = getInitData().getPos();
731

    
732
    if( mPosition==POS_1 ) return "Fused Cube";
733
    if( mPosition==POS_2 ) return "2Bar Cube";
734
    if( mPosition==POS_3 ) return "Bandaged Cube C";
735
    if( mPosition==POS_4 ) return "BiCube";
736
    if( mPosition==POS_5 ) return "AI Cube";
737

    
738
    return OBJECT_NAME;
739
    }
740

    
741
///////////////////////////////////////////////////////////////////////////////////////////////////
742

    
743
  public String getInventor()
744
    {
745
    if( mPosition==null ) mPosition = getInitData().getPos();
746

    
747
    if( mPosition==POS_1 ) return "Ting Huang";
748
    if( mPosition==POS_2 ) return "Unknown";
749
    if( mPosition==POS_3 ) return "Andreas Nortmann";
750
    if( mPosition==POS_4 ) return "Uwe Meffert";
751
    if( mPosition==POS_5 ) return "David Adams";
752

    
753
    return "??";
754
    }
755

    
756
///////////////////////////////////////////////////////////////////////////////////////////////////
757

    
758
  public int getYearOfInvention()
759
    {
760
    if( mPosition==null ) mPosition = getInitData().getPos();
761

    
762
    if( mPosition==POS_1 ) return 2011;
763
    if( mPosition==POS_2 ) return 0;
764
    if( mPosition==POS_3 ) return 2005;
765
    if( mPosition==POS_4 ) return 1999;
766
    if( mPosition==POS_5 ) return 2004;
767

    
768
    return 0;
769
    }
770

    
771
///////////////////////////////////////////////////////////////////////////////////////////////////
772

    
773
  public int getComplexity()
774
    {
775
    if( mPosition==null ) mPosition = getInitData().getPos();
776

    
777
    if( mPosition==POS_1 ) return 1;
778
    if( mPosition==POS_2 ) return 2;
779
    if( mPosition==POS_3 ) return 2;
780
    if( mPosition==POS_4 ) return 3;
781
    if( mPosition==POS_5 ) return 4;
782

    
783
    return 4;
784
    }
785

    
786
///////////////////////////////////////////////////////////////////////////////////////////////////
787

    
788
  public String[][] getTutorials()
789
    {
790
    if( mPosition==null ) mPosition = getInitData().getPos();
791

    
792
    if( mPosition==POS_1 )
793
      {
794
      return new String[][]{
795
                            {"gb","F_iJk_IvpVo","Bandaged Cube","CanChrisSolve"},
796
                            {"es","_lTgw5aEFOg","Tutorial 3x3 Fuse Cube","QBAndo"},
797
                            {"ru","raYDwFEXIq4","Как собрать Fused Cube","Алексей Ярыгин"},
798
                            {"fr","9Cfi4rhKzIw","Tutoriel: résolution du Fused Cube","Skieur Cubb"},
799
                            {"pl","0PcUoGxQa6s","Bandaged 3x3 v.A cube","MrUK"},
800
                            {"kr","1RePOLrzJNE","밴디지 타입 A 해법","듀나메스 큐브 해법연구소"},
801
                            {"vn","vg4J0U0n1oA","Tutorial N.1 - Bandaged VA","Duy Thích Rubik"},
802
                           };
803
      }
804
    if( mPosition==POS_2 )
805
      {
806
      return new String[][]{
807
                            {"ru","lS_EK0PMWI8","Как собрать 2-bar Cube","Алексей Ярыгин"},
808
                            {"pl","tX8ubTLh6p8","Bandaged 3x3 (Two bar)","MrUK"},
809
                            {"kr","NE6XuC1r8xw","밴디지 큐브","Denzel Washington"},
810
                           };
811
      }
812
    if( mPosition==POS_3 )
813
      {
814
      return new String[][]{
815
                            {"gb","7UiCVGygUT4","Bandage Cube C Tutorial","PolyakB"},
816
                            {"ru","gXenRA92Wdc","Как собрать Bandaged 3x3 Type C","YG Cuber"},
817
                            {"pl","sKfdFLm79Zs","Bandaged 3x3 v.C cube","MrUK"},
818
                            {"kr","BcCFgeFy6Ec","밴디지 타입 C 해법","듀나메스 큐브 해법연구소"},
819
                            {"vn","9674LLkPSog","Tutorial N.2 - Bandaged VC","Duy Thích Rubik"},
820
                           };
821
      }
822
    if( mPosition==POS_4 )
823
      {
824
      return new String[][]{
825
                            {"gb","AnpdIKICBpM","Trying to Solve a Bandaged Cube","RedKB"},
826
                            {"es","cUyo5fycrvI","Tutorial Bandaged Cube en español","Rafa Garcia Benacazon"},
827
                            {"ru","-MTzeEJptsg","Как собрать bandaged Cube B","стратегия знаний"},
828
                            {"fr","3rsfIJ3roT0","Tutoriel: résolution du Bicube","Skieur Cubb"},
829
                            {"de","sqWVRwkXX9w","Bandaged Cube - Tutorial","GerCubing"},
830
                            {"pl","XcHzTvVR6Po","Bandaged 3x3 v.B cube","MrUK"},
831
                            {"kr","1gsoijF_5q0","BiCube Tutorial (해법)","듀나메스 큐브 해법연구소"},
832
                            {"vn","ZCJDaF4jEbc","Tutorial N.3 - BiCube","Duy Thích Rubik"},
833
                           };
834
      }
835
    if( mPosition==POS_5 )
836
      {
837
      return new String[][]{
838
                            {"gb","b62HPjlUmYQ","4x4x4 AI Bandaged Cube 1/2","Superantoniovivaldi"},
839
                            {"gb","DQeZ0iDqt4s","4x4x4 AI Bandaged Cube 2/2","Superantoniovivaldi"},
840
                            {"es","bZRV8aXyIY4","Tutorial AI Cube 4x4","QBAndo"},
841
                            {"ru","2NIEHu6jE9o","Как собрать AI Cube","Rodion Strizhakov"},
842
                            {"fr","iP9sSg1q0K0","Résolution de l'AI Cube","asthalis"},
843
                            {"pl","y6MNyoHgY8A","All Bandage 4x4 cube TUTORIAL","MrUK"},
844
                            {"br","yGnQ4ObiPRY","Como Resolver o 4x4 Bandaged 1/4","Rafael Cinoto"},
845
                            {"br","XJUtQrwrCmA","Como Resolver o 4x4 Bandaged 2/4","Rafael Cinoto"},
846
                            {"br","Wrdec2WNBSY","Como Resolver o 4x4 Bandaged 3/4","Rafael Cinoto"},
847
                            {"br","mWvYD53fqHI","Como Resolver o 4x4 Bandaged 4/4","Rafael Cinoto"},
848
                            {"kr","MvaFtrU4O_k","AI 밴디지 큐브 해법","듀나메스 큐브 해법연구소"},
849
                            {"vn","aAP1E567ADc","Tutorial N.78 - AI Cube","Duy Thích Rubik"},
850
                           };
851
      }
852

    
853
    return null;
854
    }
855
}
(3-3/41)