Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / helpers / ObjectShape.java @ ae9d9227

1 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 a7a40b3c Leszek Koltunski
// 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 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10 198c5bf0 Leszek Koltunski
package org.distorted.objectlib.helpers;
11 29b82486 Leszek Koltunski
12 aacf5e27 Leszek Koltunski
import org.distorted.library.helpers.QuatHelper;
13 9b1fe915 Leszek Koltunski
import org.distorted.library.type.Static3D;
14 5931ae4d Leszek Koltunski
import org.distorted.library.type.Static4D;
15
import org.distorted.objectlib.main.TwistyObject;
16
17 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
18
19
public class ObjectShape
20
  {
21 9b1fe915 Leszek Koltunski
  private static final float[] mTmp1 = new float[4];
22
  private static final float[] mTmp2 = new float[4];
23
24 57ef6378 Leszek Koltunski
  private final float[][] mVertices;
25 29b82486 Leszek Koltunski
  private final int[][] mVertIndices;
26
27 fe3dec09 Leszek Koltunski
  private final boolean mFacesMultigon;
28
  private final int mNumFaces;
29
  private final int[][][] mMultigonIndices;
30
31 29b82486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
32
33 59a971c1 Leszek Koltunski
  public ObjectShape(float[][] vertices, int[][] vertIndices)
34 29b82486 Leszek Koltunski
    {
35 fe3dec09 Leszek Koltunski
    mVertices        = vertices;
36
    mVertIndices     = vertIndices;
37
    mMultigonIndices = null;
38
    mFacesMultigon   = false;
39
    mNumFaces        = vertIndices.length;
40
    }
41
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43
44
  public ObjectShape(float[][] vertices, int[][][] vertIndices)
45
    {
46
    mVertices       = vertices;
47
    mVertIndices    = null;
48
    mMultigonIndices= vertIndices;
49
    mFacesMultigon  = true;
50
    mNumFaces       = vertIndices.length;
51
    }
52
53 b76da174 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
54
55
  public void debug()
56
    {
57
    StringBuilder str = new StringBuilder();
58
    str.append("isMultigon: ");
59
    str.append(mFacesMultigon);
60
    str.append("\n");
61
    str.append("numVertices: ");
62
    int numV =mVertices.length;
63
    str.append(numV);
64 3821ebef leszek
    str.append("\n");
65 b76da174 leszek
66
    for(float[] v : mVertices)
67
      {
68 94c50a70 leszek
      str.append(" {");
69 b76da174 leszek
      str.append(v[0]);
70 94c50a70 leszek
      str.append("f, ");
71 b76da174 leszek
      str.append(v[1]);
72 94c50a70 leszek
      str.append("f, ");
73 b76da174 leszek
      str.append(v[2]);
74 94c50a70 leszek
      str.append("f },\n");
75 b76da174 leszek
      }
76
77
    if( mFacesMultigon )
78
      {
79
      int numFaces =mMultigonIndices.length;
80 94c50a70 leszek
      str.append("numFaces: ");
81 b76da174 leszek
      str.append(numFaces);
82
      str.append("\n");
83
84
      for(int[][] mMultigonIndex : mMultigonIndices)
85
        {
86
        for(int[] multigonIndex : mMultigonIndex)
87
          {
88 94c50a70 leszek
          int len = multigonIndex.length;
89
          str.append(" {");
90
91
          for(int i=0; i<len; i++)
92 b76da174 leszek
            {
93 94c50a70 leszek
            str.append( i==0 ? " " : ", ");
94
            str.append(multigonIndex[i]);
95 b76da174 leszek
            }
96 94c50a70 leszek
          str.append("},");
97 b76da174 leszek
          }
98 3821ebef leszek
        str.append("\n");
99 b76da174 leszek
        }
100
      }
101
    else
102
      {
103
      int numFaces =mVertIndices.length;
104
      str.append("\nnumFaces: ");
105
      str.append(numFaces);
106
      str.append("\n   ");
107
108
      for(int[] vertIndex : mVertIndices)
109
        {
110
        for(int index : vertIndex)
111
          {
112
          str.append(" ");
113
          str.append(index);
114
          }
115
        str.append("\n   ");
116
        }
117
      }
118
119
    android.util.Log.e("D", "ObjectShape: \n"+str);
120
    }
121
122 fe3dec09 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124
  public int getNumFaces()
125
    {
126
    return mNumFaces;
127
    }
128
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
131
  public boolean isMultigon()
132
    {
133
    return mFacesMultigon;
134 29b82486 Leszek Koltunski
    }
135
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137
138 57ef6378 Leszek Koltunski
  public float[][] getVertices()
139 29b82486 Leszek Koltunski
    {
140
    return mVertices;
141
    }
142
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144
145
  public int[][] getVertIndices()
146
    {
147
    return mVertIndices;
148
    }
149
150 fe3dec09 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152
  public int[][][] getMultigonIndices()
153
    {
154
    return mMultigonIndices;
155
    }
156
157 efa5bc1e leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
158
159
  public float[] getFirstVertexInFace(int face)
160
    {
161
    if( mFacesMultigon )
162
      {
163
      int[][][] indices=getMultigonIndices();
164
      int vertIndex=indices[face][0][0];
165
      return getVertices()[vertIndex];
166
      }
167
    else
168
      {
169
      int[][] indices=getVertIndices();
170
      int vertIndex=indices[face][0];
171
      return getVertices()[vertIndex];
172
      }
173
    }
174
175 c187cb69 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
176
177 ac97ecc0 Leszek Koltunski
  public static int computeNumComponents(ObjectShape[] shapes)
178 c187cb69 Leszek Koltunski
    {
179 ac97ecc0 Leszek Koltunski
    int ret = 0;
180
181
    for( ObjectShape shape : shapes )
182
      {
183 89c2b479 Leszek Koltunski
      int numShape = shape.mNumFaces;
184 ac97ecc0 Leszek Koltunski
      if( numShape>ret ) ret = numShape;
185
      }
186
187
    return ret;
188 c187cb69 Leszek Koltunski
    }
189 5931ae4d Leszek Koltunski
190 9b1fe915 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
191
// take vertex, apply quat, apply move, write to output
192
193
  private static void computeVertex(float[] output, float[] vertex, float[] move, Static4D quat)
194
    {
195
    QuatHelper.rotateVectorByQuat(mTmp2,vertex[0],vertex[1],vertex[2],1.0f,quat);
196
197
    int numMoves = move.length/3;
198
    float moveX=0.0f, moveY=0.0f, moveZ=0.0f;
199
200
    for(int m=0; m<numMoves; m++)
201
      {
202
      moveX += move[3*m  ];
203
      moveY += move[3*m+1];
204
      moveZ += move[3*m+2];
205
      }
206
207
    output[0] = mTmp2[0] + moveX/numMoves;
208
    output[1] = mTmp2[1] + moveY/numMoves;
209
    output[2] = mTmp2[2] + moveZ/numMoves;
210
    }
211
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213
214
  private static boolean vertInFace(float[] vertex, Static3D faceAxis, float dist)
215
    {
216 802fe251 Leszek Koltunski
    final float MAX_ERROR = 0.04f;  // Rex Cube requires this
217 9b1fe915 Leszek Koltunski
218
    float x= faceAxis.get0();
219
    float y= faceAxis.get1();
220
    float z= faceAxis.get2();
221
222
    float a = vertex[0]*x + vertex[1]*y + vertex[2]*z;
223
    float diff = a - dist;
224
225
    return diff>-MAX_ERROR && diff<MAX_ERROR;
226
    }
227
228 5931ae4d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
229
230 89c2b479 Leszek Koltunski
  private static boolean indicesContain(int[][] indices, int index)
231
    {
232
    for( int[] ind : indices )
233
      for( int i : ind )
234
        if( i==index ) return true;
235
236
    return false;
237
    }
238
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240
241
  private static boolean indicesContain(int[] indices, int index)
242 5931ae4d Leszek Koltunski
    {
243 9b1fe915 Leszek Koltunski
    for( int j : indices )
244
      if( j==index ) return true;
245
246
    return false;
247
    }
248
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251
  private static int[] computeCubitFaceColors(ObjectShape shape, float[] move, Static4D quat, Static3D[] faceAxis, float[] dist3D, float size)
252
    {
253
    float[][] vertices = shape.getVertices();
254
    int numVert = vertices.length;
255 89c2b479 Leszek Koltunski
    int numPuzzleFaces = faceAxis.length;
256
    int numCubitFaces = shape.mNumFaces;
257
    int[] cubitFaceColor = new int[numCubitFaces];
258
    for(int face=0; face<numCubitFaces; face++) cubitFaceColor[face] = 0xffffffff;
259 9b1fe915 Leszek Koltunski
260
    for(int vert=0; vert<numVert; vert++)
261
      {
262
      computeVertex(mTmp1,vertices[vert],move,quat);
263
      int vertBelongsBitmap = 0x00000000;
264
265 89c2b479 Leszek Koltunski
      for(int face=0; face<numPuzzleFaces; face++)
266 9b1fe915 Leszek Koltunski
        if( vertInFace(mTmp1,faceAxis[face],dist3D[face]*size) ) vertBelongsBitmap |= (1<<face);
267
268 89c2b479 Leszek Koltunski
      if( shape.mFacesMultigon )
269
        {
270
        for(int index=0; index<numCubitFaces; index++)
271
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mMultigonIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
272
        }
273
      else
274
        {
275
        for(int index=0; index<numCubitFaces; index++)
276
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mVertIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
277
        }
278 9b1fe915 Leszek Koltunski
      }
279
280
    return cubitFaceColor;
281
    }
282
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284
285
  private static void translateFromBitmap(int cubit, int[] colorsBitmap)
286
    {
287
    int len = colorsBitmap.length;
288
289
    for(int face=0; face<len; face++)
290
      {
291
      if( colorsBitmap[face]==0 ) colorsBitmap[face] = -1;
292
      else
293
        {
294
        int shift=0;
295
296
        while( (colorsBitmap[face]&0x1) != 1 )
297
          {
298
          colorsBitmap[face]>>=1;
299
          shift++;
300
          }
301
302
        if( colorsBitmap[face]!=1 )
303
          {
304
          android.util.Log.e("D", "ERROR, cubit= "+cubit+" face "+face+" seems to belong to "+shift+" and still "+colorsBitmap[face]);
305
          }
306
307
        colorsBitmap[face] = shift;
308
        }
309
      }
310 5931ae4d Leszek Koltunski
    }
311
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314 9b1fe915 Leszek Koltunski
  public static int[][] computeColors(ObjectShape[] shapes, float[][] moves, Static4D[] quats, TwistyObject object)
315 5931ae4d Leszek Koltunski
    {
316 9b1fe915 Leszek Koltunski
    int numCubits = moves.length;
317 5931ae4d Leszek Koltunski
    int[][] colors = new int[numCubits][];
318
    int[] numLayers = object.getNumLayers();
319 9b1fe915 Leszek Koltunski
    Static3D[] faceAxis = object.getFaceAxis();
320
    float[] dist3D = object.getDist3D(numLayers);
321
    float size = object.getSize();
322 5931ae4d Leszek Koltunski
323
    for(int cubit=0; cubit<numCubits; cubit++)
324
      {
325
      int variant = object.getCubitVariant(cubit,numLayers);
326 9b1fe915 Leszek Koltunski
      colors[cubit] = computeCubitFaceColors(shapes[variant],moves[cubit],quats[cubit],faceAxis,dist3D,size);
327
      translateFromBitmap(cubit,colors[cubit]);
328 5931ae4d Leszek Koltunski
      }
329
330
    return colors;
331
    }
332 29b82486 Leszek Koltunski
  }