Project

General

Profile

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

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

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.helpers.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.ShapeTetrahedron;
29
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
30

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

    
33
public class TwistyCoinTetrahedron extends ShapeTetrahedron
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.620f,0.621f };
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},{2},{3}},
111
         {{1},{1},{1},{0},{3},{2}},
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.06f;
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
      float A = -0.016f;
178
      float[] r0 = new float[] { A*(V[0][0]-M[0][0]), A*(V[0][1]-M[0][1]), A*(V[0][2]-M[0][2]) };
179
      float[] r1 = new float[] { A*(V[1][0]-M[1][0]), A*(V[1][1]-M[1][1]), A*(V[1][2]-M[1][2]) };
180
      float[] r2 = new float[] { A*(V[2][0]-M[2][0]), A*(V[2][1]-M[2][1]), A*(V[2][2]-M[2][2]) };
181
      float[] r3 = new float[] { A*(V[3][0]-M[3][0]), A*(V[3][1]-M[3][1]), A*(V[3][2]-M[3][2]) };
182

    
183
      mPosition = new float[][]
184
         {
185
             {V[1][0],V[1][1],V[1][2]},
186
             {V[0][0],V[0][1],V[0][2]},
187
             {V[2][0],V[2][1],V[2][2]},
188
             {V[3][0],V[3][1],V[3][2]},
189

    
190
             {M[0][0],M[0][1],M[0][2]},
191
             {M[1][0],M[1][1],M[1][2]},
192
             {M[2][0],M[2][1],M[2][2]},
193
             {M[3][0],M[3][1],M[3][2]},
194

    
195
             {L[ 0][0] +r0[0],L[ 0][1] +r0[1],L[ 0][2] +r0[2]},
196
             {L[ 1][0] +r0[0],L[ 1][1] +r0[1],L[ 1][2] +r0[2]},
197
             {L[ 2][0] +r0[0],L[ 2][1] +r0[1],L[ 2][2] +r0[2]},
198
             {L[ 3][0] +r1[0],L[ 3][1] +r1[1],L[ 3][2] +r1[2]},
199
             {L[ 4][0] +r1[0],L[ 4][1] +r1[1],L[ 4][2] +r1[2]},
200
             {L[ 5][0] +r1[0],L[ 5][1] +r1[1],L[ 5][2] +r1[2]},
201
             {L[ 6][0] +r2[0],L[ 6][1] +r2[1],L[ 6][2] +r2[2]},
202
             {L[ 7][0] +r2[0],L[ 7][1] +r2[1],L[ 7][2] +r2[2]},
203
             {L[ 8][0] +r2[0],L[ 8][1] +r2[1],L[ 8][2] +r2[2]},
204
             {L[ 9][0] +r3[0],L[ 9][1] +r3[1],L[ 9][2] +r3[2]},
205
             {L[10][0] +r3[0],L[10][1] +r3[1],L[10][2] +r3[2]},
206
             {L[11][0] +r3[0],L[11][1] +r3[1],L[11][2] +r3[2]},
207
         };
208
      }
209

    
210
    return mPosition;
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  public Static4D getCubitQuats(int cubit, int[] numLayers)
216
    {
217
    if( mQuatIndex==null ) mQuatIndex = new int[] {0,6,1,2,
218
                                                   0,5,4,3,
219
                                                   0,2,1,10,8,5,11,7,4,9,6,3 };
220
    return mObjectQuats[mQuatIndex[cubit]];
221
    }
222

    
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

    
225
  private float[] rotateVertices(float angle, float[] vector, float[] center, float[] rotAxis)
226
    {
227
    float[] ret = new float[4];
228
    float sin = (float)Math.sin(angle/2);
229
    float cos = (float)Math.cos(angle/2);
230
    float[] quat= new float[] { sin*rotAxis[0], sin*rotAxis[1], sin*rotAxis[2], cos};
231
    QuatHelper.rotateVectorByQuat(ret,vector,quat);
232

    
233
    ret[0] += center[0];
234
    ret[1] += center[1];
235
    ret[2] += center[2];
236

    
237
    return ret;
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  private void normalize(float[] v)
243
    {
244
    float len = (float)Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
245
    v[0] /= len;
246
    v[1] /= len;
247
    v[2] /= len;
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  private float[][] produceCorner()
253
    {
254
    float[][] ret = new float[5 + 3*(N+1) +3][];
255

    
256
    float C = 0.97f;
257
    ret[0] = new float[] { 0.00f,   0.0f     ,   0.00f };
258
    ret[1] = new float[] { 0.00f,   0.0f     ,  -1.50f };
259
    ret[2] = new float[] { 0.75f,   0.75f*SQ2,  -0.75f };
260
    ret[3] = new float[] {-0.75f,   0.75f*SQ2,  -0.75f };
261
    ret[4] = new float[] { 0.00f, C*0.75f*SQ2,C*-1.50f };
262

    
263
    float[] vect1 = new float[4];
264
    float[] vect2 = new float[4];
265
    float[] vect3 = new float[4];
266

    
267
    for(int i=0; i<3; i++)
268
      {
269
      vect1[i] = -D*M[0][i] + D*(V[1][i]+V[3][i])/2;
270
      vect2[i] = -D*M[3][i] + D*(V[1][i]+V[2][i])/2;
271
      vect3[i] = -D*M[2][i] + D*(V[0][i]+V[1][i])/2;
272
      }
273

    
274
    float[] rot1 = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
275
    float[] rot2 = new float[] { V[3][0]-M[3][0], V[3][1]-M[3][1], V[3][2]-M[3][2] };
276
    float[] rot3 = new float[] { V[2][0]-M[2][0], V[2][1]-M[2][1], V[2][2]-M[2][2] };
277

    
278
    normalize(rot1);
279
    normalize(rot2);
280
    normalize(rot3);
281

    
282
    float[] center1 = { M[0][0]-V[1][0], M[0][1]-V[1][1], M[0][2]-V[1][2] };
283
    float[] center2 = { M[3][0]-V[1][0], M[3][1]-V[1][1], M[3][2]-V[1][2] };
284
    float[] center3 = { M[2][0]-V[1][0], M[2][1]-V[1][1], M[2][2]-V[1][2] };
285

    
286
    for(int i=0; i<N+1; i++)
287
      {
288
      float angle = (float)(2*Math.PI/3)*i/N;
289

    
290
      ret[5        +i] = rotateVertices(angle,vect1,center1,rot1);
291
      ret[5+   N+1 +i] = rotateVertices(angle,vect2,center2,rot2);
292
      ret[5+2*(N+1)+i] = rotateVertices(angle,vect3,center3,rot3);
293
      }
294

    
295
    float B = 0.85f;
296
    ret[ 5 + 3*(N+1)  ] = new float[] { ret[0][0]*B + ret[1][0]*(1-B), ret[0][1]*B + ret[1][1]*(1-B), ret[0][2]*B + ret[1][2]*(1-B) };
297
    ret[ 5 + 3*(N+1)+1] = new float[] { ret[0][0]*B + ret[2][0]*(1-B), ret[0][1]*B + ret[2][1]*(1-B), ret[0][2]*B + ret[2][2]*(1-B) };
298
    ret[ 5 + 3*(N+1)+2] = new float[] { ret[0][0]*B + ret[3][0]*(1-B), ret[0][1]*B + ret[3][1]*(1-B), ret[0][2]*B + ret[3][2]*(1-B) };
299

    
300
    return ret;
301
    }
302

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

    
305
  private float[][] produceCenter()
306
    {
307
    float[][] ret = new float[3*N+1][];
308

    
309
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
310
    normalize(rot);
311

    
312
    float[] center1 = {   0.0f,-D*SQ2  , D  };
313
    float[] center2 = { D*1.5f, D*SQ2/2,-D/2};
314
    float[] center3 = {-D*1.5f, D*SQ2/2,-D/2};
315

    
316
    float[] vect1 = {  D*0.75f, D*0.75f*SQ2, -D*0.75f, 0.0f };
317
    float[] vect2 = { -D*1.50f,   0.00f    ,    0.00f, 0.0f };
318
    float[] vect3 = {  D*0.75f,-D*0.75f*SQ2,  D*0.75f, 0.0f };
319

    
320
    for(int i=0; i<N; i++)
321
      {
322
      float angle = (float)(Math.PI/3)*i/N;
323

    
324
      ret[  N-1-i] = rotateVertices(angle, vect1, center1, rot);
325
      ret[2*N-1-i] = rotateVertices(angle, vect2, center2, rot);
326
      ret[3*N-1-i] = rotateVertices(angle, vect3, center3, rot);
327
      }
328

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

    
331
    return ret;
332
    }
333

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

    
336
  private float[][] produceLeaf()
337
    {
338
    float[][] ret = new float[2*N+1][];
339

    
340
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
341
    normalize(rot);
342

    
343
    float[] center1 = { 0.0f, -D*0.75f*SQ2, D*0.75f };
344
    float[] center2 = { 0.0f,    0.25f*SQ2,  -0.25f };
345

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

    
350
    for(int i=0; i<N; i++)
351
      {
352
      float angle1 = (float)(  Math.PI/3)*i/N;
353
      float angle2 = (float)(2*Math.PI/3)*i/N;
354

    
355
      ret[  N-1-i] = rotateVertices(angle1, vect1, center1, rot);
356
      ret[2*N-1-i] = rotateVertices(angle2, vect2, center2, rot);
357
      }
358

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

    
361
    return ret;
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  private float[][] getVertices(int variant)
367
    {
368
         if( variant==0 ) return produceCorner();
369
    else if( variant==1 ) return produceCenter();
370
    else                  return produceLeaf();
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  private int[][] produceCornerShape()
376
    {
377
    int[][] ret = new int[9+3*N+3][];
378

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

    
385
    ret[1] = new int[N+4];
386
    ret[1][0] = 2;
387
    ret[1][1] = 0;
388
    ret[1][2] = 1;
389
    for(int i=0; i<N+1; i++) ret[1][3+i] = 6+2*N-i;
390

    
391
    ret[2] = new int[N+4];
392
    ret[2][0] = 1;
393
    ret[2][1] = 0;
394
    ret[2][2] = 3;
395
    for(int i=0; i<N+1; i++) ret[2][3+i] = 7+3*N-i;
396

    
397
    ret[3] = new int[] {5+  N,2    , 4 };
398
    ret[4] = new int[] {2    ,6+  N, 4 };
399
    ret[5] = new int[] {6+2*N,1    , 4 };
400
    ret[6] = new int[] {1    ,7+2*N, 4 };
401
    ret[7] = new int[] {7+3*N,3    , 4 };
402
    ret[8] = new int[] {3    ,5    , 4 };
403

    
404
    for(int i=0; i<N; i++)
405
      {
406
      ret[9+    i] = new int[] {5    +i, 6    +i, 4};
407
      ret[9+  N+i] = new int[] {6+  N+i, 7+  N+i, 4};
408
      ret[9+2*N+i] = new int[] {7+2*N+i, 8+2*N+i, 4};
409
      }
410

    
411
    ret[3*N+ 9] = new int[] { 3*N+8, 3*N+ 9, 3 };
412
    ret[3*N+10] = new int[] { 3*N+9, 3*N+10, 1 };
413
    ret[3*N+11] = new int[] { 3*N+8, 3*N+10, 2 };
414

    
415
    return ret;
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  private int[][] produceCenterShape()
421
    {
422
    int[][] ret = new int[3+3*(N-1)+1][];
423

    
424
    ret[0] = new int[3*N];
425
    for(int i=0; i<3*N; i++) ret[0][i] = i;
426

    
427
    for(int i=1; i<=N-1; i++)
428
      {
429
      ret[i] = new int[3];
430
      ret[i][0] = i-1;
431
      ret[i][1] = i;
432
      ret[i][2] = 3*N;
433

    
434
      ret[N-1+i] = new int[3];
435
      ret[N-1+i][0] = N+i-1;
436
      ret[N-1+i][1] = N+i;
437
      ret[N-1+i][2] = 3*N;
438

    
439
      ret[2*N-2+i] = new int[3];
440
      ret[2*N-2+i][0] = 2*N+i-1;
441
      ret[2*N-2+i][1] = 2*N+i;
442
      ret[2*N-2+i][2] = 3*N;
443
      }
444

    
445
    ret[3*N-2] = new int[] {   N-1,   N, 3*N };
446
    ret[3*N-1] = new int[] { 2*N-1, 2*N, 3*N };
447
    ret[3*N  ] = new int[] { 3*N-1,   0, 3*N };
448

    
449
    return ret;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  private int[][] produceLeafShape()
455
    {
456
    int[][] ret = new int[2+2*(N-1)+1][];
457

    
458
    ret[0] = new int[2*N];
459
    for(int i=0; i<2*N; i++) ret[0][i] = 2*N-1-i;
460

    
461
    for(int i=1; i<=N-1; i++)
462
      {
463
      ret[i] = new int[3];
464
      ret[i][0] = i;
465
      ret[i][1] = i-1;
466
      ret[i][2] = 2*N;
467

    
468
      ret[N-1+i] = new int[3];
469
      ret[N-1+i][0] = N+i;
470
      ret[N-1+i][1] = N+i-1;
471
      ret[N-1+i][2] = 2*N;
472
      }
473

    
474
    ret[2*N-1] = new int[] { N,  N-1, 2*N };
475
    ret[2*N  ] = new int[] { 0,2*N-1, 2*N };
476

    
477
    return ret;
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481

    
482
  public ObjectShape getObjectShape(int variant)
483
    {
484
    if( variant==0 )
485
      {
486
      int[][] indices = produceCornerShape();
487
      return new ObjectShape(getVertices(variant), indices);
488
      }
489
    else if( variant==1 )
490
      {
491
      int[][] indices = produceCenterShape();
492
      return new ObjectShape(getVertices(variant), indices);
493
      }
494
    else
495
      {
496
      int[][] indices = produceLeafShape();
497
      return new ObjectShape(getVertices(variant), indices);
498
      }
499
    }
500

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

    
503
  public ObjectFaceShape getObjectFaceShape(int variant)
504
    {
505
    if( variant==0 )
506
      {
507
      float h1 = isInIconMode() ? 0.0001f : 0.03f;
508
      float h2 = isInIconMode() ? 0.0001f : 0.01f;
509
      float[][] bands = { {h1,35,0.2f,0.4f,5,2,1}, {h2,35,0.2f,0.4f,2,0,0} };
510
      int num = 9+3*N+3;
511
      int[] indices   = new int[num];
512
      for(int i=3; i<num; i++) indices[i] = 1;
513
      float A = 0.5f;
514
      float[] convexCenter = { 0.0f*A, 0.75f*SQ2*A, -1.50f*A};
515
      return new ObjectFaceShape(bands,indices,convexCenter);
516
      }
517
    else if( variant==1 )
518
      {
519
      float h = isInIconMode() ? 0.0001f : 0.001f;
520
      float[][] bands = { {h,15,0.05f,0.1f,5,0,0}, {h,15,0.05f,0.1f,2,0,0} };
521
      int num = 3+3*(N-1)+1;
522
      int[] indices   = new int[num];
523
      for(int i=1; i<num; i++) indices[i] = 1;
524
      return new ObjectFaceShape(bands,indices,null);
525
      }
526
    else
527
      {
528
      float h1 = isInIconMode() ? 0.0001f : 0.015f;
529
      float h2 = isInIconMode() ? 0.0001f : 0.001f;
530
      float[][] bands = { {h1,15,0.250f,0.7f,5,0,0}, {h2,15,0.125f,0.2f,2,0,0} };
531
      int num = 2+2*(N-1)+1;
532
      int[] indices   = new int[num];
533
      for(int i=1; i<num; i++) indices[i] = 1;
534
      return new ObjectFaceShape(bands,indices,null);
535
      }
536
    }
537

    
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539

    
540
  public ObjectVertexEffects getVertexEffects(int variant)
541
    {
542
    if( variant==0 )
543
      {
544
      float[][] corners = { {0.05f,0.20f} };
545
      int num = 5 + 3*(N+1) + 3;
546
      int[] indices     = new int[num];
547
      for(int i=4; i<num; i++) indices[i] = -1;
548
      float[][] centers = { { 0.00f, 0.75f*SQ2,-1.50f} };
549
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
550
      }
551
    else if( variant==1 )
552
      {
553
      float[][] corners = { {0.06f,0.12f} };
554
      int[] indices     = new int[3*N+1];
555
      for(int i=0; i<3*N+1; i++) indices[i] = -1;
556
      float[][] centers = { { 0,0,0 } };
557
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
558
      }
559
    else
560
      {
561
      float[][] corners = { {0.06f,0.20f} };
562
      int[] indices     = new int[2*N+1];
563
      for(int i=0; i<2*N+1; i++) indices[i] = -1;
564
      float[][] centers = { { 0,0,0 } };
565
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
566
      }
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570

    
571
  public int getNumCubitVariants(int[] numLayers)
572
    {
573
    return 3;
574
    }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577

    
578
  public int getCubitVariant(int cubit, int[] numLayers)
579
    {
580
    return cubit<4 ? 0 : (cubit<8 ? 1:2);
581
    }
582

    
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584

    
585
  public float getStickerRadius()
586
    {
587
    return 0.12f;
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  public float getStickerStroke()
593
    {
594
    return isInIconMode() ? 0.15f : 0.12f;
595
    }
596

    
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

    
599
  @Override
600
  public void adjustStickerCoords()
601
    {
602
    float L = 0.02f;
603
    float Z = 0.06422593f - 0.25f*L;
604
    float X = 0.5f - L;
605

    
606
    float K = 1.45f;
607
    float A = K*0.50f;
608
    float B = K*0.25f;
609
    float C = K*0.43301257f;
610

    
611
    float D = 0.3580885f;
612
    float E = 0.12022744f;
613
    float F = 0.32227963f - 0.015f;
614
    float G = 0.14090173f + 0.01f;
615

    
616
    mStickerCoords = new float[][]
617
          {
618
            { -D, E, 0.0f, -0.5f, D, E, F, G, -F, G },
619
            { -C, B, C, B, 0.0f, -A },
620
            { -X, Z, X, Z }
621
          };
622
    }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
  public float[][] getStickerAngles()
627
    {
628
    float D1 = (float)(Math.PI/3);
629
    float D2 = (float)(Math.PI/5);
630
    float D3 = (float)(Math.PI/6);
631
    return new float[][] { { 0,0,0,-D1,0 },{D2,D2,D2},{D1,D3} };
632
    }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635
// PUBLIC API
636

    
637
  public Static3D[] getRotationAxis()
638
    {
639
    return ROT_AXIS;
640
    }
641

    
642
///////////////////////////////////////////////////////////////////////////////////////////////////
643

    
644
  public int[][] getBasicAngles()
645
    {
646
    if( mBasicAngle ==null )
647
      {
648
      int[] tmp = {3,3,3};
649
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
650
      }
651

    
652
    return mBasicAngle;
653
    }
654

    
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656

    
657
  public String getShortName()
658
    {
659
    return ObjectType.COIN_3.name();
660
    }
661

    
662
///////////////////////////////////////////////////////////////////////////////////////////////////
663

    
664
  public ObjectSignature getSignature()
665
    {
666
    return new ObjectSignature(ObjectSignatures.COIN_3);
667
    }
668

    
669
///////////////////////////////////////////////////////////////////////////////////////////////////
670

    
671
  public String getObjectName()
672
    {
673
    return "Coin Tetrahedron";
674
    }
675

    
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677

    
678
  public String getInventor()
679
    {
680
    return "Kevin Uhrik";
681
    }
682

    
683
///////////////////////////////////////////////////////////////////////////////////////////////////
684

    
685
  public int getYearOfInvention()
686
    {
687
    return 2019;
688
    }
689

    
690
///////////////////////////////////////////////////////////////////////////////////////////////////
691

    
692
  public int getComplexity()
693
    {
694
    return 0;
695
    }
696

    
697
///////////////////////////////////////////////////////////////////////////////////////////////////
698

    
699
  public String[][] getTutorials()
700
    {
701
    return new String[][] {
702
                          {"gb","2WrDNfcfpAg","Coin Pyraminx Tutorial","Brent Richter"},
703
                          {"es","5pTfSCsHPWs","Tutorial Coin Pyraminx","Kubekings"},
704
                          {"ru","qUMQsn8kg1A","Как собрать Коин Пираминкс","Алексей Ярыгин"},
705
                          {"vn","TOaiOcEE0lk","Hướng Dẫn Giải Pyraminx Coin","Rubik Cube"},
706
                         };
707
    }
708
}
(5-5/44)