Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyTrajber.java @ ac97ecc0

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.objects;
21

    
22
import org.distorted.library.type.Static3D;
23
import org.distorted.library.type.Static4D;
24
import org.distorted.objectlib.helpers.ObjectFaceShape;
25
import org.distorted.objectlib.helpers.ObjectShape;
26
import org.distorted.objectlib.helpers.ScrambleState;
27
import org.distorted.objectlib.main.ObjectControl;
28
import org.distorted.objectlib.main.ObjectType;
29
import org.distorted.objectlib.main.ShapeOctahedron;
30
import org.distorted.objectlib.touchcontrol.TouchControlOctahedron;
31

    
32
import java.io.InputStream;
33

    
34
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_OCTAHEDRON;
35
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
public class TwistyTrajber extends ShapeOctahedron
40
{
41
  // each cut is at 1/5 of the length of the segment from the center to a vertex.
42
  private static final float CUT = 0.2f;
43
  private static final float LEN = 1.5f;
44

    
45
  // the three rotation axis of a 3x3x3 cube. Must be normalized.
46
  static final Static3D[] ROT_AXIS = new Static3D[]
47
         {
48
         new Static3D(SQ2/2, 0, SQ2/2),
49
         new Static3D(    0, 1,     0),
50
         new Static3D(SQ2/2, 0,-SQ2/2)
51
         };
52

    
53
  private static final int[] mQuatIndices = new int[] {13,12,8,9,0,1, 15,10,14,11, 0,1,3,2, 8,9,5,4, 0,8,9,1,15,2,3,6};
54

    
55
  private int[][] mFaceColorMap, mEdgeColorMap, mCornerColorMap;
56
  private ScrambleState[] mStates;
57
  private int[] mBasicAngle;
58
  private int[] mFaceMap;
59
  private float[][] mCuts;
60
  private Static4D[] mQuats;
61
  private float[][] mCenters;
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

    
65
  public TwistyTrajber(int[] numL, int meshState, Static4D quat, Static3D move, float scale, InputStream stream)
66
    {
67
    super(numL, meshState, numL[0], quat, move, scale, stream);
68
    }
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  public ScrambleState[] getScrambleStates()
73
    {
74
    if( mStates==null )
75
      {
76
      int[][] m = new int[16][];
77

    
78
      for(int i=0; i<16; i++) m[i] = new int[] { 0,-1,i,0,1,i,0,2,i, 1,-1,i,1,1,i,1,2,i, 2,-1,i,2,1,i,2,2,i};
79

    
80
      mStates = new ScrambleState[]
81
          {
82
          new ScrambleState( new int[][] { m[ 1], m[ 2], m[ 3] } ),  //  0 0
83
          new ScrambleState( new int[][] {  null, m[ 4], m[ 5] } ),  //  1 x
84
          new ScrambleState( new int[][] { m[ 6],  null, m[ 7] } ),  //  2 y
85
          new ScrambleState( new int[][] { m[ 8], m[ 9],  null } ),  //  3 z
86
          new ScrambleState( new int[][] { m[10],  null, m[ 7] } ),  //  4 xy
87
          new ScrambleState( new int[][] { m[11], m[ 9],  null } ),  //  5 xz
88
          new ScrambleState( new int[][] {  null, m[12], m[ 5] } ),  //  6 yx
89
          new ScrambleState( new int[][] { m[ 8], m[13],  null } ),  //  7 yz
90
          new ScrambleState( new int[][] {  null, m[ 4], m[14] } ),  //  8 zx
91
          new ScrambleState( new int[][] { m[ 6],  null, m[15] } ),  //  9 zy
92
          new ScrambleState( new int[][] {  null,  null, m[ 5] } ),  // 10 xyx
93
          new ScrambleState( new int[][] {  null, m[ 4],  null } ),  // 11 xzx
94
          new ScrambleState( new int[][] {  null,  null, m[ 7] } ),  // 12 yxy
95
          new ScrambleState( new int[][] { m[ 6],  null,  null } ),  // 13 yzy
96
          new ScrambleState( new int[][] {  null, m[ 9],  null } ),  // 14 zxz
97
          new ScrambleState( new int[][] { m[ 8],  null,  null } ),  // 15 zyz
98
          };
99
      }
100

    
101
    return mStates;
102
    }
103

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

    
106
  private void initializeQuats()
107
    {
108
    mQuats = new Static4D[]
109
         {
110
         new Static4D(  0.0f,   0.0f,   0.0f,   1.0f),  // 0  nothing
111
         new Static4D( SQ2/2,   0.0f,  SQ2/2,   0.0f),  // 1  ( 1, 0,-1) 180
112
         new Static4D(  0.0f,   1.0f,   0.0f,   0.0f),  // 2  ( 0, 1, 0) 180
113
         new Static4D( SQ2/2,   0.0f, -SQ2/2,   0.0f),  // 3  ( 1, 0, 1) 180
114

    
115
         new Static4D(  0.5f,  SQ2/2,  -0.5f,   0.0f),  // 4 (0.5,SQ2/2,0.5) 180
116
         new Static4D(  0.5f, -SQ2/2,  -0.5f,   0.0f),  // 5 (0.5,-SQ2/2,-0.5) 180
117
         new Static4D(  1.0f,   0.0f,   0.0f,   0.0f),  // 6 (1,0,0) 180
118
         new Static4D(  0.0f,   0.0f,   1.0f,   0.0f),  // 7 (0,0,1) 180
119
         new Static4D(  0.5f,   0.0f,   0.5f,  SQ2/2),  // 8  ( 1, 0, 1) +-90
120
         new Static4D(  0.5f,   0.0f,   0.5f, -SQ2/2),  // 9  ( 1, 0, 1) -+90
121
         new Static4D(  0.5f,  SQ2/2,   0.5f,   0.0f),  // 10 (-0.5,-SQ2/2,-0.5) 180
122
         new Static4D(  0.5f, -SQ2/2,   0.5f,   0.0f),  // 11 (0.5,-SQ2/2,0.5) 180
123
         new Static4D(  0.0f,  SQ2/2,   0.0f,  SQ2/2),  // 12  ( 0, 1, 0) +-90
124
         new Static4D(  0.0f,  SQ2/2,   0.0f, -SQ2/2),  // 13  ( 0, 1, 0) -+90
125
         new Static4D(  0.5f,   0.0f,  -0.5f, -SQ2/2),  // 15  ( 1, 0,-1) -+90
126
         new Static4D(  0.5f,   0.0f,  -0.5f,  SQ2/2),  // 14  ( 1, 0,-1) +-90
127

    
128
         new Static4D( SQ2/2,   0.5f,   0.0f,   0.5f),  // 16 (+,+,0) +
129
         new Static4D(  0.0f,  -0.5f,  SQ2/2,  -0.5f),  // 17 (0,-,+) -
130
         new Static4D(  0.0f,   0.5f, -SQ2/2,  -0.5f),  // 18 (0,+,-) -
131
         new Static4D( SQ2/2,  -0.5f,   0.0f,  -0.5f),  // 19 (+,-,0) -
132
         new Static4D(-SQ2/2,  -0.5f,   0.0f,   0.5f),  // 20 (-,-,0) +
133
         new Static4D( SQ2/2,  -0.5f,   0.0f,   0.5f),  // 21 (+,-,0) +
134
         new Static4D(  0.0f,  -0.5f, -SQ2/2,   0.5f),  // 22 (0,-,-) +
135
         new Static4D(  0.0f,  -0.5f, -SQ2/2,  -0.5f),  // 23 (0,-,-) -
136
         };
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  public int[] getSolvedQuats(int cubit, int[] numLayers)
142
    {
143
    if( mQuats==null ) initializeQuats();
144
    if( mFaceMap==null ) mFaceMap = new int[] {4,0,6,2,7,3,5,1};
145
    int status = retCubitSolvedStatus(cubit,numLayers);
146
    return status<0 ? null : buildSolvedQuats(TouchControlOctahedron.FACE_AXIS[mFaceMap[status]],mQuats);
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  public Static4D[] getQuats()
152
    {
153
    if( mQuats==null ) initializeQuats();
154
    return mQuats;
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  public int getSolvedFunctionIndex()
160
    {
161
    return 0;
162
    }
163

    
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

    
166
  public float[][] getCuts(int[] numLayers)
167
    {
168
    if( mCuts==null )
169
      {
170
      final float cut= CUT*LEN*SQ2;
171
      mCuts = new float[][] { {-cut,+cut},{-cut,+cut},{-cut,+cut} };
172
      }
173

    
174
    return mCuts;
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  public boolean[][] getLayerRotatable(int[] numLayers)
180
    {
181
    int numAxis = ROT_AXIS.length;
182
    boolean[][] layerRotatable = new boolean[numAxis][];
183

    
184
    for(int i=0; i<numAxis; i++)
185
      {
186
      layerRotatable[i] = new boolean[numLayers[i]];
187
      for(int j=0; j<numLayers[i]; j++) layerRotatable[i][j] = true;
188
      }
189

    
190
    return layerRotatable;
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  public int getTouchControlType()
196
    {
197
    return TC_OCTAHEDRON;
198
    }
199

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  public int getTouchControlSplit()
203
    {
204
    return TYPE_NOT_SPLIT;
205
    }
206

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

    
209
  public int[][][] getEnabled()
210
    {
211
    return new int[][][]
212
      {
213
          {{0,1,2}},{{0,1,2}},{{0,1,2}},{{0,1,2}},{{0,1,2}},{{0,1,2}},{{0,1,2}},{{0,1,2}}
214
      };
215
    }
216

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

    
219
  public float[] getDist3D(int[] numLayers)
220
    {
221
    return null;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  public int getNumCubitFaces()
227
    {
228
    return 9;
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  public float[][] getCubitPositions(int[] numLayers)
234
    {
235
    if( mCenters==null )
236
      {
237
      mCenters = new float[][]
238
          {
239
              {   LEN,       0,   LEN},
240
              {  -LEN,       0,  -LEN},
241
              {     0, SQ2*LEN,     0},
242
              {     0,-SQ2*LEN,     0},
243
              {  -LEN,       0,   LEN},
244
              {   LEN,       0,  -LEN},
245

    
246
              {-LEN/2, (SQ2/2)*LEN, LEN/2},
247
              { LEN/2, (SQ2/2)*LEN,-LEN/2},
248
              {-LEN/2,-(SQ2/2)*LEN, LEN/2},
249
              { LEN/2,-(SQ2/2)*LEN,-LEN/2},
250
              {     0,     0,   LEN},
251
              {   LEN,     0,     0},
252
              {  -LEN,     0,     0},
253
              {     0,     0,  -LEN},
254
              { LEN/2, (SQ2/2)*LEN, LEN/2},
255
              { LEN/2,-(SQ2/2)*LEN, LEN/2},
256
              {-LEN/2, (SQ2/2)*LEN,-LEN/2},
257
              {-LEN/2,-(SQ2/2)*LEN,-LEN/2},
258

    
259
              {       0, SQ2*LEN/3, 2*LEN/3},
260
              { 2*LEN/3, SQ2*LEN/3,       0},
261
              {       0,-SQ2*LEN/3, 2*LEN/3},
262
              { 2*LEN/3,-SQ2*LEN/3,       0},
263
              {-2*LEN/3, SQ2*LEN/3,       0},
264
              {       0, SQ2*LEN/3,-2*LEN/3},
265
              {-2*LEN/3,-SQ2*LEN/3,       0},
266
              {       0,-SQ2*LEN/3,-2*LEN/3},
267
          };
268
      }
269

    
270
    return mCenters;
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

    
275
  public ObjectShape getObjectShape(int variant)
276
    {
277
    if( variant==0 )
278
      {
279
      final float A = SQ2*CUT*LEN;
280
      final float B =     CUT*LEN;
281

    
282
      float[][] vertices =
283
          {
284
             {    0,    0,    0},
285
             {    B,    A,   -B},
286
             {    B,   -A,   -B},
287
             {  2*B,    0,    0},
288
             {    0,    0, -2*B},
289
             {  3*B,    A,   -B},
290
             {  3*B,   -A,   -B},
291
             {    B,    A, -3*B},
292
             {    B,   -A, -3*B},
293

    
294
             {  LEN      ,    A, SQ2*A-LEN},
295
             {  LEN      ,   -A, SQ2*A-LEN},
296
             {  LEN-SQ2*A,    A,      -LEN},
297
             {  LEN-SQ2*A,   -A,      -LEN}
298
          };
299

    
300
      int[][] indices =
301
          {
302
             {0,3,5,1},
303
             {0,2,6,3},
304
             {0,4,8,2},
305
             {0,1,7,4},
306
             {3,6,10,9,5},
307
             {2,8,12,10,6},
308
             {4,7,11,12,8},
309
             {1,5,9,11,7},
310
             {9,10,12,11}
311
          };
312

    
313
      return new ObjectShape(vertices, indices, 4);
314
      }
315
    if( variant==1 )
316
      {
317
      final float A = SQ2*CUT*LEN;
318
      final float B = LEN-2*LEN*CUT;
319
      final float C = (SQ2/2)*A;
320

    
321
      float[][] vertices =
322
          {
323
             {    -B, 0,  0 },
324
             {  -B+C, A, -C },
325
             {  -B+C,-A, -C },
326
             {     B, 0,  0 },
327
             {   B-C, A, -C },
328
             {   B-C,-A, -C },
329
             {     0, A, -B },
330
             {     0,-A, -B },
331
          };
332

    
333
      int[][] indices =
334
          {
335
             {0,3,4,1},
336
             {0,2,5,3},
337
             {1,4,6},
338
             {2,7,5},
339
             {0,1,6,7,2},
340
             {3,5,7,6,4}
341
          };
342

    
343
      return new ObjectShape(vertices, indices, 2);
344
      }
345
    else
346
      {
347
      final float L = LEN-3*LEN*CUT;
348

    
349
      float[][] vertices =
350
          {
351
             { -L, -(SQ2/3)*L,   L/3 },
352
             {  L, -(SQ2/3)*L,   L/3 },
353
             {  0,(2*SQ2/3)*L,-2*L/3 },
354
             {  0, -(SQ2/3)*L,-2*L/3 },
355
          };
356

    
357
      int[][] indices =
358
          {
359
             {0,1,2},
360
             {0,1,3},
361
             {0,2,3},
362
             {1,3,2},
363
          };
364

    
365
      return new ObjectShape(vertices, indices, 1);
366
      }
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

    
371
  public ObjectFaceShape getObjectFaceShape(int variant)
372
    {
373
    if( variant==0 )
374
      {
375
      float[][] bands     = { {0.05f,35,0.15f,0.3f,4,1,1},{0.00f,35,0.15f,0.3f,4,1,1} };
376
      int[] bandIndices   = { 0,0,0,0,1,1,1,1,1 };
377
      float[][] corners   = { {0.03f,0.10f} };
378
      int[] cornerIndices = { 0,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1 };
379
      float[][] centers   = { { LEN/2, 0.0f, -LEN/2} };
380
      int[] centerIndices = { 0,-1,-1,-1,-1,0,0,0,0,-1,-1,-1,-1 };
381
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
382
      }
383
    if( variant==1 )
384
      {
385
      final float B = LEN-2*LEN*CUT;
386
      float[][] bands     = { {0.03f,35,0.15f,0.3f,3,1,1},{0.00f,35,0.15f,0.3f,3,1,1} };
387
      int[] bandIndices   = { 0,0,1,1,1,1 };
388
      float[][] corners   = { {0.02f,0.10f} };
389
      int[] cornerIndices = { 0,0,0,0,0,0,-1,-1 };
390
      float[][] centers   = { { 0, 0, -B} };
391
      int[] centerIndices = { 0,0,0,0,0,0,-1,-1 };
392
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
393
      }
394
    else
395
      {
396
      final float L = LEN-3*LEN*CUT;
397
      float[][] bands     = { {0.03f,35,0.15f,0.3f,4,1,1},{0.00f,35,0.15f,0.3f,4,0,0} };
398
      int[] bandIndices   = { 0,1,1,1 };
399
      float[][] corners   = { {0.02f,0.10f} };
400
      int[] cornerIndices = { 0,0,0,-1 };
401
      float[][] centers   = { {0, -(SQ2/3)*L,-2*L/3} };
402
      int[] centerIndices = { 0,0,0,-1 };
403
      return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
404
      }
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  public Static4D getQuat(int cubit, int[] numLayers)
410
    {
411
    if( mQuats==null ) initializeQuats();
412
    return mQuats[mQuatIndices[cubit]];
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public int getNumCubitVariants(int[] numLayers)
418
    {
419
    return 3;
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

    
424
  public int getCubitVariant(int cubit, int[] numLayers)
425
    {
426
    return cubit<6 ? 0 : cubit<18 ? 1 : 2;
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public int getCubitFaceColor(int cubit, int face, int[] numLayers)
432
    {
433
    int variant = getCubitVariant(cubit,numLayers);
434

    
435
    if( mFaceColorMap==null)
436
      {
437
      mFaceColorMap = new int[][] { {1,5,4,0},{3,7,6,2},{1,0,3,2},{4,5,6,7},{0,4,7,3},{5,1,2,6} };
438
      }
439

    
440
    if( mEdgeColorMap==null)
441
      {
442
      mEdgeColorMap = new int[][] { {3,0},{1,2},{4,7},{6,5}, {0,4},{5,1},{7,3},{2,6}, {1,0},{4,5},{3,2},{6,7} };
443
      }
444

    
445
    if( mCornerColorMap==null)
446
      {
447
      mCornerColorMap = new int[][] { {0},{1},{4},{5},{3},{2},{7},{6} };
448
      }
449

    
450
    switch(variant)
451
      {
452
      case 0: return face<4 ? mFaceColorMap[cubit][face]     :-1;
453
      case 1: return face<2 ? mEdgeColorMap[cubit-6][face]   :-1;
454
      case 2: return face<1 ? mCornerColorMap[cubit-18][face]:-1;
455
      }
456

    
457
    return 0;
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

    
462
  public float getStickerRadius()
463
    {
464
    return 0.12f;
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  public float getStickerStroke()
470
    {
471
    return ObjectControl.isInIconMode() ? 0.20f : 0.10f;
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public float[][] getStickerAngles()
477
    {
478
    return null;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482
// PUBLIC API
483

    
484
  public Static3D[] getRotationAxis()
485
    {
486
    return ROT_AXIS;
487
    }
488

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

    
491
  public int[] getBasicAngle()
492
    {
493
    if( mBasicAngle ==null ) mBasicAngle = new int[] { 4,4,4 };
494
    return mBasicAngle;
495
    }
496

    
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498

    
499
  public ObjectType intGetObjectType(int[] numLayers)
500
    {
501
    return ObjectType.TRAJ_3;
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public String getObjectName()
507
    {
508
    return "Trajber's Octahedron";
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  public String getInventor()
514
    {
515
    return "Josef Trajber";
516
    }
517

    
518
///////////////////////////////////////////////////////////////////////////////////////////////////
519

    
520
  public int getYearOfInvention()
521
    {
522
    return 1982;
523
    }
524

    
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526

    
527
  public int getComplexity()
528
    {
529
    return 2;
530
    }
531
}
(25-25/26)