Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyBandagedAbstract.java @ 27249eea

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.TYPE_NOT_SPLIT;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.library.type.Static4D;
16
import org.distorted.objectlib.helpers.ObjectShape;
17
import org.distorted.objectlib.helpers.ObjectSignature;
18
import org.distorted.objectlib.main.InitData;
19
import org.distorted.objectlib.shape.ShapeHexahedron;
20
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
21

    
22
import java.io.InputStream;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

    
26
public abstract class TwistyBandagedAbstract extends ShapeHexahedron
27
{
28
  static final Static3D[] ROT_AXIS = new Static3D[]
29
         {
30
           new Static3D(1,0,0),
31
           new Static3D(0,1,0),
32
           new Static3D(0,0,1)
33
         };
34

    
35
  private int[][] mBasicAngle;
36
  private float[][] mCuts;
37
  private int[][] mSolvedQuatsAbstract;
38

    
39
  protected ObjectShape[] mTmpShapes;
40
  protected int mNumVariants;
41
  protected float[][] mPosition;
42
  protected ObjectSignature mSignature;
43

    
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

    
46
  public TwistyBandagedAbstract(InitData data, int meshState, int iconMode, float size, Static4D quat, Static3D move, float scale, InputStream stream)
47
    {
48
    super(data, meshState, iconMode, size, quat, move, scale, stream);
49
    }
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52
// return 0 if cubit is 'external' (it has at least two walls which belong to two different faces
53
// of the cuboid, faces which do not both rotate along the same axis! So: it is an edge, a corner,
54
// or a bandaged cubit which 'comes out' in two different, non-opposite, faces.
55
// Otherwise, if the cubit only comes out in one face or in two faces which are opposite to each other,
56
// return the index of the first of the three quats which rotate stuff in this face (so right or left
57
// return 1 because quats 1,2,3 are the ones rotating along the X axis)
58

    
59
  private int cubitIsExternal(float[] pos, float dx, float dy, float dz)
60
    {
61
    int len = pos.length/3;
62
    int x=0, y=0, z=0;
63

    
64
    for(int i=0; i<len; i++)
65
      {
66
      float cx = pos[3*i  ];
67
      float cy = pos[3*i+1];
68
      float cz = pos[3*i+2];
69

    
70
      if( cx>dx || cx<-dx ) x=1;
71
      if( cy>dy || cy<-dy ) y=1;
72
      if( cz>dz || cz<-dz ) z=1;
73
      }
74

    
75
    if( x+y+z>=2 ) return 0;
76

    
77
    if( x==1 ) return 1;
78
    if( y==1 ) return 4;
79
    if( z==1 ) return 7;
80

    
81
    android.util.Log.e("D", "ERROR: unsupported: internal cubit! ");
82
    return 0;
83
    }
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

    
87
  float[][] getPositions()
88
    {
89
    if( mPosition==null ) mPosition = getInitData().getPos();
90
    return mPosition;
91
    }
92

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

    
102
  @Override
103
  public int[][] getSolvedQuats()
104
    {
105
    if( mSolvedQuatsAbstract==null )
106
      {
107
      int[] numLayers = getNumLayers();
108
      float dx = 0.5f*(numLayers[0]-1) - 0.1f;
109
      float dy = 0.5f*(numLayers[1]-1) - 0.1f;
110
      float dz = 0.5f*(numLayers[2]-1) - 0.1f;
111

    
112
      float[][] pos = getPositions();
113
      int numTotal = pos.length;
114
      boolean[] isExternal = new boolean[numTotal];
115
      int[] internalQuat = new int[numTotal];
116
      int numExternal = 0;
117
      int pointer = 0;
118

    
119
      for(int cubit=0; cubit<numTotal; cubit++)
120
        {
121
        int q = cubitIsExternal(pos[cubit],dx,dy,dz);
122

    
123
        if( q<=0 )
124
          {
125
          isExternal[cubit] = true;
126
          numExternal++;
127
          }
128
        else
129
          {
130
          isExternal[cubit] = false;
131
          internalQuat[pointer] = q;
132
          pointer++;
133
          }
134
        }
135

    
136
      int numInternal = numTotal - numExternal;
137

    
138
      mSolvedQuatsAbstract = new int[numInternal+1][];
139
      mSolvedQuatsAbstract[0] = new int[numExternal+1];
140
      mSolvedQuatsAbstract[0][0] = numExternal;
141

    
142
      for(int i=0; i<numInternal; i++)
143
        {
144
        int q = internalQuat[i];
145
        mSolvedQuatsAbstract[i+1] = new int[5];
146
        mSolvedQuatsAbstract[i+1][0] = 1;
147
        mSolvedQuatsAbstract[i+1][2] = q;
148
        mSolvedQuatsAbstract[i+1][3] = q+1;
149
        mSolvedQuatsAbstract[i+1][4] = q+2;
150
        }
151

    
152
      int pointerExternal = 1;
153
      int pointerInternal = 1;
154

    
155
      for(int cubit=0; cubit<numTotal; cubit++)
156
        {
157
        if( isExternal[cubit] ) mSolvedQuatsAbstract[0][pointerExternal++] = cubit;
158
        else                    mSolvedQuatsAbstract[pointerInternal++][1] = cubit;
159
        }
160
      }
161

    
162
    return mSolvedQuatsAbstract;
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
// Computing scramble states of many a bandaged cubes takes way too long time and too much space.
167
// Return null here and turn to construction of scramble tables just-in-time (scrambleType=2)
168

    
169
  public int[][] getScrambleEdges()
170
    {
171
    return null;
172
    }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
  @Override
177
  public int getScrambleType()
178
    {
179
    return 2;
180
    }
181

    
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183

    
184
  public float[][] getCuts(int[] numLayers)
185
    {
186
    if( mCuts==null )
187
      {
188
      mCuts = new float[3][];
189

    
190
      for(int axis=0; axis<3; axis++)
191
        {
192
        int len = numLayers[axis];
193
        float start = (2-len)*0.5f;
194

    
195
        if( len>=2 )
196
          {
197
          mCuts[axis] = new float[len-1];
198
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
199
          }
200
        }
201
      }
202

    
203
    return mCuts;
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  public boolean[][] getLayerRotatable(int[] numLayers)
209
    {
210
    int numAxis = ROT_AXIS.length;
211
    boolean[][] layerRotatable = new boolean[numAxis][];
212

    
213
    for(int i=0; i<numAxis; i++)
214
      {
215
      layerRotatable[i] = new boolean[numLayers[i]];
216
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
217
      }
218

    
219
    return layerRotatable;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  public int getTouchControlSplit()
225
    {
226
    return TYPE_NOT_SPLIT;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  public int[][][] getEnabled()
232
    {
233
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
234
    }
235

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

    
238
  public Static3D[] getFaceAxis()
239
    {
240
    return TouchControlHexahedron.FACE_AXIS;
241
    }
242

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

    
245
  public float[][] getStickerAngles()
246
    {
247
    return null;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  public float[][] getCubitPositions(int[] numLayers)
253
    {
254
    return getPositions();
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  public Static3D[] getRotationAxis()
260
    {
261
    return ROT_AXIS;
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  public int[][] getBasicAngles()
267
    {
268
     if( mBasicAngle==null )
269
      {
270
      int[] num = getNumLayers();
271
      int numX = num[0];
272
      int numY = num[1];
273
      int numZ = num[2];
274

    
275
      int x = numY==numZ ? 4 : 2;
276
      int y = numX==numZ ? 4 : 2;
277
      int z = numX==numY ? 4 : 2;
278

    
279
      int[] tmpX = new int[numX];
280
      for(int i=0; i<numX; i++) tmpX[i] = x;
281
      int[] tmpY = new int[numY];
282
      for(int i=0; i<numY; i++) tmpY[i] = y;
283
      int[] tmpZ = new int[numZ];
284
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
285

    
286
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
287
      }
288

    
289
    return mBasicAngle;
290
    }
291
}
(2-2/41)