Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / TwistyRex.java @ 925ed78f

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
  float[] getCuts(int numLayers)
186
    {
187
    float C = SQ3*0.15f;   // bit less than 1/6 of the length of the main diagonal
188
189
    return new float[] {-C,+C};
190
    }
191
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
194
  int getNumCubitFaces()
195
    {
196
    return FACES_PER_CUBIT;
197
    }
198
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
201 e6cf7283 Leszek Koltunski
  float[][] getCubitPositions(int numLayers)
202 59b87d56 Leszek Koltunski
    {
203
    final float DIST = 0.50f;
204 da36b97e Leszek Koltunski
    final float DIST2= (1+2*REX_D)/6;
205 59b87d56 Leszek Koltunski
206 e6cf7283 Leszek Koltunski
    final float[][] CENTERS = new float[42][];
207
208
    CENTERS[ 0] = new float[] { +DIST , +DIST2, +DIST2};
209
    CENTERS[ 1] = new float[] { +DIST , +DIST2, -DIST2};
210
    CENTERS[ 2] = new float[] { +DIST , -DIST2, -DIST2};
211
    CENTERS[ 3] = new float[] { +DIST , -DIST2, +DIST2};
212
    CENTERS[ 4] = new float[] { -DIST , +DIST2, +DIST2};
213
    CENTERS[ 5] = new float[] { -DIST , +DIST2, -DIST2};
214
    CENTERS[ 6] = new float[] { -DIST , -DIST2, -DIST2};
215
    CENTERS[ 7] = new float[] { -DIST , -DIST2, +DIST2};
216
    CENTERS[ 8] = new float[] { +DIST2, +DIST , +DIST2};
217
    CENTERS[ 9] = new float[] { +DIST2, +DIST , -DIST2};
218
    CENTERS[10] = new float[] { -DIST2, +DIST , -DIST2};
219
    CENTERS[11] = new float[] { -DIST2, +DIST , +DIST2};
220
    CENTERS[12] = new float[] { +DIST2, -DIST , +DIST2};
221
    CENTERS[13] = new float[] { +DIST2, -DIST , -DIST2};
222
    CENTERS[14] = new float[] { -DIST2, -DIST , -DIST2};
223
    CENTERS[15] = new float[] { -DIST2, -DIST , +DIST2};
224
    CENTERS[16] = new float[] { +DIST2, +DIST2, +DIST };
225
    CENTERS[17] = new float[] { +DIST2, -DIST2, +DIST };
226
    CENTERS[18] = new float[] { -DIST2, -DIST2, +DIST };
227
    CENTERS[19] = new float[] { -DIST2, +DIST2, +DIST };
228
    CENTERS[20] = new float[] { +DIST2, +DIST2, -DIST };
229
    CENTERS[21] = new float[] { +DIST2, -DIST2, -DIST };
230
    CENTERS[22] = new float[] { -DIST2, -DIST2, -DIST };
231
    CENTERS[23] = new float[] { -DIST2, +DIST2, -DIST };
232
233
    CENTERS[24] = new float[] { +DIST , +0.00f, +0.00f};
234
    CENTERS[25] = new float[] { -DIST , +0.00f, +0.00f};
235
    CENTERS[26] = new float[] { +0.00f, +DIST , +0.00f};
236
    CENTERS[27] = new float[] { +0.00f, -DIST , +0.00f};
237
    CENTERS[28] = new float[] { +0.00f, +0.00f, +DIST };
238
    CENTERS[29] = new float[] { +0.00f, +0.00f, -DIST };
239
240
    CENTERS[30] = new float[] { +0.00f, +DIST , +DIST };
241
    CENTERS[31] = new float[] { +DIST , +0.00f, +DIST };
242
    CENTERS[32] = new float[] { +0.00f, -DIST , +DIST };
243
    CENTERS[33] = new float[] { -DIST , +0.00f, +DIST };
244
    CENTERS[34] = new float[] { +DIST , +DIST , +0.00f};
245
    CENTERS[35] = new float[] { +DIST , -DIST , +0.00f};
246
    CENTERS[36] = new float[] { -DIST , -DIST , +0.00f};
247
    CENTERS[37] = new float[] { -DIST , +DIST , +0.00f};
248
    CENTERS[38] = new float[] { +0.00f, +DIST , -DIST };
249
    CENTERS[39] = new float[] { +DIST , +0.00f, -DIST };
250
    CENTERS[40] = new float[] { +0.00f, -DIST , -DIST };
251
    CENTERS[41] = new float[] { -DIST , +0.00f, -DIST };
252 59b87d56 Leszek Koltunski
253
    return CENTERS;
254
    }
255
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
258
  private Static4D getQuat(int cubit)
259
    {
260
    switch(cubit)
261
      {
262 80ec6abf Leszek Koltunski
      case  0: return new Static4D(+SQ2/2,     0,+SQ2/2,     0);
263
      case  1: return QUATS[5];
264
      case  2: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
265
      case  3: return QUATS[8];
266 59b87d56 Leszek Koltunski
      case  4: return QUATS[6];
267 80ec6abf Leszek Koltunski
      case  5: return new Static4D(-SQ2/2,     0,+SQ2/2,     0);
268 59b87d56 Leszek Koltunski
      case  6: return QUATS[11];
269 80ec6abf Leszek Koltunski
      case  7: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
270
      case  8: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
271
      case  9: return QUATS[10];
272 59b87d56 Leszek Koltunski
      case 10: return new Static4D(     0,+SQ2/2,+SQ2/2,     0);
273
      case 11: return QUATS[4];
274
      case 12: return QUATS[9];
275
      case 13: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
276
      case 14: return QUATS[7];
277
      case 15: return new Static4D(     0,-SQ2/2,+SQ2/2,     0);
278
      case 16: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
279
      case 17: return QUATS[0];
280
      case 18: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
281
      case 19: return QUATS[3];
282 80ec6abf Leszek Koltunski
      case 20: return QUATS[1];
283
      case 21: return new Static4D(+SQ2/2,-SQ2/2,     0,     0);
284
      case 22: return QUATS[2];
285
      case 23: return new Static4D(+SQ2/2,+SQ2/2,     0,     0);
286 59b87d56 Leszek Koltunski
287 80ec6abf Leszek Koltunski
      case 24: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
288
      case 25: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
289 59b87d56 Leszek Koltunski
      case 26: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
290
      case 27: return new Static4D(-SQ2/2,     0,     0, SQ2/2);
291
      case 28: return QUATS[0];
292
      case 29: return QUATS[1];
293
294
      case 30: return QUATS[0];
295
      case 31: return new Static4D(     0,     0,+SQ2/2, SQ2/2);
296
      case 32: return QUATS[3];
297
      case 33: return new Static4D(     0,     0,-SQ2/2, SQ2/2);
298 80ec6abf Leszek Koltunski
      case 34: return new Static4D(     0,-SQ2/2,     0, SQ2/2);
299 59b87d56 Leszek Koltunski
      case 35: return QUATS[7];
300
      case 36: return QUATS[9];
301 80ec6abf Leszek Koltunski
      case 37: return new Static4D(     0,+SQ2/2,     0, SQ2/2);
302 59b87d56 Leszek Koltunski
      case 38: return new Static4D(+SQ2/2,     0,     0, SQ2/2);
303
      case 39: return QUATS[8];
304
      case 40: return QUATS[1];
305
      case 41: return QUATS[6];
306
      }
307
308
    return QUATS[0];
309
    }
310
311 be56193c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
312
313
  MeshBase createFacesRexCorner()
314
    {
315
    MeshBase[] meshes = new MeshBase[2];
316
317
    float F = REX_D*SQ2;
318
    float G = (1-REX_D)*SQ2/2;
319
    float H = 0.1f;
320
    float J = +2*G/3 - H*G;
321
322
    float[] vertices = { -F/2, -G/3, +F/2, -G/3, H*F/2, J, -H*F/2, J};
323
324
    FactoryCubit factory = FactoryCubit.getInstance();
325
    float[] bands0 = factory.computeBands(+0.016f,10,G/3,0.5f,5);
326
    float[] bands1 = factory.computeBands(-0.230f,45,G/3,0.0f,2);
327
328
    meshes[0] = new MeshPolygon(vertices,bands0,1,1);
329
    meshes[0].setEffectAssociation(0,1,0);
330
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
331
    meshes[1].setEffectAssociation(0,2,0);
332
333
    return new MeshJoined(meshes);
334
    }
335
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338
  MeshBase createFacesRexFace()
339
    {
340
    MeshBase[] meshes = new MeshBase[2];
341
342
    float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
343
344
    FactoryCubit factory = FactoryCubit.getInstance();
345
    float[] bands0 = factory.computeBands(0.016f,10,REX_D/2,0.5f,5);
346
    float[] bands1 = factory.computeBands(0.000f,45,REX_D/2,0.0f,2);
347
348
    meshes[0] = new MeshPolygon(vertices,bands0,0,0);
349
    meshes[0].setEffectAssociation(0,1,0);
350
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
351
    meshes[1].setEffectAssociation(0,2,0);
352
353
    return new MeshJoined(meshes);
354
    }
355
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
358
  MeshBase createFacesRexEdge()
359
    {
360
    MeshBase[] meshes = new MeshPolygon[6];
361
    FactoryCubit factory = FactoryCubit.getInstance();
362
363
    float E = 0.5f - REX_D;
364
    float F = 0.5f;
365
    float[] vertices0 = { -F,E/3, 0,-2*E/3, +F,E/3 };
366
    float[] bands0 = factory.computeBands(0.03f,27,F/3,0.8f,5);
367
368
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 3);
369
    meshes[0].setEffectAssociation(0,1,0);
370
    meshes[1] = meshes[0].copy(true);
371
    meshes[1].setEffectAssociation(0,2,0);
372
373
    float G = (float)Math.sqrt(E*E+F*F);
374
    float[] vertices1 = { -2*G/3, -E/3, G/3, -E/3, G/3, 2*E/3 };
375
    float[] bands1 = factory.computeBands(0.00f,45,G/3,0.2f,3);
376
377
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
378
    meshes[2].setEffectAssociation(0,4,0);
379
    meshes[3] = meshes[2].copy(true);
380
    meshes[3].setEffectAssociation(0,8,0);
381
    meshes[4] = meshes[2].copy(true);
382
    meshes[4].setEffectAssociation(0,16,0);
383
    meshes[5] = meshes[2].copy(true);
384
    meshes[5].setEffectAssociation(0,32,0);
385
386
    return new MeshJoined(meshes);
387
    }
388
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390
391
  private VertexEffect[] createVertexEffectsRexEdge()
392
    {
393
    float E = 0.5f - REX_D;
394
    float F = 0.5f;
395
    float G = (float)Math.sqrt(E*E+F*F);
396
    float A = (float)((180/Math.PI)*Math.asin(E/G));
397
398
    Static3D move1 = new Static3D(    0.0f, -E/3, 0.0f);
399
    Static3D move2 = new Static3D(2*G/3 -F, +E/3, 0.0f);
400
401
    Static3D center0= new Static3D(0.0f, 0.0f, 0.0f);
402
    Static3D center1= new Static3D(  -F, 0.0f, 0.0f);
403
    Static3D center2= new Static3D(  +F, 0.0f, 0.0f);
404
    Static3D axisX  = new Static3D(1.0f, 0.0f, 0.0f);
405
    Static3D axisY  = new Static3D(0.0f, 1.0f, 0.0f);
406
    Static3D axisZ  = new Static3D(0.0f, 0.0f, 1.0f);
407
408
    Static1D angle180 = new Static1D(180);
409
    Static1D angle90  = new Static1D( 90);
410
    Static1D angle270 = new Static1D(270);
411
    Static1D angle1   = new Static1D(+A);
412
    Static1D angle2   = new Static1D(-A);
413
414
    VertexEffect[] effect = new VertexEffect[12];
415
416
    effect[0] = new VertexEffectMove(move1);
417
    effect[1] = new VertexEffectMove(move2);
418
    effect[2] = new VertexEffectRotate(  angle90, axisX, center0 );
419
    effect[3] = new VertexEffectRotate( angle270, axisX, center0 );
420
    effect[4] = new VertexEffectRotate( angle180, axisX, center0 );
421
    effect[5] = new VertexEffectRotate( angle180, axisY, center0 );
422
    effect[6] = new VertexEffectScale( new Static3D(-1, 1, 1) );
423
    effect[7] = new VertexEffectScale ( new Static3D( 1,-1, 1) );
424
    effect[8] = new VertexEffectRotate(   angle1, axisY, center1);
425
    effect[9] = new VertexEffectRotate(   angle2, axisY, center2);
426
    effect[10]= new VertexEffectRotate(   angle2, axisZ, center1);
427
    effect[11]= new VertexEffectRotate(   angle1, axisZ, center2);
428
429
    effect[0].setMeshAssociation( 3,-1);  // meshes 0 & 1
430
    effect[1].setMeshAssociation(60,-1);  // meshes 2,3,4,5
431
    effect[2].setMeshAssociation( 2,-1);  // meshes 1
432
    effect[3].setMeshAssociation(12,-1);  // meshes 2,3
433
    effect[4].setMeshAssociation(48,-1);  // meshes 4,5
434
    effect[5].setMeshAssociation(32,-1);  // mesh 5
435
    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
436
    effect[7].setMeshAssociation( 2,-1);  // apply to mesh 1
437
    effect[8].setMeshAssociation(16,-1);  // apply to mesh 4
438
    effect[9].setMeshAssociation(32,-1);  // apply to mesh 5
439
    effect[10].setMeshAssociation(4,-1);  // apply to mesh 2
440
    effect[11].setMeshAssociation(8,-1);  // apply to mesh 3
441
442
    return effect;
443
    }
444
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
447
  private VertexEffect[] createVertexEffectsRexCorner()
448
    {
449
    Static3D center= new Static3D(0.0f, 0.0f, 0.0f);
450
    Static3D axisZ = new Static3D(0.0f, 0.0f, 1.0f);
451
    Static1D angle = new Static1D(225);
452
453
    VertexEffect[] effect = new VertexEffect[1];
454
    effect[0] = new VertexEffectRotate(angle, axisZ, center);
455
456
    return effect;
457
    }
458
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
461
  private MeshBase createRexCornerMesh()
462
    {
463
    MeshBase mesh = createFacesRexCorner();
464
    VertexEffect[] effects = createVertexEffectsRexCorner();
465
    for( VertexEffect effect : effects ) mesh.apply(effect);
466
467
    final float G = (1-REX_D)/3;
468
    Static3D center = new Static3D(0.0f,0.0f,-G*SQ2/2);
469
    Static3D[] vertices = new Static3D[1];
470
    vertices[0] = new Static3D(+G,-G,+0.0f);
471
    FactoryCubit.getInstance().roundCorners(mesh,center,vertices,0.10f,0.10f);
472
473
    mesh.mergeEffComponents();
474
    mesh.addEmptyTexComponent();
475
    mesh.addEmptyTexComponent();
476
    mesh.addEmptyTexComponent();
477
    mesh.addEmptyTexComponent();
478
479
    return mesh;
480
    }
481
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483
484
  private MeshBase createRexFaceMesh()
485
    {
486
    MeshBase mesh = createFacesRexFace();
487
488
    mesh.mergeEffComponents();
489
    mesh.addEmptyTexComponent();
490
    mesh.addEmptyTexComponent();
491
    mesh.addEmptyTexComponent();
492
    mesh.addEmptyTexComponent();
493
494
    return mesh;
495
    }
496
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498
499
  private MeshBase createRexEdgeMesh()
500
    {
501
    MeshBase mesh = createFacesRexEdge();
502
    VertexEffect[] effects = createVertexEffectsRexEdge();
503
    for( VertexEffect effect : effects ) mesh.apply(effect);
504
505
    Static3D center = new Static3D(0.0f,-0.5f,-0.5f);
506
    Static3D[] vertices = new Static3D[2];
507
    vertices[0] = new Static3D(+0.5f,+0.0f,+0.0f);
508
    vertices[1] = new Static3D(-0.5f,+0.0f,+0.0f);
509
    FactoryCubit.getInstance().roundCorners(mesh,center,vertices,0.06f,0.10f);
510
511
    mesh.mergeEffComponents();
512
513
    return mesh;
514
    }
515
516 59b87d56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
517
518 a64e07d0 Leszek Koltunski
  MeshBase createCubitMesh(int cubit, int numLayers)
519 59b87d56 Leszek Koltunski
    {
520
    MeshBase mesh;
521
522 f5c134c3 Leszek Koltunski
    if( cubit<24 )
523 59b87d56 Leszek Koltunski
      {
524 be56193c Leszek Koltunski
      if( mCornerMesh==null ) mCornerMesh = createRexCornerMesh();
525 59b87d56 Leszek Koltunski
      mesh = mCornerMesh.copy(true);
526
      }
527 f5c134c3 Leszek Koltunski
    else if( cubit<30 )
528 59b87d56 Leszek Koltunski
      {
529 be56193c Leszek Koltunski
      if( mFaceMesh==null ) mFaceMesh = createRexFaceMesh();
530 59b87d56 Leszek Koltunski
      mesh = mFaceMesh.copy(true);
531
      }
532
    else
533
      {
534 be56193c Leszek Koltunski
      if( mEdgeMesh==null ) mEdgeMesh = createRexEdgeMesh();
535 59b87d56 Leszek Koltunski
      mesh = mEdgeMesh.copy(true);
536
      }
537
538
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
539
    mesh.apply(quat,0xffffffff,0);
540
541
    return mesh;
542
    }
543
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545
546
  int getFaceColor(int cubit, int cubitface, int numLayers)
547
    {
548
    return mFaceMap[cubit][cubitface];
549
    }
550
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552
553
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
554
    {
555
    int COLORS = FACE_COLORS.length;
556
    FactorySticker factory = FactorySticker.getInstance();
557 da36b97e Leszek Koltunski
    float S1 = 0.050f;
558
    float S2 = 0.051f;
559
    float R1 = 0.07f;
560
    float R2 = 0.02f;
561
    float R3 = 0.06f;
562
    float R4 = 0.04f;
563 59b87d56 Leszek Koltunski
564
    if( face<COLORS )
565
      {
566 da36b97e Leszek Koltunski
      factory.drawRexCornerSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S1, R2, R3);
567 59b87d56 Leszek Koltunski
      }
568
    else if( face<2*COLORS )
569
      {
570 da36b97e Leszek Koltunski
      float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
571
      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, S1, FACE_COLORS[face%COLORS], R4);
572 59b87d56 Leszek Koltunski
      }
573
    else
574
      {
575 5eedd516 Leszek Koltunski
      factory.drawRexEdgeSticker(canvas, paint, left, top, FACE_COLORS[face%COLORS], S2, R1);
576 59b87d56 Leszek Koltunski
      }
577
    }
578
579
///////////////////////////////////////////////////////////////////////////////////////////////////
580
581
  float returnMultiplier()
582
    {
583
    return 2.0f;
584
    }
585
586
///////////////////////////////////////////////////////////////////////////////////////////////////
587
// PUBLIC API
588
589
  public Static3D[] getRotationAxis()
590
    {
591
    return ROT_AXIS;
592
    }
593
594
///////////////////////////////////////////////////////////////////////////////////////////////////
595
596 925ed78f Leszek Koltunski
  public int[] getBasicAngle()
597 59b87d56 Leszek Koltunski
    {
598 925ed78f Leszek Koltunski
    return BASIC_ANGLE;
599 59b87d56 Leszek Koltunski
    }
600
601
///////////////////////////////////////////////////////////////////////////////////////////////////
602
603 5043d5d0 Leszek Koltunski
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
604 59b87d56 Leszek Koltunski
    {
605 5043d5d0 Leszek Koltunski
    if( num==0 )
606 59b87d56 Leszek Koltunski
      {
607 582617c1 Leszek Koltunski
      scramble[num][0] = rnd.nextInt(NUM_AXIS);
608 59b87d56 Leszek Koltunski
      }
609
    else
610
      {
611 582617c1 Leszek Koltunski
      int newVector = rnd.nextInt(NUM_AXIS -1);
612 5043d5d0 Leszek Koltunski
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
613 59b87d56 Leszek Koltunski
      }
614
615 0203be88 Leszek Koltunski
    scramble[num][1] = rnd.nextFloat()<=0.5f ? 0 : 2;
616 59b87d56 Leszek Koltunski
617 5043d5d0 Leszek Koltunski
    switch( rnd.nextInt(2) )
618
      {
619
      case 0: scramble[num][2] = -1; break;
620
      case 1: scramble[num][2] =  1; break;
621
      }
622 59b87d56 Leszek Koltunski
    }
623
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625
// The Rex is solved if and only if:
626
//
627 5eedd516 Leszek Koltunski
// 1) all 12 of its edge cubits are rotated with the same quat
628
// 2) all its face & corner cubits are rotated with the same quat like the edge ones,
629
//    and optionally they also might be upside down.
630
//
631
// i.e.
632
// corners ( 0, 1, 2, 3, 4, 5, 6, 7) and faces (24,25) - might be extra QUAT[1]
633
// corners ( 8, 9,10,11,12,13,14,15) and faces (26,27) - might be extra QUAT[2]
634
// corners (16,17,18,19,20,21,22,23) and faces (28,29) - might be extra QUAT[3]
635 59b87d56 Leszek Koltunski
636
  public boolean isSolved()
637
    {
638 cce59cd4 Leszek Koltunski
    int q1,q = CUBITS[30].mQuatIndex;
639 59b87d56 Leszek Koltunski
640 cce59cd4 Leszek Koltunski
    for(int i=31; i<42; i++)
641 59b87d56 Leszek Koltunski
      {
642
      if( CUBITS[i].mQuatIndex != q) return false;
643
      }
644
645 5eedd516 Leszek Koltunski
    q1 = mulQuat(q,1);
646
647
    for(int i=0; i<8; i++)
648
      {
649
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
650
      }
651
652
    if( CUBITS[24].mQuatIndex != q && CUBITS[24].mQuatIndex != q1 ) return false;
653
    if( CUBITS[25].mQuatIndex != q && CUBITS[25].mQuatIndex != q1 ) return false;
654
655
    q1 = mulQuat(q,2);
656
657
    for(int i=8; i<16; i++)
658
      {
659
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
660
      }
661
662
    if( CUBITS[26].mQuatIndex != q && CUBITS[26].mQuatIndex != q1 ) return false;
663
    if( CUBITS[27].mQuatIndex != q && CUBITS[27].mQuatIndex != q1 ) return false;
664
665
    q1 = mulQuat(q,3);
666
667
    for(int i=16; i<24; i++)
668
      {
669
      if( CUBITS[i].mQuatIndex != q && CUBITS[i].mQuatIndex != q1 ) return false;
670
      }
671
672
    if( CUBITS[28].mQuatIndex != q && CUBITS[28].mQuatIndex != q1 ) return false;
673
    if( CUBITS[29].mQuatIndex != q && CUBITS[29].mQuatIndex != q1 ) return false;
674
675 59b87d56 Leszek Koltunski
    return true;
676
    }
677
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679 688f7712 Leszek Koltunski
// only needed for solvers - there are no Rex solvers ATM
680 59b87d56 Leszek Koltunski
681
  public String retObjectString()
682
    {
683
    return "";
684
    }
685
686
///////////////////////////////////////////////////////////////////////////////////////////////////
687
688
  public int getObjectName(int numLayers)
689
    {
690
    return R.string.rex3;
691
    }
692
693
///////////////////////////////////////////////////////////////////////////////////////////////////
694
695
  public int getInventor(int numLayers)
696
    {
697
    return R.string.rex3_inventor;
698
    }
699
700
///////////////////////////////////////////////////////////////////////////////////////////////////
701
702
  public int getComplexity(int numLayers)
703
    {
704
    return 3;
705
    }
706
}