Project

General

Profile

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

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

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

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

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

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

    
186
    return mCuts;
187
    }
188

    
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

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

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

    
202
    return layerRotatable;
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

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

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213

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

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

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

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

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

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

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

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

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

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

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

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

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

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

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