Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyCamouflage.java @ 539b46ea

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.ObjectType;
23

    
24
import java.io.InputStream;
25

    
26
///////////////////////////////////////////////////////////////////////////////////////////////////
27

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

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

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

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

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

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

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

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

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

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

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

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

    
116
    return result;
117
    }
118

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

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

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

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

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

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

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

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

    
154
    return mEdges;
155
    }
156

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

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

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

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

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

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

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

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

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

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

    
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233

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

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

    
247
    return mDimsIndices[variant];
248
    }
249

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

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

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

    
265
    return mOffsIndices[variant];
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

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

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

    
278
    int indexO = getOffsetsIndex(variant);
279

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

    
284
    return new float[][]
285
      {
286
        { 0.5f*X +XF, 0.5f*Y +YF, 0.5f*Z +ZF},
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
      };
295
    }
296

    
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
// PUBLIC API
299

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

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

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

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

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

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

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

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

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

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

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

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

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

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

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

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

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

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

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

    
381
    float[][] variables =
382
        {
383
          { 0, A, A, A, 1  },
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
        };
392

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

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

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

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

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

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

    
414
    return 0;
415
    }
416

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

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

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

    
425
    return 0;
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

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

    
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

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

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

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

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

    
450
    return null;
451
    }
452

    
453
///////////////////////////////////////////////////////////////////////////////////////////////////
454

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

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466

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

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

    
473
    return "Camouflage";
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

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

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

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

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

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

    
496
    if( mPosition==CAM_333 ) return 3;
497

    
498
    return 0;
499
    }
500

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

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

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

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