1 |
848ceb0b
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
// Copyright 2022 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 |
a2122d42
|
leszek
|
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CUBOID;
|
13 |
848ceb0b
|
leszek
|
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
|
14 |
|
|
|
15 |
0431e308
|
leszek
|
import org.distorted.library.effect.EffectName;
|
16 |
848ceb0b
|
leszek
|
import org.distorted.library.type.Static3D;
|
17 |
|
|
import org.distorted.library.type.Static4D;
|
18 |
|
|
import org.distorted.objectlib.helpers.FactoryCubit;
|
19 |
|
|
import org.distorted.objectlib.helpers.ObjectFaceShape;
|
20 |
|
|
import org.distorted.objectlib.helpers.ObjectShape;
|
21 |
|
|
import org.distorted.objectlib.helpers.ObjectVertexEffects;
|
22 |
|
|
import org.distorted.objectlib.main.InitAssets;
|
23 |
|
|
import org.distorted.objectlib.metadata.ListObjects;
|
24 |
|
|
import org.distorted.objectlib.metadata.Metadata;
|
25 |
|
|
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
|
26 |
|
|
import org.distorted.objectlib.shape.ShapeHexahedron;
|
27 |
|
|
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
|
28 |
|
|
|
29 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
30 |
|
|
|
31 |
|
|
public class TwistyPenrose extends ShapeHexahedron
|
32 |
|
|
{
|
33 |
|
|
static final Static3D[] ROT_AXIS = new Static3D[]
|
34 |
|
|
{
|
35 |
|
|
new Static3D(1,0,0),
|
36 |
|
|
new Static3D(0,1,0),
|
37 |
|
|
new Static3D(0,0,1)
|
38 |
|
|
};
|
39 |
|
|
|
40 |
|
|
private int[][] mEdges;
|
41 |
|
|
private int[][] mBasicAngle;
|
42 |
|
|
private float[][] mCuts;
|
43 |
|
|
private int[] mQuatIndex;
|
44 |
|
|
private int[][] mFaceMap;
|
45 |
|
|
|
46 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
47 |
|
|
|
48 |
|
|
public TwistyPenrose(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
|
49 |
|
|
{
|
50 |
|
|
super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
|
51 |
|
|
}
|
52 |
|
|
|
53 |
074a0284
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
54 |
|
|
// here we cannot automatically detect the outer monochromatic walls -> use the old way.
|
55 |
|
|
|
56 |
|
|
@Override
|
57 |
|
|
public int getSolvedFunctionIndex()
|
58 |
|
|
{
|
59 |
|
|
return 0;
|
60 |
|
|
}
|
61 |
|
|
|
62 |
848ceb0b
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
63 |
0431e308
|
leszek
|
// { -0.5f, -0.49999997f, 0.5f, -0.49999997f, 0.5f, 0.49999997f, -0.5f, 0.49999997f}
|
64 |
|
|
// { -0.24999999f, 0.5f, -0.24999999f, -0.24999999f, 0.5f, -0.24999999f}
|
65 |
|
|
// { -0.5f, -0.08578644f, -0.08578644f, -0.49999997f, 0.5f, 0.08578644f, 0.085786454f, 0.5f}
|
66 |
848ceb0b
|
leszek
|
|
67 |
|
|
@Override
|
68 |
|
|
public void adjustStickerCoords()
|
69 |
|
|
{
|
70 |
1b7c08b0
|
leszek
|
final float A = 0.50f;
|
71 |
|
|
final float B = 0.25f;
|
72 |
|
|
final float C = 0.08578644f;
|
73 |
|
|
final float D = 0.23f;
|
74 |
b1050226
|
leszek
|
|
75 |
1b7c08b0
|
leszek
|
final float E = (A+D)/5;
|
76 |
|
|
final float F = 0.003f;
|
77 |
|
|
final float G = (A+D)/2;
|
78 |
|
|
final float H = 0.000f;
|
79 |
b1050226
|
leszek
|
|
80 |
1b7c08b0
|
leszek
|
mStickerCoords = new float[][][][]
|
81 |
|
|
{
|
82 |
b1050226
|
leszek
|
{{{-A, -A}, {A, -A}, {A, A}, {-A, A}}},
|
83 |
|
|
{{{-B, A}, {-B, -B}, {A, -B}, {A, -D}, {A-E+F, -D+E+F}, {A-2*E, -D+2*E}, {A-G+H, -D+G+H}, {-D+2*E, A-2*E}, {-D+E+F, A-E+F}, {-D, A}}},
|
84 |
|
|
{{{-A, -C}, {-C, -A}, {A, C}, {C, A}}}
|
85 |
1b7c08b0
|
leszek
|
};
|
86 |
848ceb0b
|
leszek
|
}
|
87 |
|
|
|
88 |
627c34cd
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
89 |
|
|
|
90 |
|
|
@Override
|
91 |
|
|
protected float[][][] getStickerRadii()
|
92 |
|
|
{
|
93 |
|
|
float R = getStickerRadius();
|
94 |
1b7c08b0
|
leszek
|
float R2 = 1.5f*R;
|
95 |
627c34cd
|
leszek
|
|
96 |
|
|
return new float[][][]
|
97 |
|
|
{
|
98 |
|
|
{ { R, R, R, R } },
|
99 |
0431e308
|
leszek
|
{ { R2, R, R2, 0, 0,0,0,0,0, 0 } },
|
100 |
|
|
{ { R, R, R, R } },
|
101 |
627c34cd
|
leszek
|
};
|
102 |
|
|
}
|
103 |
|
|
|
104 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
105 |
|
|
|
106 |
|
|
@Override
|
107 |
0431e308
|
leszek
|
public int[][] getSolvedQuats()
|
108 |
627c34cd
|
leszek
|
{
|
109 |
1b7c08b0
|
leszek
|
int[] numL = getNumLayers();
|
110 |
|
|
int nL = numL[0];
|
111 |
|
|
|
112 |
|
|
if( nL==2 )
|
113 |
|
|
{
|
114 |
|
|
return new int[][]
|
115 |
|
|
{
|
116 |
|
|
{ 8, 0,1,2,3,4,5,6,7 }
|
117 |
|
|
};
|
118 |
|
|
}
|
119 |
|
|
else if( nL==3 )
|
120 |
627c34cd
|
leszek
|
{
|
121 |
1b7c08b0
|
leszek
|
return new int[][]
|
122 |
|
|
{
|
123 |
5bc4690c
|
leszek
|
{ 11, 0,1,2,3,4,5,6,7,8,9,10 },
|
124 |
|
|
|
125 |
a2122d42
|
leszek
|
{ 1, 12, 7,13 }, // triplet of full edges 12<-->15<-->17
|
126 |
|
|
{ 1, 15, 1, 9 },
|
127 |
|
|
{ 1, 17, 3,21 },
|
128 |
|
|
{ 1, 13, 4,20 }, // triplet of full edges 13<-->16<-->19
|
129 |
|
|
{ 1, 16, 1,15 },
|
130 |
|
|
{ 1, 19, 3, 6 },
|
131 |
|
|
{ 1, 11, 4, 7 }, // triplet of full edges 11<-->14<-->18
|
132 |
|
|
{ 1, 14, 9,10 },
|
133 |
|
|
{ 1, 18, 6,22 },
|
134 |
0431e308
|
leszek
|
|
135 |
|
|
{ 1, 20, 1, 2, 3 }, // +X center; in-face rotations.
|
136 |
|
|
{ 1, 21, 1, 2, 3 }, // -X center
|
137 |
|
|
{ 1, 22, 4, 5, 6 }, // +Y center
|
138 |
|
|
{ 1, 23, 4, 5, 6 }, // -Y center
|
139 |
|
|
{ 1, 24, 7, 8, 9 }, // +Z center
|
140 |
|
|
{ 1, 25, 7, 8, 9 } // -Z center
|
141 |
1b7c08b0
|
leszek
|
};
|
142 |
|
|
}
|
143 |
5bc4690c
|
leszek
|
else if( nL==4 )
|
144 |
|
|
{
|
145 |
|
|
return new int[][]
|
146 |
|
|
{
|
147 |
|
|
{ 8, 0,1,2,3,4,5,6,7 },
|
148 |
|
|
|
149 |
|
|
{ 2, 8, 9,14 }, // duo of curved edges 8,9
|
150 |
|
|
{ 2, 10,11,16 }, // duo of curved edges 10,11
|
151 |
|
|
{ 2, 12,13,18 }, // duo of curved edges 12,13
|
152 |
|
|
|
153 |
|
|
{ 1, 16, 7,13 }, // triplet of full edges 16<-->23<-->26
|
154 |
|
|
{ 1, 23, 1, 9 },
|
155 |
|
|
{ 1, 26, 3,21 },
|
156 |
|
|
{ 1, 17, 7,13 }, // triplet of full edges 17<-->22<-->27
|
157 |
|
|
{ 1, 22, 1, 9 },
|
158 |
|
|
{ 1, 27, 3,21 },
|
159 |
|
|
|
160 |
|
|
{ 1, 18, 4,20 }, // triplet of full edges 18<--25<-->30
|
161 |
|
|
{ 1, 25, 1,15 },
|
162 |
|
|
{ 1, 30, 3, 6 },
|
163 |
|
|
{ 1, 19, 4,20 }, // triplet of full edges 19<--24<-->29
|
164 |
|
|
{ 1, 24, 1,15 },
|
165 |
|
|
{ 1, 29, 3, 6 },
|
166 |
|
|
|
167 |
|
|
{ 1, 14, 4, 7 }, // triplet of full edges 14<-->21<-->28
|
168 |
|
|
{ 1, 21, 9,10 },
|
169 |
|
|
{ 1, 28, 6,22 },
|
170 |
|
|
{ 1, 15, 4, 7 }, // triplet of full edges 15<-->20<-->29
|
171 |
|
|
{ 1, 20, 9,10 },
|
172 |
|
|
{ 1, 29, 6,22 },
|
173 |
|
|
|
174 |
|
|
{ 1, 32, 1, 2, 3 }, // +X centers; in-face rotations.
|
175 |
|
|
{ 1, 33, 1, 2, 3 },
|
176 |
|
|
{ 1, 34, 1, 2, 3 },
|
177 |
|
|
{ 1, 35, 1, 2, 3 },
|
178 |
|
|
|
179 |
|
|
{ 1, 36, 1, 2, 3 }, // -X centers
|
180 |
|
|
{ 1, 37, 1, 2, 3 },
|
181 |
|
|
{ 1, 38, 1, 2, 3 },
|
182 |
|
|
{ 1, 39, 1, 2, 3 },
|
183 |
|
|
|
184 |
|
|
{ 1, 40, 4, 5, 6 }, // +Y centers
|
185 |
|
|
{ 1, 41, 4, 5, 6 },
|
186 |
|
|
{ 1, 42, 4, 5, 6 },
|
187 |
|
|
{ 1, 43, 4, 5, 6 },
|
188 |
|
|
|
189 |
|
|
{ 1, 44, 4, 5, 6 }, // -Y centers
|
190 |
|
|
{ 1, 45, 4, 5, 6 },
|
191 |
|
|
{ 1, 46, 4, 5, 6 },
|
192 |
|
|
{ 1, 47, 4, 5, 6 },
|
193 |
|
|
|
194 |
|
|
{ 1, 48, 7, 8, 9 }, // +Z centers
|
195 |
|
|
{ 1, 49, 7, 8, 9 },
|
196 |
|
|
{ 1, 50, 7, 8, 9 },
|
197 |
|
|
{ 1, 51, 7, 8, 9 },
|
198 |
|
|
|
199 |
|
|
{ 1, 52, 7, 8, 9 }, // -Z centers
|
200 |
|
|
{ 1, 53, 7, 8, 9 },
|
201 |
|
|
{ 1, 54, 7, 8, 9 },
|
202 |
|
|
{ 1, 55, 7, 8, 9 },
|
203 |
|
|
};
|
204 |
|
|
}
|
205 |
1b7c08b0
|
leszek
|
|
206 |
|
|
return null;
|
207 |
627c34cd
|
leszek
|
}
|
208 |
|
|
|
209 |
848ceb0b
|
leszek
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
210 |
|
|
// we need to manually change the colors of the faces
|
211 |
|
|
|
212 |
|
|
@Override
|
213 |
|
|
public int getCubitFaceMap(int cubit, int face)
|
214 |
|
|
{
|
215 |
|
|
if( mFaceMap==null )
|
216 |
|
|
{
|
217 |
0431e308
|
leszek
|
final int C1 = 1;
|
218 |
|
|
final int C2 = 2;
|
219 |
|
|
final int C3 = 4;
|
220 |
627c34cd
|
leszek
|
|
221 |
1b7c08b0
|
leszek
|
int[] numL = getNumLayers();
|
222 |
|
|
int nL = numL[0];
|
223 |
|
|
|
224 |
5bc4690c
|
leszek
|
final int[] FC1 = {-1,C2,-1,C1,-1,C3};
|
225 |
|
|
final int[] FC2 = {-1,C1,-1,C2,-1,C3};
|
226 |
|
|
final int[] CC1 = {-1,C1,C2,-1,-1,-1};
|
227 |
|
|
final int[] CC2 = {-1,C3,C2,-1,-1,-1};
|
228 |
|
|
final int[] CC3 = {-1,C2,C3,-1,-1,-1};
|
229 |
|
|
final int[] CC4 = {-1,C2,C1,-1,-1,-1};
|
230 |
|
|
final int[] CC5 = {-1,C3,C1,-1,-1,-1};
|
231 |
|
|
final int[] CC6 = {-1,C1,C3,-1,-1,-1};
|
232 |
|
|
final int[] CE1 = {-1,-1,C3,-1,-1,-1};
|
233 |
|
|
final int[] CE2 = {-1,-1,C1,-1,-1,-1};
|
234 |
|
|
final int[] CE3 = {-1,-1,C2,-1,-1,-1};
|
235 |
|
|
final int[] FE1 = {-1,-1,-1,C2,-1,C1};
|
236 |
|
|
final int[] FE2 = {-1,-1,-1,C3,-1,C2};
|
237 |
|
|
final int[] FE3 = {-1,-1,-1,C1,-1,C3};
|
238 |
|
|
final int[] FE4 = {-1,-1,-1,C3,-1,C1};
|
239 |
|
|
final int[] CT1 = {-1,-1,-1,-1,C1,-1};
|
240 |
|
|
final int[] CT2 = {-1,-1,-1,-1,C2,-1};
|
241 |
|
|
final int[] CT3 = {-1,-1,-1,-1,C3,-1};
|
242 |
|
|
|
243 |
1b7c08b0
|
leszek
|
if( nL==2 )
|
244 |
|
|
{
|
245 |
|
|
mFaceMap = new int[][]
|
246 |
|
|
{
|
247 |
5bc4690c
|
leszek
|
FC1,FC2,
|
248 |
|
|
CC1,CC2,CC3,CC4,CC5,CC6
|
249 |
1b7c08b0
|
leszek
|
};
|
250 |
|
|
}
|
251 |
|
|
else if( nL==3 )
|
252 |
|
|
{
|
253 |
|
|
mFaceMap = new int[][]
|
254 |
|
|
{
|
255 |
5bc4690c
|
leszek
|
FC1,FC2,
|
256 |
|
|
CC1,CC2,CC3,CC4,CC5,CC6,
|
257 |
|
|
CE1,CE2,CE3,
|
258 |
|
|
FE1,FE2,FE3,FE1,FE2,FE4,FE2,FE1,FE4,
|
259 |
|
|
CT1,CT2,CT3,CT2,CT3,CT1
|
260 |
|
|
};
|
261 |
|
|
}
|
262 |
|
|
else if( nL==4 )
|
263 |
|
|
{
|
264 |
|
|
mFaceMap = new int[][]
|
265 |
|
|
{
|
266 |
|
|
FC1,FC2,
|
267 |
|
|
CC1,CC2,CC3,CC4,CC5,CC6,
|
268 |
|
|
CE1,CE1,CE2,CE2,CE3,CE3,
|
269 |
|
|
FE1,FE1,FE2,FE2,FE3,FE3,FE1,FE1,FE2,FE2,FE4,FE4,FE2,FE2,FE1,FE1,FE4,FE4,
|
270 |
|
|
CT1,CT1,CT1,CT1,CT2,CT2,CT2,CT2,CT3,CT3,CT3,CT3,CT2,CT2,CT2,CT2,CT3,CT3,CT3,CT3,CT1,CT1,CT1,CT1
|
271 |
1b7c08b0
|
leszek
|
};
|
272 |
|
|
}
|
273 |
848ceb0b
|
leszek
|
}
|
274 |
|
|
|
275 |
|
|
return mFaceMap[cubit][face];
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
279 |
|
|
|
280 |
|
|
public int[][] getScrambleEdges()
|
281 |
|
|
{
|
282 |
|
|
int[] numL = getNumLayers();
|
283 |
|
|
if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesCuboid(numL[0],numL[1],numL[2]);
|
284 |
|
|
return mEdges;
|
285 |
|
|
}
|
286 |
|
|
|
287 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
288 |
|
|
|
289 |
|
|
public float[][] getCuts(int[] numLayers)
|
290 |
|
|
{
|
291 |
|
|
if( mCuts==null )
|
292 |
|
|
{
|
293 |
|
|
mCuts = new float[3][];
|
294 |
|
|
|
295 |
|
|
for(int axis=0; axis<3; axis++)
|
296 |
|
|
{
|
297 |
|
|
int len = numLayers[axis];
|
298 |
|
|
float start = (2-len)*0.5f;
|
299 |
|
|
|
300 |
|
|
if( len>=2 )
|
301 |
|
|
{
|
302 |
|
|
mCuts[axis] = new float[len-1];
|
303 |
|
|
for(int i=0; i<len-1; i++) mCuts[axis][i] = start+i;
|
304 |
|
|
}
|
305 |
|
|
}
|
306 |
|
|
}
|
307 |
|
|
|
308 |
|
|
return mCuts;
|
309 |
|
|
}
|
310 |
|
|
|
311 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
312 |
|
|
|
313 |
|
|
public boolean[][] getLayerRotatable(int[] numLayers)
|
314 |
|
|
{
|
315 |
|
|
int numAxis = ROT_AXIS.length;
|
316 |
|
|
boolean[][] layerRotatable = new boolean[numAxis][];
|
317 |
|
|
|
318 |
|
|
for(int i=0; i<numAxis; i++)
|
319 |
|
|
{
|
320 |
|
|
layerRotatable[i] = new boolean[numLayers[i]];
|
321 |
|
|
for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
|
322 |
|
|
}
|
323 |
|
|
|
324 |
|
|
return layerRotatable;
|
325 |
|
|
}
|
326 |
|
|
|
327 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
328 |
|
|
|
329 |
|
|
public int getTouchControlType()
|
330 |
|
|
{
|
331 |
a2122d42
|
leszek
|
return TC_CUBOID;
|
332 |
848ceb0b
|
leszek
|
}
|
333 |
|
|
|
334 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
335 |
|
|
|
336 |
|
|
public int getTouchControlSplit()
|
337 |
|
|
{
|
338 |
|
|
return TYPE_NOT_SPLIT;
|
339 |
|
|
}
|
340 |
|
|
|
341 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
342 |
|
|
|
343 |
|
|
public int[][][] getEnabled()
|
344 |
|
|
{
|
345 |
|
|
return new int[][][] { {{1,2}},{{1,2}},{{0,2}},{{0,2}},{{0,1}},{{0,1}} };
|
346 |
|
|
}
|
347 |
|
|
|
348 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
349 |
|
|
|
350 |
|
|
public float[] getDist3D(int[] numLayers)
|
351 |
|
|
{
|
352 |
|
|
return TouchControlHexahedron.D3D;
|
353 |
|
|
}
|
354 |
|
|
|
355 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
356 |
|
|
|
357 |
|
|
public Static3D[] getFaceAxis()
|
358 |
|
|
{
|
359 |
|
|
return TouchControlHexahedron.FACE_AXIS;
|
360 |
|
|
}
|
361 |
|
|
|
362 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
363 |
|
|
|
364 |
|
|
public float[][] getCubitPositions(int[] numLayers)
|
365 |
|
|
{
|
366 |
|
|
final int X = numLayers[0];
|
367 |
|
|
final int Y = numLayers[1];
|
368 |
|
|
final int Z = numLayers[2];
|
369 |
|
|
|
370 |
|
|
final float lenX = 0.5f*(X-1);
|
371 |
|
|
final float lenY = 0.5f*(Y-1);
|
372 |
|
|
final float lenZ = 0.5f*(Z-1);
|
373 |
|
|
|
374 |
|
|
int curPos = 0;
|
375 |
|
|
int numCubits = X*Y*Z - (X-2)*(Y-2)*(Z-2);
|
376 |
|
|
float[][] pos = new float[numCubits][];
|
377 |
|
|
|
378 |
|
|
pos[curPos++] = new float[] {-lenX,+lenY,-lenZ}; // 2 full corners
|
379 |
|
|
pos[curPos++] = new float[] {+lenX,-lenY,+lenZ};
|
380 |
|
|
|
381 |
|
|
pos[curPos++] = new float[] {-lenX,-lenY,-lenZ}; // 6 round corners
|
382 |
|
|
pos[curPos++] = new float[] {-lenX,-lenY,+lenZ};
|
383 |
|
|
pos[curPos++] = new float[] {-lenX,+lenY,+lenZ};
|
384 |
|
|
pos[curPos++] = new float[] {+lenX,-lenY,-lenZ};
|
385 |
|
|
pos[curPos++] = new float[] {+lenX,+lenY,-lenZ};
|
386 |
|
|
pos[curPos++] = new float[] {+lenX,+lenY,+lenZ};
|
387 |
|
|
|
388 |
|
|
for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX, +lenY, +lenZ }; // round edges
|
389 |
|
|
for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] { +lenX, i-lenY, -lenZ };
|
390 |
|
|
for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] { -lenX, -lenY, i-lenZ };
|
391 |
|
|
|
392 |
|
|
for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX, -lenY, -lenZ }; // normal edges
|
393 |
|
|
for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX, -lenY, +lenZ };
|
394 |
|
|
for(int i=1; i<X-1; i++) pos[curPos++] = new float[] { i-lenX, +lenY, -lenZ };
|
395 |
|
|
for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] { -lenX, i-lenY, -lenZ };
|
396 |
|
|
for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] { -lenX, i-lenY, +lenZ };
|
397 |
|
|
for(int i=1; i<Y-1; i++) pos[curPos++] = new float[] { +lenX, i-lenY, +lenZ };
|
398 |
|
|
for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] { -lenX, +lenY, i-lenZ };
|
399 |
|
|
for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] { +lenX, -lenY, i-lenZ };
|
400 |
|
|
for(int i=1; i<Z-1; i++) pos[curPos++] = new float[] { +lenX, +lenY, i-lenZ };
|
401 |
|
|
|
402 |
|
|
for(int y=1; y<Y-1; y++)
|
403 |
|
|
for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {+lenX,y-lenY,z-lenZ}; // centers
|
404 |
|
|
|
405 |
|
|
for(int y=1; y<Y-1; y++)
|
406 |
|
|
for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {-lenX,y-lenY,z-lenZ};
|
407 |
|
|
|
408 |
|
|
for(int x=1; x<X-1; x++)
|
409 |
|
|
for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,+lenY,z-lenZ};
|
410 |
|
|
|
411 |
|
|
for(int x=1; x<X-1; x++)
|
412 |
|
|
for(int z=1; z<Z-1; z++) pos[curPos++] = new float[] {x-lenX,-lenY,z-lenZ};
|
413 |
|
|
|
414 |
|
|
for(int x=1; x<X-1; x++)
|
415 |
|
|
for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,+lenZ};
|
416 |
|
|
|
417 |
|
|
for(int x=1; x<X-1; x++)
|
418 |
|
|
for(int y=1; y<Y-1; y++) pos[curPos++] = new float[] {x-lenX,y-lenY,-lenZ};
|
419 |
|
|
|
420 |
|
|
return pos;
|
421 |
|
|
}
|
422 |
|
|
|
423 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
424 |
|
|
|
425 |
|
|
public Static4D getCubitQuats(int cubit, int[] numLayers)
|
426 |
|
|
{
|
427 |
|
|
if( mQuatIndex==null )
|
428 |
|
|
{
|
429 |
5bc4690c
|
leszek
|
int[] numL = getNumLayers();
|
430 |
|
|
int nL = numL[0];
|
431 |
|
|
|
432 |
|
|
if( nL==2 )
|
433 |
|
|
{
|
434 |
|
|
mQuatIndex = new int[]
|
435 |
|
|
{
|
436 |
|
|
3,5,
|
437 |
|
|
2,9,20,11,13,6
|
438 |
|
|
};
|
439 |
|
|
}
|
440 |
|
|
else if( nL==3 )
|
441 |
|
|
{
|
442 |
|
|
mQuatIndex = new int[]
|
443 |
|
|
{
|
444 |
|
|
3,5,
|
445 |
|
|
2,9,20,11,13,6,
|
446 |
|
|
6,11,2,
|
447 |
|
|
0,1,3,7,12,10,17,4,16,
|
448 |
|
|
6,4,1,3,0,2
|
449 |
|
|
};
|
450 |
|
|
}
|
451 |
|
|
else if( nL==4 )
|
452 |
|
|
{
|
453 |
|
|
mQuatIndex = new int[]
|
454 |
|
|
{
|
455 |
|
|
3,5,
|
456 |
|
|
2,9,20,11,13,6,
|
457 |
|
|
6,6,11,11,2,2,
|
458 |
|
|
0,0,1,1,3,3,7,7,12,12,10,10,17,17,4,4,16,16,
|
459 |
|
|
6,6,6,6,4,4,4,4,1,1,1,1,3,3,3,3,0,0,0,0,2,2,2,2
|
460 |
|
|
};
|
461 |
|
|
}
|
462 |
848ceb0b
|
leszek
|
}
|
463 |
|
|
return mObjectQuats[mQuatIndex[cubit]];
|
464 |
|
|
}
|
465 |
|
|
|
466 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
467 |
|
|
|
468 |
|
|
private float[][] getVertices(int variant)
|
469 |
|
|
{
|
470 |
1b7c08b0
|
leszek
|
final float A = 0.5f;
|
471 |
|
|
|
472 |
848ceb0b
|
leszek
|
if( variant==1 || variant==2 )
|
473 |
|
|
{
|
474 |
0431e308
|
leszek
|
return new float[][]
|
475 |
|
|
{
|
476 |
1b7c08b0
|
leszek
|
{-A,-A,-A },
|
477 |
|
|
{ A,-A,-A },
|
478 |
|
|
{ A, A,-A },
|
479 |
|
|
{-A,-A, A },
|
480 |
|
|
{ A,-A, A },
|
481 |
|
|
{ A, A, A },
|
482 |
0431e308
|
leszek
|
};
|
483 |
848ceb0b
|
leszek
|
}
|
484 |
|
|
else
|
485 |
|
|
{
|
486 |
|
|
return new float[][]
|
487 |
|
|
{
|
488 |
1b7c08b0
|
leszek
|
{ A, A, A },
|
489 |
|
|
{ A, A,-A },
|
490 |
|
|
{ A,-A, A },
|
491 |
|
|
{ A,-A,-A },
|
492 |
|
|
{-A, A, A },
|
493 |
|
|
{-A, A,-A },
|
494 |
|
|
{-A,-A, A },
|
495 |
|
|
{-A,-A,-A },
|
496 |
848ceb0b
|
leszek
|
};
|
497 |
|
|
}
|
498 |
|
|
}
|
499 |
|
|
|
500 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
501 |
|
|
|
502 |
|
|
public ObjectShape getObjectShape(int variant)
|
503 |
|
|
{
|
504 |
|
|
if( variant==1 || variant==2 )
|
505 |
|
|
{
|
506 |
0431e308
|
leszek
|
int[][] indices =
|
507 |
|
|
{
|
508 |
|
|
{2,1,0},
|
509 |
|
|
{3,4,5},
|
510 |
|
|
{0,3,5,2},
|
511 |
|
|
{0,1,4,3},
|
512 |
|
|
{5,4,1,2}
|
513 |
|
|
};
|
514 |
848ceb0b
|
leszek
|
|
515 |
|
|
return new ObjectShape(getVertices(variant), indices);
|
516 |
|
|
}
|
517 |
|
|
else
|
518 |
|
|
{
|
519 |
|
|
int[][] indices =
|
520 |
|
|
{
|
521 |
|
|
{2,3,1,0},
|
522 |
|
|
{7,6,4,5},
|
523 |
|
|
{4,0,1,5},
|
524 |
|
|
{7,3,2,6},
|
525 |
|
|
{6,2,0,4},
|
526 |
|
|
{3,7,5,1}
|
527 |
|
|
};
|
528 |
|
|
|
529 |
|
|
return new ObjectShape(getVertices(variant), indices);
|
530 |
|
|
}
|
531 |
|
|
}
|
532 |
|
|
|
533 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
534 |
|
|
|
535 |
|
|
public ObjectFaceShape getObjectFaceShape(int variant)
|
536 |
|
|
{
|
537 |
|
|
int extraI, extraV, n1, n2, numL = getNumLayers()[0];
|
538 |
|
|
|
539 |
|
|
switch(numL)
|
540 |
|
|
{
|
541 |
1b7c08b0
|
leszek
|
case 2 : n1 = 7; n2 = 7; extraI = 2; extraV = 1; break;
|
542 |
|
|
case 3 : n1 = 6; n2 = 6; extraI = 1; extraV = 1; break;
|
543 |
|
|
case 4 : n1 = 5; n2 = 6; extraI = 1; extraV = 0; break;
|
544 |
848ceb0b
|
leszek
|
default: n1 = 5; n2 = 6; extraI = 0; extraV = 0; break;
|
545 |
|
|
}
|
546 |
|
|
|
547 |
1b7c08b0
|
leszek
|
float h1 = isInIconMode() ? 0.001f : 0.06f;
|
548 |
848ceb0b
|
leszek
|
float h2 = isInIconMode() ? 0.001f : 0.030f;
|
549 |
1b7c08b0
|
leszek
|
int angle = 40;
|
550 |
848ceb0b
|
leszek
|
float R = 0.5f;
|
551 |
|
|
float S = 0.7f;
|
552 |
|
|
|
553 |
|
|
float[][] bands =
|
554 |
|
|
{
|
555 |
|
|
{ h1,angle,R,S,n1,extraI,extraV},
|
556 |
adb5b717
|
leszek
|
{0.001f, 1,R,S, 2, n1-2,extraV},
|
557 |
|
|
{0.001f, 1,R,S, 2, 0, 0},
|
558 |
1b7c08b0
|
leszek
|
{0.001f, 1,R,S,n1,extraI,extraV},
|
559 |
848ceb0b
|
leszek
|
{ h2,angle,R,S,n2,extraI,extraV},
|
560 |
|
|
};
|
561 |
|
|
|
562 |
|
|
switch(variant)
|
563 |
|
|
{
|
564 |
0431e308
|
leszek
|
case 0: return new ObjectFaceShape(bands,new int[] {3,0,3,0,3,0},null);
|
565 |
1b7c08b0
|
leszek
|
case 1: return new ObjectFaceShape(bands,new int[] { 3,4,4,3,3 },null);
|
566 |
|
|
case 2: return new ObjectFaceShape(bands,new int[] { 3,3,4,3,3 },null);
|
567 |
0431e308
|
leszek
|
case 3: return new ObjectFaceShape(bands,new int[] {1,1,1,0,1,0},null);
|
568 |
|
|
case 4: return new ObjectFaceShape(bands,new int[] {2,2,2,2,0,2},null);
|
569 |
848ceb0b
|
leszek
|
}
|
570 |
|
|
|
571 |
0431e308
|
leszek
|
return null;
|
572 |
848ceb0b
|
leszek
|
}
|
573 |
|
|
|
574 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
575 |
|
|
|
576 |
|
|
public ObjectVertexEffects getVertexEffects(int variant)
|
577 |
|
|
{
|
578 |
|
|
float[][] vertices= getVertices(variant);
|
579 |
|
|
|
580 |
0431e308
|
leszek
|
if( variant==1 || variant==2 )
|
581 |
848ceb0b
|
leszek
|
{
|
582 |
1b7c08b0
|
leszek
|
float[][] centers= { {0.25f, -0.25f, 0.0f} };
|
583 |
|
|
float[][] corners= { {0.050f,0.15f} };
|
584 |
0431e308
|
leszek
|
int[] indices = { 0,0,0,0,0,0 };
|
585 |
|
|
ObjectVertexEffects effects = FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
|
586 |
|
|
String n = EffectName.PIPE.name();
|
587 |
|
|
float[] v = {0.5f,0,0,1,0.92f};
|
588 |
|
|
float[] c = {-0.5f,0.5f,0.0f};
|
589 |
|
|
float[] r = {0,0,0,0};
|
590 |
|
|
effects.joinEffect(n,v,c,r,true);
|
591 |
|
|
return effects;
|
592 |
848ceb0b
|
leszek
|
}
|
593 |
|
|
else
|
594 |
|
|
{
|
595 |
1b7c08b0
|
leszek
|
float[][] centers= { {0.0f, 0.0f, 0.0f} };
|
596 |
|
|
float[][] corners= { {0.040f,0.15f} };
|
597 |
0431e308
|
leszek
|
int[] indices = { 0,0,0,0,0,0,0,0 };
|
598 |
|
|
return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
|
599 |
848ceb0b
|
leszek
|
}
|
600 |
|
|
}
|
601 |
|
|
|
602 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
603 |
|
|
|
604 |
|
|
public int getNumCubitVariants(int[] numLayers)
|
605 |
|
|
{
|
606 |
1b7c08b0
|
leszek
|
return numLayers[0]==2 ? 2 : 5;
|
607 |
848ceb0b
|
leszek
|
}
|
608 |
|
|
|
609 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
610 |
|
|
|
611 |
|
|
public int getCubitVariant(int cubit, int[] numLayers)
|
612 |
|
|
{
|
613 |
5bc4690c
|
leszek
|
int nL = numLayers[0];
|
614 |
|
|
|
615 |
|
|
if( nL==2 )
|
616 |
|
|
{
|
617 |
|
|
return cubit<2 ? 0 : 1;
|
618 |
|
|
}
|
619 |
|
|
else if( nL==3 )
|
620 |
|
|
{
|
621 |
|
|
if( cubit < 2 ) return 0;
|
622 |
|
|
if( cubit < 8 ) return 1;
|
623 |
|
|
if( cubit < 11 ) return 2;
|
624 |
|
|
if( cubit < 20 ) return 3;
|
625 |
|
|
return 4;
|
626 |
|
|
}
|
627 |
|
|
else if( nL==4 )
|
628 |
|
|
{
|
629 |
|
|
if( cubit < 2 ) return 0;
|
630 |
|
|
if( cubit < 8 ) return 1;
|
631 |
|
|
if( cubit < 14 ) return 2;
|
632 |
|
|
if( cubit < 32 ) return 3;
|
633 |
|
|
return 4;
|
634 |
|
|
}
|
635 |
848ceb0b
|
leszek
|
|
636 |
5bc4690c
|
leszek
|
return -1;
|
637 |
848ceb0b
|
leszek
|
}
|
638 |
|
|
|
639 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
640 |
|
|
|
641 |
|
|
public float getStickerRadius()
|
642 |
|
|
{
|
643 |
|
|
return 0.10f;
|
644 |
|
|
}
|
645 |
|
|
|
646 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
647 |
|
|
|
648 |
|
|
public float getStickerStroke()
|
649 |
|
|
{
|
650 |
1b7c08b0
|
leszek
|
return isInIconMode() ? 0.22f : 0.13f;
|
651 |
848ceb0b
|
leszek
|
}
|
652 |
|
|
|
653 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
654 |
|
|
|
655 |
|
|
public float[][][] getStickerAngles()
|
656 |
|
|
{
|
657 |
0431e308
|
leszek
|
return null;
|
658 |
848ceb0b
|
leszek
|
}
|
659 |
|
|
|
660 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
661 |
|
|
// PUBLIC API
|
662 |
|
|
|
663 |
|
|
public Static3D[] getRotationAxis()
|
664 |
|
|
{
|
665 |
|
|
return ROT_AXIS;
|
666 |
|
|
}
|
667 |
|
|
|
668 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
669 |
|
|
|
670 |
|
|
public String getShortName()
|
671 |
|
|
{
|
672 |
1b7c08b0
|
leszek
|
int[] numL = getNumLayers();
|
673 |
5bc4690c
|
leszek
|
|
674 |
|
|
switch(numL[0])
|
675 |
|
|
{
|
676 |
|
|
case 2: return ListObjects.PENR_2.name();
|
677 |
|
|
case 3: return ListObjects.PENR_3.name();
|
678 |
|
|
case 4: return ListObjects.PENR_4.name();
|
679 |
|
|
}
|
680 |
|
|
|
681 |
|
|
return null;
|
682 |
848ceb0b
|
leszek
|
}
|
683 |
|
|
|
684 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
685 |
|
|
|
686 |
|
|
public int[][] getBasicAngles()
|
687 |
|
|
{
|
688 |
|
|
if( mBasicAngle ==null )
|
689 |
|
|
{
|
690 |
|
|
int num = getNumLayers()[0];
|
691 |
|
|
int[] tmp = new int[num];
|
692 |
|
|
for(int i=0; i<num; i++) tmp[i] = 4;
|
693 |
|
|
mBasicAngle = new int[][] { tmp,tmp,tmp };
|
694 |
|
|
}
|
695 |
|
|
|
696 |
|
|
return mBasicAngle;
|
697 |
|
|
}
|
698 |
|
|
|
699 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
700 |
|
|
|
701 |
|
|
public String[][] getTutorials()
|
702 |
|
|
{
|
703 |
1b7c08b0
|
leszek
|
int[] numL = getNumLayers();
|
704 |
|
|
|
705 |
5bc4690c
|
leszek
|
if( numL[0]==3 )
|
706 |
1b7c08b0
|
leszek
|
{
|
707 |
|
|
return new String[][] {
|
708 |
|
|
{"gb","Qit_PhYq-AI","Penrose Cube Tutorial","Manqube Manish Rathod"},
|
709 |
|
|
{"es","e6q1GwDeqFc","Tutorial del Penrose Cube","Rubiking"},
|
710 |
|
|
{"ru","LeYvajdcizQ","Как собрать Penrose Cube","YG Cuber"},
|
711 |
|
|
{"fr","jrHq_nZuQGk","Résolution du Penrose Cube","asthalis"},
|
712 |
|
|
{"de","P5dck40kTU0","Penrose Cube Tutorial","rofrisch"},
|
713 |
|
|
{"pl","o_c_pIOC6RU","Jak ułożyć kostkę Penrose","Kostki logiczne TV"},
|
714 |
|
|
{"br","6Iz95dtq1dE","Como resolver o Cubo Penrose","Cubo vício"},
|
715 |
|
|
{"kr","uzeoQzkDWM0","펜로즈 큐브","큐브놀이터"},
|
716 |
|
|
{"vn","PjyCCsxJyBU","Hướng dẫn giải Penrose Cube","Rubik Ocean"},
|
717 |
|
|
{"tw","lkzFMKmlB_8","Penrose Cube","不正常魔術方塊研究中心"},
|
718 |
|
|
};
|
719 |
|
|
}
|
720 |
|
|
|
721 |
|
|
return null;
|
722 |
848ceb0b
|
leszek
|
}
|
723 |
|
|
}
|