1
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2
|
// Copyright 2023 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.bandaged;
|
11
|
|
12
|
import static org.distorted.objectlib.main.TwistyObject.SQ2;
|
13
|
import static org.distorted.objectlib.main.TwistyObject.SQ3;
|
14
|
|
15
|
import org.distorted.library.type.Static3D;
|
16
|
import org.distorted.library.type.Static4D;
|
17
|
|
18
|
import org.distorted.objectlib.helpers.QuatGroupGenerator;
|
19
|
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
|
20
|
|
21
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
22
|
|
23
|
public class FactoryBandagedSkewb extends FactoryBandaged
|
24
|
{
|
25
|
private static FactoryBandagedSkewb mThis;
|
26
|
private Static4D[] mObjectQuats;
|
27
|
private int[] mCenterMap, mEdgeMap;
|
28
|
|
29
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
30
|
|
31
|
private FactoryBandagedSkewb()
|
32
|
{
|
33
|
|
34
|
}
|
35
|
|
36
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
37
|
|
38
|
public static FactoryBandagedSkewb getInstance()
|
39
|
{
|
40
|
if( mThis==null ) mThis = new FactoryBandagedSkewb();
|
41
|
return mThis;
|
42
|
}
|
43
|
|
44
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
45
|
|
46
|
public static int numCorners(int size)
|
47
|
{
|
48
|
return 8;
|
49
|
}
|
50
|
|
51
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
52
|
|
53
|
public static int numEdges(int size)
|
54
|
{
|
55
|
return (size-2)*12;
|
56
|
}
|
57
|
|
58
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
59
|
|
60
|
public static int numCenters(int size)
|
61
|
{
|
62
|
return 6*((size-2)*(size-2) + (size-1)*(size-1));
|
63
|
}
|
64
|
|
65
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
66
|
|
67
|
public float[][] getVertices(int[] numLayers, int variant)
|
68
|
{
|
69
|
float A = numLayers[0]==2 ? 1.0f : 0.75f;
|
70
|
|
71
|
switch(variant)
|
72
|
{
|
73
|
case 0: return new float[][] { {-A,0,0},{0,-A,0},{0,0,-A},{-A,-A,-A},{0,0,0} };
|
74
|
case 1: return new float[][] { {-A,0,0},{0,-A,0},{A,0,0},{0,A,0},{0,0,-A} };
|
75
|
case 2: return new float[][] { {-A,0,0},{A,0,0},{0,-A,0},{0,0,-A} };
|
76
|
}
|
77
|
|
78
|
return null;
|
79
|
}
|
80
|
|
81
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
82
|
|
83
|
public int[][] getIndices(int[] numLayers, int variant)
|
84
|
{
|
85
|
switch(variant)
|
86
|
{
|
87
|
case 0: return new int[][] { {0,1,4},{2,0,4},{1,2,4},{3,1,0},{3,2,1},{3,0,2} };
|
88
|
case 1: return new int[][] { {0,1,2,3},{4,1,0},{4,2,1},{4,3,2},{4,0,3} };
|
89
|
case 2: return new int[][] { {2,1,0},{3,0,1},{2,3,1},{3,2,0} };
|
90
|
}
|
91
|
|
92
|
return null;
|
93
|
}
|
94
|
|
95
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
96
|
|
97
|
public int getNumVariants(int[] numLayers)
|
98
|
{
|
99
|
return numLayers[0]==2 ? 2:3;
|
100
|
}
|
101
|
|
102
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
103
|
|
104
|
public float[][][] getPositions(int[] numLayers)
|
105
|
{
|
106
|
return createPositions(numLayers[0]);
|
107
|
}
|
108
|
|
109
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
110
|
|
111
|
public Static3D[] getNormals()
|
112
|
{
|
113
|
return TouchControlHexahedron.FACE_AXIS;
|
114
|
}
|
115
|
|
116
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
117
|
|
118
|
public int getElementVariant(int[] numLayers, float x, float y, float z)
|
119
|
{
|
120
|
if( numLayers[0]==2 )
|
121
|
{
|
122
|
return x*y*z==0 ? 1:0;
|
123
|
}
|
124
|
if( numLayers[0]==3 )
|
125
|
{
|
126
|
float m = (2*x)*(2*y)*(2*z);
|
127
|
if( m*m==729 ) return 0;
|
128
|
|
129
|
if( (x==0 && y!=0 && z!=0) ||
|
130
|
(x!=0 && y==0 && z!=0) ||
|
131
|
(x!=0 && y!=0 && z==0) ) return 2;
|
132
|
|
133
|
return 1;
|
134
|
}
|
135
|
|
136
|
return 0;
|
137
|
}
|
138
|
|
139
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
140
|
|
141
|
private void createQuats()
|
142
|
{
|
143
|
final Static3D[] axis = new Static3D[]
|
144
|
{
|
145
|
new Static3D( SQ3/3, SQ3/3, SQ3/3),
|
146
|
new Static3D( SQ3/3, SQ3/3,-SQ3/3),
|
147
|
new Static3D( SQ3/3,-SQ3/3, SQ3/3),
|
148
|
new Static3D( SQ3/3,-SQ3/3,-SQ3/3)
|
149
|
};
|
150
|
|
151
|
int[] tmp = new int[] {3,3};
|
152
|
int[][] basicAngles = new int[][] { tmp,tmp,tmp,tmp };
|
153
|
|
154
|
mObjectQuats = QuatGroupGenerator.computeGroup(axis,basicAngles);
|
155
|
}
|
156
|
|
157
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
158
|
|
159
|
public Static4D getElementQuat(int[] numLayers, int cubitIndex)
|
160
|
{
|
161
|
if( mObjectQuats==null ) createQuats();
|
162
|
if( mCenterMap ==null ) mCenterMap = new int[] { 0,9,1,4,2,3};
|
163
|
if( mEdgeMap ==null ) mEdgeMap = new int[] { 0,11,10,9, 2,5,8,3, 1,4,7,6 };
|
164
|
|
165
|
switch(cubitIndex)
|
166
|
{
|
167
|
case 0: return mObjectQuats[0]; // unit quat
|
168
|
case 1: return new Static4D( SQ2/2,0,0,SQ2/2); // 90 along X
|
169
|
case 2: return new Static4D(-SQ2/2,0,0,SQ2/2); // -90 along X
|
170
|
case 3: return mObjectQuats[9]; // 180 along X
|
171
|
case 4: return new Static4D(0, SQ2/2,0,SQ2/2); // 90 along Y
|
172
|
case 5: return mObjectQuats[11]; // 180 along Y
|
173
|
case 6: return mObjectQuats[10]; // 180 along Z
|
174
|
case 7: return new Static4D(SQ2/2,0,-SQ2/2,0); // 180 along (SQ2/2,0,-SQ2/2)
|
175
|
default: if( numLayers[0]==2 )
|
176
|
{
|
177
|
int index = mCenterMap[cubitIndex-8];
|
178
|
return mObjectQuats[index];
|
179
|
}
|
180
|
else
|
181
|
{
|
182
|
if( cubitIndex<38 ) return mObjectQuats[mCenterMap[(cubitIndex-8)/5]];
|
183
|
else return mObjectQuats[mEdgeMap[(cubitIndex-38)]];
|
184
|
}
|
185
|
}
|
186
|
}
|
187
|
|
188
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
189
|
|
190
|
public static float[][][] createPositions(int size)
|
191
|
{
|
192
|
int numVariants = (size==2 ? 2:3);
|
193
|
|
194
|
final float COR = 0.50f*size;
|
195
|
final float EDG = 0.50f*size;
|
196
|
final float CEN = 0.50f*size;
|
197
|
final float HAL = 0.25f*size;
|
198
|
|
199
|
float[][][] ret = new float[numVariants][][];
|
200
|
|
201
|
ret[0] = new float[][]
|
202
|
{
|
203
|
{ COR, COR, COR },
|
204
|
{ COR, COR,-COR },
|
205
|
{ COR,-COR, COR },
|
206
|
{ COR,-COR,-COR },
|
207
|
{-COR, COR, COR },
|
208
|
{-COR, COR,-COR },
|
209
|
{-COR,-COR, COR },
|
210
|
{-COR,-COR,-COR }
|
211
|
};
|
212
|
|
213
|
if( size==2 )
|
214
|
{
|
215
|
ret[1] = new float[][]
|
216
|
{
|
217
|
{ 0, 0, CEN },
|
218
|
{ 0, 0,-CEN },
|
219
|
{ 0, CEN, 0 },
|
220
|
{ 0,-CEN, 0 },
|
221
|
{ CEN, 0, 0 },
|
222
|
{-CEN, 0, 0 }
|
223
|
};
|
224
|
}
|
225
|
else
|
226
|
{
|
227
|
ret[1] = new float[][]
|
228
|
{
|
229
|
{ 0, 0, CEN },
|
230
|
{ HAL, HAL, CEN },
|
231
|
{ HAL,-HAL, CEN },
|
232
|
{-HAL, HAL, CEN },
|
233
|
{-HAL,-HAL, CEN },
|
234
|
{ 0, 0,-CEN },
|
235
|
{ HAL, HAL,-CEN },
|
236
|
{ HAL,-HAL,-CEN },
|
237
|
{-HAL, HAL,-CEN },
|
238
|
{-HAL,-HAL,-CEN },
|
239
|
{ 0, CEN, 0 },
|
240
|
{ HAL, CEN, HAL },
|
241
|
{ HAL, CEN,-HAL },
|
242
|
{-HAL, CEN, HAL },
|
243
|
{-HAL, CEN,-HAL },
|
244
|
{ 0,-CEN, 0 },
|
245
|
{ HAL,-CEN, HAL },
|
246
|
{ HAL,-CEN,-HAL },
|
247
|
{-HAL,-CEN, HAL },
|
248
|
{-HAL,-CEN,-HAL },
|
249
|
{ CEN, 0, 0 },
|
250
|
{ CEN, HAL, HAL },
|
251
|
{ CEN, HAL,-HAL },
|
252
|
{ CEN,-HAL, HAL },
|
253
|
{ CEN,-HAL,-HAL },
|
254
|
{-CEN, 0, 0 },
|
255
|
{-CEN, HAL, HAL },
|
256
|
{-CEN, HAL,-HAL },
|
257
|
{-CEN,-HAL, HAL },
|
258
|
{-CEN,-HAL,-HAL },
|
259
|
};
|
260
|
ret[2] = new float[][]
|
261
|
{
|
262
|
{ 0, EDG, EDG },
|
263
|
{ 0, EDG,-EDG },
|
264
|
{ 0,-EDG, EDG },
|
265
|
{ 0,-EDG,-EDG },
|
266
|
{ EDG, 0, EDG },
|
267
|
{ EDG, 0,-EDG },
|
268
|
{-EDG, 0, EDG },
|
269
|
{-EDG, 0,-EDG },
|
270
|
{ EDG, EDG, 0 },
|
271
|
{ EDG,-EDG, 0 },
|
272
|
{-EDG, EDG, 0 },
|
273
|
{-EDG,-EDG, 0 },
|
274
|
};
|
275
|
}
|
276
|
|
277
|
return ret;
|
278
|
}
|
279
|
|
280
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
281
|
|
282
|
public float[][] getDiameterAxis()
|
283
|
{
|
284
|
return new float[][]
|
285
|
{
|
286
|
{ SQ2/2, SQ2/2, 0 },
|
287
|
{ SQ2/2,-SQ2/2, 0 },
|
288
|
{ SQ2/2, 0, SQ2/2 },
|
289
|
{ SQ2/2, 0,-SQ2/2 },
|
290
|
{ 0, SQ2/2, SQ2/2 },
|
291
|
{ 0, SQ2/2,-SQ2/2 },
|
292
|
};
|
293
|
}
|
294
|
|
295
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
296
|
|
297
|
public float sizeCorrection(int[] numLayers)
|
298
|
{
|
299
|
return 1.0f;
|
300
|
}
|
301
|
|
302
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
303
|
|
304
|
public int diameterMap(float diameter)
|
305
|
{
|
306
|
if( diameter>=5.49f ) return 11;
|
307
|
if( diameter>1.1f && diameter<3.20f ) return 3;
|
308
|
return (int)(2*diameter+0.01f);
|
309
|
}
|
310
|
|
311
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
312
|
|
313
|
public float[] getDist3D(int[] numLayers)
|
314
|
{
|
315
|
final float d = TouchControlHexahedron.DIST3D*numLayers[0];
|
316
|
return new float[] {d,d,d,d,d,d};
|
317
|
}
|
318
|
|
319
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
320
|
|
321
|
public float[][] getBands(boolean iconMode, int[] numLayers)
|
322
|
{
|
323
|
float height= iconMode ? 0.001f : 0.055f;
|
324
|
int[] angle = {1,35,30,25,22,20,17,15,13,11,9};
|
325
|
float R = 0.3f;
|
326
|
float S = 0.5f;
|
327
|
int extraI = numLayers[0]==2 ? 2:1;
|
328
|
int extraV = numLayers[0]==2 ? 2:1;
|
329
|
int numVertA= numLayers[0]==2 ? 7:5;
|
330
|
int numVertI= numLayers[0]==2 ? 3:2;
|
331
|
|
332
|
return new float[][] { { 0.001f ,angle[ 0],R,S,numVertI,extraV,extraI},
|
333
|
{height ,angle[ 1],R,S,numVertA,extraV,extraI},
|
334
|
{height ,angle[ 1],R,S,numVertA,extraV,extraI},
|
335
|
{height/ 1.5f,angle[ 2],R,S,numVertA,extraV,extraI},
|
336
|
{height/ 2.0f,angle[ 3],R,S,numVertA,extraV,extraI},
|
337
|
{height/ 2.5f,angle[ 4],R,S,numVertA,extraV,extraI},
|
338
|
{height/ 3.0f,angle[ 5],R,S,numVertA,extraV,extraI},
|
339
|
{height/ 3.5f,angle[ 6],R,S,numVertA,extraV,extraI},
|
340
|
{height/ 4.0f,angle[ 7],R,S,numVertA,extraV,extraI},
|
341
|
{height/ 4.5f,angle[ 8],R,S,numVertA,extraV,extraI},
|
342
|
{height/ 5.0f,angle[ 9],R,S,numVertA,extraV,extraI},
|
343
|
{height/ 5.5f,angle[10],R,S,numVertA,extraV,extraI}
|
344
|
};
|
345
|
}
|
346
|
}
|