Project

General

Profile

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

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

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.ShapeColors;
27
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
  private static final int[] FACE_COLORS = new int[] { ShapeColors.COLOR_WHITE};
45
  private static final float[] MIRROR_VEC = { 0.06f, 0.07f, 0.08f };
46

    
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
  public TwistyMirrorJing(int iconMode, Static4D quat, Static3D move, float scale, Metadata meta, InitAssets asset)
59
    {
60
    super(iconMode, meta.getNumLayers()[0], quat, move, scale, meta, asset);
61
    }
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
81

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

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

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

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

    
98
  @Override
99
  public float[][] returnRotationFactor()
100
    {
101
    float[] f = { 1.4f, 2.0f };
102
    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
    return TC_CHANGING_MIRROR;
139
    }
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
    float A = 0.9f;
283

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

    
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
      int E = 1;
328
      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
      int E = 0;
336
      float height = isInIconMode() ? 0.001f : 0.02f;
337
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
338
      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
         if( variant< 4 ) A = -0.4f;
357
    else if( variant<10 ) A = -1.0f;
358
    else                  A = -0.9f;
359

    
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
         if( variant< 4 ) { S = 0.05f; R=0.15f; }
378
    else if( variant<10 ) { S = 0.05f; R=0.10f; }
379
    else                  { S = 0.05f; R=0.15f; }
380

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

    
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
    return ListObjects.MJIN_2.name();
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

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