Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikSkewb.java @ 4fb1fc0d

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
           0xffffff00, 0xffffffff,   // FACE_AXIS[0] (right-YELLOW) FACE_AXIS[1] (left  -WHITE)
76
           0xff0000ff, 0xff00ff00,   // FACE_AXIS[2] (top  -BLUE  ) FACE_AXIS[3] (bottom-GREEN)
77
           0xffff0000, 0xffb5651d    // FACE_AXIS[4] (front-RED   ) FACE_AXIS[5] (back  -BROWN)
78
         };
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 eab9d8f8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
401
// Each face has two types of a texture: the central square and the triangle in the corner.
402
403
  int getNumStickerTypes()
404
    {
405
    return 2;
406
    }
407
408 7403cdfa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
409
410
  float getBasicStep()
411
    {
412
    return SQ3;
413
    }
414
415 fb52fae9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
  int getNumCubitFaces()
418
    {
419
    return FACES_PER_CUBIT;
420
    }
421
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
424
  Static3D[] getCubitPositions(int size)
425
    {
426
    return CENTERS;
427
    }
428
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430
431
  private Static4D getQuat(int cubit)
432
    {
433
    switch(cubit)
434
      {
435
      case  0: return QUATS[0];                          //  unit quat
436
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
437
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
438
      case  3: return QUATS[1];                          // 180 along X
439
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
440
      case  5: return QUATS[2];                          // 180 along Y
441
      case  6: return QUATS[3];                          // 180 along Z
442
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
443
      case  8: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
444
      case  9: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
445
      case 10: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
446
      case 11: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
447
      case 12: return QUATS[0];                          //  unit quaternion
448
      case 13: return QUATS[1];                          // 180 along X
449
      }
450
451
    return null;
452
    }
453
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455
456
  MeshBase createCubitMesh(int cubit)
457
    {
458
    MeshBase mesh;
459
460
    if( cubit<8 )
461
      {
462
      if( mCornerMesh==null ) createCornerMesh();
463
      mesh = mCornerMesh.copy(true);
464
      }
465
    else
466
      {
467
      if( mFaceMesh==null ) createFaceMesh();
468
      mesh = mFaceMesh.copy(true);
469
      }
470
471
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
472
    mesh.apply(quat,0xffffffff,0);
473
474
    return mesh;
475
    }
476
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478
479
  int getFaceColor(int cubit, int cubitface, int size)
480
    {
481
    return mFaceMap[cubit][cubitface];
482
    }
483
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485
486
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
487
    {
488 eab9d8f8 Leszek Koltunski
    int COLORS = FACE_COLORS.length;
489
490
    if( face<COLORS )
491
      {
492
      float STROKE = 0.035f*side;
493
      float L= left+0.125f*side;
494
      float H= 0.375f*side;
495
      float LEN = 0.5f*side;
496
497
      paint.setAntiAlias(true);
498
      paint.setStrokeWidth(STROKE);
499
      paint.setColor(FACE_COLORS[face]);
500
      paint.setStyle(Paint.Style.FILL);
501
502
      canvas.drawRect(left,top,left+side,top+side,paint);
503
504
      paint.setColor(INTERIOR_COLOR);
505
      paint.setStyle(Paint.Style.STROKE);
506
507
      canvas.drawLine( L    , H,  L+LEN, H    , paint);
508
      canvas.drawLine( L    , H,  L+LEN, H+LEN, paint);
509
      canvas.drawLine( L+LEN, H,  L+LEN, H+LEN, paint);
510
511
      float S1 = 0.125f*side;
512
      float S2 = 0.070f*side;
513
      float X  = 0.7f*S2;
514
515
      float LA = left+0.625f*side;
516
      float RA = left+0.125f*side;
517
      float TA = 0.375f*side;
518
      float BA = 0.875f*side;
519
520
      canvas.drawArc( LA-S1, TA     , LA     , TA+S1, 270, 90, false, paint);
521
      canvas.drawArc( RA+X , TA     , RA+X+S2, TA+S2, 135,135, false, paint);
522
      canvas.drawArc( LA-S2, BA-X-S2, LA     , BA-X ,   0,135, false, paint);
523
      }
524
    else
525
      {
526
      final float R = (SQ2/2)*side*0.10f;
527
      final float M = side*(0.5f-SQ2/4+0.018f);
528
529
      paint.setColor(FACE_COLORS[face-COLORS]);
530
      paint.setStyle(Paint.Style.FILL);
531
      canvas.drawRoundRect( left+M, top+M, left+side-M, top+side-M, R, R, paint);
532
      }
533 fb52fae9 Leszek Koltunski
    }
534
535
///////////////////////////////////////////////////////////////////////////////////////////////////
536
537
  float returnMultiplier()
538
    {
539
    return 2.0f;
540
    }
541
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543
544
  float[] getRowChances()
545
    {
546
    float[] chances = new float[2];
547
548
    chances[0] = 0.5f;
549
    chances[1] = 1.0f;
550
551
    return chances;
552
    }
553
554
///////////////////////////////////////////////////////////////////////////////////////////////////
555
// PUBLIC API
556
557
  public Static3D[] getRotationAxis()
558
    {
559
    return ROT_AXIS;
560
    }
561
562
///////////////////////////////////////////////////////////////////////////////////////////////////
563
564
  public int getBasicAngle()
565
    {
566
    return 3;
567
    }
568
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570
571
  public int computeRowFromOffset(float offset)
572
    {
573 63002261 Leszek Koltunski
    return offset<0.25f ? 0:1;
574 fb52fae9 Leszek Koltunski
    }
575
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577
578
  public float returnRotationFactor(float offset)
579
    {
580
    return 1.0f;
581
    }
582
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584
585
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
586
    {
587
    int numAxis = ROTATION_AXIS.length;
588
589
    if( oldRotAxis == START_AXIS )
590
      {
591
      return rnd.nextInt(numAxis);
592
      }
593
    else
594
      {
595
      int newVector = rnd.nextInt(numAxis-1);
596
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
597
      }
598
    }
599
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601
602
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
603
    {
604
    float rowFloat = rnd.nextFloat();
605
606
    for(int row=0; row<mRowChances.length; row++)
607
      {
608
      if( rowFloat<=mRowChances[row] ) return row;
609
      }
610
611
    return 0;
612
    }
613
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615
// remember about the double cover or unit quaternions!
616
617
  private int mulQuat(int q1, int q2)
618
    {
619
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
620
621
    float rX = result.get0();
622
    float rY = result.get1();
623
    float rZ = result.get2();
624
    float rW = result.get3();
625
626
    final float MAX_ERROR = 0.1f;
627
    float dX,dY,dZ,dW;
628
629
    for(int i=0; i<QUATS.length; i++)
630
      {
631
      dX = QUATS[i].get0() - rX;
632
      dY = QUATS[i].get1() - rY;
633
      dZ = QUATS[i].get2() - rZ;
634
      dW = QUATS[i].get3() - rW;
635
636
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
637
          dY<MAX_ERROR && dY>-MAX_ERROR &&
638
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
639
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
640
641
      dX = QUATS[i].get0() + rX;
642
      dY = QUATS[i].get1() + rY;
643
      dZ = QUATS[i].get2() + rZ;
644
      dW = QUATS[i].get3() + rW;
645
646
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
647
          dY<MAX_ERROR && dY>-MAX_ERROR &&
648
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
649
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
650
      }
651
652
    return -1;
653
    }
654
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656
// The Skewb is solved if and only if:
657
//
658
// 1) all of its corner cubits are rotated with the same quat
659
// 2) all its face cubits are rotated with the same quat like the corner ones,
660
//    and optionally they also might be upside down.
661
//
662
// i.e.
663
// cubits [ 8] and [ 9] - might be extra QUAT[1]
664
// cubits [10] and [11] - might be extra QUAT[2]
665
// cubits [12] and [13] - might be extra QUAT[3]
666
667
  public boolean isSolved()
668
    {
669
    int q = CUBITS[0].mQuatIndex;
670
671
    if ( CUBITS[1].mQuatIndex == q &&
672
         CUBITS[2].mQuatIndex == q &&
673
         CUBITS[3].mQuatIndex == q &&
674
         CUBITS[4].mQuatIndex == q &&
675
         CUBITS[5].mQuatIndex == q &&
676
         CUBITS[6].mQuatIndex == q &&
677
         CUBITS[7].mQuatIndex == q  )
678
      {
679
      int q1 = mulQuat(q,1);
680
      int q2 = mulQuat(q,2);
681
      int q3 = mulQuat(q,3);
682
683
      return (CUBITS[ 8].mQuatIndex == q || CUBITS[ 8].mQuatIndex == q1) &&
684
             (CUBITS[ 9].mQuatIndex == q || CUBITS[ 9].mQuatIndex == q1) &&
685
             (CUBITS[10].mQuatIndex == q || CUBITS[10].mQuatIndex == q2) &&
686
             (CUBITS[11].mQuatIndex == q || CUBITS[11].mQuatIndex == q2) &&
687
             (CUBITS[12].mQuatIndex == q || CUBITS[12].mQuatIndex == q3) &&
688
             (CUBITS[13].mQuatIndex == q || CUBITS[13].mQuatIndex == q3)  ;
689
      }
690
691
    return false;
692
    }
693
694
///////////////////////////////////////////////////////////////////////////////////////////////////
695 ee35e63c Leszek Koltunski
// only needed for solvers - there are no Skewb solvers ATM)
696 fb52fae9 Leszek Koltunski
697
  public String retObjectString()
698
    {
699
    return "";
700
    }
701
702
}