Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 31de4259

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CUBOID;
23
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24

    
25
import java.io.InputStream;
26

    
27
import org.distorted.library.main.DistortedLibrary;
28
import org.distorted.library.type.Static3D;
29
import org.distorted.library.type.Static4D;
30

    
31
import org.distorted.objectlib.helpers.FactoryBandagedCubit;
32
import org.distorted.objectlib.helpers.ObjectFaceShape;
33
import org.distorted.objectlib.scrambling.ScrambleStateBandagedCuboid;
34
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
35
import org.distorted.objectlib.helpers.ObjectShape;
36
import org.distorted.objectlib.scrambling.ScrambleState;
37
import org.distorted.objectlib.main.ShapeHexahedron;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
abstract class TwistyBandagedAbstract extends ShapeHexahedron
42
{
43
  private static final int CUBIT_111 = 0;
44
  private static final int CUBIT_211 = 1;
45
  private static final int CUBIT_311 = 2;
46
  private static final int CUBIT_221 = 3;
47
  private static final int CUBIT_222 = 4;
48
  private static final int CUBIT_OTH = 5;
49

    
50
  // the three rotation axis of a 3x3 Cube. Must be normalized.
51
  static final Static3D[] ROT_AXIS = new Static3D[]
52
         {
53
           new Static3D(1,0,0),
54
           new Static3D(0,1,0),
55
           new Static3D(0,0,1)
56
         };
57

    
58
  private static final int[][] mDims = new int[][]
59
        {
60
         {1,1,1},  // has to be X>=Z>=Y so that all
61
         {2,1,1},  // the faces are horizontal
62
         {3,1,1},
63
         {2,1,2},
64
         {2,2,2},
65
        };
66

    
67
  private int[][] mBasicAngle;
68
  private Static4D[] mInitQuats;
69
  private float[][] mCuts;
70
  private ScrambleState[] mStates;
71
  private int[] mCubitVariantMap;
72
  private int[] mTypeVariantMap;
73
  private int[][] mSolvedQuatsAbstract;
74

    
75
  float[][] POSITIONS;
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  TwistyBandagedAbstract(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
80
    {
81
    super(numL, meshState, iconMode, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, scale, stream);
82
    }
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  abstract float[][] getPositions();
87

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

    
90
  private boolean cubitIsExternal(float[] pos, int x, int y, int z)
91
    {
92
    int len = pos.length/3;
93
    float dx = 0.5f*(x-1) - 0.1f;
94
    float dy = 0.5f*(y-1) - 0.1f;
95
    float dz = 0.5f*(z-1) - 0.1f;
96

    
97
    if( x==1 )
98
      {
99
      for(int i=0; i<len; i++)
100
        {
101
        float cy = pos[3*i+1];
102
        float cz = pos[3*i+2];
103
        if( cy>=dy || cy<=-dy || cz>=dz || cz<=-dz ) return true;
104
        }
105
      }
106

    
107
    if( y==1 )
108
      {
109
      for(int i=0; i<len; i++)
110
        {
111
        float cx = pos[3*i  ];
112
        float cz = pos[3*i+2];
113
        if( cx>=dx || cx<=-dx || cz>=dz || cz<=-dz ) return true;
114
        }
115
      }
116

    
117
    if( z==1 )
118
      {
119
      for(int i=0; i<len; i++)
120
        {
121
        float cx = pos[3*i  ];
122
        float cy = pos[3*i+1];
123
        if( cx>=dx || cx<=-dx || cy>=dy || cy<=-dy ) return true;
124
        }
125
      }
126

    
127
    return false;
128
    }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
// If we have a flat cuboid than retCubitSolvedStatus() wrongly reports that the internal cubits
132
// are edges (they do have two non-black faces after all!) which leads to wrong solvedQuats and
133
// mis-detection of a solved status. Correct this manually here.
134
//
135
// Note that this is still not completely good in case of bandaged cuboids - there can be a 4x4x2
136
// bandaged cuboid whose 4 'internal' cubits from the 4x4 face are fused with the other 4 internal
137
// cubits from the other 4x4 face - and those would again get mis-detected as edges...
138

    
139
  @Override
140
  public int[][] getSolvedQuats()
141
    {
142
    if( mSolvedQuatsAbstract==null )
143
      {
144
      int[] numLayers = getNumLayers();
145
      int x = numLayers[0];
146
      int y = numLayers[1];
147
      int z = numLayers[2];
148

    
149
      if( (x==1 && y>2 && z>2) || (x>2 && y==1 && z>2) || (x>2 && y>2 && z==1) )
150
        {
151
        int q;
152

    
153
             if( x==1 )  q=1;
154
        else if( y==1 )  q=4;
155
        else             q=7;
156

    
157
        float[][] pos = getPositions();
158
        int numTotal = pos.length;
159
        boolean[] isExternal = new boolean[numTotal];
160
        int numExternal = 0;
161

    
162
        for(int cubit=0; cubit<numTotal; cubit++)
163
          if( cubitIsExternal(pos[cubit],x,y,z) )
164
            {
165
            isExternal[cubit] = true;
166
            numExternal++;
167
            }
168

    
169
        int numInternal = numTotal - numExternal;
170

    
171
        mSolvedQuatsAbstract = new int[numInternal+1][];
172

    
173
        mSolvedQuatsAbstract[0] = new int[numExternal+1];
174
        mSolvedQuatsAbstract[0][0] = numExternal;
175

    
176
        for(int i=0; i<numInternal; i++)
177
          {
178
          mSolvedQuatsAbstract[i+1] = new int[5];
179
          mSolvedQuatsAbstract[i+1][0] = 1;
180
          mSolvedQuatsAbstract[i+1][2] = q;
181
          mSolvedQuatsAbstract[i+1][3] = q+1;
182
          mSolvedQuatsAbstract[i+1][4] = q+2;
183
          }
184

    
185
        int pointerExternal = 1;
186
        int pointerInternal = 1;
187

    
188
        for(int cubit=0; cubit<numTotal; cubit++)
189
          {
190
          if( isExternal[cubit] ) mSolvedQuatsAbstract[0][pointerExternal++] = cubit;
191
          else                    mSolvedQuatsAbstract[pointerInternal++][1] = cubit;
192
          }
193
        }
194
      else
195
        {
196
        mSolvedQuatsAbstract = super.getSolvedQuats();
197
        }
198
      }
199

    
200
    return mSolvedQuatsAbstract;
201
    }
202

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

    
205
  public ScrambleState[] getScrambleStates()
206
    {
207
    if( mStates==null && !isInIconMode() )
208
      {
209
      long signature = getSignature();
210
      mStates = ScrambleStateBandagedCuboid.computeGraph(signature);
211
      }
212

    
213
    return mStates;
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  private int getType(float[] pos)
219
    {
220
    switch(pos.length)
221
      {
222
      case  3: return CUBIT_111;
223
      case  6: return CUBIT_211;
224
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
225
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
226
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
227
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
228
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
229
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
230
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
231
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
232
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
233
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
234
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
235
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
236
      case 24: float x3 = pos[0];
237
               float y3 = pos[1];
238
               float z3 = pos[2];
239
               float x4=-10,y4=-10,z4=-10;
240
               int i;
241

    
242
               for(i=0; i<8; i++)
243
                 {
244
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
245
                   {
246
                   x4 = pos[3*i  ];
247
                   y4 = pos[3*i+1];
248
                   z4 = pos[3*i+2];
249
                   break;
250
                   }
251
                 }
252
               if( i==9 ) return CUBIT_OTH;
253

    
254
               float dX = x4-x3;
255
               float dY = y4-y3;
256
               float dZ = z4-z3;
257

    
258
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
259
                 {
260
                 for(i=0; i<8; i++)
261
                   {
262
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
263
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
264
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
265
                   }
266

    
267
                 return CUBIT_222;
268
                 }
269

    
270
      default: return CUBIT_OTH;
271
      }
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  private int getQuatIndex(int cubit)
277
    {
278
    float[][] positions = getPositions();
279
    int len = positions.length;
280

    
281
    if( cubit>=0 && cubit<len )
282
      {
283
      float[] pos = positions[cubit];
284
      int type = getType(pos);
285

    
286
      switch(type)
287
        {
288
        case CUBIT_222:
289
        case CUBIT_111: return 0;
290
        case CUBIT_211:
291
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
292
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
293
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
294
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
295
        }
296
      }
297

    
298
    return 0;
299
    }
300

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

    
303
  private int getSigIndex(float x, float y, float z)
304
    {
305
    if( x==-1.0f )
306
      {
307
           if( y==-1.0f ) return z==0.5f ? 4:9;
308
      else if( y==-0.5f ) return z==1.0f ? 14 : (z==0.0f ? 17:20);
309
      else if( y== 0.0f ) return z==0.5f ? 25:30;
310
      else if( y== 0.5f ) return z==1.0f ? 35 : (z==0.0f ? 38:41);
311
      else if( y== 1.0f ) return z==0.5f ? 46:51;
312
      }
313
    else if( x==-0.5f )
314
      {
315
           if( y==-1.0f ) return z==1.0f ? 1  : (z==0.0f ?  6:11);
316
      else if( y== 0.0f ) return z==1.0f ? 22 : (z==0.0f ? 27:32);
317
      else if( y== 1.0f ) return z==1.0f ? 43 : (z==0.0f ? 48:53);
318
      }
319
    else if( x==0.0f )
320
      {
321
           if( y==-1.0f ) return z==0.5f ? 3:8;
322
      else if( y==-0.5f ) return z==1.0f ? 13 : (z==0.0f ? 16:19);
323
      else if( y== 0.0f ) return z==0.5f ? 24:29;
324
      else if( y== 0.5f ) return z==1.0f ? 34 : (z==0.0f ? 37:40);
325
      else if( y== 1.0f ) return z==0.5f ? 45:50;
326
      }
327
    else if( x==0.5f )
328
      {
329
           if( y==-1.0f ) return z==1.0f ? 0  : (z==0.0f ?  5:10);
330
      else if( y== 0.0f ) return z==1.0f ? 21 : (z==0.0f ? 26:31);
331
      else if( y== 1.0f ) return z==1.0f ? 42 : (z==0.0f ? 47:52);
332
      }
333
    else if( x==1.0f )
334
      {
335
           if( y==-1.0f ) return z==0.5f ? 2:7;
336
      else if( y==-0.5f ) return z==1.0f ? 12 : (z==0.0f ? 15:18);
337
      else if( y== 0.0f ) return z==0.5f ? 23:28;
338
      else if( y== 0.5f ) return z==1.0f ? 33 : (z==0.0f ? 36:39);
339
      else if( y== 1.0f ) return z==0.5f ? 44:49;
340
      }
341
    else
342
      {
343
      android.util.Log.e("D", "ERROR! mx="+x);
344
      }
345

    
346
    return -1;
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  private long markConnection(float x1, float y1, float z1, float x2, float y2, float z2)
352
    {
353
    float dx = x1-x2;
354
    float dy = y1-y2;
355
    float dz = z1-z2;
356

    
357
    if( (dx==0 && dy==0 && (dz==1 || dz==-1) ) ||
358
        (dz==0 && dx==0 && (dy==1 || dy==-1) ) ||
359
        (dy==0 && dz==0 && (dx==1 || dx==-1) )  )
360
      {
361
      float mx = (x1+x2)/2;
362
      float my = (y1+y2)/2;
363
      float mz = (z1+z2)/2;
364

    
365
      int index = getSigIndex(mx,my,mz);
366

    
367
      return (1L<<index);
368
      }
369

    
370
    return 0;
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  long markConnections(long signature, float[] position)
376
    {
377
    int len = position.length/3;
378

    
379
    for(int i=0; i<len; i++)
380
      {
381
      float x = position[3*i  ];
382
      float y = position[3*i+1];
383
      float z = position[3*i+2];
384

    
385
      for(int j=i+1; j<len; j++)
386
        {
387
        signature |= markConnection(x,y,z,position[3*j],position[3*j+1],position[3*j+2]);
388
        }
389
      }
390

    
391
    return signature;
392
    }
393

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

    
396
  public long getSignature()
397
    {
398
    long signature = 0;
399
    float[][] positions = getPositions();
400
    for(float[] pos : positions ) signature = markConnections(signature,pos);
401
    return signature;
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public ObjectShape getObjectShape(int variant)
407
    {
408
    int type,numTypes = mDims.length;
409
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
410

    
411
    if( type<numTypes )
412
      {
413
      int X = mDims[type][0];
414
      int Y = mDims[type][1];
415
      int Z = mDims[type][2];
416

    
417
      float[][] vertices =
418
        {
419
          {+0.5f*X,+0.5f*Y,+0.5f*Z},
420
          {+0.5f*X,+0.5f*Y,-0.5f*Z},
421
          {+0.5f*X,-0.5f*Y,+0.5f*Z},
422
          {+0.5f*X,-0.5f*Y,-0.5f*Z},
423
          {-0.5f*X,+0.5f*Y,+0.5f*Z},
424
          {-0.5f*X,+0.5f*Y,-0.5f*Z},
425
          {-0.5f*X,-0.5f*Y,+0.5f*Z},
426
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
427
        };
428

    
429
      int[][] indices =
430
        {
431
          {2,3,1,0},
432
          {7,6,4,5},
433
          {4,0,1,5},
434
          {7,3,2,6},
435
          {6,2,0,4},
436
          {3,7,5,1},
437
        };
438

    
439
      return new ObjectShape(vertices, indices);
440
      }
441

    
442
    float[][] positions = getPositions();
443
    int cubit,numCubits = positions.length;
444

    
445
    for(cubit=0; cubit<numCubits; cubit++)
446
      {
447
      if( mCubitVariantMap[cubit]==variant ) break;
448
      }
449

    
450
    if( cubit>=numCubits )
451
      {
452
      android.util.Log.e("D", "unknown variant: "+variant);
453
      return null;
454
      }
455

    
456
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
457
    return factory.createIrregularShape(variant,positions[cubit]);
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

    
462
  public ObjectFaceShape getObjectFaceShape(int variant)
463
    {
464
    boolean roundCorners = DistortedLibrary.fastCompilationTF();
465
    int type,numTypes = mDims.length;
466
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
467

    
468
    if( type<numTypes )
469
      {
470
      int val = roundCorners ? 0 : -1;
471
      int X = mDims[type][0];
472
      int Y = mDims[type][1];
473
      int Z = mDims[type][2];
474

    
475
      float height        = isInIconMode() ? 0.001f : 0.048f;
476
      int[] bandIndices   = { 0,0,1,1,2,2 };
477
      float[][] corners   = { {0.04f,0.15f} };
478
      int[] cornerIndices = { val,val,val,val,val,val,val,val };
479
      int[] centerIndices = { 0,1,2,3,4,5,6,7 };
480

    
481
      int maxXY = Math.max(X,Y);
482
      int maxXZ = Math.max(X,Z);
483
      int maxYZ = Math.max(Y,Z);
484

    
485
      int angle = 45;
486
      float R = 0.25f;
487
      float S = 0.50f;
488

    
489
      float[][] bands =
490
        {
491
          {height/maxYZ,angle,R,S,5,0,0},
492
          {height/maxXZ,angle,R,S,5,0,0},
493
          {height/maxXY,angle,R,S,5,0,0}
494
        };
495

    
496
      float[][] centers =
497
        {
498
          {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
499
          {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
500
          {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
501
          {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
502
          {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
503
          {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
504
          {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
505
          {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
506
        };
507

    
508
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
509
      }
510

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

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

    
517
  public float[][] getCubitPositions(int[] numLayers)
518
    {
519
    return getPositions();
520
    }
521

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

    
524
  public Static4D getCubitQuats(int cubit, int[] numLayers)
525
    {
526
    if( mInitQuats ==null )
527
      {
528
      mInitQuats = new Static4D[]
529
        {
530
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
531
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
532
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
533
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
534
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
535
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
536
        };
537
      }
538

    
539
    return mInitQuats[getQuatIndex(cubit)];
540
    }
541

    
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543

    
544
  public int getNumCubitVariants(int[] numLayers)
545
    {
546
    int numVariants = 0;
547
    float[][] positions = getPositions();
548
    boolean C111=false;
549
    boolean C211=false;
550
    boolean C311=false;
551
    boolean C221=false;
552
    boolean C222=false;
553

    
554
    int numCubits = positions.length;
555
    mCubitVariantMap = new int[numCubits];
556

    
557
    int numTypes = mDims.length;
558
    mTypeVariantMap = new int[numTypes];
559
    for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
560

    
561
    for (int cubit=0; cubit<numCubits; cubit++)
562
      {
563
      int type = getType(positions[cubit]);
564

    
565
      switch (type)
566
        {
567
        case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=numVariants++; }
568
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
569
                        break;
570
        case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=numVariants++; }
571
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
572
                        break;
573
        case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=numVariants++; }
574
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
575
                        break;
576
        case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=numVariants++; }
577
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
578
                        break;
579
        case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=numVariants++; }
580
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
581
                        break;
582
        default       : mCubitVariantMap[cubit] = numVariants++;
583
        }
584
      }
585

    
586
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
587
    factory.prepare(numVariants,numLayers[0],numLayers[1],numLayers[2]);
588

    
589
    return numVariants;
590
    }
591

    
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593

    
594
  public int getCubitVariant(int cubit, int[] numLayers)
595
    {
596
    return mCubitVariantMap[cubit];
597
    }
598

    
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600

    
601
  public float[][] getCuts(int[] numLayers)
602
    {
603
    if( mCuts==null )
604
      {
605
      mCuts = new float[3][];
606

    
607
      for(int axis=0; axis<3; axis++)
608
        {
609
        int len = numLayers[axis];
610
        float start = (2-len)*0.5f;
611

    
612
        if( len>=2 )
613
          {
614
          mCuts[axis] = new float[len-1];
615
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
616
          }
617
        }
618
      }
619

    
620
    return mCuts;
621
    }
622

    
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624

    
625
  public boolean[][] getLayerRotatable(int[] numLayers)
626
    {
627
    int numAxis = ROT_AXIS.length;
628
    boolean[][] layerRotatable = new boolean[numAxis][];
629

    
630
    for(int i=0; i<numAxis; i++)
631
      {
632
      layerRotatable[i] = new boolean[numLayers[i]];
633
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
634
      }
635

    
636
    return layerRotatable;
637
    }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640

    
641
  public int getTouchControlType()
642
    {
643
    return TC_CUBOID;
644
    }
645

    
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647

    
648
  public int getTouchControlSplit()
649
    {
650
    return TYPE_NOT_SPLIT;
651
    }
652

    
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654

    
655
  public int[][][] getEnabled()
656
    {
657
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
658
    }
659

    
660
///////////////////////////////////////////////////////////////////////////////////////////////////
661

    
662
  public float[] getDist3D(int[] numLayers)
663
    {
664
    float x = numLayers[0];
665
    float y = numLayers[1];
666
    float z = numLayers[2];
667
    float a = (x+y+z)/1.5f;
668

    
669
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
670
    }
671

    
672
///////////////////////////////////////////////////////////////////////////////////////////////////
673

    
674
  public Static3D[] getFaceAxis()
675
    {
676
    return TouchControlHexahedron.FACE_AXIS;
677
    }
678

    
679
///////////////////////////////////////////////////////////////////////////////////////////////////
680

    
681
  public float getStickerRadius()
682
    {
683
    return 0.10f;
684
    }
685

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

    
688
  public float getStickerStroke()
689
    {
690
    return isInIconMode() ? 0.16f : 0.08f;
691
    }
692

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

    
695
  public float[][] getStickerAngles()
696
    {
697
    return null;
698
    }
699

    
700
///////////////////////////////////////////////////////////////////////////////////////////////////
701
// PUBLIC API
702

    
703
  public Static3D[] getRotationAxis()
704
    {
705
    return ROT_AXIS;
706
    }
707

    
708
///////////////////////////////////////////////////////////////////////////////////////////////////
709

    
710
  public int[][] getBasicAngles()
711
    {
712
     if( mBasicAngle==null )
713
      {
714
      int[] num = getNumLayers();
715
      int numX = num[0];
716
      int numY = num[1];
717
      int numZ = num[2];
718

    
719
      int x = numY==numZ ? 4 : 2;
720
      int y = numX==numZ ? 4 : 2;
721
      int z = numX==numY ? 4 : 2;
722

    
723
      int[] tmpX = new int[numX];
724
      for(int i=0; i<numX; i++) tmpX[i] = x;
725
      int[] tmpY = new int[numY];
726
      for(int i=0; i<numY; i++) tmpY[i] = y;
727
      int[] tmpZ = new int[numZ];
728
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
729

    
730
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
731
      }
732

    
733
    return mBasicAngle;
734
    }
735
}
(4-4/36)