Project

General

Profile

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

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

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 int getNumFaces()
56
    {
57
    return mNumFaces;
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  public boolean isMultigon()
63
    {
64
    return mFacesMultigon;
65
    }
66

    
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68

    
69
  public float[][] getVertices()
70
    {
71
    return mVertices;
72
    }
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  public int[][] getVertIndices()
77
    {
78
    return mVertIndices;
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  public int[][][] getMultigonIndices()
84
    {
85
    return mMultigonIndices;
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
  public float[] getFirstVertexInFace(int face)
91
    {
92
    if( mFacesMultigon )
93
      {
94
      int[][][] indices=getMultigonIndices();
95
      int vertIndex=indices[face][0][0];
96
      return getVertices()[vertIndex];
97
      }
98
    else
99
      {
100
      int[][] indices=getVertIndices();
101
      int vertIndex=indices[face][0];
102
      return getVertices()[vertIndex];
103
      }
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

    
108
  public static int computeNumComponents(ObjectShape[] shapes)
109
    {
110
    int ret = 0;
111

    
112
    for( ObjectShape shape : shapes )
113
      {
114
      int numShape = shape.mNumFaces;
115
      if( numShape>ret ) ret = numShape;
116
      }
117

    
118
    return ret;
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122
// take vertex, apply quat, apply move, write to output
123

    
124
  private static void computeVertex(float[] output, float[] vertex, float[] move, Static4D quat)
125
    {
126
    QuatHelper.rotateVectorByQuat(mTmp2,vertex[0],vertex[1],vertex[2],1.0f,quat);
127

    
128
    int numMoves = move.length/3;
129
    float moveX=0.0f, moveY=0.0f, moveZ=0.0f;
130

    
131
    for(int m=0; m<numMoves; m++)
132
      {
133
      moveX += move[3*m  ];
134
      moveY += move[3*m+1];
135
      moveZ += move[3*m+2];
136
      }
137

    
138
    output[0] = mTmp2[0] + moveX/numMoves;
139
    output[1] = mTmp2[1] + moveY/numMoves;
140
    output[2] = mTmp2[2] + moveZ/numMoves;
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  private static boolean vertInFace(float[] vertex, Static3D faceAxis, float dist)
146
    {
147
    final float MAX_ERROR = 0.04f;  // Rex Cube requires this
148

    
149
    float x= faceAxis.get0();
150
    float y= faceAxis.get1();
151
    float z= faceAxis.get2();
152

    
153
    float a = vertex[0]*x + vertex[1]*y + vertex[2]*z;
154
    float diff = a - dist;
155

    
156
    return diff>-MAX_ERROR && diff<MAX_ERROR;
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  private static boolean indicesContain(int[][] indices, int index)
162
    {
163
    for( int[] ind : indices )
164
      for( int i : ind )
165
        if( i==index ) return true;
166

    
167
    return false;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  private static boolean indicesContain(int[] indices, int index)
173
    {
174
    for( int j : indices )
175
      if( j==index ) return true;
176

    
177
    return false;
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  private static int[] computeCubitFaceColors(ObjectShape shape, float[] move, Static4D quat, Static3D[] faceAxis, float[] dist3D, float size)
183
    {
184
    float[][] vertices = shape.getVertices();
185
    int numVert = vertices.length;
186
    int numPuzzleFaces = faceAxis.length;
187
    int numCubitFaces = shape.mNumFaces;
188
    int[] cubitFaceColor = new int[numCubitFaces];
189
    for(int face=0; face<numCubitFaces; face++) cubitFaceColor[face] = 0xffffffff;
190

    
191
    for(int vert=0; vert<numVert; vert++)
192
      {
193
      computeVertex(mTmp1,vertices[vert],move,quat);
194
      int vertBelongsBitmap = 0x00000000;
195

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

    
199
      if( shape.mFacesMultigon )
200
        {
201
        for(int index=0; index<numCubitFaces; index++)
202
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mMultigonIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
203
        }
204
      else
205
        {
206
        for(int index=0; index<numCubitFaces; index++)
207
          if( cubitFaceColor[index]!=0 && indicesContain(shape.mVertIndices[index],vert) ) cubitFaceColor[index] &= vertBelongsBitmap;
208
        }
209
      }
210

    
211
    return cubitFaceColor;
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  private static void translateFromBitmap(int cubit, int[] colorsBitmap)
217
    {
218
    int len = colorsBitmap.length;
219

    
220
    for(int face=0; face<len; face++)
221
      {
222
      if( colorsBitmap[face]==0 ) colorsBitmap[face] = -1;
223
      else
224
        {
225
        int shift=0;
226

    
227
        while( (colorsBitmap[face]&0x1) != 1 )
228
          {
229
          colorsBitmap[face]>>=1;
230
          shift++;
231
          }
232

    
233
        if( colorsBitmap[face]!=1 )
234
          {
235
          android.util.Log.e("D", "ERROR, cubit= "+cubit+" face "+face+" seems to belong to "+shift+" and still "+colorsBitmap[face]);
236
          }
237

    
238
        colorsBitmap[face] = shift;
239
        }
240
      }
241
    }
242

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

    
245
  public static int[][] computeColors(ObjectShape[] shapes, float[][] moves, Static4D[] quats, TwistyObject object)
246
    {
247
    int numCubits = moves.length;
248
    int[][] colors = new int[numCubits][];
249
    int[] numLayers = object.getNumLayers();
250
    Static3D[] faceAxis = object.getFaceAxis();
251
    float[] dist3D = object.getDist3D(numLayers);
252
    float size = object.getSize();
253

    
254
    for(int cubit=0; cubit<numCubits; cubit++)
255
      {
256
      int variant = object.getCubitVariant(cubit,numLayers);
257
      colors[cubit] = computeCubitFaceColors(shapes[variant],moves[cubit],quats[cubit],faceAxis,dist3D,size);
258
      translateFromBitmap(cubit,colors[cubit]);
259
      }
260

    
261
    return colors;
262
    }
263
  }
(10-10/16)