Project

General

Profile

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

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

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_CHANGING_MIRROR;
13

    
14
import org.distorted.library.effect.EffectName;
15
import org.distorted.library.main.DistortedLibrary;
16
import org.distorted.library.type.Static3D;
17
import org.distorted.library.type.Static4D;
18

    
19
import org.distorted.objectlib.bandaged.FactoryBandagedCuboid;
20
import org.distorted.objectlib.helpers.ObjectFaceShape;
21
import org.distorted.objectlib.metadata.Metadata;
22
import org.distorted.objectlib.signature.ObjectSignature;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitAssets;
25
import org.distorted.objectlib.helpers.ObjectShape;
26
import org.distorted.objectlib.metadata.ListObjects;
27
import org.distorted.objectlib.scrambling.ObjectScrambler;
28
import org.distorted.objectlib.signature.ObjectSignatureCuboid;
29

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

    
32
public class TwistyBandagedCuboid extends TwistyBandagedAbstract
33
{
34
  public static final String OBJECT_NAME_CUBOID = "LOCAL_BANDAGED";
35

    
36
  public static final float STRENGTH = 0.04f;
37
  public static final float REGION_SIZE = 0.15f;
38

    
39
  private static final int CUBIT_111 = 0;
40
  private static final int CUBIT_211 = 1;
41
  private static final int CUBIT_311 = 2;
42
  private static final int CUBIT_221 = 3;
43
  private static final int CUBIT_222 = 4;
44
  private static final int CUBIT_OTH = 5;
45

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

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

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

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

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

    
148
  // AI Cube
149
  public static final float[][] POS_5 = new float[][]
150
        {
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
          {-1.5f, 1.5f,-1.5f, -0.5f, 1.5f,-1.5f, -1.5f, 0.5f,-1.5f, -0.5f, 0.5f,-1.5f,
156
           -1.5f, 1.5f,-0.5f, -0.5f, 1.5f,-0.5f, -1.5f, 0.5f,-0.5f, -0.5f, 0.5f,-0.5f, },
157
          { 1.5f,-1.5f,-1.5f,  0.5f,-1.5f,-1.5f,  1.5f,-0.5f,-1.5f,  0.5f,-0.5f,-1.5f,
158
            1.5f,-1.5f,-0.5f,  0.5f,-1.5f,-0.5f,  1.5f,-0.5f,-0.5f,  0.5f,-0.5f,-0.5f, },
159

    
160
          {-1.5f, 1.5f, 1.5f },
161
          {-1.5f, 1.5f, 0.5f },
162
          {-1.5f, 0.5f, 1.5f },
163
          {-1.5f, 0.5f, 0.5f },
164
          {-0.5f, 1.5f, 1.5f },
165
          {-0.5f, 1.5f, 0.5f },
166
          {-0.5f, 0.5f, 1.5f },
167

    
168
          { 1.5f,-1.5f, 1.5f },
169
          { 1.5f,-1.5f, 0.5f },
170
          { 1.5f,-0.5f, 1.5f },
171
          { 1.5f,-0.5f, 0.5f },
172
          { 0.5f,-1.5f, 1.5f },
173
          { 0.5f,-1.5f, 0.5f },
174
          { 0.5f,-0.5f, 1.5f },
175

    
176
          { 1.5f, 1.5f,-1.5f },
177
          { 1.5f, 1.5f,-0.5f },
178
          { 1.5f, 0.5f,-1.5f },
179
          { 1.5f, 0.5f,-0.5f },
180
          { 0.5f, 1.5f,-1.5f },
181
          { 0.5f, 1.5f,-0.5f },
182
          { 0.5f, 0.5f,-1.5f },
183

    
184
          {-1.5f,-1.5f,-1.5f },
185
          {-1.5f,-1.5f,-0.5f },
186
          {-1.5f,-0.5f,-1.5f },
187
          {-1.5f,-0.5f,-0.5f },
188
          {-0.5f,-1.5f,-1.5f },
189
          {-0.5f,-1.5f,-0.5f },
190
          {-0.5f,-0.5f,-1.5f },
191
        };
192

    
193
  // Burr Cube
194
  public static final float[][] POS_6 = new float[][]
195
        {
196
          {-1.5f, 1.5f, 1.5f,-0.5f, 1.5f, 1.5f},
197
          { 1.5f, 1.5f, 1.5f, 0.5f, 1.5f, 1.5f},
198
          {-0.5f, 0.5f, 1.5f, 0.5f, 0.5f, 1.5f},
199
          {-1.5f,-0.5f, 1.5f,-0.5f,-0.5f, 1.5f},
200
          { 1.5f,-0.5f, 1.5f, 0.5f,-0.5f, 1.5f},
201
          {-0.5f,-1.5f, 1.5f, 0.5f,-1.5f, 1.5f},
202

    
203
          {-1.5f, 1.5f,-1.5f,-0.5f, 1.5f,-1.5f},
204
          { 1.5f, 1.5f,-1.5f, 0.5f, 1.5f,-1.5f},
205
          {-0.5f, 0.5f,-1.5f, 0.5f, 0.5f,-1.5f},
206
          {-1.5f,-0.5f,-1.5f,-0.5f,-0.5f,-1.5f},
207
          { 1.5f,-0.5f,-1.5f, 0.5f,-0.5f,-1.5f},
208
          {-0.5f,-1.5f,-1.5f, 0.5f,-1.5f,-1.5f},
209

    
210
          { 1.5f, 1.5f, 0.5f, 1.5f, 1.5f,-0.5f},
211
          { 1.5f, 0.5f, 1.5f, 1.5f, 0.5f, 0.5f},
212
          { 1.5f, 0.5f,-1.5f, 1.5f, 0.5f,-0.5f},
213
          { 1.5f,-0.5f, 0.5f, 1.5f,-0.5f,-0.5f},
214
          { 1.5f,-1.5f, 1.5f, 1.5f,-1.5f, 0.5f},
215
          { 1.5f,-1.5f,-1.5f, 1.5f,-1.5f,-0.5f},
216

    
217
          {-1.5f, 1.5f, 0.5f,-1.5f, 1.5f,-0.5f},
218
          {-1.5f, 0.5f, 1.5f,-1.5f, 0.5f, 0.5f},
219
          {-1.5f, 0.5f,-1.5f,-1.5f, 0.5f,-0.5f},
220
          {-1.5f,-0.5f, 0.5f,-1.5f,-0.5f,-0.5f},
221
          {-1.5f,-1.5f, 1.5f,-1.5f,-1.5f, 0.5f},
222
          {-1.5f,-1.5f,-1.5f,-1.5f,-1.5f,-0.5f},
223

    
224
          {-0.5f, 1.5f,-0.5f, 0.5f, 1.5f,-0.5f},
225
          {-0.5f, 1.5f, 0.5f, 0.5f, 1.5f, 0.5f},
226

    
227
          { 0.5f,-1.5f, 0.5f, 0.5f,-1.5f,-0.5f},
228
          {-0.5f,-1.5f, 0.5f,-0.5f,-1.5f,-0.5f},
229
        };
230

    
231
  private int[][] mEdges;
232
  private int[] mCubitVariantMap;
233
  private int[] mTypeVariantMap;
234
  private Static4D[] mInitQuats;
235

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

    
238
  public TwistyBandagedCuboid(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
239
    {
240
    super(iconMode, (meta.getNumLayers()[0]+meta.getNumLayers()[1]+meta.getNumLayers()[2])/3.0f, quat, move, scale, meta, asset);
241
    }
242

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

    
245
  @Override
246
  public int[][] getMinimalCubiesInRow()
247
    {
248
    int[] numL = getNumLayers();
249
    int x = numL[0];
250
    int y = numL[1];
251
    int z = numL[2];
252
    int num = 0;
253

    
254
    if( ((x-y)%2)==0 && x!=y )
255
      {
256
      int m = Math.min(x,y);
257
      num = m*z;
258
      }
259
    if( ((x-z)%2)==0 && x!=z )
260
      {
261
      int m = Math.min(x,z);
262
      int n = m*y;
263
      if( num==0 || num>n ) num=n;
264
      }
265
    if( ((y-z)%2)==0 && y!=z )
266
      {
267
      int m = Math.min(y,z);
268
      int n = m*x;
269
      if( num==0 || num>n ) num=n;
270
      }
271

    
272
    if( num>0 )
273
      {
274
      int max = x>y ? Math.max(x,z) : Math.max(y,z);
275
      int min = x<y ? Math.min(x,z) : Math.min(y,z);
276
      int val = min==1 ? 1 : num;
277

    
278
      int[] m = new int[max];
279
      for(int i=0; i<max; i++) m[i] = val;
280
      return new int[][]{m, m, m};
281
      }
282

    
283
    return null;
284
    }
285

    
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287
// Computing scramble states of many a bandaged cubes takes way too long time and too much space.
288
// Return null here and turn to construction of scramble tables just-in-time (scrambleType=2)
289
// Unless this is AI Cube :)
290

    
291
  public int[][] getScrambleEdges()
292
    {
293
    if( mPosition==null ) mPosition = getMetadata().getPos();
294

    
295
    if( mPosition==POS_5 )
296
      {
297
      if( mEdges==null )
298
        {
299
        mEdges = new int[][]
300
          {
301
            { 36, 1,37, 2,38, 3,39, 4,40, 5,41, 6 },  // 0: beg
302
            {  6, 7, 7, 7, 8, 7, 9, 7,10, 7,11, 7 },  // 1: R before
303
            {  0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8 },  // 2: L before
304
            { 12, 9,13, 9,14, 9,15, 9,16, 9,17, 9 },  // 3: D before
305
            { 18,10,19,10,20,10,21,10,22,10,23,10 },  // 4: U before
306
            { 24,11,25,11,26,11,27,11,28,11,29,11 },  // 5: B before
307
            { 30,12,31,12,32,12,33,12,34,12,35,12 },  // 6: F before
308
            { 42, 3,43, 4,44, 5,45, 6 }, // 7: R after
309
            { 46, 3,47, 4,48, 5,49, 6 }, // 8: L after
310
            { 50, 1,51, 2,52, 5,53, 6 }, // 9: D after
311
            { 54, 1,55, 2,56, 5,57, 6 }, //10: U after
312
            { 58, 1,59, 2,60, 3,61, 4 }, //11: B after
313
            { 62, 1,63, 2,64, 3,65, 4 }, //12: F after
314
          };
315
        }
316

    
317
      return mEdges;
318
      }
319

    
320
    return null;
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324
// AI Cube is scrambled using algorithms
325

    
326
  @Override
327
  public int[][] getScrambleAlgorithms()
328
    {
329
    if( mPosition==null ) mPosition = getMetadata().getPos();
330

    
331
    if( mPosition==POS_5 )
332
      {
333
      return new int[][]
334
          {
335
              { 0,1,-1 }, { 0,1, 1 }, { 0,1, 2 }, { 0,2,-1 }, { 0,2, 1 }, { 0,2, 2 },  //  0-5 : L
336
              { 0,4,-1 }, { 0,4, 1 }, { 0,4, 2 }, { 0,8,-1 }, { 0,8, 1 }, { 0,8, 2 },  //  6-11: R
337
              { 1,1,-1 }, { 1,1, 1 }, { 1,1, 2 }, { 1,2,-1 }, { 1,2, 1 }, { 1,2, 2 },  // 12-17: D
338
              { 1,4,-1 }, { 1,4, 1 }, { 1,4, 2 }, { 1,8,-1 }, { 1,8, 1 }, { 1,8, 2 },  // 18-23: U
339
              { 2,1,-1 }, { 2,1, 1 }, { 2,1, 2 }, { 2,2,-1 }, { 2,2, 1 }, { 2,2, 2 },  // 24-29: B
340
              { 2,4,-1 }, { 2,4, 1 }, { 2,4, 2 }, { 2,8,-1 }, { 2,8, 1 }, { 2,8, 2 },  // 30-35: F
341

    
342
              { 1,8,1, 2,1,2 },  // 36: BEG->R
343
              { 1,1,1, 2,1,2 },  // 37: BEG->L
344
              { 2,8,1, 0,8,2 },  // 38: BEG->D
345
              { 2,1,1, 0,8,2 },  // 39: BEG->U
346
              { 0,8,1, 1,8,2 },  // 40: BEG->B
347
              { 0,1,1, 1,8,2 },  // 41: BEG->F
348

    
349
              { 1,1,-1, 0,8,2, 2,1,-1 }, // 42: R->D
350
              { 1,8, 1, 0,8,2, 2,8, 1 }, // 43: R->U
351
              { 2,1, 1, 0,8,2, 1,1, 1 }, // 44: R->B
352
              { 2,8,-1, 0,8,2, 1,8,-1 }, // 45: R->F
353

    
354
              { 1,1,-1, 0,1,2, 2,8, 1 }, // 46: L->D
355
              { 1,8, 1, 0,1,2, 2,1,-1 }, // 47: L->U
356
              { 2,1, 1, 0,1,2, 1,8,-1 }, // 48: L->B
357
              { 2,8,-1, 0,1,2, 1,1, 1 }, // 49: L->F
358

    
359
              { 0,8,-1, 1,1,2, 2,1, 1 }, // 50: D->R
360
              { 0,1, 1, 1,1,2, 2,8,-1 }, // 51: D->L
361
              { 2,1,-1, 1,1,2, 0,8, 1 }, // 52: D->B
362
              { 2,8, 1, 1,1,2, 0,1,-1 }, // 53: D->F
363

    
364
              { 0,8,-1, 1,8,2, 2,8,-1 }, // 54: U->R
365
              { 0,1, 1, 1,8,2, 2,1, 1 }, // 55: U->L
366
              { 2,1,-1, 1,8,2, 0,1,-1 }, // 56: U->B
367
              { 2,8, 1, 1,8,2, 0,8, 1 }, // 57: U->F
368

    
369
              { 0,8, 1, 2,1,2, 1,1,-1 }, // 58: B->R
370
              { 0,1,-1, 2,1,2, 1,8, 1 }, // 59: B->L
371
              { 1,1, 1, 2,1,2, 0,8,-1 }, // 60: B->D
372
              { 1,8,-1, 2,1,2, 0,1, 1 }, // 61: B->U
373

    
374
              { 0,8, 1, 2,8,2, 1,8, 1 }, // 62: F->R
375
              { 0,1,-1, 2,8,2, 1,1,-1 }, // 63: F->L
376
              { 1,1, 1, 2,8,2, 0,1, 1 }, // 64: F->D
377
              { 1,8,-1, 2,8,2, 0,8,-1 }, // 65: F->U
378
          };
379
      }
380
    else
381
      {
382
      return null;
383
      }
384
    }
385

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
// AI Cube is scrambled using algorithms
388

    
389
  @Override
390
  public int getScrambleType()
391
    {
392
    if( mPosition==null ) mPosition = getMetadata().getPos();
393

    
394
    return mPosition==POS_5 ? ObjectScrambler.SCRAMBLING_ALGORITHMS : ObjectScrambler.SCRAMBLING_BANDAGED;
395
    }
396

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

    
399
  private int getType(float[] pos)
400
    {
401
    switch(pos.length)
402
      {
403
      case  3: return CUBIT_111;
404
      case  6: return CUBIT_211;
405
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
406
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
407
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
408
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
409
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
410
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
411
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
412
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
413
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
414
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
415
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
416
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
417
      case 24: float x3 = pos[0];
418
               float y3 = pos[1];
419
               float z3 = pos[2];
420
               float x4=-10,y4=-10,z4=-10;
421
               int i;
422

    
423
               for(i=0; i<8; i++)
424
                 {
425
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
426
                   {
427
                   x4 = pos[3*i  ];
428
                   y4 = pos[3*i+1];
429
                   z4 = pos[3*i+2];
430
                   break;
431
                   }
432
                 }
433
               if( i==9 ) return CUBIT_OTH;
434

    
435
               float dX = x4-x3;
436
               float dY = y4-y3;
437
               float dZ = z4-z3;
438

    
439
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
440
                 {
441
                 for(i=0; i<8; i++)
442
                   {
443
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
444
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
445
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
446
                   }
447

    
448
                 return CUBIT_222;
449
                 }
450

    
451
      default: return CUBIT_OTH;
452
      }
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  private int getQuatIndex(int cubit)
458
    {
459
    float[][] positions = getPositions();
460
    int len = positions.length;
461

    
462
    if( cubit>=0 && cubit<len )
463
      {
464
      float[] pos = positions[cubit];
465
      int type = getType(pos);
466

    
467
      switch(type)
468
        {
469
        case CUBIT_222:
470
        case CUBIT_111: return 0;
471
        case CUBIT_211:
472
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
473
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
474
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
475
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
476
        }
477
      }
478

    
479
    return 0;
480
    }
481

    
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

    
484
  private int[] getDim(int variant)
485
    {
486
    int type,numTypes = mDims.length;
487
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
488
    return type<numTypes ? mDims[type] : null;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

    
493
  private void produceTmpShape(int variant)
494
    {
495
    float[][] positions = getPositions();
496
    int cubit,numCubits = positions.length;
497

    
498
    for(cubit=0; cubit<numCubits; cubit++)
499
      {
500
      if( mCubitVariantMap[cubit]==variant ) break;
501
      }
502

    
503
    if( cubit>=numCubits )
504
      {
505
      android.util.Log.e("D", "unknown variant: "+variant);
506
      }
507
    else
508
      {
509
      FactoryBandagedCuboid factory = FactoryBandagedCuboid.getInstance();
510
      mTmpShapes[variant] = factory.createIrregularShape(variant,positions[cubit]);
511
      }
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515
// PUBLIC API
516

    
517
  public int getTouchControlType()
518
    {
519
    return TC_CHANGING_MIRROR;
520
    }
521

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  public ObjectShape getObjectShape(int variant)
525
    {
526
    if( getDim(variant)!=null )
527
      {
528
      int[][] indices =
529
        {
530
          {2,3,1,0},
531
          {7,6,4,5},
532
          {4,0,1,5},
533
          {7,3,2,6},
534
          {6,2,0,4},
535
          {3,7,5,1},
536
        };
537

    
538
      return new ObjectShape( getVertices(variant), indices);
539
      }
540

    
541
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
542
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
543
    return mTmpShapes[variant];
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
  public ObjectFaceShape getObjectFaceShape(int variant)
549
    {
550
    int[] dim = getDim(variant);
551
    FactoryBandagedCuboid factory = FactoryBandagedCuboid.getInstance();
552

    
553
    if( dim!=null )
554
      {
555
      int[] numLayers = getNumLayers();
556
      boolean iconMode = isInIconMode();
557
      float[][] bands = factory.getBands(iconMode,numLayers);
558

    
559
      int X = dim[0];
560
      int Y = dim[1];
561
      int Z = dim[2];
562
      int DX = Math.max(Y,Z);
563
      int DY = Math.max(X,Z);
564
      int DZ = Math.max(X,Y);
565

    
566
      int[] bandIndices= { DX,DX,DY,DY,DZ,DZ };
567

    
568
      return new ObjectFaceShape(bands,bandIndices,null);
569
      }
570

    
571

    
572
    return factory.createIrregularFaceShape(variant, isInIconMode() );
573
    }
574

    
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576

    
577
  public ObjectVertexEffects getVertexEffects(int variant)
578
    {
579
    int[] numLayers = getNumLayers();
580
    int size = (numLayers[0]+numLayers[1]+numLayers[2])/3;
581
    boolean round = (DistortedLibrary.fastCompilationTF() && size<=5 && !isInIconMode());
582

    
583
    if( getDim(variant)!=null )
584
      {
585
      float[][] vertices = getVertices(variant);
586
      float strength = -STRENGTH;
587

    
588
      float[][] variables =
589
        {
590
          { 0, strength*vertices[0][0], strength*vertices[0][1], strength*vertices[0][2], 1  },
591
          { 0, strength*vertices[1][0], strength*vertices[1][1], strength*vertices[1][2], 1  },
592
          { 0, strength*vertices[2][0], strength*vertices[2][1], strength*vertices[2][2], 1  },
593
          { 0, strength*vertices[3][0], strength*vertices[3][1], strength*vertices[3][2], 1  },
594
          { 0, strength*vertices[4][0], strength*vertices[4][1], strength*vertices[4][2], 1  },
595
          { 0, strength*vertices[5][0], strength*vertices[5][1], strength*vertices[5][2], 1  },
596
          { 0, strength*vertices[6][0], strength*vertices[6][1], strength*vertices[6][2], 1  },
597
          { 0, strength*vertices[7][0], strength*vertices[7][1], strength*vertices[7][2], 1  },
598
        };
599

    
600
      String name = EffectName.DEFORM.name();
601
      float[] reg = {0,0,0,REGION_SIZE};
602

    
603
      String[] names = {name,name,name,name,name,name,name,name};
604
      float[][] regions = {reg,reg,reg,reg,reg,reg,reg,reg};
605
      boolean[] uses = {round,round,round,round,round,round,round,round};
606

    
607
      return new ObjectVertexEffects(names,variables,vertices,regions,uses);
608
      }
609

    
610
    FactoryBandagedCuboid factory = FactoryBandagedCuboid.getInstance();
611
    return factory.createVertexEffects(variant,round);
612
    }
613

    
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615

    
616
  public Static4D getCubitQuats(int cubit, int[] numLayers)
617
    {
618
    if( mInitQuats ==null )
619
      {
620
      mInitQuats = new Static4D[]
621
        {
622
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
623
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
624
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
625
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
626
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
627
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
628
        };
629
      }
630

    
631
    return mInitQuats[getQuatIndex(cubit)];
632
    }
633

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

    
636
  public int getNumCubitVariants(int[] numLayers)
637
    {
638
    if( mNumVariants==0 )
639
      {
640
      float[][] positions = getPositions();
641
      boolean C111=false;
642
      boolean C211=false;
643
      boolean C311=false;
644
      boolean C221=false;
645
      boolean C222=false;
646

    
647
      int numCubits = positions.length;
648
      mCubitVariantMap = new int[numCubits];
649

    
650
      int numTypes = mDims.length;
651
      mTypeVariantMap = new int[numTypes];
652
      for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
653

    
654
      for (int cubit=0; cubit<numCubits; cubit++)
655
        {
656
        int type = getType(positions[cubit]);
657

    
658
        switch (type)
659
          {
660
          case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=mNumVariants++; }
661
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
662
                          break;
663
          case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=mNumVariants++; }
664
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
665
                          break;
666
          case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=mNumVariants++; }
667
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
668
                          break;
669
          case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=mNumVariants++; }
670
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
671
                          break;
672
          case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=mNumVariants++; }
673
                          mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
674
                          break;
675
          default       : mCubitVariantMap[cubit] = mNumVariants++;
676
          }
677
        }
678

    
679
      FactoryBandagedCuboid factory = FactoryBandagedCuboid.getInstance();
680
      factory.prepare(mNumVariants,numLayers);
681
      }
682

    
683
    return mNumVariants;
684
    }
685

    
686
///////////////////////////////////////////////////////////////////////////////////////////////////
687

    
688
  public int getCubitVariant(int cubit, int[] numLayers)
689
    {
690
    return mCubitVariantMap[cubit];
691
    }
692

    
693
///////////////////////////////////////////////////////////////////////////////////////////////////
694

    
695
  private float[][] getVertices(int variant)
696
    {
697
    int[] dim = getDim(variant);
698

    
699
    if( dim!=null )
700
      {
701
      int X = dim[0];
702
      int Y = dim[1];
703
      int Z = dim[2];
704

    
705
      return new float[][]
706
        {
707
          { 0.5f*X, 0.5f*Y, 0.5f*Z},
708
          { 0.5f*X, 0.5f*Y,-0.5f*Z},
709
          { 0.5f*X,-0.5f*Y, 0.5f*Z},
710
          { 0.5f*X,-0.5f*Y,-0.5f*Z},
711
          {-0.5f*X, 0.5f*Y, 0.5f*Z},
712
          {-0.5f*X, 0.5f*Y,-0.5f*Z},
713
          {-0.5f*X,-0.5f*Y, 0.5f*Z},
714
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
715
        };
716
      }
717

    
718
    if( mTmpShapes==null ) mTmpShapes = new ObjectShape[mNumVariants];
719
    if( mTmpShapes[variant]==null ) produceTmpShape(variant);
720
    return mTmpShapes[variant].getVertices();
721
    }
722

    
723
///////////////////////////////////////////////////////////////////////////////////////////////////
724
// PUBLIC API
725

    
726
  public float[] getDist3D(int[] numLayers)
727
    {
728
    float x = numLayers[0];
729
    float y = numLayers[1];
730
    float z = numLayers[2];
731
    float a = (x+y+z)/1.5f;
732

    
733
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
734
    }
735

    
736
///////////////////////////////////////////////////////////////////////////////////////////////////
737

    
738
  public float getStickerRadius()
739
    {
740
    return 0.10f;
741
    }
742

    
743
///////////////////////////////////////////////////////////////////////////////////////////////////
744

    
745
  public float getStickerStroke()
746
    {
747
    if( mPosition==null ) mPosition = getMetadata().getPos();
748
    boolean icon = isInIconMode();
749

    
750
    if( mPosition==POS_5 ) return icon ? 0.30f : 0.11f;
751
    if( mPosition==POS_6 ) return icon ? 0.30f : 0.10f;
752

    
753
    return icon ? 0.16f : 0.08f;
754
    }
755

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

    
758
  public String getShortName()
759
    {
760
    if( mPosition==null ) mPosition = getMetadata().getPos();
761

    
762
    if( mPosition==POS_1 ) return ListObjects.BAN1_3.name();
763
    if( mPosition==POS_2 ) return ListObjects.BAN2_3.name();
764
    if( mPosition==POS_3 ) return ListObjects.BAN3_3.name();
765
    if( mPosition==POS_4 ) return ListObjects.BAN4_3.name();
766
    if( mPosition==POS_5 ) return ListObjects.BAN5_4.name();
767
    if( mPosition==POS_6 ) return ListObjects.BAN6_4.name();
768

    
769
    if( mSignature==null ) mSignature = getSignature();
770
    int[] numLayers = getNumLayers();
771
    int number = 100*numLayers[0]+10*numLayers[1]+numLayers[2];
772

    
773
    return number+"_"+mSignature.getString();
774
    }
775

    
776
///////////////////////////////////////////////////////////////////////////////////////////////////
777

    
778
  public ObjectSignature getSignature()
779
    {
780
    if( mSignature==null )
781
      {
782
      int[] numLayers = getNumLayers();
783
      mSignature = new ObjectSignatureCuboid(numLayers[0],numLayers[1],numLayers[2],mPosition);
784
      }
785
    return mSignature;
786
    }
787

    
788

    
789
///////////////////////////////////////////////////////////////////////////////////////////////////
790

    
791
  public String getObjectName()
792
    {
793
    if( mPosition==null ) mPosition = getMetadata().getPos();
794

    
795
    if( mPosition==POS_1 ||
796
    mPosition==POS_2 ||
797
    mPosition==POS_3 ||
798
    mPosition==POS_4 ||
799
    mPosition==POS_5 ||
800
    mPosition==POS_6  ) return getMetadata().getObjectName();
801

    
802
    return OBJECT_NAME_CUBOID;
803
    }
804

    
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806

    
807
  public String getInventor()
808
    {
809
    if( mPosition==null ) mPosition = getMetadata().getPos();
810

    
811
    if( mPosition==POS_1 ||
812
        mPosition==POS_2 ||
813
        mPosition==POS_3 ||
814
        mPosition==POS_4 ||
815
        mPosition==POS_5 ||
816
        mPosition==POS_6  ) return getMetadata().getAuthor();
817

    
818
    return "??";
819
    }
820

    
821
///////////////////////////////////////////////////////////////////////////////////////////////////
822

    
823
  public int getYearOfInvention()
824
    {
825
    if( mPosition==null ) mPosition = getMetadata().getPos();
826

    
827
    if( mPosition==POS_1 ||
828
        mPosition==POS_2 ||
829
        mPosition==POS_3 ||
830
        mPosition==POS_4 ||
831
        mPosition==POS_5 ||
832
        mPosition==POS_6  ) return getMetadata().getYearOfInvention();
833

    
834
    return 0;
835
    }
836

    
837
///////////////////////////////////////////////////////////////////////////////////////////////////
838

    
839
  public float getComplexity()
840
    {
841
    if( mPosition==null ) mPosition = getMetadata().getPos();
842

    
843
    if( mPosition==POS_1 ||
844
        mPosition==POS_2 ||
845
        mPosition==POS_3 ||
846
        mPosition==POS_4 ||
847
        mPosition==POS_5 ||
848
        mPosition==POS_6  ) return getMetadata().getDifficulty();
849

    
850
    return 4;
851
    }
852

    
853
///////////////////////////////////////////////////////////////////////////////////////////////////
854

    
855
  public String[][] getTutorials()
856
    {
857
    if( mPosition==null ) mPosition = getMetadata().getPos();
858

    
859
    if( mPosition==POS_1 )
860
      {
861
      return new String[][]{
862
                            {"gb","F_iJk_IvpVo","Bandaged Cube","CanChrisSolve"},
863
                            {"es","_lTgw5aEFOg","Tutorial 3x3 Fuse Cube","QBAndo"},
864
                            {"ru","raYDwFEXIq4","Как собрать Fused Cube","Алексей Ярыгин"},
865
                            {"fr","9Cfi4rhKzIw","Tutoriel: résolution du Fused Cube","Skieur Cubb"},
866
                            {"pl","0PcUoGxQa6s","Bandaged 3x3 v.A cube","MrUK"},
867
                            {"kr","1RePOLrzJNE","밴디지 타입 A 해법","듀나메스 큐브 해법연구소"},
868
                            {"vn","vg4J0U0n1oA","Tutorial N.1 - Bandaged VA","Duy Thích Rubik"},
869
                            {"tw","N2LuxPS4EhU","三階綑綁方塊(A款) 教學","不正常魔術方塊研究中心"},
870
                           };
871
      }
872
    if( mPosition==POS_2 )
873
      {
874
      return new String[][]{
875
                            {"ru","lS_EK0PMWI8","Как собрать 2-bar Cube","Алексей Ярыгин"},
876
                            {"pl","tX8ubTLh6p8","Bandaged 3x3 (Two bar)","MrUK"},
877
                            {"kr","NE6XuC1r8xw","밴디지 큐브","Denzel Washington"},
878
                           };
879
      }
880
    if( mPosition==POS_3 )
881
      {
882
      return new String[][]{
883
                            {"gb","7UiCVGygUT4","Bandage Cube C Tutorial","PolyakB"},
884
                            {"ru","gXenRA92Wdc","Как собрать Bandaged 3x3 Type C","YG Cuber"},
885
                            {"pl","sKfdFLm79Zs","Bandaged 3x3 v.C cube","MrUK"},
886
                            {"kr","BcCFgeFy6Ec","밴디지 타입 C 해법","듀나메스 큐브 해법연구소"},
887
                            {"vn","9674LLkPSog","Tutorial N.2 - Bandaged VC","Duy Thích Rubik"},
888
                            {"tw","o1DqhDRaZt4","三階綑綁方塊-三方 教學","不正常魔術方塊研究中心"},
889
                           };
890
      }
891
    if( mPosition==POS_4 )
892
      {
893
      return new String[][]{
894
                            {"gb","AnpdIKICBpM","Trying to Solve a Bandaged Cube","RedKB"},
895
                            {"es","cUyo5fycrvI","Tutorial Bandaged Cube en español","Rafa Garcia Benacazon"},
896
                            {"ru","-MTzeEJptsg","Как собрать bandaged Cube B","стратегия знаний"},
897
                            {"fr","3rsfIJ3roT0","Tutoriel: résolution du Bicube","Skieur Cubb"},
898
                            {"de","sqWVRwkXX9w","Bandaged Cube - Tutorial","GerCubing"},
899
                            {"pl","XcHzTvVR6Po","Bandaged 3x3 v.B cube","MrUK"},
900
                            {"kr","1gsoijF_5q0","BiCube Tutorial (해법)","듀나메스 큐브 해법연구소"},
901
                            {"vn","ZCJDaF4jEbc","Tutorial N.3 - BiCube","Duy Thích Rubik"},
902
                            {"tw","J8XnfMHkFC8","三階綑綁 Bicube 教學","不正常魔術方塊研究中心"},
903
                           };
904
      }
905
    if( mPosition==POS_5 )
906
      {
907
      return new String[][]{
908
                            {"gb","b62HPjlUmYQ","4x4x4 AI Bandaged Cube 1/2","Superantoniovivaldi"},
909
                            {"gb","DQeZ0iDqt4s","4x4x4 AI Bandaged Cube 2/2","Superantoniovivaldi"},
910
                            {"es","bZRV8aXyIY4","Tutorial AI Cube 4x4","QBAndo"},
911
                            {"ru","2NIEHu6jE9o","Как собрать AI Cube","Rodion Strizhakov"},
912
                            {"fr","iP9sSg1q0K0","Résolution de l'AI Cube","asthalis"},
913
                            {"pl","y6MNyoHgY8A","All Bandage 4x4 cube TUTORIAL","MrUK"},
914
                            {"br","yGnQ4ObiPRY","Como Resolver o 4x4 Bandaged 1/4","Rafael Cinoto"},
915
                            {"br","XJUtQrwrCmA","Como Resolver o 4x4 Bandaged 2/4","Rafael Cinoto"},
916
                            {"br","Wrdec2WNBSY","Como Resolver o 4x4 Bandaged 3/4","Rafael Cinoto"},
917
                            {"br","mWvYD53fqHI","Como Resolver o 4x4 Bandaged 4/4","Rafael Cinoto"},
918
                            {"kr","MvaFtrU4O_k","AI 밴디지 큐브 해법","듀나메스 큐브 해법연구소"},
919
                            {"vn","aAP1E567ADc","Tutorial N.78 - AI Cube","Duy Thích Rubik"},
920
                           };
921
      }
922
    if( mPosition==POS_6 )
923
      {
924
      return new String[][]{
925
                            {"gb","_FnNzFo0ITM","Burr Cube Tutorial 1/2","Superantoniovivaldi"},
926
                            {"gb","NOf-UcNh4sI","Burr Cube Tutorial 2/2","Superantoniovivaldi"},
927
                            {"es","xR2TLKQmym8","Cómo Resuelvo Wall Cube","Robert Cubes"},
928
                            {"vn","cbDUtkIJjfk","Tutorial N.96 - Burr Cube","Duy Thích Rubik"},
929
                           };
930
      }
931
    return null;
932
    }
933
}
(3-3/59)