Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / bandaged / FactoryBandagedOctahedron.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.bandaged;
11

    
12
import static org.distorted.objectlib.main.TwistyObject.SQ2;
13

    
14
import org.distorted.library.type.Static3D;
15
import org.distorted.library.type.Static4D;
16
import org.distorted.objectlib.touchcontrol.TouchControlOctahedron;
17

    
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
public class FactoryBandagedOctahedron extends FactoryBandaged
21
  {
22
  private static FactoryBandagedOctahedron mThis;
23
  private float[][][] mVertices;
24
  private int[][][] mIndices;
25
  private int[] mTetraToFaceMap;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
  private FactoryBandagedOctahedron()
30
    {
31

    
32
    }
33

    
34
///////////////////////////////////////////////////////////////////////////////////////////////////
35

    
36
  public static FactoryBandagedOctahedron getInstance()
37
    {
38
    if( mThis==null ) mThis = new FactoryBandagedOctahedron();
39
    return mThis;
40
    }
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
  static int getNumOctahedrons(int layers)
45
    {
46
    return layers==1 ? 1 : 4*(layers-1)*(layers-1) + 2;
47
    }
48

    
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

    
51
  static int getNumTetrahedrons(int layers)
52
    {
53
    return 4*layers*(layers-1);
54
    }
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

    
58
  private static int createOctaPositions(float[][] centers, int index, int layers, float height)
59
    {
60
    float x = (layers-1)*0.5f;
61
    float z = (layers+1)*0.5f;
62

    
63
    for(int i=0; i<layers; i++, index++)
64
      {
65
      z -= 1;
66
      centers[index][0] = x;
67
      centers[index][1] = height;
68
      centers[index][2] = z;
69
      }
70

    
71
    for(int i=0; i<layers-1; i++, index++)
72
      {
73
      x -= 1;
74
      centers[index][0] = x;
75
      centers[index][1] = height;
76
      centers[index][2] = z;
77
      }
78

    
79
    for(int i=0; i<layers-1; i++, index++)
80
      {
81
      z += 1;
82
      centers[index][0] = x;
83
      centers[index][1] = height;
84
      centers[index][2] = z;
85
      }
86

    
87
    for(int i=0; i<layers-2; i++, index++)
88
      {
89
      x += 1;
90
      centers[index][0] = x;
91
      centers[index][1] = height;
92
      centers[index][2] = z;
93
      }
94

    
95
    return index;
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  private static int createTetraPositions(float[][] centers, int index, int layers, float height)
101
    {
102
    float x = (layers-1)*0.5f;
103
    float z =  layers*0.5f;
104

    
105
    for(int i=0; i<layers-1; i++, index++)
106
      {
107
      z -= 1;
108
      centers[index][0] = x;
109
      centers[index][1] = height;
110
      centers[index][2] = z;
111
      }
112

    
113
    x += 0.5f;
114
    z -= 0.5f;
115

    
116
    for(int i=0; i<layers-1; i++, index++)
117
      {
118
      x -= 1;
119
      centers[index][0] = x;
120
      centers[index][1] = height;
121
      centers[index][2] = z;
122
      }
123

    
124
    x -= 0.5f;
125
    z -= 0.5f;
126

    
127
    for(int i=0; i<layers-1; i++, index++)
128
      {
129
      z += 1;
130
      centers[index][0] = x;
131
      centers[index][1] = height;
132
      centers[index][2] = z;
133
      }
134

    
135
    x -= 0.5f;
136
    z += 0.5f;
137

    
138
    for(int i=0; i<layers-1; i++, index++)
139
      {
140
      x += 1;
141
      centers[index][0] = x;
142
      centers[index][1] = height;
143
      centers[index][2] = z;
144
      }
145

    
146
    return index;
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  public static float[][][] createPositions(int size)
152
    {
153
    int numO = getNumOctahedrons(size);
154
    int numT = getNumTetrahedrons(size);
155
    int index = 0;
156
    float height = 0.0f;
157

    
158
    float[][][] ret = new float[2][][];
159
    ret[0] = new float[numO][3];
160
    ret[1] = new float[numT][3];
161

    
162
    index = createOctaPositions(ret[0],index,size,height);
163

    
164
    for(int i=size-1; i>0; i--)
165
      {
166
      height += SQ2/2;
167
      index = createOctaPositions(ret[0],index,i,+height);
168
      index = createOctaPositions(ret[0],index,i,-height);
169
      }
170

    
171
    height = SQ2/4;
172
    index = 0;
173

    
174
    for(int i=size; i>1; i--)
175
      {
176
      index = createTetraPositions(ret[1],index,i,-height);
177
      index = createTetraPositions(ret[1],index,i,+height);
178
      height += SQ2/2;
179
      }
180

    
181
    return ret;
182
    }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
  public float[][] getVertices(int[] numLayers, int variant)
187
    {
188
    if( mVertices==null ) mVertices = new float[2][][];
189

    
190
    if( variant==0 )
191
      {
192
      if( mVertices[0]==null )
193
        mVertices[0] = new float[][] { { 0.5f,0.0f,0.5f},{ 0.5f,0.0f,-0.5f},{-0.5f,0.0f,-0.5f},{-0.5f,0.0f,0.5f},{ 0.0f,SQ2/2,0.0f},{ 0.0f,-SQ2/2,0.0f} };
194

    
195
      return mVertices[0];
196
      }
197
    else
198
      {
199
      if( mVertices[1]==null )
200
        mVertices[1] = new float[][] { {-0.5f, SQ2/4, 0.0f},{ 0.5f, SQ2/4, 0.0f},{ 0.0f,-SQ2/4, 0.5f},{ 0.0f,-SQ2/4,-0.5f} };
201

    
202
      return mVertices[1];
203
      }
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  public int[][] getIndices(int[] numLayers, int variant)
209
    {
210
    if( mIndices==null ) mIndices = new int[2][][];
211

    
212
    if( variant==0 )
213
      {
214
      if( mIndices[0]==null )
215
        mIndices[0] = new int[][] { {3,0,4},{0,1,4},{1,2,4},{2,3,4},{5,0,3},{5,1,0},{5,2,1},{5,3,2} };
216

    
217
      return mIndices[0];
218
      }
219
    else
220
      {
221
      if( mIndices[1]==null )
222
        mIndices[1] = new int[][] { {2,1,0},{3,0,1},{3,2,0},{2,3,1} };
223

    
224
      return mIndices[1];
225
      }
226
    }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229
// element is an octahedron iff its Y is an integer multiple of (SQ2/2).
230

    
231
  public static boolean isOctahedron(float y)
232
    {
233
    float H = SQ2/2;
234
    int num = (int)(2*(y+10*H)/H + 0.1f);
235
    return num%2 == 0;
236
    }
237

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

    
240
  public int getNumVariants(int[] numLayers)
241
    {
242
    return 2;
243
    }
244

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

    
247
  public int getElementVariant(int[] numLayers, float x, float y, float z)
248
    {
249
    return isOctahedron(y) ? 0 : 1;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  private int retFaceTetraBelongsTo(int tetra, int numLayers)
255
    {
256
    if( mTetraToFaceMap==null ) mTetraToFaceMap = new int[] {5,6,7,4,1,2,3,0};
257

    
258
    for(int i=numLayers-1; i>0; i--)
259
      {
260
      if( tetra < 8*i ) return mTetraToFaceMap[tetra/i];
261
      tetra -= 8*i;
262
      }
263

    
264
    return -1;
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  public Static4D getElementQuat(int[] numLayers, int cubitIndex)
270
    {
271
    int numL = numLayers[0];
272
    int numO = getNumOctahedrons(numL);
273

    
274
    if( cubitIndex<numO ) return QUAT;
275

    
276
    switch( retFaceTetraBelongsTo(cubitIndex-numO, numL) )
277
      {
278
      case 0: return QUAT;
279
      case 1: return new Static4D(0,-SQ2/2,0,SQ2/2);
280
      case 2: return QUAT;
281
      case 3: return new Static4D(0, SQ2/2,0,SQ2/2);
282
      case 4: return new Static4D(0,     0,1,    0);
283
      case 5: return QUAT;
284
      case 6: return new Static4D(     1,0,0,    0);
285
      case 7: return QUAT;
286
      }
287

    
288
    return null;
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  public float[][][] getPositions(int[] numLayers)
294
    {
295
    return createPositions(numLayers[0]);
296
    }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
  public Static3D[] getNormals()
301
    {
302
    return TouchControlOctahedron.FACE_AXIS;
303
    }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306
// normalized 'edges' of the octahedron.
307

    
308
  public float[][] getDiameterAxis()
309
    {
310
    return new float[][]
311
            {
312
                    {    1,    0,    0},
313
                    {    0,    0,    1},
314
                    { 0.5f,SQ2/2, 0.5f},
315
                    { 0.5f,SQ2/2,-0.5f},
316
                    {-0.5f,SQ2/2, 0.5f},
317
                    {-0.5f,SQ2/2,-0.5f},
318
            };
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  public float sizeCorrection(int[] numLayers)
324
    {
325
    return 1.0f;
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  public int diameterMap(float diameter)
331
    {
332
    if( diameter>=5.49f ) return 11;
333
    if( diameter>1.1f && diameter<1.9f ) return 3;
334
    return (int)(2*diameter+0.01f);
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

    
339
  public float[] getDist3D(int[] numLayers)
340
    {
341
    final float d = TouchControlOctahedron.DIST3D*numLayers[0];
342
    return new float[] {d,d,d,d,d,d,d,d};
343
    }
344

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

    
347
  public float[][] getBands(boolean iconMode, int[] numLayers)
348
    {
349
    float height= iconMode ? 0.001f : 0.05f;
350
    int[] angle = {1,26,24,22,20,18,16,14,12,10,8};
351
    float R     = 0.3f;
352
    float S     = 0.5f;
353
    int extraI  = numLayers[0]>2 ? 0:1;
354
    int extraV  = numLayers[0]>2 ? 0:1;
355
    int numVertA= numLayers[0]>3 ? 5:6;
356
    int numVertI= numLayers[0]>4 ? 2:3;
357

    
358
    return new float[][] { {  0.001f    ,angle[ 0],R,S,numVertI,extraV,extraI},
359
                           {height      ,angle[ 1],R,S,numVertA,extraV,extraI},
360
                           {height      ,angle[ 1],R,S,numVertA,extraV,extraI},
361
                           {height/ 1.5f,angle[ 2],R,S,numVertA,extraV,extraI},
362
                           {height/ 2.0f,angle[ 3],R,S,numVertA,extraV,extraI},
363
                           {height/ 2.5f,angle[ 4],R,S,numVertA,extraV,extraI},
364
                           {height/ 3.0f,angle[ 5],R,S,numVertA,extraV,extraI},
365
                           {height/ 3.5f,angle[ 6],R,S,numVertA,extraV,extraI},
366
                           {height/ 4.0f,angle[ 7],R,S,numVertA,extraV,extraI},
367
                           {height/ 4.5f,angle[ 8],R,S,numVertA,extraV,extraI},
368
                           {height/ 5.0f,angle[ 9],R,S,numVertA,extraV,extraI},
369
                           {height/ 5.5f,angle[10],R,S,numVertA,extraV,extraI}
370
                          };
371
    }
372
  }
(12-12/15)