Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyMirrorJing.java @ 962b8ff6

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
import static org.distorted.objectlib.touchcontrol.TouchControl.TYPE_NOT_SPLIT;
14

    
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17
import org.distorted.objectlib.helpers.FactoryCubit;
18
import org.distorted.objectlib.helpers.FactoryShape;
19
import org.distorted.objectlib.helpers.ObjectFaceShape;
20
import org.distorted.objectlib.helpers.ObjectShape;
21
import org.distorted.objectlib.helpers.ObjectVertexEffects;
22
import org.distorted.objectlib.main.InitAssets;
23
import org.distorted.objectlib.metadata.ListObjects;
24
import org.distorted.objectlib.metadata.Metadata;
25
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
26
import org.distorted.objectlib.shape.ShapeTetrahedron;
27
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
28

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

    
31
public class TwistyMirrorJing extends ShapeTetrahedron
32
{
33
  public static final Static3D[] ROT_AXIS = new Static3D[]
34
         {
35
           new Static3D(     0,-SQ3/3,-SQ6/3),
36
           new Static3D(     0,-SQ3/3, SQ6/3),
37
           new Static3D( SQ6/3, SQ3/3,     0),
38
           new Static3D(-SQ6/3, SQ3/3,     0),
39
         };
40

    
41
  private static final float JING_F = 0.48f;
42

    
43
  private static final int[] FACE_COLORS = new int[] { COLOR_WHITE };
44
  private static final float[] MIRROR_VEC = { 0.06f, 0.07f, 0.08f };
45

    
46
  private int[][] mEdges;
47
  private int[][] mBasicAngle;
48
  private float[][] mCuts;
49
  private float[][] mPositions;
50
  private ObjectShape[] mShapes;
51
  private float[][] mCutPlanes;
52
  private float[] mDist3D, mDist;
53
  private float[][] mPotentialVertices;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
  public TwistyMirrorJing(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
58
    {
59
    super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
60
    }
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
// here we cannot automatically detect the outer monochromatic walls -> use the old way.
64

    
65
  @Override
66
  public int getSolvedFunctionIndex()
67
    {
68
    return 0;
69
    }
70

    
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

    
73
  @Override
74
  public int[][] getSolvedQuats()
75
    {
76
    return getOldSolvedQuats();
77
    }
78

    
79
///////////////////////////////////////////////////////////////////////////////////////////////////
80

    
81
  @Override
82
  public int getInternalColor()
83
    {
84
    return 0xff333333;
85
    }
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  @Override
90
  public int[] getColorTable()
91
    {
92
    return FACE_COLORS;
93
    }
94

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

    
97
  @Override
98
  public float[][] returnRotationFactor()
99
    {
100
    float[] f = { 1.4f, 2.0f };
101
    return new float[][] { f,f,f,f };
102
    }
103

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

    
106
  public int[][] getScrambleEdges()
107
    {
108
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
109
    return mEdges;
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  public float[][] getCuts(int[] numLayers)
115
    {
116
    if( mCuts==null )
117
      {
118
      float[] c = new float[] { (JING_F-0.51f)*(SQ6/3) };
119
      mCuts = new float[][] {c,c,c,c};
120
      }
121

    
122
    return mCuts;
123
    }
124

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

    
127
  public boolean[][] getLayerRotatable(int[] numLayers)
128
    {
129
    boolean[] tmp = {true,true};
130
    return new boolean[][] { tmp,tmp,tmp,tmp };
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  public int getTouchControlType()
136
    {
137
    return TC_CHANGING_MIRROR;
138
    }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  public int getTouchControlSplit()
143
    {
144
    return TYPE_NOT_SPLIT;
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  public int[][][] getEnabled()
150
    {
151
    return null;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
// 'full' dists (not divided by numLayers)
156

    
157
  private float[] getDist()
158
    {
159
    if( mDist==null )
160
      {
161
      float DX = MIRROR_VEC[0];
162
      float DY = MIRROR_VEC[1];
163
      float DZ = MIRROR_VEC[2];
164
      Static3D[] axis = getFaceAxis();
165
      mDist = new float[4];
166

    
167
      for( int a=0; a<4; a++ )
168
        {
169
        Static3D ax = axis[a];
170
        float d = ax.get0()*DX + ax.get1()*DY + ax.get2()*DZ;
171
        mDist[a] = SQ6/6 + d;
172
        }
173
      }
174

    
175
    return mDist;
176
    }
177

    
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
// 'regular' dists for the touchControl (have to be divided by numLayers)
180

    
181
  public float[] getDist3D(int[] numLayers)
182
    {
183
    if( mDist3D==null )
184
      {
185
      float[] d = getDist();
186
      mDist3D = new float[] { d[0]/2, d[1]/2, d[2]/2, d[3]/2 };
187
      }
188

    
189
    return mDist3D;
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  public Static3D[] getFaceAxis()
195
    {
196
    return TouchControlTetrahedron.FACE_AXIS;
197
    }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  private float[][] getPositions()
202
    {
203
    if( mPositions==null )
204
      {
205
      final float X = MIRROR_VEC[0];
206
      final float Y = MIRROR_VEC[1];
207
      final float Z = MIRROR_VEC[2];
208

    
209
      mPositions = new float[][]
210
        {
211
          { 0.000f +X, -SQ2/2 +Y,  1.000f +Z },
212
          { 0.000f +X, -SQ2/2 +Y, -1.000f +Z },
213
          {-1.000f +X,  SQ2/2 +Y,  0.000f +Z },
214
          { 1.000f +X,  SQ2/2 +Y,  0.000f +Z },
215

    
216
          { 0.000f +X, -SQ2/2 +Y,  0.000f +Z },
217
          {-0.500f +X, 0.000f +Y,  0.500f +Z },
218
          { 0.500f +X, 0.000f +Y,  0.500f +Z },
219
          {-0.500f +X, 0.000f +Y, -0.500f +Z },
220
          { 0.500f +X, 0.000f +Y, -0.500f +Z },
221
          { 0.000f +X,  SQ2/2 +Y,  0.000f +Z },
222

    
223
          { 0.000f +X,  SQ2/6 +Y,  1.0f/3 +Z },
224
          { 0.000f +X,  SQ2/6 +Y, -1.0f/3 +Z },
225
          {-1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
226
          { 1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
227
        };
228
      }
229

    
230
    return mPositions;
231
    }
232

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

    
235
  public float[][] getCubitPositions(int[] numLayers)
236
    {
237
    return getPositions();
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  public Static4D getCubitQuats(int cubit, int[] numLayers)
243
    {
244
    return mObjectQuats[0];
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  private void createCutPlanes()
250
    {
251
    int numPlanes = 2*4;
252
    mCutPlanes = new float[numPlanes][];
253
    Static3D[] faceAxis = getFaceAxis();
254
    float[] dist = getDist();
255
    int[] numLayers = getNumLayers();
256
    float[][] cuts = getCuts(numLayers);
257
    float cut = cuts[0][0];
258

    
259
    for(int p=0; p<4; p++)
260
      {
261
      Static3D ax = faceAxis[p];
262
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), dist[p] };
263
      }
264

    
265
    for(int p=4; p<8; p++)
266
      {
267
      Static3D ax = ROT_AXIS[p-4];
268
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut };
269
      }
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

    
274
  private float[] internalPoint(int variant)
275
    {
276
    float[][] pos = getPositions();
277
    float[] position = pos[variant];
278

    
279
    float[] ret = new float[3];
280

    
281
    float A = 0.9f;
282

    
283
    ret[0] = A*position[0];
284
    ret[1] = A*position[1];
285
    ret[2] = A*position[2];
286

    
287
    return ret;
288
    }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
  public ObjectShape getObjectShape(int variant)
293
    {
294
    if( mShapes==null )
295
      {
296
      int[] numLayers = getNumLayers();
297
      int numV = getNumCubitVariants(numLayers);
298
      mShapes = new ObjectShape[numV];
299
      createCutPlanes();
300
      mPotentialVertices = FactoryShape.computePotentialVertices(mCutPlanes);
301
      }
302

    
303
    if( mShapes[variant]==null )
304
      {
305
      float[][] pos = getPositions();
306
      float[] point = internalPoint(variant);
307
      mShapes[variant] = FactoryShape.createShape(mCutPlanes,mPotentialVertices,pos[variant],point);
308
      }
309

    
310
    return mShapes[variant];
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  public ObjectFaceShape getObjectFaceShape(int variant)
316
    {
317
    ObjectShape shape = getObjectShape(variant);
318
    int[][] ind    = shape.getVertIndices();
319
    float[][] vert = shape.getVertices();
320
    float[][] pos  = getPositions();
321
    int[] indices  = FactoryShape.produceBandIndices(vert, pos[variant], ind, getFaceAxis(), getDist() );
322

    
323
    if( variant<4 )
324
      {
325
      int N = 5;
326
      int E = 1;
327
      float height = isInIconMode() ? 0.001f : 0.02f;
328
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
329
      return new ObjectFaceShape(bands,indices,null);
330
      }
331
    else if( variant<10 )
332
      {
333
      int N = 5;
334
      int E = 0;
335
      float height = isInIconMode() ? 0.001f : 0.02f;
336
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
337
      return new ObjectFaceShape(bands,indices,null);
338
      }
339
    else
340
      {
341
      int N = 5;
342
      int E = 0;
343
      float height = isInIconMode() ? 0.001f : 0.02f;
344
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
345
      return new ObjectFaceShape(bands,indices,null);
346
      }
347
    }
348

    
349
///////////////////////////////////////////////////////////////////////////////////////////////////
350

    
351
  private float[][] computeVertexEffectCenter(int variant)
352
    {
353
    float A;
354

    
355
         if( variant< 4 ) A = -0.4f;
356
    else if( variant<10 ) A = -1.0f;
357
    else                  A = -0.9f;
358

    
359
    float[][] positions = getPositions();
360
    float[] p = positions[variant];
361

    
362
    return new float[][] {{ A*p[0], A*p[1], A*p[2] }};
363
    }
364

    
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366

    
367
  public ObjectVertexEffects getVertexEffects(int variant)
368
    {
369
    ObjectShape shape  = getObjectShape(variant);
370
    float[][] vertices = shape.getVertices();
371
    float[][] centers  = computeVertexEffectCenter(variant);
372
    float[][] pos      = getPositions();
373
    int[] indices      = FactoryShape.computeVertexEffectsIndices(vertices, pos[variant], getFaceAxis(), getDist() );
374

    
375
    float S,R;
376
         if( variant< 4 ) { S = 0.05f; R=0.15f; }
377
    else if( variant<10 ) { S = 0.05f; R=0.10f; }
378
    else                  { S = 0.05f; R=0.15f; }
379

    
380
    float[][] corners = {{S,R}};
381

    
382
    return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  public int getNumCubitVariants(int[] numLayers)
388
    {
389
    return 14;
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  public int getCubitVariant(int cubit, int[] numLayers)
395
    {
396
    return cubit;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public float getStickerRadius()
402
    {
403
    return 0.06f;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public float getStickerStroke()
409
    {
410
    return isInIconMode() ? 0.10f : 0.05f;
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  public float[][][] getStickerAngles()
416
    {
417
    return null;
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421
// PUBLIC API
422

    
423
  public Static3D[] getRotationAxis()
424
    {
425
    return ROT_AXIS;
426
    }
427

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

    
430
  public int[][] getBasicAngles()
431
    {
432
    if( mBasicAngle ==null )
433
      {
434
      int num = getNumLayers()[0];
435
      int[] tmp = new int[num];
436
      for(int i=0; i<num; i++) tmp[i] = 3;
437
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
438
      }
439

    
440
    return mBasicAngle;
441
    }
442

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

    
445
  public String getShortName()
446
    {
447
    return ListObjects.MJIN_2.name();
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  public String[][] getTutorials()
453
    {
454
    return null;
455
    }
456
}
(32-32/59)