Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / objects / TwistyMirrorJing.java @ 33ba467a

1 ed6b7481 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
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 f18abf2a leszek
import static org.distorted.objectlib.touchcontrol.TouchControl.TC_CHANGING_MIRROR;
13 ed6b7481 leszek
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 361fd0de leszek
import org.distorted.objectlib.metadata.ListObjects;
24 ae9d9227 leszek
import org.distorted.objectlib.metadata.Metadata;
25 ed6b7481 leszek
import org.distorted.objectlib.scrambling.ScrambleEdgeGenerator;
26 b7ae2292 leszek
import org.distorted.objectlib.shape.ShapeColors;
27 ed6b7481 leszek
import org.distorted.objectlib.shape.ShapeTetrahedron;
28
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
29
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31
32
public class TwistyMirrorJing extends ShapeTetrahedron
33
{
34
  public static final Static3D[] ROT_AXIS = new Static3D[]
35
         {
36
           new Static3D(     0,-SQ3/3,-SQ6/3),
37
           new Static3D(     0,-SQ3/3, SQ6/3),
38
           new Static3D( SQ6/3, SQ3/3,     0),
39
           new Static3D(-SQ6/3, SQ3/3,     0),
40
         };
41
42
  private static final float JING_F = 0.48f;
43
44 33ba467a leszek
  private static final int[] FACE_COLORS = new int[] { ShapeColors.COLOR_WHITE};
45 f7f5771f leszek
  private static final float[] MIRROR_VEC = { 0.06f, 0.07f, 0.08f };
46 ed6b7481 leszek
47
  private int[][] mEdges;
48
  private int[][] mBasicAngle;
49
  private float[][] mCuts;
50
  private float[][] mPositions;
51
  private ObjectShape[] mShapes;
52
  private float[][] mCutPlanes;
53
  private float[] mDist3D, mDist;
54
  private float[][] mPotentialVertices;
55
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
58 ae9d9227 leszek
  public TwistyMirrorJing(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
59 ed6b7481 leszek
    {
60 ae9d9227 leszek
    super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
61 ed6b7481 leszek
    }
62
63 074a0284 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
64
// here we cannot automatically detect the outer monochromatic walls -> use the old way.
65
66
  @Override
67
  public int getSolvedFunctionIndex()
68
    {
69
    return 0;
70
    }
71
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73
74
  @Override
75
  public int[][] getSolvedQuats()
76
    {
77
    return getOldSolvedQuats();
78
    }
79
80 ed6b7481 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
81
82
  @Override
83
  public int getInternalColor()
84
    {
85
    return 0xff333333;
86
    }
87
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
90
  @Override
91 962b8ff6 leszek
  public int[] getColorTable()
92 ed6b7481 leszek
    {
93 962b8ff6 leszek
    return FACE_COLORS;
94 ed6b7481 leszek
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98
  @Override
99
  public float[][] returnRotationFactor()
100
    {
101 f18abf2a leszek
    float[] f = { 1.4f, 2.0f };
102 ed6b7481 leszek
    return new float[][] { f,f,f,f };
103
    }
104
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
107
  public int[][] getScrambleEdges()
108
    {
109
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
110
    return mEdges;
111
    }
112
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114
115
  public float[][] getCuts(int[] numLayers)
116
    {
117
    if( mCuts==null )
118
      {
119
      float[] c = new float[] { (JING_F-0.51f)*(SQ6/3) };
120
      mCuts = new float[][] {c,c,c,c};
121
      }
122
123
    return mCuts;
124
    }
125
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127
128
  public boolean[][] getLayerRotatable(int[] numLayers)
129
    {
130
    boolean[] tmp = {true,true};
131
    return new boolean[][] { tmp,tmp,tmp,tmp };
132
    }
133
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135
136
  public int getTouchControlType()
137
    {
138 f18abf2a leszek
    return TC_CHANGING_MIRROR;
139 ed6b7481 leszek
    }
140
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
143
  public int getTouchControlSplit()
144
    {
145
    return TYPE_NOT_SPLIT;
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150
  public int[][][] getEnabled()
151
    {
152
    return null;
153
    }
154
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// 'full' dists (not divided by numLayers)
157
158
  private float[] getDist()
159
    {
160
    if( mDist==null )
161
      {
162
      float DX = MIRROR_VEC[0];
163
      float DY = MIRROR_VEC[1];
164
      float DZ = MIRROR_VEC[2];
165
      Static3D[] axis = getFaceAxis();
166
      mDist = new float[4];
167
168
      for( int a=0; a<4; a++ )
169
        {
170
        Static3D ax = axis[a];
171
        float d = ax.get0()*DX + ax.get1()*DY + ax.get2()*DZ;
172
        mDist[a] = SQ6/6 + d;
173
        }
174
      }
175
176
    return mDist;
177
    }
178
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180
// 'regular' dists for the touchControl (have to be divided by numLayers)
181
182
  public float[] getDist3D(int[] numLayers)
183
    {
184
    if( mDist3D==null )
185
      {
186
      float[] d = getDist();
187
      mDist3D = new float[] { d[0]/2, d[1]/2, d[2]/2, d[3]/2 };
188
      }
189
190
    return mDist3D;
191
    }
192
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195
  public Static3D[] getFaceAxis()
196
    {
197
    return TouchControlTetrahedron.FACE_AXIS;
198
    }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201
202
  private float[][] getPositions()
203
    {
204
    if( mPositions==null )
205
      {
206
      final float X = MIRROR_VEC[0];
207
      final float Y = MIRROR_VEC[1];
208
      final float Z = MIRROR_VEC[2];
209
210
      mPositions = new float[][]
211
        {
212
          { 0.000f +X, -SQ2/2 +Y,  1.000f +Z },
213
          { 0.000f +X, -SQ2/2 +Y, -1.000f +Z },
214
          {-1.000f +X,  SQ2/2 +Y,  0.000f +Z },
215
          { 1.000f +X,  SQ2/2 +Y,  0.000f +Z },
216
217
          { 0.000f +X, -SQ2/2 +Y,  0.000f +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.500f +X, 0.000f +Y, -0.500f +Z },
222
          { 0.000f +X,  SQ2/2 +Y,  0.000f +Z },
223
224
          { 0.000f +X,  SQ2/6 +Y,  1.0f/3 +Z },
225
          { 0.000f +X,  SQ2/6 +Y, -1.0f/3 +Z },
226
          {-1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
227
          { 1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
228
        };
229
      }
230
231
    return mPositions;
232
    }
233
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
236
  public float[][] getCubitPositions(int[] numLayers)
237
    {
238
    return getPositions();
239
    }
240
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243
  public Static4D getCubitQuats(int cubit, int[] numLayers)
244
    {
245
    return mObjectQuats[0];
246
    }
247
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
250
  private void createCutPlanes()
251
    {
252
    int numPlanes = 2*4;
253
    mCutPlanes = new float[numPlanes][];
254
    Static3D[] faceAxis = getFaceAxis();
255
    float[] dist = getDist();
256
    int[] numLayers = getNumLayers();
257
    float[][] cuts = getCuts(numLayers);
258
    float cut = cuts[0][0];
259
260
    for(int p=0; p<4; p++)
261
      {
262
      Static3D ax = faceAxis[p];
263
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), dist[p] };
264
      }
265
266
    for(int p=4; p<8; p++)
267
      {
268
      Static3D ax = ROT_AXIS[p-4];
269
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut };
270
      }
271
    }
272
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275
  private float[] internalPoint(int variant)
276
    {
277
    float[][] pos = getPositions();
278
    float[] position = pos[variant];
279
280
    float[] ret = new float[3];
281
282 f7f5771f leszek
    float A = 0.9f;
283 ed6b7481 leszek
284 f7f5771f leszek
    ret[0] = A*position[0];
285
    ret[1] = A*position[1];
286
    ret[2] = A*position[2];
287 ed6b7481 leszek
288
    return ret;
289
    }
290
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293
  public ObjectShape getObjectShape(int variant)
294
    {
295
    if( mShapes==null )
296
      {
297
      int[] numLayers = getNumLayers();
298
      int numV = getNumCubitVariants(numLayers);
299
      mShapes = new ObjectShape[numV];
300
      createCutPlanes();
301
      mPotentialVertices = FactoryShape.computePotentialVertices(mCutPlanes);
302
      }
303
304
    if( mShapes[variant]==null )
305
      {
306
      float[][] pos = getPositions();
307
      float[] point = internalPoint(variant);
308
      mShapes[variant] = FactoryShape.createShape(mCutPlanes,mPotentialVertices,pos[variant],point);
309
      }
310
311
    return mShapes[variant];
312
    }
313
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315
316
  public ObjectFaceShape getObjectFaceShape(int variant)
317
    {
318
    ObjectShape shape = getObjectShape(variant);
319
    int[][] ind    = shape.getVertIndices();
320
    float[][] vert = shape.getVertices();
321
    float[][] pos  = getPositions();
322
    int[] indices  = FactoryShape.produceBandIndices(vert, pos[variant], ind, getFaceAxis(), getDist() );
323
324
    if( variant<4 )
325
      {
326
      int N = 5;
327 f7f5771f leszek
      int E = 1;
328 ed6b7481 leszek
      float height = isInIconMode() ? 0.001f : 0.02f;
329
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
330
      return new ObjectFaceShape(bands,indices,null);
331
      }
332
    else if( variant<10 )
333
      {
334
      int N = 5;
335 f7f5771f leszek
      int E = 0;
336 ed6b7481 leszek
      float height = isInIconMode() ? 0.001f : 0.02f;
337 f7f5771f leszek
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
338 ed6b7481 leszek
      return new ObjectFaceShape(bands,indices,null);
339
      }
340
    else
341
      {
342
      int N = 5;
343
      int E = 0;
344
      float height = isInIconMode() ? 0.001f : 0.02f;
345
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
346
      return new ObjectFaceShape(bands,indices,null);
347
      }
348
    }
349
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352
  private float[][] computeVertexEffectCenter(int variant)
353
    {
354
    float A;
355
356 f7f5771f leszek
         if( variant< 4 ) A = -0.4f;
357
    else if( variant<10 ) A = -1.0f;
358
    else                  A = -0.9f;
359 ed6b7481 leszek
360
    float[][] positions = getPositions();
361
    float[] p = positions[variant];
362
363
    return new float[][] {{ A*p[0], A*p[1], A*p[2] }};
364
    }
365
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
368
  public ObjectVertexEffects getVertexEffects(int variant)
369
    {
370
    ObjectShape shape  = getObjectShape(variant);
371
    float[][] vertices = shape.getVertices();
372
    float[][] centers  = computeVertexEffectCenter(variant);
373
    float[][] pos      = getPositions();
374
    int[] indices      = FactoryShape.computeVertexEffectsIndices(vertices, pos[variant], getFaceAxis(), getDist() );
375
376
    float S,R;
377 f7f5771f leszek
         if( variant< 4 ) { S = 0.05f; R=0.15f; }
378 176ae5bb leszek
    else if( variant<10 ) { S = 0.05f; R=0.10f; }
379 f7f5771f leszek
    else                  { S = 0.05f; R=0.15f; }
380 ed6b7481 leszek
381 f7f5771f leszek
    float[][] corners = {{S,R}};
382 ed6b7481 leszek
383
    return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
384
    }
385
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387
388
  public int getNumCubitVariants(int[] numLayers)
389
    {
390
    return 14;
391
    }
392
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
395
  public int getCubitVariant(int cubit, int[] numLayers)
396
    {
397
    return cubit;
398
    }
399
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401
402
  public float getStickerRadius()
403
    {
404
    return 0.06f;
405
    }
406
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408
409
  public float getStickerStroke()
410
    {
411
    return isInIconMode() ? 0.10f : 0.05f;
412
    }
413
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415
416
  public float[][][] getStickerAngles()
417
    {
418
    return null;
419
    }
420
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422
// PUBLIC API
423
424
  public Static3D[] getRotationAxis()
425
    {
426
    return ROT_AXIS;
427
    }
428
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430
431
  public int[][] getBasicAngles()
432
    {
433
    if( mBasicAngle ==null )
434
      {
435
      int num = getNumLayers()[0];
436
      int[] tmp = new int[num];
437
      for(int i=0; i<num; i++) tmp[i] = 3;
438
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
439
      }
440
441
    return mBasicAngle;
442
    }
443
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
446
  public String getShortName()
447
    {
448 361fd0de leszek
    return ListObjects.MJIN_2.name();
449 ed6b7481 leszek
    }
450
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452
453
  public String[][] getTutorials()
454
    {
455
    return null;
456
    }
457
}