Project

General

Profile

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

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

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

    
64
  @Override
65
  public int getInternalColor()
66
    {
67
    return 0xff333333;
68
    }
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  @Override
73
  public int getColor(int face)
74
    {
75
    return FACE_COLORS[face];
76
    }
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

    
80
  @Override
81
  public int getNumFaceColors()
82
    {
83
    return 1;
84
    }
85

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

    
88
  @Override
89
  public float[][] returnRotationFactor()
90
    {
91
    float[] f = { 1.4f, 2.0f };
92
    return new float[][] { f,f,f,f };
93
    }
94

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

    
97
  public int[][] getScrambleEdges()
98
    {
99
    if( mEdges==null ) mEdges = ScrambleEdgeGenerator.getScrambleEdgesSingle(mBasicAngle);
100
    return mEdges;
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  public float[][] getCuts(int[] numLayers)
106
    {
107
    if( mCuts==null )
108
      {
109
      float[] c = new float[] { (JING_F-0.51f)*(SQ6/3) };
110
      mCuts = new float[][] {c,c,c,c};
111
      }
112

    
113
    return mCuts;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  public boolean[][] getLayerRotatable(int[] numLayers)
119
    {
120
    boolean[] tmp = {true,true};
121
    return new boolean[][] { tmp,tmp,tmp,tmp };
122
    }
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  public int getTouchControlType()
127
    {
128
    return TC_CHANGING_MIRROR;
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  public int getTouchControlSplit()
134
    {
135
    return TYPE_NOT_SPLIT;
136
    }
137

    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  public int[][][] getEnabled()
141
    {
142
    return null;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
// 'full' dists (not divided by numLayers)
147

    
148
  private float[] getDist()
149
    {
150
    if( mDist==null )
151
      {
152
      float DX = MIRROR_VEC[0];
153
      float DY = MIRROR_VEC[1];
154
      float DZ = MIRROR_VEC[2];
155
      Static3D[] axis = getFaceAxis();
156
      mDist = new float[4];
157

    
158
      for( int a=0; a<4; a++ )
159
        {
160
        Static3D ax = axis[a];
161
        float d = ax.get0()*DX + ax.get1()*DY + ax.get2()*DZ;
162
        mDist[a] = SQ6/6 + d;
163
        }
164
      }
165

    
166
    return mDist;
167
    }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170
// 'regular' dists for the touchControl (have to be divided by numLayers)
171

    
172
  public float[] getDist3D(int[] numLayers)
173
    {
174
    if( mDist3D==null )
175
      {
176
      float[] d = getDist();
177
      mDist3D = new float[] { d[0]/2, d[1]/2, d[2]/2, d[3]/2 };
178
      }
179

    
180
    return mDist3D;
181
    }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
  public Static3D[] getFaceAxis()
186
    {
187
    return TouchControlTetrahedron.FACE_AXIS;
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

    
192
  private float[][] getPositions()
193
    {
194
    if( mPositions==null )
195
      {
196
      final float X = MIRROR_VEC[0];
197
      final float Y = MIRROR_VEC[1];
198
      final float Z = MIRROR_VEC[2];
199

    
200
      mPositions = new float[][]
201
        {
202
          { 0.000f +X, -SQ2/2 +Y,  1.000f +Z },
203
          { 0.000f +X, -SQ2/2 +Y, -1.000f +Z },
204
          {-1.000f +X,  SQ2/2 +Y,  0.000f +Z },
205
          { 1.000f +X,  SQ2/2 +Y,  0.000f +Z },
206

    
207
          { 0.000f +X, -SQ2/2 +Y,  0.000f +Z },
208
          {-0.500f +X, 0.000f +Y,  0.500f +Z },
209
          { 0.500f +X, 0.000f +Y,  0.500f +Z },
210
          {-0.500f +X, 0.000f +Y, -0.500f +Z },
211
          { 0.500f +X, 0.000f +Y, -0.500f +Z },
212
          { 0.000f +X,  SQ2/2 +Y,  0.000f +Z },
213

    
214
          { 0.000f +X,  SQ2/6 +Y,  1.0f/3 +Z },
215
          { 0.000f +X,  SQ2/6 +Y, -1.0f/3 +Z },
216
          {-1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
217
          { 1.0f/3 +X, -SQ2/6 +Y,  0.000f +Z },
218
        };
219
      }
220

    
221
    return mPositions;
222
    }
223

    
224
///////////////////////////////////////////////////////////////////////////////////////////////////
225

    
226
  public float[][] getCubitPositions(int[] numLayers)
227
    {
228
    return getPositions();
229
    }
230

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

    
233
  public Static4D getCubitQuats(int cubit, int[] numLayers)
234
    {
235
    return mObjectQuats[0];
236
    }
237

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239

    
240
  private void createCutPlanes()
241
    {
242
    int numPlanes = 2*4;
243
    mCutPlanes = new float[numPlanes][];
244
    Static3D[] faceAxis = getFaceAxis();
245
    float[] dist = getDist();
246
    int[] numLayers = getNumLayers();
247
    float[][] cuts = getCuts(numLayers);
248
    float cut = cuts[0][0];
249

    
250
    for(int p=0; p<4; p++)
251
      {
252
      Static3D ax = faceAxis[p];
253
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), dist[p] };
254
      }
255

    
256
    for(int p=4; p<8; p++)
257
      {
258
      Static3D ax = ROT_AXIS[p-4];
259
      mCutPlanes[p] = new float[] { ax.get0(), ax.get1(), ax.get2(), cut };
260
      }
261
    }
262

    
263
///////////////////////////////////////////////////////////////////////////////////////////////////
264

    
265
  private float[] internalPoint(int variant)
266
    {
267
    float[][] pos = getPositions();
268
    float[] position = pos[variant];
269

    
270
    float[] ret = new float[3];
271

    
272
    float A = 0.9f;
273

    
274
    ret[0] = A*position[0];
275
    ret[1] = A*position[1];
276
    ret[2] = A*position[2];
277

    
278
    return ret;
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
  public ObjectShape getObjectShape(int variant)
284
    {
285
    if( mShapes==null )
286
      {
287
      int[] numLayers = getNumLayers();
288
      int numV = getNumCubitVariants(numLayers);
289
      mShapes = new ObjectShape[numV];
290
      createCutPlanes();
291
      mPotentialVertices = FactoryShape.computePotentialVertices(mCutPlanes);
292
      }
293

    
294
    if( mShapes[variant]==null )
295
      {
296
      float[][] pos = getPositions();
297
      float[] point = internalPoint(variant);
298
      mShapes[variant] = FactoryShape.createShape(mCutPlanes,mPotentialVertices,pos[variant],point);
299
      }
300

    
301
    return mShapes[variant];
302
    }
303

    
304
///////////////////////////////////////////////////////////////////////////////////////////////////
305

    
306
  public ObjectFaceShape getObjectFaceShape(int variant)
307
    {
308
    ObjectShape shape = getObjectShape(variant);
309
    int[][] ind    = shape.getVertIndices();
310
    float[][] vert = shape.getVertices();
311
    float[][] pos  = getPositions();
312
    int[] indices  = FactoryShape.produceBandIndices(vert, pos[variant], ind, getFaceAxis(), getDist() );
313

    
314
    if( variant<4 )
315
      {
316
      int N = 5;
317
      int E = 1;
318
      float height = isInIconMode() ? 0.001f : 0.02f;
319
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
320
      return new ObjectFaceShape(bands,indices,null);
321
      }
322
    else if( variant<10 )
323
      {
324
      int N = 5;
325
      int E = 0;
326
      float height = isInIconMode() ? 0.001f : 0.02f;
327
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,N,E,E} };
328
      return new ObjectFaceShape(bands,indices,null);
329
      }
330
    else
331
      {
332
      int N = 5;
333
      int E = 0;
334
      float height = isInIconMode() ? 0.001f : 0.02f;
335
      float[][] bands = { {height,35,0.3f,0.5f,N,E,E}, {0.001f,35,0.3f,0.5f,3,0,0} };
336
      return new ObjectFaceShape(bands,indices,null);
337
      }
338
    }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
  private float[][] computeVertexEffectCenter(int variant)
343
    {
344
    float A;
345

    
346
         if( variant< 4 ) A = -0.4f;
347
    else if( variant<10 ) A = -1.0f;
348
    else                  A = -0.9f;
349

    
350
    float[][] positions = getPositions();
351
    float[] p = positions[variant];
352

    
353
    return new float[][] {{ A*p[0], A*p[1], A*p[2] }};
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

    
358
  public ObjectVertexEffects getVertexEffects(int variant)
359
    {
360
    ObjectShape shape  = getObjectShape(variant);
361
    float[][] vertices = shape.getVertices();
362
    float[][] centers  = computeVertexEffectCenter(variant);
363
    float[][] pos      = getPositions();
364
    int[] indices      = FactoryShape.computeVertexEffectsIndices(vertices, pos[variant], getFaceAxis(), getDist() );
365

    
366
    float S,R;
367
         if( variant< 4 ) { S = 0.05f; R=0.15f; }
368
    else if( variant<10 ) { S = 0.05f; R=0.10f; }
369
    else                  { S = 0.05f; R=0.15f; }
370

    
371
    float[][] corners = {{S,R}};
372

    
373
    return FactoryCubit.generateVertexEffect(vertices,corners,indices,centers,indices);
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

    
378
  public int getNumCubitVariants(int[] numLayers)
379
    {
380
    return 14;
381
    }
382

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

    
385
  public int getCubitVariant(int cubit, int[] numLayers)
386
    {
387
    return cubit;
388
    }
389

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public float getStickerRadius()
393
    {
394
    return 0.06f;
395
    }
396

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

    
399
  public float getStickerStroke()
400
    {
401
    return isInIconMode() ? 0.10f : 0.05f;
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  public float[][][] getStickerAngles()
407
    {
408
    return null;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412
// PUBLIC API
413

    
414
  public Static3D[] getRotationAxis()
415
    {
416
    return ROT_AXIS;
417
    }
418

    
419
///////////////////////////////////////////////////////////////////////////////////////////////////
420

    
421
  public int[][] getBasicAngles()
422
    {
423
    if( mBasicAngle ==null )
424
      {
425
      int num = getNumLayers()[0];
426
      int[] tmp = new int[num];
427
      for(int i=0; i<num; i++) tmp[i] = 3;
428
      mBasicAngle = new int[][] { tmp,tmp,tmp,tmp };
429
      }
430

    
431
    return mBasicAngle;
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  public String getShortName()
437
    {
438
    return ListObjects.MJIN_2.name();
439
    }
440

    
441
///////////////////////////////////////////////////////////////////////////////////////////////////
442

    
443
  public String[][] getTutorials()
444
    {
445
    return null;
446
    }
447
}
(32-32/57)