Project

General

Profile

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

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

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.InitAssets;
19
import org.distorted.objectlib.main.InitData;
20
import org.distorted.objectlib.shape.ShapeHexahedron;
21
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
22

    
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

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

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

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

    
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
135
      int numInternal = numTotal - numExternal;
136

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

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

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

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

    
161
    return mSolvedQuatsAbstract;
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  public float[][] getCuts(int[] numLayers)
167
    {
168
    if( mCuts==null )
169
      {
170
      mCuts = new float[3][];
171

    
172
      for(int axis=0; axis<3; axis++)
173
        {
174
        int len = numLayers[axis];
175
        float start = (2-len)*0.5f;
176

    
177
        if( len>=2 )
178
          {
179
          mCuts[axis] = new float[len-1];
180
          for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
181
          }
182
        }
183
      }
184

    
185
    return mCuts;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  public boolean[][] getLayerRotatable(int[] numLayers)
191
    {
192
    int numAxis = ROT_AXIS.length;
193
    boolean[][] layerRotatable = new boolean[numAxis][];
194

    
195
    for(int i=0; i<numAxis; i++)
196
      {
197
      layerRotatable[i] = new boolean[numLayers[i]];
198
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
199
      }
200

    
201
    return layerRotatable;
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205

    
206
  public int getTouchControlSplit()
207
    {
208
    return TYPE_NOT_SPLIT;
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  public int[][][] getEnabled()
214
    {
215
    return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  public Static3D[] getFaceAxis()
221
    {
222
    return TouchControlHexahedron.FACE_AXIS;
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  public float[][] getStickerAngles()
228
    {
229
    return null;
230
    }
231

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

    
234
  public float[][] getCubitPositions(int[] numLayers)
235
    {
236
    return getPositions();
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  public Static3D[] getRotationAxis()
242
    {
243
    return ROT_AXIS;
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  public int[][] getBasicAngles()
249
    {
250
     if( mBasicAngle==null )
251
      {
252
      int[] num = getNumLayers();
253
      int numX = num[0];
254
      int numY = num[1];
255
      int numZ = num[2];
256

    
257
      int x = numY==numZ ? 4 : 2;
258
      int y = numX==numZ ? 4 : 2;
259
      int z = numX==numY ? 4 : 2;
260

    
261
      int[] tmpX = new int[numX];
262
      for(int i=0; i<numX; i++) tmpX[i] = x;
263
      int[] tmpY = new int[numY];
264
      for(int i=0; i<numY; i++) tmpY[i] = y;
265
      int[] tmpZ = new int[numZ];
266
      for(int i=0; i<numZ; i++) tmpZ[i] = z;
267

    
268
      mBasicAngle = new int[][] { tmpX,tmpY,tmpZ };
269
      }
270

    
271
    return mBasicAngle;
272
    }
273
}
(2-2/41)