Project

General

Profile

Download (20.6 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCoinTetrahedron.java @ b480f4dd

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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_TETRAHEDRON;
13
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_SPLIT_EDGE_COIN;
14

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

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

    
33
public class TwistyCoinTetrahedron extends ShapeHexahedron
34
{
35
  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 int N = 5;
44
  private static final float D = 0.9f;
45

    
46
  private int[][] mEdges;
47
  private int[][] mBasicAngle;
48
  private float[][] mCuts;
49
  private float[][] mPosition;
50
  private int[] mQuatIndex;
51

    
52
  private float[][] V,M,L;
53

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

    
56
  public TwistyCoinTetrahedron(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
57
    {
58
    super(meshState, iconMode, data.getNumLayers()[0], quat, move, scale, data, asset);
59
    }
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
  public int[][] getScrambleEdges()
64
    {
65
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
66
    return mEdges;
67
    }
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
  public float[][] getCuts(int[] numLayers)
72
    {
73
    if( mCuts==null )
74
      {
75
      float[] cut = new float[] {-0.95f*(SQ6/4),0};
76
      mCuts = new float[][] { cut,cut,cut,cut };
77
      }
78

    
79
    return mCuts;
80
    }
81

    
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

    
84
  public boolean[][] getLayerRotatable(int[] numLayers)
85
    {
86
    boolean[] tmp = new boolean[] {true,false,true};
87
    return new boolean[][] { tmp,tmp,tmp,tmp };
88
    }
89

    
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91

    
92
  public int getTouchControlType()
93
    {
94
    return TC_TETRAHEDRON;
95
    }
96

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  public int getTouchControlSplit()
100
    {
101
    return TYPE_SPLIT_EDGE_COIN;
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  public int[][][] getEnabled()
107
    {
108
    return new int[][][]
109
      {
110
         {{0},{0},{0},{1},{3},{2}},
111
         {{1},{1},{1},{0},{2},{3}},
112
         {{2},{2},{2},{3},{1},{0}},
113
         {{3},{3},{3},{2},{0},{1}}
114
      };
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

    
119
  public float[] getDist3D(int[] numLayers)
120
    {
121
    return TouchControlTetrahedron.D3D;
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  public Static3D[] getFaceAxis()
127
    {
128
    return TouchControlTetrahedron.FACE_AXIS;
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  private void initVertices()
134
    {
135
    V = new float[][]
136
        {
137
            { 0.0f,-0.75f*SQ2,-1.5f},
138
            { 0.0f,-0.75f*SQ2, 1.5f},
139
            { 1.5f, 0.75f*SQ2, 0.0f},
140
            {-1.5f, 0.75f*SQ2, 0.0f},
141
        };
142

    
143
    float A = 1.04f;
144
    M = new float[4][3];
145

    
146
    for(int i=0; i<4; i++)
147
      for(int j=0; j<3; j++)
148
        M[i][j] = A*(V[0][j]+V[1][j]+V[2][j]+V[3][j]-V[i][j])/3;
149

    
150
    L = new float[12][3];
151

    
152
    for(int i=0; i<3; i++)
153
      {
154
      L[ 0][i] = 0.5f*V[1][i] + 0.25f*V[2][i] + 0.25f*V[3][i];
155
      L[ 1][i] = 0.5f*V[3][i] + 0.25f*V[1][i] + 0.25f*V[2][i];
156
      L[ 2][i] = 0.5f*V[2][i] + 0.25f*V[1][i] + 0.25f*V[3][i];
157
      L[ 3][i] = 0.5f*V[0][i] + 0.25f*V[2][i] + 0.25f*V[3][i];
158
      L[ 4][i] = 0.5f*V[2][i] + 0.25f*V[0][i] + 0.25f*V[3][i];
159
      L[ 5][i] = 0.5f*V[3][i] + 0.25f*V[0][i] + 0.25f*V[2][i];
160
      L[ 6][i] = 0.5f*V[3][i] + 0.25f*V[1][i] + 0.25f*V[0][i];
161
      L[ 7][i] = 0.5f*V[0][i] + 0.25f*V[1][i] + 0.25f*V[3][i];
162
      L[ 8][i] = 0.5f*V[1][i] + 0.25f*V[0][i] + 0.25f*V[3][i];
163
      L[ 9][i] = 0.5f*V[2][i] + 0.25f*V[1][i] + 0.25f*V[0][i];
164
      L[10][i] = 0.5f*V[0][i] + 0.25f*V[1][i] + 0.25f*V[2][i];
165
      L[11][i] = 0.5f*V[1][i] + 0.25f*V[0][i] + 0.25f*V[2][i];
166
      }
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
  public float[][] getCubitPositions(int[] numLayers)
172
    {
173
    if( mPosition==null )
174
      {
175
      if( V==null ) initVertices();
176

    
177
      mPosition = new float[][]
178
         {
179
             {V[1][0],V[1][1],V[1][2]},
180
             {V[0][0],V[0][1],V[0][2]},
181
             {V[2][0],V[2][1],V[2][2]},
182
             {V[3][0],V[3][1],V[3][2]},
183

    
184
             {M[0][0],M[0][1],M[0][2]},
185
             {M[1][0],M[1][1],M[1][2]},
186
             {M[2][0],M[2][1],M[2][2]},
187
             {M[3][0],M[3][1],M[3][2]},
188

    
189
             {L[ 0][0],L[ 0][1],L[ 0][2]},
190
             {L[ 1][0],L[ 1][1],L[ 1][2]},
191
             {L[ 2][0],L[ 2][1],L[ 2][2]},
192
             {L[ 3][0],L[ 3][1],L[ 3][2]},
193
             {L[ 4][0],L[ 4][1],L[ 4][2]},
194
             {L[ 5][0],L[ 5][1],L[ 5][2]},
195
             {L[ 6][0],L[ 6][1],L[ 6][2]},
196
             {L[ 7][0],L[ 7][1],L[ 7][2]},
197
             {L[ 8][0],L[ 8][1],L[ 8][2]},
198
             {L[ 9][0],L[ 9][1],L[ 9][2]},
199
             {L[10][0],L[10][1],L[10][2]},
200
             {L[11][0],L[11][1],L[11][2]},
201
         };
202
      }
203

    
204
    return mPosition;
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  public Static4D getCubitQuats(int cubit, int[] numLayers)
210
    {
211
    if( mQuatIndex==null ) mQuatIndex = new int[] {0,6,1,2,
212
                                                   0,5,4,3,
213
                                                   0,2,1,10,8,5,11,7,4,9,6,3 };
214
    return mObjectQuats[mQuatIndex[cubit]];
215
    }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
  private float[] rotateVertices(float angle, float[] vector, float[] center, float[] rotAxis)
220
    {
221
    float[] ret = new float[4];
222
    float sin = (float)Math.sin(angle/2);
223
    float cos = (float)Math.cos(angle/2);
224
    float[] quat= new float[] { sin*rotAxis[0], sin*rotAxis[1], sin*rotAxis[2], cos};
225
    QuatHelper.rotateVectorByQuat(ret,vector,quat);
226

    
227
    ret[0] += center[0];
228
    ret[1] += center[1];
229
    ret[2] += center[2];
230

    
231
    return ret;
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  private void normalize(float[] v)
237
    {
238
    float len = (float)Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
239
    v[0] /= len;
240
    v[1] /= len;
241
    v[2] /= len;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  private float[][] produceCorner()
247
    {
248
    float[][] ret = new float[5 + 3*(N+1)][];
249

    
250
    ret[0] = new float[] { 0.00f, 0.0f     , 0.00f };
251
    ret[1] = new float[] { 0.00f, 0.0f     ,-1.50f };
252
    ret[2] = new float[] { 0.75f, 0.75f*SQ2,-0.75f };
253
    ret[3] = new float[] {-0.75f, 0.75f*SQ2,-0.75f };
254
    ret[4] = new float[] { 0.00f, 0.75f*SQ2,-1.50f };
255

    
256
    float[] vect1 = new float[4];
257
    float[] vect2 = new float[4];
258
    float[] vect3 = new float[4];
259

    
260
    for(int i=0; i<3; i++)
261
      {
262
      vect1[i] = -D*M[0][i] + D*(V[1][i]+V[3][i])/2;
263
      vect2[i] = -D*M[3][i] + D*(V[1][i]+V[2][i])/2;
264
      vect3[i] = -D*M[2][i] + D*(V[0][i]+V[1][i])/2;
265
      }
266

    
267
    float[] rot1 = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
268
    float[] rot2 = new float[] { V[3][0]-M[3][0], V[3][1]-M[3][1], V[3][2]-M[3][2] };
269
    float[] rot3 = new float[] { V[2][0]-M[2][0], V[2][1]-M[2][1], V[2][2]-M[2][2] };
270

    
271
    normalize(rot1);
272
    normalize(rot2);
273
    normalize(rot3);
274

    
275
    float[] center1 = { M[0][0]-V[1][0], M[0][1]-V[1][1], M[0][2]-V[1][2] };
276
    float[] center2 = { M[3][0]-V[1][0], M[3][1]-V[1][1], M[3][2]-V[1][2] };
277
    float[] center3 = { M[2][0]-V[1][0], M[2][1]-V[1][1], M[2][2]-V[1][2] };
278

    
279
    for(int i=0; i<N+1; i++)
280
      {
281
      float angle = (float)(2*Math.PI/3)*i/N;
282

    
283
      ret[5        +i] = rotateVertices(angle,vect1,center1,rot1);
284
      ret[5+   N+1 +i] = rotateVertices(angle,vect2,center2,rot2);
285
      ret[5+2*(N+1)+i] = rotateVertices(angle,vect3,center3,rot3);
286
      }
287

    
288
    return ret;
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  private float[][] produceCenter()
294
    {
295
    float[][] ret = new float[3*N+1][];
296

    
297
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
298
    normalize(rot);
299

    
300
    float[] center1 = {   0.0f,-D*SQ2  , D  };
301
    float[] center2 = { D*1.5f, D*SQ2/2,-D/2};
302
    float[] center3 = {-D*1.5f, D*SQ2/2,-D/2};
303

    
304
    float[] vect1 = {  D*0.75f, D*0.75f*SQ2, -D*0.75f, 0.0f };
305
    float[] vect2 = { -D*1.50f,   0.00f    ,    0.00f, 0.0f };
306
    float[] vect3 = {  D*0.75f,-D*0.75f*SQ2,  D*0.75f, 0.0f };
307

    
308
    for(int i=0; i<N; i++)
309
      {
310
      float angle = (float)(Math.PI/3)*i/N;
311

    
312
      ret[  N-1-i] = rotateVertices(angle, vect1, center1, rot);
313
      ret[2*N-1-i] = rotateVertices(angle, vect2, center2, rot);
314
      ret[3*N-1-i] = rotateVertices(angle, vect3, center3, rot);
315
      }
316

    
317
    ret[3*N] = new float[] { 0.0f, -SQ2/4, -0.5f };
318

    
319
    return ret;
320
    }
321

    
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

    
324
  private float[][] produceLeaf()
325
    {
326
    float[][] ret = new float[2*N+1][];
327

    
328
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
329
    normalize(rot);
330

    
331
    float[] center1 = { 0.0f, -D*0.75f*SQ2, D*0.75f };
332
    float[] center2 = { 0.0f,    0.25f*SQ2,  -0.25f };
333

    
334
    float[] vect1 = {  D*0.75f, D*0.75f*SQ2, -D*0.75f, 0.0f };
335
    float[] vect2 = new float[4];
336
    for(int i=0; i<3; i++) vect2[i] = -D*M[0][i] + D*(V[1][i]+V[3][i])/2;
337

    
338
    for(int i=0; i<N; i++)
339
      {
340
      float angle1 = (float)(  Math.PI/3)*i/N;
341
      float angle2 = (float)(2*Math.PI/3)*i/N;
342

    
343
      ret[  N-1-i] = rotateVertices(angle1, vect1, center1, rot);
344
      ret[2*N-1-i] = rotateVertices(angle2, vect2, center2, rot);
345
      }
346

    
347
    ret[2*N] = new float[] { 0.0f, -0.75f*SQ2/10, -1.5f/10 };
348

    
349
    return ret;
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  private float[][] getVertices(int variant)
355
    {
356
         if( variant==0 ) return produceCorner();
357
    else if( variant==1 ) return produceCenter();
358
    else                  return produceLeaf();
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  private int[][] produceCornerShape()
364
    {
365
    int[][] ret = new int[9+3*N][];
366

    
367
    ret[0] = new int[N+4];
368
    ret[0][0] = 3;
369
    ret[0][1] = 0;
370
    ret[0][2] = 2;
371
    for(int i=0; i<N+1; i++) ret[0][3+i] = 5+N-i;
372

    
373
    ret[1] = new int[N+4];
374
    ret[1][0] = 2;
375
    ret[1][1] = 0;
376
    ret[1][2] = 1;
377
    for(int i=0; i<N+1; i++) ret[1][3+i] = 6+2*N-i;
378

    
379
    ret[2] = new int[N+4];
380
    ret[2][0] = 1;
381
    ret[2][1] = 0;
382
    ret[2][2] = 3;
383
    for(int i=0; i<N+1; i++) ret[2][3+i] = 7+3*N-i;
384

    
385
    ret[3] = new int[] {5+  N,2    , 4 };
386
    ret[4] = new int[] {2    ,6+  N, 4 };
387
    ret[5] = new int[] {6+2*N,1    , 4 };
388
    ret[6] = new int[] {1    ,7+2*N, 4 };
389
    ret[7] = new int[] {7+3*N,3    , 4 };
390
    ret[8] = new int[] {3    ,5    , 4 };
391

    
392
    for(int i=0; i<N; i++)
393
      {
394
      ret[9+    i] = new int[] {5    +i, 6    +i, 4};
395
      ret[9+  N+i] = new int[] {6+  N+i, 7+  N+i, 4};
396
      ret[9+2*N+i] = new int[] {7+2*N+i, 8+2*N+i, 4};
397
      }
398

    
399
    return ret;
400
    }
401

    
402
///////////////////////////////////////////////////////////////////////////////////////////////////
403

    
404
  private int[][] produceCenterShape()
405
    {
406
    int[][] ret = new int[3+3*(N-1)+1][];
407

    
408
    ret[0] = new int[3*N];
409
    for(int i=0; i<3*N; i++) ret[0][i] = 3*N-1-i;
410

    
411
    for(int i=1; i<=N-1; i++)
412
      {
413
      ret[i] = new int[3];
414
      ret[i][0] = i;
415
      ret[i][1] = i-1;
416
      ret[i][2] = 3*N;
417

    
418
      ret[N-1+i] = new int[3];
419
      ret[N-1+i][0] = N+i;
420
      ret[N-1+i][1] = N+i-1;
421
      ret[N-1+i][2] = 3*N;
422

    
423
      ret[2*N-2+i] = new int[3];
424
      ret[2*N-2+i][0] = 2*N+i;
425
      ret[2*N-2+i][1] = 2*N+i-1;
426
      ret[2*N-2+i][2] = 3*N;
427
      }
428

    
429
    ret[3*N-2] = new int[] {   N-1,   N, 3*N };
430
    ret[3*N-1] = new int[] { 2*N-1, 2*N, 3*N };
431
    ret[3*N  ] = new int[] { 3*N-1,   0, 3*N };
432

    
433
    return ret;
434
    }
435

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

    
438
  private int[][] produceLeafShape()
439
    {
440
    int[][] ret = new int[2+2*(N-1)+1][];
441

    
442
    ret[0] = new int[2*N];
443
    for(int i=0; i<2*N; i++) ret[0][i] = 2*N-1-i;
444

    
445
    for(int i=1; i<=N-1; i++)
446
      {
447
      ret[i] = new int[3];
448
      ret[i][0] = i;
449
      ret[i][1] = i-1;
450
      ret[i][2] = 2*N;
451

    
452
      ret[N-1+i] = new int[3];
453
      ret[N-1+i][0] = N+i;
454
      ret[N-1+i][1] = N+i-1;
455
      ret[N-1+i][2] = 2*N;
456
      }
457

    
458
    ret[2*N-1] = new int[] { N,  N-1, 2*N };
459
    ret[2*N  ] = new int[] { 0,2*N-1, 2*N };
460

    
461
    return ret;
462
    }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
  public ObjectShape getObjectShape(int variant)
467
    {
468
    if( variant==0 )
469
      {
470
      int[][] indices = produceCornerShape();
471
      return new ObjectShape(getVertices(variant), indices);
472
      }
473
    else if( variant==1 )
474
      {
475
      int[][] indices = produceCenterShape();
476
      return new ObjectShape(getVertices(variant), indices);
477
      }
478
    else
479
      {
480
      int[][] indices = produceLeafShape();
481
      return new ObjectShape(getVertices(variant), indices);
482
      }
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public ObjectFaceShape getObjectFaceShape(int variant)
488
    {
489
    if( variant==0 )
490
      {
491
      float h1 = isInIconMode() ? 0.001f : 0.035f;
492
      float h2 = isInIconMode() ? 0.001f : 0.01f;
493
      float[][] bands = { {h1,35,0.2f,0.4f,5,1,0}, {h2,35,0.2f,0.4f,2,0,0} };
494
      int[] indices   = new int[9+3*N];
495
      for(int i=3; i<9+3*N; i++) indices[i] = 1;
496
      float A = 0.5f;
497
      float[] convexCenter = { 0.0f*A, 0.75f*SQ2*A, -1.50f*A};
498
      return new ObjectFaceShape(bands,indices,convexCenter);
499
      }
500
    else if( variant==1 )
501
      {
502
      float h1 = isInIconMode() ? 0.001f : 0.00f;
503
      float h2 = isInIconMode() ? 0.001f : 0.00f;
504
      float[][] bands = { {h1,15,0.1f,0.2f,5,0,0}, {h2,15,0.1f,0.2f,2,0,0} };
505
      int num = 3+3*(N-1)+1;
506
      int[] indices   = new int[num];
507
      for(int i=1; i<num; i++) indices[i] = 1;
508
      return new ObjectFaceShape(bands,indices,null);
509
      }
510
    else
511
      {
512
      float h1 = isInIconMode() ? 0.001f : 0.0f;
513
      float h2 = isInIconMode() ? 0.001f : 0.0f;
514
      float[][] bands = { {h1,15,0.250f,0.7f,5,0,0}, {h2,15,0.125f,0.2f,2,0,0} };
515
      int num = 2+2*(N-1)+1;
516
      int[] indices   = new int[num];
517
      for(int i=1; i<num; i++) indices[i] = 1;
518
      return new ObjectFaceShape(bands,indices,null);
519
      }
520
    }
521

    
522
///////////////////////////////////////////////////////////////////////////////////////////////////
523

    
524
  public ObjectVertexEffects getVertexEffects(int variant)
525
    {
526
    if( variant==0 )
527
      {
528
      float[][] corners = { {0.04f,0.15f} };
529
      int[] indices     = new int[5 + 3*(N+1)];
530
      for(int i=4; i<5 + 3*(N+1); i++) indices[i] = -1;
531
      float[][] centers = { { 0.00f, 0.75f*SQ2,-1.50f} };
532
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
533
      }
534
    else if( variant==1 )
535
      {
536
      float[][] corners = { {0.06f,0.12f} };
537
      int[] indices     = new int[3*N+1];
538
      for(int i=0; i<3*N+1; i++) indices[i] = -1;
539
      float[][] centers = { { 0,0,0 } };
540
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
541
      }
542
    else
543
      {
544
      float[][] corners = { {0.06f,0.20f} };
545
      int[] indices     = new int[2*N+1];
546
      for(int i=0; i<2*N+1; i++) indices[i] = -1;
547
      float[][] centers = { { 0,0,0 } };
548
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
549
      }
550
    }
551

    
552
///////////////////////////////////////////////////////////////////////////////////////////////////
553

    
554
  public int getNumCubitVariants(int[] numLayers)
555
    {
556
    return 3;
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560

    
561
  public int getCubitVariant(int cubit, int[] numLayers)
562
    {
563
    return cubit<4 ? 0 : (cubit<8 ? 1:2);
564
    }
565

    
566
///////////////////////////////////////////////////////////////////////////////////////////////////
567

    
568
  public float getStickerRadius()
569
    {
570
    return 0.09f;
571
    }
572

    
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574

    
575
  public float getStickerStroke()
576
    {
577
    return isInIconMode() ? 0.20f : 0.09f;
578
    }
579

    
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581

    
582
  public float[][] getStickerAngles()
583
    {
584
    return null;   // TODO
585
    }
586

    
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588
// PUBLIC API
589

    
590
  public Static3D[] getRotationAxis()
591
    {
592
    return ROT_AXIS;
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public int[][] getBasicAngles()
598
    {
599
    if( mBasicAngle ==null )
600
      {
601
      int[] tmp = {3,3,3};
602
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
603
      }
604

    
605
    return mBasicAngle;
606
    }
607

    
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

    
610
  public String getShortName()
611
    {
612
    return ObjectType.COIN_3.name();
613
    }
614

    
615
///////////////////////////////////////////////////////////////////////////////////////////////////
616

    
617
  public ObjectSignature getSignature()
618
    {
619
    return new ObjectSignature(ObjectSignatures.COIN_3);
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

    
624
  public String getObjectName()
625
    {
626
    return "Coin Tetrahedron";
627
    }
628

    
629
///////////////////////////////////////////////////////////////////////////////////////////////////
630

    
631
  public String getInventor()
632
    {
633
    return "Kevin Uhrik";
634
    }
635

    
636
///////////////////////////////////////////////////////////////////////////////////////////////////
637

    
638
  public int getYearOfInvention()
639
    {
640
    return 2019;
641
    }
642

    
643
///////////////////////////////////////////////////////////////////////////////////////////////////
644

    
645
  public int getComplexity()
646
    {
647
    return 0;
648
    }
649

    
650
///////////////////////////////////////////////////////////////////////////////////////////////////
651

    
652
  public String[][] getTutorials()
653
    {
654
    return new String[][] {
655
                          {"gb","2WrDNfcfpAg","Coin Pyraminx Tutorial","Brent Richter"},
656
                          {"es","5pTfSCsHPWs","Tutorial Coin Pyraminx","Kubekings"},
657
                          {"ru","qUMQsn8kg1A","Как собрать Коин Пираминкс","Алексей Ярыгин"},
658
                          {"vn","TOaiOcEE0lk","Hướng Dẫn Giải Pyraminx Coin","Rubik Cube"},
659
                         };
660
    }
661
}
(5-5/44)