Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / helpers / FactoryBandaged3x3Cubit.java @ beee90ab

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.helpers;
21

    
22
import java.util.ArrayList;
23

    
24
import org.distorted.library.mesh.MeshBase;
25
import org.distorted.library.type.Static3D;
26
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
27

    
28
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
public class FactoryBandaged3x3Cubit
33
  {
34
  private static final int WALL_MARKED=0;
35
  private static final int WALL_EMPTY =-1;
36

    
37
  private static final int AXIS_XP = 0;
38
  private static final int AXIS_XM = 1;
39
  private static final int AXIS_YP = 2;
40
  private static final int AXIS_YM = 3;
41
  private static final int AXIS_ZP = 4;
42
  private static final int AXIS_ZM = 5;
43

    
44
  private static final float[][] VECTOR =
45
      {
46
          {-1.0f,-1.0f,-1.0f},
47
          {-1.0f,-1.0f,+1.0f},
48
          {-1.0f,+1.0f,-1.0f},
49
          {-1.0f,+1.0f,+1.0f},
50
          {+1.0f,-1.0f,-1.0f},
51
          {+1.0f,-1.0f,+1.0f},
52
          {+1.0f,+1.0f,-1.0f},
53
          {+1.0f,+1.0f,+1.0f}
54
      };
55

    
56
  private static FactoryBandaged3x3Cubit mThis;
57
  private ArrayList<float[]> mVertexArray;
58
  private ArrayList<float[]> mTmpArray;
59
  private float[][][] mVertices;
60
  private int[][][] mIndices;
61
  private float[][] mMove;
62
  private final int[] mWall;
63
  private final int[][] mPoints;
64
  private final boolean[][][] mTmp;
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  private FactoryBandaged3x3Cubit()
69
    {
70
    mWall= new int[9];
71
    mPoints = new int[4][4];
72
    mTmp = new boolean[3][3][3];
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  private float[][] getVertices(ArrayList<float[]> list, float[] move, int variant)
78
    {
79
    int numMoves = move.length/3;
80
    mMove[variant][0]=0.0f;
81
    mMove[variant][1]=0.0f;
82
    mMove[variant][2]=0.0f;
83

    
84
    for(int m=0; m<numMoves; m++)
85
      {
86
      mMove[variant][0] += move[3*m  ];
87
      mMove[variant][1] += move[3*m+1];
88
      mMove[variant][2] += move[3*m+2];
89
      }
90

    
91
    mMove[variant][0]/=numMoves;
92
    mMove[variant][1]/=numMoves;
93
    mMove[variant][2]/=numMoves;
94

    
95
    int total  = 0;
96
    int length = list.size();
97
    float[][] vertices = new float[length][];
98

    
99
    for( int i=0; i<length; i++ )
100
      {
101
      vertices[i] = list.get(i);
102
      total += vertices[i].length/3;
103
      }
104

    
105
    float[][] verts = new float[total][3];
106
    int pointer = 0;
107

    
108
    for(int i=0; i<length; i++)
109
      {
110
      int len = vertices[i].length/3;
111

    
112
      for(int j=0; j<len; j++)
113
        {
114
        verts[pointer][0] = vertices[i][3*j  ] - mMove[variant][0];
115
        verts[pointer][1] = vertices[i][3*j+1] - mMove[variant][1];
116
        verts[pointer][2] = vertices[i][3*j+2] - mMove[variant][2];
117
        pointer++;
118
        }
119
      }
120

    
121
    return verts;
122
    }
123

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

    
126
  private int[][] getIndices(ArrayList<float[]> list)
127
    {
128
    int indicesSoFar=0;
129
    int length = list.size();
130
    int[][] indices = new int[length][];
131

    
132
    for( int i=0; i<length; i++ )
133
      {
134
      float[] f = list.get(i);
135
      int len = f.length/3;
136
      int[] ind = new int[len];
137
      for(int j=0; j<len; j++) ind[j] = (indicesSoFar++);
138
      indices[i] = ind;
139
      }
140

    
141
    return indices;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  private void markAllVertices(float[] vertex, float[][] vertices, int[][] indices, int pointer, int variant)
147
    {
148
    int lenI = indices.length;
149

    
150
    for(int index=0; index<lenI; index++)
151
      {
152
      int len = indices[index].length;
153

    
154
      for(int i=0; i<len; i++)
155
        {
156
        if( mIndices[variant][index][i] == -1 )
157
          {
158
          int ind = indices[index][i];
159
          float[] ver = vertices[ind];
160

    
161
          if( vertex[0]==ver[0] && vertex[1]==ver[1] && vertex[2]==ver[2] )
162
            {
163
            mIndices[variant][index][i] = pointer;
164
            }
165
          }
166
        }
167
      }
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
// So far the 'vertices/indices' are stored inefficiently, with each vertex stored three times
172
// (each one normally is a corner of three faces) or even six times. Compress!
173
// Example of six times: the central vertex here:
174
//
175
// { 1.0f,  0.0f, -1.0f,
176
//   1.0f, -1.0f, -1.0f,
177
//   1.0f, -1.0f, +0.0f,
178
//   0.0f, -1.0f, -1.0f },
179

    
180
  private void compressVerticesAndIndices(int variant, float[][] vertices, int[][] indices)
181
    {
182
    if( mTmpArray==null ) mTmpArray = new ArrayList<>();
183

    
184
    int lenI = indices.length;
185
    int pointer=0;
186

    
187
    mIndices[variant] = new int[lenI][];
188

    
189
    for(int index=0; index<lenI; index++)
190
      {
191
      int len = indices[index].length;
192
      mIndices[variant][index] = new int[len];
193
      for(int i=0; i<len; i++) mIndices[variant][index][i] = -1;
194
      }
195

    
196
    for(int index=0; index<lenI; index++)
197
      {
198
      int len = indices[index].length;
199

    
200
      for(int i=0; i<len; i++)
201
        {
202
        if( mIndices[variant][index][i] == -1 )
203
          {
204
          int ind = indices[index][i];
205
          float[] ver = vertices[ind];
206
          mTmpArray.add(ver);
207
          markAllVertices(ver,vertices,indices,pointer,variant);
208
          pointer++;
209
          }
210
        }
211
      }
212

    
213
    int len = mTmpArray.size();
214
    mVertices[variant] = new float[len][];
215

    
216
    for(int i=0; i<len; i++)
217
      {
218
      mVertices[variant][i] = mTmpArray.remove(0);
219
      }
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  private boolean cubitExists(float[] pos, float x, float y, float z)
225
    {
226
    int len = pos.length/3;
227

    
228
    for(int i=0; i<len; i++)
229
      if( pos[3*i]==x && pos[3*i+1]==y && pos[3*i+2]==z ) return true;
230

    
231
    return false;
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  private void createRight0(ArrayList<float[]> list)
237
    {
238
    mWall[0] = (mTmp[0][2][2] && !mTmp[1][2][2]) ? WALL_MARKED:WALL_EMPTY;
239
    mWall[1] = (mTmp[0][2][1] && !mTmp[1][2][1]) ? WALL_MARKED:WALL_EMPTY;
240
    mWall[2] = (mTmp[0][2][0] && !mTmp[1][2][0]) ? WALL_MARKED:WALL_EMPTY;
241
    mWall[3] = (mTmp[0][1][2] && !mTmp[1][1][2]) ? WALL_MARKED:WALL_EMPTY;
242
    mWall[4] = (mTmp[0][1][1] && !mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
243
    mWall[5] = (mTmp[0][1][0] && !mTmp[1][1][0]) ? WALL_MARKED:WALL_EMPTY;
244
    mWall[6] = (mTmp[0][0][2] && !mTmp[1][0][2]) ? WALL_MARKED:WALL_EMPTY;
245
    mWall[7] = (mTmp[0][0][1] && !mTmp[1][0][1]) ? WALL_MARKED:WALL_EMPTY;
246
    mWall[8] = (mTmp[0][0][0] && !mTmp[1][0][0]) ? WALL_MARKED:WALL_EMPTY;
247

    
248
    createVertices(list,mWall,AXIS_XP,0);
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  private void createRight1(ArrayList<float[]> list)
254
    {
255
    mWall[0] = (mTmp[1][2][2] && !mTmp[2][2][2]) ? WALL_MARKED:WALL_EMPTY;
256
    mWall[1] = (mTmp[1][2][1] && !mTmp[2][2][1]) ? WALL_MARKED:WALL_EMPTY;
257
    mWall[2] = (mTmp[1][2][0] && !mTmp[2][2][0]) ? WALL_MARKED:WALL_EMPTY;
258
    mWall[3] = (mTmp[1][1][2] && !mTmp[2][1][2]) ? WALL_MARKED:WALL_EMPTY;
259
    mWall[4] = (mTmp[1][1][1] && !mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
260
    mWall[5] = (mTmp[1][1][0] && !mTmp[2][1][0]) ? WALL_MARKED:WALL_EMPTY;
261
    mWall[6] = (mTmp[1][0][2] && !mTmp[2][0][2]) ? WALL_MARKED:WALL_EMPTY;
262
    mWall[7] = (mTmp[1][0][1] && !mTmp[2][0][1]) ? WALL_MARKED:WALL_EMPTY;
263
    mWall[8] = (mTmp[1][0][0] && !mTmp[2][0][0]) ? WALL_MARKED:WALL_EMPTY;
264

    
265
    createVertices(list,mWall,AXIS_XP,1);
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  private void createRight2(ArrayList<float[]> list)
271
    {
272
    mWall[0] = mTmp[2][2][2] ? WALL_MARKED:WALL_EMPTY;
273
    mWall[1] = mTmp[2][2][1] ? WALL_MARKED:WALL_EMPTY;
274
    mWall[2] = mTmp[2][2][0] ? WALL_MARKED:WALL_EMPTY;
275
    mWall[3] = mTmp[2][1][2] ? WALL_MARKED:WALL_EMPTY;
276
    mWall[4] = mTmp[2][1][1] ? WALL_MARKED:WALL_EMPTY;
277
    mWall[5] = mTmp[2][1][0] ? WALL_MARKED:WALL_EMPTY;
278
    mWall[6] = mTmp[2][0][2] ? WALL_MARKED:WALL_EMPTY;
279
    mWall[7] = mTmp[2][0][1] ? WALL_MARKED:WALL_EMPTY;
280
    mWall[8] = mTmp[2][0][0] ? WALL_MARKED:WALL_EMPTY;
281

    
282
    createVertices(list,mWall,AXIS_XP,2);
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  private void createLeft0(ArrayList<float[]> list)
288
    {
289
    mWall[0] = mTmp[0][2][0] ? WALL_MARKED:WALL_EMPTY;
290
    mWall[1] = mTmp[0][2][1] ? WALL_MARKED:WALL_EMPTY;
291
    mWall[2] = mTmp[0][2][2] ? WALL_MARKED:WALL_EMPTY;
292
    mWall[3] = mTmp[0][1][0] ? WALL_MARKED:WALL_EMPTY;
293
    mWall[4] = mTmp[0][1][1] ? WALL_MARKED:WALL_EMPTY;
294
    mWall[5] = mTmp[0][1][2] ? WALL_MARKED:WALL_EMPTY;
295
    mWall[6] = mTmp[0][0][0] ? WALL_MARKED:WALL_EMPTY;
296
    mWall[7] = mTmp[0][0][1] ? WALL_MARKED:WALL_EMPTY;
297
    mWall[8] = mTmp[0][0][2] ? WALL_MARKED:WALL_EMPTY;
298

    
299
    createVertices(list,mWall,AXIS_XM,0);
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  private void createLeft1(ArrayList<float[]> list)
305
    {
306
    mWall[0] = (!mTmp[0][2][0] && mTmp[1][2][0]) ? WALL_MARKED:WALL_EMPTY;
307
    mWall[1] = (!mTmp[0][2][1] && mTmp[1][2][1]) ? WALL_MARKED:WALL_EMPTY;
308
    mWall[2] = (!mTmp[0][2][2] && mTmp[1][2][2]) ? WALL_MARKED:WALL_EMPTY;
309
    mWall[3] = (!mTmp[0][1][0] && mTmp[1][1][0]) ? WALL_MARKED:WALL_EMPTY;
310
    mWall[4] = (!mTmp[0][1][1] && mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
311
    mWall[5] = (!mTmp[0][1][2] && mTmp[1][1][2]) ? WALL_MARKED:WALL_EMPTY;
312
    mWall[6] = (!mTmp[0][0][0] && mTmp[1][0][0]) ? WALL_MARKED:WALL_EMPTY;
313
    mWall[7] = (!mTmp[0][0][1] && mTmp[1][0][1]) ? WALL_MARKED:WALL_EMPTY;
314
    mWall[8] = (!mTmp[0][0][2] && mTmp[1][0][2]) ? WALL_MARKED:WALL_EMPTY;
315

    
316
    createVertices(list,mWall,AXIS_XM,1);
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  private void createLeft2(ArrayList<float[]> list)
322
    {
323
    mWall[0] = (!mTmp[1][2][0] && mTmp[2][2][0]) ? WALL_MARKED:WALL_EMPTY;
324
    mWall[1] = (!mTmp[1][2][1] && mTmp[2][2][1]) ? WALL_MARKED:WALL_EMPTY;
325
    mWall[2] = (!mTmp[1][2][2] && mTmp[2][2][2]) ? WALL_MARKED:WALL_EMPTY;
326
    mWall[3] = (!mTmp[1][1][0] && mTmp[2][1][0]) ? WALL_MARKED:WALL_EMPTY;
327
    mWall[4] = (!mTmp[1][1][1] && mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
328
    mWall[5] = (!mTmp[1][1][2] && mTmp[2][1][2]) ? WALL_MARKED:WALL_EMPTY;
329
    mWall[6] = (!mTmp[1][0][0] && mTmp[2][0][0]) ? WALL_MARKED:WALL_EMPTY;
330
    mWall[7] = (!mTmp[1][0][1] && mTmp[2][0][1]) ? WALL_MARKED:WALL_EMPTY;
331
    mWall[8] = (!mTmp[1][0][2] && mTmp[2][0][2]) ? WALL_MARKED:WALL_EMPTY;
332

    
333
    createVertices(list,mWall,AXIS_XM,2);
334
    }
335

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  private void createTop0(ArrayList<float[]> list)
339
    {
340
    mWall[0] = (mTmp[0][0][0] && !mTmp[0][1][0]) ? WALL_MARKED:WALL_EMPTY;
341
    mWall[1] = (mTmp[1][0][0] && !mTmp[1][1][0]) ? WALL_MARKED:WALL_EMPTY;
342
    mWall[2] = (mTmp[2][0][0] && !mTmp[2][1][0]) ? WALL_MARKED:WALL_EMPTY;
343
    mWall[3] = (mTmp[0][0][1] && !mTmp[0][1][1]) ? WALL_MARKED:WALL_EMPTY;
344
    mWall[4] = (mTmp[1][0][1] && !mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
345
    mWall[5] = (mTmp[2][0][1] && !mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
346
    mWall[6] = (mTmp[0][0][2] && !mTmp[0][1][2]) ? WALL_MARKED:WALL_EMPTY;
347
    mWall[7] = (mTmp[1][0][2] && !mTmp[1][1][2]) ? WALL_MARKED:WALL_EMPTY;
348
    mWall[8] = (mTmp[2][0][2] && !mTmp[2][1][2]) ? WALL_MARKED:WALL_EMPTY;
349

    
350
    createVertices(list,mWall,AXIS_YP,0);
351
    }
352

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

    
355
  private void createTop1(ArrayList<float[]> list)
356
    {
357
    mWall[0] = (mTmp[0][1][0] && !mTmp[0][2][0]) ? WALL_MARKED:WALL_EMPTY;
358
    mWall[1] = (mTmp[1][1][0] && !mTmp[1][2][0]) ? WALL_MARKED:WALL_EMPTY;
359
    mWall[2] = (mTmp[2][1][0] && !mTmp[2][2][0]) ? WALL_MARKED:WALL_EMPTY;
360
    mWall[3] = (mTmp[0][1][1] && !mTmp[0][2][1]) ? WALL_MARKED:WALL_EMPTY;
361
    mWall[4] = (mTmp[1][1][1] && !mTmp[1][2][1]) ? WALL_MARKED:WALL_EMPTY;
362
    mWall[5] = (mTmp[2][1][1] && !mTmp[2][2][1]) ? WALL_MARKED:WALL_EMPTY;
363
    mWall[6] = (mTmp[0][1][2] && !mTmp[0][2][2]) ? WALL_MARKED:WALL_EMPTY;
364
    mWall[7] = (mTmp[1][1][2] && !mTmp[1][2][2]) ? WALL_MARKED:WALL_EMPTY;
365
    mWall[8] = (mTmp[2][1][2] && !mTmp[2][2][2]) ? WALL_MARKED:WALL_EMPTY;
366

    
367
    createVertices(list,mWall,AXIS_YP,1);
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  private void createTop2(ArrayList<float[]> list)
373
    {
374
    mWall[0] = mTmp[0][2][0] ? WALL_MARKED:WALL_EMPTY;
375
    mWall[1] = mTmp[1][2][0] ? WALL_MARKED:WALL_EMPTY;
376
    mWall[2] = mTmp[2][2][0] ? WALL_MARKED:WALL_EMPTY;
377
    mWall[3] = mTmp[0][2][1] ? WALL_MARKED:WALL_EMPTY;
378
    mWall[4] = mTmp[1][2][1] ? WALL_MARKED:WALL_EMPTY;
379
    mWall[5] = mTmp[2][2][1] ? WALL_MARKED:WALL_EMPTY;
380
    mWall[6] = mTmp[0][2][2] ? WALL_MARKED:WALL_EMPTY;
381
    mWall[7] = mTmp[1][2][2] ? WALL_MARKED:WALL_EMPTY;
382
    mWall[8] = mTmp[2][2][2] ? WALL_MARKED:WALL_EMPTY;
383

    
384
    createVertices(list,mWall,AXIS_YP,2);
385
    }
386

    
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

    
389
  private void createBottom0(ArrayList<float[]> list)
390
    {
391
    mWall[0] = mTmp[0][0][2] ? WALL_MARKED:WALL_EMPTY;
392
    mWall[1] = mTmp[1][0][2] ? WALL_MARKED:WALL_EMPTY;
393
    mWall[2] = mTmp[2][0][2] ? WALL_MARKED:WALL_EMPTY;
394
    mWall[3] = mTmp[0][0][1] ? WALL_MARKED:WALL_EMPTY;
395
    mWall[4] = mTmp[1][0][1] ? WALL_MARKED:WALL_EMPTY;
396
    mWall[5] = mTmp[2][0][1] ? WALL_MARKED:WALL_EMPTY;
397
    mWall[6] = mTmp[0][0][0] ? WALL_MARKED:WALL_EMPTY;
398
    mWall[7] = mTmp[1][0][0] ? WALL_MARKED:WALL_EMPTY;
399
    mWall[8] = mTmp[2][0][0] ? WALL_MARKED:WALL_EMPTY;
400

    
401
    createVertices(list,mWall,AXIS_YM,0);
402
    }
403

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

    
406
  private void createBottom1(ArrayList<float[]> list)
407
    {
408
    mWall[0] = (mTmp[0][1][2] && !mTmp[0][0][2]) ? WALL_MARKED:WALL_EMPTY;
409
    mWall[1] = (mTmp[1][1][2] && !mTmp[1][0][2]) ? WALL_MARKED:WALL_EMPTY;
410
    mWall[2] = (mTmp[2][1][2] && !mTmp[2][0][2]) ? WALL_MARKED:WALL_EMPTY;
411
    mWall[3] = (mTmp[0][1][1] && !mTmp[0][0][1]) ? WALL_MARKED:WALL_EMPTY;
412
    mWall[4] = (mTmp[1][1][1] && !mTmp[1][0][1]) ? WALL_MARKED:WALL_EMPTY;
413
    mWall[5] = (mTmp[2][1][1] && !mTmp[2][0][1]) ? WALL_MARKED:WALL_EMPTY;
414
    mWall[6] = (mTmp[0][1][0] && !mTmp[0][0][0]) ? WALL_MARKED:WALL_EMPTY;
415
    mWall[7] = (mTmp[1][1][0] && !mTmp[1][0][0]) ? WALL_MARKED:WALL_EMPTY;
416
    mWall[8] = (mTmp[2][1][0] && !mTmp[2][0][0]) ? WALL_MARKED:WALL_EMPTY;
417

    
418
    createVertices(list,mWall,AXIS_YM,1);
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

    
423
  private void createBottom2(ArrayList<float[]> list)
424
    {
425
    mWall[0] = (mTmp[0][2][2] && !mTmp[0][1][2]) ? WALL_MARKED:WALL_EMPTY;
426
    mWall[1] = (mTmp[1][2][2] && !mTmp[1][1][2]) ? WALL_MARKED:WALL_EMPTY;
427
    mWall[2] = (mTmp[2][2][2] && !mTmp[2][1][2]) ? WALL_MARKED:WALL_EMPTY;
428
    mWall[3] = (mTmp[0][2][1] && !mTmp[0][1][1]) ? WALL_MARKED:WALL_EMPTY;
429
    mWall[4] = (mTmp[1][2][1] && !mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
430
    mWall[5] = (mTmp[2][2][1] && !mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
431
    mWall[6] = (mTmp[0][2][0] && !mTmp[0][1][0]) ? WALL_MARKED:WALL_EMPTY;
432
    mWall[7] = (mTmp[1][2][0] && !mTmp[1][1][0]) ? WALL_MARKED:WALL_EMPTY;
433
    mWall[8] = (mTmp[2][2][0] && !mTmp[2][1][0]) ? WALL_MARKED:WALL_EMPTY;
434

    
435
    createVertices(list,mWall,AXIS_YM,2);
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  private void createFront0(ArrayList<float[]> list)
441
    {
442
    mWall[0] = (mTmp[0][2][0] && !mTmp[0][2][1]) ? WALL_MARKED:WALL_EMPTY;
443
    mWall[1] = (mTmp[1][2][0] && !mTmp[1][2][1]) ? WALL_MARKED:WALL_EMPTY;
444
    mWall[2] = (mTmp[2][2][0] && !mTmp[2][2][1]) ? WALL_MARKED:WALL_EMPTY;
445
    mWall[3] = (mTmp[0][1][0] && !mTmp[0][1][1]) ? WALL_MARKED:WALL_EMPTY;
446
    mWall[4] = (mTmp[1][1][0] && !mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
447
    mWall[5] = (mTmp[2][1][0] && !mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
448
    mWall[6] = (mTmp[0][0][0] && !mTmp[0][0][1]) ? WALL_MARKED:WALL_EMPTY;
449
    mWall[7] = (mTmp[1][0][0] && !mTmp[1][0][1]) ? WALL_MARKED:WALL_EMPTY;
450
    mWall[8] = (mTmp[2][0][0] && !mTmp[2][0][1]) ? WALL_MARKED:WALL_EMPTY;
451

    
452
    createVertices(list,mWall,AXIS_ZP,0);
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  private void createFront1(ArrayList<float[]> list)
458
    {
459
    mWall[0] = (mTmp[0][2][1] && !mTmp[0][2][2]) ? WALL_MARKED:WALL_EMPTY;
460
    mWall[1] = (mTmp[1][2][1] && !mTmp[1][2][2]) ? WALL_MARKED:WALL_EMPTY;
461
    mWall[2] = (mTmp[2][2][1] && !mTmp[2][2][2]) ? WALL_MARKED:WALL_EMPTY;
462
    mWall[3] = (mTmp[0][1][1] && !mTmp[0][1][2]) ? WALL_MARKED:WALL_EMPTY;
463
    mWall[4] = (mTmp[1][1][1] && !mTmp[1][1][2]) ? WALL_MARKED:WALL_EMPTY;
464
    mWall[5] = (mTmp[2][1][1] && !mTmp[2][1][2]) ? WALL_MARKED:WALL_EMPTY;
465
    mWall[6] = (mTmp[0][0][1] && !mTmp[0][0][2]) ? WALL_MARKED:WALL_EMPTY;
466
    mWall[7] = (mTmp[1][0][1] && !mTmp[1][0][2]) ? WALL_MARKED:WALL_EMPTY;
467
    mWall[8] = (mTmp[2][0][1] && !mTmp[2][0][2]) ? WALL_MARKED:WALL_EMPTY;
468

    
469
    createVertices(list,mWall,AXIS_ZP,1);
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  private void createFront2(ArrayList<float[]> list)
475
    {
476
    mWall[0] = mTmp[0][2][2] ? WALL_MARKED:WALL_EMPTY;
477
    mWall[1] = mTmp[1][2][2] ? WALL_MARKED:WALL_EMPTY;
478
    mWall[2] = mTmp[2][2][2] ? WALL_MARKED:WALL_EMPTY;
479
    mWall[3] = mTmp[0][1][2] ? WALL_MARKED:WALL_EMPTY;
480
    mWall[4] = mTmp[1][1][2] ? WALL_MARKED:WALL_EMPTY;
481
    mWall[5] = mTmp[2][1][2] ? WALL_MARKED:WALL_EMPTY;
482
    mWall[6] = mTmp[0][0][2] ? WALL_MARKED:WALL_EMPTY;
483
    mWall[7] = mTmp[1][0][2] ? WALL_MARKED:WALL_EMPTY;
484
    mWall[8] = mTmp[2][0][2] ? WALL_MARKED:WALL_EMPTY;
485

    
486
    createVertices(list,mWall,AXIS_ZP,2);
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  private void createBack0(ArrayList<float[]> list)
492
    {
493
    mWall[0] = mTmp[2][2][0] ? WALL_MARKED:WALL_EMPTY;
494
    mWall[1] = mTmp[1][2][0] ? WALL_MARKED:WALL_EMPTY;
495
    mWall[2] = mTmp[0][2][0] ? WALL_MARKED:WALL_EMPTY;
496
    mWall[3] = mTmp[2][1][0] ? WALL_MARKED:WALL_EMPTY;
497
    mWall[4] = mTmp[1][1][0] ? WALL_MARKED:WALL_EMPTY;
498
    mWall[5] = mTmp[0][1][0] ? WALL_MARKED:WALL_EMPTY;
499
    mWall[6] = mTmp[2][0][0] ? WALL_MARKED:WALL_EMPTY;
500
    mWall[7] = mTmp[1][0][0] ? WALL_MARKED:WALL_EMPTY;
501
    mWall[8] = mTmp[0][0][0] ? WALL_MARKED:WALL_EMPTY;
502

    
503
    createVertices(list,mWall,AXIS_ZM,0);
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  private void createBack1(ArrayList<float[]> list)
509
    {
510
    mWall[0] = (mTmp[2][2][1] && !mTmp[2][2][0]) ? WALL_MARKED:WALL_EMPTY;
511
    mWall[1] = (mTmp[1][2][1] && !mTmp[1][2][0]) ? WALL_MARKED:WALL_EMPTY;
512
    mWall[2] = (mTmp[0][2][1] && !mTmp[0][2][0]) ? WALL_MARKED:WALL_EMPTY;
513
    mWall[3] = (mTmp[2][1][1] && !mTmp[2][1][0]) ? WALL_MARKED:WALL_EMPTY;
514
    mWall[4] = (mTmp[1][1][1] && !mTmp[1][1][0]) ? WALL_MARKED:WALL_EMPTY;
515
    mWall[5] = (mTmp[0][1][1] && !mTmp[0][1][0]) ? WALL_MARKED:WALL_EMPTY;
516
    mWall[6] = (mTmp[2][0][1] && !mTmp[2][0][0]) ? WALL_MARKED:WALL_EMPTY;
517
    mWall[7] = (mTmp[1][0][1] && !mTmp[1][0][0]) ? WALL_MARKED:WALL_EMPTY;
518
    mWall[8] = (mTmp[0][0][1] && !mTmp[0][0][0]) ? WALL_MARKED:WALL_EMPTY;
519

    
520
    createVertices(list,mWall,AXIS_ZM,1);
521
    }
522

    
523
///////////////////////////////////////////////////////////////////////////////////////////////////
524

    
525
  private void createBack2(ArrayList<float[]> list)
526
    {
527
    mWall[0] = (mTmp[2][2][2] && !mTmp[2][2][1]) ? WALL_MARKED:WALL_EMPTY;
528
    mWall[1] = (mTmp[1][2][2] && !mTmp[1][2][1]) ? WALL_MARKED:WALL_EMPTY;
529
    mWall[2] = (mTmp[0][2][2] && !mTmp[0][2][1]) ? WALL_MARKED:WALL_EMPTY;
530
    mWall[3] = (mTmp[2][1][2] && !mTmp[2][1][1]) ? WALL_MARKED:WALL_EMPTY;
531
    mWall[4] = (mTmp[1][1][2] && !mTmp[1][1][1]) ? WALL_MARKED:WALL_EMPTY;
532
    mWall[5] = (mTmp[0][1][2] && !mTmp[0][1][1]) ? WALL_MARKED:WALL_EMPTY;
533
    mWall[6] = (mTmp[2][0][2] && !mTmp[2][0][1]) ? WALL_MARKED:WALL_EMPTY;
534
    mWall[7] = (mTmp[1][0][2] && !mTmp[1][0][1]) ? WALL_MARKED:WALL_EMPTY;
535
    mWall[8] = (mTmp[0][0][2] && !mTmp[0][0][1]) ? WALL_MARKED:WALL_EMPTY;
536

    
537
    createVertices(list,mWall,AXIS_ZM,2);
538
    }
539

    
540
///////////////////////////////////////////////////////////////////////////////////////////////////
541

    
542
  private void markNeighbours(int[] wall, int index, int section)
543
    {
544
    wall[index] = section;
545

    
546
    switch(index)
547
      {
548
      case 0: if( wall[1]==WALL_MARKED ) markNeighbours(wall,1,section);
549
              if( wall[3]==WALL_MARKED ) markNeighbours(wall,3,section);
550
              break;
551
      case 1: if( wall[0]==WALL_MARKED ) markNeighbours(wall,0,section);
552
              if( wall[2]==WALL_MARKED ) markNeighbours(wall,2,section);
553
              if( wall[4]==WALL_MARKED ) markNeighbours(wall,4,section);
554
              break;
555
      case 2: if( wall[1]==WALL_MARKED ) markNeighbours(wall,1,section);
556
              if( wall[5]==WALL_MARKED ) markNeighbours(wall,5,section);
557
              break;
558
      case 3: if( wall[0]==WALL_MARKED ) markNeighbours(wall,0,section);
559
              if( wall[4]==WALL_MARKED ) markNeighbours(wall,4,section);
560
              if( wall[6]==WALL_MARKED ) markNeighbours(wall,6,section);
561
              break;
562
      case 4: if( wall[1]==WALL_MARKED ) markNeighbours(wall,1,section);
563
              if( wall[3]==WALL_MARKED ) markNeighbours(wall,3,section);
564
              if( wall[5]==WALL_MARKED ) markNeighbours(wall,5,section);
565
              if( wall[7]==WALL_MARKED ) markNeighbours(wall,7,section);
566
              break;
567
      case 5: if( wall[2]==WALL_MARKED ) markNeighbours(wall,2,section);
568
              if( wall[4]==WALL_MARKED ) markNeighbours(wall,4,section);
569
              if( wall[8]==WALL_MARKED ) markNeighbours(wall,8,section);
570
              break;
571
      case 6: if( wall[3]==WALL_MARKED ) markNeighbours(wall,3,section);
572
              if( wall[7]==WALL_MARKED ) markNeighbours(wall,7,section);
573
              break;
574
      case 7: if( wall[4]==WALL_MARKED ) markNeighbours(wall,4,section);
575
              if( wall[6]==WALL_MARKED ) markNeighbours(wall,6,section);
576
              if( wall[8]==WALL_MARKED ) markNeighbours(wall,8,section);
577
              break;
578
      case 8: if( wall[5]==WALL_MARKED ) markNeighbours(wall,5,section);
579
              if( wall[7]==WALL_MARKED ) markNeighbours(wall,7,section);
580
              break;
581
      }
582
    }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

    
586
  private int markSections(int[] wall)
587
    {
588
    int sections = 0;
589

    
590
    for(int i=0; i<9; i++)
591
      if( wall[i]==WALL_MARKED )
592
        {
593
        sections++;
594
        markNeighbours(wall,i,sections);
595
        }
596

    
597
    return sections;
598
    }
599

    
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601
// return true iff exactly three or exactly one of the four values (x1,x2,x3,x4) are equal to 'value'.
602

    
603
  private boolean threeOrOne(int x1, int x2, int x3, int x4, int value)
604
    {
605
    if( x1==value ) return x2==value ? (x3==value)^(x4==value) : (x3==value)^(x4!=value);
606
    else            return x2==value ? (x3==value)^(x4!=value) : (x3==value)^(x4==value);
607
    }
608

    
609
///////////////////////////////////////////////////////////////////////////////////////////////////
610

    
611
  private int buildPoints(int[] wall, int section)
612
    {
613
    mPoints[0][0] = (wall[0]==section                   ) ? 0 : -1;
614
    mPoints[1][0] = (wall[0]==section)^(wall[1]==section) ? 0 : -1;
615
    mPoints[2][0] = (wall[1]==section)^(wall[2]==section) ? 0 : -1;
616
    mPoints[3][0] = (wall[2]==section                   ) ? 0 : -1;
617
    mPoints[0][1] = (wall[0]==section)^(wall[3]==section) ? 0 : -1;
618
    mPoints[1][1] = threeOrOne(wall[0],wall[1],wall[3],wall[4],section) ? 0 : -1;
619
    mPoints[2][1] = threeOrOne(wall[1],wall[2],wall[4],wall[5],section) ? 0 : -1;
620
    mPoints[3][1] = (wall[2]==section)^(wall[5]==section) ? 0 : -1;
621
    mPoints[0][2] = (wall[3]==section)^(wall[6]==section) ? 0 : -1;
622
    mPoints[1][2] = threeOrOne(wall[3],wall[4],wall[6],wall[7],section) ? 0 : -1;
623
    mPoints[2][2] = threeOrOne(wall[4],wall[5],wall[7],wall[8],section) ? 0 : -1;
624
    mPoints[3][2] = (wall[5]==section)^(wall[8]==section) ? 0 : -1;
625
    mPoints[0][3] = (wall[6]==section                   ) ? 0 : -1;
626
    mPoints[1][3] = (wall[6]==section)^(wall[7]==section) ? 0 : -1;
627
    mPoints[2][3] = (wall[7]==section)^(wall[8]==section) ? 0 : -1;
628
    mPoints[3][3] = (wall[8]==section                   ) ? 0 : -1;
629

    
630
    int numPoints=0;
631

    
632
    for(int i=0; i<4; i++)
633
      for(int j=0; j<4; j++)
634
        {
635
        if( mPoints[i][j]==0 ) numPoints++;
636
        }
637

    
638
    return numPoints;
639
    }
640

    
641
///////////////////////////////////////////////////////////////////////////////////////////////////
642

    
643
  private boolean isOddVertical(int x, int y)
644
    {
645
    int number = 0;
646

    
647
    for(int i=0; i<y; i++)
648
      if( mPoints[x][i]==0 ) number++;
649

    
650
    return (number%2)==0;
651
    }
652

    
653
///////////////////////////////////////////////////////////////////////////////////////////////////
654

    
655
  private boolean isOddHorizontal(int x, int y)
656
    {
657
    int number = 0;
658

    
659
    for(int i=0; i<x; i++)
660
      if( mPoints[i][y]==0 ) number++;
661

    
662
    return (number%2)==0;
663
    }
664

    
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666

    
667
  private int moveUp(int x, int y)
668
    {
669
    for(int i=y-1; i>=0; i--)
670
      if( mPoints[x][i]==0 ) return i;
671

    
672
    android.util.Log.e("D", "moveUp error!");
673
    return 0;
674
    }
675

    
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677

    
678
  private int moveDown(int x, int y)
679
    {
680
    for(int i=y+1; i<4; i++)
681
      if( mPoints[x][i]==0 ) return i;
682

    
683
    android.util.Log.e("D", "moveDown error!");
684
    return 0;
685
    }
686

    
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

    
689
  private int moveLeft(int x, int y)
690
    {
691
    for(int i=x-1; i>=0; i--)
692
      if( mPoints[i][y]==0 ) return i;
693

    
694
    android.util.Log.e("D", "moveLeft error!");
695
    return 0;
696
    }
697

    
698
///////////////////////////////////////////////////////////////////////////////////////////////////
699

    
700
  private int moveRight(int x, int y)
701
    {
702
    for(int i=x+1; i<4; i++)
703
      if( mPoints[i][y]==0 ) return i;
704

    
705
    android.util.Log.e("D", "moveRight error!");
706
    return 0;
707
    }
708

    
709
///////////////////////////////////////////////////////////////////////////////////////////////////
710

    
711
  private float[] buildVertices(int[] wall, int section)
712
    {
713
    int numPoints = buildPoints(wall,section);
714
    int numSections = numPoints/2;
715
    float[] vertices = new float[3*numPoints];
716
    int x=0,y=0,pointer=0;
717

    
718
    for(int i=0; i<4; i++)
719
      for(int j=0; j<4; j++)
720
        if( mPoints[i][j]==0 )
721
          {
722
          x = i;
723
          y = j;
724
          i = j = 4;
725
          }
726

    
727
    for(int s=0; s<numSections; s++)
728
      {
729
      vertices[6*pointer  ] = x-1.5f;
730
      vertices[6*pointer+1] = 1.5f-y;
731
      vertices[6*pointer+2] = 0.0f;
732

    
733
      y = isOddVertical(x,y) ? moveDown(x,y) : moveUp(x,y);
734

    
735
      vertices[6*pointer+3] = x-1.5f;
736
      vertices[6*pointer+4] = 1.5f-y;
737
      vertices[6*pointer+5] = 0.0f;
738

    
739
      x = isOddHorizontal(x,y) ? moveRight(x,y) : moveLeft(x,y);
740

    
741
      pointer++;
742
      }
743

    
744
    return vertices;
745
    }
746

    
747
///////////////////////////////////////////////////////////////////////////////////////////////////
748

    
749
  private void rotateAndMoveVertices(float[] vertices, int axis, int layer)
750
    {
751
    int i,len = vertices.length/3;
752

    
753
    switch(axis)
754
      {
755
      case AXIS_XP: for(i=0; i<len; i++)
756
                      {
757
                      vertices[3*i+2] = -vertices[3*i];
758
                      vertices[3*i  ] = layer-0.5f;
759
                      }
760
                    break;
761
      case AXIS_XM: for(i=0; i<len; i++)
762
                      {
763
                      vertices[3*i+2] = vertices[3*i];
764
                      vertices[3*i  ] = layer-1.5f;
765
                      }
766
                    break;
767
      case AXIS_YP: for(i=0; i<len; i++)
768
                      {
769
                      vertices[3*i+2] = -vertices[3*i+1];
770
                      vertices[3*i+1] = layer-0.5f;
771
                      }
772
                    break;
773
      case AXIS_YM: for(i=0; i<len; i++)
774
                      {
775
                      vertices[3*i+2] = vertices[3*i+1];
776
                      vertices[3*i+1] = layer-1.5f;
777
                      }
778
                    break;
779
      case AXIS_ZP: for(i=0; i<len; i++)
780
                      {
781
                      vertices[3*i+2] = layer-0.5f;
782
                      }
783
                    break;
784
      case AXIS_ZM: for(i=0; i<len; i++)
785
                      {
786
                      vertices[3*i  ] = -vertices[3*i];
787
                      vertices[3*i+2] = layer-1.5f;
788
                      }
789
                    break;
790
      }
791
    }
792

    
793
///////////////////////////////////////////////////////////////////////////////////////////////////
794
// 1. assume the 'wall' is in the XY plane
795
// 2. split the wall into individual connected regions and for each such region:
796
//   a. build the list of vertices (Z=0)
797
//   b. take the axis into consideration and rotate the vertices.
798
//   c. take layer into consideration and move the vertices.
799
//   d. add the resulting vertices to the list.
800

    
801
  private void createVertices(ArrayList<float[]> list, int[] wall, int axis, int layer)
802
    {
803
    int sections = markSections(wall);
804

    
805
    for(int i=0; i<sections; i++)
806
      {
807
      float[] vertices = buildVertices(wall,i+1);
808

    
809
      rotateAndMoveVertices(vertices,axis,layer);
810
      list.add(vertices);
811
/*
812
      int len = vertices.length/3;
813
      String w="";
814

    
815
      for(int j=0; j<len; j++)
816
        {
817
        w += ( "["+vertices[3*j]+" "+vertices[3*j+1]+" "+vertices[3*j+2]+"] ");
818
        }
819
      android.util.Log.e("D", i+" vertices after: "+w);
820
*/
821
      }
822
    }
823

    
824
///////////////////////////////////////////////////////////////////////////////////////////////////
825

    
826
  private static boolean vertInFace(float[] vertex, float[] move, Static3D faceAxis, float dist)
827
    {
828
    final float MAX_ERROR = 0.01f;
829

    
830
    float x= faceAxis.get0();
831
    float y= faceAxis.get1();
832
    float z= faceAxis.get2();
833

    
834
    float a = (vertex[0]+move[0])*x + (vertex[1]+move[1])*y + (vertex[2]+move[2])*z;
835
    float diff = a - dist;
836

    
837
    return diff>-MAX_ERROR && diff<MAX_ERROR;
838
    }
839

    
840
///////////////////////////////////////////////////////////////////////////////////////////////////
841
// (vertices,indices) define a cubit face, i.e. a connected subset of the 3x3 grid.
842
// Return its 'diameter', i.e. max(width,height)
843

    
844
  private int faceDiameter(float[][] vertices, int[] indices)
845
    {
846
    float maxX = -1.5f;
847
    float minX = +1.5f;
848
    float maxY = -1.5f;
849
    float minY = +1.5f;
850
    float maxZ = -1.5f;
851
    float minZ = +1.5f;
852

    
853
    for (int index : indices)
854
      {
855
      float[] v = vertices[index];
856

    
857
      if (v[0] > maxX) maxX = v[0];
858
      if (v[0] < minX) minX = v[0];
859
      if (v[1] > maxY) maxY = v[1];
860
      if (v[1] < minY) minY = v[1];
861
      if (v[2] > maxZ) maxZ = v[2];
862
      if (v[2] < minZ) minZ = v[2];
863
      }
864

    
865
    float diffX = maxX-minX;
866
    float diffY = maxY-minY;
867
    float diffZ = maxZ-minZ;
868

    
869
    float max = diffX>diffY ? Math.max(diffX,diffZ) : Math.max(diffY,diffZ);
870

    
871
    return (int)max;
872
    }
873

    
874
///////////////////////////////////////////////////////////////////////////////////////////////////
875
// return array of:
876
// 0 if this is an inner face, 1 if its diameter is 1, 2 if diameter is 2, 3 if 3.
877

    
878
  private int[] generateBandIndices(float[][] vertices, int[][] indices, float[] move)
879
    {
880
    int numCubitFaces = indices.length;
881
    int[] bandIndices = new int[numCubitFaces];
882

    
883
    for(int cubitFace=0; cubitFace<numCubitFaces; cubitFace++)
884
      {
885
      bandIndices[cubitFace] = 0xffffffff;
886
      int numVertices = indices[cubitFace].length;
887

    
888
      for(int vertex=0; vertex<numVertices; vertex++)
889
        {
890
        int vertBelongsBitmap = 0x00000000;
891

    
892
        for(int face=0; face<6; face++)
893
          {
894
          float[] vert = vertices[ indices[cubitFace][vertex] ];
895
          if( vertInFace(vert, move, TouchControlHexahedron.FACE_AXIS[face],1.5f) )
896
            {
897
            vertBelongsBitmap |= (1<<face);
898
            }
899
          }
900

    
901
        bandIndices[cubitFace] &= vertBelongsBitmap;
902
        }
903

    
904
      if( bandIndices[cubitFace]!=0 ) // outer face
905
        {
906
        bandIndices[cubitFace] = faceDiameter(vertices, indices[cubitFace]);
907
        }
908

    
909
      //android.util.Log.e("D", "cubit face "+cubitFace+" : "+bandIndices[cubitFace]);
910
      }
911

    
912
    return bandIndices;
913
    }
914

    
915
///////////////////////////////////////////////////////////////////////////////////////////////////
916

    
917
  private int[] generateCornerIndices(float[][] vertices, boolean roundCorners)
918
    {
919
    int len = vertices.length;
920
    int val = roundCorners ? 0 : -1;
921
    int[] cornerIndices = new int[len];
922
    for(int i=0; i<len; i++) cornerIndices[i] = val;
923
    return cornerIndices;
924
    }
925

    
926
///////////////////////////////////////////////////////////////////////////////////////////////////
927

    
928
  private int computeVectorFace(float[] prev, float[] curr, float[] next)
929
    {
930
    float ax = prev[0]-curr[0];
931
    float ay = prev[1]-curr[1];
932
    float az = prev[2]-curr[2];
933

    
934
    float bx = next[0]-curr[0];
935
    float by = next[1]-curr[1];
936
    float bz = next[2]-curr[2];
937

    
938
    float lena = (float)Math.sqrt(ax*ax + ay*ay + az*az);
939
    float lenb = (float)Math.sqrt(bx*bx + by*by + bz*bz);
940

    
941
    ax /= lena;
942
    ay /= lena;
943
    az /= lena;
944

    
945
    bx /= lenb;
946
    by /= lenb;
947
    bz /= lenb;
948

    
949
    float cx = ax + bx + ay*bz-az*by;
950
    float cy = ay + by + az*bx-ax*bz;
951
    float cz = az + bz + ax*by-ay*bx;
952

    
953
    return (cx<0 ? 0:4) + (cy<0 ? 0:2) + (cz<0 ? 0:1);
954
    }
955

    
956
///////////////////////////////////////////////////////////////////////////////////////////////////
957

    
958
  private float[] computeVector(int index, float[][] vertices, int[][] indices, int[] bandIndices)
959
    {
960
    int band=0;
961
    int len = indices.length;
962
    int vector=-1;
963

    
964
    for(int i=0; i<len; i++)
965
      {
966
      int len2 = indices[i].length;
967

    
968
      for(int j=0; j<len2; j++)
969
        {
970
        if( indices[i][j]==index )
971
          {
972
          int prev = j>0 ? j-1 : len2-1;
973
          int next = j<len2-1 ? j+1 : 0;
974

    
975
          int prevIndex = indices[i][prev];
976
          int currIndex = indices[i][j];
977
          int nextIndex = indices[i][next];
978

    
979
          int newVector = computeVectorFace(vertices[prevIndex],vertices[currIndex],vertices[nextIndex]);
980
          if( vector!=-1 && vector!=newVector ) return null;
981

    
982
          vector = newVector;
983
          band |= bandIndices[i];
984
          }
985
        }
986
      }
987

    
988
    return band==0 ? null : VECTOR[vector];
989
    }
990

    
991
///////////////////////////////////////////////////////////////////////////////////////////////////
992

    
993
  private float[][] generateVectors(float[][] vertices, int[][] indices, int[] bandIndices)
994
    {
995
    int len = vertices.length;
996
    float[][] vectors = new float[len][];
997

    
998
    for(int i=0; i<len; i++)
999
      {
1000
      vectors[i] = computeVector(i,vertices,indices,bandIndices);
1001
      }
1002

    
1003
    return vectors;
1004
    }
1005

    
1006
///////////////////////////////////////////////////////////////////////////////////////////////////
1007

    
1008
  private float[][] generateCenters(float[][] vertices, float[][] vectors)
1009
    {
1010
    int pointer=0,total=0;
1011
    int len = vertices.length;
1012

    
1013
    for( float[] vector : vectors )
1014
      {
1015
      if( vector!=null ) total++;
1016
      }
1017

    
1018
    float[][] centers = new float[total][3];
1019

    
1020
    for( int i=0; i<len; i++ )
1021
      {
1022
      if( vectors[i]!=null )
1023
        {
1024
        centers[pointer][0] = vertices[i][0]+vectors[i][0];
1025
        centers[pointer][1] = vertices[i][1]+vectors[i][1];
1026
        centers[pointer][2] = vertices[i][2]+vectors[i][2];
1027
        pointer++;
1028
        }
1029
      }
1030

    
1031
    return centers;
1032
    }
1033

    
1034
///////////////////////////////////////////////////////////////////////////////////////////////////
1035

    
1036
  private int[] generateCenterIndices(float[][] vectors)
1037
    {
1038
    int pointer=0;
1039
    int len = vectors.length;
1040
    int[] centerIndices = new int[len];
1041

    
1042
    for(int i=0; i<len; i++)
1043
      {
1044
      if( vectors[i]==null )
1045
        {
1046
        centerIndices[i] = -1;
1047
        }
1048
      else
1049
        {
1050
        centerIndices[i] = pointer;
1051
        pointer++;
1052
        }
1053
      }
1054

    
1055
    return centerIndices;
1056
    }
1057

    
1058
///////////////////////////////////////////////////////////////////////////////////////////////////
1059
// PUBLIC API
1060

    
1061
  public static FactoryBandaged3x3Cubit getInstance()
1062
    {
1063
    if( mThis==null ) mThis = new FactoryBandaged3x3Cubit();
1064
    return mThis;
1065
    }
1066

    
1067
///////////////////////////////////////////////////////////////////////////////////////////////////
1068

    
1069
  public void prepare(int numVariants)
1070
    {
1071
    if( mVertexArray==null ) mVertexArray = new ArrayList<>();
1072
    mVertices= new float[numVariants][][];
1073
    mIndices = new int[numVariants][][];
1074
    mMove = new float[numVariants][3];
1075
    }
1076

    
1077
///////////////////////////////////////////////////////////////////////////////////////////////////
1078

    
1079
  public ObjectShape createIrregularShape(int variant, float[] pos)
1080
    {
1081
    mVertexArray.clear();
1082

    
1083
    for(int x=0; x<3; x++)
1084
      for(int y=0; y<3; y++)
1085
        for(int z=0; z<3; z++)
1086
          {
1087
          mTmp[x][y][z] = cubitExists(pos,x-1.0f,y-1.0f,z-1.0f);
1088
          }
1089

    
1090
    createRight0(mVertexArray);
1091
    createRight1(mVertexArray);
1092
    createRight2(mVertexArray);
1093

    
1094
    createLeft0(mVertexArray);
1095
    createLeft1(mVertexArray);
1096
    createLeft2(mVertexArray);
1097

    
1098
    createTop0(mVertexArray);
1099
    createTop1(mVertexArray);
1100
    createTop2(mVertexArray);
1101

    
1102
    createBottom0(mVertexArray);
1103
    createBottom1(mVertexArray);
1104
    createBottom2(mVertexArray);
1105

    
1106
    createFront0(mVertexArray);
1107
    createFront1(mVertexArray);
1108
    createFront2(mVertexArray);
1109

    
1110
    createBack0(mVertexArray);
1111
    createBack1(mVertexArray);
1112
    createBack2(mVertexArray);
1113

    
1114
    float[][] verts = getVertices(mVertexArray,pos,variant);
1115
    int[][] inds    = getIndices(mVertexArray);
1116

    
1117
    compressVerticesAndIndices(variant,verts,inds);
1118

    
1119
    return new ObjectShape(mVertices[variant], mIndices[variant]);
1120
    }
1121

    
1122
///////////////////////////////////////////////////////////////////////////////////////////////////
1123

    
1124
  private void debug(float[][] vert, int[][] ind)
1125
    {
1126
    String vv="VERTICES: ";
1127
    for (float[] floats : vert)
1128
      {
1129
      vv += "\n";
1130
      int lenV2 = floats.length / 3;
1131

    
1132
      for (int v2 = 0; v2 < lenV2; v2++)
1133
        {
1134
        vv += " {";
1135
        vv += (floats[3 * v2] + " ");
1136
        vv += (floats[3 * v2 + 1] + " ");
1137
        vv += (floats[3 * v2 + 2] + " ");
1138
        vv += "}";
1139
        }
1140
      }
1141
    android.util.Log.e("D", vv);
1142

    
1143
    String ii="INDICES: ";
1144
    for (int[] ints : ind)
1145
      {
1146
      ii += "\n";
1147
      int lenI2 = ints.length;
1148

    
1149
      for (int i2 = 0; i2 < lenI2; i2++)
1150
        {
1151
        ii += (ints[i2] + " ");
1152
        }
1153
      }
1154
    android.util.Log.e("D", ii);
1155
    }
1156

    
1157
///////////////////////////////////////////////////////////////////////////////////////////////////
1158

    
1159
  public ObjectFaceShape createIrregularFaceShape(int variant, boolean iconMode, boolean roundCorners)
1160
    {
1161
    float height   = iconMode ? 0.001f : 0.05f;
1162
    int angle      = 60;
1163
    float R        = 0.2f;
1164
    float S        = 0.7f;
1165
    int numVertices= 5;
1166
    int extraI     = 1;
1167
    int extraV     = 1;
1168

    
1169
    float[][] corners   = { {0.02f,0.12f} };
1170
    float[][] bands     = { {  0.001f,angle,R,S,numVertices,extraV,extraI},
1171
                            {height/1,angle,R,S,numVertices,extraV,extraI},
1172
                            {height/2,angle,R,S,numVertices,extraV,extraI},
1173
                            {height/3,angle,R,S,numVertices,extraV,extraI} };
1174

    
1175
    int[] bandIndices   = generateBandIndices(mVertices[variant], mIndices[variant], mMove[variant]);
1176
    int[] cornerIndices = generateCornerIndices(mVertices[variant], roundCorners);
1177
    float[][] vertexVec = generateVectors(mVertices[variant], mIndices[variant], bandIndices);
1178
    float[][] centers   = generateCenters(mVertices[variant], vertexVec);
1179
    int[] centerIndices = generateCenterIndices(vertexVec);
1180

    
1181
    return new ObjectFaceShape(bands,bandIndices,corners,cornerIndices,centers,centerIndices,null);
1182
    }
1183

    
1184
///////////////////////////////////////////////////////////////////////////////////////////////////
1185

    
1186
  public MeshBase createMesh(float[] pos, boolean iconMode, boolean roundCorners)
1187
    {
1188
    prepare(1);
1189
    ObjectShape shape    = createIrregularShape(0,pos);
1190
    ObjectFaceShape face = createIrregularFaceShape(0,iconMode,roundCorners);
1191
    int[][] indices      = shape.getVertIndices();
1192
    int numComponents    = indices.length;
1193

    
1194
    FactoryCubit factory = FactoryCubit.getInstance();
1195
    factory.clear();
1196
    factory.createNewFaceTransform(shape,null);
1197
    return factory.createRoundedSolid(shape,face,MESH_NICE,numComponents);
1198
    }
1199
  }
(2-2/10)