Project

General

Profile

« Previous | Next » 

Revision bc649d9a

Added by Leszek Koltunski about 3 years ago

Beginnings of a new object: Skewb Ultimate.

View differences:

src/main/java/org/distorted/objects/MovementUltimate.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 org.distorted.library.type.Static3D;
23

  
24
import static org.distorted.objects.TwistyMinx.C2;
25
import static org.distorted.objects.TwistyMinx.COS54;
26
import static org.distorted.objects.TwistyMinx.LEN;
27
import static org.distorted.objects.TwistyMinx.SIN54;
28
import static org.distorted.objects.TwistyObject.SQ5;
29

  
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

  
32
class MovementUltimate extends Movement
33
{
34
  static final float DIST3D = (float)Math.sqrt(0.625f+0.275f*SQ5)/3;
35
  static final float DIST2D = (0.5f*SIN54/COS54)/3;
36

  
37
  static final Static3D[] FACE_AXIS = new Static3D[]
38
         {
39
           new Static3D(    C2/LEN, SIN54/LEN,    0      ),
40
           new Static3D(    C2/LEN,-SIN54/LEN,    0      ),
41
           new Static3D(   -C2/LEN, SIN54/LEN,    0      ),
42
           new Static3D(   -C2/LEN,-SIN54/LEN,    0      ),
43
           new Static3D( 0        ,    C2/LEN, SIN54/LEN ),
44
           new Static3D( 0        ,    C2/LEN,-SIN54/LEN ),
45
           new Static3D( 0        ,   -C2/LEN, SIN54/LEN ),
46
           new Static3D( 0        ,   -C2/LEN,-SIN54/LEN ),
47
           new Static3D( SIN54/LEN,    0     ,    C2/LEN ),
48
           new Static3D( SIN54/LEN,    0     ,   -C2/LEN ),
49
           new Static3D(-SIN54/LEN,    0     ,    C2/LEN ),
50
           new Static3D(-SIN54/LEN,    0     ,   -C2/LEN )
51
         };
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  MovementUltimate()
56
    {
57
    super(TwistyUltimate.ROT_AXIS, FACE_AXIS, DIST3D, DIST2D);
58
    }
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
  int computeRowFromOffset(int face, int size, float offset)
63
    {
64
    if( size==3 )
65
      {
66
      return offset<DIST2D ? 0:2;
67
      }
68
    if( size==5 )
69
      {
70
      float quot = offset / DIST2D;
71

  
72
      if( quot>0.00f && quot<=0.34f ) return 0;
73
      if( quot>0.34f && quot<=1.00f ) return 1;
74
      if( quot>1.00f && quot<=1.66f ) return 3;
75
      if( quot>1.66f && quot<=2.00f ) return 4;
76
      }
77

  
78
    return 0;
79
    }
80

  
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

  
83
  public float returnRotationFactor(int size, int row)
84
    {
85
    return 1.0f;
86
    }
87

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
// return angle (in radians) that the line connecting the center C of the pentagonal face and the
90
// first vertex of the pentagon makes with a vertical line coming upwards from the center C.
91

  
92
  private float returnAngle(int face)
93
    {
94
    switch(face)
95
      {
96
      case  0:
97
      case  2:
98
      case  6:
99
      case  7: return 0.0f;
100
      case  1:
101
      case  3:
102
      case  4:
103
      case  5: return (float)(36*Math.PI/180);
104
      case  9:
105
      case 10: return (float)(54*Math.PI/180);
106
      case  8:
107
      case 11: return (float)(18*Math.PI/180);
108
      }
109

  
110
    return 0.0f;
111
    }
112

  
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114
// The pair (distance,angle) defines a point P in R^2 in polar coordinate system. Let V be the vector
115
// from the center of the coordinate system to P.
116
// Let P' be the point defined by polar (distance,angle+PI/2). Let Lh be the half-line starting at
117
// P' and going in the direction of V.
118
// Return true iff point 'point' lies on the left of Lh, i.e. when we rotate (using the center of
119
// the coordinate system as the center of rotation) 'point' and Lh in such a way that Lh points
120
// directly upwards, is 'point' on the left or the right of it?
121

  
122
  private boolean isOnTheLeft(float[] point, float distance, float angle)
123
    {
124
    float sin = (float)Math.sin(angle);
125
    float cos = (float)Math.cos(angle);
126

  
127
    float vx = point[0] + sin*distance;
128
    float vy = point[1] - cos*distance;
129

  
130
    return vx*sin < vy*cos;
131
    }
132

  
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134
// Return 1,2,3,4,5 - the vertex of the pentagon to which point 'point' is the closest, if the
135
// 'point' is inside the pentagon - or 0 otherwise.
136
// The 'first' vertex is the one we meet the first when we rotate clockwise starting from 12:00.
137
// This vertex makes angle 'returnAngle()' with the line coming out upwards from the center of the
138
// pentagon.
139
// Distance from the center to a vertex of the pentagon = 1/(6*COS54)
140

  
141
  private int returnPartOfThePentagon(float[] point, int face)
142
    {
143
    float angle = returnAngle(face);
144
    float A = (float)(Math.PI/5);
145

  
146
    for(int i=0; i<5; i++)
147
      {
148
      if( isOnTheLeft(point, DIST2D, (9-2*i)*A-angle) ) return 0;
149
      }
150

  
151
    if( isOnTheLeft(point, 0, 2.5f*A-angle) )
152
      {
153
      if( isOnTheLeft(point, 0, 3.5f*A-angle) )
154
        {
155
        return isOnTheLeft(point, 0, 5.5f*A-angle) ? 4 : 5;
156
        }
157
      else return 1;
158
      }
159
    else
160
      {
161
      if( isOnTheLeft(point, 0, 4.5f*A-angle) )
162
        {
163
        return 3;
164
        }
165
      else
166
        {
167
        return isOnTheLeft(point, 0, 6.5f*A-angle) ? 2 : 1;
168
        }
169
      }
170
    }
171

  
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

  
174
  boolean isInsideFace(int face, float[] p)
175
    {
176
    return returnPartOfThePentagon(p,face) > 0;
177
    }
178

  
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

  
181
  void computeEnabledAxis(int face, float[] touchPoint, int[] enabled)
182
    {
183
    int part = returnPartOfThePentagon(touchPoint,face);
184

  
185
    if( part>0 )
186
      {
187
      enabled[0] = 2;
188

  
189
      switch(face)
190
        {
191
        case  0:  switch(part)
192
                    {
193
                    case 1: enabled[1]=2; enabled[2]=3; break;
194
                    case 2: enabled[1]=3; enabled[2]=5; break;
195
                    case 3: enabled[1]=5; enabled[2]=1; break;
196
                    case 4: enabled[1]=1; enabled[2]=4; break;
197
                    case 5: enabled[1]=4; enabled[2]=2; break;
198
                    }
199
                  break;
200

  
201
        case  1:  switch(part)
202
                    {
203
                    case 1: enabled[1]=0; enabled[2]=5; break;
204
                    case 2: enabled[1]=5; enabled[2]=2; break;
205
                    case 3: enabled[1]=2; enabled[2]=3; break;
206
                    case 4: enabled[1]=3; enabled[2]=4; break;
207
                    case 5: enabled[1]=4; enabled[2]=0; break;
208
                    }
209
                  break;
210

  
211
        case  2:  switch(part)
212
                    {
213
                    case 1: enabled[1]=3; enabled[2]=2; break;
214
                    case 2: enabled[1]=2; enabled[2]=5; break;
215
                    case 3: enabled[1]=5; enabled[2]=0; break;
216
                    case 4: enabled[1]=0; enabled[2]=4; break;
217
                    case 5: enabled[1]=4; enabled[2]=3; break;
218
                    }
219
                  break;
220

  
221
        case  3:  switch(part)
222
                    {
223
                    case 1: enabled[1]=1; enabled[2]=5; break;
224
                    case 2: enabled[1]=5; enabled[2]=3; break;
225
                    case 3: enabled[1]=3; enabled[2]=2; break;
226
                    case 4: enabled[1]=2; enabled[2]=4; break;
227
                    case 5: enabled[1]=4; enabled[2]=1; break;
228
                    }
229
                  break;
230

  
231
        case  4:  switch(part)
232
                    {
233
                    case 1: enabled[1]=3; enabled[2]=0; break;
234
                    case 2: enabled[1]=0; enabled[2]=4; break;
235
                    case 3: enabled[1]=4; enabled[2]=5; break;
236
                    case 4: enabled[1]=5; enabled[2]=1; break;
237
                    case 5: enabled[1]=1; enabled[2]=3; break;
238
                    }
239
                  break;
240

  
241
        case  5:  switch(part)
242
                    {
243
                    case 1: enabled[1]=2; enabled[2]=1; break;
244
                    case 2: enabled[1]=1; enabled[2]=4; break;
245
                    case 3: enabled[1]=4; enabled[2]=5; break;
246
                    case 4: enabled[1]=5; enabled[2]=0; break;
247
                    case 5: enabled[1]=0; enabled[2]=2; break;
248
                    }
249
                  break;
250

  
251
        case  6:  switch(part)
252
                    {
253
                    case 1: enabled[1]=5; enabled[2]=4; break;
254
                    case 2: enabled[1]=4; enabled[2]=1; break;
255
                    case 3: enabled[1]=1; enabled[2]=2; break;
256
                    case 4: enabled[1]=2; enabled[2]=0; break;
257
                    case 5: enabled[1]=0; enabled[2]=5; break;
258
                    }
259
                  break;
260

  
261
        case  7:  switch(part)
262
                    {
263
                    case 1: enabled[1]=5; enabled[2]=4; break;
264
                    case 2: enabled[1]=4; enabled[2]=0; break;
265
                    case 3: enabled[1]=0; enabled[2]=3; break;
266
                    case 4: enabled[1]=3; enabled[2]=1; break;
267
                    case 5: enabled[1]=1; enabled[2]=5; break;
268
                    }
269
                  break;
270

  
271
        case  8: switch(part)
272
                    {
273
                    case 1: enabled[1]=2; enabled[2]=0; break;
274
                    case 2: enabled[1]=0; enabled[2]=1; break;
275
                    case 3: enabled[1]=1; enabled[2]=3; break;
276
                    case 4: enabled[1]=3; enabled[2]=5; break;
277
                    case 5: enabled[1]=5; enabled[2]=2; break;
278
                    }
279
                  break;
280

  
281
        case  9:  switch(part)
282
                    {
283
                    case 1: enabled[1]=3; enabled[2]=4; break;
284
                    case 2: enabled[1]=4; enabled[2]=2; break;
285
                    case 3: enabled[1]=2; enabled[2]=1; break;
286
                    case 4: enabled[1]=1; enabled[2]=0; break;
287
                    case 5: enabled[1]=0; enabled[2]=3; break;
288
                    }
289
                  break;
290

  
291
        case 10:  switch(part)
292
                    {
293
                    case 1: enabled[1]=2; enabled[2]=4; break;
294
                    case 2: enabled[1]=4; enabled[2]=3; break;
295
                    case 3: enabled[1]=3; enabled[2]=0; break;
296
                    case 4: enabled[1]=0; enabled[2]=1; break;
297
                    case 5: enabled[1]=1; enabled[2]=2; break;
298
                    }
299
                  break;
300

  
301
        case 11:  switch(part)
302
                    {
303
                    case 1: enabled[1]=3; enabled[2]=1; break;
304
                    case 2: enabled[1]=1; enabled[2]=0; break;
305
                    case 3: enabled[1]=0; enabled[2]=2; break;
306
                    case 4: enabled[1]=2; enabled[2]=5; break;
307
                    case 5: enabled[1]=5; enabled[2]=3; break;
308
                    }
309
                  break;
310
        }
311
      }
312
    else
313
      {
314
      enabled[0] = 0;
315
      }
316
    }
317
}
src/main/java/org/distorted/objects/ObjectList.java
59 59
         30
60 60
       ),
61 61

  
62
  DIAM (
62
  ULTI (
63 63
         new int[][] {
64
                       {2 , 10, R.raw.diam2, R.drawable.ui_small_diam, R.drawable.ui_medium_diam, R.drawable.ui_big_diam, R.drawable.ui_huge_diam} ,
64
                       {2 , 18, R.raw.diam2, R.drawable.ui_small_diam, R.drawable.ui_medium_diam, R.drawable.ui_big_diam, R.drawable.ui_huge_diam} ,
65 65
                     },
66
         TwistyDiamond.class,
67
         new MovementDiamond(),
66
         TwistyUltimate.class,
67
         new MovementUltimate(),
68 68
         1,
69
         60
69
         30
70 70
       ),
71 71

  
72 72
  DINO (
......
201 201
         5,
202 202
         60
203 203
       ),
204

  
205
  DIAM (
206
         new int[][] {
207
                       {2 , 10, R.raw.diam2, R.drawable.ui_small_diam, R.drawable.ui_medium_diam, R.drawable.ui_big_diam, R.drawable.ui_huge_diam} ,
208
                       {3 , 18, R.raw.diam2, R.drawable.ui_small_diam, R.drawable.ui_medium_diam, R.drawable.ui_big_diam, R.drawable.ui_huge_diam} ,
209
                     },
210
         TwistyDiamond.class,
211
         new MovementDiamond(),
212
         6,
213
         60
214
       ),
204 215
  ;
205 216

  
206 217
  public static final int NUM_OBJECTS = values().length;
......
584 595
      {
585 596
      case  0: return new TwistyCube          (size, quat, texture, mesh, effects, moves, res, scrWidth);
586 597
      case  1: return new TwistyPyraminx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
587
      case  2: return new TwistyDiamond       (size, quat, texture, mesh, effects, moves, res, scrWidth);
598
      case  2: return new TwistyUltimate      (size, quat, texture, mesh, effects, moves, res, scrWidth);
588 599
      case  3: return new TwistyDino6         (size, quat, texture, mesh, effects, moves, res, scrWidth);
589 600
      case  4: return new TwistyDino4         (size, quat, texture, mesh, effects, moves, res, scrWidth);
590 601
      case  5: return new TwistyRedi          (size, quat, texture, mesh, effects, moves, res, scrWidth);
......
595 606
      case 10: return new TwistyKilominx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
596 607
      case 11: return new TwistyMegaminx      (size, quat, texture, mesh, effects, moves, res, scrWidth);
597 608
      case 12: return new TwistyBandagedFused (size, quat, texture, mesh, effects, moves, res, scrWidth);
598
      case 13: return new TwistyBandaged2Bar(size, quat, texture, mesh, effects, moves, res, scrWidth);
609
      case 13: return new TwistyBandaged2Bar  (size, quat, texture, mesh, effects, moves, res, scrWidth);
599 610
      case 14: return new TwistyBandaged3Plate(size, quat, texture, mesh, effects, moves, res, scrWidth);
600 611
      case 15: return new TwistyBandagedEvil  (size, quat, texture, mesh, effects, moves, res, scrWidth);
612
      case 16: return new TwistyDiamond       (size, quat, texture, mesh, effects, moves, res, scrWidth);
601 613
      }
602 614

  
603 615
    return null;
src/main/java/org/distorted/objects/TwistyMinx.java
61 61
           new Static3D( SIN54/LEN,    0     ,   -C2/LEN )
62 62
         };
63 63

  
64
  private static final int MINX_LGREEN = 0xff53aa00;
65
  private static final int MINX_PINK   = 0xfffd7ab7;
66
  private static final int MINX_SANDY  = 0xffefd48b;
67
  private static final int MINX_LBLUE  = 0xff00a2d7;
68
  private static final int MINX_ORANGE = 0xffff6200;
69
  private static final int MINX_VIOLET = 0xff7d59a4;
70
  private static final int MINX_DGREEN = 0xff007a47;
71
  private static final int MINX_DRED   = 0xffbd0000;
72
  private static final int MINX_DBLUE  = 0xff1a29b2;
73
  private static final int MINX_DYELLOW= 0xffffc400;
74
  private static final int MINX_WHITE  = 0xffffffff;
75
  private static final int MINX_GREY   = 0xff727c7b;
64
  static final int MINX_LGREEN = 0xff53aa00;
65
  static final int MINX_PINK   = 0xfffd7ab7;
66
  static final int MINX_SANDY  = 0xffefd48b;
67
  static final int MINX_LBLUE  = 0xff00a2d7;
68
  static final int MINX_ORANGE = 0xffff6200;
69
  static final int MINX_VIOLET = 0xff7d59a4;
70
  static final int MINX_DGREEN = 0xff007a47;
71
  static final int MINX_DRED   = 0xffbd0000;
72
  static final int MINX_DBLUE  = 0xff1a29b2;
73
  static final int MINX_DYELLOW= 0xffffc400;
74
  static final int MINX_WHITE  = 0xffffffff;
75
  static final int MINX_GREY   = 0xff727c7b;
76 76

  
77 77
  static final int[] FACE_COLORS = new int[]
78 78
         {
src/main/java/org/distorted/objects/TwistyUltimate.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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.helpers.FactoryCubit;
27
import org.distorted.helpers.FactorySticker;
28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedTexture;
31
import org.distorted.library.mesh.MeshBase;
32
import org.distorted.library.mesh.MeshSquare;
33
import org.distorted.library.type.Static3D;
34
import org.distorted.library.type.Static4D;
35
import org.distorted.main.R;
36

  
37
import java.util.Random;
38

  
39
import static org.distorted.objects.TwistyMinx.MINX_DBLUE;
40
import static org.distorted.objects.TwistyMinx.MINX_DGREEN;
41
import static org.distorted.objects.TwistyMinx.MINX_DRED;
42
import static org.distorted.objects.TwistyMinx.MINX_DYELLOW;
43
import static org.distorted.objects.TwistyMinx.MINX_GREY;
44
import static org.distorted.objects.TwistyMinx.MINX_LBLUE;
45
import static org.distorted.objects.TwistyMinx.MINX_LGREEN;
46
import static org.distorted.objects.TwistyMinx.MINX_ORANGE;
47
import static org.distorted.objects.TwistyMinx.MINX_PINK;
48
import static org.distorted.objects.TwistyMinx.MINX_SANDY;
49
import static org.distorted.objects.TwistyMinx.MINX_VIOLET;
50
import static org.distorted.objects.TwistyMinx.MINX_WHITE;
51

  
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53

  
54
class TwistyUltimate extends TwistyObject
55
{
56
  private static final float A = (float)Math.sqrt(21*SQ5+47);
57
  private static final float B = SQ6*(5*SQ5+11)/(6*A);
58
  private static final float C = SQ6*(  SQ5+ 2)/(3*A);
59
  private static final float D = SQ3/3;
60
  private static final float E = (SQ5+1)/4;
61
  private static final float F = (SQ5-1)/4;
62

  
63
  static final Static3D[] ROT_AXIS = new Static3D[]
64
         {
65
           new Static3D( B,0,C ),
66
           new Static3D( C,B,0 ),
67
           new Static3D(-D,D,D ),
68
           new Static3D( 0,C,-B)
69
         };
70

  
71
  private static final int[] FACE_COLORS = new int[]
72
         {
73
           MINX_LGREEN, MINX_PINK   , MINX_SANDY , MINX_LBLUE,
74
           MINX_ORANGE, MINX_VIOLET , MINX_DGREEN, MINX_DRED ,
75
           MINX_DBLUE , MINX_DYELLOW, MINX_WHITE , MINX_GREY
76
         };
77

  
78
  private static final Static4D[] QUATS = new Static4D[]
79
         {
80
           new Static4D( 0.0f, 0.0f, 0.0f, 1.0f ),
81
           new Static4D(-0.5f, 0.5f, 0.5f, 0.5f ),
82
           new Static4D( 0.5f,-0.5f,-0.5f, 0.5f ),
83
           new Static4D( 0.0f,    F,   -E, 0.5f ),
84
           new Static4D( 0.0f,   -F,    E, 0.5f ),
85
           new Static4D(    E, 0.0f,    F, 0.5f ),
86
           new Static4D(   -E, 0.0f,   -F, 0.5f ),
87
           new Static4D(    F,    E, 0.0f, 0.5f ),
88
           new Static4D(   -F,   -E, 0.0f, 0.5f ),
89
           new Static4D(    E,    F,-0.5f, 0.0f ),
90
           new Static4D( 0.5f,   -E,    F, 0.0f ),
91
           new Static4D(    F, 0.5f,    E, 0.0f )
92
         };
93

  
94
  private static final double[][] VERTICES_SMALL = new double[][]
95
         {
96
           { 0.0       ,  0.0      , 0.0       },
97
           { -0.5*E    , 0.5*E+0.25, -0.25     },
98
           {-0.25      , -E/2      , (-2*E-1)/4},
99
           { 0.5*E+0.25, 0.25      , -E/2      },
100
           { 0.0       , 0.5       , -E-0.5    },
101
           { 0.0       , 0.5       , 0.0       },
102
           { -0.5*E    ,-0.5*E+0.25, -0.25     },
103
           {  0.5*E    ,-0.5*E+0.25, -0.25     }
104
         };
105

  
106
  private static final int[][] VERT_INDEXES_SMALL = new int[][]
107
         {
108
           {6,0,5,1},   // counterclockwise!
109
           {0,7,3,5},
110
           {0,6,2,7},
111
           {4,3,5,1},
112
           {4,2,7,3},
113
           {4,1,6,2},
114
         };
115

  
116
  private static final double[][] VERTICES_BIG = new double[][]
117
         {
118
           {-E/2     ,-E/2+0.25,     0.25},
119
           { E/2     , E/2-0.25,    -0.25},
120
           {-E       ,     0.00,     0.00},
121
           {     0.25, E/2     ,-E/2-0.25},
122
           {-E/2     ,-E/2-0.25,     0.25},
123
           { E/2+0.25,    -0.25,-E/2     },
124
           {-E       ,    -0.50,     0.00},
125
           {     0.50,     0.00,-E       },
126
           {-E  +0.25, E/2     ,-E/2-0.25},
127
           {     0.25,-E/2-0.50,-E/2+0.25},
128
           {-E/2     ,-E/2-0.25,-E  -0.25}
129
         };
130

  
131
  private static final int[][] VERT_INDEXES_BIG = new int[][]
132
         {
133
           {0,1,3,8,2},   // counterclockwise!
134
           {0,4,9,5,1},
135
           { 0,2,6,4},
136
           { 1,5,7,3},
137
           {10,9,4,6},
138
           {10,9,5,7},
139
           {10,8,3,7},
140
           {10,8,2,6}
141
         };
142

  
143
  // TODO
144
  private static final float[][] STICKERS = new float[][]
145
         {
146
              { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f }
147
         };
148

  
149
  private static MeshBase[] mMeshes;
150

  
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

  
153
  TwistyUltimate(int size, Static4D quat, DistortedTexture texture,
154
                 MeshSquare mesh, DistortedEffects effects, int[][] moves, Resources res, int scrWidth)
155
    {
156
    super(size, size, quat, texture, mesh, effects, moves, ObjectList.ULTI, res, scrWidth);
157
    }
158

  
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

  
161
  MeshBase createCubitMesh(int cubit, int numLayers)
162
    {
163
    if( mMeshes==null )
164
      {
165
      FactoryCubit factory = FactoryCubit.getInstance();
166
      factory.clear();
167
      mMeshes = new MeshBase[2];
168
      }
169

  
170
    MeshBase mesh;
171

  
172
    if( cubit<8 )
173
      {
174
      if( mMeshes[0]==null )
175
        {
176
        float[][] bands= new float[][]
177
          {
178
             {0.04f,17,0.5f,0.2f,5,  2,2},
179
             {0.01f, 1,0.5f,0.2f,5,  2,2}
180
          };
181
        int[] bandIndexes   = new int[] { 0,0,0,1,1,1 };
182
        float[][] corners   = new float[][] {  { 0.013f, 0.08f } };
183
        int[] cornerIndexes = new int[] { 0, 0, 0, 0,-1, 0, 0, 0 };
184
        float[][] centers   = new float[][] { { 0.0f,-0.5f, -(SQ5+3)/4 } };
185
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0 };
186

  
187
        FactoryCubit factory = FactoryCubit.getInstance();
188
        factory.createNewFaceTransform(VERTICES_SMALL,VERT_INDEXES_SMALL);
189
        mMeshes[0] = factory.createRoundedSolid(VERTICES_SMALL, VERT_INDEXES_SMALL,
190
                                                bands, bandIndexes,
191
                                                corners, cornerIndexes,
192
                                                centers, centerIndexes,
193
                                                getNumCubitFaces() );
194
        }
195
      mesh = mMeshes[0].copy(true);
196
      }
197
    else
198
      {
199
      if( mMeshes[1]==null )
200
        {
201
        float[][] bands= new float[][]
202
          {
203
            {0.04f,17,0.5f,0.2f,5,  2,2},
204
            {0.04f,17,0.5f,0.2f,5,  2,2},
205
            {0.01f, 1,0.5f,0.2f,5,  2,2}
206
          };
207
        int[] bandIndexes   = new int[] { 0,0,1,1,2,2,2,2 };
208
        float[][] corners   = new float[][] { { 0.013f, 0.08f } };
209
        int[] cornerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,-1 };
210
        float[][] centers   = new float[][] { { -(SQ5+1)/8, 0.25f, -(SQ5+5)/8 } };
211
        int[] centerIndexes = new int[] { 0,0,0,0,0,0,0,0,0,0,0 };
212

  
213
        FactoryCubit factory = FactoryCubit.getInstance();
214
        factory.createNewFaceTransform(VERTICES_BIG,VERT_INDEXES_BIG);
215
        mMeshes[1] = factory.createRoundedSolid(VERTICES_BIG, VERT_INDEXES_BIG,
216
                                                bands, bandIndexes,
217
                                                corners, cornerIndexes,
218
                                                centers, centerIndexes,
219
                                                getNumCubitFaces() );
220
        }
221
      mesh = mMeshes[1].copy(true);
222
      }
223

  
224
    MatrixEffectQuaternion quat = new MatrixEffectQuaternion( getQuat(cubit), new Static3D(0,0,0) );
225
    mesh.apply(quat,0xffffffff,0);
226

  
227
    return mesh;
228
    }
229

  
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
// TODO
232

  
233
  private Static4D getQuat(int cubit)
234
    {
235
    switch(cubit)
236
      {
237
      case  0:
238
      case  1:
239
      case  2:
240
      case  3:
241
      case  4:
242
      case  5:
243
      case  6:
244
      case  7:
245

  
246
      case  8:
247
      case  9:
248
      case 10:
249
      case 11:
250
      case 12:
251
      case 13: return QUATS[0];
252
      }
253

  
254
    return null;
255
    }
256

  
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

  
259
  float[][] getCubitPositions(int numLayers)
260
    {
261
    float[][] tmp = new float[14][];
262

  
263
    // TODO
264

  
265
    return tmp;
266
    }
267

  
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
// TODO
270

  
271
  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
272
    {
273
    float R = 0.10f;
274
    float S = 0.08f;
275

  
276
    FactorySticker factory = FactorySticker.getInstance();
277
    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], S, FACE_COLORS[face], R);
278
    }
279

  
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281
// TODO
282

  
283
  int getFaceColor(int cubit, int cubitface, int size)
284
    {
285
    return CUBITS[cubit].mRotationRow[cubitface/2] == (cubitface%2==0 ? (1<<(size-1)):1) ? cubitface : NUM_FACES;
286
    }
287

  
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
// TODO
290

  
291
  float returnMultiplier()
292
    {
293
    return getNumLayers();
294
    }
295

  
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

  
298
  Static4D[] getQuats()
299
    {
300
    return QUATS;
301
    }
302

  
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

  
305
  boolean shouldResetTextureMaps()
306
    {
307
    return false;
308
    }
309

  
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

  
312
  int getNumFaces()
313
    {
314
    return FACE_COLORS.length;
315
    }
316

  
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

  
319
  float[] getCuts(int numLayers)
320
    {
321
    float[] cuts = new float[1];
322
    cuts[0] = 0.0f;
323

  
324
    return cuts;
325
    }
326

  
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

  
329
  int getNumStickerTypes(int numLayers)
330
    {
331
    return STICKERS.length;
332
    }
333

  
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

  
336
  int getNumCubitFaces()
337
    {
338
    return 8;
339
    }
340

  
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

  
343
  float getScreenRatio()
344
    {
345
    return 0.5f;
346
    }
347

  
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

  
350
  float[] getRowChances(int numLayers)
351
    {
352
    float[] chances = new float[2];
353
    chances[0] = 0.5f;
354
    chances[1] = 1.0f;
355

  
356
    return chances;
357
    }
358

  
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
// PUBLIC API
361

  
362
  public Static3D[] getRotationAxis()
363
    {
364
    return ROT_AXIS;
365
    }
366

  
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

  
369
  public int getBasicAngle()
370
    {
371
    return 3;
372
    }
373

  
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

  
376
  public void randomizeNewScramble(int[][] scramble, Random rnd, int num)
377
    {
378
    if( num==0 )
379
      {
380
      scramble[num][0] = rnd.nextInt(ROTATION_AXIS.length);
381
      }
382
    else
383
      {
384
      int newVector = rnd.nextInt(ROTATION_AXIS.length-1);
385
      scramble[num][0] = (newVector>=scramble[num-1][0] ? newVector+1 : newVector);
386
      }
387

  
388
    float rowFloat = rnd.nextFloat();
389

  
390
    for(int row=0; row<mRowChances.length; row++)
391
      {
392
      if( rowFloat<=mRowChances[row] )
393
        {
394
        scramble[num][1] = row;
395
        break;
396
        }
397
      }
398

  
399
    switch( rnd.nextInt(2) )
400
      {
401
      case 0: scramble[num][2] =  1; break;
402
      case 1: scramble[num][2] = -1; break;
403
      }
404
    }
405

  
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

  
408
  public boolean isSolved()
409
    {
410
    int index = CUBITS[0].mQuatIndex;
411

  
412
    for(int i=1; i<NUM_CUBITS; i++)
413
      {
414
      if( CUBITS[i].mQuatIndex != index ) return false;
415
      }
416

  
417
    return true;
418
    }
419

  
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421
// only needed for solvers - there are no Skewb Ultimate solvers ATM)
422

  
423
  public String retObjectString()
424
    {
425
    return "";
426
    }
427

  
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

  
430
  public int getObjectName(int numLayers)
431
    {
432
    return R.string.ulti2;
433
    }
434

  
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

  
437
  public int getInventor(int numLayers)
438
    {
439
    return R.string.ulti2_inventor;
440
    }
441

  
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

  
444
  public int getComplexity(int numLayers)
445
    {
446
    return 6;
447
    }
448
}
src/main/res/raw/compute_quats.c
2 2
#include <math.h>
3 3
#include <stdlib.h>
4 4

  
5
#define PYRA
5
#define ULTI
6 6

  
7 7
#define SQ2 1.41421356237f
8 8
#define SQ3 1.73205080757f
9
#define SQ5 2.23606797750f
9 10
#define PI  3.14159265358f
10
#define NUM_QUATS  100
11
#define NUM_QUATS  200
11 12

  
12 13
#ifdef PYRA 
13 14
#define NUM_AXIS    4
......
61 62

  
62 63
#endif
63 64

  
65
#ifdef ULTI
66
#define NUM_AXIS 4
67
#define BASIC_ANGLE 3
68

  
69
float axis[NUM_AXIS][3] = {   { 5*SQ5/16 + 11.0f/16,              0.0f   ,    SQ5/8  + 1.0f/4 } ,
70
                              {   SQ5/8  +  1.0f/4 ,  5*SQ5/16 + 11.0f/16,             0.0f   } ,
71
                              {-3*SQ5/16 -  7.0f/16,  3*SQ5/16 +  7.0f/16,  3*SQ5/16 + 7.0f/16} ,
72
                              {             0.0f   ,    SQ5/4  +  1.0f/2 , -5*SQ5/8  -11.0f/8 } };
73

  
74
#endif
75

  
76

  
64 77
int inserted=0;
65 78

  
66 79
///////////////////////////////////////////////////////////////////
......
127 140
    if( is_the_same(quat,to+4*i)==1 ) return;
128 141
    }
129 142

  
130
  to[4*inserted+0] = quat[0];
131
  to[4*inserted+1] = quat[1];
132
  to[4*inserted+2] = quat[2];
133
  to[4*inserted+3] = quat[3];
143
  if( inserted<NUM_QUATS )
144
    {
145
    to[4*inserted+0] = quat[0];
146
    to[4*inserted+1] = quat[1];
147
    to[4*inserted+2] = quat[2];
148
    to[4*inserted+3] = quat[3];
149

  
150
    inserted++;
151
    }
152
  else
153
    {
154
    printf("Error: inserted=%d\n", inserted);
155
    }
156
  }
157

  
158
///////////////////////////////////////////////////////////////////
159

  
160
void normalize(int index)
161
  {
162
  float* a = axis[index];
163

  
164
  float len = (float)(sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]));
134 165

  
135
  inserted++;
166
  a[0] /= len;  
167
  a[1] /= len;  
168
  a[2] /= len;  
136 169
  }
137 170

  
138 171
///////////////////////////////////////////////////////////////////
......
146 179
  tmp[0] = 0.0f; tmp[1] = 0.0f; tmp[2] = 0.0f; tmp[3] = 1.0f;
147 180
  insert(tmp,table);
148 181

  
182
  for(int ax=0; ax<NUM_AXIS; ax++)
183
    {
184
    normalize(ax);
185
    }
186

  
149 187
  for(int angle=1; angle<BASIC_ANGLE; angle++)
150 188
    for( int ax=0; ax<NUM_AXIS; ax++)
151 189
      {
src/main/res/values/strings.xml
94 94
    <string name="minx3" translatable="false">Megaminx</string>
95 95
    <string name="minx4" translatable="false">Master Kilominx</string>
96 96
    <string name="minx5" translatable="false">Gigaminx</string>
97
    <string name="ulti2" translatable="false">Skewb Ultimate</string>
97 98

  
98 99
    <string name="bandaged_fused"  translatable="false">Fused Cube</string>
99 100
    <string name="bandaged_2bar"   translatable="false">2Bar Cube</string>
......
121 122
    <string name="minx3_inventor" translatable="false">Ferenc Szlivka, 1982</string>
122 123
    <string name="minx4_inventor" translatable="false">David Gugl, 2010</string>
123 124
    <string name="minx5_inventor" translatable="false">Tyler Fox, 2006</string>
125
    <string name="ulti2_inventor" translatable="false">Tony Fisher, 2000</string>
124 126

  
125 127
    <string name="bandaged_fused_inventor"  translatable="false">who knows</string>
126 128
    <string name="bandaged_2bar_inventor"   translatable="false">who knows</string>

Also available in: Unified diff