Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyWindmill.java @ 5d09301e

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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 java.io.InputStream;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.library.type.Static4D;
16

    
17
import org.distorted.objectlib.helpers.ObjectFaceShape;
18
import org.distorted.objectlib.helpers.ObjectShape;
19
import org.distorted.objectlib.helpers.ObjectSignature;
20
import org.distorted.objectlib.main.InitData;
21
import org.distorted.objectlib.scrambling.ScrambleState;
22
import org.distorted.objectlib.main.ObjectType;
23
import org.distorted.objectlib.main.ShapeHexahedron;
24
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
25

    
26
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CHANGING_SHAPEMOD;
27
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
public class TwistyWindmill extends ShapeHexahedron
32
{
33
  private static final float X = 1.8f;  // the cut goes from a corner and splits the opposing side 1.2 / 1.8
34
  private static final float L = (float)Math.sqrt(9+X*X);
35

    
36
  static final Static3D[] ROT_AXIS = new Static3D[]
37
         {
38
           new Static3D(  3/L, 0.0f, X/L),
39
           new Static3D( 0.0f, 1.0f,0.0f),
40
           new Static3D( -X/L, 0.0f, 3/L),
41
         };
42

    
43
  private ScrambleState[] mStates;
44
  private int[][] mBasicAngle;
45
  private float[][] mCuts;
46
  private float[][] mPositions;
47
  private int[] mQuatIndex;
48

    
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

    
51
  public TwistyWindmill(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
52
    {
53
    super(data, meshState, iconMode, data.getNumLayers()[0], quat, move, scale, stream);
54
    }
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

    
58
  @Override
59
  public int getInternalColor()
60
    {
61
    return 0xff333333;
62
    }
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
// same as in a 3x3
66

    
67
  public ScrambleState[] getScrambleStates()
68
    {
69
    if( mStates==null )
70
      {
71
      int[][] m = new int[16][];
72

    
73
      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};
74

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

    
96
    return mStates;
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  public float[][] getCuts(int[] numLayers)
102
    {
103
    if( mCuts==null )
104
      {
105
      float C = 3*SQ5/10;
106
      float[] cut = new float[] {-C,+C};
107
      mCuts = new float[][] { cut,cut,cut };
108
      }
109

    
110
    return mCuts;
111
    }
112

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

    
115
  public boolean[][] getLayerRotatable(int[] numLayers)
116
    {
117
    boolean[] tmp = new boolean[] {true,true,true};
118
    return new boolean[][] { tmp,tmp,tmp };
119
    }
120

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

    
123
  public int getTouchControlType()
124
    {
125
    return TC_CHANGING_SHAPEMOD;
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  public int getTouchControlSplit()
131
    {
132
    return TYPE_NOT_SPLIT;
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  public int[][][] getEnabled()
138
    {
139
    return null;
140
    }
141

    
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

    
144
  public float[] getDist3D(int[] numLayers)
145
    {
146
    return TouchControlHexahedron.D3D;
147
    }
148

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

    
151
  public Static3D[] getFaceAxis()
152
    {
153
    return TouchControlHexahedron.FACE_AXIS;
154
    }
155

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

    
158
  public float[][] getCubitPositions(int[] numLayers)
159
    {
160
    if( mPositions==null )
161
      {
162
      final float DIS1 = -X/2 + 1.5f;
163
      final float DIS2 = -X/2;
164

    
165
      mPositions = new float[][]
166
         {
167
             { DIS1, 1.0f, 1.5f },
168
             { 1.5f, 1.0f,-DIS1 },
169
             {-DIS1, 1.0f,-1.5f },
170
             {-1.5f, 1.0f, DIS1 },
171
             { DIS1, 0.0f, 1.5f },
172
             { 1.5f, 0.0f,-DIS1 },
173
             {-DIS1, 0.0f,-1.5f },
174
             {-1.5f, 0.0f, DIS1 },
175
             { DIS1,-1.0f, 1.5f },
176
             { 1.5f,-1.0f,-DIS1 },
177
             {-DIS1,-1.0f,-1.5f },
178
             {-1.5f,-1.0f, DIS1 },
179

    
180
             { DIS2, 1.0f, 1.5f },
181
             { 1.5f, 1.0f,-DIS2 },
182
             {-DIS2, 1.0f,-1.5f },
183
             {-1.5f, 1.0f, DIS2 },
184
             { DIS2, 0.0f, 1.5f },
185
             { 1.5f, 0.0f,-DIS2 },
186
             {-DIS2, 0.0f,-1.5f },
187
             {-1.5f, 0.0f, DIS2 },
188
             { DIS2,-1.0f, 1.5f },
189
             { 1.5f,-1.0f,-DIS2 },
190
             {-DIS2,-1.0f,-1.5f },
191
             {-1.5f,-1.0f, DIS2 },
192

    
193
             { 0.0f, 1.0f, 0.0f },
194
             { 0.0f,-1.0f, 0.0f },
195
         };
196
      }
197

    
198
    return mPositions;
199
    }
200

    
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

    
203
  public Static4D getCubitQuats(int cubit, int[] numLayers)
204
    {
205
    if( mQuatIndex==null ) mQuatIndex = new int[] { 0,6,5,4,0,6,5,4,0,6,5,4,
206
                                                    0,6,5,4,0,6,5,4,0,6,5,4,
207
                                                    0,0 };
208
    return mObjectQuats[mQuatIndex[cubit]];
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  public ObjectShape getObjectShape(int variant)
214
    {
215
    if( variant==0 )
216
      {
217
      final float h = 3*X*X/(X*X+9);
218
      final float d = h*X/3;
219
      final float l = X/2;
220

    
221
      float[][] vertices =
222
          {
223
             {  -l, 0.5f, 0.0f },
224
             {   l, 0.5f, 0.0f },
225
             {   l,-0.5f, 0.0f },
226
             {  -l,-0.5f, 0.0f },
227
             { d-l, 0.5f,   -h },
228
             { d-l,-0.5f,   -h },
229
          };
230

    
231
      int[][] indices =
232
          {
233
             { 3,2,1,0 },
234
             { 0,1,4 },
235
             { 5,2,3 },
236
             { 5,3,0,4 },
237
             { 2,5,4,1 },
238
          };
239

    
240
      return new ObjectShape(vertices, indices);
241
      }
242
    else if( variant==1 )
243
      {
244
      final float h = 3*X*X/(X*X+9);
245
      final float d = h*X/3;
246
      final float H = 3*h/X;
247
      final float l = (3-X)/2;
248

    
249
      float[][] vertices =
250
          {
251
             { -l, 0.5f, 0.0f },
252
             {  l, 0.5f, 0.0f },
253
             {  l,-0.5f, 0.0f },
254
             { -l,-0.5f, 0.0f },
255
             {h-l, 0.5f,  -H  },
256
             {d+l, 0.5f,  -h  },
257
             {d+l,-0.5f,  -h  },
258
             {h-l,-0.5f,  -H  }
259
          };
260

    
261
      int[][] indices =
262
          {
263
             { 3,2,1,0 },
264
             { 0,1,5,4 },
265
             { 7,6,2,3 },
266
             { 2,6,5,1 },
267
             { 6,7,4,5 },
268
             { 7,3,0,4 }
269
          };
270

    
271
      return new ObjectShape(vertices, indices);
272
      }
273
    else
274
      {
275
      final float h = 3*X*X/(X*X+9);
276
      final float H = 3*h/X;
277
      final float x = 1.5f-H;
278
      final float y = 1.5f-h;
279

    
280
      float[][] vertices =
281
          {
282
             { -y, 0.5f, x },
283
             {  x, 0.5f, y },
284
             {  x,-0.5f, y },
285
             { -y,-0.5f, x },
286
             { -x, 0.5f,-y },
287
             {  y, 0.5f,-x },
288
             {  y,-0.5f,-x },
289
             { -x,-0.5f,-y }
290
          };
291

    
292
      int[][] indices =
293
          {
294
             { 3,2,1,0 },
295
             { 0,1,5,4 },
296
             { 7,6,2,3 },
297
             { 2,6,5,1 },
298
             { 6,7,4,5 },
299
             { 7,3,0,4 }
300
          };
301

    
302
      return new ObjectShape(vertices, indices);
303
      }
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  public ObjectFaceShape getObjectFaceShape(int variant)
309
    {
310
    if( variant==0 )
311
      {
312
      final float h = 3*X*X/(X*X+9);
313
      final float d = h*X/3;
314
      final float l = X/2;
315
      float h1 = isInIconMode() ? 0.001f : 0.025f;
316
      float h2 = isInIconMode() ? 0.001f : 0.020f;
317

    
318
      float[][] bands   = { {h1,20,0.2f,0.4f,5,1,1}, {h2,20,0.2f,0.4f,5,1,1} };
319
      int[] bandIndices = { 0,0,0,1,1 };
320
      float[][] corners = { {0.04f,0.09f} };
321
      int[] indices     = { 0,0,0,0,-1,-1 };
322
      float[][] centers = { { d-l, 0.0f,-h } };
323
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
324
      }
325
    else if( variant==1 )
326
      {
327
      final float h = 3*X*X/(X*X+9);
328
      final float H = 3*h/X;
329
      final float l = (3-X)/2;
330
      float h1 = isInIconMode() ? 0.001f : 0.03f;
331
      float h2 = isInIconMode() ? 0.001f : 0.02f;
332

    
333
      float[][] bands   = { {h1,20,0.2f,0.4f,5,1,1}, {h2,20,0.2f,0.4f,5,1,1} };
334
      int[] bandIndices = { 0,0,0,1,1,1 };
335
      float[][] corners = { {0.03f,0.09f} };
336
      int[] indices     = { 0,0,0,0,-1,-1,-1,-1 };
337
      float[][] centers = { {h-l, 0.5f, -H } };
338
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
339
      }
340
    else
341
      {
342
      float h1 = isInIconMode() ? 0.001f : 0.05f;
343
      float h2 = isInIconMode() ? 0.001f : 0.04f;
344
      float[][] bands   = { {h1,35,0.25f,0.7f,5,1,0}, {h2,35,0.25f,0.7f,5,1,0} };
345
      int[] bandIndices = { 1,0,0,1,1,1 };
346
      float[][] corners = { {0.04f,0.12f} };
347
      int[] indices     = { 0,0,0,0,0,0,0,0 };
348
      float[][] centers = { {0.0f, 0.0f, 0.0f } };
349
      return new ObjectFaceShape(bands,bandIndices,corners,indices,centers,indices,null);
350
      }
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  public int getNumCubitVariants(int[] numLayers)
356
    {
357
    return 3;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public int getCubitVariant(int cubit, int[] numLayers)
363
    {
364
    return cubit<12 ? 0 : (cubit<24 ? 1:2);
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  public float getStickerRadius()
370
    {
371
    return 0.10f;
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  public float getStickerStroke()
377
    {
378
    return isInIconMode() ? 0.22f : 0.10f;
379
    }
380

    
381
///////////////////////////////////////////////////////////////////////////////////////////////////
382

    
383
  public float[][] getStickerAngles()
384
    {
385
    return null;
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389
// PUBLIC API
390

    
391
  public Static3D[] getRotationAxis()
392
    {
393
    return ROT_AXIS;
394
    }
395

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

    
398
  public int[][] getBasicAngles()
399
    {
400
    if( mBasicAngle ==null )
401
      {
402
      int num = getNumLayers()[0];
403
      int[] tmp = new int[num];
404
      for(int i=0; i<num; i++) tmp[i] = 4;
405
      mBasicAngle = new int[][] { tmp,tmp,tmp };
406
      }
407
    return mBasicAngle;
408
    }
409

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

    
412
  public String getShortName()
413
    {
414
    return ObjectType.WIND_3.name();
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

    
419
  public ObjectSignature getSignature()
420
    {
421
    return new ObjectSignature(ObjectType.WIND_3);
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  public String getObjectName()
427
    {
428
    return "Windmill Cube";
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  public String getInventor()
434
    {
435
    return "Katsuhiko Okamoto";
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public int getYearOfInvention()
441
    {
442
    return 2003;
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  public int getComplexity()
448
    {
449
    return 2;
450
    }
451

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

    
454
  public String[][] getTutorials()
455
    {
456
    return new String[][]{
457
                          {"gb","Jh8Bg7gT3PI","Windmill Cube Tutorial","Cube Solve Hero"},
458
                          {"es","wVyJs7AboKk","Como resolver Windmill","Tutoriales Rubik"},
459
                          {"ru","vavVAuEplKI","Как собрать Мельницу","Алексей Ярыгин"},
460
                          {"fr","qiVsyF1nn7o","Résolution du Windmill Cube","asthalis"},
461
                          {"de","JCYcAd0iCKk","Windmill Cube Tutorial","Pezcraft"},
462
                          {"pl","GZI_PtcURaA","Windmill TUTORIAL PL","MrUk"},
463
                          {"br","TXNVMp70lVE","Resolução do Windmill Cube","Pedro Filho"},
464
                          {"kr","gELuvKW2Itw","윈드밀  큐브 해법 강좌","굿맨's 큐브 이야기"},
465
                          {"vn","diiy8OqqtrE","Tutorial N.16 - Windmill Cube","Duy Thích Rubik"},
466
                         };
467
    }
468
}
(36-36/36)