Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 1d581993

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 b1f0d55d Leszek Koltunski
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CUBOID;
23 c9c71c3f Leszek Koltunski
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
24 29b82486 Leszek Koltunski
25 82eb152a Leszek Koltunski
import java.io.InputStream;
26 29b82486 Leszek Koltunski
27 db758bd0 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
28 29b82486 Leszek Koltunski
import org.distorted.library.type.Static3D;
29
import org.distorted.library.type.Static4D;
30
31 b1f0d55d Leszek Koltunski
import org.distorted.objectlib.helpers.FactoryBandagedCubit;
32 3ee1d662 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectFaceShape;
33 1d581993 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectSignature;
34
import org.distorted.objectlib.scrambling.ScrambleStateBandaged3x3;
35 c9c71c3f Leszek Koltunski
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
36 198c5bf0 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectShape;
37 10b7e306 Leszek Koltunski
import org.distorted.objectlib.scrambling.ScrambleState;
38 386af988 Leszek Koltunski
import org.distorted.objectlib.main.ShapeHexahedron;
39 29b82486 Leszek Koltunski
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
42 386af988 Leszek Koltunski
abstract class TwistyBandagedAbstract extends ShapeHexahedron
43 29b82486 Leszek Koltunski
{
44 289ca015 Leszek Koltunski
  private static final int CUBIT_111 = 0;
45
  private static final int CUBIT_211 = 1;
46
  private static final int CUBIT_311 = 2;
47
  private static final int CUBIT_221 = 3;
48
  private static final int CUBIT_222 = 4;
49
  private static final int CUBIT_OTH = 5;
50
51 29b82486 Leszek Koltunski
  // the three rotation axis of a 3x3 Cube. Must be normalized.
52
  static final Static3D[] ROT_AXIS = new Static3D[]
53
         {
54
           new Static3D(1,0,0),
55
           new Static3D(0,1,0),
56
           new Static3D(0,0,1)
57
         };
58
59 7af68038 Leszek Koltunski
  private static final int[][] mDims = new int[][]
60 29b82486 Leszek Koltunski
        {
61
         {1,1,1},  // has to be X>=Z>=Y so that all
62
         {2,1,1},  // the faces are horizontal
63
         {3,1,1},
64
         {2,1,2},
65 289ca015 Leszek Koltunski
         {2,2,2},
66 29b82486 Leszek Koltunski
        };
67
68 beee90ab Leszek Koltunski
  private int[][] mBasicAngle;
69 29b82486 Leszek Koltunski
  private Static4D[] mInitQuats;
70
  private float[][] mCuts;
71 289ca015 Leszek Koltunski
  private ScrambleState[] mStates;
72
  private int[] mCubitVariantMap;
73
  private int[] mTypeVariantMap;
74 31de4259 Leszek Koltunski
  private int[][] mSolvedQuatsAbstract;
75 289ca015 Leszek Koltunski
76 29b82486 Leszek Koltunski
  float[][] POSITIONS;
77
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79
80 3bf19410 Leszek Koltunski
  TwistyBandagedAbstract(int[] numL, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
81 29b82486 Leszek Koltunski
    {
82 b1f0d55d Leszek Koltunski
    super(numL, meshState, iconMode, (numL[0]+numL[1]+numL[2])/3.0f, quat, move, scale, stream);
83 29b82486 Leszek Koltunski
    }
84
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86
87
  abstract float[][] getPositions();
88 289ca015 Leszek Koltunski
89 31de4259 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
90 d8e03a81 Leszek Koltunski
// return 0 if cubit is 'external' (it has at least two walls which belong to two different faces
91
// of the cuboid, faces which do not both rotate along the same axis! So: it is an edge, a corner,
92
// or a bandaged cubit which 'comes out' in two different, non-opposite, faces.
93
// Otherwise, if the cubit only comes out in one face or in two faces which are opposite to each other,
94
// return the index of the first of the three quats which rotate stuff in this face (so right or left
95
// return 1 because quats 1,2,3 are the ones rotating along the X axis)
96
97
  private int cubitIsExternal(float[] pos, float dx, float dy, float dz)
98 31de4259 Leszek Koltunski
    {
99
    int len = pos.length/3;
100 d8e03a81 Leszek Koltunski
    int x=0, y=0, z=0;
101 31de4259 Leszek Koltunski
102 d8e03a81 Leszek Koltunski
    for(int i=0; i<len; i++)
103 31de4259 Leszek Koltunski
      {
104 d8e03a81 Leszek Koltunski
      float cx = pos[3*i  ];
105
      float cy = pos[3*i+1];
106
      float cz = pos[3*i+2];
107 31de4259 Leszek Koltunski
108 d8e03a81 Leszek Koltunski
      if( cx>dx || cx<-dx ) x=1;
109
      if( cy>dy || cy<-dy ) y=1;
110
      if( cz>dz || cz<-dz ) z=1;
111 31de4259 Leszek Koltunski
      }
112
113 d8e03a81 Leszek Koltunski
    if( x+y+z>=2 ) return 0;
114 31de4259 Leszek Koltunski
115 d8e03a81 Leszek Koltunski
    if( x==1 ) return 1;
116
    if( y==1 ) return 4;
117
    if( z==1 ) return 7;
118
119
    android.util.Log.e("D", "ERROR: unsupported: internal cubit! ");
120
    return 0;
121 31de4259 Leszek Koltunski
    }
122
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
// If we have a flat cuboid than retCubitSolvedStatus() wrongly reports that the internal cubits
125
// are edges (they do have two non-black faces after all!) which leads to wrong solvedQuats and
126
// mis-detection of a solved status. Correct this manually here.
127
//
128
// Note that this is still not completely good in case of bandaged cuboids - there can be a 4x4x2
129
// bandaged cuboid whose 4 'internal' cubits from the 4x4 face are fused with the other 4 internal
130
// cubits from the other 4x4 face - and those would again get mis-detected as edges...
131
132
  @Override
133
  public int[][] getSolvedQuats()
134
    {
135
    if( mSolvedQuatsAbstract==null )
136
      {
137
      int[] numLayers = getNumLayers();
138 d8e03a81 Leszek Koltunski
      float dx = 0.5f*(numLayers[0]-1) - 0.1f;
139
      float dy = 0.5f*(numLayers[1]-1) - 0.1f;
140
      float dz = 0.5f*(numLayers[2]-1) - 0.1f;
141
142
      float[][] pos = getPositions();
143
      int numTotal = pos.length;
144
      boolean[] isExternal = new boolean[numTotal];
145
      int[] internalQuat = new int[numTotal];
146
      int numExternal = 0;
147
      int pointer = 0;
148
149
      for(int cubit=0; cubit<numTotal; cubit++)
150 31de4259 Leszek Koltunski
        {
151 d8e03a81 Leszek Koltunski
        int q = cubitIsExternal(pos[cubit],dx,dy,dz);
152 31de4259 Leszek Koltunski
153 d8e03a81 Leszek Koltunski
        if( q<=0 )
154 31de4259 Leszek Koltunski
          {
155 d8e03a81 Leszek Koltunski
          isExternal[cubit] = true;
156
          numExternal++;
157 31de4259 Leszek Koltunski
          }
158 d8e03a81 Leszek Koltunski
        else
159 31de4259 Leszek Koltunski
          {
160 d8e03a81 Leszek Koltunski
          isExternal[cubit] = false;
161
          internalQuat[pointer] = q;
162
          pointer++;
163 31de4259 Leszek Koltunski
          }
164
        }
165 d8e03a81 Leszek Koltunski
166
      int numInternal = numTotal - numExternal;
167
168
      mSolvedQuatsAbstract = new int[numInternal+1][];
169
      mSolvedQuatsAbstract[0] = new int[numExternal+1];
170
      mSolvedQuatsAbstract[0][0] = numExternal;
171
172
      for(int i=0; i<numInternal; i++)
173
        {
174
        int q = internalQuat[i];
175
        mSolvedQuatsAbstract[i+1] = new int[5];
176
        mSolvedQuatsAbstract[i+1][0] = 1;
177
        mSolvedQuatsAbstract[i+1][2] = q;
178
        mSolvedQuatsAbstract[i+1][3] = q+1;
179
        mSolvedQuatsAbstract[i+1][4] = q+2;
180
        }
181
182
      int pointerExternal = 1;
183
      int pointerInternal = 1;
184
185
      for(int cubit=0; cubit<numTotal; cubit++)
186 31de4259 Leszek Koltunski
        {
187 d8e03a81 Leszek Koltunski
        if( isExternal[cubit] ) mSolvedQuatsAbstract[0][pointerExternal++] = cubit;
188
        else                    mSolvedQuatsAbstract[pointerInternal++][1] = cubit;
189 31de4259 Leszek Koltunski
        }
190
      }
191
192
    return mSolvedQuatsAbstract;
193
    }
194
195 1d581993 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
196
197
  public ObjectSignature getSignature()
198
    {
199
    long signature = 0;
200
    float[][] positions = getPositions();
201
    for(float[] pos : positions ) signature = markConnections(signature,pos);
202
203
    return new ObjectSignature(signature);
204
    }
205
206 289ca015 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
207
208
  public ScrambleState[] getScrambleStates()
209
    {
210 70a42319 Leszek Koltunski
    if( mStates==null && !isInIconMode() )
211 289ca015 Leszek Koltunski
      {
212 1d581993 Leszek Koltunski
      ObjectSignature signature = getSignature();
213
      mStates = ScrambleStateBandaged3x3.computeGraph(signature.getLong3());
214 289ca015 Leszek Koltunski
      }
215
216
    return mStates;
217
    }
218
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221 1ef59b1d Leszek Koltunski
  private int getType(float[] pos)
222 289ca015 Leszek Koltunski
    {
223 1ef59b1d Leszek Koltunski
    switch(pos.length)
224 289ca015 Leszek Koltunski
      {
225
      case  3: return CUBIT_111;
226
      case  6: return CUBIT_211;
227 1ef59b1d Leszek Koltunski
      case  9: boolean x1 = (pos[0]==pos[3] && pos[0]==pos[6]);
228
               boolean y1 = (pos[1]==pos[4] && pos[1]==pos[7]);
229
               boolean z1 = (pos[2]==pos[5] && pos[2]==pos[8]);
230 289ca015 Leszek Koltunski
               return ( (x1&&y1) || (x1&&z1) || (y1&&z1) ) ? CUBIT_311 : CUBIT_OTH;
231 1ef59b1d Leszek Koltunski
      case 12: float x = (pos[0]+pos[3]+pos[6]+pos[ 9])/4;
232
               float y = (pos[1]+pos[4]+pos[7]+pos[10])/4;
233
               float z = (pos[2]+pos[5]+pos[8]+pos[11])/4;
234
               float d1 = (pos[0]-x)*(pos[0]-x) + (pos[ 1]-y)*(pos[ 1]-y) + (pos[ 2]-z)*(pos[ 2]-z);
235
               float d2 = (pos[3]-x)*(pos[3]-x) + (pos[ 4]-y)*(pos[ 4]-y) + (pos[ 5]-z)*(pos[ 5]-z);
236
               float d3 = (pos[6]-x)*(pos[6]-x) + (pos[ 7]-y)*(pos[ 7]-y) + (pos[ 8]-z)*(pos[ 8]-z);
237
               float d4 = (pos[9]-x)*(pos[9]-x) + (pos[10]-y)*(pos[10]-y) + (pos[11]-z)*(pos[11]-z);
238
               return ( d1==0.5f && d2==0.5f && d3==0.5f && d4==0.5f ) ? CUBIT_221 : CUBIT_OTH;
239
      case 24: float x3 = pos[0];
240
               float y3 = pos[1];
241
               float z3 = pos[2];
242 289ca015 Leszek Koltunski
               float x4=-10,y4=-10,z4=-10;
243
               int i;
244
245
               for(i=0; i<8; i++)
246
                 {
247 1ef59b1d Leszek Koltunski
                 if( pos[3*i]!=x3 && pos[3*i+1]!=y3 && pos[3*i+2]!=z3 )
248 289ca015 Leszek Koltunski
                   {
249 1ef59b1d Leszek Koltunski
                   x4 = pos[3*i  ];
250
                   y4 = pos[3*i+1];
251
                   z4 = pos[3*i+2];
252 289ca015 Leszek Koltunski
                   break;
253
                   }
254
                 }
255
               if( i==9 ) return CUBIT_OTH;
256
257
               float dX = x4-x3;
258
               float dY = y4-y3;
259
               float dZ = z4-z3;
260
261
               if( (dX==1.0f || dX==-1.0f) && (dY==1.0f || dY==-1.0f) && (dZ==1.0f || dZ==-1.0f) )
262
                 {
263
                 for(i=0; i<8; i++)
264
                   {
265 1ef59b1d Leszek Koltunski
                   if( (pos[3*i  ]!=x3 && pos[3*i  ]!=x4) ||
266
                       (pos[3*i+1]!=y3 && pos[3*i+1]!=y4) ||
267
                       (pos[3*i+2]!=z3 && pos[3*i+2]!=z4)  ) return CUBIT_OTH;
268 289ca015 Leszek Koltunski
                   }
269
270
                 return CUBIT_222;
271
                 }
272
273
      default: return CUBIT_OTH;
274
      }
275
    }
276 29b82486 Leszek Koltunski
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278
279
  private int getQuatIndex(int cubit)
280
    {
281 289ca015 Leszek Koltunski
    float[][] positions = getPositions();
282
    int len = positions.length;
283
284
    if( cubit>=0 && cubit<len )
285
      {
286
      float[] pos = positions[cubit];
287
      int type = getType(pos);
288
289
      switch(type)
290
        {
291
        case CUBIT_222:
292
        case CUBIT_111: return 0;
293
        case CUBIT_211:
294
        case CUBIT_311: return (pos[1]==pos[4]) ? (pos[0]==pos[3] ? 2 : 0) : 3;
295
        case CUBIT_221: if( pos[0]==pos[3] && pos[0]==pos[6] ) return 3;
296
                        if( pos[1]==pos[4] && pos[1]==pos[7] ) return 0;
297
                        if( pos[2]==pos[5] && pos[2]==pos[8] ) return 1;
298
        }
299
      }
300
301
    return 0;
302 29b82486 Leszek Koltunski
    }
303
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305
306 289ca015 Leszek Koltunski
  private int getSigIndex(float x, float y, float z)
307
    {
308
    if( x==-1.0f )
309
      {
310
           if( y==-1.0f ) return z==0.5f ? 4:9;
311
      else if( y==-0.5f ) return z==1.0f ? 14 : (z==0.0f ? 17:20);
312
      else if( y== 0.0f ) return z==0.5f ? 25:30;
313
      else if( y== 0.5f ) return z==1.0f ? 35 : (z==0.0f ? 38:41);
314
      else if( y== 1.0f ) return z==0.5f ? 46:51;
315
      }
316
    else if( x==-0.5f )
317
      {
318
           if( y==-1.0f ) return z==1.0f ? 1  : (z==0.0f ?  6:11);
319
      else if( y== 0.0f ) return z==1.0f ? 22 : (z==0.0f ? 27:32);
320
      else if( y== 1.0f ) return z==1.0f ? 43 : (z==0.0f ? 48:53);
321
      }
322
    else if( x==0.0f )
323
      {
324
           if( y==-1.0f ) return z==0.5f ? 3:8;
325
      else if( y==-0.5f ) return z==1.0f ? 13 : (z==0.0f ? 16:19);
326
      else if( y== 0.0f ) return z==0.5f ? 24:29;
327
      else if( y== 0.5f ) return z==1.0f ? 34 : (z==0.0f ? 37:40);
328
      else if( y== 1.0f ) return z==0.5f ? 45:50;
329
      }
330
    else if( x==0.5f )
331
      {
332
           if( y==-1.0f ) return z==1.0f ? 0  : (z==0.0f ?  5:10);
333
      else if( y== 0.0f ) return z==1.0f ? 21 : (z==0.0f ? 26:31);
334
      else if( y== 1.0f ) return z==1.0f ? 42 : (z==0.0f ? 47:52);
335
      }
336
    else if( x==1.0f )
337
      {
338
           if( y==-1.0f ) return z==0.5f ? 2:7;
339
      else if( y==-0.5f ) return z==1.0f ? 12 : (z==0.0f ? 15:18);
340
      else if( y== 0.0f ) return z==0.5f ? 23:28;
341
      else if( y== 0.5f ) return z==1.0f ? 33 : (z==0.0f ? 36:39);
342
      else if( y== 1.0f ) return z==0.5f ? 44:49;
343
      }
344
    else
345
      {
346
      android.util.Log.e("D", "ERROR! mx="+x);
347
      }
348
349
    return -1;
350
    }
351
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
354
  private long markConnection(float x1, float y1, float z1, float x2, float y2, float z2)
355 29b82486 Leszek Koltunski
    {
356 289ca015 Leszek Koltunski
    float dx = x1-x2;
357
    float dy = y1-y2;
358
    float dz = z1-z2;
359 3ee1d662 Leszek Koltunski
360 289ca015 Leszek Koltunski
    if( (dx==0 && dy==0 && (dz==1 || dz==-1) ) ||
361
        (dz==0 && dx==0 && (dy==1 || dy==-1) ) ||
362
        (dy==0 && dz==0 && (dx==1 || dx==-1) )  )
363 3ee1d662 Leszek Koltunski
      {
364 289ca015 Leszek Koltunski
      float mx = (x1+x2)/2;
365
      float my = (y1+y2)/2;
366
      float mz = (z1+z2)/2;
367
368
      int index = getSigIndex(mx,my,mz);
369
370
      return (1L<<index);
371
      }
372
373
    return 0;
374
    }
375
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
378 e85c8f90 Leszek Koltunski
  long markConnections(long signature, float[] position)
379 289ca015 Leszek Koltunski
    {
380
    int len = position.length/3;
381
382
    for(int i=0; i<len; i++)
383 29b82486 Leszek Koltunski
      {
384 289ca015 Leszek Koltunski
      float x = position[3*i  ];
385
      float y = position[3*i+1];
386
      float z = position[3*i+2];
387
388
      for(int j=i+1; j<len; j++)
389
        {
390
        signature |= markConnection(x,y,z,position[3*j],position[3*j+1],position[3*j+2]);
391
        }
392
      }
393
394
    return signature;
395 3ee1d662 Leszek Koltunski
    }
396
397 289ca015 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
398
399
  public ObjectShape getObjectShape(int variant)
400
    {
401
    int type,numTypes = mDims.length;
402
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
403
404
    if( type<numTypes )
405 29b82486 Leszek Koltunski
      {
406 289ca015 Leszek Koltunski
      int X = mDims[type][0];
407
      int Y = mDims[type][1];
408
      int Z = mDims[type][2];
409
410
      float[][] vertices =
411
        {
412
          {+0.5f*X,+0.5f*Y,+0.5f*Z},
413
          {+0.5f*X,+0.5f*Y,-0.5f*Z},
414
          {+0.5f*X,-0.5f*Y,+0.5f*Z},
415
          {+0.5f*X,-0.5f*Y,-0.5f*Z},
416
          {-0.5f*X,+0.5f*Y,+0.5f*Z},
417
          {-0.5f*X,+0.5f*Y,-0.5f*Z},
418
          {-0.5f*X,-0.5f*Y,+0.5f*Z},
419
          {-0.5f*X,-0.5f*Y,-0.5f*Z}
420
        };
421
422
      int[][] indices =
423
        {
424
          {2,3,1,0},
425
          {7,6,4,5},
426
          {4,0,1,5},
427
          {7,3,2,6},
428
          {6,2,0,4},
429
          {3,7,5,1},
430
        };
431
432
      return new ObjectShape(vertices, indices);
433
      }
434
435 a7c10d03 Leszek Koltunski
    float[][] positions = getPositions();
436
    int cubit,numCubits = positions.length;
437
438
    for(cubit=0; cubit<numCubits; cubit++)
439
      {
440
      if( mCubitVariantMap[cubit]==variant ) break;
441
      }
442
443
    if( cubit>=numCubits )
444
      {
445
      android.util.Log.e("D", "unknown variant: "+variant);
446
      return null;
447
      }
448
449 b1f0d55d Leszek Koltunski
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
450 a7c10d03 Leszek Koltunski
    return factory.createIrregularShape(variant,positions[cubit]);
451 289ca015 Leszek Koltunski
    }
452
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454
455
  public ObjectFaceShape getObjectFaceShape(int variant)
456
    {
457 d2d80cb5 Leszek Koltunski
    boolean roundCorners = DistortedLibrary.fastCompilationTF();
458 289ca015 Leszek Koltunski
    int type,numTypes = mDims.length;
459
    for(type=0; type<numTypes; type++) if( mTypeVariantMap[type]==variant ) break;
460 29b82486 Leszek Koltunski
461 289ca015 Leszek Koltunski
    if( type<numTypes )
462 29b82486 Leszek Koltunski
      {
463 db758bd0 Leszek Koltunski
      int val = roundCorners ? 0 : -1;
464 289ca015 Leszek Koltunski
      int X = mDims[type][0];
465
      int Y = mDims[type][1];
466
      int Z = mDims[type][2];
467
468 3bf19410 Leszek Koltunski
      float height        = isInIconMode() ? 0.001f : 0.048f;
469 289ca015 Leszek Koltunski
      int[] bandIndices   = { 0,0,1,1,2,2 };
470
      float[][] corners   = { {0.04f,0.15f} };
471 db758bd0 Leszek Koltunski
      int[] cornerIndices = { val,val,val,val,val,val,val,val };
472 289ca015 Leszek Koltunski
      int[] centerIndices = { 0,1,2,3,4,5,6,7 };
473
474
      int maxXY = Math.max(X,Y);
475
      int maxXZ = Math.max(X,Z);
476
      int maxYZ = Math.max(Y,Z);
477
478 01a68e12 Leszek Koltunski
      int angle = 45;
479
      float R = 0.25f;
480
      float S = 0.50f;
481
482 289ca015 Leszek Koltunski
      float[][] bands =
483
        {
484 cde08c52 Leszek Koltunski
          {height/maxYZ,angle,R,S,5,0,0},
485
          {height/maxXZ,angle,R,S,5,0,0},
486
          {height/maxXY,angle,R,S,5,0,0}
487 289ca015 Leszek Koltunski
        };
488
489
      float[][] centers =
490
        {
491
          {+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
492
          {+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
493
          {+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
494
          {+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)},
495
          {-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1)},
496
          {-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1)},
497
          {-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1)},
498
          {-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1)}
499
        };
500
501
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
502
      }
503
504 b1f0d55d Leszek Koltunski
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
505 db758bd0 Leszek Koltunski
    return factory.createIrregularFaceShape(variant, isInIconMode(), roundCorners );
506 29b82486 Leszek Koltunski
    }
507
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509
510 d0e6cf7f Leszek Koltunski
  public float[][] getCubitPositions(int[] numLayers)
511
    {
512
    return getPositions();
513
    }
514
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516
517
  public Static4D getCubitQuats(int cubit, int[] numLayers)
518 29b82486 Leszek Koltunski
    {
519
    if( mInitQuats ==null )
520
      {
521
      mInitQuats = new Static4D[]
522
        {
523
        new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // NULL
524
        new Static4D( SQ2/2,   0.0f,   0.0f, -SQ2/2),  // X
525
        new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // Y
526
        new Static4D(  0.0f,   0.0f,  SQ2/2, -SQ2/2),  // Z
527
        new Static4D( -0.5f,  +0.5f,  -0.5f,  +0.5f),  // ZX
528
        new Static4D( +0.5f,  +0.5f,  +0.5f,  -0.5f),  // YX
529
        };
530
      }
531
532
    return mInitQuats[getQuatIndex(cubit)];
533
    }
534
535
///////////////////////////////////////////////////////////////////////////////////////////////////
536
537 e30c522a Leszek Koltunski
  public int getNumCubitVariants(int[] numLayers)
538 29b82486 Leszek Koltunski
    {
539 a7c10d03 Leszek Koltunski
    int numVariants = 0;
540 289ca015 Leszek Koltunski
    float[][] positions = getPositions();
541
    boolean C111=false;
542
    boolean C211=false;
543
    boolean C311=false;
544
    boolean C221=false;
545
    boolean C222=false;
546
547
    int numCubits = positions.length;
548
    mCubitVariantMap = new int[numCubits];
549
550
    int numTypes = mDims.length;
551
    mTypeVariantMap = new int[numTypes];
552
    for(int i=0; i<numTypes; i++) mTypeVariantMap[i] = -1;
553
554
    for (int cubit=0; cubit<numCubits; cubit++)
555 7af68038 Leszek Koltunski
      {
556 289ca015 Leszek Koltunski
      int type = getType(positions[cubit]);
557
558
      switch (type)
559 7af68038 Leszek Koltunski
        {
560 a7c10d03 Leszek Koltunski
        case CUBIT_111: if (!C111) { C111 = true; mTypeVariantMap[CUBIT_111]=numVariants++; }
561 289ca015 Leszek Koltunski
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_111];
562
                        break;
563 a7c10d03 Leszek Koltunski
        case CUBIT_211: if (!C211) { C211 = true; mTypeVariantMap[CUBIT_211]=numVariants++; }
564 289ca015 Leszek Koltunski
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_211];
565
                        break;
566 a7c10d03 Leszek Koltunski
        case CUBIT_311: if (!C311) { C311 = true; mTypeVariantMap[CUBIT_311]=numVariants++; }
567 289ca015 Leszek Koltunski
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_311];
568
                        break;
569 a7c10d03 Leszek Koltunski
        case CUBIT_221: if (!C221) { C221 = true; mTypeVariantMap[CUBIT_221]=numVariants++; }
570 289ca015 Leszek Koltunski
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_221];
571
                        break;
572 a7c10d03 Leszek Koltunski
        case CUBIT_222: if (!C222) { C222 = true; mTypeVariantMap[CUBIT_222]=numVariants++; }
573 289ca015 Leszek Koltunski
                        mCubitVariantMap[cubit]=mTypeVariantMap[CUBIT_222];
574
                        break;
575 a7c10d03 Leszek Koltunski
        default       : mCubitVariantMap[cubit] = numVariants++;
576 7af68038 Leszek Koltunski
        }
577
      }
578
579 b1f0d55d Leszek Koltunski
    FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
580 52e3d46b Leszek Koltunski
    factory.prepare(numVariants,numLayers[0],numLayers[1],numLayers[2]);
581 a7c10d03 Leszek Koltunski
582
    return numVariants;
583 29b82486 Leszek Koltunski
    }
584
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586
587 e30c522a Leszek Koltunski
  public int getCubitVariant(int cubit, int[] numLayers)
588 29b82486 Leszek Koltunski
    {
589 289ca015 Leszek Koltunski
    return mCubitVariantMap[cubit];
590 29b82486 Leszek Koltunski
    }
591
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593
594 7bbfc84f Leszek Koltunski
  public float[][] getCuts(int[] numLayers)
595 29b82486 Leszek Koltunski
    {
596
    if( mCuts==null )
597
      {
598 b1f0d55d Leszek Koltunski
      mCuts = new float[3][];
599 29b82486 Leszek Koltunski
600 b1f0d55d Leszek Koltunski
      for(int axis=0; axis<3; axis++)
601 29b82486 Leszek Koltunski
        {
602 b1f0d55d Leszek Koltunski
        int len = numLayers[axis];
603
        float start = (2-len)*0.5f;
604
605
        if( len>=2 )
606
          {
607
          mCuts[axis] = new float[len-1];
608
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
609
          }
610 29b82486 Leszek Koltunski
        }
611
      }
612
613
    return mCuts;
614
    }
615
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617
618 59c20632 Leszek Koltunski
  public boolean[][] getLayerRotatable(int[] numLayers)
619 29b82486 Leszek Koltunski
    {
620 59c20632 Leszek Koltunski
    int numAxis = ROT_AXIS.length;
621
    boolean[][] layerRotatable = new boolean[numAxis][];
622 a57e6870 Leszek Koltunski
623 59c20632 Leszek Koltunski
    for(int i=0; i<numAxis; i++)
624
      {
625
      layerRotatable[i] = new boolean[numLayers[i]];
626
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
627 29b82486 Leszek Koltunski
      }
628 59c20632 Leszek Koltunski
629
    return layerRotatable;
630
    }
631
632
///////////////////////////////////////////////////////////////////////////////////////////////////
633
634 11fa413d Leszek Koltunski
  public int getTouchControlType()
635 59c20632 Leszek Koltunski
    {
636 b1f0d55d Leszek Koltunski
    return TC_CUBOID;
637 59c20632 Leszek Koltunski
    }
638
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640
641 11fa413d Leszek Koltunski
  public int getTouchControlSplit()
642 59c20632 Leszek Koltunski
    {
643
    return TYPE_NOT_SPLIT;
644 29b82486 Leszek Koltunski
    }
645
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647
648 59c20632 Leszek Koltunski
  public int[][][] getEnabled()
649
    {
650 9b1fe915 Leszek Koltunski
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
651 59c20632 Leszek Koltunski
    }
652
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654
655
  public float[] getDist3D(int[] numLayers)
656
    {
657 b1f0d55d Leszek Koltunski
    float x = numLayers[0];
658
    float y = numLayers[1];
659
    float z = numLayers[2];
660
    float a = (x+y+z)/1.5f;
661
662
    return new float[] {x/a,x/a,y/a,y/a,z/a,z/a};
663 4c9ca251 Leszek Koltunski
    }
664
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666
667
  public Static3D[] getFaceAxis()
668
    {
669
    return TouchControlHexahedron.FACE_AXIS;
670 59c20632 Leszek Koltunski
    }
671
672 3d766df3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
673
674 d53fb890 Leszek Koltunski
  public float getStickerRadius()
675 3d766df3 Leszek Koltunski
    {
676
    return 0.10f;
677
    }
678
679
///////////////////////////////////////////////////////////////////////////////////////////////////
680
681 d53fb890 Leszek Koltunski
  public float getStickerStroke()
682 3d766df3 Leszek Koltunski
    {
683 3bf19410 Leszek Koltunski
    return isInIconMode() ? 0.16f : 0.08f;
684 3d766df3 Leszek Koltunski
    }
685
686 00f4980d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
687
688 d53fb890 Leszek Koltunski
  public float[][] getStickerAngles()
689 00f4980d Leszek Koltunski
    {
690
    return null;
691
    }
692
693 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
694
// PUBLIC API
695
696
  public Static3D[] getRotationAxis()
697
    {
698
    return ROT_AXIS;
699
    }
700
701
///////////////////////////////////////////////////////////////////////////////////////////////////
702
703 beee90ab Leszek Koltunski
  public int[][] getBasicAngles()
704 29b82486 Leszek Koltunski
    {
705 b1f0d55d Leszek Koltunski
     if( mBasicAngle==null )
706 beee90ab Leszek Koltunski
      {
707 b1f0d55d Leszek Koltunski
      int[] num = getNumLayers();
708
      int numX = num[0];
709
      int numY = num[1];
710
      int numZ = num[2];
711
712
      int x = numY==numZ ? 4 : 2;
713
      int y = numX==numZ ? 4 : 2;
714
      int z = numX==numY ? 4 : 2;
715
716
      int[] tmpX = new int[numX];
717
      for(int i=0; i<numX; i++) tmpX[i] = x;
718
      int[] tmpY = new int[numY];
719
      for(int i=0; i<numY; i++) tmpY[i] = y;
720
      int[] tmpZ = new int[numZ];
721
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
722
723
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
724 beee90ab Leszek Koltunski
      }
725
726 29b82486 Leszek Koltunski
    return mBasicAngle;
727
    }
728
}