Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikSkewb.java @ 77899b4c

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