Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikSkewb.java @ ece1b58d

1 fb52fae9 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
import org.distorted.library.effect.MatrixEffectQuaternion;
27
import org.distorted.library.effect.VertexEffectDeform;
28
import org.distorted.library.effect.VertexEffectMove;
29
import org.distorted.library.effect.VertexEffectRotate;
30
import org.distorted.library.effect.VertexEffectScale;
31
import org.distorted.library.main.DistortedEffects;
32
import org.distorted.library.main.DistortedTexture;
33
import org.distorted.library.mesh.MeshBase;
34
import org.distorted.library.mesh.MeshJoined;
35
import org.distorted.library.mesh.MeshPolygon;
36
import org.distorted.library.mesh.MeshSquare;
37
import org.distorted.library.mesh.MeshTriangle;
38
import org.distorted.library.type.Static1D;
39
import org.distorted.library.type.Static3D;
40
import org.distorted.library.type.Static4D;
41
import org.distorted.main.RubikSurfaceView;
42
43
import java.util.Random;
44
45
import static org.distorted.effects.scramble.ScrambleEffect.START_AXIS;
46
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48
49
public class RubikSkewb extends RubikObject
50
{
51
  private static final float SQ2 = (float)Math.sqrt(2);
52
  private static final float SQ3 = (float)Math.sqrt(3);
53
54
  private static final int FACES_PER_CUBIT =6;
55
56
  // the four rotation axis of a RubikSkewb. Must be normalized.
57
  static final Static3D[] ROT_AXIS = new Static3D[]
58
         {
59
           new Static3D(+SQ3/3,+SQ3/3,+SQ3/3),
60
           new Static3D(+SQ3/3,+SQ3/3,-SQ3/3),
61
           new Static3D(+SQ3/3,-SQ3/3,+SQ3/3),
62
           new Static3D(+SQ3/3,-SQ3/3,-SQ3/3)
63
         };
64
65
  // the six axis that determine the faces
66
  static final Static3D[] FACE_AXIS = new Static3D[]
67
         {
68
           new Static3D(1,0,0), new Static3D(-1,0,0),
69
           new Static3D(0,1,0), new Static3D(0,-1,0),
70
           new Static3D(0,0,1), new Static3D(0,0,-1)
71
         };
72
73
  private static final int[] FACE_COLORS = new int[]
74
         {
75 ece1b58d Leszek Koltunski
           COLOR_YELLOW, COLOR_WHITE,
76
           COLOR_BLUE  , COLOR_GREEN,
77
           COLOR_RED   , COLOR_BROWN
78 fb52fae9 Leszek Koltunski
         };
79
80
  // All legal rotation quats of a RubikSkewb
81
  private static final Static4D[] QUATS = new Static4D[]
82
         {
83
           new Static4D(  0.0f,  0.0f,  0.0f,  1.0f ),
84
           new Static4D(  1.0f,  0.0f,  0.0f,  0.0f ),
85
           new Static4D(  0.0f,  1.0f,  0.0f,  0.0f ),
86
           new Static4D(  0.0f,  0.0f,  1.0f,  0.0f ),
87
88
           new Static4D(  0.5f,  0.5f,  0.5f,  0.5f ),
89
           new Static4D(  0.5f,  0.5f,  0.5f, -0.5f ),
90
           new Static4D(  0.5f,  0.5f, -0.5f,  0.5f ),
91
           new Static4D(  0.5f,  0.5f, -0.5f, -0.5f ),
92
           new Static4D(  0.5f, -0.5f,  0.5f,  0.5f ),
93
           new Static4D(  0.5f, -0.5f,  0.5f, -0.5f ),
94
           new Static4D(  0.5f, -0.5f, -0.5f,  0.5f ),
95
           new Static4D(  0.5f, -0.5f, -0.5f, -0.5f )
96
         };
97
98 63002261 Leszek Koltunski
  private static final float DIST_CORNER = 0.50f;
99
  private static final float DIST_CENTER = 0.49f;
100
101 fb52fae9 Leszek Koltunski
  // centers of the 8 corners + 6 sides ( i.e. of the all 14 cubits)
102
  private static final Static3D[] CENTERS = new Static3D[]
103
         {
104 63002261 Leszek Koltunski
           new Static3D( DIST_CORNER, DIST_CORNER, DIST_CORNER ),
105
           new Static3D( DIST_CORNER, DIST_CORNER,-DIST_CORNER ),
106
           new Static3D( DIST_CORNER,-DIST_CORNER, DIST_CORNER ),
107
           new Static3D( DIST_CORNER,-DIST_CORNER,-DIST_CORNER ),
108
           new Static3D(-DIST_CORNER, DIST_CORNER, DIST_CORNER ),
109
           new Static3D(-DIST_CORNER, DIST_CORNER,-DIST_CORNER ),
110
           new Static3D(-DIST_CORNER,-DIST_CORNER, DIST_CORNER ),
111
           new Static3D(-DIST_CORNER,-DIST_CORNER,-DIST_CORNER ),
112
113
           new Static3D( DIST_CENTER,        0.0f,        0.0f ),
114
           new Static3D(-DIST_CENTER,        0.0f,        0.0f ),
115
           new Static3D(        0.0f, DIST_CENTER,        0.0f ),
116
           new Static3D(        0.0f,-DIST_CENTER,        0.0f ),
117
           new Static3D(        0.0f,        0.0f, DIST_CENTER ),
118
           new Static3D(        0.0f,        0.0f,-DIST_CENTER ),
119 fb52fae9 Leszek Koltunski
         };
120
121
  // Colors of the faces of cubits. Each cubit, even the face pyramid, has 6 faces
122
  // (the face has one extra 'fake' face so that everything would have the same number)
123
  private static final int[][] mFaceMap = new int[][]
124
         {
125 eab9d8f8 Leszek Koltunski
           { 4,2,0, 12,12,12 },
126
           { 2,5,0, 12,12,12 },
127
           { 3,4,0, 12,12,12 },
128
           { 5,3,0, 12,12,12 },
129
           { 1,2,4, 12,12,12 },
130
           { 5,2,1, 12,12,12 },
131
           { 4,3,1, 12,12,12 },
132
           { 1,3,5, 12,12,12 },
133
134
           { 6 , 12,12,12,12,12 },
135
           { 7 , 12,12,12,12,12 },
136
           { 8 , 12,12,12,12,12 },
137
           { 9 , 12,12,12,12,12 },
138
           { 10, 12,12,12,12,12 },
139
           { 11, 12,12,12,12,12 },
140 fb52fae9 Leszek Koltunski
         };
141
142
  private static MeshBase mCornerMesh, mFaceMesh;
143
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
146
  RubikSkewb(int size, Static4D quat, DistortedTexture texture,
147
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
148
    {
149
    super(size, 60, quat, texture, mesh, effects, moves, RubikObjectList.SKEW, res, scrWidth);
150
    }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
154
  private void createCornerMesh()
155
    {
156
    float D = 0.02f;
157
    float E = 0.5f;
158
    float F = SQ2/2;
159
160
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
161
162
    float[] bands0 = { 1.0f    , 0,
163
                       1.0f-2*D, D*0.25f,
164
                       1.0f-4*D, D*0.35f,
165
                       1.0f-8*D, D*0.6f,
166
                       0.60f   , D*1.0f,
167
                       0.30f   , D*1.375f,
168
                       0.0f    , D*1.4f };
169
170
    MeshBase[] meshes = new MeshBase[FACES_PER_CUBIT];
171
172
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
173
    meshes[0].setEffectAssociation(0,1,0);
174
    meshes[1] = meshes[0].copy(true);
175
    meshes[1].setEffectAssociation(0,2,0);
176
    meshes[2] = meshes[0].copy(true);
177
    meshes[2].setEffectAssociation(0,4,0);
178
179
    float[] vertices1 = { 0,0, F,0, F/2,(SQ3/2)*F };
180 eab9d8f8 Leszek Koltunski
    float[] bands1 = { 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f };
181 fb52fae9 Leszek Koltunski
182 eab9d8f8 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
183 fb52fae9 Leszek Koltunski
    meshes[3].setEffectAssociation(0,8,0);
184
    meshes[4] = meshes[3].copy(true);
185
    meshes[4].setEffectAssociation(0,16,0);
186
    meshes[5] = meshes[3].copy(true);
187
    meshes[5].setEffectAssociation(0,32,0);
188
189
    mCornerMesh = new MeshJoined(meshes);
190
191
    Static3D axisX  = new Static3D(1,0,0);
192
    Static3D axisY  = new Static3D(0,1,0);
193
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
194
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
195
    Static1D angle1 = new Static1D(+90);
196
    Static1D angle2 = new Static1D(-90);
197
    Static1D angle3 = new Static1D(-15);
198
    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
199
    Static1D angle5 = new Static1D(120);
200
    Static1D angle6 = new Static1D(240);
201
    Static3D center1= new Static3D(0,0,0);
202
    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
203
    Static3D move1  = new Static3D(-E/4,-E/4,0);
204
    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
205
206
    float d0 =-0.04f;
207
    float d1 = 0.04f;
208
    float r0 = 0.15f;
209
    float r1 = 0.10f;
210
211
    Static3D vec0   = new Static3D(d0*(+SQ3/3),d0*(+SQ3/3),d0*(+SQ3/3));
212
    Static3D vec1   = new Static3D(d1*(+SQ3/3),d1*(-SQ3/3),d1*(-SQ3/3));
213
    Static3D vec2   = new Static3D(d1*(-SQ3/3),d1*(+SQ3/3),d1*(-SQ3/3));
214
    Static3D vec3   = new Static3D(d1*(-SQ3/3),d1*(-SQ3/3),d1*(+SQ3/3));
215
216
    Static1D radius = new Static1D(0.5f);
217
218
    Static3D cent0  = new Static3D( 0.0f, 0.0f, 0.0f);
219
    Static3D cent1  = new Static3D(-0.5f, 0.0f, 0.0f);
220
    Static3D cent2  = new Static3D( 0.0f,-0.5f, 0.0f);
221
    Static3D cent3  = new Static3D( 0.0f, 0.0f,-0.5f);
222
223
    Static4D reg0   = new Static4D(0,0,0,r0);
224
    Static4D reg1   = new Static4D(0,0,0,r1);
225
226
    VertexEffectMove   effect0 = new VertexEffectMove(move1);
227
    VertexEffectScale  effect1 = new VertexEffectScale(new Static3D(1,1,-1));
228
    VertexEffectRotate effect2 = new VertexEffectRotate(angle1,axisX,center1);
229
    VertexEffectRotate effect3 = new VertexEffectRotate(angle2,axisY,center1);
230
    VertexEffectMove   effect4 = new VertexEffectMove(move2);
231
    VertexEffectRotate effect5 = new VertexEffectRotate(angle1,axisX,center2);
232
    VertexEffectRotate effect6 = new VertexEffectRotate(angle3,axisY,center2);
233
    VertexEffectRotate effect7 = new VertexEffectRotate(angle4,axis0,center2);
234
    VertexEffectRotate effect8 = new VertexEffectRotate(angle5,axis1,center2);
235
    VertexEffectRotate effect9 = new VertexEffectRotate(angle6,axis1,center2);
236
237
    VertexEffectDeform effect10= new VertexEffectDeform(vec0,radius,cent0,reg0);
238
    VertexEffectDeform effect11= new VertexEffectDeform(vec1,radius,cent1,reg1);
239
    VertexEffectDeform effect12= new VertexEffectDeform(vec2,radius,cent2,reg1);
240
    VertexEffectDeform effect13= new VertexEffectDeform(vec3,radius,cent3,reg1);
241
242
    effect0.setMeshAssociation( 7,-1);  // meshes 0,1,2
243
    effect1.setMeshAssociation( 6,-1);  // meshes 1,2
244
    effect2.setMeshAssociation( 2,-1);  // mesh 1
245
    effect3.setMeshAssociation( 4,-1);  // mesh 2
246
    effect4.setMeshAssociation(56,-1);  // meshes 3,4,5
247
    effect5.setMeshAssociation(56,-1);  // meshes 3,4,5
248
    effect6.setMeshAssociation(56,-1);  // meshes 3,4,5
249
    effect7.setMeshAssociation(56,-1);  // meshes 3,4,5
250
    effect8.setMeshAssociation(16,-1);  // mesh 4
251
    effect9.setMeshAssociation(32,-1);  // mesh 5
252
253
    effect10.setMeshAssociation(63,-1); // all meshes
254
    effect11.setMeshAssociation(63,-1); // all meshes
255
    effect12.setMeshAssociation(63,-1); // all meshes
256
    effect13.setMeshAssociation(63,-1); // all meshes
257
258
    mCornerMesh.apply(effect0);
259
    mCornerMesh.apply(effect1);
260
    mCornerMesh.apply(effect2);
261
    mCornerMesh.apply(effect3);
262
    mCornerMesh.apply(effect4);
263
    mCornerMesh.apply(effect5);
264
    mCornerMesh.apply(effect6);
265
    mCornerMesh.apply(effect7);
266
    mCornerMesh.apply(effect8);
267
    mCornerMesh.apply(effect9);
268
269
    mCornerMesh.apply(effect10);
270
    mCornerMesh.apply(effect11);
271
    mCornerMesh.apply(effect12);
272
    mCornerMesh.apply(effect13);
273
274
    mCornerMesh.mergeEffComponents();
275
    }
276
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278
279
  private void createFaceMesh()
280
    {
281
    int association = 1;
282
283
    float D = 0.03f;
284
    float E = SQ2/4;
285
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
286
287 eab9d8f8 Leszek Koltunski
    float[] bands0 = { 1.0f    , 0,
288
                       1.0f-D/2, D*0.30f,
289
                       1.0f- D , D*0.50f,
290
                       1.0f-2*D, D*0.80f,
291
                       0.60f   , D*1.40f,
292
                       0.30f   , D*1.60f,
293
                       0.0f    , D*1.70f };
294 fb52fae9 Leszek Koltunski
295
    MeshBase[] meshes = new MeshBase[FACES_PER_CUBIT];
296
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
297
    meshes[0].setEffectAssociation(0,association,0);
298
299
    association <<= 1;
300
301
    float[] vertices1 = { -E,-SQ3*E, +E,-SQ3*E, 0,0 };
302 eab9d8f8 Leszek Koltunski
    float[] bands1 = { 1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f };
303 fb52fae9 Leszek Koltunski
304
    meshes[1] = new MeshPolygon(vertices1,bands1,0,0);
305
    meshes[1].setEffectAssociation(0,association,0);
306
307
    for(int i=2; i<FACES_PER_CUBIT-1; i++)
308
      {
309
      association <<= 1;
310
      meshes[i] = meshes[1].copy(true);
311
      meshes[i].setEffectAssociation(0,association,0);
312
      }
313
314
    association <<= 1;
315
    meshes[FACES_PER_CUBIT-1] = new MeshTriangle(1);                  // empty triangle so that
316
    meshes[FACES_PER_CUBIT-1].setEffectAssociation(0,association,0);  // all cubits have 6 faces
317
318
    mFaceMesh = new MeshJoined(meshes);
319
320
    Static3D center = new Static3D(0,0,0);
321
    Static3D axis1   = new Static3D(1,0,0);
322
    Static3D axis2   = new Static3D(0,0,1);
323
    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
324
325 eab9d8f8 Leszek Koltunski
    float f = 0.05f;
326 fb52fae9 Leszek Koltunski
    float r = 0.10f;
327
    float d = 0.5f;
328
    float e = +D*0.6f;
329
    Static3D vector0 = new Static3D(-f, 0, 0);
330
    Static3D vector1 = new Static3D( 0,+f, 0);
331
    Static3D vector2 = new Static3D(+f, 0, 0);
332
    Static3D vector3 = new Static3D( 0,-f, 0);
333
    Static1D radius  = new Static1D(1.0f);
334
    Static4D region  = new Static4D(0,0,0,r);
335
    Static3D center0 = new Static3D(+d, 0, e);
336
    Static3D center1 = new Static3D( 0,-d, e);
337
    Static3D center2 = new Static3D(-d, 0, e);
338
    Static3D center3 = new Static3D( 0,+d, e);
339
340
    VertexEffectRotate effect0 = new VertexEffectRotate( new Static1D(angle), axis1, center);
341
    VertexEffectRotate effect1 = new VertexEffectRotate( new Static1D(  135), axis2, center);
342
    VertexEffectRotate effect2 = new VertexEffectRotate( new Static1D(   45), axis2, center);
343
    VertexEffectRotate effect3 = new VertexEffectRotate( new Static1D(  -45), axis2, center);
344
    VertexEffectRotate effect4 = new VertexEffectRotate( new Static1D( -135), axis2, center);
345
    VertexEffectMove   effect5 = new VertexEffectMove( new Static3D(0,0,-0.5f) );
346
    VertexEffectDeform effect6 = new VertexEffectDeform(vector0,radius,center0,region);
347
    VertexEffectDeform effect7 = new VertexEffectDeform(vector1,radius,center1,region);
348
    VertexEffectDeform effect8 = new VertexEffectDeform(vector2,radius,center2,region);
349
    VertexEffectDeform effect9 = new VertexEffectDeform(vector3,radius,center3,region);
350
    VertexEffectScale  effect10= new VertexEffectScale(0.01f);
351
352
    effect0.setMeshAssociation(30,-1);  // meshes 1,2,3,4
353
    effect1.setMeshAssociation( 2,-1);  // mesh 1
354
    effect2.setMeshAssociation( 5,-1);  // meshes 0,2
355
    effect3.setMeshAssociation( 8,-1);  // mesh 3
356
    effect4.setMeshAssociation(16,-1);  // mesh 4
357
    effect5.setMeshAssociation(30,-1);  // meshes 1,2,3,4
358
    effect6.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
359
    effect7.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
360
    effect8.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
361
    effect9.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
362
    effect10.setMeshAssociation(32,-1); // mesh 5
363
364
    mFaceMesh.apply(effect0);
365
    mFaceMesh.apply(effect1);
366
    mFaceMesh.apply(effect2);
367
    mFaceMesh.apply(effect3);
368
    mFaceMesh.apply(effect4);
369
    mFaceMesh.apply(effect5);
370
    mFaceMesh.apply(effect6);
371
    mFaceMesh.apply(effect7);
372
    mFaceMesh.apply(effect8);
373
    mFaceMesh.apply(effect9);
374
    mFaceMesh.apply(effect10);
375
376
    mFaceMesh.mergeEffComponents();
377
    }
378
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  float getScreenRatio()
382
    {
383
    return 1.0f;
384
    }
385
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
388
  Static4D[] getQuats()
389
    {
390
    return QUATS;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395
  int getNumFaces()
396
    {
397
    return FACE_COLORS.length;
398
    }
399
400 eaee1ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402
  boolean shouldResetTextureMaps()
403
    {
404
    return false;
405
    }
406
407 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
408
// Each face has two types of a texture: the central square and the triangle in the corner.
409
410
  int getNumStickerTypes()
411
    {
412
    return 2;
413
    }
414
415 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
  float getBasicStep()
418
    {
419
    return SQ3;
420
    }
421
422 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
423
424
  int getNumCubitFaces()
425
    {
426
    return FACES_PER_CUBIT;
427
    }
428
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430
431
  Static3D[] getCubitPositions(int size)
432
    {
433
    return CENTERS;
434
    }
435
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437
438
  private Static4D getQuat(int cubit)
439
    {
440
    switch(cubit)
441
      {
442
      case  0: return QUATS[0];                          //  unit quat
443
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
444
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
445
      case  3: return QUATS[1];                          // 180 along X
446
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
447
      case  5: return QUATS[2];                          // 180 along Y
448
      case  6: return QUATS[3];                          // 180 along Z
449
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
450
      case  8: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
451
      case  9: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
452
      case 10: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
453
      case 11: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
454
      case 12: return QUATS[0];                          //  unit quaternion
455
      case 13: return QUATS[1];                          // 180 along X
456
      }
457
458
    return null;
459
    }
460
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462
463
  MeshBase createCubitMesh(int cubit)
464
    {
465
    MeshBase mesh;
466
467
    if( cubit<8 )
468
      {
469
      if( mCornerMesh==null ) createCornerMesh();
470
      mesh = mCornerMesh.copy(true);
471
      }
472
    else
473
      {
474
      if( mFaceMesh==null ) createFaceMesh();
475
      mesh = mFaceMesh.copy(true);
476
      }
477
478
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
479
    mesh.apply(quat,0xffffffff,0);
480
481
    return mesh;
482
    }
483
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485
486
  int getFaceColor(int cubit, int cubitface, int size)
487
    {
488
    return mFaceMap[cubit][cubitface];
489
    }
490
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492
493
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
494
    {
495 eab9d8f8 Leszek Koltunski
    int COLORS = FACE_COLORS.length;
496
497
    if( face<COLORS )
498
      {
499
      float STROKE = 0.035f*side;
500
      float L= left+0.125f*side;
501
      float H= 0.375f*side;
502
      float LEN = 0.5f*side;
503
504
      paint.setAntiAlias(true);
505
      paint.setStrokeWidth(STROKE);
506
      paint.setColor(FACE_COLORS[face]);
507
      paint.setStyle(Paint.Style.FILL);
508
509
      canvas.drawRect(left,top,left+side,top+side,paint);
510
511
      paint.setColor(INTERIOR_COLOR);
512
      paint.setStyle(Paint.Style.STROKE);
513
514
      canvas.drawLine( L    , H,  L+LEN, H    , paint);
515
      canvas.drawLine( L    , H,  L+LEN, H+LEN, paint);
516
      canvas.drawLine( L+LEN, H,  L+LEN, H+LEN, paint);
517
518
      float S1 = 0.125f*side;
519
      float S2 = 0.070f*side;
520
      float X  = 0.7f*S2;
521
522
      float LA = left+0.625f*side;
523
      float RA = left+0.125f*side;
524
      float TA = 0.375f*side;
525
      float BA = 0.875f*side;
526
527
      canvas.drawArc( LA-S1, TA     , LA     , TA+S1, 270, 90, false, paint);
528
      canvas.drawArc( RA+X , TA     , RA+X+S2, TA+S2, 135,135, false, paint);
529
      canvas.drawArc( LA-S2, BA-X-S2, LA     , BA-X ,   0,135, false, paint);
530
      }
531
    else
532
      {
533
      final float R = (SQ2/2)*side*0.10f;
534
      final float M = side*(0.5f-SQ2/4+0.018f);
535
536
      paint.setColor(FACE_COLORS[face-COLORS]);
537
      paint.setStyle(Paint.Style.FILL);
538
      canvas.drawRoundRect( left+M, top+M, left+side-M, top+side-M, R, R, paint);
539
      }
540 fb52fae9 Leszek Koltunski
    }
541
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543
544
  float returnMultiplier()
545
    {
546
    return 2.0f;
547
    }
548
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550
551
  float[] getRowChances()
552
    {
553
    float[] chances = new float[2];
554
555
    chances[0] = 0.5f;
556
    chances[1] = 1.0f;
557
558
    return chances;
559
    }
560
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
// PUBLIC API
563
564
  public Static3D[] getRotationAxis()
565
    {
566
    return ROT_AXIS;
567
    }
568
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570
571
  public int getBasicAngle()
572
    {
573
    return 3;
574
    }
575
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577
578
  public int computeRowFromOffset(float offset)
579
    {
580 63002261 Leszek Koltunski
    return offset<0.25f ? 0:1;
581 fb52fae9 Leszek Koltunski
    }
582
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584
585
  public float returnRotationFactor(float offset)
586
    {
587
    return 1.0f;
588
    }
589
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591
592
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
593
    {
594
    int numAxis = ROTATION_AXIS.length;
595
596
    if( oldRotAxis == START_AXIS )
597
      {
598
      return rnd.nextInt(numAxis);
599
      }
600
    else
601
      {
602
      int newVector = rnd.nextInt(numAxis-1);
603
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
604
      }
605
    }
606
607
///////////////////////////////////////////////////////////////////////////////////////////////////
608
609
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
610
    {
611
    float rowFloat = rnd.nextFloat();
612
613
    for(int row=0; row<mRowChances.length; row++)
614
      {
615
      if( rowFloat<=mRowChances[row] ) return row;
616
      }
617
618
    return 0;
619
    }
620
621
///////////////////////////////////////////////////////////////////////////////////////////////////
622
// remember about the double cover or unit quaternions!
623
624
  private int mulQuat(int q1, int q2)
625
    {
626
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
627
628
    float rX = result.get0();
629
    float rY = result.get1();
630
    float rZ = result.get2();
631
    float rW = result.get3();
632
633
    final float MAX_ERROR = 0.1f;
634
    float dX,dY,dZ,dW;
635
636
    for(int i=0; i<QUATS.length; i++)
637
      {
638
      dX = QUATS[i].get0() - rX;
639
      dY = QUATS[i].get1() - rY;
640
      dZ = QUATS[i].get2() - rZ;
641
      dW = QUATS[i].get3() - rW;
642
643
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
644
          dY<MAX_ERROR && dY>-MAX_ERROR &&
645
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
646
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
647
648
      dX = QUATS[i].get0() + rX;
649
      dY = QUATS[i].get1() + rY;
650
      dZ = QUATS[i].get2() + rZ;
651
      dW = QUATS[i].get3() + rW;
652
653
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
654
          dY<MAX_ERROR && dY>-MAX_ERROR &&
655
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
656
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
657
      }
658
659
    return -1;
660
    }
661
662
///////////////////////////////////////////////////////////////////////////////////////////////////
663
// The Skewb is solved if and only if:
664
//
665
// 1) all of its corner cubits are rotated with the same quat
666
// 2) all its face cubits are rotated with the same quat like the corner ones,
667
//    and optionally they also might be upside down.
668
//
669
// i.e.
670
// cubits [ 8] and [ 9] - might be extra QUAT[1]
671
// cubits [10] and [11] - might be extra QUAT[2]
672
// cubits [12] and [13] - might be extra QUAT[3]
673
674
  public boolean isSolved()
675
    {
676
    int q = CUBITS[0].mQuatIndex;
677
678
    if ( CUBITS[1].mQuatIndex == q &&
679
         CUBITS[2].mQuatIndex == q &&
680
         CUBITS[3].mQuatIndex == q &&
681
         CUBITS[4].mQuatIndex == q &&
682
         CUBITS[5].mQuatIndex == q &&
683
         CUBITS[6].mQuatIndex == q &&
684
         CUBITS[7].mQuatIndex == q  )
685
      {
686
      int q1 = mulQuat(q,1);
687
      int q2 = mulQuat(q,2);
688
      int q3 = mulQuat(q,3);
689
690
      return (CUBITS[ 8].mQuatIndex == q || CUBITS[ 8].mQuatIndex == q1) &&
691
             (CUBITS[ 9].mQuatIndex == q || CUBITS[ 9].mQuatIndex == q1) &&
692
             (CUBITS[10].mQuatIndex == q || CUBITS[10].mQuatIndex == q2) &&
693
             (CUBITS[11].mQuatIndex == q || CUBITS[11].mQuatIndex == q2) &&
694
             (CUBITS[12].mQuatIndex == q || CUBITS[12].mQuatIndex == q3) &&
695
             (CUBITS[13].mQuatIndex == q || CUBITS[13].mQuatIndex == q3)  ;
696
      }
697
698
    return false;
699
    }
700
701
///////////////////////////////////////////////////////////////////////////////////////////////////
702 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
703 fb52fae9 Leszek Koltunski
704
  public String retObjectString()
705
    {
706
    return "";
707
    }
708
709
}