Project

General

Profile

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

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

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.InitAssets;
22
import org.distorted.objectlib.main.InitData;
23
import org.distorted.objectlib.main.ObjectSignatures;
24
import org.distorted.objectlib.main.ObjectType;
25
import org.distorted.objectlib.scrambling.ObjectScrambler;
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(int meshState, int iconMode, Static4D quat, Static3D move, float scale, InitData data, InitAssets asset)
123
    {
124
    super(meshState, iconMode, SIZE_CORRECTION*(data.getNumLayers()[0]+data.getNumLayers()[1]+data.getNumLayers()[2])/3.0f,
125
          quat, move, scale, data, asset);
126
    }
127

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

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

    
136
///////////////////////////////////////////////////////////////////////////////////////////////////
137

    
138
  public int[][] getScrambleEdges()
139
    {
140
    if( mEdges==null )
141
      {
142
      mEdges = new int[][]
143
        {
144
          {0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0}
145
        };
146
      }
147

    
148
    return mEdges;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  @Override
154
  public int[][] getScrambleAlgorithms()
155
    {
156
    return new int[][]
157
      {
158
        // VTS' algorithm1: ('swap 2 edges and 2 pairs of centers')
159
        {2, 1, 1,  1, 0, 1,  0, 2, 1,  1, 0,-1,  0, 2,-1,
160
         1, 0, 1,  0, 2, 1,  1, 0,-1,  0, 2,-1,  2, 1,-1,
161
         0, 2, 1,  1, 0, 1,  0, 2,-1,  1, 0,-1,  0, 2, 1,
162
         1, 0, 1,  0, 2,-1,  1, 0,-1,  0, 2, 1,  0, 3, 1,
163
         1, 0, 2,  2, 0, 1,  1, 0,-2,  2, 0,-1,  1, 0, 2,
164
         0, 2,-1,  2, 1, 1,  0, 2, 1,  1, 0, 2,  2, 0, 1,
165
         1, 0,-2,  2, 0,-1,  1, 0, 2,  0, 2,-1,  2, 1,-2},
166

    
167
        // algorithm1 rotated around the corner
168
        {1, 1, 1,  0, 2,-1,  2, 0,-1,  0, 2, 1,  2, 0, 1,
169
         0, 2,-1,  2, 0,-1,  0, 2, 1,  2, 0, 1,  1, 1,-1,
170
         2, 0,-1,  0, 2,-1,  2, 0, 1,  0, 2, 1,  2, 0,-1,
171
         0, 2,-1,  2, 0, 1,  0, 2, 1,  2, 1,-1,  2, 0,-1,
172
         0, 2,-2,  1, 0, 1,  0, 2, 2,  1, 0,-1,  0, 2,-2,
173
         2, 0, 1,  1, 1, 1,  2, 0,-1,  0, 2,-2,  1, 0, 1,
174
         0, 2, 2,  1, 0,-1,  0, 2,-2,  2, 0, 1,  1, 1,-2},
175

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

    
185
       // VTS' algorithm2: swap two 221 edges
186
        {2, 2, 1,  1, 0, 1,  2, 2,-1,  1, 0,-1,  1, 2, 1,
187
         2, 2,-2,  0, 2,-1,  2, 2, 2,  0, 2, 1,  2, 2,-2,
188
         1, 2,-1,  0, 2,-1,  1, 2, 1,  2, 2,-2,  0, 2,-1,
189
         2, 2, 2,  0, 2, 1,  2, 2,-2,  1, 2,-1,  0, 2,-2,
190
         1, 0, 1,  2, 2, 1,  1, 0,-1,  2, 2, -1},
191

    
192
       // algorithm2 rotated around the corner
193
        {0, 0,-1,  2, 0, 1,  0, 0, 1,  2, 0,-1,  2, 2, 1,
194
         0, 0, 2,  1, 0, 1,  0, 0,-2,  1, 0,-1,  0, 0, 2,
195
         2, 2,-1,  1, 1, 1,  2, 2, 1,  0, 0, 2,  1, 0, 1,
196
         0, 0,-2,  1, 0,-1,  0, 0, 2,  2, 2,-1,  1, 1, 2,
197
         2, 0, 1,  0, 0,-1,  2, 0,-1,  0, 0, 1},
198

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

    
206
       // VTS' algorithm3: swap two 221 blocks
207
        {2, 2,-2,  0, 2,-1,  2, 2, 2,  0, 2, 1,  2, 2,-2,
208
         1, 2,-1,  0, 2,-1,  1, 2, 1,  2, 2,-2,  0, 2,-1,
209
         2, 2, 2,  0, 2, 1,  2, 2,-2,  1, 2,-1,  0, 2, 2,
210
         1, 2, 1 },
211

    
212
       // algorithm3 rotated around the corner
213
        {0, 0,-2,  1, 0, 1,  0, 0,-2,  1, 0,-1,  0, 0, 2,
214
         2, 2,-1,  1, 1, 1,  2, 2, 1,  0, 0, 2,  1, 0, 1,
215
         0, 0,-2,  1, 0,-1,  0, 0, 2,  2, 2,-1,  1, 1,-2,
216
         2, 2, 1 },
217

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

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
  private int getDimsIndex(int variant)
229
    {
230
    if( mPosition==null ) mPosition = getInitData().getPos();
231

    
232
    if( mPosition==CAM_333 )
233
      {
234
      if( mDimsIndices==null ) mDimsIndices = new int[]
235
                                   { 0,
236
                                     1,0,2,0,3,0,
237
                                     3,0,7,2,1,0,7,3,7,2,1,0,
238
                                     6,2,1,0,5,4,3 };
239
      }
240

    
241
    return mDimsIndices[variant];
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  private int getOffsetsIndex(int variant)
247
    {
248
    if( mPosition==null ) mPosition = getInitData().getPos();
249

    
250
    if( mPosition==CAM_333 )
251
      {
252
      if( mOffsIndices==null ) mOffsIndices = new int[]
253
                                   { 0,
254
                                     0,1,0,4,0,6,
255
                                     4,7,0,6,6,8,0,1,0,1,4,9,
256
                                     6,8,7,10,4,1,9 };
257
      }
258

    
259
    return mOffsIndices[variant];
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
  private float[][] getVertices(int variant)
265
    {
266
    int indexD = getDimsIndex(variant);
267

    
268
    int X=DIMS[indexD][0];
269
    int Y=DIMS[indexD][1];
270
    int Z=DIMS[indexD][2];
271

    
272
    int indexO = getOffsetsIndex(variant);
273

    
274
    float XF = OFFSETS[indexO][0];
275
    float YF = OFFSETS[indexO][1];
276
    float ZF = OFFSETS[indexO][2];
277

    
278
    return new float[][]
279
      {
280
        { 0.5f*X +XF, 0.5f*Y +YF, 0.5f*Z +ZF},
281
        { 0.5f*X +XF, 0.5f*Y +YF,-0.5f*Z +ZF},
282
        { 0.5f*X +XF,-0.5f*Y +YF, 0.5f*Z +ZF},
283
        { 0.5f*X +XF,-0.5f*Y +YF,-0.5f*Z +ZF},
284
        {-0.5f*X +XF, 0.5f*Y +YF, 0.5f*Z +ZF},
285
        {-0.5f*X +XF, 0.5f*Y +YF,-0.5f*Z +ZF},
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
      };
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
// PUBLIC API
293

    
294
  public int getTouchControlType()
295
    {
296
    return TC_CHANGING_MIRROR;
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  public float[] getDist3D(int[] numLayers)
302
    {
303
    float x = numLayers[0];
304
    float y = numLayers[1];
305
    float z = numLayers[2];
306
    float a = SIZE_CORRECTION*(x+y+z)/1.5f;
307

    
308
    return new float[] {(x+2)/a,x/a,y/a,(y+2)/a,z/a,(z+2)/a};
309
    }
310

    
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312

    
313
  public Static4D getCubitQuats(int cubit, int[] numLayers)
314
    {
315
    return mObjectQuats[0];
316
    }
317

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

    
320
  public ObjectShape getObjectShape(int variant)
321
    {
322
    int[][] indices =
323
        {
324
          {2,3,1,0},
325
          {7,6,4,5},
326
          {4,0,1,5},
327
          {7,3,2,6},
328
          {6,2,0,4},
329
          {3,7,5,1},
330
        };
331

    
332
    return new ObjectShape( getVertices(variant), indices);
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  public ObjectFaceShape getObjectFaceShape(int variant)
338
    {
339
    int index = getDimsIndex(variant);
340

    
341
    int X = DIMS[index][0];
342
    int Y = DIMS[index][1];
343
    int Z = DIMS[index][2];
344

    
345
    float height     = isInIconMode() ? 0.001f : 0.03f;
346
    int[] bandIndices= { 0,0,1,1,2,2 };
347

    
348
    int maxXY = Math.max(X,Y);
349
    int maxXZ = Math.max(X,Z);
350
    int maxYZ = Math.max(Y,Z);
351

    
352
    int angle = 45;
353
    float R = 0.10f;
354
    float S = 0.25f;
355
    float N = 4;
356

    
357
    float[][] bands =
358
        {
359
          {height/maxYZ,angle,R,S,N,0,0},
360
          {height/maxXZ,angle,R,S,N,0,0},
361
          {height/maxXY,angle,R,S,N,0,0}
362
        };
363

    
364
    return new ObjectFaceShape(bands,bandIndices,null);
365
    }
366

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

    
369
  public ObjectVertexEffects getVertexEffects(int variant)
370
    {
371
    boolean round = false;
372
    float[][] vertices = getVertices(variant);
373
    float A = -0.03f;
374

    
375
    float[][] variables =
376
        {
377
          { 0, A, A, A, 1  },
378
          { 0, A, A,-A, 1  },
379
          { 0, A,-A, A, 1  },
380
          { 0, A,-A,-A, 1  },
381
          { 0,-A, A, A, 1  },
382
          { 0,-A, A,-A, 1  },
383
          { 0,-A,-A, A, 1  },
384
          { 0,-A,-A,-A, 1  },
385
        };
386

    
387
    String name = EffectName.DEFORM.name();
388
    float[] reg = {0,0,0,0.10f};
389

    
390
    String[] names = {name,name,name,name,name,name,name,name};
391
    float[][] regions = {reg,reg,reg,reg,reg,reg,reg,reg};
392
    boolean[] uses = {round,round,round,round,round,round,round,round};
393

    
394
    return new ObjectVertexEffects(names,variables,vertices,regions,uses);
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
  public int getCubitVariant(int cubit, int[] numLayers)
400
    {
401
    if( mPosition==null ) mPosition = getInitData().getPos();
402

    
403
    if( mPosition==CAM_333 )
404
      {
405
      return cubit;
406
      }
407

    
408
    return 0;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  public int getNumCubitVariants(int[] numLayers)
414
    {
415
    if( mPosition==null ) mPosition = getInitData().getPos();
416

    
417
    if( mPosition==CAM_333 ) return 26;
418

    
419
    return 0;
420
    }
421

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

    
424
  public float getStickerRadius()
425
    {
426
    return 0.18f;
427
    }
428

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

    
431
  public float getStickerStroke()
432
    {
433
    return isInIconMode() ? 0.30f : 0.18f;
434
    }
435

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

    
438
  public String getShortName()
439
    {
440
    if( mPosition==null ) mPosition = getInitData().getPos();
441

    
442
    if( mPosition==CAM_333 ) return ObjectType.CA_333.name();
443

    
444
    return null;
445
    }
446

    
447
///////////////////////////////////////////////////////////////////////////////////////////////////
448

    
449
  public ObjectSignature getSignature()
450
    {
451
    if( mSignature==null )
452
      {
453
      if( mPosition==null ) mPosition = getInitData().getPos();
454
      if( mPosition==CAM_333 ) mSignature = new ObjectSignature(ObjectSignatures.CA_333);
455
      }
456
    return mSignature;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public String getObjectName()
462
    {
463
    if( mPosition==null ) mPosition = getInitData().getPos();
464

    
465
    if( mPosition==CAM_333 ) return "Camouflage 3x3x3";
466

    
467
    return "Camouflage";
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  public String getInventor()
473
    {
474
    return "Guan Yang";
475
    }
476

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

    
479
  public int getYearOfInvention()
480
    {
481
    return 2013;
482
    }
483

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

    
486
  public int getComplexity()
487
    {
488
    if( mPosition==null ) mPosition = getInitData().getPos();
489

    
490
    if( mPosition==CAM_333 ) return 4;
491

    
492
    return 0;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public String[][] getTutorials()
498
    {
499
    if( mPosition==null ) mPosition = getInitData().getPos();
500

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

    
513
    return null;
514
    }
515
}
(5-5/46)