Project

General

Profile

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

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

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_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.metadata.Metadata;
22
import org.distorted.objectlib.signature.ObjectSignature;
23
import org.distorted.objectlib.helpers.ObjectVertexEffects;
24
import org.distorted.objectlib.main.InitAssets;
25
import org.distorted.objectlib.signature.ObjectConstants;
26
import org.distorted.objectlib.metadata.ListObjects;
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

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

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

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

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

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

    
63
  @Override
64
  public float[][] returnRotationFactor()
65
    {
66
    float C1 = 1.0f;
67
    float C2 = 1.7f;
68
    float[] f = new float[] { C1,C1,C2 };
69
    return new float[][] { f,f,f,f };
70
    }
71

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

    
74
  public int[][] getScrambleEdges()
75
    {
76
    if( mEdges==null )
77
      {
78
      mEdges = new int[][]
79
          {
80
              { 2,1,3,1, 6,1,7,1, 10,1,11,1, 14,1,15,1}, // tips
81
              { 0,0,1,0, 4,0,5,0,  8,0, 9,0, 12,0,13,0}, // centers
82
          };
83
      }
84

    
85
    return mEdges;
86
    }
87

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

    
90
  @Override
91
  public int[][] getScrambleAlgorithms()
92
    {
93
    setUpRotatable();
94
    return ScrambleEdgeGenerator.getScramblingAlgorithms(mBasicAngle, mRotatable);
95
    }
96

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

    
99
  public float[][] getCuts(int[] numLayers)
100
    {
101
    if( mCuts==null )
102
      {
103
      float[] cut = new float[] { -0.620f,0.600f };
104
      mCuts = new float[][] { cut,cut,cut,cut };
105
      }
106

    
107
    return mCuts;
108
    }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
  private void setUpRotatable()
113
    {
114
    if( mRotatable==null )
115
      {
116
      boolean[] tmp = new boolean[] {true,false,true};
117
      mRotatable = new boolean[][] { tmp,tmp,tmp,tmp };
118
      }
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  public boolean[][] getLayerRotatable(int[] numLayers)
124
    {
125
    setUpRotatable();
126
    return mRotatable;
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  public int getTouchControlType()
132
    {
133
    return TC_TETRAHEDRON;
134
    }
135

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  public int getTouchControlSplit()
139
    {
140
    return TYPE_SPLIT_EDGE_COIN;
141
    }
142

    
143
///////////////////////////////////////////////////////////////////////////////////////////////////
144

    
145
  public int[][][] getEnabled()
146
    {
147
    return new int[][][]
148
      {
149
         {{0},{0},{0},{1},{2},{3}},
150
         {{1},{1},{1},{0},{3},{2}},
151
         {{2},{2},{2},{3},{1},{0}},
152
         {{3},{3},{3},{2},{0},{1}}
153
      };
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  public float[] getDist3D(int[] numLayers)
159
    {
160
    return TouchControlTetrahedron.D3D;
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  public Static3D[] getFaceAxis()
166
    {
167
    return TouchControlTetrahedron.FACE_AXIS;
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  private void initVertices()
173
    {
174
    V = new float[][]
175
        {
176
            { 0.0f,-0.75f*SQ2,-1.5f},
177
            { 0.0f,-0.75f*SQ2, 1.5f},
178
            { 1.5f, 0.75f*SQ2, 0.0f},
179
            {-1.5f, 0.75f*SQ2, 0.0f},
180
        };
181

    
182
    M = new float[4][3];
183

    
184
    for(int i=0; i<4; i++)
185
      for(int j=0; j<3; j++)
186
        M[i][j] = (V[0][j]+V[1][j]+V[2][j]+V[3][j]-V[i][j])/3;
187

    
188
    final float B = 0.492f;
189
    L = new float[12][3];
190

    
191
    for(int i=0; i<3; i++)
192
      {
193
      L[ 0][i] = B*V[1][i] + (1-B)*(V[2][i] + V[3][i])/2;
194
      L[ 1][i] = B*V[3][i] + (1-B)*(V[1][i] + V[2][i])/2;
195
      L[ 2][i] = B*V[2][i] + (1-B)*(V[1][i] + V[3][i])/2;
196
      L[ 3][i] = B*V[0][i] + (1-B)*(V[2][i] + V[3][i])/2;
197
      L[ 4][i] = B*V[2][i] + (1-B)*(V[0][i] + V[3][i])/2;
198
      L[ 5][i] = B*V[3][i] + (1-B)*(V[0][i] + V[2][i])/2;
199
      L[ 6][i] = B*V[3][i] + (1-B)*(V[1][i] + V[0][i])/2;
200
      L[ 7][i] = B*V[0][i] + (1-B)*(V[1][i] + V[3][i])/2;
201
      L[ 8][i] = B*V[1][i] + (1-B)*(V[0][i] + V[3][i])/2;
202
      L[ 9][i] = B*V[2][i] + (1-B)*(V[1][i] + V[0][i])/2;
203
      L[10][i] = B*V[0][i] + (1-B)*(V[1][i] + V[2][i])/2;
204
      L[11][i] = B*V[1][i] + (1-B)*(V[0][i] + V[2][i])/2;
205
      }
206
    }
207

    
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

    
210
  public float[][] getCubitPositions(int[] numLayers)
211
    {
212
    if( mPosition==null )
213
      {
214
      if( V==null ) initVertices();
215

    
216
      float A = -0.016f;
217
      float B =  1.06f;
218
      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]) };
219
      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]) };
220
      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]) };
221
      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]) };
222

    
223
      mPosition = new float[][]
224
         {
225
             {V[1][0],V[1][1],V[1][2]},
226
             {V[0][0],V[0][1],V[0][2]},
227
             {V[2][0],V[2][1],V[2][2]},
228
             {V[3][0],V[3][1],V[3][2]},
229

    
230
             {B*M[0][0],B*M[0][1],B*M[0][2]},
231
             {B*M[1][0],B*M[1][1],B*M[1][2]},
232
             {B*M[2][0],B*M[2][1],B*M[2][2]},
233
             {B*M[3][0],B*M[3][1],B*M[3][2]},
234

    
235
             {L[ 0][0] +r0[0],L[ 0][1] +r0[1],L[ 0][2] +r0[2]},
236
             {L[ 1][0] +r0[0],L[ 1][1] +r0[1],L[ 1][2] +r0[2]},
237
             {L[ 2][0] +r0[0],L[ 2][1] +r0[1],L[ 2][2] +r0[2]},
238
             {L[ 3][0] +r1[0],L[ 3][1] +r1[1],L[ 3][2] +r1[2]},
239
             {L[ 4][0] +r1[0],L[ 4][1] +r1[1],L[ 4][2] +r1[2]},
240
             {L[ 5][0] +r1[0],L[ 5][1] +r1[1],L[ 5][2] +r1[2]},
241
             {L[ 6][0] +r2[0],L[ 6][1] +r2[1],L[ 6][2] +r2[2]},
242
             {L[ 7][0] +r2[0],L[ 7][1] +r2[1],L[ 7][2] +r2[2]},
243
             {L[ 8][0] +r2[0],L[ 8][1] +r2[1],L[ 8][2] +r2[2]},
244
             {L[ 9][0] +r3[0],L[ 9][1] +r3[1],L[ 9][2] +r3[2]},
245
             {L[10][0] +r3[0],L[10][1] +r3[1],L[10][2] +r3[2]},
246
             {L[11][0] +r3[0],L[11][1] +r3[1],L[11][2] +r3[2]},
247
         };
248
      }
249

    
250
    return mPosition;
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

    
255
  public Static4D getCubitQuats(int cubit, int[] numLayers)
256
    {
257
    if( mQuatIndex==null ) mQuatIndex = new int[] {0,6,1,2,
258
                                                   0,5,4,3,
259
                                                   0,2,1,10,8,5,11,7,4,9,6,3 };
260
    return mObjectQuats[mQuatIndex[cubit]];
261
    }
262

    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
  private float[] rotateVertices(float angle, float[] vector, float[] center, float[] rotAxis)
266
    {
267
    float[] ret = new float[4];
268
    float sin = (float)Math.sin(angle/2);
269
    float cos = (float)Math.cos(angle/2);
270
    float[] quat= new float[] { sin*rotAxis[0], sin*rotAxis[1], sin*rotAxis[2], cos};
271
    QuatHelper.rotateVectorByQuat(ret,vector,quat);
272

    
273
    ret[0] += center[0];
274
    ret[1] += center[1];
275
    ret[2] += center[2];
276

    
277
    return ret;
278
    }
279

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  private void normalize(float[] v)
283
    {
284
    float len = (float)Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
285
    v[0] /= len;
286
    v[1] /= len;
287
    v[2] /= len;
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  private float[][] produceCorner()
293
    {
294
    float[][] ret = new float[5 + 3*(N+1) +3][];
295

    
296
    float C = 0.50f;
297
    ret[0] = new float[] { 0.00f,   0.0f     ,   0.00f };
298
    ret[1] = new float[] { 0.00f,   0.0f     ,  -1.50f };
299
    ret[2] = new float[] { 0.75f,   0.75f*SQ2,  -0.75f };
300
    ret[3] = new float[] {-0.75f,   0.75f*SQ2,  -0.75f };
301
    ret[4] = new float[] { 0.00f, C*0.75f*SQ2,C*-1.50f };
302

    
303
    float[] vect1 = new float[4];
304
    float[] vect2 = new float[4];
305
    float[] vect3 = new float[4];
306

    
307
    float G = 0.94f;
308

    
309
    for(int i=0; i<3; i++)
310
      {
311
      vect1[i] = -G*M[0][i] + G*(V[1][i]+V[3][i])/2;
312
      vect2[i] = -G*M[3][i] + G*(V[1][i]+V[2][i])/2;
313
      vect3[i] = -G*M[2][i] + G*(V[0][i]+V[1][i])/2;
314
      }
315

    
316
    float[] rot1 = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
317
    float[] rot2 = new float[] { V[3][0]-M[3][0], V[3][1]-M[3][1], V[3][2]-M[3][2] };
318
    float[] rot3 = new float[] { V[2][0]-M[2][0], V[2][1]-M[2][1], V[2][2]-M[2][2] };
319

    
320
    normalize(rot1);
321
    normalize(rot2);
322
    normalize(rot3);
323

    
324
    float[] center1 = { M[0][0]-V[1][0], M[0][1]-V[1][1], M[0][2]-V[1][2] };
325
    float[] center2 = { M[3][0]-V[1][0], M[3][1]-V[1][1], M[3][2]-V[1][2] };
326
    float[] center3 = { M[2][0]-V[1][0], M[2][1]-V[1][1], M[2][2]-V[1][2] };
327

    
328
    for(int i=0; i<N+1; i++)
329
      {
330
      float angle = (float)(2*Math.PI/3)*i/N;
331

    
332
      ret[5        +i] = rotateVertices(angle,vect1,center1,rot1);
333
      ret[5+   N+1 +i] = rotateVertices(angle,vect2,center2,rot2);
334
      ret[5+2*(N+1)+i] = rotateVertices(angle,vect3,center3,rot3);
335
      }
336

    
337
    float B = 0.85f;
338
    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) };
339
    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) };
340
    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) };
341

    
342
    return ret;
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  private float[][] produceCenter()
348
    {
349
    final float D = 0.96f;
350
    float[][] ret = new float[3*N+1][];
351

    
352
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
353
    normalize(rot);
354

    
355
    float[] center1 = {   0.0f,-D*SQ2  , D  };
356
    float[] center2 = { D*1.5f, D*SQ2/2,-D/2};
357
    float[] center3 = {-D*1.5f, D*SQ2/2,-D/2};
358

    
359
    float[] vect1 = {  D*0.75f, D*0.75f*SQ2, -D*0.75f, 0.0f };
360
    float[] vect2 = { -D*1.50f,   0.00f    ,    0.00f, 0.0f };
361
    float[] vect3 = {  D*0.75f,-D*0.75f*SQ2,  D*0.75f, 0.0f };
362

    
363
    for(int i=0; i<N; i++)
364
      {
365
      float angle = (float)(Math.PI/3)*i/N;
366

    
367
      ret[  N-1-i] = rotateVertices(angle, vect1, center1, rot);
368
      ret[2*N-1-i] = rotateVertices(angle, vect2, center2, rot);
369
      ret[3*N-1-i] = rotateVertices(angle, vect3, center3, rot);
370
      }
371

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

    
374
    return ret;
375
    }
376

    
377
///////////////////////////////////////////////////////////////////////////////////////////////////
378

    
379
  private float[][] produceLeaf()
380
    {
381
    float[][] ret = new float[2*N+1][];
382

    
383
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
384
    normalize(rot);
385

    
386
    float[] center1 = { 0.0f, -0.75f*SQ2, 0.75f };
387
    float[] center2 = { 0.0f,  0.25f*SQ2,-0.25f };
388

    
389
    float[] vect1 = {  0.75f, 0.75f*SQ2, -0.75f, 0.0f };
390
    float[] vect2 = new float[4];
391
    for(int i=0; i<3; i++) vect2[i] = -M[0][i] + (V[1][i]+V[3][i])/2;
392

    
393
    final float G = 0.95f;
394

    
395
    for(int i=0; i<N; i++)
396
      {
397
      float angle1 = (float)(  Math.PI/3)*i/N;
398
      float angle2 = (float)(2*Math.PI/3)*i/N;
399

    
400
      ret[  N-1-i] = rotateVertices(angle1, vect1, center1, rot);
401
      ret[2*N-1-i] = rotateVertices(angle2, vect2, center2, rot);
402

    
403
      float[] tmp = ret[N-1-i];
404
      tmp[0]*=G;
405
      tmp[1]*=G;
406
      tmp[2]*=G;
407
      tmp = ret[2*N-1-i];
408
      tmp[0]*=G;
409
      tmp[1]*=G;
410
      tmp[2]*=G;
411
      }
412

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

    
415
    return ret;
416
    }
417

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

    
420
  private float[][] getVertices(int variant)
421
    {
422
         if( variant==0 ) return produceCorner();
423
    else if( variant==1 ) return produceCenter();
424
    else                  return produceLeaf();
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  private int[][] produceCornerShape()
430
    {
431
    int[][] ret = new int[9+3*N+3][];
432

    
433
    ret[0] = new int[N+4];
434
    ret[0][0] = 3;
435
    ret[0][1] = 0;
436
    ret[0][2] = 2;
437
    for(int i=0; i<N+1; i++) ret[0][3+i] = 5+N-i;
438

    
439
    ret[1] = new int[N+4];
440
    ret[1][0] = 2;
441
    ret[1][1] = 0;
442
    ret[1][2] = 1;
443
    for(int i=0; i<N+1; i++) ret[1][3+i] = 6+2*N-i;
444

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

    
451
    ret[3] = new int[] {5+  N,2    , 4 };
452
    ret[4] = new int[] {2    ,6+  N, 4 };
453
    ret[5] = new int[] {6+2*N,1    , 4 };
454
    ret[6] = new int[] {1    ,7+2*N, 4 };
455
    ret[7] = new int[] {7+3*N,3    , 4 };
456
    ret[8] = new int[] {3    ,5    , 4 };
457

    
458
    for(int i=0; i<N; i++)
459
      {
460
      ret[9+    i] = new int[] {5    +i, 6    +i, 4};
461
      ret[9+  N+i] = new int[] {6+  N+i, 7+  N+i, 4};
462
      ret[9+2*N+i] = new int[] {7+2*N+i, 8+2*N+i, 4};
463
      }
464

    
465
    ret[3*N+ 9] = new int[] { 3*N+8, 3*N+ 9, 3 };
466
    ret[3*N+10] = new int[] { 3*N+9, 3*N+10, 1 };
467
    ret[3*N+11] = new int[] { 3*N+8, 3*N+10, 2 };
468

    
469
    return ret;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  private int[][] produceCenterShape()
475
    {
476
    int[][] ret = new int[3+3*(N-1)+1][];
477

    
478
    ret[0] = new int[3*N];
479
    for(int i=0; i<3*N; i++) ret[0][i] = i;
480

    
481
    for(int i=1; i<=N-1; i++)
482
      {
483
      ret[i] = new int[3];
484
      ret[i][0] = 3*N;
485
      ret[i][1] = i;
486
      ret[i][2] = i-1;
487

    
488
      ret[N-1+i] = new int[3];
489
      ret[N-1+i][0] = 3*N;
490
      ret[N-1+i][1] = N+i;
491
      ret[N-1+i][2] = N+i-1;
492

    
493
      ret[2*N-2+i] = new int[3];
494
      ret[2*N-2+i][0] = 3*N;
495
      ret[2*N-2+i][1] = 2*N+i;
496
      ret[2*N-2+i][2] = 2*N+i-1;
497
      }
498

    
499
    ret[3*N-2] = new int[] {   N-1,   N, 3*N };
500
    ret[3*N-1] = new int[] { 2*N-1, 2*N, 3*N };
501
    ret[3*N  ] = new int[] { 3*N-1,   0, 3*N };
502

    
503
    return ret;
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  private int[][] produceLeafShape()
509
    {
510
    int[][] ret = new int[2+2*(N-1)+1][];
511

    
512
    ret[0] = new int[2*N];
513
    for(int i=0; i<2*N; i++) ret[0][i] = 2*N-1-i;
514

    
515
    for(int i=1; i<=N-1; i++)
516
      {
517
      ret[i] = new int[3];
518
      ret[i][0] = i;
519
      ret[i][1] = i-1;
520
      ret[i][2] = 2*N;
521

    
522
      ret[N-1+i] = new int[3];
523
      ret[N-1+i][0] = N+i;
524
      ret[N-1+i][1] = N+i-1;
525
      ret[N-1+i][2] = 2*N;
526
      }
527

    
528
    ret[2*N-1] = new int[] { N,  N-1, 2*N };
529
    ret[2*N  ] = new int[] { 0,2*N-1, 2*N };
530

    
531
    return ret;
532
    }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
  public ObjectShape getObjectShape(int variant)
537
    {
538
    if( variant==0 )
539
      {
540
      int[][] indices = produceCornerShape();
541
      return new ObjectShape(getVertices(variant), indices);
542
      }
543
    else if( variant==1 )
544
      {
545
      int[][] indices = produceCenterShape();
546
      return new ObjectShape(getVertices(variant), indices);
547
      }
548
    else
549
      {
550
      int[][] indices = produceLeafShape();
551
      return new ObjectShape(getVertices(variant), indices);
552
      }
553
    }
554

    
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556

    
557
  public ObjectFaceShape getObjectFaceShape(int variant)
558
    {
559
    if( variant==0 )
560
      {
561
      float h1 = isInIconMode() ? 0.0001f : 0.03f;
562
      float h2 = isInIconMode() ? 0.0001f : 0.01f;
563
      float[][] bands = { {h1,35,0.2f,0.4f,5,2,1}, {h2,35,0.2f,0.4f,2,0,0} };
564
      int num = 9+3*N+3;
565
      int[] indices   = new int[num];
566
      for(int i=3; i<num; i++) indices[i] = 1;
567
      float A = 0.5f;
568
      float[] convexCenter = { 0.0f*A, 0.75f*SQ2*A, -1.50f*A};
569
      return new ObjectFaceShape(bands,indices,convexCenter);
570
      }
571
    else if( variant==1 )
572
      {
573
      float h = isInIconMode() ? 0.0001f : 0.001f;
574
      float[][] bands = { {h,15,0.05f,0.1f,5,0,0}, {h,15,0.05f,0.1f,2,0,0} };
575
      int num = 3+3*(N-1)+1;
576
      int[] indices   = new int[num];
577
      for(int i=1; i<num; i++) indices[i] = 1;
578
      return new ObjectFaceShape(bands,indices,null);
579
      }
580
    else
581
      {
582
      float h1 = isInIconMode() ? 0.0001f : 0.001f;
583
      float h2 = isInIconMode() ? 0.0001f : 0.001f;
584
      float[][] bands = { {h1,35,0.30f,0.5f,5,0,0}, {h2,25,0.125f,0.2f,2,0,0} };
585
      int num = 2+2*(N-1)+1;
586
      int[] indices   = new int[num];
587
      for(int i=1; i<num; i++) indices[i] = 1;
588
      return new ObjectFaceShape(bands,indices,null);
589
      }
590
    }
591

    
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593

    
594
  public ObjectVertexEffects getVertexEffects(int variant)
595
    {
596
    if( variant==0 )
597
      {
598
      float[][] corners = { {0.05f,0.20f} };
599
      int num = 5 + 3*(N+1) + 3;
600
      int[] indices     = new int[num];
601
      for(int i=1; i<num; i++) indices[i] = -1;
602
      float[][] centers = { { 0.00f, 0.75f*SQ2,-1.50f} };
603
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
604
      }
605
    else if( variant==1 )
606
      {
607
      float[][] corners = { {0.02f,0.20f} };
608
      int[] indices     = new int[3*N+1];
609
      for(int i=0; i<3*N+1; i++) indices[i] = -1;
610
      indices[  N-1] = 0;
611
      indices[2*N-1] = 0;
612
      indices[3*N-1] = 0;
613

    
614
      float[][] centers = { { 0.0f, -SQ2/4, -0.5f } };
615
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
616
      }
617
    else
618
      {
619
      float[][] corners = { {0.017f,0.10f} };
620
      int[] indices     = new int[2*N+1];
621
      for(int i=0; i<2*N+1; i++) indices[i] = -1;
622
      indices[  N-1] = 0;
623
      indices[2*N-1] = 0;
624

    
625
      float A = 10;
626
      float[][] centers = { { 0.0f, A*-0.75f*SQ2/10, A*-1.5f/10 } };
627
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
628
      }
629
    }
630

    
631
///////////////////////////////////////////////////////////////////////////////////////////////////
632

    
633
  public int getNumCubitVariants(int[] numLayers)
634
    {
635
    return 3;
636
    }
637

    
638
///////////////////////////////////////////////////////////////////////////////////////////////////
639

    
640
  public int getCubitVariant(int cubit, int[] numLayers)
641
    {
642
    return cubit<4 ? 0 : (cubit<8 ? 1:2);
643
    }
644

    
645
///////////////////////////////////////////////////////////////////////////////////////////////////
646

    
647
  public float getStickerRadius()
648
    {
649
    return 0.12f;
650
    }
651

    
652
///////////////////////////////////////////////////////////////////////////////////////////////////
653

    
654
  public float getStickerStroke()
655
    {
656
    return isInIconMode() ? 0.15f : 0.19f;
657
    }
658

    
659
///////////////////////////////////////////////////////////////////////////////////////////////////
660

    
661
  @Override
662
  public void adjustStickerCoords()
663
    {
664
    float Y = 0.02f;
665
    float Z = 0.06422593f - 0.25f*Y;
666
    float X = 0.5f - Y;
667

    
668
    float K = 1.45f;
669
    float A = K*0.50f;
670
    float B = K*0.25f;
671
    float C = K*0.43301257f;
672

    
673
    float D = 0.3580885f;
674
    float E = 0.12022744f;
675
    float F = 0.32227963f - 0.015f;
676
    float G = 0.14090173f + 0.01f;
677

    
678
    float H = 0.5f;
679
    float I = 0.0f;
680

    
681
    mStickerCoords = new float[][][][]
682
          {
683
                  { { {-D, E}, { I,-H}, {D, E}, {F, G}, {-F, G} } },
684
                  { { {-C, B}, { C, B}, {I,-A} } },
685
                  { { {-X, Z}, { X, Z} } }
686
          };
687
    }
688

    
689
///////////////////////////////////////////////////////////////////////////////////////////////////
690

    
691
  public float[][][] getStickerAngles()
692
    {
693
    float D1 = (float)(Math.PI/3);
694
    float D2 = (float)(Math.PI/5);
695
    float D3 = (float)(Math.PI/6);
696
    return new float[][][] { {{ 0,0,0,-D1,0 }} , {{D2,D2,D2}} , {{D1,D3}} };
697
    }
698

    
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700
// PUBLIC API
701

    
702
  public Static3D[] getRotationAxis()
703
    {
704
    return ROT_AXIS;
705
    }
706

    
707
///////////////////////////////////////////////////////////////////////////////////////////////////
708

    
709
  public int[][] getBasicAngles()
710
    {
711
    if( mBasicAngle ==null )
712
      {
713
      int[] tmp = {3,3,3};
714
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
715
      }
716

    
717
    return mBasicAngle;
718
    }
719

    
720
///////////////////////////////////////////////////////////////////////////////////////////////////
721

    
722
  public String getShortName()
723
    {
724
    return ListObjects.COIN_3.name();
725
    }
726

    
727
///////////////////////////////////////////////////////////////////////////////////////////////////
728

    
729
  public ObjectSignature getSignature()
730
    {
731
    return new ObjectSignature(ObjectConstants.COIN_3);
732
    }
733

    
734
///////////////////////////////////////////////////////////////////////////////////////////////////
735

    
736
  public String getObjectName()
737
    {
738
    return "Coin Tetrahedron";
739
    }
740

    
741
///////////////////////////////////////////////////////////////////////////////////////////////////
742

    
743
  public String getInventor()
744
    {
745
    return "Kevin Uhrik";
746
    }
747

    
748
///////////////////////////////////////////////////////////////////////////////////////////////////
749

    
750
  public int getYearOfInvention()
751
    {
752
    return 2019;
753
    }
754

    
755
///////////////////////////////////////////////////////////////////////////////////////////////////
756

    
757
  public float getComplexity()
758
    {
759
    return 0.4f;
760
    }
761

    
762
///////////////////////////////////////////////////////////////////////////////////////////////////
763

    
764
  public String[][] getTutorials()
765
    {
766
    return new String[][] {
767
                          {"gb","2WrDNfcfpAg","Coin Pyraminx Tutorial","Brent Richter"},
768
                          {"es","5pTfSCsHPWs","Tutorial Coin Pyraminx","Kubekings"},
769
                          {"ru","qUMQsn8kg1A","Как собрать Коин Пираминкс","Алексей Ярыгин"},
770
                          {"vn","TOaiOcEE0lk","Hướng Dẫn Giải Pyraminx Coin","Rubik Cube"},
771
                          {"tw","ofVag-kYgQ4","圓盤金字塔 ","1hrBLD"},
772
                         };
773
    }
774
}
(10-10/57)