Project

General

Profile

Download (24.8 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ 516451c4

1 59b87d56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.objects;
21
22
import android.content.res.Resources;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25
26 749ef882 Leszek Koltunski
import org.distorted.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28 59b87d56 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectQuaternion;
29 be56193c Leszek Koltunski
import org.distorted.library.effect.VertexEffect;
30
import org.distorted.library.effect.VertexEffectMove;
31
import org.distorted.library.effect.VertexEffectRotate;
32
import org.distorted.library.effect.VertexEffectScale;
33 59b87d56 Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
34
import org.distorted.library.main.DistortedTexture;
35
import org.distorted.library.mesh.MeshBase;
36 be56193c Leszek Koltunski
import org.distorted.library.mesh.MeshJoined;
37
import org.distorted.library.mesh.MeshPolygon;
38 59b87d56 Leszek Koltunski
import org.distorted.library.mesh.MeshSquare;
39 be56193c Leszek Koltunski
import org.distorted.library.type.Static1D;
40 59b87d56 Leszek Koltunski
import org.distorted.library.type.Static3D;
41
import org.distorted.library.type.Static4D;
42
import org.distorted.main.R;
43
44
import java.util.Random;
45
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47
48
public class TwistyRex extends TwistyObject
49
{
50 da36b97e Leszek Koltunski
  private static final int FACES_PER_CUBIT =6;
51 59b87d56 Leszek Koltunski
52 be56193c Leszek Koltunski
  public static final float REX_D = 0.2f;
53
54 59b87d56 Leszek Koltunski
  // the four rotation axis of a RubikRex. Must be normalized.
55
  static final Static3D[] ROT_AXIS = new Static3D[]
56
         {
57
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
58
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
59
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
60
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
61
         };
62
63 925ed78f Leszek Koltunski
  private static final int[] BASIC_ANGLE = new int[] { 3,3,3,3 };
64
65 59b87d56 Leszek Koltunski
  private static final int[] FACE_COLORS = new int[]
66
         {
67
           COLOR_YELLOW, COLOR_WHITE,
68
           COLOR_BLUE  , COLOR_GREEN,
69 323b217c Leszek Koltunski
           COLOR_RED   , COLOR_ORANGE
70 59b87d56 Leszek Koltunski
         };
71
72
  // All legal rotation quats of a RubikRex
73
  private static final Static4D[] QUATS = new Static4D[]
74
         {
75
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
76
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
77
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
78
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
79
80
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
81
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
82
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
83
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
84
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
85
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
86
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
87
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
88
         };
89
90
  private static final int[][] mFaceMap =
91
         {
92 da36b97e Leszek Koltunski
           {  0, 18,18,18,18,18 },
93
           {  0, 18,18,18,18,18 },
94
           {  0, 18,18,18,18,18 },
95
           {  0, 18,18,18,18,18 },
96
           {  1, 18,18,18,18,18 },
97
           {  1, 18,18,18,18,18 },
98
           {  1, 18,18,18,18,18 },
99
           {  1, 18,18,18,18,18 },
100
           {  2, 18,18,18,18,18 },
101
           {  2, 18,18,18,18,18 },
102
           {  2, 18,18,18,18,18 },
103
           {  2, 18,18,18,18,18 },
104
           {  3, 18,18,18,18,18 },
105
           {  3, 18,18,18,18,18 },
106
           {  3, 18,18,18,18,18 },
107
           {  3, 18,18,18,18,18 },
108
           {  4, 18,18,18,18,18 },
109
           {  4, 18,18,18,18,18 },
110
           {  4, 18,18,18,18,18 },
111
           {  4, 18,18,18,18,18 },
112
           {  5, 18,18,18,18,18 },
113
           {  5, 18,18,18,18,18 },
114
           {  5, 18,18,18,18,18 },
115
           {  5, 18,18,18,18,18 },
116
117
           {  6, 18,18,18,18,18 },
118
           {  7, 18,18,18,18,18 },
119
           {  8, 18,18,18,18,18 },
120
           {  9, 18,18,18,18,18 },
121
           { 10, 18,18,18,18,18 },
122
           { 11, 18,18,18,18,18 },
123
124
           { 16,14, 18,18,18,18 },
125
           { 16,12, 18,18,18,18 },
126
           { 16,15, 18,18,18,18 },
127
           { 16,13, 18,18,18,18 },
128
           { 12,14, 18,18,18,18 },
129
           { 15,12, 18,18,18,18 },
130
           { 15,13, 18,18,18,18 },
131
           { 13,14, 18,18,18,18 },
132
           { 14,17, 18,18,18,18 },
133
           { 12,17, 18,18,18,18 },
134
           { 17,15, 18,18,18,18 },
135
           { 13,17, 18,18,18,18 },
136 59b87d56 Leszek Koltunski
         };
137
138
  private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142
  TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
143
            DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
144
    {
145 db875721 Leszek Koltunski
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.REX, res, scrWidth);
146 59b87d56 Leszek Koltunski
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150
  float getScreenRatio()
151
    {
152 80ec6abf Leszek Koltunski
    return 1.5f;
153 59b87d56 Leszek Koltunski
    }
154
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
157
  Static4D[] getQuats()
158
    {
159
    return QUATS;
160
    }
161
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
164
  int getNumFaces()
165
    {
166
    return FACE_COLORS.length;
167
    }
168
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170
171
  boolean shouldResetTextureMaps()
172
    {
173
    return false;
174
    }
175
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177
178 a64e07d0 Leszek Koltunski
  int getNumStickerTypes(int numLayers)
179 59b87d56 Leszek Koltunski
    {
180
    return 3;
181
    }
182
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184
185 e6734aa9 Leszek Koltunski
  float[][] getCuts(int numLayers)
186 59b87d56 Leszek Koltunski
    {
187 e6734aa9 Leszek Koltunski
    float[] cut = new float[] {-SQ3*0.15f,+SQ3*0.15f}; // bit less than 1/6 of the length of the main diagonal
188
    return new float[][] { cut,cut,cut,cut };
189 59b87d56 Leszek Koltunski
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
  int getNumCubitFaces()
194
    {
195
    return FACES_PER_CUBIT;
196
    }
197
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
200 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
201 59b87d56 Leszek Koltunski
    {
202
    final float DIST = 0.50f;
203 da36b97e Leszek Koltunski
    final float DIST2= (1+2*REX_D)/6;
204 59b87d56 Leszek Koltunski
205 e6cf7283 Leszek Koltunski
    final float[][] CENTERS = new float[42][];
206
207
    CENTERS[ 0] = new float[] { +DIST , +DIST2, +DIST2};
208
    CENTERS[ 1] = new float[] { +DIST , +DIST2, -DIST2};
209
    CENTERS[ 2] = new float[] { +DIST , -DIST2, -DIST2};
210
    CENTERS[ 3] = new float[] { +DIST , -DIST2, +DIST2};
211
    CENTERS[ 4] = new float[] { -DIST , +DIST2, +DIST2};
212
    CENTERS[ 5] = new float[] { -DIST , +DIST2, -DIST2};
213
    CENTERS[ 6] = new float[] { -DIST , -DIST2, -DIST2};
214
    CENTERS[ 7] = new float[] { -DIST , -DIST2, +DIST2};
215
    CENTERS[ 8] = new float[] { +DIST2, +DIST , +DIST2};
216
    CENTERS[ 9] = new float[] { +DIST2, +DIST , -DIST2};
217
    CENTERS[10] = new float[] { -DIST2, +DIST , -DIST2};
218
    CENTERS[11] = new float[] { -DIST2, +DIST , +DIST2};
219
    CENTERS[12] = new float[] { +DIST2, -DIST , +DIST2};
220
    CENTERS[13] = new float[] { +DIST2, -DIST , -DIST2};
221
    CENTERS[14] = new float[] { -DIST2, -DIST , -DIST2};
222
    CENTERS[15] = new float[] { -DIST2, -DIST , +DIST2};
223
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST };
224
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST };
225
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST };
226
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST };
227
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST };
228
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST };
229
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST };
230
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST };
231
232
    CENTERS[24] = new float[] { +DIST , +0.00f, +0.00f};
233
    CENTERS[25] = new float[] { -DIST , +0.00f, +0.00f};
234
    CENTERS[26] = new float[] { +0.00f, +DIST , +0.00f};
235
    CENTERS[27] = new float[] { +0.00f, -DIST , +0.00f};
236
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST };
237
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST };
238
239
    CENTERS[30] = new float[] { +0.00f, +DIST , +DIST };
240
    CENTERS[31] = new float[] { +DIST , +0.00f, +DIST };
241
    CENTERS[32] = new float[] { +0.00f, -DIST , +DIST };
242
    CENTERS[33] = new float[] { -DIST , +0.00f, +DIST };
243
    CENTERS[34] = new float[] { +DIST , +DIST , +0.00f};
244
    CENTERS[35] = new float[] { +DIST , -DIST , +0.00f};
245
    CENTERS[36] = new float[] { -DIST , -DIST , +0.00f};
246
    CENTERS[37] = new float[] { -DIST , +DIST , +0.00f};
247
    CENTERS[38] = new float[] { +0.00f, +DIST , -DIST };
248
    CENTERS[39] = new float[] { +DIST , +0.00f, -DIST };
249
    CENTERS[40] = new float[] { +0.00f, -DIST , -DIST };
250
    CENTERS[41] = new float[] { -DIST , +0.00f, -DIST };
251 59b87d56 Leszek Koltunski
252
    return CENTERS;
253
    }
254
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256
257
  private Static4D getQuat(int cubit)
258
    {
259
    switch(cubit)
260
      {
261 80ec6abf Leszek Koltunski
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
262
      case  1: return QUATS[5];
263
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
264
      case  3: return QUATS[8];
265 59b87d56 Leszek Koltunski
      case  4: return QUATS[6];
266 80ec6abf Leszek Koltunski
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
267 59b87d56 Leszek Koltunski
      case  6: return QUATS[11];
268 80ec6abf Leszek Koltunski
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
269
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
270
      case  9: return QUATS[10];
271 59b87d56 Leszek Koltunski
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
272
      case 11: return QUATS[4];
273
      case 12: return QUATS[9];
274
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
275
      case 14: return QUATS[7];
276
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
277
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
278
      case 17: return QUATS[0];
279
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
280
      case 19: return QUATS[3];
281 80ec6abf Leszek Koltunski
      case 20: return QUATS[1];
282
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
283
      case 22: return QUATS[2];
284
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
285 59b87d56 Leszek Koltunski
286 80ec6abf Leszek Koltunski
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
287
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
288 59b87d56 Leszek Koltunski
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
289
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
290
      case 28: return QUATS[0];
291
      case 29: return QUATS[1];
292
293
      case 30: return QUATS[0];
294
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
295
      case 32: return QUATS[3];
296
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
297 80ec6abf Leszek Koltunski
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
298 59b87d56 Leszek Koltunski
      case 35: return QUATS[7];
299
      case 36: return QUATS[9];
300 80ec6abf Leszek Koltunski
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
301 59b87d56 Leszek Koltunski
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
302
      case 39: return QUATS[8];
303
      case 40: return QUATS[1];
304
      case 41: return QUATS[6];
305
      }
306
307
    return QUATS[0];
308
    }
309
310 be56193c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
311
312
  MeshBase createFacesRexCorner()
313
    {
314
    MeshBase[] meshes = new MeshBase[2];
315
316
    float F = REX_D*SQ2;
317
    float G = (1-REX_D)*SQ2/2;
318
    float H = 0.1f;
319
    float J = +2*G/3 - H*G;
320
321
    float[] vertices = { -F/2, -G/3, +F/2, -G/3, H*F/2, J, -H*F/2, J};
322
323
    FactoryCubit factory = FactoryCubit.getInstance();
324
    float[] bands0 = factory.computeBands(+0.016f,10,G/3,0.5f,5);
325
    float[] bands1 = factory.computeBands(-0.230f,45,G/3,0.0f,2);
326
327
    meshes[0] = new MeshPolygon(vertices,bands0,1,1);
328
    meshes[0].setEffectAssociation(0,1,0);
329
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
330
    meshes[1].setEffectAssociation(0,2,0);
331
332
    return new MeshJoined(meshes);
333
    }
334
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336
337
  MeshBase createFacesRexFace()
338
    {
339
    MeshBase[] meshes = new MeshBase[2];
340
341
    float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
342
343
    FactoryCubit factory = FactoryCubit.getInstance();
344
    float[] bands0 = factory.computeBands(0.016f,10,REX_D/2,0.5f,5);
345
    float[] bands1 = factory.computeBands(0.000f,45,REX_D/2,0.0f,2);
346
347
    meshes[0] = new MeshPolygon(vertices,bands0,0,0);
348
    meshes[0].setEffectAssociation(0,1,0);
349
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
350
    meshes[1].setEffectAssociation(0,2,0);
351
352
    return new MeshJoined(meshes);
353
    }
354
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
357
  MeshBase createFacesRexEdge()
358
    {
359
    MeshBase[] meshes = new MeshPolygon[6];
360
    FactoryCubit factory = FactoryCubit.getInstance();
361
362
    float E = 0.5f - REX_D;
363
    float F = 0.5f;
364
    float[] vertices0 = { -F,E/3, 0,-2*E/3, +F,E/3 };
365
    float[] bands0 = factory.computeBands(0.03f,27,F/3,0.8f,5);
366
367
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 3);
368
    meshes[0].setEffectAssociation(0,1,0);
369
    meshes[1] = meshes[0].copy(true);
370
    meshes[1].setEffectAssociation(0,2,0);
371
372
    float G = (float)Math.sqrt(E*E+F*F);
373
    float[] vertices1 = { -2*G/3, -E/3, G/3, -E/3, G/3, 2*E/3 };
374
    float[] bands1 = factory.computeBands(0.00f,45,G/3,0.2f,3);
375
376
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
377
    meshes[2].setEffectAssociation(0,4,0);
378
    meshes[3] = meshes[2].copy(true);
379
    meshes[3].setEffectAssociation(0,8,0);
380
    meshes[4] = meshes[2].copy(true);
381
    meshes[4].setEffectAssociation(0,16,0);
382
    meshes[5] = meshes[2].copy(true);
383
    meshes[5].setEffectAssociation(0,32,0);
384
385
    return new MeshJoined(meshes);
386
    }
387
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389
390
  private VertexEffect[] createVertexEffectsRexEdge()
391
    {
392
    float E = 0.5f - REX_D;
393
    float F = 0.5f;
394
    float G = (float)Math.sqrt(E*E+F*F);
395
    float A = (float)((180/Math.PI)*Math.asin(E/G));
396
397
    Static3D move1 = new Static3D(    0.0f, -E/3, 0.0f);
398
    Static3D move2 = new Static3D(2*G/3 -F, +E/3, 0.0f);
399
400
    Static3D center0= new Static3D(0.0f, 0.0f, 0.0f);
401
    Static3D center1= new Static3D(  -F, 0.0f, 0.0f);
402
    Static3D center2= new Static3D(  +F, 0.0f, 0.0f);
403
    Static3D axisX  = new Static3D(1.0f, 0.0f, 0.0f);
404
    Static3D axisY  = new Static3D(0.0f, 1.0f, 0.0f);
405
    Static3D axisZ  = new Static3D(0.0f, 0.0f, 1.0f);
406
407
    Static1D angle180 = new Static1D(180);
408
    Static1D angle90  = new Static1D( 90);
409
    Static1D angle270 = new Static1D(270);
410
    Static1D angle1   = new Static1D(+A);
411
    Static1D angle2   = new Static1D(-A);
412
413
    VertexEffect[] effect = new VertexEffect[12];
414
415
    effect[0] = new VertexEffectMove(move1);
416
    effect[1] = new VertexEffectMove(move2);
417
    effect[2] = new VertexEffectRotate(  angle90, axisX, center0 );
418
    effect[3] = new VertexEffectRotate( angle270, axisX, center0 );
419
    effect[4] = new VertexEffectRotate( angle180, axisX, center0 );
420
    effect[5] = new VertexEffectRotate( angle180, axisY, center0 );
421
    effect[6] = new VertexEffectScale( new Static3D(-1, 1, 1) );
422
    effect[7] = new VertexEffectScale ( new Static3D( 1,-1, 1) );
423
    effect[8] = new VertexEffectRotate(   angle1, axisY, center1);
424
    effect[9] = new VertexEffectRotate(   angle2, axisY, center2);
425
    effect[10]= new VertexEffectRotate(   angle2, axisZ, center1);
426
    effect[11]= new VertexEffectRotate(   angle1, axisZ, center2);
427
428
    effect[0].setMeshAssociation( 3,-1);  // meshes 0 & 1
429
    effect[1].setMeshAssociation(60,-1);  // meshes 2,3,4,5
430
    effect[2].setMeshAssociation( 2,-1);  // meshes 1
431
    effect[3].setMeshAssociation(12,-1);  // meshes 2,3
432
    effect[4].setMeshAssociation(48,-1);  // meshes 4,5
433
    effect[5].setMeshAssociation(32,-1);  // mesh 5
434
    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
435
    effect[7].setMeshAssociation( 2,-1);  // apply to mesh 1
436
    effect[8].setMeshAssociation(16,-1);  // apply to mesh 4
437
    effect[9].setMeshAssociation(32,-1);  // apply to mesh 5
438
    effect[10].setMeshAssociation(4,-1);  // apply to mesh 2
439
    effect[11].setMeshAssociation(8,-1);  // apply to mesh 3
440
441
    return effect;
442
    }
443
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
446
  private VertexEffect[] createVertexEffectsRexCorner()
447
    {
448
    Static3D center= new Static3D(0.0f, 0.0f, 0.0f);
449
    Static3D axisZ = new Static3D(0.0f, 0.0f, 1.0f);
450
    Static1D angle = new Static1D(225);
451
452
    VertexEffect[] effect = new VertexEffect[1];
453
    effect[0] = new VertexEffectRotate(angle, axisZ, center);
454
455
    return effect;
456
    }
457
458
///////////////////////////////////////////////////////////////////////////////////////////////////
459
460
  private MeshBase createRexCornerMesh()
461
    {
462
    MeshBase mesh = createFacesRexCorner();
463
    VertexEffect[] effects = createVertexEffectsRexCorner();
464
    for( VertexEffect effect : effects ) mesh.apply(effect);
465
466
    final float G = (1-REX_D)/3;
467
    Static3D center = new Static3D(0.0f,0.0f,-G*SQ2/2);
468
    Static3D[] vertices = new Static3D[1];
469
    vertices[0] = new Static3D(+G,-G,+0.0f);
470
    FactoryCubit.getInstance().roundCorners(mesh,center,vertices,0.10f,0.10f);
471
472
    mesh.mergeEffComponents();
473
    mesh.addEmptyTexComponent();
474
    mesh.addEmptyTexComponent();
475
    mesh.addEmptyTexComponent();
476
    mesh.addEmptyTexComponent();
477
478
    return mesh;
479
    }
480
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482
483
  private MeshBase createRexFaceMesh()
484
    {
485
    MeshBase mesh = createFacesRexFace();
486
487
    mesh.mergeEffComponents();
488
    mesh.addEmptyTexComponent();
489
    mesh.addEmptyTexComponent();
490
    mesh.addEmptyTexComponent();
491
    mesh.addEmptyTexComponent();
492
493
    return mesh;
494
    }
495
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497
498
  private MeshBase createRexEdgeMesh()
499
    {
500
    MeshBase mesh = createFacesRexEdge();
501
    VertexEffect[] effects = createVertexEffectsRexEdge();
502
    for( VertexEffect effect : effects ) mesh.apply(effect);
503
504
    Static3D center = new Static3D(0.0f,-0.5f,-0.5f);
505
    Static3D[] vertices = new Static3D[2];
506
    vertices[0] = new Static3D(+0.5f,+0.0f,+0.0f);
507
    vertices[1] = new Static3D(-0.5f,+0.0f,+0.0f);
508
    FactoryCubit.getInstance().roundCorners(mesh,center,vertices,0.06f,0.10f);
509
510
    mesh.mergeEffComponents();
511
512
    return mesh;
513
    }
514
515 59b87d56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
516
517 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
518 59b87d56 Leszek Koltunski
    {
519
    MeshBase mesh;
520
521 f5c134c3 Leszek Koltunski
    if( cubit<24 )
522 59b87d56 Leszek Koltunski
      {
523 be56193c Leszek Koltunski
      if( mCornerMesh==null ) mCornerMesh = createRexCornerMesh();
524 59b87d56 Leszek Koltunski
      mesh = mCornerMesh.copy(true);
525
      }
526 f5c134c3 Leszek Koltunski
    else if( cubit<30 )
527 59b87d56 Leszek Koltunski
      {
528 be56193c Leszek Koltunski
      if( mFaceMesh==null ) mFaceMesh = createRexFaceMesh();
529 59b87d56 Leszek Koltunski
      mesh = mFaceMesh.copy(true);
530
      }
531
    else
532
      {
533 be56193c Leszek Koltunski
      if( mEdgeMesh==null ) mEdgeMesh = createRexEdgeMesh();
534 59b87d56 Leszek Koltunski
      mesh = mEdgeMesh.copy(true);
535
      }
536
537
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
538
    mesh.apply(quat,0xffffffff,0);
539
540
    return mesh;
541
    }
542
543
///////////////////////////////////////////////////////////////////////////////////////////////////
544
545
  int getFaceColor(int cubit, int cubitface, int numLayers)
546
    {
547
    return mFaceMap[cubit][cubitface];
548
    }
549
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551
552
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
553
    {
554
    int COLORS = FACE_COLORS.length;
555
    FactorySticker factory = FactorySticker.getInstance();
556 da36b97e Leszek Koltunski
    float S1 = 0.050f;
557
    float S2 = 0.051f;
558
    float R1 = 0.07f;
559
    float R2 = 0.02f;
560
    float R3 = 0.06f;
561
    float R4 = 0.04f;
562 59b87d56 Leszek Koltunski
563
    if( face<COLORS )
564
      {
565 da36b97e Leszek Koltunski
      factory.drawRexCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S1, R2, R3);
566 59b87d56 Leszek Koltunski
      }
567
    else if( face<2*COLORS )
568
      {
569 da36b97e Leszek Koltunski
      float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
570
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S1, FACE_COLORS[face%COLORS], R4);
571 59b87d56 Leszek Koltunski
      }
572
    else
573
      {
574 5eedd516 Leszek Koltunski
      factory.drawRexEdgeSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S2, R1);
575 59b87d56 Leszek Koltunski
      }
576
    }
577
578
///////////////////////////////////////////////////////////////////////////////////////////////////
579
580
  float returnMultiplier()
581
    {
582
    return 2.0f;
583
    }
584
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586
// PUBLIC API
587
588
  public Static3D[] getRotationAxis()
589
    {
590
    return ROT_AXIS;
591
    }
592
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594
595 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
596 59b87d56 Leszek Koltunski
    {
597 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
598 59b87d56 Leszek Koltunski
    }
599
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601
602 9f171eba Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int curr, int total)
603 59b87d56 Leszek Koltunski
    {
604 9f171eba Leszek Koltunski
    if( curr==0 )
605 59b87d56 Leszek Koltunski
      {
606 9f171eba Leszek Koltunski
      scramble[curr][0] = rnd.nextInt(NUM_AXIS);
607 59b87d56 Leszek Koltunski
      }
608
    else
609
      {
610 582617c1 Leszek Koltunski
      int newVector = rnd.nextInt(NUM_AXIS -1);
611 9f171eba Leszek Koltunski
      scramble[curr][0] = (newVector>=scramble[curr-1][0] ? newVector+1 : newVector);
612 59b87d56 Leszek Koltunski
      }
613
614 9f171eba Leszek Koltunski
    scramble[curr][1] = rnd.nextFloat()<=0.5f ? 0 : 2;
615 59b87d56 Leszek Koltunski
616 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
617
      {
618 9f171eba Leszek Koltunski
      case 0: scramble[curr][2] = -1; break;
619
      case 1: scramble[curr][2] =  1; break;
620 5043d5d0 Leszek Koltunski
      }
621 59b87d56 Leszek Koltunski
    }
622
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624
// The Rex is solved if and only if:
625
//
626 5eedd516 Leszek Koltunski
// 1) all 12 of its edge cubits are rotated with the same quat
627
// 2) all its face & corner cubits are rotated with the same quat like the edge ones,
628
//    and optionally they also might be upside down.
629
//
630
// i.e.
631
// corners ( 0, 1, 2, 3, 4, 5, 6, 7) and faces (24,25) - might be extra QUAT[1]
632
// corners ( 8, 9,10,11,12,13,14,15) and faces (26,27) - might be extra QUAT[2]
633
// corners (16,17,18,19,20,21,22,23) and faces (28,29) - might be extra QUAT[3]
634 59b87d56 Leszek Koltunski
635
  public boolean isSolved()
636
    {
637 cce59cd4 Leszek Koltunski
    int q1,q = CUBITS[30].mQuatIndex;
638 59b87d56 Leszek Koltunski
639 cce59cd4 Leszek Koltunski
    for(int i=31; i<42; i++)
640 59b87d56 Leszek Koltunski
      {
641
      if( CUBITS[i].mQuatIndex != q) return false;
642
      }
643
644 5eedd516 Leszek Koltunski
    q1 = mulQuat(q,1);
645
646
    for(int i=0; i<8; i++)
647
      {
648
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
649
      }
650
651
    if( CUBITS[24].mQuatIndex != q && CUBITS[24].mQuatIndex != q1 ) return false;
652
    if( CUBITS[25].mQuatIndex != q && CUBITS[25].mQuatIndex != q1 ) return false;
653
654
    q1 = mulQuat(q,2);
655
656
    for(int i=8; i<16; i++)
657
      {
658
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
659
      }
660
661
    if( CUBITS[26].mQuatIndex != q && CUBITS[26].mQuatIndex != q1 ) return false;
662
    if( CUBITS[27].mQuatIndex != q && CUBITS[27].mQuatIndex != q1 ) return false;
663
664
    q1 = mulQuat(q,3);
665
666
    for(int i=16; i<24; i++)
667
      {
668
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
669
      }
670
671
    if( CUBITS[28].mQuatIndex != q && CUBITS[28].mQuatIndex != q1 ) return false;
672
    if( CUBITS[29].mQuatIndex != q && CUBITS[29].mQuatIndex != q1 ) return false;
673
674 59b87d56 Leszek Koltunski
    return true;
675
    }
676
677
///////////////////////////////////////////////////////////////////////////////////////////////////
678 688f7712 Leszek Koltunski
// only needed for solvers - there are no Rex solvers ATM
679 59b87d56 Leszek Koltunski
680
  public String retObjectString()
681
    {
682
    return "";
683
    }
684
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686
687
  public int getObjectName(int numLayers)
688
    {
689
    return R.string.rex3;
690
    }
691
692
///////////////////////////////////////////////////////////////////////////////////////////////////
693
694
  public int getInventor(int numLayers)
695
    {
696
    return R.string.rex3_inventor;
697
    }
698
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700
701
  public int getComplexity(int numLayers)
702
    {
703
    return 3;
704
    }
705
}