Project

General

Profile

« Previous | Next » 

Revision ed6b7481

Added by Leszek Koltunski 7 months ago

First tries at Bump Jing and Bump Pyraminx ( both crash on startup now)

View differences:

src/main/java/org/distorted/objectlib/main/TwistyObject.java
574 574

  
575 575
  public int getVariantStickerShape(int variant, int face)
576 576
    {
577
    return face>=mStickerVariants[variant].length ? -1 : mStickerVariants[variant][face];
577
    int[] var = mStickerVariants[variant];
578
    return face>=var.length ? -1 : var[face];
578 579
    }
579 580

  
580 581
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objectlib/objects/TwistyMirrorJing.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.objectlib.objects;
11

  
12
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CHANGING_SHAPEMOD;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14

  
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17
import org.distorted.objectlib.helpers.FactoryCubit;
18
import org.distorted.objectlib.helpers.FactoryShape;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectShape;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.main.InitData;
24
import org.distorted.objectlib.main.ObjectType;
25
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
26
import org.distorted.objectlib.shape.ShapeTetrahedron;
27
import org.distorted.objectlib.signature.ObjectConstants;
28
import org.distorted.objectlib.signature.ObjectSignature;
29
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
public class TwistyMirrorJing extends ShapeTetrahedron
34
{
35
  public static final Static3D[] ROT_AXIS = new Static3D[]
36
         {
37
           new Static3D(     0,-SQ3/3,-SQ6/3),
38
           new Static3D(     0,-SQ3/3, SQ6/3),
39
           new Static3D( SQ6/3, SQ3/3,     0),
40
           new Static3D(-SQ6/3, SQ3/3,     0),
41
         };
42

  
43
  private static final float JING_F = 0.48f;
44

  
45
  private static final int[] FACE_COLORS = new int[] { COLOR_WHITE };
46
  private static final float[] MIRROR_VEC = { 0.0f, 0.0f, 0.0f };
47

  
48
  private int[][] mEdges;
49
  private int[][] mBasicAngle;
50
  private float[][] mCuts;
51
  private float[][] mPositions;
52
  private ObjectShape[] mShapes;
53
  private float[][] mCutPlanes;
54
  private float[] mDist3D, mDist;
55
  private float[][] mPotentialVertices;
56

  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

  
59
  public TwistyMirrorJing(int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
60
    {
61
    super(iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
62
    }
63

  
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

  
66
  @Override
67
  public int getInternalColor()
68
    {
69
    return 0xff333333;
70
    }
71

  
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

  
74
  @Override
75
  public int getColor(int face)
76
    {
77
    return FACE_COLORS[face];
78
    }
79

  
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

  
82
  @Override
83
  public int getNumFaceColors()
84
    {
85
    return 1;
86
    }
87

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

  
90
  @Override
91
  public float[][] returnRotationFactor()
92
    {
93
    int numL = getNumLayers()[0];
94
    float[] f = new float[numL];
95
    for(int i=0; i<numL; i++) f[i] = 1.3f;
96
    return new float[][] { f,f,f,f };
97
    }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
  public int[][] getScrambleEdges()
102
    {
103
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
104
    return mEdges;
105
    }
106

  
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

  
109
  public float[][] getCuts(int[] numLayers)
110
    {
111
    if( mCuts==null )
112
      {
113
      float[] c = new float[] { (JING_F-0.51f)*(SQ6/3) };
114
      mCuts = new float[][] {c,c,c,c};
115
      }
116

  
117
    return mCuts;
118
    }
119

  
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

  
122
  public boolean[][] getLayerRotatable(int[] numLayers)
123
    {
124
    boolean[] tmp = {true,true};
125
    return new boolean[][] { tmp,tmp,tmp,tmp };
126
    }
127

  
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

  
130
  public int getTouchControlType()
131
    {
132
    return TC_CHANGING_SHAPEMOD;
133
    }
134

  
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

  
137
  public int getTouchControlSplit()
138
    {
139
    return TYPE_NOT_SPLIT;
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  public int[][][] getEnabled()
145
    {
146
    return null;
147
    }
148

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150
// 'full' dists (not divided by numLayers)
151

  
152
  private float[] getDist()
153
    {
154
    if( mDist==null )
155
      {
156
      float DX = MIRROR_VEC[0];
157
      float DY = MIRROR_VEC[1];
158
      float DZ = MIRROR_VEC[2];
159
      Static3D[] axis = getFaceAxis();
160
      mDist = new float[4];
161

  
162
      for( int a=0; a<4; a++ )
163
        {
164
        Static3D ax = axis[a];
165
        float d = ax.get0()*DX + ax.get1()*DY + ax.get2()*DZ;
166
        mDist[a] = SQ6/6 + d;
167
        }
168
      }
169

  
170
    return mDist;
171
    }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
// 'regular' dists for the touchControl (have to be divided by numLayers)
175

  
176
  public float[] getDist3D(int[] numLayers)
177
    {
178
    if( mDist3D==null )
179
      {
180
      float[] d = getDist();
181
      mDist3D = new float[] { d[0]/2, d[1]/2, d[2]/2, d[3]/2 };
182
      }
183

  
184
    return mDist3D;
185
    }
186

  
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

  
189
  public Static3D[] getFaceAxis()
190
    {
191
    return TouchControlTetrahedron.FACE_AXIS;
192
    }
193

  
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

  
196
  private float[][] getPositions()
197
    {
198
    if( mPositions==null )
199
      {
200
      final float X = MIRROR_VEC[0];
201
      final float Y = MIRROR_VEC[1];
202
      final float Z = MIRROR_VEC[2];
203

  
204
      mPositions = new float[][]
205
        {
206
          { 0.000f +X, -SQ2/2 +Y,  1.000f +Z },
207
          { 0.000f +X, -SQ2/2 +Y, -1.000f +Z },
208
          {-1.000f +X,  SQ2/2 +Y,  0.000f +Z },
209
          { 1.000f +X,  SQ2/2 +Y,  0.000f +Z },
210

  
211
          { 0.000f +X, -SQ2/2 +Y,  0.000f +Z },
212
          {-0.500f +X, 0.000f +Y,  0.500f +Z },
213
          { 0.500f +X, 0.000f +Y,  0.500f +Z },
214
          {-0.500f +X, 0.000f +Y, -0.500f +Z },
215
          { 0.500f +X, 0.000f +Y, -0.500f +Z },
216
          { 0.000f +X,  SQ2/2 +Y,  0.000f +Z },
217

  
218
          { 0.000f +X,  SQ2/6 +Y,  1.0f/3 +Z },
219
          { 0.000f +X,  SQ2/6 +Y, -1.0f/3 +Z },
220
          {-1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
221
          { 1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
222
        };
223
      }
224

  
225
    return mPositions;
226
    }
227

  
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

  
230
  public float[][] getCubitPositions(int[] numLayers)
231
    {
232
    return getPositions();
233
    }
234

  
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

  
237
  public Static4D getCubitQuats(int cubit, int[] numLayers)
238
    {
239
    return mObjectQuats[0];
240
    }
241

  
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

  
244
  private void createCutPlanes()
245
    {
246
    int numPlanes = 2*4;
247
    mCutPlanes = new float[numPlanes][];
248
    Static3D[] faceAxis = getFaceAxis();
249
    float[] dist = getDist();
250
    int[] numLayers = getNumLayers();
251
    float[][] cuts = getCuts(numLayers);
252
    float cut = cuts[0][0];
253

  
254
    for(int p=0; p<4; p++)
255
      {
256
      Static3D ax = faceAxis[p];
257
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), dist[p] };
258
      }
259

  
260
    for(int p=4; p<8; p++)
261
      {
262
      Static3D ax = ROT_AXIS[p-4];
263
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut };
264
      }
265
    }
266

  
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

  
269
  private float[] internalPoint(int variant)
270
    {
271
    float[][] pos = getPositions();
272
    float[] position = pos[variant];
273
    float[][] center = computeVertexEffectCenter(variant);
274
    float[] cent = center[0];
275

  
276
    float[] ret = new float[3];
277

  
278
    float A = 0.1f;
279

  
280
    ret[0] = position[0] + A*cent[0];
281
    ret[1] = position[1] + A*cent[1];
282
    ret[2] = position[2] + A*cent[2];
283

  
284
    return ret;
285
    }
286

  
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

  
289
  public ObjectShape getObjectShape(int variant)
290
    {
291
    if( mShapes==null )
292
      {
293
      int[] numLayers = getNumLayers();
294
      int numV = getNumCubitVariants(numLayers);
295
      mShapes = new ObjectShape[numV];
296
      createCutPlanes();
297
      mPotentialVertices = FactoryShape.computePotentialVertices(mCutPlanes);
298
      }
299

  
300
    if( mShapes[variant]==null )
301
      {
302
      float[][] pos = getPositions();
303
      float[] point = internalPoint(variant);
304
      mShapes[variant] = FactoryShape.createShape(mCutPlanes,mPotentialVertices,pos[variant],point);
305
      }
306

  
307
    return mShapes[variant];
308
    }
309

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

  
312
  public ObjectFaceShape getObjectFaceShape(int variant)
313
    {
314
    ObjectShape shape = getObjectShape(variant);
315
    int[][] ind    = shape.getVertIndices();
316
    float[][] vert = shape.getVertices();
317
    float[][] pos  = getPositions();
318
    int[] indices  = FactoryShape.produceBandIndices(vert, pos[variant], ind, getFaceAxis(), getDist() );
319

  
320
    if( variant<4 )
321
      {
322
      int N = 5;
323
      int E = 2;
324
      float height = isInIconMode() ? 0.001f : 0.02f;
325
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
326
      return new ObjectFaceShape(bands,indices,null);
327
      }
328
    else if( variant<10 )
329
      {
330
      int N = 5;
331
      int E = 1;
332
      float height = isInIconMode() ? 0.001f : 0.02f;
333
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
334
      return new ObjectFaceShape(bands,indices,null);
335
      }
336
    else
337
      {
338
      int N = 5;
339
      int E = 0;
340
      float height = isInIconMode() ? 0.001f : 0.02f;
341
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
342
      return new ObjectFaceShape(bands,indices,null);
343
      }
344
    }
345

  
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

  
348
  private float[][] computeVertexEffectCenter(int variant)
349
    {
350
    float A;
351

  
352
         if( variant< 4 ) A = 0.4f;
353
    else if( variant<10 ) A = 1.0f;
354
    else                  A = 0.9f;
355

  
356
    float[][] positions = getPositions();
357
    float[] p = positions[variant];
358

  
359
    return new float[][] {{ A*p[0], A*p[1], A*p[2] }};
360
    }
361

  
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

  
364
  public ObjectVertexEffects getVertexEffects(int variant)
365
    {
366
    ObjectShape shape  = getObjectShape(variant);
367
    float[][] vertices = shape.getVertices();
368
    float[][] centers  = computeVertexEffectCenter(variant);
369
    float[][] pos      = getPositions();
370
    int[] indices      = FactoryShape.computeVertexEffectsIndices(vertices, pos[variant], getFaceAxis(), getDist() );
371

  
372
    float S,R;
373
         if( variant< 4 ) { S = 0.03f; R=0.15f; }
374
    else if( variant<10 ) { S = 0.03f; R=0.15f; }
375
    else                  { S = 0.03f; R=0.15f; }
376

  
377
    float[][] corners  = new float[][]{{S,R}};
378

  
379
    return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
380
    }
381

  
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

  
384
  public int getNumCubitVariants(int[] numLayers)
385
    {
386
    return 14;
387
    }
388

  
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390

  
391
  public int getCubitVariant(int cubit, int[] numLayers)
392
    {
393
    return cubit;
394
    }
395

  
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

  
398
  public float getStickerRadius()
399
    {
400
    return 0.06f;
401
    }
402

  
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

  
405
  public float getStickerStroke()
406
    {
407
    return isInIconMode() ? 0.10f : 0.05f;
408
    }
409

  
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

  
412
  public float[][][] getStickerAngles()
413
    {
414
    return null;
415
    }
416

  
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
// PUBLIC API
419

  
420
  public Static3D[] getRotationAxis()
421
    {
422
    return ROT_AXIS;
423
    }
424

  
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

  
427
  public int[][] getBasicAngles()
428
    {
429
    if( mBasicAngle ==null )
430
      {
431
      int num = getNumLayers()[0];
432
      int[] tmp = new int[num];
433
      for(int i=0; i<num; i++) tmp[i] = 3;
434
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
435
      }
436

  
437
    return mBasicAngle;
438
    }
439

  
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

  
442
  public String getShortName()
443
    {
444
    return ObjectType.MJIN_2.name();
445
    }
446

  
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

  
449
  public ObjectSignature getSignature()
450
    {
451
    return new ObjectSignature(ObjectConstants.MJIN_2);
452
    }
453

  
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

  
456
  public String getObjectName()
457
    {
458
    return "Bump Jing's Pyraminx";
459
    }
460

  
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

  
463
  public String getInventor()
464
    {
465
    return "Floyd Newberry";
466
    }
467

  
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

  
470
  public int getYearOfInvention()
471
    {
472
    return 2015;
473
    }
474

  
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

  
477
  public int getComplexity()
478
    {
479
    return 1;
480
    }
481

  
482
///////////////////////////////////////////////////////////////////////////////////////////////////
483

  
484
  public String[][] getTutorials()
485
    {
486
    return null;
487
    }
488
}
src/main/java/org/distorted/objectlib/objects/TwistyMirrorPyraminx.java
15 15
import org.distorted.library.type.Static3D;
16 16
import org.distorted.library.type.Static4D;
17 17
import org.distorted.objectlib.helpers.FactoryCubit;
18
import org.distorted.objectlib.helpers.FactoryShape;
18 19
import org.distorted.objectlib.helpers.ObjectFaceShape;
19 20
import org.distorted.objectlib.helpers.ObjectShape;
20 21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
21 22
import org.distorted.objectlib.main.InitAssets;
22 23
import org.distorted.objectlib.main.InitData;
23 24
import org.distorted.objectlib.main.ObjectType;
24
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
25
import org.distorted.objectlib.shape.ShapeHexahedron;
25
import org.distorted.objectlib.shape.ShapeTetrahedron;
26 26
import org.distorted.objectlib.signature.ObjectConstants;
27 27
import org.distorted.objectlib.signature.ObjectSignature;
28
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
28
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
29 29

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

  
32
public class TwistyMirrorPyraminx extends ShapeHexahedron
32
public class TwistyMirrorPyraminx extends ShapeTetrahedron
33 33
{
34
  public static final Static3D[] ROT_AXIS =
35
         {
36
           new Static3D( SQ3/3, SQ3/3, SQ3/3),
37
           new Static3D( SQ3/3, SQ3/3,-SQ3/3),
38
           new Static3D( SQ3/3,-SQ3/3, SQ3/3),
39
           new Static3D( SQ3/3,-SQ3/3,-SQ3/3)
40
         };
34
  static final Static3D[] ROT_AXIS = new Static3D[]
35
    {
36
      new Static3D(     0,-SQ3/3,-SQ6/3),
37
      new Static3D(     0,-SQ3/3, SQ6/3),
38
      new Static3D( SQ6/3, SQ3/3,     0),
39
      new Static3D(-SQ6/3, SQ3/3,     0),
40
    };
41 41

  
42 42
  private static final int[] FACE_COLORS = new int[] { COLOR_WHITE };
43
  private static final float[] MIRROR_VEC = { 0.10f, 0.25f, 0.40f };
43
  private static final float[] MIRROR_VEC = { 0.0f, 0.0f, 0.0f };
44 44

  
45 45
  private int[][] mEdges;
46 46
  private int[][] mBasicAngle;
47 47
  private float[][] mCuts;
48 48
  private float[][] mPositions;
49
  private ObjectShape[] mShapes;
50
  private float[][] mCutPlanes;
51
  private float[] mDist3D, mDist;
52
  private float[][] mPotentialVertices;
49 53

  
50 54
///////////////////////////////////////////////////////////////////////////////////////////////////
51 55

  
52 56
  public TwistyMirrorPyraminx(int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
53 57
    {
54
    super(iconMode, 2*data.getNumLayers()[0]-2, quat, move, scale, data, asset);
58
    super(iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
55 59
    }
56 60

  
57 61
///////////////////////////////////////////////////////////////////////////////////////////////////
......
59 63
  @Override
60 64
  public int getInternalColor()
61 65
    {
62
    return 0xff222222;
66
    return 0xff333333;
63 67
    }
64 68

  
65 69
///////////////////////////////////////////////////////////////////////////////////////////////////
......
83 87
  @Override
84 88
  public float[][] returnRotationFactor()
85 89
    {
86
    int numL = getNumLayers()[0];
87
    float[] f = new float[numL];
88
    for(int i=0; i<numL; i++) f[i] = 1.7f;
89
    return new float[][] { f,f,f,f };
90
    int numL= getNumLayers()[0];
91
    float[][] factor = new float[4][numL];
92

  
93
    for(int ax=0; ax<4; ax++)
94
      for(int la=0; la<numL; la++) factor[ax][la] = ((float)numL)/(numL-la);
95

  
96
    return factor;
90 97
    }
91 98

  
92 99
///////////////////////////////////////////////////////////////////////////////////////////////////
93 100

  
94 101
  public int[][] getScrambleEdges()
95 102
    {
96
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
103
    if( mEdges==null )
104
      {
105
      int nL = getNumLayers()[0];
106
      mEdges = new int[nL][];
107

  
108
      for(int i=0; i<nL; i++)
109
        {
110
        int numEnabledMoves = 2*(nL-i);
111
        mEdges[i] = new int[4*2*numEnabledMoves];
112

  
113
        int index = 0;
114
        int startMove= 0;
115
        int offset = (i==nL-1 ? 2:0);  // if the last move was a tip, the only possible
116
                                       // next move is the second-to-largest layer.
117
        fillEdge(mEdges[i],index,startMove,offset,numEnabledMoves);
118
        index += (2*numEnabledMoves);
119
        startMove += (2*nL);
120
        fillEdge(mEdges[i],index,startMove,offset,numEnabledMoves);
121
        index += (2*numEnabledMoves);
122
        startMove += (2*nL);
123
        fillEdge(mEdges[i],index,startMove,offset,numEnabledMoves);
124
        index += (2*numEnabledMoves);
125
        startMove += (2*nL);
126
        fillEdge(mEdges[i],index,startMove,offset,numEnabledMoves);
127
        }
128
      }
129

  
97 130
    return mEdges;
98 131
    }
99 132

  
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

  
135
  private void fillEdge(int[] edge, int index, int move, int offset, int num)
136
    {
137
    for(int i=0; i<num; i++)
138
      {
139
      edge[index+2*i  ] = (move+offset);
140
      edge[index+2*i+1] = (i+offset)/2;
141
      move++;
142
      }
143
    }
144

  
100 145
///////////////////////////////////////////////////////////////////////////////////////////////////
101 146

  
102 147
  public float[][] getCuts(int[] numLayers)
103 148
    {
104 149
    if( mCuts==null )
105 150
      {
106
      int numAxis = ROT_AXIS.length;
107
      final float CUT = SQ3/6;
108
      mCuts = new float[numAxis][];
109

  
110
      for(int a=0; a<numAxis; a++)
111
        {
112
        Static3D ax = ROT_AXIS[a];
113
        float move = MIRROR_VEC[0]*ax.get0() + MIRROR_VEC[1]*ax.get1() + MIRROR_VEC[2]*ax.get2();
114
        mCuts[a] = new float[] {-CUT+move,CUT+move};
115
        }
151
      float[] c = { SQ6/12, 5*SQ6/12 };  // ??
152
      mCuts = new float[][] {c,c,c,c};
116 153
      }
117 154

  
118 155
    return mCuts;
......
122 159

  
123 160
  public boolean[][] getLayerRotatable(int[] numLayers)
124 161
    {
125
    boolean[] tmp = new boolean[] {true,true};
162
    boolean[] tmp = {true,true,true};
126 163
    return new boolean[][] { tmp,tmp,tmp,tmp };
127 164
    }
128 165

  
......
148 185
    }
149 186

  
150 187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
// 'full' dists (not divided by numLayers)
189

  
190
  private float[] getDist()
191
    {
192
    if( mDist==null )
193
      {
194
      float DX = MIRROR_VEC[0];
195
      float DY = MIRROR_VEC[1];
196
      float DZ = MIRROR_VEC[2];
197
      Static3D[] axis = getFaceAxis();
198
      mDist = new float[4];
199

  
200
      for( int a=0; a<4; a++ )
201
        {
202
        Static3D ax = axis[a];
203
        float d = ax.get0()*DX + ax.get1()*DY + ax.get2()*DZ;
204
        mDist[a] = SQ6/6 + d;
205
        }
206
      }
207

  
208
    return mDist;
209
    }
210

  
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212
// 'regular' dists for the touchControl (have to be divided by numLayers)
151 213

  
152 214
  public float[] getDist3D(int[] numLayers)
153 215
    {
154
    int N = numLayers[0];
155
    float DX = MIRROR_VEC[0]/N;
156
    float DY = MIRROR_VEC[1]/N;
157
    float DZ = MIRROR_VEC[2]/N;
158
    return new float[] { 0.5f+DX, 0.5f-DX, 0.5f-DY, 0.5f+DY, 0.5f-DZ, 0.5f+DZ };
216
    if( mDist3D==null )
217
      {
218
      float[] d = getDist();
219
      mDist3D = new float[] { d[0]/3, d[1]/3, d[2]/3, d[3]/3 };
220
      }
221

  
222
    return mDist3D;
159 223
    }
160 224

  
161 225
///////////////////////////////////////////////////////////////////////////////////////////////////
162 226

  
163 227
  public Static3D[] getFaceAxis()
164 228
    {
165
    return TouchControlHexahedron.FACE_AXIS;
229
    return TouchControlTetrahedron.FACE_AXIS;
166 230
    }
167 231

  
168 232
///////////////////////////////////////////////////////////////////////////////////////////////////
169 233

  
170
  public float[][] getCubitPositions(int[] numLayers)
234
  private void addTetrahedralLattice(int size, int index, float[][] pos)
235
    {
236
    final float DX = 1.0f;
237
    final float DY = SQ2/2;
238
    final float DZ = 1.0f;
239

  
240
    float startX = 0.0f;
241
    float startY =-DY*(size-1)/2;
242
    float startZ = DZ*(size-1)/2;
243

  
244
    for(int layer=0; layer<size; layer++)
245
      {
246
      float currX = startX;
247
      float currY = startY;
248

  
249
      for(int x=0; x<layer+1; x++)
250
        {
251
        float currZ = startZ;
252

  
253
        for(int z=0; z<size-layer; z++)
254
          {
255
          pos[index] = new float[] {currX,currY,currZ};
256
          index++;
257
          currZ -= DZ;
258
          }
259

  
260
        currX += DX;
261
        }
262

  
263
      startX-=DX/2;
264
      startY+=DY;
265
      startZ-=DZ/2;
266
      }
267
    }
268

  
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

  
271
  private float[][] getPositions()
171 272
    {
172 273
    if( mPositions==null )
173 274
      {
174
      final float DIST_CORNER = 1;
175
      final float DIST_CENTER = 1;
176

  
177
      mPositions = new float[8+6][];
178

  
179
      /// CORNERS //////////////////////////////////////////////
180

  
181
      mPositions[0] = new float[]{ DIST_CORNER,  DIST_CORNER,  DIST_CORNER};
182
      mPositions[1] = new float[]{ DIST_CORNER,  DIST_CORNER, -DIST_CORNER};
183
      mPositions[2] = new float[]{ DIST_CORNER, -DIST_CORNER,  DIST_CORNER};
184
      mPositions[3] = new float[]{ DIST_CORNER, -DIST_CORNER, -DIST_CORNER};
185
      mPositions[4] = new float[]{-DIST_CORNER,  DIST_CORNER,  DIST_CORNER};
186
      mPositions[5] = new float[]{-DIST_CORNER,  DIST_CORNER, -DIST_CORNER};
187
      mPositions[6] = new float[]{-DIST_CORNER, -DIST_CORNER,  DIST_CORNER};
188
      mPositions[7] = new float[]{-DIST_CORNER, -DIST_CORNER, -DIST_CORNER};
189

  
190
      /// CENTERS //////////////////////////////////////////////
191

  
192
      final float X = 0.0f;
193
      final float Y = 0.0f;
194
      final float Z = 0.0f;
195

  
196
      mPositions[ 8] = new float[]{ X, Y, DIST_CENTER };
197
      mPositions[ 9] = new float[]{ X, Y,-DIST_CENTER };
198
      mPositions[10] = new float[]{ X, DIST_CENTER, Z };
199
      mPositions[11] = new float[]{ X,-DIST_CENTER, Z };
200
      mPositions[12] = new float[]{ DIST_CENTER, Y, Z };
201
      mPositions[13] = new float[]{-DIST_CENTER, Y, Z };
275
      final float X = MIRROR_VEC[0];
276
      final float Y = MIRROR_VEC[1];
277
      final float Z = MIRROR_VEC[2];
278

  
279
      mPositions = new float[14][];
280

  
281
      addTetrahedralLattice(3, 0,mPositions);
282
      addTetrahedralLattice(2,10,mPositions);
283

  
284
      for( float[] pos : mPositions )
285
        {
286
        pos[0] += X;
287
        pos[1] += Y;
288
        pos[2] += Z;
289
        }
202 290
      }
203 291

  
204 292
    return mPositions;
205 293
    }
206 294

  
295

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

  
298
  public float[][] getCubitPositions(int[] numLayers)
299
    {
300
    return getPositions();
301
    }
302

  
207 303
///////////////////////////////////////////////////////////////////////////////////////////////////
208 304

  
209 305
  public Static4D getCubitQuats(int cubit, int[] numLayers)
......
212 308
    }
213 309

  
214 310
///////////////////////////////////////////////////////////////////////////////////////////////////
215
// TODO
216 311

  
217
  private float[][] getVertices(int variant)
312
  private void createCutPlanes()
218 313
    {
219
    return null;
314
    int numPlanes = 3*4;
315
    mCutPlanes = new float[numPlanes][];
316
    Static3D[] faceAxis = getFaceAxis();
317
    float[] dist = getDist();
318
    int[] numLayers = getNumLayers();
319
    float[][] cuts = getCuts(numLayers);
320
    float cut0 = cuts[0][0];
321
    float cut1 = cuts[0][1];
322

  
323
    for(int p=0; p<4; p++)
324
      {
325
      Static3D ax = faceAxis[p];
326
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), dist[p] };
327
      }
328

  
329
    for(int p=4; p<8; p++)
330
      {
331
      Static3D ax = ROT_AXIS[p-4];
332
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut0 };
333
      }
334
    for(int p=8; p<12; p++)
335
      {
336
      Static3D ax = ROT_AXIS[p-8];
337
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut1 };
338
      }
339
    }
340

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

  
343
  private float[] internalPoint(int variant)
344
    {
345
    float[][] pos = getPositions();
346
    float[] position = pos[variant];
347
    float[][] center = computeVertexEffectCenter(variant);
348
    float[] cent = center[0];
349

  
350
    float[] ret = new float[3];
351

  
352
    float A = 0.05f;
353

  
354
    ret[0] = position[0] + A*cent[0];
355
    ret[1] = position[1] + A*cent[1];
356
    ret[2] = position[2] + A*cent[2];
357

  
358
    return ret;
220 359
    }
221 360

  
222 361
///////////////////////////////////////////////////////////////////////////////////////////////////
223
// TODO
224 362

  
225 363
  public ObjectShape getObjectShape(int variant)
226 364
    {
227
    return null;
365
    if( mShapes==null )
366
      {
367
      int[] numLayers = getNumLayers();
368
      int numV = getNumCubitVariants(numLayers);
369
      mShapes = new ObjectShape[numV];
370
      createCutPlanes();
371
      mPotentialVertices = FactoryShape.computePotentialVertices(mCutPlanes);
372
      }
373

  
374
    if( mShapes[variant]==null )
375
      {
376
      float[][] pos = getPositions();
377
      float[] point = internalPoint(variant);
378
      mShapes[variant] = FactoryShape.createShape(mCutPlanes,mPotentialVertices,pos[variant],point);
379
      }
380

  
381
    return mShapes[variant];
228 382
    }
229 383

  
230 384
///////////////////////////////////////////////////////////////////////////////////////////////////
231 385

  
232 386
  public ObjectFaceShape getObjectFaceShape(int variant)
233 387
    {
234
    if( variant<8 )
388
    ObjectShape shape = getObjectShape(variant);
389
    int[][] ind    = shape.getVertIndices();
390
    float[][] vert = shape.getVertices();
391
    float[][] pos  = getPositions();
392
    int[] indices  = FactoryShape.produceBandIndices(vert, pos[variant], ind, getFaceAxis(), getDist() );
393

  
394
    if( variant<10 )
235 395
      {
236
      int N = 6;
237
      int E1= 3;
238
      int E2= 1;
239
      float height = isInIconMode() ? 0.001f : 0.02f;
240
      float[][] bands = { {height,35,0.16f,0.7f,N,E1,E1}, {0.001f, 35,1.00f,0.0f,3,1,E2} };
241
      int[] indices   = { 0,0,0,1,1,1 };
396
      int N = 5;
397
      int E = 1;
398
      float height = isInIconMode() ? 0.001f : 0.04f;
399
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
242 400
      return new ObjectFaceShape(bands,indices,null);
243 401
      }
244 402
    else
245 403
      {
246
      int N = 6;
247
      int E = 2;
248
      float height = isInIconMode() ? 0.001f : 0.04f;
249
      float[][] bands = { {height,35,SQ2/8,0.9f,N,E,E}, {0.001f,35,1,0.0f,3,0,0} };
250
      int[] indices   = { 0,1,1,1,1 };
404
      int N = 5;
405
      int E = 1;
406
      float height = isInIconMode() ? 0.001f : 0.05f;
407
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
251 408
      return new ObjectFaceShape(bands,indices,null);
252 409
      }
253 410
    }
254 411

  
255 412
///////////////////////////////////////////////////////////////////////////////////////////////////
256
// TODO: centers, number of vertices
413

  
414
  private float[][] computeVertexEffectCenter(int variant)
415
    {
416
    float A = variant<4 ? 0.5f : 1.0f;
417

  
418
    float[][] positions = getPositions();
419
    float[] p = positions[variant];
420

  
421
    return new float[][] {{ A*p[0], A*p[1], A*p[2] }};
422
    }
423

  
424
///////////////////////////////////////////////////////////////////////////////////////////////////
257 425

  
258 426
  public ObjectVertexEffects getVertexEffects(int variant)
259 427
    {
260
    if( variant<8 )
261
      {
262
      float[][] corners   = { {0.05f,0.25f}, {0.05f,0.20f} };
263
      int[] cornerIndices = { 1,1,1,0,0 };
264
      float[][] centers   = { {-0.5f, -0.5f, -0.5f} };
265
      int[] centerIndices = { 0,0,0,-1,0 };
266
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
267
      }
268
    else
269
      {
270
      float[][] corners   = { {0.06f,0.15f} };
271
      int[] cornerIndices = { 0,0,0,0,0 };
272
      float[][] centers   = { {0,0,-0.4f} };
273
      int[] centerIndices = { 0,0,0,0,-1 };
274
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,cornerIndices,centers,centerIndices);
275
      }
428
    ObjectShape shape  = getObjectShape(variant);
429
    float[][] vertices = shape.getVertices();
430
    float[][] centers  = computeVertexEffectCenter(variant);
431
    float[][] pos      = getPositions();
432
    int[] indices      = FactoryShape.computeVertexEffectsIndices(vertices, pos[variant], getFaceAxis(), getDist() );
433
    float[][] corners  = variant<10 ? new float[][]{{0.03f, 0.20f}} : new float[][]{{0.03f, 0.15f}};
434

  
435
    return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
276 436
    }
277 437

  
278 438
///////////////////////////////////////////////////////////////////////////////////////////////////
......
300 460

  
301 461
  public float getStickerStroke()
302 462
    {
303
    return isInIconMode() ? 0.16f : 0.08f;
463
    return isInIconMode() ? 0.12f : 0.08f;
304 464
    }
305 465

  
306 466
///////////////////////////////////////////////////////////////////////////////////////////////////
......
337 497

  
338 498
  public String getShortName()
339 499
    {
340
    switch(getNumLayers()[0])
341
      {
342
      case 2: return ObjectType.SKEW_2.name();
343
      case 3: return ObjectType.SKEW_3.name();
344
      }
345

  
346
    return ObjectType.SKEW_2.name();
500
    return ObjectType.MPYR_3.name();
347 501
    }
348 502

  
349 503
///////////////////////////////////////////////////////////////////////////////////////////////////
350 504

  
351 505
  public ObjectSignature getSignature()
352 506
    {
353
    switch(getNumLayers()[0])
354
      {
355
      case 2: return new ObjectSignature(ObjectConstants.SKEW_2);
356
      case 3: return new ObjectSignature(ObjectConstants.SKEW_3);
357
      }
358

  
359
    return null;
507
    return new ObjectSignature(ObjectConstants.MPYR_3);
360 508
    }
361 509

  
362 510
///////////////////////////////////////////////////////////////////////////////////////////////////
363 511

  
364 512
  public String getObjectName()
365 513
    {
366
    switch(getNumLayers()[0])
367
      {
368
      case 2: return "Skewb";
369
      case 3: return "Master Skewb";
370
      }
371
    return null;
514
    return "Bump Pyraminx";
372 515
    }
373 516

  
374 517
///////////////////////////////////////////////////////////////////////////////////////////////////
375 518

  
376 519
  public String getInventor()
377 520
    {
378
    switch(getNumLayers()[0])
379
      {
380
      case 2: return "Tony Durham";
381
      case 3: return "Katsuhiko Okamoto";
382
      }
383
    return null;
521
    return "Ryan Allsop";
384 522
    }
385 523

  
386 524
///////////////////////////////////////////////////////////////////////////////////////////////////
387 525

  
388 526
  public int getYearOfInvention()
389 527
    {
390
    switch(getNumLayers()[0])
391
      {
392
      case 2: return 1982;
393
      case 3: return 2003;
394
      }
395
    return 1982;
528
    return 2012;
396 529
    }
397 530

  
398 531
///////////////////////////////////////////////////////////////////////////////////////////////////
399 532

  
400 533
  public int getComplexity()
401 534
    {
402
    switch(getNumLayers()[0])
403
      {
404
      case 2: return 1;
405
      case 3: return 3;
406
      }
407
    return 5;
535
    return 1;
408 536
    }
409 537

  
410 538
///////////////////////////////////////////////////////////////////////////////////////////////////
411 539

  
412 540
  public String[][] getTutorials()
413 541
    {
414
    int[] numLayers = getNumLayers();
415

  
416
    switch(numLayers[0])
417
      {
418
      case 2: return new String[][] {
419
                          {"gb","I6132yshkeU","How to Solve the Skewb","Z3"},
420
                          {"es","wxQX3HhPgds","Resolver Skewb (Principiantes)","Cuby"},
421
                          {"ru","EICw3aqn6Bc","Как собрать Скьюб?","Алексей Ярыгин"},
422
                          {"fr","lR-GuIroh4k","Comment réussir le skewb","Rachma Nikov"},
423
                          {"de","7RX6D5pznOk","Skewb lösen","Pezcraft"},
424
                          {"pl","ofRu1fByNpk","Jak ułożyć: Skewb","DżoDżo"},
425
                          {"br","mNycauwshWs","Como resolver o Skewb","Pedro Filho"},
426
                          {"kr","5R3sU-_bMAI","SKEWB 초보 공식","iamzoone"},
427
                          {"vn","Db5mXuqgQP8","Tutorial N.5 - Skewb","Duy Thích Rubik"},
428
                          {"tw","XtZL9WFMkA8","斜轉魔方教學","不正常魔術方塊研究中心"},
429
                         };
430
      case 3: return new String[][] {
431
                          {"gb","Jiuf7zQyPYI","Master Skewb Cube Tutorial","Bearded Cubing"},
432
                          {"es","8TP6p63KQCA","Master Skewb en Español","jorlozCubes"},
433
                          {"ru","7155QSp3T74","часть 1: Как собрать мастер Скьюб","Иван Циков"},
434
                          {"ru","14ey-RihjgY","часть 2: Как собрать мастер Скьюб","Иван Циков"},
435
                          {"ru","watq6TLa5_E","часть 2.5: Как собрать мастер Скьюб","Иван Циков"},
436
                          {"ru","UnsvseFBXmo","часть 3: Как собрать мастер Скьюб","Иван Циков"},
437
                          {"fr","tYMoY4EOHVA","Résolution du Master Skewb","Asthalis"},
438
                          {"de","LSErzqGNElI","Master Skewb lösen","JamesKnopf"},
439
                          {"pl","Y7l3AYFvDJI","Master Skewb TUTORIAL PL","MrUk"},
440
                          {"kr","ycR-WmXJCG0","마스터 스큐브 3번째 해법","듀나메스 큐브 해법연구소"},
441
                          {"vn","uG8H0ZQTZgw","Tutorial N.35 - Master Skewb","Duy Thích Rubik"},
442
                          {"tw","PAPa069Y92M","大師斜轉方塊 教學","不正常魔術方塊研究中心"},
443
                         };
444
      }
445 542
    return null;
446 543
    }
447 544
}
src/main/java/org/distorted/objectlib/objects/TwistyMirrorSkewb.java
167 167
    {
168 168
    if( mDist3D==null )
169 169
      {
170
      float DX = MIRROR_VEC[0]/2;
171
      float DY = MIRROR_VEC[1]/2;
172
      float DZ = MIRROR_VEC[2]/2;
173
      mDist3D = new float[] {0.5f+DX, 0.5f-DX, 0.5f+DY, 0.5f-DY, 0.5f+DZ, 0.5f-DZ};
170
      float[] d = getDist();
171
      mDist3D = new float[] { d[0]/2, d[1]/2, d[2]/2, d[3]/2, d[4]/2, d[5]/2 };
174 172
      }
175 173

  
176 174
    return mDist3D;
src/main/java/org/distorted/objectlib/objects/TwistyPyraminx.java
167 167

  
168 168
      for(int i=0; i<numL-1; i++)
169 169
        {
170

  
171 170
        mCuts[0][i] = cut;
172 171
        mCuts[1][i] = cut;
173 172
        mCuts[2][i] = cut;
src/main/java/org/distorted/objectlib/signature/ObjectConstants.java
97 97
  public static final int FADI_5 = 81;
98 98
  public static final int LATT_5 = 82;
99 99
  public static final int MSKE_2 = 83;
100
  public static final int MPYR_3 = 84;
100
  public static final int MJIN_2 = 84;
101
  public static final int MPYR_3 = 85;
101 102
  }

Also available in: Unified diff