Project

General

Profile

« Previous | Next » 

Revision fb52fae9

Added by Leszek Koltunski over 4 years ago

Beginnings of support for the Skewb.

View differences:

src/main/java/org/distorted/objects/RubikCube.java
548 548
    final int FRONT= 4;
549 549
    final int BACK = 5;
550 550

  
551
    final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B'};
552

  
553
/////////////////////
554
// LIVE DEBUGGING
555
/////////////////////
556
try
557
  {
558
/////////////////////
551
    // 'I' - interior, theoretically can happen
552
    final char[] FACE_NAMES = { 'R', 'L', 'U', 'D', 'F', 'B', 'I'};
559 553

  
560 554
    face = UP;
561 555

  
......
640 634
      objectString.append(FACE_NAMES[color]);
641 635
      }
642 636

  
643
/////////////////////
644
  }
645
catch(java.lang.ArrayIndexOutOfBoundsException ex)
646
  {
647
  FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
648

  
649
  String str="";
650
  for(int i=0; i<NUM_CUBITS; i++)
651
    {
652
    str += (CUBITS[i].mQuatIndex+" ");
653
    }
654

  
655
  crashlytics.setCustomKey("ObjectString", "color="+color+" cubitIndex="+cubitIndex+" face="+face+" row="+row+" col="+col );
656
  crashlytics.setCustomKey("Quaternion", "NUM_CUBITS: "+NUM_CUBITS+" quats: "+str );
657
  crashlytics.recordException(ex);
658
  }
659
/////////////////////
660
// END LIVE DEBUGGING
661
/////////////////////
662

  
663 637
    return objectString.toString();
664 638
    }
665 639
}
src/main/java/org/distorted/objects/RubikMovementSkewb.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
class RubikMovementSkewb extends RubikMovement
25
{
26
  RubikMovementSkewb()
27
    {
28
    super(RubikSkewb.ROT_AXIS, RubikSkewb.FACE_AXIS, 0.5f, 0.5f);
29
    }
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
// _____________
33
// |  \  0  /  |
34
// |   \   /   |
35
// | 3 |   | 1 |
36
// |   /   \   |
37
// |  /  2  \  |
38
// -------------
39

  
40
  private int getQuarter(float[] touchPoint)
41
    {
42
    boolean p0 = touchPoint[1] >= touchPoint[0];
43
    boolean p1 = touchPoint[1] >=-touchPoint[0];
44

  
45
    if( p0 )  return p1 ? 0:3;
46
    else      return p1 ? 1:2;
47
    }
48

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

  
51
  boolean isInsideFace(float[] p)
52
    {
53
    return ( p[0]<=0.5f && p[0]>=-0.5f && p[1]<=0.5f && p[1]>=-0.5f );
54
    }
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

  
58
  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
59
    {
60
    enabled[0] = 2;
61

  
62
    int quarter = getQuarter(touchPoint);
63

  
64
    switch(face)
65
      {
66
      case 0: switch(quarter)
67
                {
68
                case 0: enabled[1]=0; enabled[2]=1; break;
69
                case 1: enabled[1]=3; enabled[2]=1; break;
70
                case 2: enabled[1]=2; enabled[2]=3; break;
71
                case 3: enabled[1]=0; enabled[2]=2; break;
72
                }
73
              break;
74
      case 1: switch(quarter)
75
                {
76
                case 0: enabled[1]=2; enabled[2]=3; break;
77
                case 1: enabled[1]=3; enabled[2]=1; break;
78
                case 2: enabled[1]=0; enabled[2]=1; break;
79
                case 3: enabled[1]=0; enabled[2]=2; break;
80
                }
81
              break;
82
      case 2: switch(quarter)
83
                {
84
                case 0: enabled[1]=1; enabled[2]=2; break;
85
                case 1: enabled[1]=0; enabled[2]=1; break;
86
                case 2: enabled[1]=0; enabled[2]=3; break;
87
                case 3: enabled[1]=2; enabled[2]=3; break;
88
                }
89
              break;
90
      case 3: switch(quarter)
91
                {
92
                case 0: enabled[1]=1; enabled[2]=2; break;
93
                case 1: enabled[1]=2; enabled[2]=3; break;
94
                case 2: enabled[1]=0; enabled[2]=3; break;
95
                case 3: enabled[1]=0; enabled[2]=1; break;
96
                }
97
              break;
98
      case 4: switch(quarter)
99
                {
100
                case 0: enabled[1]=0; enabled[2]=3; break;
101
                case 1: enabled[1]=0; enabled[2]=2; break;
102
                case 2: enabled[1]=1; enabled[2]=2; break;
103
                case 3: enabled[1]=1; enabled[2]=3; break;
104
                }
105
              break;
106
      case 5: switch(quarter)
107
                {
108
                case 0: enabled[1]=1; enabled[2]=2; break;
109
                case 1: enabled[1]=0; enabled[2]=2; break;
110
                case 2: enabled[1]=0; enabled[2]=3; break;
111
                case 3: enabled[1]=1; enabled[2]=3; break;
112
                }
113
              break;
114
      }
115
    }
116
}
src/main/java/org/distorted/objects/RubikObject.java
59 59
  private static final float MAX_SIZE_CHANGE = 1.3f;
60 60
  private static final float MIN_SIZE_CHANGE = 0.8f;
61 61

  
62
  private static boolean mCreateFromDMesh = true;
62
  private static boolean mCreateFromDMesh = false;
63 63

  
64 64
  private static final Static3D CENTER = new Static3D(0,0,0);
65 65
  static final int INTERIOR_COLOR = 0xff000000;
src/main/java/org/distorted/objects/RubikObjectList.java
65 65
         new RubikMovementDino(),
66 66
         2
67 67
       ),
68

  
69
  SKEW (
70
         new int[][] {
71
                       {2 , 11, R.raw.dino, R.drawable.ui_small_dino, R.drawable.ui_medium_dino, R.drawable.ui_big_dino, R.drawable.ui_huge_dino} ,
72
                     },
73
         RubikSkewb.class,
74
         new RubikMovementSkewb(),
75
         2
76
       ),
68 77
  ;
69 78

  
70 79
  public static final int NUM_OBJECTS = values().length;
......
433 442
    {
434 443
    DistortedTexture texture = new DistortedTexture();
435 444
    DistortedEffects effects = new DistortedEffects();
436
    MeshSquare mesh      = new MeshSquare(20,20);   // mesh of the node, not of the cubits
445
    MeshSquare mesh          = new MeshSquare(20,20);   // mesh of the node, not of the cubits
437 446

  
438 447
    switch(ordinal())
439 448
      {
440 449
      case 0: return new RubikCube    (size, quat, texture, mesh, effects, moves, res, scrWidth);
441 450
      case 1: return new RubikPyraminx(size, quat, texture, mesh, effects, moves, res, scrWidth);
442 451
      case 2: return new RubikDino    (size, quat, texture, mesh, effects, moves, res, scrWidth);
452
      case 3: return new RubikSkewb   (size, quat, texture, mesh, effects, moves, res, scrWidth);
443 453
      }
444 454

  
445 455
    return null;
src/main/java/org/distorted/objects/RubikSkewb.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
  // centers of the 8 corners + 6 sides ( i.e. of the all 14 cubits)
99
  private static final Static3D[] CENTERS = new Static3D[]
100
         {
101
           new Static3D( 0.5f, 0.5f, 0.5f ),
102
           new Static3D( 0.5f, 0.5f,-0.5f ),
103
           new Static3D( 0.5f,-0.5f, 0.5f ),
104
           new Static3D( 0.5f,-0.5f,-0.5f ),
105
           new Static3D(-0.5f, 0.5f, 0.5f ),
106
           new Static3D(-0.5f, 0.5f,-0.5f ),
107
           new Static3D(-0.5f,-0.5f, 0.5f ),
108
           new Static3D(-0.5f,-0.5f,-0.5f ),
109

  
110
           new Static3D( 0.5f, 0.0f, 0.0f ),
111
           new Static3D(-0.5f, 0.0f, 0.0f ),
112
           new Static3D( 0.0f, 0.5f, 0.0f ),
113
           new Static3D( 0.0f,-0.5f, 0.0f ),
114
           new Static3D( 0.0f, 0.0f, 0.5f ),
115
           new Static3D( 0.0f, 0.0f,-0.5f ),
116
         };
117

  
118
  // Colors of the faces of cubits. Each cubit, even the face pyramid, has 6 faces
119
  // (the face has one extra 'fake' face so that everything would have the same number)
120
  private static final int[][] mFaceMap = new int[][]
121
         {
122
           { 4,2,0, 6,6,6 },
123
           { 2,5,0, 6,6,6 },
124
           { 3,4,0, 6,6,6 },
125
           { 5,3,0, 6,6,6 },
126
           { 1,2,4, 6,6,6 },
127
           { 5,2,1, 6,6,6 },
128
           { 4,3,1, 6,6,6 },
129
           { 1,3,5, 6,6,6 },
130

  
131
           { 0, 6,6,6,6,6 },
132
           { 1, 6,6,6,6,6 },
133
           { 2, 6,6,6,6,6 },
134
           { 3, 6,6,6,6,6 },
135
           { 4, 6,6,6,6,6 },
136
           { 5, 6,6,6,6,6 },
137
         };
138

  
139
  private static MeshBase mCornerMesh, mFaceMesh;
140

  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

  
143
  RubikSkewb(int size, Static4D quat, DistortedTexture texture,
144
             MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
145
    {
146
    super(size, 60, quat, texture, mesh, effects, moves, RubikObjectList.SKEW, res, scrWidth);
147
    }
148

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

  
151
  private void createCornerMesh()
152
    {
153
    float D = 0.02f;
154
    float E = 0.5f;
155
    float F = SQ2/2;
156

  
157
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
158

  
159
    float[] bands0 = { 1.0f    , 0,
160
                       1.0f-2*D, D*0.25f,
161
                       1.0f-4*D, D*0.35f,
162
                       1.0f-8*D, D*0.6f,
163
                       0.60f   , D*1.0f,
164
                       0.30f   , D*1.375f,
165
                       0.0f    , D*1.4f };
166

  
167
    MeshBase[] meshes = new MeshBase[FACES_PER_CUBIT];
168

  
169
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
170
    meshes[0].setEffectAssociation(0,1,0);
171
    meshes[1] = meshes[0].copy(true);
172
    meshes[1].setEffectAssociation(0,2,0);
173
    meshes[2] = meshes[0].copy(true);
174
    meshes[2].setEffectAssociation(0,4,0);
175

  
176
    float[] vertices1 = { 0,0, F,0, F/2,(SQ3/2)*F };
177
    float[] bands1 = { 1.0f, 0.0f, 0.0f, 0.0f };
178

  
179
    meshes[3] = new MeshPolygon(vertices1,bands1,0,0);
180
    meshes[3].setEffectAssociation(0,8,0);
181
    meshes[4] = meshes[3].copy(true);
182
    meshes[4].setEffectAssociation(0,16,0);
183
    meshes[5] = meshes[3].copy(true);
184
    meshes[5].setEffectAssociation(0,32,0);
185

  
186
    mCornerMesh = new MeshJoined(meshes);
187

  
188
    Static3D axisX  = new Static3D(1,0,0);
189
    Static3D axisY  = new Static3D(0,1,0);
190
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
191
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
192
    Static1D angle1 = new Static1D(+90);
193
    Static1D angle2 = new Static1D(-90);
194
    Static1D angle3 = new Static1D(-15);
195
    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
196
    Static1D angle5 = new Static1D(120);
197
    Static1D angle6 = new Static1D(240);
198
    Static3D center1= new Static3D(0,0,0);
199
    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
200
    Static3D move1  = new Static3D(-E/4,-E/4,0);
201
    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
202

  
203
    float d0 =-0.04f;
204
    float d1 = 0.04f;
205
    float r0 = 0.15f;
206
    float r1 = 0.10f;
207

  
208
    Static3D vec0   = new Static3D(d0*(+SQ3/3),d0*(+SQ3/3),d0*(+SQ3/3));
209
    Static3D vec1   = new Static3D(d1*(+SQ3/3),d1*(-SQ3/3),d1*(-SQ3/3));
210
    Static3D vec2   = new Static3D(d1*(-SQ3/3),d1*(+SQ3/3),d1*(-SQ3/3));
211
    Static3D vec3   = new Static3D(d1*(-SQ3/3),d1*(-SQ3/3),d1*(+SQ3/3));
212

  
213
    Static1D radius = new Static1D(0.5f);
214

  
215
    Static3D cent0  = new Static3D( 0.0f, 0.0f, 0.0f);
216
    Static3D cent1  = new Static3D(-0.5f, 0.0f, 0.0f);
217
    Static3D cent2  = new Static3D( 0.0f,-0.5f, 0.0f);
218
    Static3D cent3  = new Static3D( 0.0f, 0.0f,-0.5f);
219

  
220
    Static4D reg0   = new Static4D(0,0,0,r0);
221
    Static4D reg1   = new Static4D(0,0,0,r1);
222

  
223
    VertexEffectMove   effect0 = new VertexEffectMove(move1);
224
    VertexEffectScale  effect1 = new VertexEffectScale(new Static3D(1,1,-1));
225
    VertexEffectRotate effect2 = new VertexEffectRotate(angle1,axisX,center1);
226
    VertexEffectRotate effect3 = new VertexEffectRotate(angle2,axisY,center1);
227
    VertexEffectMove   effect4 = new VertexEffectMove(move2);
228
    VertexEffectRotate effect5 = new VertexEffectRotate(angle1,axisX,center2);
229
    VertexEffectRotate effect6 = new VertexEffectRotate(angle3,axisY,center2);
230
    VertexEffectRotate effect7 = new VertexEffectRotate(angle4,axis0,center2);
231
    VertexEffectRotate effect8 = new VertexEffectRotate(angle5,axis1,center2);
232
    VertexEffectRotate effect9 = new VertexEffectRotate(angle6,axis1,center2);
233

  
234
    VertexEffectDeform effect10= new VertexEffectDeform(vec0,radius,cent0,reg0);
235
    VertexEffectDeform effect11= new VertexEffectDeform(vec1,radius,cent1,reg1);
236
    VertexEffectDeform effect12= new VertexEffectDeform(vec2,radius,cent2,reg1);
237
    VertexEffectDeform effect13= new VertexEffectDeform(vec3,radius,cent3,reg1);
238

  
239
    effect0.setMeshAssociation( 7,-1);  // meshes 0,1,2
240
    effect1.setMeshAssociation( 6,-1);  // meshes 1,2
241
    effect2.setMeshAssociation( 2,-1);  // mesh 1
242
    effect3.setMeshAssociation( 4,-1);  // mesh 2
243
    effect4.setMeshAssociation(56,-1);  // meshes 3,4,5
244
    effect5.setMeshAssociation(56,-1);  // meshes 3,4,5
245
    effect6.setMeshAssociation(56,-1);  // meshes 3,4,5
246
    effect7.setMeshAssociation(56,-1);  // meshes 3,4,5
247
    effect8.setMeshAssociation(16,-1);  // mesh 4
248
    effect9.setMeshAssociation(32,-1);  // mesh 5
249

  
250
    effect10.setMeshAssociation(63,-1); // all meshes
251
    effect11.setMeshAssociation(63,-1); // all meshes
252
    effect12.setMeshAssociation(63,-1); // all meshes
253
    effect13.setMeshAssociation(63,-1); // all meshes
254

  
255
    mCornerMesh.apply(effect0);
256
    mCornerMesh.apply(effect1);
257
    mCornerMesh.apply(effect2);
258
    mCornerMesh.apply(effect3);
259
    mCornerMesh.apply(effect4);
260
    mCornerMesh.apply(effect5);
261
    mCornerMesh.apply(effect6);
262
    mCornerMesh.apply(effect7);
263
    mCornerMesh.apply(effect8);
264
    mCornerMesh.apply(effect9);
265

  
266
    mCornerMesh.apply(effect10);
267
    mCornerMesh.apply(effect11);
268
    mCornerMesh.apply(effect12);
269
    mCornerMesh.apply(effect13);
270

  
271
    mCornerMesh.mergeEffComponents();
272
    }
273

  
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

  
276
  private void createFaceMesh()
277
    {
278
    int association = 1;
279

  
280
    float D = 0.03f;
281
    float E = SQ2/4;
282
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
283

  
284
    float[] bands0 = { 1.0f    ,0,
285
                       1.0f-D/2,D*0.45f,
286
                       1.0f-D  ,D*0.75f,
287
                       1.0f-2*D,D,
288
                       0.60f, 0.052f,
289
                       0.30f, 0.060f,
290
                       0.0f, 0.065f };
291

  
292
    MeshBase[] meshes = new MeshBase[FACES_PER_CUBIT];
293
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
294
    meshes[0].setEffectAssociation(0,association,0);
295

  
296
    association <<= 1;
297

  
298
    float[] vertices1 = { -E,-SQ3*E, +E,-SQ3*E, 0,0 };
299
    float[] bands1 = { 1.0f, 0.0f, 0.0f, 0.0f };
300

  
301
    meshes[1] = new MeshPolygon(vertices1,bands1,0,0);
302
    meshes[1].setEffectAssociation(0,association,0);
303

  
304
    for(int i=2; i<FACES_PER_CUBIT-1; i++)
305
      {
306
      association <<= 1;
307
      meshes[i] = meshes[1].copy(true);
308
      meshes[i].setEffectAssociation(0,association,0);
309
      }
310

  
311
    association <<= 1;
312
    meshes[FACES_PER_CUBIT-1] = new MeshTriangle(1);                  // empty triangle so that
313
    meshes[FACES_PER_CUBIT-1].setEffectAssociation(0,association,0);  // all cubits have 6 faces
314

  
315
    mFaceMesh = new MeshJoined(meshes);
316

  
317
    Static3D center = new Static3D(0,0,0);
318
    Static3D axis1   = new Static3D(1,0,0);
319
    Static3D axis2   = new Static3D(0,0,1);
320
    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
321

  
322
    float f = 0.06f;
323
    float r = 0.10f;
324
    float d = 0.5f;
325
    float e = +D*0.6f;
326
    Static3D vector0 = new Static3D(-f, 0, 0);
327
    Static3D vector1 = new Static3D( 0,+f, 0);
328
    Static3D vector2 = new Static3D(+f, 0, 0);
329
    Static3D vector3 = new Static3D( 0,-f, 0);
330
    Static1D radius  = new Static1D(1.0f);
331
    Static4D region  = new Static4D(0,0,0,r);
332
    Static3D center0 = new Static3D(+d, 0, e);
333
    Static3D center1 = new Static3D( 0,-d, e);
334
    Static3D center2 = new Static3D(-d, 0, e);
335
    Static3D center3 = new Static3D( 0,+d, e);
336

  
337
    VertexEffectRotate effect0 = new VertexEffectRotate( new Static1D(angle), axis1, center);
338
    VertexEffectRotate effect1 = new VertexEffectRotate( new Static1D(  135), axis2, center);
339
    VertexEffectRotate effect2 = new VertexEffectRotate( new Static1D(   45), axis2, center);
340
    VertexEffectRotate effect3 = new VertexEffectRotate( new Static1D(  -45), axis2, center);
341
    VertexEffectRotate effect4 = new VertexEffectRotate( new Static1D( -135), axis2, center);
342
    VertexEffectMove   effect5 = new VertexEffectMove( new Static3D(0,0,-0.5f) );
343
    VertexEffectDeform effect6 = new VertexEffectDeform(vector0,radius,center0,region);
344
    VertexEffectDeform effect7 = new VertexEffectDeform(vector1,radius,center1,region);
345
    VertexEffectDeform effect8 = new VertexEffectDeform(vector2,radius,center2,region);
346
    VertexEffectDeform effect9 = new VertexEffectDeform(vector3,radius,center3,region);
347
    VertexEffectScale  effect10= new VertexEffectScale(0.01f);
348

  
349
    effect0.setMeshAssociation(30,-1);  // meshes 1,2,3,4
350
    effect1.setMeshAssociation( 2,-1);  // mesh 1
351
    effect2.setMeshAssociation( 5,-1);  // meshes 0,2
352
    effect3.setMeshAssociation( 8,-1);  // mesh 3
353
    effect4.setMeshAssociation(16,-1);  // mesh 4
354
    effect5.setMeshAssociation(30,-1);  // meshes 1,2,3,4
355
    effect6.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
356
    effect7.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
357
    effect8.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
358
    effect9.setMeshAssociation(31,-1);  // meshes 0,1,2,3,4
359
    effect10.setMeshAssociation(32,-1); // mesh 5
360

  
361
    mFaceMesh.apply(effect0);
362
    mFaceMesh.apply(effect1);
363
    mFaceMesh.apply(effect2);
364
    mFaceMesh.apply(effect3);
365
    mFaceMesh.apply(effect4);
366
    mFaceMesh.apply(effect5);
367
    mFaceMesh.apply(effect6);
368
    mFaceMesh.apply(effect7);
369
    mFaceMesh.apply(effect8);
370
    mFaceMesh.apply(effect9);
371
    mFaceMesh.apply(effect10);
372

  
373
    mFaceMesh.mergeEffComponents();
374
    }
375

  
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

  
378
  float getScreenRatio()
379
    {
380
    return 1.0f;
381
    }
382

  
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

  
385
  Static4D[] getQuats()
386
    {
387
    return QUATS;
388
    }
389

  
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

  
392
  int getNumFaces()
393
    {
394
    return FACE_COLORS.length;
395
    }
396

  
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

  
399
  int getNumCubitFaces()
400
    {
401
    return FACES_PER_CUBIT;
402
    }
403

  
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

  
406
  Static3D[] getCubitPositions(int size)
407
    {
408
    return CENTERS;
409
    }
410

  
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

  
413
  private Static4D getQuat(int cubit)
414
    {
415
    switch(cubit)
416
      {
417
      case  0: return QUATS[0];                          //  unit quat
418
      case  1: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
419
      case  2: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
420
      case  3: return QUATS[1];                          // 180 along X
421
      case  4: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
422
      case  5: return QUATS[2];                          // 180 along Y
423
      case  6: return QUATS[3];                          // 180 along Z
424
      case  7: return new Static4D(SQ2/2,0,-SQ2/2,0);    // 180 along (SQ2/2,0,-SQ2/2)
425
      case  8: return new Static4D(0,-SQ2/2,0,SQ2/2);    // -90 along Y
426
      case  9: return new Static4D(0, SQ2/2,0,SQ2/2);    //  90 along Y
427
      case 10: return new Static4D( SQ2/2,0,0,SQ2/2);    //  90 along X
428
      case 11: return new Static4D(-SQ2/2,0,0,SQ2/2);    // -90 along X
429
      case 12: return QUATS[0];                          //  unit quaternion
430
      case 13: return QUATS[1];                          // 180 along X
431
      }
432

  
433
    return null;
434
    }
435

  
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

  
438
  MeshBase createCubitMesh(int cubit)
439
    {
440
    MeshBase mesh;
441

  
442
    if( cubit<8 )
443
      {
444
      if( mCornerMesh==null ) createCornerMesh();
445
      mesh = mCornerMesh.copy(true);
446
      }
447
    else
448
      {
449
      if( mFaceMesh==null ) createFaceMesh();
450
      mesh = mFaceMesh.copy(true);
451
      }
452

  
453
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
454
    mesh.apply(quat,0xffffffff,0);
455

  
456
    return mesh;
457
    }
458

  
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

  
461
  int getFaceColor(int cubit, int cubitface, int size)
462
    {
463
    return mFaceMap[cubit][cubitface];
464
    }
465

  
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467
// TODO
468

  
469
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top, int side)
470
    {
471
    paint.setColor(FACE_COLORS[face]);
472
    paint.setStyle(Paint.Style.FILL);
473
    canvas.drawRect(left,top,left+side,top+side,paint);
474
    }
475

  
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

  
478
  float returnMultiplier()
479
    {
480
    return 2.0f;
481
    }
482

  
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

  
485
  float[] getRowChances()
486
    {
487
    float[] chances = new float[2];
488

  
489
    chances[0] = 0.5f;
490
    chances[1] = 1.0f;
491

  
492
    return chances;
493
    }
494

  
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496
// PUBLIC API
497

  
498
  public Static3D[] getRotationAxis()
499
    {
500
    return ROT_AXIS;
501
    }
502

  
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504

  
505
  public int getBasicAngle()
506
    {
507
    return 3;
508
    }
509

  
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

  
512
  public int computeRowFromOffset(float offset)
513
    {
514
    return offset<0.5f ? 0:1;
515
    }
516

  
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518

  
519
  public float returnRotationFactor(float offset)
520
    {
521
    return 1.0f;
522
    }
523

  
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525

  
526
  public int randomizeNewRotAxis(Random rnd, int oldRotAxis)
527
    {
528
    int numAxis = ROTATION_AXIS.length;
529

  
530
    if( oldRotAxis == START_AXIS )
531
      {
532
      return rnd.nextInt(numAxis);
533
      }
534
    else
535
      {
536
      int newVector = rnd.nextInt(numAxis-1);
537
      return (newVector>=oldRotAxis ? newVector+1 : newVector);
538
      }
539
    }
540

  
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

  
543
  public int randomizeNewRow(Random rnd, int oldRotAxis, int oldRow, int newRotAxis)
544
    {
545
    float rowFloat = rnd.nextFloat();
546

  
547
    for(int row=0; row<mRowChances.length; row++)
548
      {
549
      if( rowFloat<=mRowChances[row] ) return row;
550
      }
551

  
552
    return 0;
553
    }
554

  
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556
// remember about the double cover or unit quaternions!
557

  
558
  private int mulQuat(int q1, int q2)
559
    {
560
    Static4D result = RubikSurfaceView.quatMultiply(QUATS[q1],QUATS[q2]);
561

  
562
    float rX = result.get0();
563
    float rY = result.get1();
564
    float rZ = result.get2();
565
    float rW = result.get3();
566

  
567
    final float MAX_ERROR = 0.1f;
568
    float dX,dY,dZ,dW;
569

  
570
    for(int i=0; i<QUATS.length; i++)
571
      {
572
      dX = QUATS[i].get0() - rX;
573
      dY = QUATS[i].get1() - rY;
574
      dZ = QUATS[i].get2() - rZ;
575
      dW = QUATS[i].get3() - rW;
576

  
577
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
578
          dY<MAX_ERROR && dY>-MAX_ERROR &&
579
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
580
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
581

  
582
      dX = QUATS[i].get0() + rX;
583
      dY = QUATS[i].get1() + rY;
584
      dZ = QUATS[i].get2() + rZ;
585
      dW = QUATS[i].get3() + rW;
586

  
587
      if( dX<MAX_ERROR && dX>-MAX_ERROR &&
588
          dY<MAX_ERROR && dY>-MAX_ERROR &&
589
          dZ<MAX_ERROR && dZ>-MAX_ERROR &&
590
          dW<MAX_ERROR && dW>-MAX_ERROR  ) return i;
591
      }
592

  
593
    return -1;
594
    }
595

  
596
///////////////////////////////////////////////////////////////////////////////////////////////////
597
// The Skewb is solved if and only if:
598
//
599
// 1) all of its corner cubits are rotated with the same quat
600
// 2) all its face cubits are rotated with the same quat like the corner ones,
601
//    and optionally they also might be upside down.
602
//
603
// i.e.
604
// cubits [ 8] and [ 9] - might be extra QUAT[1]
605
// cubits [10] and [11] - might be extra QUAT[2]
606
// cubits [12] and [13] - might be extra QUAT[3]
607

  
608
  public boolean isSolved()
609
    {
610
    int q = CUBITS[0].mQuatIndex;
611

  
612
    if ( CUBITS[1].mQuatIndex == q &&
613
         CUBITS[2].mQuatIndex == q &&
614
         CUBITS[3].mQuatIndex == q &&
615
         CUBITS[4].mQuatIndex == q &&
616
         CUBITS[5].mQuatIndex == q &&
617
         CUBITS[6].mQuatIndex == q &&
618
         CUBITS[7].mQuatIndex == q  )
619
      {
620
      int q1 = mulQuat(q,1);
621
      int q2 = mulQuat(q,2);
622
      int q3 = mulQuat(q,3);
623

  
624
      return (CUBITS[ 8].mQuatIndex == q || CUBITS[ 8].mQuatIndex == q1) &&
625
             (CUBITS[ 9].mQuatIndex == q || CUBITS[ 9].mQuatIndex == q1) &&
626
             (CUBITS[10].mQuatIndex == q || CUBITS[10].mQuatIndex == q2) &&
627
             (CUBITS[11].mQuatIndex == q || CUBITS[11].mQuatIndex == q2) &&
628
             (CUBITS[12].mQuatIndex == q || CUBITS[12].mQuatIndex == q3) &&
629
             (CUBITS[13].mQuatIndex == q || CUBITS[13].mQuatIndex == q3)  ;
630
      }
631

  
632
    return false;
633
    }
634

  
635
///////////////////////////////////////////////////////////////////////////////////////////////////
636
// TODO  (only needed for solvers - there are no Skewb solvers ATM)
637

  
638
  public String retObjectString()
639
    {
640
    return "";
641
    }
642

  
643
}

Also available in: Unified diff