Project

General

Profile

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

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

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.helpers;
11

    
12
import org.distorted.library.helpers.QuatHelper;
13
import org.distorted.library.type.Static3D;
14
import org.distorted.library.type.Static4D;
15
import org.distorted.objectlib.main.TwistyObject;
16

    
17
///////////////////////////////////////////////////////////////////////////////////////////////////
18

    
19
public class ObjectShape
20
  {
21
  private static final float[] mTmp1 = new float[4];
22
  private static final float[] mTmp2 = new float[4];
23

    
24
  private final float[][] mVertices;
25
  private final int[][] mVertIndices;
26

    
27
  private final boolean mFacesMultigon;
28
  private final int mNumFaces;
29
  private final int[][][] mMultigonIndices;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
  public ObjectShape(float[][] vertices, int[][] vertIndices)
34
    {
35
    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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
    str.append("\n");
65

    
66
    for(float[] v : mVertices)
67
      {
68
      str.append(" (");
69
      str.append(v[0]);
70
      str.append(" ");
71
      str.append(v[1]);
72
      str.append(" ");
73
      str.append(v[2]);
74
      str.append(")");
75
      }
76

    
77
    if( mFacesMultigon )
78
      {
79
      int numFaces =mMultigonIndices.length;
80
      str.append("\nnumFaces: ");
81
      str.append(numFaces);
82
      str.append("\n");
83

    
84
      for(int[][] mMultigonIndex : mMultigonIndices)
85
        {
86
        for(int[] multigonIndex : mMultigonIndex)
87
          {
88
          str.append(" [");
89
          for(int index : multigonIndex)
90
            {
91
            str.append(" ");
92
            str.append(index);
93
            }
94
          str.append("]");
95
          }
96
        str.append("\n");
97
        }
98
      }
99
    else
100
      {
101
      int numFaces =mVertIndices.length;
102
      str.append("\nnumFaces: ");
103
      str.append(numFaces);
104
      str.append("\n   ");
105

    
106
      for(int[] vertIndex : mVertIndices)
107
        {
108
        for(int index : vertIndex)
109
          {
110
          str.append(" ");
111
          str.append(index);
112
          }
113
        str.append("\n   ");
114
        }
115
      }
116

    
117
    android.util.Log.e("D", "ObjectShape: \n"+str);
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  public int getNumFaces()
123
    {
124
    return mNumFaces;
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  public boolean isMultigon()
130
    {
131
    return mFacesMultigon;
132
    }
133

    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

    
136
  public float[][] getVertices()
137
    {
138
    return mVertices;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  public int[][] getVertIndices()
144
    {
145
    return mVertIndices;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  public int[][][] getMultigonIndices()
151
    {
152
    return mMultigonIndices;
153
    }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
  public float[] getFirstVertexInFace(int face)
158
    {
159
    if( mFacesMultigon )
160
      {
161
      int[][][] indices=getMultigonIndices();
162
      int vertIndex=indices[face][0][0];
163
      return getVertices()[vertIndex];
164
      }
165
    else
166
      {
167
      int[][] indices=getVertIndices();
168
      int vertIndex=indices[face][0];
169
      return getVertices()[vertIndex];
170
      }
171
    }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

    
175
  public static int computeNumComponents(ObjectShape[] shapes)
176
    {
177
    int ret = 0;
178

    
179
    for( ObjectShape shape : shapes )
180
      {
181
      int numShape = shape.mNumFaces;
182
      if( numShape>ret ) ret = numShape;
183
      }
184

    
185
    return ret;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
// take vertex, apply quat, apply move, write to output
190

    
191
  private static void computeVertex(float[] output, float[] vertex, float[] move, Static4D quat)
192
    {
193
    QuatHelper.rotateVectorByQuat(mTmp2,vertex[0],vertex[1],vertex[2],1.0f,quat);
194

    
195
    int numMoves = move.length/3;
196
    float moveX=0.0f, moveY=0.0f, moveZ=0.0f;
197

    
198
    for(int m=0; m<numMoves; m++)
199
      {
200
      moveX += move[3*m  ];
201
      moveY += move[3*m+1];
202
      moveZ += move[3*m+2];
203
      }
204

    
205
    output[0] = mTmp2[0] + moveX/numMoves;
206
    output[1] = mTmp2[1] + moveY/numMoves;
207
    output[2] = mTmp2[2] + moveZ/numMoves;
208
    }
209

    
210
///////////////////////////////////////////////////////////////////////////////////////////////////
211

    
212
  private static boolean vertInFace(float[] vertex, Static3D faceAxis, float dist)
213
    {
214
    final float MAX_ERROR = 0.04f;  // Rex Cube requires this
215

    
216
    float x= faceAxis.get0();
217
    float y= faceAxis.get1();
218
    float z= faceAxis.get2();
219

    
220
    float a = vertex[0]*x + vertex[1]*y + vertex[2]*z;
221
    float diff = a - dist;
222

    
223
    return diff>-MAX_ERROR && diff<MAX_ERROR;
224
    }
225

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

    
228
  private static boolean indicesContain(int[][] indices, int index)
229
    {
230
    for( int[] ind : indices )
231
      for( int i : ind )
232
        if( i==index ) return true;
233

    
234
    return false;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  private static boolean indicesContain(int[] indices, int index)
240
    {
241
    for( int j : indices )
242
      if( j==index ) return true;
243

    
244
    return false;
245
    }
246

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

    
249
  private static int[] computeCubitFaceColors(ObjectShape shape, float[] move, Static4D quat, Static3D[] faceAxis, float[] dist3D, float size)
250
    {
251
    float[][] vertices = shape.getVertices();
252
    int numVert = vertices.length;
253
    int numPuzzleFaces = faceAxis.length;
254
    int numCubitFaces = shape.mNumFaces;
255
    int[] cubitFaceColor = new int[numCubitFaces];
256
    for(int face=0; face<numCubitFaces; face++) cubitFaceColor[face] = 0xffffffff;
257

    
258
    for(int vert=0; vert<numVert; vert++)
259
      {
260
      computeVertex(mTmp1,vertices[vert],move,quat);
261
      int vertBelongsBitmap = 0x00000000;
262

    
263
      for(int face=0; face<numPuzzleFaces; face++)
264
        if( vertInFace(mTmp1,faceAxis[face],dist3D[face]*size) ) vertBelongsBitmap |= (1<<face);
265

    
266
      if( shape.mFacesMultigon )
267
        {
268
        for(int index=0; index<numCubitFaces; index++)
269
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mMultigonIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
270
        }
271
      else
272
        {
273
        for(int index=0; index<numCubitFaces; index++)
274
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mVertIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
275
        }
276
      }
277

    
278
    return cubitFaceColor;
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
  private static void translateFromBitmap(int cubit, int[] colorsBitmap)
284
    {
285
    int len = colorsBitmap.length;
286

    
287
    for(int face=0; face<len; face++)
288
      {
289
      if( colorsBitmap[face]==0 ) colorsBitmap[face] = -1;
290
      else
291
        {
292
        int shift=0;
293

    
294
        while( (colorsBitmap[face]&0x1) != 1 )
295
          {
296
          colorsBitmap[face]>>=1;
297
          shift++;
298
          }
299

    
300
        if( colorsBitmap[face]!=1 )
301
          {
302
          android.util.Log.e("D", "ERROR, cubit= "+cubit+" face "+face+" seems to belong to "+shift+" and still "+colorsBitmap[face]);
303
          }
304

    
305
        colorsBitmap[face] = shift;
306
        }
307
      }
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  public static int[][] computeColors(ObjectShape[] shapes, float[][] moves, Static4D[] quats, TwistyObject object)
313
    {
314
    int numCubits = moves.length;
315
    int[][] colors = new int[numCubits][];
316
    int[] numLayers = object.getNumLayers();
317
    Static3D[] faceAxis = object.getFaceAxis();
318
    float[] dist3D = object.getDist3D(numLayers);
319
    float size = object.getSize();
320

    
321
    for(int cubit=0; cubit<numCubits; cubit++)
322
      {
323
      int variant = object.getCubitVariant(cubit,numLayers);
324
      colors[cubit] = computeCubitFaceColors(shapes[variant],moves[cubit],quats[cubit],faceAxis,dist3D,size);
325
      translateFromBitmap(cubit,colors[cubit]);
326
      }
327

    
328
    return colors;
329
    }
330
  }
(7-7/13)