Project

General

Profile

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

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

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.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
  private boolean[][] mRotatable;
52

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

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

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

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

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

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
  public int[][] getScrambleEdges()
76
    {
77
    if( mEdges==null )
78
      {
79
      setUpRotatable();
80
      mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle, mRotatable);
81
      }
82

    
83
    return mEdges;
84
    }
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

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

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

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

    
105
    return mCuts;
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

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

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

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

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

    
129
  public int getTouchControlType()
130
    {
131
    return TC_TETRAHEDRON;
132
    }
133

    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

    
136
  public int getTouchControlSplit()
137
    {
138
    return TYPE_SPLIT_EDGE_COIN;
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

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

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

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

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

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

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

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

    
180
    float A = 1.06f;
181
    M = new float[4][3];
182

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

    
187
    L = new float[12][3];
188

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

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

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

    
214
      float A = -0.016f;
215
      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]) };
216
      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]) };
217
      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]) };
218
      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]) };
219

    
220
      mPosition = new float[][]
221
         {
222
             {V[1][0],V[1][1],V[1][2]},
223
             {V[0][0],V[0][1],V[0][2]},
224
             {V[2][0],V[2][1],V[2][2]},
225
             {V[3][0],V[3][1],V[3][2]},
226

    
227
             {M[0][0],M[0][1],M[0][2]},
228
             {M[1][0],M[1][1],M[1][2]},
229
             {M[2][0],M[2][1],M[2][2]},
230
             {M[3][0],M[3][1],M[3][2]},
231

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

    
247
    return mPosition;
248
    }
249

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

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

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

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

    
270
    ret[0] += center[0];
271
    ret[1] += center[1];
272
    ret[2] += center[2];
273

    
274
    return ret;
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

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

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

    
289
  private float[][] produceCorner()
290
    {
291
    float[][] ret = new float[5 + 3*(N+1) +3][];
292

    
293
    float C = 0.97f;
294
    ret[0] = new float[] { 0.00f,   0.0f     ,   0.00f };
295
    ret[1] = new float[] { 0.00f,   0.0f     ,  -1.50f };
296
    ret[2] = new float[] { 0.75f,   0.75f*SQ2,  -0.75f };
297
    ret[3] = new float[] {-0.75f,   0.75f*SQ2,  -0.75f };
298
    ret[4] = new float[] { 0.00f, C*0.75f*SQ2,C*-1.50f };
299

    
300
    float[] vect1 = new float[4];
301
    float[] vect2 = new float[4];
302
    float[] vect3 = new float[4];
303

    
304
    for(int i=0; i<3; i++)
305
      {
306
      vect1[i] = -D*M[0][i] + D*(V[1][i]+V[3][i])/2;
307
      vect2[i] = -D*M[3][i] + D*(V[1][i]+V[2][i])/2;
308
      vect3[i] = -D*M[2][i] + D*(V[0][i]+V[1][i])/2;
309
      }
310

    
311
    float[] rot1 = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
312
    float[] rot2 = new float[] { V[3][0]-M[3][0], V[3][1]-M[3][1], V[3][2]-M[3][2] };
313
    float[] rot3 = new float[] { V[2][0]-M[2][0], V[2][1]-M[2][1], V[2][2]-M[2][2] };
314

    
315
    normalize(rot1);
316
    normalize(rot2);
317
    normalize(rot3);
318

    
319
    float[] center1 = { M[0][0]-V[1][0], M[0][1]-V[1][1], M[0][2]-V[1][2] };
320
    float[] center2 = { M[3][0]-V[1][0], M[3][1]-V[1][1], M[3][2]-V[1][2] };
321
    float[] center3 = { M[2][0]-V[1][0], M[2][1]-V[1][1], M[2][2]-V[1][2] };
322

    
323
    for(int i=0; i<N+1; i++)
324
      {
325
      float angle = (float)(2*Math.PI/3)*i/N;
326

    
327
      ret[5        +i] = rotateVertices(angle,vect1,center1,rot1);
328
      ret[5+   N+1 +i] = rotateVertices(angle,vect2,center2,rot2);
329
      ret[5+2*(N+1)+i] = rotateVertices(angle,vect3,center3,rot3);
330
      }
331

    
332
    float B = 0.85f;
333
    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) };
334
    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) };
335
    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) };
336

    
337
    return ret;
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  private float[][] produceCenter()
343
    {
344
    float[][] ret = new float[3*N+1][];
345

    
346
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
347
    normalize(rot);
348

    
349
    float[] center1 = {   0.0f,-D*SQ2  , D  };
350
    float[] center2 = { D*1.5f, D*SQ2/2,-D/2};
351
    float[] center3 = {-D*1.5f, D*SQ2/2,-D/2};
352

    
353
    float[] vect1 = {  D*0.75f, D*0.75f*SQ2, -D*0.75f, 0.0f };
354
    float[] vect2 = { -D*1.50f,   0.00f    ,    0.00f, 0.0f };
355
    float[] vect3 = {  D*0.75f,-D*0.75f*SQ2,  D*0.75f, 0.0f };
356

    
357
    for(int i=0; i<N; i++)
358
      {
359
      float angle = (float)(Math.PI/3)*i/N;
360

    
361
      ret[  N-1-i] = rotateVertices(angle, vect1, center1, rot);
362
      ret[2*N-1-i] = rotateVertices(angle, vect2, center2, rot);
363
      ret[3*N-1-i] = rotateVertices(angle, vect3, center3, rot);
364
      }
365

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

    
368
    return ret;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  private float[][] produceLeaf()
374
    {
375
    float[][] ret = new float[2*N+1][];
376

    
377
    float[] rot = new float[] { V[0][0]-M[0][0], V[0][1]-M[0][1], V[0][2]-M[0][2] };
378
    normalize(rot);
379

    
380
    float[] center1 = { 0.0f, -D*0.75f*SQ2, D*0.75f };
381
    float[] center2 = { 0.0f,    0.25f*SQ2,  -0.25f };
382

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

    
387
    for(int i=0; i<N; i++)
388
      {
389
      float angle1 = (float)(  Math.PI/3)*i/N;
390
      float angle2 = (float)(2*Math.PI/3)*i/N;
391

    
392
      ret[  N-1-i] = rotateVertices(angle1, vect1, center1, rot);
393
      ret[2*N-1-i] = rotateVertices(angle2, vect2, center2, rot);
394
      }
395

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

    
398
    return ret;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  private float[][] getVertices(int variant)
404
    {
405
         if( variant==0 ) return produceCorner();
406
    else if( variant==1 ) return produceCenter();
407
    else                  return produceLeaf();
408
    }
409

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

    
412
  private int[][] produceCornerShape()
413
    {
414
    int[][] ret = new int[9+3*N+3][];
415

    
416
    ret[0] = new int[N+4];
417
    ret[0][0] = 3;
418
    ret[0][1] = 0;
419
    ret[0][2] = 2;
420
    for(int i=0; i<N+1; i++) ret[0][3+i] = 5+N-i;
421

    
422
    ret[1] = new int[N+4];
423
    ret[1][0] = 2;
424
    ret[1][1] = 0;
425
    ret[1][2] = 1;
426
    for(int i=0; i<N+1; i++) ret[1][3+i] = 6+2*N-i;
427

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

    
434
    ret[3] = new int[] {5+  N,2    , 4 };
435
    ret[4] = new int[] {2    ,6+  N, 4 };
436
    ret[5] = new int[] {6+2*N,1    , 4 };
437
    ret[6] = new int[] {1    ,7+2*N, 4 };
438
    ret[7] = new int[] {7+3*N,3    , 4 };
439
    ret[8] = new int[] {3    ,5    , 4 };
440

    
441
    for(int i=0; i<N; i++)
442
      {
443
      ret[9+    i] = new int[] {5    +i, 6    +i, 4};
444
      ret[9+  N+i] = new int[] {6+  N+i, 7+  N+i, 4};
445
      ret[9+2*N+i] = new int[] {7+2*N+i, 8+2*N+i, 4};
446
      }
447

    
448
    ret[3*N+ 9] = new int[] { 3*N+8, 3*N+ 9, 3 };
449
    ret[3*N+10] = new int[] { 3*N+9, 3*N+10, 1 };
450
    ret[3*N+11] = new int[] { 3*N+8, 3*N+10, 2 };
451

    
452
    return ret;
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  private int[][] produceCenterShape()
458
    {
459
    int[][] ret = new int[3+3*(N-1)+1][];
460

    
461
    ret[0] = new int[3*N];
462
    for(int i=0; i<3*N; i++) ret[0][i] = i;
463

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

    
471
      ret[N-1+i] = new int[3];
472
      ret[N-1+i][0] = N+i-1;
473
      ret[N-1+i][1] = N+i;
474
      ret[N-1+i][2] = 3*N;
475

    
476
      ret[2*N-2+i] = new int[3];
477
      ret[2*N-2+i][0] = 2*N+i-1;
478
      ret[2*N-2+i][1] = 2*N+i;
479
      ret[2*N-2+i][2] = 3*N;
480
      }
481

    
482
    ret[3*N-2] = new int[] {   N-1,   N, 3*N };
483
    ret[3*N-1] = new int[] { 2*N-1, 2*N, 3*N };
484
    ret[3*N  ] = new int[] { 3*N-1,   0, 3*N };
485

    
486
    return ret;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  private int[][] produceLeafShape()
492
    {
493
    int[][] ret = new int[2+2*(N-1)+1][];
494

    
495
    ret[0] = new int[2*N];
496
    for(int i=0; i<2*N; i++) ret[0][i] = 2*N-1-i;
497

    
498
    for(int i=1; i<=N-1; i++)
499
      {
500
      ret[i] = new int[3];
501
      ret[i][0] = i;
502
      ret[i][1] = i-1;
503
      ret[i][2] = 2*N;
504

    
505
      ret[N-1+i] = new int[3];
506
      ret[N-1+i][0] = N+i;
507
      ret[N-1+i][1] = N+i-1;
508
      ret[N-1+i][2] = 2*N;
509
      }
510

    
511
    ret[2*N-1] = new int[] { N,  N-1, 2*N };
512
    ret[2*N  ] = new int[] { 0,2*N-1, 2*N };
513

    
514
    return ret;
515
    }
516

    
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518

    
519
  public ObjectShape getObjectShape(int variant)
520
    {
521
    if( variant==0 )
522
      {
523
      int[][] indices = produceCornerShape();
524
      return new ObjectShape(getVertices(variant), indices);
525
      }
526
    else if( variant==1 )
527
      {
528
      int[][] indices = produceCenterShape();
529
      return new ObjectShape(getVertices(variant), indices);
530
      }
531
    else
532
      {
533
      int[][] indices = produceLeafShape();
534
      return new ObjectShape(getVertices(variant), indices);
535
      }
536
    }
537

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

    
540
  public ObjectFaceShape getObjectFaceShape(int variant)
541
    {
542
    if( variant==0 )
543
      {
544
      float h1 = isInIconMode() ? 0.0001f : 0.03f;
545
      float h2 = isInIconMode() ? 0.0001f : 0.01f;
546
      float[][] bands = { {h1,35,0.2f,0.4f,5,2,1}, {h2,35,0.2f,0.4f,2,0,0} };
547
      int num = 9+3*N+3;
548
      int[] indices   = new int[num];
549
      for(int i=3; i<num; i++) indices[i] = 1;
550
      float A = 0.5f;
551
      float[] convexCenter = { 0.0f*A, 0.75f*SQ2*A, -1.50f*A};
552
      return new ObjectFaceShape(bands,indices,convexCenter);
553
      }
554
    else if( variant==1 )
555
      {
556
      float h = isInIconMode() ? 0.0001f : 0.001f;
557
      float[][] bands = { {h,15,0.05f,0.1f,5,0,0}, {h,15,0.05f,0.1f,2,0,0} };
558
      int num = 3+3*(N-1)+1;
559
      int[] indices   = new int[num];
560
      for(int i=1; i<num; i++) indices[i] = 1;
561
      return new ObjectFaceShape(bands,indices,null);
562
      }
563
    else
564
      {
565
      float h1 = isInIconMode() ? 0.0001f : 0.015f;
566
      float h2 = isInIconMode() ? 0.0001f : 0.001f;
567
      float[][] bands = { {h1,15,0.250f,0.7f,5,0,0}, {h2,15,0.125f,0.2f,2,0,0} };
568
      int num = 2+2*(N-1)+1;
569
      int[] indices   = new int[num];
570
      for(int i=1; i<num; i++) indices[i] = 1;
571
      return new ObjectFaceShape(bands,indices,null);
572
      }
573
    }
574

    
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576

    
577
  public ObjectVertexEffects getVertexEffects(int variant)
578
    {
579
    if( variant==0 )
580
      {
581
      float[][] corners = { {0.05f,0.20f} };
582
      int num = 5 + 3*(N+1) + 3;
583
      int[] indices     = new int[num];
584
      for(int i=4; i<num; i++) indices[i] = -1;
585
      float[][] centers = { { 0.00f, 0.75f*SQ2,-1.50f} };
586
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
587
      }
588
    else if( variant==1 )
589
      {
590
      float[][] corners = { {0.06f,0.12f} };
591
      int[] indices     = new int[3*N+1];
592
      for(int i=0; i<3*N+1; i++) indices[i] = -1;
593
      float[][] centers = { { 0,0,0 } };
594
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
595
      }
596
    else
597
      {
598
      float[][] corners = { {0.06f,0.20f} };
599
      int[] indices     = new int[2*N+1];
600
      for(int i=0; i<2*N+1; i++) indices[i] = -1;
601
      float[][] centers = { { 0,0,0 } };
602
      return FactoryCubit.generateVertexEffect(getVertices(variant),corners,indices,centers,indices);
603
      }
604
    }
605

    
606
///////////////////////////////////////////////////////////////////////////////////////////////////
607

    
608
  public int getNumCubitVariants(int[] numLayers)
609
    {
610
    return 3;
611
    }
612

    
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614

    
615
  public int getCubitVariant(int cubit, int[] numLayers)
616
    {
617
    return cubit<4 ? 0 : (cubit<8 ? 1:2);
618
    }
619

    
620
///////////////////////////////////////////////////////////////////////////////////////////////////
621

    
622
  public float getStickerRadius()
623
    {
624
    return 0.12f;
625
    }
626

    
627
///////////////////////////////////////////////////////////////////////////////////////////////////
628

    
629
  public float getStickerStroke()
630
    {
631
    return isInIconMode() ? 0.15f : 0.12f;
632
    }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
  @Override
637
  public void adjustStickerCoords()
638
    {
639
    float L = 0.02f;
640
    float Z = 0.06422593f - 0.25f*L;
641
    float X = 0.5f - L;
642

    
643
    float K = 1.45f;
644
    float A = K*0.50f;
645
    float B = K*0.25f;
646
    float C = K*0.43301257f;
647

    
648
    float D = 0.3580885f;
649
    float E = 0.12022744f;
650
    float F = 0.32227963f - 0.015f;
651
    float G = 0.14090173f + 0.01f;
652

    
653
    mStickerCoords = new float[][]
654
          {
655
            { -D, E, 0.0f, -0.5f, D, E, F, G, -F, G },
656
            { -C, B, C, B, 0.0f, -A },
657
            { -X, Z, X, Z }
658
          };
659
    }
660

    
661
///////////////////////////////////////////////////////////////////////////////////////////////////
662

    
663
  public float[][] getStickerAngles()
664
    {
665
    float D1 = (float)(Math.PI/3);
666
    float D2 = (float)(Math.PI/5);
667
    float D3 = (float)(Math.PI/6);
668
    return new float[][] { { 0,0,0,-D1,0 },{D2,D2,D2},{D1,D3} };
669
    }
670

    
671
///////////////////////////////////////////////////////////////////////////////////////////////////
672
// PUBLIC API
673

    
674
  public Static3D[] getRotationAxis()
675
    {
676
    return ROT_AXIS;
677
    }
678

    
679
///////////////////////////////////////////////////////////////////////////////////////////////////
680

    
681
  public int[][] getBasicAngles()
682
    {
683
    if( mBasicAngle ==null )
684
      {
685
      int[] tmp = {3,3,3};
686
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
687
      }
688

    
689
    return mBasicAngle;
690
    }
691

    
692
///////////////////////////////////////////////////////////////////////////////////////////////////
693

    
694
  public String getShortName()
695
    {
696
    return ObjectType.COIN_3.name();
697
    }
698

    
699
///////////////////////////////////////////////////////////////////////////////////////////////////
700

    
701
  public ObjectSignature getSignature()
702
    {
703
    return new ObjectSignature(ObjectSignatures.COIN_3);
704
    }
705

    
706
///////////////////////////////////////////////////////////////////////////////////////////////////
707

    
708
  public String getObjectName()
709
    {
710
    return "Coin Tetrahedron";
711
    }
712

    
713
///////////////////////////////////////////////////////////////////////////////////////////////////
714

    
715
  public String getInventor()
716
    {
717
    return "Kevin Uhrik";
718
    }
719

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

    
722
  public int getYearOfInvention()
723
    {
724
    return 2019;
725
    }
726

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

    
729
  public int getComplexity()
730
    {
731
    return 0;
732
    }
733

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

    
736
  public String[][] getTutorials()
737
    {
738
    return new String[][] {
739
                          {"gb","2WrDNfcfpAg","Coin Pyraminx Tutorial","Brent Richter"},
740
                          {"es","5pTfSCsHPWs","Tutorial Coin Pyraminx","Kubekings"},
741
                          {"ru","qUMQsn8kg1A","Как собрать Коин Пираминкс","Алексей Ярыгин"},
742
                          {"vn","TOaiOcEE0lk","Hướng Dẫn Giải Pyraminx Coin","Rubik Cube"},
743
                         };
744
    }
745
}
(7-7/47)