Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCamouflage.java @ 2dffaf22

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_CHANGING_MIRROR;
13

    
14
import org.distorted.library.effect.EffectName;
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
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.helpers.ObjectVertexEffects;
21
import org.distorted.objectlib.main.InitData;
22
import org.distorted.objectlib.main.ObjectSignatures;
23
import org.distorted.objectlib.main.ObjectType;
24

    
25
import java.io.InputStream;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
public class TwistyCamouflage extends TwistyBandagedAbstract
30
{
31
  private static final float SIZE_CORRECTION = 1.18f;
32

    
33
  public static final float[][] CAM_333 = new float[][]
34
    {
35
      getCenters( -1.0f, 1.0f, 1.0f, 2, 2, 2),
36

    
37
      getCenters(  0.5f, 1.0f, 1.0f, 1, 2, 2),
38
      getCenters(  1.5f, 1.0f, 1.0f, 1, 2, 2),
39
      getCenters( -1.0f,-0.5f, 1.0f, 2, 1, 2),
40
      getCenters( -1.0f,-1.5f, 1.0f, 2, 1, 2),
41
      getCenters( -1.0f, 1.0f,-0.5f, 2, 2, 1),
42
      getCenters( -1.0f, 1.0f,-1.5f, 2, 2, 1),
43

    
44
      getCenters( -1.0f,-1.5f,-0.5f, 2, 1, 1),
45
      getCenters( -1.0f,-1.5f,-1.5f, 2, 1, 1),
46
      getCenters( -1.5f,-0.5f,-0.5f, 1, 1, 1), // center
47
      getCenters( -1.0f,-0.5f,-1.5f, 2, 1, 1),
48
      getCenters(  0.5f, 1.0f,-1.5f, 1, 2, 1),
49
      getCenters(  1.5f, 1.0f,-1.5f, 1, 2, 1),
50
      getCenters(  0.5f, 1.5f,-0.5f, 1, 1, 1), // center
51
      getCenters(  1.5f, 1.0f,-0.5f, 1, 2, 1),
52
      getCenters(  0.5f,-0.5f, 1.5f, 1, 1, 1), // center
53
      getCenters(  1.5f,-0.5f, 1.0f, 1, 1, 2),
54
      getCenters(  0.5f,-1.5f, 1.0f, 1, 1, 2),
55
      getCenters(  1.5f,-1.5f, 1.0f, 1, 1, 2),
56

    
57
      getCenters(  0.5f,-0.5f,-1.5f, 1, 1, 1),
58
      getCenters(  1.5f,-0.5f,-1.5f, 1, 1, 1),
59
      getCenters(  0.5f,-1.5f,-1.5f, 1, 1, 1),
60
      getCenters(  1.5f,-1.5f,-1.5f, 1, 1, 1),
61
      getCenters(  0.5f,-1.5f,-0.5f, 1, 1, 1),
62
      getCenters(  1.5f,-0.5f,-0.5f, 1, 1, 1),
63
      getCenters(  1.5f,-1.5f,-0.5f, 1, 1, 1),
64
    };
65

    
66
  private static final int[][] DIMS = new int[][]
67
    {
68
      {2,2,2},
69
      {1,2,2},
70
      {2,1,2},
71
      {2,2,1},
72
      {2,1,1},
73
      {1,2,1},
74
      {1,1,2},
75
      {1,1,1},
76
    };
77

    
78
  private static final float[][] OFFSETS = new float[][]
79
    {
80
      { 0.0f, 0.0f, 0.0f},
81
      { 0.5f, 0.0f, 0.0f},
82
      {-0.5f, 0.0f, 0.0f},
83
      { 0.0f, 0.5f, 0.0f},
84
      { 0.0f,-0.5f, 0.0f},
85
      { 0.0f, 0.0f, 0.5f},
86
      { 0.0f, 0.0f,-0.5f},
87
      { 0.0f,-0.5f,-0.5f},
88
      { 0.5f, 0.0f,-0.5f},
89
      { 0.5f,-0.5f, 0.0f},
90
      { 0.5f,-0.5f,-0.5f},
91
    };
92

    
93
  private int[] mDimsIndices, mOffsIndices;
94
  private int[][] mEdges;
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  private static float[] getCenters( float x, float y, float z, int xd, int yd, int zd )
99
    {
100
    float XS = 0.5f*(1-xd) + x;
101
    float YS = 0.5f*(1-yd) + y;
102
    float ZS = 0.5f*(1-zd) + z;
103

    
104
    int index=0;
105
    float[] result = new float[3*xd*yd*zd];
106

    
107
    for(int i=0; i<xd; i++)
108
      for(int j=0; j<yd; j++)
109
        for(int k=0; k<zd; k++)
110
          {
111
          result[3*index  ] = XS+i;
112
          result[3*index+1] = YS+j;
113
          result[3*index+2] = ZS+k;
114
          index++;
115
          }
116

    
117
    return result;
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  public TwistyCamouflage(InitData data, int meshState, int iconMode, Static4D quat, Static3D move, float scale, InputStream stream)
123
    {
124
    super(data, meshState, iconMode, SIZE_CORRECTION*(data.getNumLayers()[0]+data.getNumLayers()[1]+data.getNumLayers()[2])/3.0f, quat, move, scale, stream);
125
    }
126

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

    
129
  @Override
130
  public int getInternalColor()
131
    {
132
    return 0xff333333;
133
    }
134

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

    
137
  @Override
138
  public int getScrambleType()
139
    {
140
    return 0;
141
    }
142

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

    
145
  public int[][] getScrambleEdges()
146
    {
147
    if( mEdges==null )
148
      {
149
      mEdges = new int[][]
150
        {
151
          {0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0}
152
        };
153
      }
154

    
155
    return mEdges;
156
    }
157

    
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

    
160
  @Override
161
  public int[][] getScrambleAlgorithms()
162
    {
163
    return new int[][]
164
      {
165
        // VTS' algorithm1: ('swap 2 edges and 2 pairs of centers')
166
        {2, 1, 1,  1, 0, 1,  0, 2, 1,  1, 0,-1,  0, 2,-1,
167
         1, 0, 1,  0, 2, 1,  1, 0,-1,  0, 2,-1,  2, 1,-1,
168
         0, 2, 1,  1, 0, 1,  0, 2,-1,  1, 0,-1,  0, 2, 1,
169
         1, 0, 1,  0, 2,-1,  1, 0,-1,  0, 2, 1,  0, 3, 1,
170
         1, 0, 2,  2, 0, 1,  1, 0,-2,  2, 0,-1,  1, 0, 2,
171
         0, 2,-1,  2, 1, 1,  0, 2, 1,  1, 0, 2,  2, 0, 1,
172
         1, 0,-2,  2, 0,-1,  1, 0, 2,  0, 2,-1,  2, 1,-2},
173

    
174
        // algorithm1 rotated around the corner
175
        {1, 1, 1,  0, 2,-1,  2, 0,-1,  0, 2, 1,  2, 0, 1,
176
         0, 2,-1,  2, 0,-1,  0, 2, 1,  2, 0, 1,  1, 1,-1,
177
         2, 0,-1,  0, 2,-1,  2, 0, 1,  0, 2, 1,  2, 0,-1,
178
         0, 2,-1,  2, 0, 1,  0, 2, 1,  2, 1,-1,  2, 0,-1,
179
         0, 2,-2,  1, 0, 1,  0, 2, 2,  1, 0,-1,  0, 2,-2,
180
         2, 0, 1,  1, 1, 1,  2, 0,-1,  0, 2,-2,  1, 0, 1,
181
         0, 2, 2,  1, 0,-1,  0, 2,-2,  2, 0, 1,  1, 1,-2},
182

    
183
        // algorithm1 rotated again around the corner
184
        {0, 2,-1,  2, 0, 1,  1, 0,-1,  2, 0,-1,  1, 0, 1,
185
         2, 0, 1,  1, 0,-1,  2, 0,-1,  1, 0, 1,  0, 2, 1,
186
         1, 0,-1,  2, 0, 1,  1, 0, 1,  2, 0,-1,  1, 0,-1,
187
         2, 0, 1,  1, 0, 1,  2, 0,-1,  1, 1,-1,  1, 0,-1,
188
         2, 0, 2,  0, 2,-1,  2, 0,-2,  0, 2, 1,  2, 0, 2,
189
         1, 0, 1,  0, 2,-1,  1, 0,-1,  2, 0, 2,  0, 2,-1,
190
         2, 0,-2,  0, 2, 1,  2, 0, 2,  1, 0, 1,  0, 2, 2},
191

    
192
       // VTS' algorithm2: swap two 221 edges
193
        {2, 2, 1,  1, 0, 1,  2, 2,-1,  1, 0,-1,  1, 2, 1,
194
         2, 2,-2,  0, 2,-1,  2, 2, 2,  0, 2, 1,  2, 2,-2,
195
         1, 2,-1,  0, 2,-1,  1, 2, 1,  2, 2,-2,  0, 2,-1,
196
         2, 2, 2,  0, 2, 1,  2, 2,-2,  1, 2,-1,  0, 2,-2,
197
         1, 0, 1,  2, 2, 1,  1, 0,-1,  2, 2, -1},
198

    
199
       // algorithm2 rotated around the corner
200
        {0, 0,-1,  2, 0, 1,  0, 0, 1,  2, 0,-1,  2, 2, 1,
201
         0, 0, 2,  1, 0, 1,  0, 0,-2,  1, 0,-1,  0, 0, 2,
202
         2, 2,-1,  1, 1, 1,  2, 2, 1,  0, 0, 2,  1, 0, 1,
203
         0, 0,-2,  1, 0,-1,  0, 0, 2,  2, 2,-1,  1, 1, 2,
204
         2, 0, 1,  0, 0,-1,  2, 0,-1,  0, 0, 1},
205

    
206
       // algorithm2 rotated again around the corner
207
        {1, 2, 1,  0, 2,-1,  1, 2,-1,  0, 2, 1,  0, 0,-1,
208
         1, 2,-2,  2, 0, 1,  1, 2, 2,  2, 0,-1,  1, 2,-2,
209
         0, 0, 1,  2, 1, 1,  0, 0,-1,  1, 2,-2,  2, 0, 1,
210
         1, 2, 2,  2, 0,-1,  1, 2,-2,  0, 0, 1,  2, 1, 2,
211
         0, 2,-1,  1, 2, 1,  0, 2, 1,  1, 2,-1},
212

    
213
       // VTS' algorithm3: swap two 221 blocks
214
        {2, 2,-2,  0, 2,-1,  2, 2, 2,  0, 2, 1,  2, 2,-2,
215
         1, 2,-1,  0, 2,-1,  1, 2, 1,  2, 2,-2,  0, 2,-1,
216
         2, 2, 2,  0, 2, 1,  2, 2,-2,  1, 2,-1,  0, 2, 2,
217
         1, 2, 1 },
218

    
219
       // algorithm3 rotated around the corner
220
        {0, 0,-2,  1, 0, 1,  0, 0,-2,  1, 0,-1,  0, 0, 2,
221
         2, 2,-1,  1, 1, 1,  2, 2, 1,  0, 0, 2,  1, 0, 1,
222
         0, 0,-2,  1, 0,-1,  0, 0, 2,  2, 2,-1,  1, 1,-2,
223
         2, 2, 1 },
224

    
225
       // algorithm3 rotated again around the corner
226
        {1, 2, 2,  2, 0, 1,  1, 2, 2,  2, 0,-1,  1, 2,-2,
227
         0, 0, 1,  2, 1, 1,  0, 0,-1,  1, 2,-2,  2, 0, 1,
228
         1, 2, 2,  2, 0,-1,  1, 2,-2,  0, 0, 1,  2, 1,-2,
229
         0, 0,-1 }
230
      };
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
  private int getDimsIndex(int variant)
236
    {
237
    if( mPosition==null ) mPosition = getInitData().getPos();
238

    
239
    if( mPosition==CAM_333 )
240
      {
241
      if( mDimsIndices==null ) mDimsIndices = new int[]
242
                                   { 0,
243
                                     1,0,2,0,3,0,
244
                                     3,0,7,2,1,0,7,3,7,2,1,0,
245
                                     6,2,1,0,5,4,3 };
246
      }
247

    
248
    return mDimsIndices[variant];
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  private int getOffsetsIndex(int variant)
254
    {
255
    if( mPosition==null ) mPosition = getInitData().getPos();
256

    
257
    if( mPosition==CAM_333 )
258
      {
259
      if( mOffsIndices==null ) mOffsIndices = new int[]
260
                                   { 0,
261
                                     0,1,0,4,0,6,
262
                                     4,7,0,6,6,8,0,1,0,1,4,9,
263
                                     6,8,7,10,4,1,9 };
264
      }
265

    
266
    return mOffsIndices[variant];
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  private float[][] getVertices(int variant)
272
    {
273
    int indexD = getDimsIndex(variant);
274

    
275
    int X=DIMS[indexD][0];
276
    int Y=DIMS[indexD][1];
277
    int Z=DIMS[indexD][2];
278

    
279
    int indexO = getOffsetsIndex(variant);
280

    
281
    float XF = OFFSETS[indexO][0];
282
    float YF = OFFSETS[indexO][1];
283
    float ZF = OFFSETS[indexO][2];
284

    
285
    return new float[][]
286
      {
287
        { 0.5f*X +XF, 0.5f*Y +YF, 0.5f*Z +ZF},
288
        { 0.5f*X +XF, 0.5f*Y +YF,-0.5f*Z +ZF},
289
        { 0.5f*X +XF,-0.5f*Y +YF, 0.5f*Z +ZF},
290
        { 0.5f*X +XF,-0.5f*Y +YF,-0.5f*Z +ZF},
291
        {-0.5f*X +XF, 0.5f*Y +YF, 0.5f*Z +ZF},
292
        {-0.5f*X +XF, 0.5f*Y +YF,-0.5f*Z +ZF},
293
        {-0.5f*X +XF,-0.5f*Y +YF, 0.5f*Z +ZF},
294
        {-0.5f*X +XF,-0.5f*Y +YF,-0.5f*Z +ZF}
295
      };
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299
// PUBLIC API
300

    
301
  public int getTouchControlType()
302
    {
303
    return TC_CHANGING_MIRROR;
304
    }
305

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

    
308
  public float[] getDist3D(int[] numLayers)
309
    {
310
    float x = numLayers[0];
311
    float y = numLayers[1];
312
    float z = numLayers[2];
313
    float a = SIZE_CORRECTION*(x+y+z)/1.5f;
314

    
315
    return new float[] {(x+2)/a,x/a,y/a,(y+2)/a,z/a,(z+2)/a};
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  public Static4D getCubitQuats(int cubit, int[] numLayers)
321
    {
322
    return mObjectQuats[0];
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  public ObjectShape getObjectShape(int variant)
328
    {
329
    int[][] indices =
330
        {
331
          {2,3,1,0},
332
          {7,6,4,5},
333
          {4,0,1,5},
334
          {7,3,2,6},
335
          {6,2,0,4},
336
          {3,7,5,1},
337
        };
338

    
339
    return new ObjectShape( getVertices(variant), indices);
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
  public ObjectFaceShape getObjectFaceShape(int variant)
345
    {
346
    int index = getDimsIndex(variant);
347

    
348
    int X = DIMS[index][0];
349
    int Y = DIMS[index][1];
350
    int Z = DIMS[index][2];
351

    
352
    float height     = isInIconMode() ? 0.001f : 0.03f;
353
    int[] bandIndices= { 0,0,1,1,2,2 };
354

    
355
    int maxXY = Math.max(X,Y);
356
    int maxXZ = Math.max(X,Z);
357
    int maxYZ = Math.max(Y,Z);
358

    
359
    int angle = 45;
360
    float R = 0.10f;
361
    float S = 0.25f;
362
    float N = 4;
363

    
364
    float[][] bands =
365
        {
366
          {height/maxYZ,angle,R,S,N,0,0},
367
          {height/maxXZ,angle,R,S,N,0,0},
368
          {height/maxXY,angle,R,S,N,0,0}
369
        };
370

    
371
    return new ObjectFaceShape(bands,bandIndices,null);
372
    }
373

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

    
376
  public ObjectVertexEffects getVertexEffects(int variant)
377
    {
378
    boolean round = false;
379
    float[][] vertices = getVertices(variant);
380
    float A = -0.03f;
381

    
382
    float[][] variables =
383
        {
384
          { 0, A, A, A, 1  },
385
          { 0, A, A,-A, 1  },
386
          { 0, A,-A, A, 1  },
387
          { 0, A,-A,-A, 1  },
388
          { 0,-A, A, A, 1  },
389
          { 0,-A, A,-A, 1  },
390
          { 0,-A,-A, A, 1  },
391
          { 0,-A,-A,-A, 1  },
392
        };
393

    
394
    String name = EffectName.DEFORM.name();
395
    float[] reg = {0,0,0,0.10f};
396

    
397
    String[] names = {name,name,name,name,name,name,name,name};
398
    float[][] regions = {reg,reg,reg,reg,reg,reg,reg,reg};
399
    boolean[] uses = {round,round,round,round,round,round,round,round};
400

    
401
    return new ObjectVertexEffects(names,variables,vertices,regions,uses);
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public int getCubitVariant(int cubit, int[] numLayers)
407
    {
408
    if( mPosition==null ) mPosition = getInitData().getPos();
409

    
410
    if( mPosition==CAM_333 )
411
      {
412
      return cubit;
413
      }
414

    
415
    return 0;
416
    }
417

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

    
420
  public int getNumCubitVariants(int[] numLayers)
421
    {
422
    if( mPosition==null ) mPosition = getInitData().getPos();
423

    
424
    if( mPosition==CAM_333 ) return 26;
425

    
426
    return 0;
427
    }
428

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

    
431
  public float getStickerRadius()
432
    {
433
    return 0.18f;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public float getStickerStroke()
439
    {
440
    return isInIconMode() ? 0.30f : 0.18f;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  public String getShortName()
446
    {
447
    if( mPosition==null ) mPosition = getInitData().getPos();
448

    
449
    if( mPosition==CAM_333 ) return ObjectType.CA_333.name();
450

    
451
    return null;
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  public ObjectSignature getSignature()
457
    {
458
    if( mSignature==null )
459
      {
460
      if( mPosition==null ) mPosition = getInitData().getPos();
461
      if( mPosition==CAM_333 ) mSignature = new ObjectSignature(ObjectSignatures.CA_333);
462
      }
463
    return mSignature;
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

    
468
  public String getObjectName()
469
    {
470
    if( mPosition==null ) mPosition = getInitData().getPos();
471

    
472
    if( mPosition==CAM_333 ) return "Camouflage 3x3x3";
473

    
474
    return "Camouflage";
475
    }
476

    
477
///////////////////////////////////////////////////////////////////////////////////////////////////
478

    
479
  public String getInventor()
480
    {
481
    return "Guan Yang";
482
    }
483

    
484
///////////////////////////////////////////////////////////////////////////////////////////////////
485

    
486
  public int getYearOfInvention()
487
    {
488
    return 2013;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

    
493
  public int getComplexity()
494
    {
495
    if( mPosition==null ) mPosition = getInitData().getPos();
496

    
497
    if( mPosition==CAM_333 ) return 4;
498

    
499
    return 0;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
  public String[][] getTutorials()
505
    {
506
    if( mPosition==null ) mPosition = getInitData().getPos();
507

    
508
    if( mPosition==CAM_333 )
509
      {
510
      return new String[][]{
511
                            {"gb","f9zmpCfg25k","3x3x3 Camouflage Part 1","Superantoniovivaldi"},
512
                            {"gb","O8pGyi5Juxk","3x3x3 Camouflage Part 2","Superantoniovivaldi"},
513
                            {"es","V1RPBIzEwp4","Tutorial 3x3 Camouflage","Manu rubiks"},
514
                            {"ru","DRGNOSw5pPc","Как собрать 3х3х3 camouflage","Илья Топор-Гилка"},
515
                            {"fr","9BfI1Fcbcl8","Résolution du Camouflage Cube","Skieur Cubb"},
516
                            {"pl","uEVvR2jDdI0","Camouflage 3x3x3 Tutorial","MrUK"},
517
                           };
518
      }
519

    
520
    return null;
521
    }
522
}
(4-4/41)