Project

General

Profile

Download (90.9 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / helpers / FactoryCubit.java @ 31cd7256

1 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 749ef882 Leszek Koltunski
package org.distorted.helpers;
21 ac940e24 Leszek Koltunski
22 b1f2ccf5 Leszek Koltunski
import org.distorted.library.effect.MatrixEffectMove;
23
import org.distorted.library.effect.MatrixEffectQuaternion;
24
import org.distorted.library.effect.MatrixEffectScale;
25 68f6046c Leszek Koltunski
import org.distorted.library.effect.VertexEffect;
26 ac940e24 Leszek Koltunski
import org.distorted.library.effect.VertexEffectDeform;
27
import org.distorted.library.effect.VertexEffectMove;
28
import org.distorted.library.effect.VertexEffectRotate;
29
import org.distorted.library.effect.VertexEffectScale;
30
import org.distorted.library.mesh.MeshBase;
31
import org.distorted.library.mesh.MeshJoined;
32
import org.distorted.library.mesh.MeshPolygon;
33
import org.distorted.library.type.Static1D;
34
import org.distorted.library.type.Static3D;
35
import org.distorted.library.type.Static4D;
36
37 b1f2ccf5 Leszek Koltunski
import java.util.ArrayList;
38
39 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 749ef882 Leszek Koltunski
public class FactoryCubit
42 ac940e24 Leszek Koltunski
  {
43
  private static final float SQ2 = (float)Math.sqrt(2);
44
  private static final float SQ3 = (float)Math.sqrt(3);
45 4e627d8b Leszek Koltunski
  private static final float SQ5 = (float)Math.sqrt(5);
46 68f6046c Leszek Koltunski
  private static final float SQ6 = (float)Math.sqrt(6);
47 ac940e24 Leszek Koltunski
48 b5347187 Leszek Koltunski
  private static final Static1D RADIUS = new Static1D(1);
49
  private static FactoryCubit mThis;
50
51
  // IVY
52
  static final float IVY_D = 0.003f;
53
  static final float IVY_C = 0.59f;
54
  static final float IVY_M = 0.35f;
55
  private static final int IVY_N = 8;
56
57
  // REX
58 749ef882 Leszek Koltunski
  public static final float REX_D = 0.2f;
59 b5347187 Leszek Koltunski
60
  // KILO / MEGAMINX
61 749ef882 Leszek Koltunski
  public static final float SIN54    = (SQ5+1)/4;
62
  public static final float COS54    = (float)(Math.sqrt(10-2*SQ5)/4);
63
  public static final float SIN18    = (SQ5-1)/4;
64
  public static final float COS18    = (float)(0.25f*Math.sqrt(10.0f+2.0f*SQ5));
65
  public static final float COS_HALFD= (float)(Math.sqrt(0.5f-0.1f*SQ5)); // cos(half the dihedral angle)
66
  public static final float SIN_HALFD= (float)(Math.sqrt(0.5f+0.1f*SQ5)); // sin(half the dihedral angle)
67
  public static final float DIHEDRAL1= (float)(Math.acos(-SQ5/5)*180/Math.PI);
68
  public static final float DIHEDRAL2= (float)((180/Math.PI)*Math.asin((2*SIN54*SIN54-1)/COS54) - 90);
69
  public static final float MINX_SC  = 0.5f;
70 4e627d8b Leszek Koltunski
71 b1f2ccf5 Leszek Koltunski
72
  private static final double[] mBuffer = new double[3];
73
  private static final double[] mQuat1  = new double[4];
74
  private static final double[] mQuat2  = new double[4];
75
  private static final double[] mQuat3  = new double[4];
76
  private static final double[] mQuat4  = new double[4];
77
78
  private static class StickerCoords
79
    {
80
    double[] vertices;
81
    }
82
83
  private static class FaceTransform
84
    {
85
    int sticker;
86
    double vx,vy,vz;
87
    double scale;
88
    double qx,qy,qz,qw;
89
    boolean flip;
90
    }
91
92 31cd7256 Leszek Koltunski
  private static final ArrayList<FaceTransform> mNewFaceTransf = new ArrayList<>();
93
  private static final ArrayList<FaceTransform> mOldFaceTransf = new ArrayList<>();
94 b1f2ccf5 Leszek Koltunski
  private static final ArrayList<StickerCoords> mStickerCoords = new ArrayList<>();
95
96 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98 b89898c5 Leszek Koltunski
  private FactoryCubit()
99 ac940e24 Leszek Koltunski
    {
100
101
    }
102
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
105 b89898c5 Leszek Koltunski
  public static FactoryCubit getInstance()
106 ac940e24 Leszek Koltunski
    {
107 b89898c5 Leszek Koltunski
    if( mThis==null ) mThis = new FactoryCubit();
108 ac940e24 Leszek Koltunski
109
    return mThis;
110
    }
111
112 2fcfce81 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
113
// H - height of the band in the middle
114
// alpha - angle of the edge  [0,90]
115
// dist - often in a polygon the distance from edge to center is not 1, but something else.
116
// This is the distance.
117
// K - where to begin the second, much more flat part of the band. [0,1]
118
// N - number of bands. N>=3
119
//
120
// theory: two distinct parts to the band:
121
// 1) (0,B) - steep
122
// 2) (B,1) - flat
123
//
124
// In first part, we have y = g(x) ; in second - y = g(f(x)) where
125
//
126
// g(x) = sqrt( R^2 - (x-D)^2 ) - R*cos(alpha)
127
// f(x) = ((D-B)/(1-B)*x + B*(1-D)/(1-B)
128
// h(x) = R*(sin(alpha) - sin(x))
129
// R = H/(1-cos(alpha))
130
// D = H*sin(alpha)
131
// B = h(K*alpha)
132
//
133
// The N points are taken at:
134
//
135
// 1) in the second part, there are K2 = (N-3)/3 such points
136
// 2) in the first - K1 = (N-3) - K2
137
// 3) also, the 3 points 0,B,1
138
//
139
// so we have the sequence A[i] of N points
140
//
141
// 0
142
// h((i+1)*(1-K)*alpha/(K1+1)) (i=0,1,...,K1-1)
143
// B
144
// (1-B)*(i+1)/(K2+1) + B   (i=0,i,...,K2-1)
145
// 1
146
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148
149
  private float f(float D, float B, float x)
150
    {
151
    return ((D-B)*x + B*(1-D))/(1-B);
152
    }
153
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
156
  private float g(float R, float D, float x, float cosAlpha)
157
    {
158
    float d = x-D;
159
    return (float)(Math.sqrt(R*R-d*d)-R*cosAlpha);
160
    }
161
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
164
  private float h(float R, float sinAlpha, float x)
165
    {
166
    return R*(sinAlpha-(float)Math.sin(x));
167
    }
168
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170
171
  private float[] computeBands(float H, int alpha, float dist, float K, int N)
172
    {
173
    float[] bands = new float[2*N];
174
175
    bands[0] = 1.0f;
176
    bands[1] = 0.0f;
177
178
    float beta = (float)Math.atan(dist*Math.tan(Math.PI*alpha/180));
179
    float sinBeta = (float)Math.sin(beta);
180
    float cosBeta = (float)Math.cos(beta);
181
    float R = cosBeta<1.0f ? H/(1.0f-cosBeta) : 0.0f;
182
    float D = R*sinBeta;
183
    float B = h(R,sinBeta,K*beta);
184
185
    if( D>1.0f )
186
      {
187
      for(int i=1; i<N; i++)
188
        {
189
        bands[2*i  ] = (float)(N-1-i)/(N-1);
190
        bands[2*i+1] = H*(1-bands[2*i]);
191
        }
192
      }
193
    else
194
      {
195
      int K2 = (int)((N-3)*K);
196
      int K1 = (N-3)-K2;
197
198
      for(int i=0; i<=K1; i++)
199
        {
200
        float angle = K*beta + (1-K)*beta*(K1-i)/(K1+1);
201
        float x = h(R,sinBeta,angle);
202
        bands[2*i+2] = 1.0f - x;
203
        bands[2*i+3] = g(R,D,x,cosBeta);
204
        }
205
206
      for(int i=0; i<=K2; i++)
207
        {
208
        float x = (1-B)*(i+1)/(K2+1) + B;
209
        bands[2*K1+2 + 2*i+2] = 1.0f - x;
210
        bands[2*K1+2 + 2*i+3] = g(R,D,f(D,B,x),cosBeta);
211
        }
212
      }
213
214
    bands[2*N-2] = 0.0f;
215
    bands[2*N-1] =    H;
216
217
    return bands;
218
    }
219
220 05cc8075 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  private void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius)
223
    {
224
    Static4D reg= new Static4D(0,0,0,regionRadius);
225
226
    float centX = center.get0();
227
    float centY = center.get1();
228
    float centZ = center.get2();
229
230
    for (Static3D vertex : vertices)
231
      {
232
      float x = strength*(centX - vertex.get0());
233
      float y = strength*(centY - vertex.get1());
234
      float z = strength*(centZ - vertex.get2());
235
236
      VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg);
237
      mesh.apply(effect);
238
      }
239
    }
240
241 ac940e24 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243 55fb45c2 Leszek Koltunski
  MeshBase createFacesSkewbCorner()
244 ac940e24 Leszek Koltunski
    {
245 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[6];
246
247 ac940e24 Leszek Koltunski
    float E = 0.5f;
248
    float F = SQ2/2;
249 d92030e4 Leszek Koltunski
    float G = SQ6/16;
250 ac940e24 Leszek Koltunski
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
251 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.028f,35,E/3,0.7f,7);
252 ac940e24 Leszek Koltunski
253
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
254
    meshes[0].setEffectAssociation(0,1,0);
255
    meshes[1] = meshes[0].copy(true);
256
    meshes[1].setEffectAssociation(0,2,0);
257
    meshes[2] = meshes[0].copy(true);
258
    meshes[2].setEffectAssociation(0,4,0);
259
260 d92030e4 Leszek Koltunski
    float[] vertices1 = { -F/2,-2*G, F/2,-2*G, 3*F/8,-G, 1*F/8,G, 0,2*G };
261 2fcfce81 Leszek Koltunski
    float[] bands1 = computeBands(0,0,1,0,3);
262 ac940e24 Leszek Koltunski
263
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
264
    meshes[3].setEffectAssociation(0,8,0);
265
    meshes[4] = meshes[3].copy(true);
266
    meshes[4].setEffectAssociation(0,16,0);
267
    meshes[5] = meshes[3].copy(true);
268
    meshes[5].setEffectAssociation(0,32,0);
269
270 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
271 ac940e24 Leszek Koltunski
    }
272
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275 55fb45c2 Leszek Koltunski
  MeshBase createFacesSkewbFace()
276 ac940e24 Leszek Koltunski
    {
277 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[5];
278
279 ac940e24 Leszek Koltunski
    float E = SQ2/4;
280
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
281 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.051f,35,E/2,0.9f,7);
282 ac940e24 Leszek Koltunski
283
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
284 8d3cfe99 Leszek Koltunski
    meshes[0].setEffectAssociation(0,1,0);
285 ac940e24 Leszek Koltunski
286 a97e02b7 Leszek Koltunski
    float[] vertices1 = { -E,-SQ3*E, -E*0.7f,-SQ3*E, +E*0.7f,-SQ3*E, +E,-SQ3*E, 0,0 };
287 2fcfce81 Leszek Koltunski
    float[] bands1 = computeBands(0,0,1,0,3);
288 ac940e24 Leszek Koltunski
289
    meshes[1] = new MeshPolygon(vertices1,bands1,0,0);
290 8d3cfe99 Leszek Koltunski
    meshes[1].setEffectAssociation(0,2,0);
291
    meshes[2] = meshes[1].copy(true);
292
    meshes[2].setEffectAssociation(0,4,0);
293
    meshes[3] = meshes[1].copy(true);
294
    meshes[3].setEffectAssociation(0,8,0);
295
    meshes[4] = meshes[1].copy(true);
296
    meshes[4].setEffectAssociation(0,16,0);
297 ac940e24 Leszek Koltunski
298 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
299 ac940e24 Leszek Koltunski
    }
300
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302
303 55fb45c2 Leszek Koltunski
  MeshBase createFacesDino()
304 ac940e24 Leszek Koltunski
    {
305 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshPolygon[4];
306 ac940e24 Leszek Koltunski
307
    float E = 0.5f*SQ2;
308
    float F = 0.5f;
309
    float[] vertices0 = { -F,F/3, 0,-2*F/3, +F,F/3 };
310 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.028f,30,F/3,0.8f,7);
311 ac940e24 Leszek Koltunski
312
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 5);
313
    meshes[0].setEffectAssociation(0,1,0);
314
    meshes[1] = meshes[0].copy(true);
315
    meshes[1].setEffectAssociation(0,2,0);
316
317
    float[] vertices1 = { -E/2,-E*(SQ3/6), E/2,-E*(SQ3/6), 0,E*(SQ3/3) };
318 2fcfce81 Leszek Koltunski
    float[] bands1 = computeBands(0.02f,45,F/3,0.2f,3);
319 ac940e24 Leszek Koltunski
320
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
321
    meshes[2].setEffectAssociation(0,4,0);
322
    meshes[3] = meshes[2].copy(true);
323
    meshes[3].setEffectAssociation(0,8,0);
324
325 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
326 ac940e24 Leszek Koltunski
    }
327
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329
330 55fb45c2 Leszek Koltunski
  MeshBase createFacesHelicopterCorner()
331 ac940e24 Leszek Koltunski
    {
332 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[6];
333
334 ac940e24 Leszek Koltunski
    float E = 0.5f;
335
    float F = SQ2/4;
336 2fcfce81 Leszek Koltunski
    float G = 1.0f/12;
337 ac940e24 Leszek Koltunski
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
338 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.028f,35,E/4,0.7f,7);
339 ac940e24 Leszek Koltunski
340
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
341
    meshes[0].setEffectAssociation(0,1,0);
342
    meshes[1] = meshes[0].copy(true);
343
    meshes[1].setEffectAssociation(0,2,0);
344
    meshes[2] = meshes[0].copy(true);
345
    meshes[2].setEffectAssociation(0,4,0);
346
347 2fcfce81 Leszek Koltunski
    float[] vertices1 = { -F,-G, 0,-G, +F,-G, 0,2*G };
348
    float[] bands1 = computeBands(0.00f,0,0,0.0f,3);
349 ac940e24 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
350
    meshes[3].setEffectAssociation(0,8,0);
351
    meshes[4] = meshes[3].copy(true);
352
    meshes[4].setEffectAssociation(0,16,0);
353
    meshes[5] = meshes[3].copy(true);
354
    meshes[5].setEffectAssociation(0,32,0);
355
356 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
357 ac940e24 Leszek Koltunski
    }
358
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
361 55fb45c2 Leszek Koltunski
  MeshBase createFacesHelicopterFace()
362 ac940e24 Leszek Koltunski
    {
363 8d3cfe99 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[4];
364 ac940e24 Leszek Koltunski
365
    float E = 0.5f;
366
    float F = SQ2/4;
367
    float G = 1.0f/12;
368
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
369 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.028f,35,E/4,0.7f,7);
370 ac940e24 Leszek Koltunski
371
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
372
    meshes[0].setEffectAssociation(0,1,0);
373
374
    float[] vertices1 = { -F,-G, +F,-G, 0,2*G};
375 2fcfce81 Leszek Koltunski
    float[] bands1 = computeBands(0.01f,45,F,0.0f,3);
376 ac940e24 Leszek Koltunski
377
    meshes[1] = new MeshPolygon(vertices1, bands1, 1, 3);
378
    meshes[1].setEffectAssociation(0,2,0);
379
380
    float[] vertices2 = { -E/2,-F/3, +E/2,-F/3, 0,2*F/3};
381
382 2fcfce81 Leszek Koltunski
    meshes[2] = new MeshPolygon(vertices2, bands1, 1, 3);
383 ac940e24 Leszek Koltunski
    meshes[2].setEffectAssociation(0,4,0);
384
    meshes[3] = meshes[2].copy(true);
385
    meshes[3].setEffectAssociation(0,8,0);
386
387 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
388 68f6046c Leszek Koltunski
    }
389
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391
392 55fb45c2 Leszek Koltunski
  MeshBase createFacesRediEdge()
393 68f6046c Leszek Koltunski
    {
394 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshPolygon[6];
395 68f6046c Leszek Koltunski
396
    float F = 0.25f;
397
    float[] vertices0 = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
398 2fcfce81 Leszek Koltunski
    float[] bands0 = computeBands(0.038f,35,F,0.7f,7);
399 68f6046c Leszek Koltunski
400
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 2);
401
    meshes[0].setEffectAssociation(0,1,0);
402
    meshes[1] = meshes[0].copy(true);
403
    meshes[1].setEffectAssociation(0,2,0);
404
405 2fcfce81 Leszek Koltunski
    float[] bands1 = computeBands(0.02f,35,F/2,0.2f,3);
406 68f6046c Leszek Koltunski
    float[] vertices1 = { -F/2, +F/2, -F/2, -1.5f*F, 1.5f*F, +F/2 };
407
408
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
409
    meshes[2].setEffectAssociation(0,4,0);
410
    meshes[3] = meshes[2].copy(true);
411
    meshes[3].setEffectAssociation(0,8,0);
412
413 962437b5 Leszek Koltunski
    float X = 0.25f*SQ2;
414
    float Y = SQ6/16;
415
    float[] vertices2 = { -X, Y, -1.5f*X, -Y, +1.5f*X, -Y, +X, Y };
416 68f6046c Leszek Koltunski
417 2fcfce81 Leszek Koltunski
    meshes[4] = new MeshPolygon(vertices2, bands1, 1, 1);
418 68f6046c Leszek Koltunski
    meshes[4].setEffectAssociation(0,16,0);
419
    meshes[5] = meshes[4].copy(true);
420
    meshes[5].setEffectAssociation(0,32,0);
421
422 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
423 962437b5 Leszek Koltunski
    }
424
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426
427 55fb45c2 Leszek Koltunski
  MeshBase createFacesRediCorner()
428 962437b5 Leszek Koltunski
    {
429 2fcfce81 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[6];
430 962437b5 Leszek Koltunski
431
    float E = 0.5f;
432 2fcfce81 Leszek Koltunski
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
433
    float[] bands0 = computeBands(0.06f,35,E,0.7f,6);
434 962437b5 Leszek Koltunski
435 2fcfce81 Leszek Koltunski
    meshes[0] = new MeshPolygon(vertices0,bands0,2,2);
436 962437b5 Leszek Koltunski
    meshes[0].setEffectAssociation(0,1,0);
437
    meshes[1] = meshes[0].copy(true);
438
    meshes[1].setEffectAssociation(0,2,0);
439
    meshes[2] = meshes[0].copy(true);
440
    meshes[2].setEffectAssociation(0,4,0);
441
442 ae755eda Leszek Koltunski
    float F = 0.5f;
443 962437b5 Leszek Koltunski
    float X = 0.5f;
444 2fcfce81 Leszek Koltunski
    float G = 0.72f;
445
    float[] vertices1 = { -E,+F, -E+X,0, -E,-F, -E*G,-F, +E*G,-F, +E,-F, +E-X,0, +E,+F, +E*G,+F, -E*G,+F };
446
    float[] bands1 = computeBands(0.0f,0,1.0f,0.0f,2);
447 962437b5 Leszek Koltunski
448 2fcfce81 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices1,bands1,0,0);
449 962437b5 Leszek Koltunski
    meshes[3].setEffectAssociation(0,8,0);
450
    meshes[4] = meshes[3].copy(true);
451
    meshes[4].setEffectAssociation(0,16,0);
452
    meshes[5] = meshes[3].copy(true);
453
    meshes[5].setEffectAssociation(0,32,0);
454
455 55fb45c2 Leszek Koltunski
    return new MeshJoined(meshes);
456
    }
457 962437b5 Leszek Koltunski
458 49cd8581 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
459
460
  MeshBase createFacesIvyCorner()
461
    {
462 db3b12e6 Leszek Koltunski
    MeshBase[] meshes = new MeshBase[6];
463
464
    final float angle = (float)Math.PI/(2*IVY_N);
465 6a224bdc Leszek Koltunski
    final float CORR  = 1.0f - 2*IVY_D;
466 886d1ebb Leszek Koltunski
    final float DIST  = -0.5f*CORR + IVY_D;
467
    float[] vertices  = new float[2*(IVY_N+1)+6];
468
469
    vertices[0] = (0.5f-IVY_M) * IVY_C;
470
    vertices[1] = (DIST-IVY_M) * IVY_C;
471
    vertices[2] = (0.5f-IVY_M) * IVY_C;
472
    vertices[3] = (0.5f-IVY_M) * IVY_C;
473
    vertices[4] = (DIST-IVY_M) * IVY_C;
474
    vertices[5] = (0.5f-IVY_M) * IVY_C;
475 db3b12e6 Leszek Koltunski
476
    for(int i=0; i<=IVY_N; i++)
477
      {
478
      float ang = (IVY_N-i)*angle;
479
      float sin = (float)Math.sin(ang);
480
      float cos = (float)Math.cos(ang);
481
482 886d1ebb Leszek Koltunski
      vertices[2*i+6] = (CORR*(cos-0.5f)-IVY_M)*IVY_C;
483
      vertices[2*i+7] = (CORR*(sin-0.5f)-IVY_M)*IVY_C;
484 db3b12e6 Leszek Koltunski
      }
485
486 f9464035 Leszek Koltunski
    float[] bands0 = computeBands(+0.012f,20,0.2f,0.5f,7);
487
    float[] bands1 = computeBands(-0.100f,20,0.2f,0.0f,2);
488 db3b12e6 Leszek Koltunski
489 2113cf12 Leszek Koltunski
    meshes[0] = new MeshPolygon(vertices,bands0,1,2);
490 db3b12e6 Leszek Koltunski
    meshes[0].setEffectAssociation(0,1,0);
491
    meshes[1] = meshes[0].copy(true);
492
    meshes[1].setEffectAssociation(0,2,0);
493
    meshes[2] = meshes[0].copy(true);
494
    meshes[2].setEffectAssociation(0,4,0);
495 2113cf12 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices,bands1,1,2);
496 db3b12e6 Leszek Koltunski
    meshes[3].setEffectAssociation(0,8,0);
497
    meshes[4] = meshes[3].copy(true);
498
    meshes[4].setEffectAssociation(0,16,0);
499
    meshes[5] = meshes[3].copy(true);
500
    meshes[5].setEffectAssociation(0,32,0);
501
502
    return new MeshJoined(meshes);
503 49cd8581 Leszek Koltunski
    }
504
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506
507
  MeshBase createFacesIvyFace()
508
    {
509
    MeshBase[] meshes = new MeshBase[2];
510
511
    final float angle = (float)Math.PI/(2*IVY_N);
512 9e5b990e Leszek Koltunski
    final float CORR  = 1.0f - 2*IVY_D;
513 49cd8581 Leszek Koltunski
    float[] vertices = new float[4*IVY_N];
514
515
    for(int i=0; i<IVY_N; i++)
516
      {
517
      float sin = (float)Math.sin(i*angle);
518
      float cos = (float)Math.cos(i*angle);
519
520 18a5f95f Leszek Koltunski
      vertices[2*i          ] = CORR*(0.5f-cos);
521
      vertices[2*i+1        ] = CORR*(0.5f-sin);
522
      vertices[2*i  +2*IVY_N] = CORR*(cos-0.5f);
523
      vertices[2*i+1+2*IVY_N] = CORR*(sin-0.5f);
524 49cd8581 Leszek Koltunski
      }
525
526 886d1ebb Leszek Koltunski
    float[] bands0 = computeBands(+0.03f,35,0.5f,0.5f,5);
527 9e5b990e Leszek Koltunski
    float[] bands1 = computeBands(-0.10f,45,0.5f,0.0f,2);
528 49cd8581 Leszek Koltunski
529 18a5f95f Leszek Koltunski
    meshes[0] = new MeshPolygon(vertices,bands0,0,0);
530 49cd8581 Leszek Koltunski
    meshes[0].setEffectAssociation(0,1,0);
531
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
532
    meshes[1].setEffectAssociation(0,2,0);
533
534
    return new MeshJoined(meshes);
535
    }
536
537 59b87d56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
538
539
  MeshBase createFacesRexCorner()
540
    {
541
    MeshBase[] meshes = new MeshBase[2];
542
543 da36b97e Leszek Koltunski
    float F = REX_D*SQ2;
544
    float G = (1-REX_D)*SQ2/2;
545
    float H = 0.1f;
546
    float J = +2*G/3 - H*G;
547
548
    float[] vertices = { -F/2, -G/3, +F/2, -G/3, H*F/2, J, -H*F/2, J};
549 59b87d56 Leszek Koltunski
550 da36b97e Leszek Koltunski
    float[] bands0 = computeBands(+0.016f,10,G/3,0.5f,5);
551
    float[] bands1 = computeBands(-0.230f,45,G/3,0.0f,2);
552 59b87d56 Leszek Koltunski
553
    meshes[0] = new MeshPolygon(vertices,bands0,1,1);
554
    meshes[0].setEffectAssociation(0,1,0);
555
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
556
    meshes[1].setEffectAssociation(0,2,0);
557
558
    return new MeshJoined(meshes);
559
    }
560
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
563
  MeshBase createFacesRexFace()
564
    {
565
    MeshBase[] meshes = new MeshBase[2];
566
567 da36b97e Leszek Koltunski
    float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
568 59b87d56 Leszek Koltunski
569 da36b97e Leszek Koltunski
    float[] bands0 = computeBands(0.016f,10,REX_D/2,0.5f,5);
570
    float[] bands1 = computeBands(0.000f,45,REX_D/2,0.0f,2);
571 59b87d56 Leszek Koltunski
572
    meshes[0] = new MeshPolygon(vertices,bands0,0,0);
573
    meshes[0].setEffectAssociation(0,1,0);
574
    meshes[1] = new MeshPolygon(vertices,bands1,0,0);
575
    meshes[1].setEffectAssociation(0,2,0);
576
577
    return new MeshJoined(meshes);
578
    }
579
580
///////////////////////////////////////////////////////////////////////////////////////////////////
581
582
  MeshBase createFacesRexEdge()
583
    {
584 da36b97e Leszek Koltunski
    MeshBase[] meshes = new MeshPolygon[6];
585 59b87d56 Leszek Koltunski
586 da36b97e Leszek Koltunski
    float E = 0.5f - REX_D;
587
    float F = 0.5f;
588
    float[] vertices0 = { -F,E/3, 0,-2*E/3, +F,E/3 };
589
    float[] bands0 = computeBands(0.03f,27,F/3,0.8f,5);
590 59b87d56 Leszek Koltunski
591 da36b97e Leszek Koltunski
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 3);
592 59b87d56 Leszek Koltunski
    meshes[0].setEffectAssociation(0,1,0);
593
    meshes[1] = meshes[0].copy(true);
594
    meshes[1].setEffectAssociation(0,2,0);
595 da36b97e Leszek Koltunski
596
    float G = (float)Math.sqrt(E*E+F*F);
597
    float[] vertices1 = { -2*G/3, -E/3, G/3, -E/3, G/3, 2*E/3 };
598
    float[] bands1 = computeBands(0.00f,45,G/3,0.2f,3);
599
600
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
601 59b87d56 Leszek Koltunski
    meshes[2].setEffectAssociation(0,4,0);
602
    meshes[3] = meshes[2].copy(true);
603
    meshes[3].setEffectAssociation(0,8,0);
604 da36b97e Leszek Koltunski
    meshes[4] = meshes[2].copy(true);
605
    meshes[4].setEffectAssociation(0,16,0);
606
    meshes[5] = meshes[2].copy(true);
607
    meshes[5].setEffectAssociation(0,32,0);
608 59b87d56 Leszek Koltunski
609
    return new MeshJoined(meshes);
610
    }
611
612 bbc6da6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
613
614 7764a67a Leszek Koltunski
  MeshBase createFacesKilominxCenter()
615 bbc6da6c Leszek Koltunski
    {
616
    MeshBase[] meshes = new MeshPolygon[6];
617
618 7764a67a Leszek Koltunski
    float X1= 0.5f*SIN54;
619
    float Y1= 0.5f*SIN_HALFD;
620
    float Y2= Y1 - 0.5f*COS54;
621 12313693 Leszek Koltunski
    float H = 0.5f* SIN54 /COS54  ;
622 a64e07d0 Leszek Koltunski
    float X2= MINX_SC*H* SIN_HALFD;
623
    float Y3= MINX_SC*H/(2*COS_HALFD);
624
    float Y4= MINX_SC*H*(1/(2*COS_HALFD) - COS_HALFD);
625 4e627d8b Leszek Koltunski
626
    float[] vertices0 = { -X1, Y2, 0, -Y1, X1, Y2, 0, Y1 };
627 4b4c217e Leszek Koltunski
    float[] bands0 = computeBands(0.04f,17,0.3f,0.2f,5);
628 4e627d8b Leszek Koltunski
    float[] vertices1 = { -X2, Y4, 0, -Y3, X2, Y4, 0, Y3 };
629 32f4e2a7 Leszek Koltunski
    float[] bands1 = computeBands(0.00f, 0,0.25f,0.5f,2);
630 bbc6da6c Leszek Koltunski
631
    meshes[0] = new MeshPolygon(vertices0, bands0, 1, 1);
632
    meshes[0].setEffectAssociation(0, 1,0);
633
    meshes[1] = meshes[0].copy(true);
634
    meshes[1].setEffectAssociation(0, 2,0);
635
    meshes[2] = meshes[0].copy(true);
636
    meshes[2].setEffectAssociation(0, 4,0);
637 32f4e2a7 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices1, bands1, 0, 0);
638 bbc6da6c Leszek Koltunski
    meshes[3].setEffectAssociation(0, 8,0);
639
    meshes[4] = meshes[3].copy(true);
640
    meshes[4].setEffectAssociation(0,16,0);
641
    meshes[5] = meshes[3].copy(true);
642
    meshes[5].setEffectAssociation(0,32,0);
643
644
    return new MeshJoined(meshes);
645
    }
646
647 a64e07d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
648
649 16f34a98 Leszek Koltunski
  MeshBase createFacesMinxCorner(int numLayers)
650 a64e07d0 Leszek Koltunski
    {
651
    MeshBase[] meshes = new MeshPolygon[6];
652
653
    float Y = COS54/(2*SIN54);
654
655
    float[] vertices0 = { -0.5f, 0.0f, 0.0f, -Y, 0.5f, 0.0f, 0.0f, Y };
656 61b217a5 Leszek Koltunski
657
    int numBands0 = numLayers==3 ? 5 : 3;
658
    int numBands1 = numLayers==3 ? 2 : 2;
659
    float h       = numLayers==3 ? 0.04f : 0.03f;
660
    int   e       = numLayers==3 ? 4 : 1;
661
662
    float[] bands0 = computeBands(h    ,34,0.3f,0.2f, numBands0);
663
    float[] bands1 = computeBands(0.00f,34,0.3f,0.2f, numBands1);
664 a64e07d0 Leszek Koltunski
665
    meshes[0] = new MeshPolygon(vertices0, bands0, 1, 1);
666
    meshes[0].setEffectAssociation(0, 1,0);
667
    meshes[1] = meshes[0].copy(true);
668
    meshes[1].setEffectAssociation(0, 2,0);
669
    meshes[2] = meshes[0].copy(true);
670
    meshes[2].setEffectAssociation(0, 4,0);
671 61b217a5 Leszek Koltunski
    meshes[3] = new MeshPolygon(vertices0, bands1, 1, e);
672 a64e07d0 Leszek Koltunski
    meshes[3].setEffectAssociation(0, 8,0);
673
    meshes[4] = meshes[3].copy(true);
674
    meshes[4].setEffectAssociation(0,16,0);
675
    meshes[5] = meshes[3].copy(true);
676
    meshes[5].setEffectAssociation(0,32,0);
677
678
    return new MeshJoined(meshes);
679
    }
680
681 16f34a98 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
682
683
  MeshBase createFacesKilominxEdge(int numLayers, float width, float height)
684
    {
685
     MeshBase[] meshes = new MeshPolygon[6];
686
687
    float D = height/COS18;
688
    float W = D*SIN18;
689
    float X1 = height/2;
690
    float Y1 = width/2;
691
    float Y2 = (width+W)/2;
692
    float X3 = D*SIN54;
693
    float Y3 = D*COS54;
694
    float X4 = height*SIN_HALFD;
695
    float Y4 = height*COS_HALFD;
696
697
    float[] vertices0 = { -X1,-Y1, X1, -Y1, X1, Y1+W,-X1, Y1 };
698
    float[] vertices1 = { -X1,-Y2, X1, -Y2, X1, Y2+W,-X1, Y2 };
699
    float[] vertices2 = { -X3, 0.0f, 0.0f, -Y3, X3, 0.0f, 0.0f, Y3 };
700
    float[] vertices3 = { -X4, 0.0f, 0.0f, -Y4, X4, 0.0f, 0.0f, Y4 };
701
702
    int numBands0 = numLayers<=5 ? 5 : 3;
703
    int numBands1 = numLayers<=5 ? 3 : 2;
704
    float h       = numLayers<=5 ? 0.03f : 0.03f;
705
706
    float[] bands0 = computeBands(h    ,34,0.2f,0.2f,numBands0);
707
    float[] bands1 = computeBands(0.01f,34,0.3f,0.2f,numBands1);
708
709
    meshes[0] = new MeshPolygon(vertices0, bands0, 1, 1);
710
    meshes[0].setEffectAssociation(0, 1,0);
711
    meshes[1] = meshes[0].copy(true);
712
    meshes[1].setEffectAssociation(0, 2,0);
713
    meshes[2] = new MeshPolygon(vertices1, bands1, 0, 0);
714
    meshes[2].setEffectAssociation(0, 4,0);
715
    meshes[3] = meshes[2].copy(true);
716
    meshes[3].setEffectAssociation(0, 8,0);
717 32f4e2a7 Leszek Koltunski
    meshes[4] = new MeshPolygon(vertices2, bands1, 0, 0);
718 16f34a98 Leszek Koltunski
    meshes[4].setEffectAssociation(0,16,0);
719 32f4e2a7 Leszek Koltunski
    meshes[5] = new MeshPolygon(vertices3, bands1, 0, 0);
720 16f34a98 Leszek Koltunski
    meshes[5].setEffectAssociation(0,32,0);
721
722
    return new MeshJoined(meshes);
723
    }
724
725 db608887 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
726
727 61b217a5 Leszek Koltunski
  MeshBase createFacesMegaminxEdge(int numLayers, float width, float height)
728 db608887 Leszek Koltunski
    {
729
    MeshBase[] meshes = new MeshPolygon[6];
730
731
    float D = height/COS18;
732
    float W = D*SIN18;
733
734
    float Y1 = 0.5f*width;
735
    float Y2 = 0.5f*width + W;
736
    float Y3 = 0.5f*width + 2*W;
737
    float X2 = D*SIN54;
738
    float X1 = 0.5f*height;
739
    float Y4 = D*COS54;
740
741
    float[] vertices0 = { -X1, Y1, -X1, -Y1, X1, -Y2, X1, Y2 };
742
    float[] vertices1 = { -X1, Y3, -X1, -Y3, X1, -Y2, X1, Y2 };
743
    float[] vertices2 = { -X2, 0.0f, 0.0f, -Y4, X2, 0.0f, 0.0f, Y4 };
744
745 61b217a5 Leszek Koltunski
    int numBands0 = numLayers==3 ? 5 : 3;
746
    int numBands1 = numLayers==3 ? 2 : 2;
747
    float h       = numLayers==3 ? 0.03f : 0.03f;
748
749
    float[] bands0 = computeBands(h    ,34,0.2f,0.2f,numBands0);
750
    float[] bands1 = computeBands(0.00f,34,0.3f,0.2f,numBands1);
751 db608887 Leszek Koltunski
752 e4bf4d02 Leszek Koltunski
    meshes[0] = new MeshPolygon(vertices0, bands0, 0, 0);
753 db608887 Leszek Koltunski
    meshes[0].setEffectAssociation(0, 1,0);
754
    meshes[1] = meshes[0].copy(true);
755
    meshes[1].setEffectAssociation(0, 2,0);
756 e4bf4d02 Leszek Koltunski
    meshes[2] = new MeshPolygon(vertices1, bands1, 0, 0);
757 db608887 Leszek Koltunski
    meshes[2].setEffectAssociation(0, 4,0);
758
    meshes[3] = meshes[2].copy(true);
759
    meshes[3].setEffectAssociation(0, 8,0);
760 e4bf4d02 Leszek Koltunski
    meshes[4] = new MeshPolygon(vertices2, bands1, 0, 0);
761 db608887 Leszek Koltunski
    meshes[4].setEffectAssociation(0,16,0);
762
    meshes[5] = meshes[4].copy(true);
763
    meshes[5].setEffectAssociation(0,32,0);
764
765
    return new MeshJoined(meshes);
766
    }
767
768 e4bf4d02 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
769
770 61b217a5 Leszek Koltunski
  MeshBase createFacesMegaminxCenter(int numLayers)
771 e4bf4d02 Leszek Koltunski
    {
772
    MeshBase[] meshes = new MeshPolygon[2];
773
774 ed01e351 Leszek Koltunski
    float R  = 0.5f;
775
    float X1 = R*COS54;
776 e4bf4d02 Leszek Koltunski
    float Y1 = R*SIN54;
777
    float X2 = R*COS18;
778
    float Y2 = R*SIN18;
779
780
    float[] vertices0 = { -X1,+Y1, -X2,-Y2, 0.0f,-R, +X2,-Y2, +X1,+Y1 };
781 61b217a5 Leszek Koltunski
782
    int numBands0 = numLayers==3 ? 4 : 3;
783
    int numBands1 = numLayers==3 ? 2 : 2;
784
    float h       = numLayers==3 ? 0.04f : 0.04f;
785
786
    float[] bands0 = computeBands( h    ,45, R/3,0.2f, numBands0);
787
    float[] bands1 = computeBands( 0.00f,34, R/3,0.2f, numBands1);
788 e4bf4d02 Leszek Koltunski
789
    meshes[0] = new MeshPolygon(vertices0, bands0, 0, 0);
790
    meshes[0].setEffectAssociation(0,1,0);
791
    meshes[1] = new MeshPolygon(vertices0, bands1, 0, 0);
792
    meshes[1].setEffectAssociation(0,2,0);
793
794
    return new MeshJoined(meshes);
795
    }
796
797 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
798
799
  private float[] createVertices(int A, int B)
800
    {
801
    float E = 0.5f / Math.max(A,B);
802
    return new float[] { -A*E,-B*E, +A*E,-B*E, +A*E,+B*E, -A*E,+B*E };
803
    }
804
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806
807
  MeshBase createCuboid(int[] dimensions)
808
    {
809
    int X = dimensions[0];
810
    int Y = dimensions[1];
811
    int Z = dimensions[2];
812
813
    float[] verticesXY = createVertices(X,Y);
814
    float[] verticesXZ = createVertices(X,Z);
815
    float[] verticesYZ = createVertices(Z,Y);
816
817
    float defHeight = 0.048f;
818
819
    float[] bandsX = computeBands( defHeight/X,65,0.25f,0.5f,5);
820
    float[] bandsY = computeBands( defHeight/Y,65,0.25f,0.5f,5);
821
    float[] bandsZ = computeBands( defHeight/Z,65,0.25f,0.5f,5);
822
823
    MeshBase[] meshes = new MeshPolygon[6];
824
825
    meshes[0] = new MeshPolygon(verticesYZ,bandsX,1,2);
826
    meshes[0].setEffectAssociation(0,1,0);
827
    meshes[1] = meshes[0].copy(true);
828
    meshes[1].setEffectAssociation(0,2,0);
829
    meshes[2] = new MeshPolygon(verticesXZ,bandsY,1,2);
830
    meshes[2].setEffectAssociation(0,4,0);
831
    meshes[3] = meshes[2].copy(true);
832
    meshes[3].setEffectAssociation(0,8,0);
833
    meshes[4] = new MeshPolygon(verticesXY,bandsZ,1,2);
834
    meshes[4].setEffectAssociation(0,16,0);
835
    meshes[5] = meshes[4].copy(true);
836
    meshes[5].setEffectAssociation(0,32,0);
837
838
    return new MeshJoined(meshes);
839
    }
840
841 2fcfce81 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
842
// EFFECTS
843 55fb45c2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
844
845
///////////////////////////////////////////////////////////////////////////////////////////////////
846
847
  VertexEffect[] createVertexEffectsSkewbCorner()
848
    {
849
    float E = 0.5f;
850
851
    Static3D axisX  = new Static3D(1,0,0);
852
    Static3D axisY  = new Static3D(0,1,0);
853
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
854
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
855
    Static1D angle1 = new Static1D(+90);
856
    Static1D angle2 = new Static1D(-90);
857
    Static1D angle3 = new Static1D(-15);
858
    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
859
    Static1D angle5 = new Static1D(120);
860
    Static1D angle6 = new Static1D(240);
861
    Static3D center1= new Static3D(0,0,0);
862
    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
863
    Static3D move1  = new Static3D(-E/4,-E/4,0);
864 d92030e4 Leszek Koltunski
    Static3D move2  = new Static3D(-0.5f+SQ2/4,-0.5f+SQ6/8,-0.5f);
865 55fb45c2 Leszek Koltunski
866
    VertexEffect[] effect = new VertexEffect[10];
867
868
    effect[0] = new VertexEffectMove(move1);
869
    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
870
    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
871
    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
872
    effect[4] = new VertexEffectMove(move2);
873
    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
874
    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
875
    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
876
    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
877
    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
878
879
    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
880
    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
881
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
882
    effect[3].setMeshAssociation( 4,-1);  // mesh 2
883
    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
884
    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
885
    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
886
    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
887
    effect[8].setMeshAssociation(16,-1);  // mesh 4
888
    effect[9].setMeshAssociation(32,-1);  // mesh 5
889
890
    return effect;
891
    }
892
893
///////////////////////////////////////////////////////////////////////////////////////////////////
894
895
  VertexEffect[] createVertexEffectsSkewbFace()
896
    {
897
    Static3D center = new Static3D(0,0,0);
898
    Static3D axisX  = new Static3D(1,0,0);
899
    Static3D axisZ  = new Static3D(0,0,1);
900
    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
901
902
    VertexEffect[] effect = new VertexEffect[6];
903
904
    effect[0] = new VertexEffectRotate( new Static1D(angle), axisX, center);
905
    effect[1] = new VertexEffectRotate( new Static1D(  135), axisZ, center);
906
    effect[2] = new VertexEffectRotate( new Static1D(   45), axisZ, center);
907
    effect[3] = new VertexEffectRotate( new Static1D(  -45), axisZ, center);
908
    effect[4] = new VertexEffectRotate( new Static1D( -135), axisZ, center);
909
    effect[5] = new VertexEffectMove( new Static3D(0,0,-0.5f) );
910
911
    effect[0].setMeshAssociation(30,-1);  // meshes 1,2,3,4
912
    effect[1].setMeshAssociation( 2,-1);  // mesh 1
913
    effect[2].setMeshAssociation( 5,-1);  // meshes 0,2
914
    effect[3].setMeshAssociation( 8,-1);  // mesh 3
915
    effect[4].setMeshAssociation(16,-1);  // mesh 4
916
    effect[5].setMeshAssociation(30,-1);  // meshes 1,2,3,4
917
918
    return effect;
919
    }
920
921
///////////////////////////////////////////////////////////////////////////////////////////////////
922
923
  VertexEffect[] createVertexEffectsDino()
924
    {
925
    float E = 0.5f*SQ2;
926
    float F = 0.5f;
927
    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
928
929 2fcfce81 Leszek Koltunski
    Static1D angle1 = new Static1D(-ANGLE);
930
    Static1D angle2 = new Static1D(+ANGLE);
931 55fb45c2 Leszek Koltunski
    Static3D axisX  = new Static3D(1,0,0);
932
    Static3D axisY  = new Static3D(0,1,0);
933
    Static3D axisZ  = new Static3D(0,-1,1);
934
    Static3D center0= new Static3D(0,0,0);
935
    Static3D center1= new Static3D(0,-3*F,0);
936
937
    VertexEffect[] effect = new VertexEffect[10];
938
939
    effect[0] = new VertexEffectScale ( new Static3D(3,3,3) );
940
    effect[1] = new VertexEffectMove  ( new Static3D(0,-F,0) );
941
    effect[2] = new VertexEffectRotate( new Static1D(90), axisX, center0 );
942
    effect[3] = new VertexEffectScale ( new Static3D(1,-1,1) );
943
    effect[4] = new VertexEffectMove  ( new Static3D(3*E/2,E*(SQ3/2)-3*F,0) );
944
    effect[5] = new VertexEffectRotate( new Static1D(+90), axisY, center1 );
945
    effect[6] = new VertexEffectScale ( new Static3D(-1,1,1) );
946
    effect[7] = new VertexEffectRotate( new Static1D( 45), axisX, center1 );
947
    effect[8] = new VertexEffectRotate( angle1           , axisZ, center1 );
948
    effect[9] = new VertexEffectRotate( angle2           , axisZ, center1 );
949
950
    effect[0].setMeshAssociation(15,-1);  // apply to meshes 0,1,2,3
951
    effect[1].setMeshAssociation( 3,-1);  // apply to meshes 0,1
952
    effect[2].setMeshAssociation( 2,-1);  // apply to mesh 1
953 da36b97e Leszek Koltunski
    effect[3].setMeshAssociation( 2,-1);  // apply to mesh 1
954 55fb45c2 Leszek Koltunski
    effect[4].setMeshAssociation(12,-1);  // apply to meshes 2,3
955
    effect[5].setMeshAssociation(12,-1);  // apply to meshes 2,3
956
    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
957
    effect[7].setMeshAssociation(12,-1);  // apply to meshes 2,3
958
    effect[8].setMeshAssociation( 4,-1);  // apply to mesh 2
959
    effect[9].setMeshAssociation( 8,-1);  // apply to mesh 3
960
961
    return effect;
962
    }
963
964
///////////////////////////////////////////////////////////////////////////////////////////////////
965
966
  VertexEffect[] createVertexEffectsHelicopterCorner()
967
    {
968
    float E = 0.5f;
969
970
    Static3D axisX  = new Static3D(1,0,0);
971
    Static3D axisY  = new Static3D(0,1,0);
972
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
973
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
974
    Static1D angle1 = new Static1D(+90);
975
    Static1D angle2 = new Static1D(-90);
976
    Static1D angle3 = new Static1D(-135);
977
    Static1D angle4 = new Static1D(90);
978
    Static1D angle5 = new Static1D(120);
979
    Static1D angle6 = new Static1D(240);
980
    Static3D center1= new Static3D(0,0,0);
981
    Static3D center2= new Static3D(-0.25f,-0.25f,-0.25f);
982
    Static3D move1  = new Static3D(-E/4,-E/4,0);
983
    Static3D move2  = new Static3D(-0.25f,(-1.0f/6)-0.25f,-0.25f);
984
985
    VertexEffect[] effect = new VertexEffect[10];
986
987
    effect[0] = new VertexEffectMove(move1);
988
    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
989
    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
990
    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
991
    effect[4] = new VertexEffectMove(move2);
992
    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
993
    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
994
    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
995
    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
996
    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
997
998
    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
999
    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
1000
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
1001
    effect[3].setMeshAssociation( 4,-1);  // mesh 2
1002
    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
1003
    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
1004
    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
1005
    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
1006
    effect[8].setMeshAssociation(16,-1);  // mesh 4
1007
    effect[9].setMeshAssociation(32,-1);  // mesh 5
1008
1009
    return effect;
1010
    }
1011
1012
///////////////////////////////////////////////////////////////////////////////////////////////////
1013
1014
  VertexEffect[] createVertexEffectsHelicopterFace()
1015
    {
1016
    float E = 0.5f;
1017
    float F = SQ2/4;
1018
1019
    Static3D move0  = new Static3D(-E/4, -E/4, 0);
1020
    Static3D move1  = new Static3D(-(SQ2/24)-E/2, -(SQ2/24)-E/2, 0);
1021
    Static3D move2  = new Static3D(-E/2, F/3, 0);
1022
    Static3D move3  = new Static3D(+E/2, F/3, 0);
1023
    Static3D move4  = new Static3D(+E/3,+E/3, 0);
1024
    Static1D angle1 = new Static1D(135);
1025
    Static1D angle2 = new Static1D(90);
1026
    Static1D angle3 = new Static1D(-90);
1027
    Static1D angle4 = new Static1D(-135);
1028
    Static3D axisX  = new Static3D(1,0,0);
1029
    Static3D axisY  = new Static3D(0,1,0);
1030
    Static3D axisZ  = new Static3D(0,0,1);
1031
    Static3D axis1  = new Static3D(1,-1,0);
1032
    Static3D center = new Static3D(0,0,0);
1033
    Static3D center1= new Static3D(-E/2,-E/2,0);
1034
1035
    VertexEffect[] effect = new VertexEffect[10];
1036
1037
    effect[0] = new VertexEffectMove(move0);
1038
    effect[1] = new VertexEffectRotate(angle1, axisZ, center);
1039
    effect[2] = new VertexEffectMove(move1);
1040
    effect[3] = new VertexEffectRotate(angle2, axis1, center1);
1041
    effect[4] = new VertexEffectMove(move2);
1042
    effect[5] = new VertexEffectMove(move3);
1043
    effect[6] = new VertexEffectRotate(angle3, axisZ, center);
1044
    effect[7] = new VertexEffectRotate(angle4, axisX, center);
1045
    effect[8] = new VertexEffectRotate(angle1, axisY, center);
1046
    effect[9] = new VertexEffectMove(move4);
1047
1048
    effect[0].setMeshAssociation( 1,-1);  // mesh 0
1049
    effect[1].setMeshAssociation( 2,-1);  // mesh 1
1050
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
1051
    effect[3].setMeshAssociation( 2,-1);  // mesh 1
1052
    effect[4].setMeshAssociation( 4,-1);  // mesh 2
1053
    effect[5].setMeshAssociation( 8,-1);  // mesh 3
1054
    effect[6].setMeshAssociation( 8,-1);  // mesh 3
1055
    effect[7].setMeshAssociation( 4,-1);  // mesh 2
1056
    effect[8].setMeshAssociation( 8,-1);  // mesh 3
1057
    effect[9].setMeshAssociation(15,-1);  // meshes 0,1,2,3
1058
1059
    return effect;
1060
    }
1061
1062
///////////////////////////////////////////////////////////////////////////////////////////////////
1063
1064
  VertexEffect[] createVertexEffectsRediEdge()
1065
    {
1066
    Static3D move0 = new Static3D(0.0f, -0.5f, 0.0f);
1067
    Static3D move1 = new Static3D(0.25f, -0.25f, 0.0f);
1068
    Static3D move2 = new Static3D(0.5f, 0.0f, 0.0f);
1069
    Static3D move3 = new Static3D(0.0f, (SQ3-6)/8, (SQ3-6)/8);
1070
    Static3D flipZ = new Static3D(1,1,-1);
1071
    Static3D flipX = new Static3D(-1,1,1);
1072
    Static3D scale = new Static3D(2,2,2);
1073
    Static3D cent0 = new Static3D(0,0, 0);
1074
    Static3D cent1 = new Static3D(0,0, -1.5f);
1075
    Static3D axisX = new Static3D(1,0, 0);
1076
    Static3D axisY = new Static3D(0,1, 0);
1077
    Static3D axis  = new Static3D(0,SQ2/2,-SQ2/2);
1078
    Static1D angle1= new Static1D(90);
1079
    Static1D angle2= new Static1D(45);
1080
    Static1D angle3= new Static1D( (float)(180/Math.PI*Math.acos(SQ3/3)) );
1081
1082
    VertexEffect[] effect = new VertexEffect[12];
1083
1084
    effect[0] = new VertexEffectScale(scale);
1085
    effect[1] = new VertexEffectMove(move0);
1086
    effect[2] = new VertexEffectScale(flipZ);
1087
    effect[3] = new VertexEffectRotate(angle1,axisX,cent0);
1088
    effect[4] = new VertexEffectMove(move1);
1089
    effect[5] = new VertexEffectRotate(angle1,axisY,cent0);
1090
    effect[6] = new VertexEffectMove(move2);
1091
    effect[7] = new VertexEffectScale(flipX);
1092
    effect[8] = new VertexEffectRotate(angle2,axisX,cent0);
1093
    effect[9] = new VertexEffectMove(move3);
1094
    effect[10]= new VertexEffectRotate(angle3,axis ,cent1);
1095
    effect[11]= new VertexEffectScale(flipX);
1096
1097
    effect[0].setMeshAssociation(63,-1);  // meshes 0,1,2,3,4,5
1098
    effect[1].setMeshAssociation( 3,-1);  // meshes 0,1
1099
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
1100
    effect[3].setMeshAssociation( 2,-1);  // mesh 1
1101
    effect[4].setMeshAssociation(12,-1);  // meshes 2,3
1102
    effect[5].setMeshAssociation(60,-1);  // meshes 2,3,4,5
1103
    effect[6].setMeshAssociation(12,-1);  // meshes 2,3
1104
    effect[7].setMeshAssociation( 8,-1);  // mesh 3
1105
    effect[8].setMeshAssociation(48,-1);  // meshes 4,5
1106
    effect[9].setMeshAssociation(48,-1);  // meshes 4,5
1107
    effect[10].setMeshAssociation(48,-1); // meshes 4,5
1108
    effect[11].setMeshAssociation(32,-1); // mesh 5
1109
1110
    return effect;
1111
    }
1112
1113
///////////////////////////////////////////////////////////////////////////////////////////////////
1114
1115
  VertexEffect[] createVertexEffectsRediCorner()
1116
    {
1117
    Static3D axisY   = new Static3D(0,1,0);
1118
    Static3D axisX   = new Static3D(1,0,0);
1119 962437b5 Leszek Koltunski
    Static3D axisZ   = new Static3D(0,0,1);
1120
    Static3D center  = new Static3D(0,0,0);
1121
    Static1D angle90 = new Static1D(90);
1122
    Static1D angle270= new Static1D(270);
1123
    Static1D angle45 = new Static1D(-45);
1124 ae755eda Leszek Koltunski
    Static3D scale   = new Static3D(1.0f, SQ2, 1.0f);
1125 962437b5 Leszek Koltunski
1126 ae755eda Leszek Koltunski
    VertexEffect[] effect = new VertexEffect[7];
1127 55fb45c2 Leszek Koltunski
1128
    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
1129
    effect[1] = new VertexEffectRotate( angle270, axisX, center );
1130
    effect[2] = new VertexEffectRotate( angle90 , axisY, center );
1131 ae755eda Leszek Koltunski
    effect[3] = new VertexEffectScale(scale);
1132
    effect[4] = new VertexEffectRotate( angle45 , axisX, center );
1133
    effect[5] = new VertexEffectRotate( angle90 , axisY, center );
1134
    effect[6] = new VertexEffectRotate( angle270, axisZ, center );
1135 55fb45c2 Leszek Koltunski
1136
    effect[0].setMeshAssociation( 7,-1);  // 0,1,2
1137
    effect[1].setMeshAssociation( 2,-1);  // 1
1138
    effect[2].setMeshAssociation( 4,-1);  // 2
1139 ae755eda Leszek Koltunski
    effect[3].setMeshAssociation(56,-1);  // 3,4,5
1140
    effect[4].setMeshAssociation(56,-1);  // 3,4,5
1141
    effect[5].setMeshAssociation(16,-1);  // 4
1142
    effect[6].setMeshAssociation(32,-1);  // 5
1143 55fb45c2 Leszek Koltunski
1144
    return effect;
1145
    }
1146
1147 49cd8581 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1148
1149
  VertexEffect[] createVertexEffectsIvyCorner()
1150
    {
1151 db3b12e6 Leszek Koltunski
    Static3D axisX  = new Static3D(1,0,0);
1152
    Static3D axisY  = new Static3D(0,1,0);
1153
    Static1D angle1 = new Static1D(+90);
1154
    Static1D angle2 = new Static1D(-90);
1155
    Static3D center = new Static3D(0,0,0);
1156 886d1ebb Leszek Koltunski
    Static3D move1  = new Static3D(IVY_M-0.5f,IVY_M-0.5f,0);
1157 db3b12e6 Leszek Koltunski
1158
    VertexEffect[] effect = new VertexEffect[5];
1159
1160 886d1ebb Leszek Koltunski
    effect[0] = new VertexEffectScale(1/IVY_C);
1161 db3b12e6 Leszek Koltunski
    effect[1] = new VertexEffectMove(move1);
1162
    effect[2] = new VertexEffectScale(new Static3D(1,1,-1));
1163
    effect[3] = new VertexEffectRotate(angle1,axisX,center);
1164
    effect[4] = new VertexEffectRotate(angle2,axisY,center);
1165
1166
    effect[2].setMeshAssociation(54,-1);  // meshes 1,2,4,5
1167
    effect[3].setMeshAssociation(18,-1);  // meshes 1,4
1168
    effect[4].setMeshAssociation(36,-1);  // meshes 2,5
1169
1170
    return effect;
1171 49cd8581 Leszek Koltunski
    }
1172
1173 59b87d56 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1174
1175
  VertexEffect[] createVertexEffectsRexEdge()
1176
    {
1177 da36b97e Leszek Koltunski
    float E = 0.5f - REX_D;
1178
    float F = 0.5f;
1179
    float G = (float)Math.sqrt(E*E+F*F);
1180
    float A = (float)((180/Math.PI)*Math.asin(E/G));
1181 59b87d56 Leszek Koltunski
1182 da36b97e Leszek Koltunski
    Static3D move1 = new Static3D(    0.0f, -E/3, 0.0f);
1183
    Static3D move2 = new Static3D(2*G/3 -F, +E/3, 0.0f);
1184
1185
    Static3D center0= new Static3D(0.0f, 0.0f, 0.0f);
1186
    Static3D center1= new Static3D(  -F, 0.0f, 0.0f);
1187
    Static3D center2= new Static3D(  +F, 0.0f, 0.0f);
1188
    Static3D axisX  = new Static3D(1.0f, 0.0f, 0.0f);
1189
    Static3D axisY  = new Static3D(0.0f, 1.0f, 0.0f);
1190
    Static3D axisZ  = new Static3D(0.0f, 0.0f, 1.0f);
1191 59b87d56 Leszek Koltunski
1192
    Static1D angle180 = new Static1D(180);
1193
    Static1D angle90  = new Static1D( 90);
1194 da36b97e Leszek Koltunski
    Static1D angle270 = new Static1D(270);
1195
    Static1D angle1   = new Static1D(+A);
1196
    Static1D angle2   = new Static1D(-A);
1197 59b87d56 Leszek Koltunski
1198 da36b97e Leszek Koltunski
    VertexEffect[] effect = new VertexEffect[12];
1199 59b87d56 Leszek Koltunski
1200 da36b97e Leszek Koltunski
    effect[0] = new VertexEffectMove(move1);
1201
    effect[1] = new VertexEffectMove(move2);
1202
    effect[2] = new VertexEffectRotate(  angle90, axisX, center0 );
1203
    effect[3] = new VertexEffectRotate( angle270, axisX, center0 );
1204
    effect[4] = new VertexEffectRotate( angle180, axisX, center0 );
1205
    effect[5] = new VertexEffectRotate( angle180, axisY, center0 );
1206
    effect[6] = new VertexEffectScale ( new Static3D(-1, 1, 1) );
1207
    effect[7] = new VertexEffectScale ( new Static3D( 1,-1, 1) );
1208
    effect[8] = new VertexEffectRotate(   angle1, axisY, center1);
1209
    effect[9] = new VertexEffectRotate(   angle2, axisY, center2);
1210
    effect[10]= new VertexEffectRotate(   angle2, axisZ, center1);
1211
    effect[11]= new VertexEffectRotate(   angle1, axisZ, center2);
1212
1213
    effect[0].setMeshAssociation( 3,-1);  // meshes 0 & 1
1214
    effect[1].setMeshAssociation(60,-1);  // meshes 2,3,4,5
1215
    effect[2].setMeshAssociation( 2,-1);  // meshes 1
1216
    effect[3].setMeshAssociation(12,-1);  // meshes 2,3
1217
    effect[4].setMeshAssociation(48,-1);  // meshes 4,5
1218
    effect[5].setMeshAssociation(32,-1);  // mesh 5
1219
    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
1220
    effect[7].setMeshAssociation( 2,-1);  // apply to mesh 1
1221
    effect[8].setMeshAssociation(16,-1);  // apply to mesh 4
1222
    effect[9].setMeshAssociation(32,-1);  // apply to mesh 5
1223
    effect[10].setMeshAssociation(4,-1);  // apply to mesh 2
1224
    effect[11].setMeshAssociation(8,-1);  // apply to mesh 3
1225 59b87d56 Leszek Koltunski
1226
    return effect;
1227
    }
1228
1229
///////////////////////////////////////////////////////////////////////////////////////////////////
1230
1231
  VertexEffect[] createVertexEffectsRexCorner()
1232
    {
1233
    Static3D center= new Static3D(0.0f, 0.0f, 0.0f);
1234
    Static3D axisZ = new Static3D(0.0f, 0.0f, 1.0f);
1235 80ec6abf Leszek Koltunski
    Static1D angle = new Static1D(225);
1236 59b87d56 Leszek Koltunski
1237 f5c134c3 Leszek Koltunski
    VertexEffect[] effect = new VertexEffect[1];
1238 59b87d56 Leszek Koltunski
    effect[0] = new VertexEffectRotate(angle, axisZ, center);
1239
1240
    return effect;
1241
    }
1242
1243 bbc6da6c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1244
1245 7764a67a Leszek Koltunski
  VertexEffect[] createVertexEffectsKilominxCenter(float width)
1246 bbc6da6c Leszek Koltunski
    {
1247 b5347187 Leszek Koltunski
    VertexEffect[] effect = new VertexEffect[11];
1248 4e627d8b Leszek Koltunski
1249 7764a67a Leszek Koltunski
    float H = 0.5f*(SIN54/COS54);
1250
    float Y1= 0.5f*SIN_HALFD;
1251 a64e07d0 Leszek Koltunski
    float Y2= H/(2*COS_HALFD);
1252 db608887 Leszek Koltunski
    float cos18 = (float)(Math.sqrt(1- SIN18 * SIN18));
1253 a64e07d0 Leszek Koltunski
    float LEN   = (float)Math.sqrt(H*H/(COS_HALFD*COS_HALFD) + 0.25f);
1254 4e627d8b Leszek Koltunski
1255
    Static3D axisZ = new Static3D(0.0f  , 0.0f , 1.0f);
1256
    Static3D axisY = new Static3D(0.0f  , 1.0f , 0.0f);
1257 7764a67a Leszek Koltunski
    Static3D axisA = new Static3D(-SIN18, cos18, 0.0f);
1258 a64e07d0 Leszek Koltunski
    Static3D axisC = new Static3D( H/LEN, -0.5f/LEN,-H* SIN_HALFD /(COS_HALFD*LEN));
1259 4e627d8b Leszek Koltunski
1260
    Static3D move1 = new Static3D(0,-Y1,0);
1261
    Static3D move2 = new Static3D(0,-Y2,0);
1262 7764a67a Leszek Koltunski
    Static3D move3 = new Static3D(0.5f*cos18,0.5f*SIN18,0);
1263 4e627d8b Leszek Koltunski
    Static3D center= new Static3D(0.0f, 0.0f, 0.0f);
1264
1265
    Static1D angle1 = new Static1D(54);
1266 7764a67a Leszek Koltunski
    Static1D angle2 = new Static1D(DIHEDRAL1/2+18);
1267 4e627d8b Leszek Koltunski
    Static1D angle3 = new Static1D(90);
1268
    Static1D angle4 = new Static1D(120);
1269
    Static1D angle5 = new Static1D(240);
1270 7764a67a Leszek Koltunski
    Static1D angle6 = new Static1D(90-DIHEDRAL1/2);
1271 4e627d8b Leszek Koltunski
1272
    effect[0] = new VertexEffectMove(move1);
1273 b1dea8dd Leszek Koltunski
    effect[1] = new VertexEffectScale(1/MINX_SC);
1274
    effect[2] = new VertexEffectMove(move2);
1275
    effect[3] = new VertexEffectRotate(angle1, axisZ, center);
1276
    effect[4] = new VertexEffectRotate(angle2, axisZ, center);
1277
    effect[5] = new VertexEffectRotate(angle3, axisA, center);
1278
    effect[6] = new VertexEffectMove(move3);
1279
    effect[7] = new VertexEffectRotate(angle4, axisC, center);
1280
    effect[8] = new VertexEffectRotate(angle5, axisC, center);
1281
    effect[9] = new VertexEffectRotate(angle6, axisY, center);
1282 b5347187 Leszek Koltunski
    effect[10]= new VertexEffectScale(width/0.5f);
1283 bbc6da6c Leszek Koltunski
1284 4e627d8b Leszek Koltunski
    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
1285
    effect[1].setMeshAssociation(56,-1);  // meshes 3,4,5
1286 b1dea8dd Leszek Koltunski
    effect[2].setMeshAssociation(56,-1);  // meshes 3,4,5
1287
    effect[3].setMeshAssociation( 7,-1);  // meshes 0,1,2
1288 4e627d8b Leszek Koltunski
    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
1289
    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
1290 b1dea8dd Leszek Koltunski
    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
1291
    effect[7].setMeshAssociation(18,-1);  // meshes 1,4
1292
    effect[8].setMeshAssociation(36,-1);  // meshes 2,5
1293 4e627d8b Leszek Koltunski
1294
    return effect;
1295 bbc6da6c Leszek Koltunski
    }
1296
1297 a64e07d0 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1298
1299 16f34a98 Leszek Koltunski
  VertexEffect[] createVertexEffectsMinxCorner(float width)
1300 a64e07d0 Leszek Koltunski
    {
1301
    VertexEffect[] effect = new VertexEffect[9];
1302
1303
    float Y = COS54/(2*SIN54);
1304
1305
    float sinA = (2*SIN54*SIN54-1)/COS54;
1306
    float cosA = (float)Math.sqrt(1-sinA*sinA);
1307
    float LEN  = 0.5f/SIN54;
1308 16f34a98 Leszek Koltunski
    float scale= width/LEN;
1309 a64e07d0 Leszek Koltunski
1310
    Static3D axisA = new Static3D( SIN54, COS54, 0.0f);
1311
    Static3D axisB = new Static3D(-SIN54, COS54, 0.0f);
1312
    Static3D axisX = new Static3D(  1.0f,  0.0f, 0.0f);
1313
1314
    Static3D centerU = new Static3D( 0.0f, Y, 0.0f);
1315
    Static3D centerD = new Static3D( 0.0f,-Y, 0.0f);
1316
1317
    Static3D move1= new Static3D(0.0f, -sinA*LEN, -cosA*LEN );
1318
    Static3D move2= new Static3D(0.0f, Y , 0.0f );
1319
1320 db608887 Leszek Koltunski
    Static1D angleD = new Static1D(DIHEDRAL1);
1321
    Static1D angleE = new Static1D(360-DIHEDRAL1);
1322
    Static1D angleF = new Static1D(DIHEDRAL2);
1323 a64e07d0 Leszek Koltunski
1324
    effect[0] = new VertexEffectScale ( new Static3D( 1, 1,-1) );
1325
    effect[1] = new VertexEffectRotate(angleE, axisA, centerU);
1326
    effect[2] = new VertexEffectRotate(angleD, axisB, centerU);
1327
    effect[3] = new VertexEffectMove(move1);
1328
    effect[4] = new VertexEffectRotate(angleE, axisA, centerD);
1329
    effect[5] = new VertexEffectRotate(angleD, axisB, centerD);
1330
    effect[6] = new VertexEffectRotate(angleF, axisX, centerD);
1331
    effect[7] = new VertexEffectMove(move2);
1332
    effect[8] = new VertexEffectScale(scale);
1333
1334
    effect[0].setMeshAssociation(  3,-1);  // meshes 0,1
1335
    effect[1].setMeshAssociation( 16,-1);  // mesh 4
1336
    effect[2].setMeshAssociation( 32,-1);  // mesh 5
1337
    effect[3].setMeshAssociation( 56,-1);  // meshes 3,4,5
1338
    effect[4].setMeshAssociation(  1,-1);  // mesh 0
1339
    effect[5].setMeshAssociation(  2,-1);  // mesh 1
1340
1341
    return effect;
1342
    }
1343
1344 16f34a98 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1345
1346
  VertexEffect[] createVertexEffectsKilominxEdge(float width, float height, boolean left)
1347
    {
1348
    VertexEffect[] effect = new VertexEffect[11 + (left ? 0:1)];
1349
1350
    float D = height/COS18;
1351
    float W = D*SIN18;
1352
    float X1 = height/2;
1353
    float Y1 = width/2;
1354
    float Y2 = (width+W)/2;
1355
    float Y3 = D*COS54;
1356
    float Y4 = height*COS_HALFD;
1357
    float Z = 2*height*COS_HALFD;
1358
    float alpha = 90-DIHEDRAL1/2;
1359
1360
    Static1D angle1 = new Static1D(alpha);
1361
    Static1D angle2 = new Static1D(180-alpha);
1362
    Static1D angle3 = new Static1D(DIHEDRAL2);
1363
    Static1D angle4 = new Static1D(90);
1364
1365
    Static3D move1 = new Static3D(+X1,-Y1,0);
1366
    Static3D move2 = new Static3D(-X1,-Y2+W,-Z);
1367
    Static3D move3 = new Static3D(0,+Y3,0);
1368
    Static3D move4 = new Static3D(0,-Y4-width,0);
1369
    Static3D scale = new Static3D(+1,+1,-1);
1370
1371
    Static3D axisXplus = new Static3D(+1, 0, 0);
1372
    Static3D axisYplus = new Static3D( 0,+1, 0);
1373
1374
    Static3D center1= new Static3D( 0, 0, 0);
1375
    Static3D center2= new Static3D( 0, 0,-Z);
1376
    Static3D center3= new Static3D( 0,-width, 0);
1377
1378
    effect[ 0] = new VertexEffectMove(move1);
1379
    effect[ 1] = new VertexEffectMove(move2);
1380
    effect[ 2] = new VertexEffectMove(move3);
1381
    effect[ 3] = new VertexEffectMove(move4);
1382
    effect[ 4] = new VertexEffectScale(scale);
1383
    effect[ 5] = new VertexEffectRotate(angle1, axisYplus , center1);
1384
    effect[ 6] = new VertexEffectRotate(angle2, axisYplus , center1);
1385
    effect[ 7] = new VertexEffectRotate(angle1, axisYplus , center2);
1386
    effect[ 8] = new VertexEffectRotate(angle2, axisYplus , center2);
1387
    effect[ 9] = new VertexEffectRotate(angle3, axisXplus , center1);
1388
    effect[10] = new VertexEffectRotate(angle4, axisXplus , center3);
1389
1390
    if( !left )
1391
      {
1392
      Static3D scale1 = new Static3D(+1,-1,+1);
1393
      effect[11] = new VertexEffectScale(scale1);
1394
      }
1395
1396
    effect[ 0].setMeshAssociation( 3,-1);  // meshes 0,1
1397
    effect[ 1].setMeshAssociation(12,-1);  // meshes 2,3
1398
    effect[ 2].setMeshAssociation(16,-1);  // mesh 4
1399
    effect[ 3].setMeshAssociation(32,-1);  // mesh 5
1400
    effect[ 4].setMeshAssociation( 2,-1);  // mesh 1
1401
    effect[ 5].setMeshAssociation( 1,-1);  // mesh 0
1402
    effect[ 6].setMeshAssociation( 2,-1);  // mesh 1
1403
    effect[ 7].setMeshAssociation( 4,-1);  // mesh 2
1404
    effect[ 8].setMeshAssociation( 8,-1);  // mesh 3
1405
    effect[ 9].setMeshAssociation(16,-1);  // mesh 4
1406
    effect[10].setMeshAssociation(32,-1);  // mesh 5
1407
1408
    return effect;
1409
    }
1410
1411 db608887 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1412
1413
  VertexEffect[] createVertexEffectsMegaminxEdge(float width, float height)
1414
    {
1415
    VertexEffect[] effect = new VertexEffect[11];
1416
1417
    float X = 0.5f*height;
1418
    float Y = height*(COS54/COS18) + width*0.5f;
1419
    float Z = 2*height*COS_HALFD;
1420
1421
    float alpha = 90-DIHEDRAL1/2;
1422
    float beta  = DIHEDRAL2;
1423
1424
    Static1D angle1 = new Static1D(alpha);
1425
    Static1D angle2 = new Static1D(180-alpha);
1426
    Static1D angle3 = new Static1D(beta);
1427
1428
    Static3D move1 = new Static3D(X,0,0);
1429
    Static3D move2 = new Static3D(X,0,-Z);
1430
    Static3D move3 = new Static3D(0,+Y,0);
1431
    Static3D move4 = new Static3D(0,-Y,0);
1432
    Static3D scale = new Static3D(+1,+1,-1);
1433
1434
    Static3D axisXplus = new Static3D(+1, 0, 0);
1435
    Static3D axisXminus= new Static3D(-1, 0, 0);
1436
    Static3D axisYplus = new Static3D( 0,+1, 0);
1437
    Static3D axisYminus= new Static3D( 0,-1, 0);
1438
1439
    Static3D center1= new Static3D( 0, 0, 0);
1440
    Static3D center2= new Static3D( 0, 0,-Z);
1441
    Static3D center3= new Static3D( 0,+width*0.5f, 0);
1442
    Static3D center4= new Static3D( 0,-width*0.5f, 0);
1443
1444
    effect[ 0] = new VertexEffectMove(move1);
1445
    effect[ 1] = new VertexEffectMove(move2);
1446
    effect[ 2] = new VertexEffectMove(move3);
1447
    effect[ 3] = new VertexEffectMove(move4);
1448
    effect[ 4] = new VertexEffectScale(scale);
1449
    effect[ 5] = new VertexEffectRotate(angle1, axisYplus , center1);
1450
    effect[ 6] = new VertexEffectRotate(angle2, axisYplus , center1);
1451
    effect[ 7] = new VertexEffectRotate(angle1, axisYminus, center2);
1452
    effect[ 8] = new VertexEffectRotate(angle2, axisYminus, center2);
1453
    effect[ 9] = new VertexEffectRotate(angle3, axisXplus , center3);
1454
    effect[10] = new VertexEffectRotate(angle3, axisXminus, center4);
1455
1456
    effect[ 0].setMeshAssociation( 3,-1);  // meshes 0,1
1457
    effect[ 1].setMeshAssociation(12,-1);  // meshes 2,3
1458
    effect[ 2].setMeshAssociation(16,-1);  // mesh 4
1459
    effect[ 3].setMeshAssociation(32,-1);  // mesh 5
1460
    effect[ 4].setMeshAssociation( 2,-1);  // mesh 1
1461
    effect[ 5].setMeshAssociation( 1,-1);  // mesh 0
1462
    effect[ 6].setMeshAssociation( 2,-1);  // mesh 1
1463
    effect[ 7].setMeshAssociation( 4,-1);  // mesh 2
1464
    effect[ 8].setMeshAssociation( 8,-1);  // mesh 3
1465
    effect[ 9].setMeshAssociation(16,-1);  // mesh 4
1466
    effect[10].setMeshAssociation(32,-1);  // mesh 5
1467
1468
    return effect;
1469
    }
1470
1471 e4bf4d02 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1472
1473 ed01e351 Leszek Koltunski
  VertexEffect[] createVertexEffectsMegaminxCenter(float width)
1474 e4bf4d02 Leszek Koltunski
    {
1475 ed01e351 Leszek Koltunski
    VertexEffect[] effect = new VertexEffect[2];
1476 e4bf4d02 Leszek Koltunski
1477
    Static1D angle = new Static1D(DIHEDRAL2);
1478
    Static3D axisX = new Static3D( 1.0f, 0.0f, 0.0f);
1479
    Static3D center= new Static3D( 0, 0, 0);
1480
1481 ed01e351 Leszek Koltunski
    effect[0] = new VertexEffectScale(width/COS54);
1482
    effect[1] = new VertexEffectRotate(angle, axisX, center);
1483 e4bf4d02 Leszek Koltunski
1484
    return effect;
1485
    }
1486
1487 4c0a6d97 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1488
1489
  VertexEffect[] createCuboidEffects(int[] dimensions)
1490
    {
1491
    float X = dimensions[0];
1492
    float Y = dimensions[1];
1493
    float Z = dimensions[2];
1494
1495
    float MAX_XY = Math.max(X,Y);
1496
    float MAX_XZ = Math.max(X,Z);
1497
    float MAX_YZ = Math.max(Z,Y);
1498
1499
    Static1D angle = new Static1D(90);
1500
    Static3D move  = new Static3D( 0.0f, 0.0f, 0.5f);
1501
    Static3D axisX = new Static3D( 1.0f, 0.0f, 0.0f);
1502
    Static3D axisY = new Static3D( 0.0f, 1.0f, 0.0f);
1503
    Static3D center= new Static3D( 0.0f, 0.0f, 0.0f);
1504
1505
    Static3D scale3 = new Static3D(MAX_XY,MAX_XY,+Z);
1506
    Static3D scale4 = new Static3D(MAX_XY,MAX_XY,-Z);
1507
    Static3D scale5 = new Static3D(MAX_XZ,+Y,MAX_XZ);
1508
    Static3D scale6 = new Static3D(MAX_XZ,-Y,MAX_XZ);
1509
    Static3D scale7 = new Static3D(+X,MAX_YZ,MAX_YZ);
1510
    Static3D scale8 = new Static3D(-X,MAX_YZ,MAX_YZ);
1511
1512
    VertexEffect[] effect = new VertexEffect[9];
1513
1514
    effect[0] = new VertexEffectMove(move);
1515
    effect[1] = new VertexEffectRotate(angle, axisX, center);
1516
    effect[2] = new VertexEffectRotate(angle, axisY, center);
1517
    effect[3] = new VertexEffectScale(scale3);
1518
    effect[4] = new VertexEffectScale(scale4);
1519
    effect[5] = new VertexEffectScale(scale5);
1520
    effect[6] = new VertexEffectScale(scale6);
1521
    effect[7] = new VertexEffectScale(scale7);
1522
    effect[8] = new VertexEffectScale(scale8);
1523
1524
    effect[1].setMeshAssociation(12,-1);  // meshes 2,3
1525
    effect[2].setMeshAssociation( 3,-1);  // meshes 0,1
1526
    effect[3].setMeshAssociation(16,-1);  // mesh 4
1527
    effect[4].setMeshAssociation(32,-1);  // mesh 5
1528
    effect[5].setMeshAssociation( 8,-1);  // mesh 3
1529
    effect[6].setMeshAssociation( 4,-1);  // mesh 2
1530
    effect[7].setMeshAssociation( 1,-1);  // mesh 0
1531
    effect[8].setMeshAssociation( 2,-1);  // mesh 1
1532
1533
    return effect;
1534
    }
1535
1536 55fb45c2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1537
// OBJECTS
1538
///////////////////////////////////////////////////////////////////////////////////////////////////
1539
1540
1541
///////////////////////////////////////////////////////////////////////////////////////////////////
1542
// SKEWB
1543
1544 749ef882 Leszek Koltunski
  public MeshBase createSkewbCornerMesh()
1545 55fb45c2 Leszek Koltunski
    {
1546
    MeshBase mesh = createFacesSkewbCorner();
1547
    VertexEffect[] effects = createVertexEffectsSkewbCorner();
1548
    for( VertexEffect effect : effects ) mesh.apply(effect);
1549
1550
    float E = 0.5f;
1551
    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
1552
1553
    Static3D[] verticesType1 = new Static3D[1];
1554
    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
1555
    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
1556
1557
    Static3D[] verticesType2 = new Static3D[3];
1558
    verticesType2[0] = new Static3D(-E, 0, 0);
1559
    verticesType2[1] = new Static3D( 0,-E, 0);
1560
    verticesType2[2] = new Static3D( 0, 0,-E);
1561
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
1562
1563
    mesh.mergeEffComponents();
1564
1565
    return mesh;
1566
    }
1567
1568
///////////////////////////////////////////////////////////////////////////////////////////////////
1569
1570 749ef882 Leszek Koltunski
  public MeshBase createSkewbFaceMesh()
1571 55fb45c2 Leszek Koltunski
    {
1572
    MeshBase mesh = createFacesSkewbFace();
1573
    VertexEffect[] effects = createVertexEffectsSkewbFace();
1574
    for( VertexEffect effect : effects ) mesh.apply(effect);
1575
1576
    Static3D roundingCenter = new Static3D(0,0,-0.2f);
1577
    float E = SQ2/4;
1578
    Static3D[] vertices = new Static3D[4];
1579
    vertices[0] = new Static3D(-E*SQ2,      0, 0);
1580
    vertices[1] = new Static3D(+E*SQ2,      0, 0);
1581
    vertices[2] = new Static3D(     0, -E*SQ2, 0);
1582
    vertices[3] = new Static3D(     0, +E*SQ2, 0);
1583 d92030e4 Leszek Koltunski
    roundCorners(mesh,roundingCenter,vertices,0.06f,0.10f);
1584 55fb45c2 Leszek Koltunski
1585
    mesh.mergeEffComponents();
1586
    mesh.addEmptyTexComponent();
1587
1588
    return mesh;
1589
    }
1590
1591
///////////////////////////////////////////////////////////////////////////////////////////////////
1592
// DINO
1593
1594 749ef882 Leszek Koltunski
  public MeshBase createDinoMesh()
1595 55fb45c2 Leszek Koltunski
    {
1596
    MeshBase mesh = createFacesDino();
1597
    VertexEffect[] effects = createVertexEffectsDino();
1598
    for( VertexEffect effect : effects ) mesh.apply(effect);
1599
1600
    float F = 0.5f;
1601
    Static3D roundingCenter = new Static3D(0.0f, -1.5f*F, -1.5f*F);
1602
    Static3D[] verticesRound = new Static3D[4];
1603
    verticesRound[0] = new Static3D(     0,-3*F,    0 );
1604
    verticesRound[1] = new Static3D(     0,   0, -3*F );
1605
    verticesRound[2] = new Static3D(  -3*F,   0,    0 );
1606
    verticesRound[3] = new Static3D(  +3*F,   0,    0 );
1607
    roundCorners(mesh,roundingCenter,verticesRound,0.10f,0.40f);
1608
1609
    mesh.mergeEffComponents();
1610
1611
    return mesh;
1612
    }
1613
1614
///////////////////////////////////////////////////////////////////////////////////////////////////
1615
// Helicopter
1616
1617 749ef882 Leszek Koltunski
  public MeshBase createHelicopterCornerMesh()
1618 55fb45c2 Leszek Koltunski
    {
1619
    MeshBase mesh = createFacesHelicopterCorner();
1620
    VertexEffect[] effects = createVertexEffectsHelicopterCorner();
1621
    for( VertexEffect effect : effects ) mesh.apply(effect);
1622
1623
    float E = 0.5f;
1624
    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
1625
1626
    Static3D[] verticesType1 = new Static3D[1];
1627
    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
1628
    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
1629
1630
    Static3D[] verticesType2 = new Static3D[3];
1631
    verticesType2[0] = new Static3D(-E, 0, 0);
1632
    verticesType2[1] = new Static3D( 0,-E, 0);
1633
    verticesType2[2] = new Static3D( 0, 0,-E);
1634 2fcfce81 Leszek Koltunski
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
1635 55fb45c2 Leszek Koltunski
1636
    mesh.mergeEffComponents();
1637
1638
    return mesh;
1639
    }
1640
1641
///////////////////////////////////////////////////////////////////////////////////////////////////
1642
1643 749ef882 Leszek Koltunski
  public MeshBase createHelicopterFaceMesh()
1644 55fb45c2 Leszek Koltunski
    {
1645
    MeshBase mesh = createFacesHelicopterFace();
1646
    VertexEffect[] effects = createVertexEffectsHelicopterFace();
1647
    for( VertexEffect effect : effects ) mesh.apply(effect);
1648
1649
    float E = 0.5f;
1650
    Static3D roundingCenter = new Static3D(-E/2 + E/3,-E/2 + E/3,-E/2);
1651
1652
    Static3D[] verticesType1 = new Static3D[1];
1653
    verticesType1[0] = new Static3D(E/3,E/3,0.0f);
1654
    roundCorners(mesh,roundingCenter,verticesType1,0.06f,0.15f);
1655
1656
    Static3D[] verticesType2 = new Static3D[2];
1657
    verticesType2[0] = new Static3D(-E+E/3, E/3  , 0);
1658
    verticesType2[1] = new Static3D( E/3  ,-E+E/3, 0);
1659 2fcfce81 Leszek Koltunski
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
1660 55fb45c2 Leszek Koltunski
1661
    mesh.mergeEffComponents();
1662
    mesh.addEmptyTexComponent();
1663
    mesh.addEmptyTexComponent();
1664
1665
    return mesh;
1666
    }
1667
1668
///////////////////////////////////////////////////////////////////////////////////////////////////
1669
// Redi cube
1670
1671 749ef882 Leszek Koltunski
  public MeshBase createRediEdgeMesh()
1672 55fb45c2 Leszek Koltunski
    {
1673
    MeshBase mesh = createFacesRediEdge();
1674
    VertexEffect[] effects = createVertexEffectsRediEdge();
1675
    for( VertexEffect effect : effects ) mesh.apply(effect);
1676
1677
    Static3D center = new Static3D(0.0f,-0.75f,-0.75f);
1678 2fcfce81 Leszek Koltunski
    Static3D[] vertices = new Static3D[2];
1679 55fb45c2 Leszek Koltunski
    vertices[0] = new Static3D( 0.5f, 0.0f, 0.0f);
1680
    vertices[1] = new Static3D(-0.5f, 0.0f, 0.0f);
1681
    roundCorners(mesh,center,vertices,0.06f,0.20f);
1682
1683
    mesh.mergeEffComponents();
1684
1685
    return mesh;
1686
    }
1687
1688
///////////////////////////////////////////////////////////////////////////////////////////////////
1689
1690 749ef882 Leszek Koltunski
  public MeshBase createRediCornerMesh()
1691 55fb45c2 Leszek Koltunski
    {
1692
    MeshBase mesh = createFacesRediCorner();
1693
    VertexEffect[] effects = createVertexEffectsRediCorner();
1694
    for( VertexEffect effect : effects ) mesh.apply(effect);
1695
1696
    Static3D center = new Static3D(0,0,0);
1697 05cc8075 Leszek Koltunski
    Static3D[] vertices = new Static3D[8];
1698
    vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
1699
    vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
1700
    vertices[2] = new Static3D(+0.5f,-0.5f,+0.5f);
1701
    vertices[3] = new Static3D(+0.5f,-0.5f,-0.5f);
1702
    vertices[4] = new Static3D(-0.5f,+0.5f,+0.5f);
1703
    vertices[5] = new Static3D(-0.5f,+0.5f,-0.5f);
1704
    vertices[6] = new Static3D(-0.5f,-0.5f,+0.5f);
1705
    vertices[7] = new Static3D(-0.5f,-0.5f,-0.5f);
1706
1707
    roundCorners(mesh,center,vertices,0.06f,0.12f);
1708 962437b5 Leszek Koltunski
1709
    mesh.mergeEffComponents();
1710
1711 49cd8581 Leszek Koltunski
    return mesh;
1712
    }
1713
1714
///////////////////////////////////////////////////////////////////////////////////////////////////
1715
1716 749ef882 Leszek Koltunski
  public MeshBase createIvyCornerMesh()
1717 49cd8581 Leszek Koltunski
    {
1718
    MeshBase mesh = createFacesIvyCorner();
1719
    VertexEffect[] effects = createVertexEffectsIvyCorner();
1720
    for( VertexEffect effect : effects ) mesh.apply(effect);
1721
1722
    Static3D center = new Static3D(-0.5f,-0.5f,-0.5f);
1723 f9464035 Leszek Koltunski
    Static3D[] vertices = new Static3D[4];
1724 6a224bdc Leszek Koltunski
    vertices[0] = new Static3D(+0.0f,+0.0f,+0.0f);
1725 f9464035 Leszek Koltunski
    vertices[1] = new Static3D(-1.0f,+0.0f,+0.0f);
1726
    vertices[2] = new Static3D(+0.0f,-1.0f,+0.0f);
1727
    vertices[3] = new Static3D(+0.0f,+0.0f,-1.0f);
1728
1729
    roundCorners(mesh,center,vertices,0.03f,0.10f);
1730 49cd8581 Leszek Koltunski
1731
    mesh.mergeEffComponents();
1732
1733
    return mesh;
1734
    }
1735
1736
///////////////////////////////////////////////////////////////////////////////////////////////////
1737
1738 749ef882 Leszek Koltunski
  public MeshBase createIvyFaceMesh()
1739 49cd8581 Leszek Koltunski
    {
1740
    MeshBase mesh = createFacesIvyFace();
1741
1742 f9464035 Leszek Koltunski
    Static3D center = new Static3D(-0.0f,-0.0f,-0.5f);
1743
    Static3D[] vertices = new Static3D[2];
1744
    vertices[0] = new Static3D(-0.5f,+0.5f,+0.0f);
1745
    vertices[1] = new Static3D(+0.5f,-0.5f,+0.0f);
1746
1747
    roundCorners(mesh,center,vertices,0.03f,0.10f);
1748
1749 49cd8581 Leszek Koltunski
    mesh.mergeEffComponents();
1750
    mesh.addEmptyTexComponent();
1751
    mesh.addEmptyTexComponent();
1752
    mesh.addEmptyTexComponent();
1753
    mesh.addEmptyTexComponent();
1754
1755 59b87d56 Leszek Koltunski
    return mesh;
1756
    }
1757
1758
///////////////////////////////////////////////////////////////////////////////////////////////////
1759
1760 749ef882 Leszek Koltunski
  public MeshBase createRexCornerMesh()
1761 59b87d56 Leszek Koltunski
    {
1762
    MeshBase mesh = createFacesRexCorner();
1763
    VertexEffect[] effects = createVertexEffectsRexCorner();
1764
    for( VertexEffect effect : effects ) mesh.apply(effect);
1765
1766 da36b97e Leszek Koltunski
    final float G = (1-REX_D)/3;
1767
    Static3D center = new Static3D(0.0f,0.0f,-G*SQ2/2);
1768 59b87d56 Leszek Koltunski
    Static3D[] vertices = new Static3D[1];
1769 72b93c08 Leszek Koltunski
    vertices[0] = new Static3D(+G,-G,+0.0f);
1770 da36b97e Leszek Koltunski
    roundCorners(mesh,center,vertices,0.10f,0.10f);
1771 59b87d56 Leszek Koltunski
1772
    mesh.mergeEffComponents();
1773
    mesh.addEmptyTexComponent();
1774
    mesh.addEmptyTexComponent();
1775 da36b97e Leszek Koltunski
    mesh.addEmptyTexComponent();
1776
    mesh.addEmptyTexComponent();
1777 59b87d56 Leszek Koltunski
1778
    return mesh;
1779
    }
1780
1781
///////////////////////////////////////////////////////////////////////////////////////////////////
1782
1783 749ef882 Leszek Koltunski
  public MeshBase createRexFaceMesh()
1784 59b87d56 Leszek Koltunski
    {
1785
    MeshBase mesh = createFacesRexFace();
1786
1787
    mesh.mergeEffComponents();
1788
    mesh.addEmptyTexComponent();
1789
    mesh.addEmptyTexComponent();
1790 da36b97e Leszek Koltunski
    mesh.addEmptyTexComponent();
1791
    mesh.addEmptyTexComponent();
1792 59b87d56 Leszek Koltunski
1793
    return mesh;
1794
    }
1795
1796
///////////////////////////////////////////////////////////////////////////////////////////////////
1797
1798 749ef882 Leszek Koltunski
  public MeshBase createRexEdgeMesh()
1799 59b87d56 Leszek Koltunski
    {
1800
    MeshBase mesh = createFacesRexEdge();
1801
    VertexEffect[] effects = createVertexEffectsRexEdge();
1802
    for( VertexEffect effect : effects ) mesh.apply(effect);
1803
1804
    Static3D center = new Static3D(0.0f,-0.5f,-0.5f);
1805
    Static3D[] vertices = new Static3D[2];
1806
    vertices[0] = new Static3D(+0.5f,+0.0f,+0.0f);
1807
    vertices[1] = new Static3D(-0.5f,+0.0f,+0.0f);
1808 0b8ffe1a Leszek Koltunski
    roundCorners(mesh,center,vertices,0.06f,0.10f);
1809 59b87d56 Leszek Koltunski
1810
    mesh.mergeEffComponents();
1811
1812 bbc6da6c Leszek Koltunski
    return mesh;
1813
    }
1814
1815
///////////////////////////////////////////////////////////////////////////////////////////////////
1816
1817 749ef882 Leszek Koltunski
  public MeshBase createKilominxCenterMesh(float width)
1818 bbc6da6c Leszek Koltunski
    {
1819 7764a67a Leszek Koltunski
    MeshBase mesh = createFacesKilominxCenter();
1820
    VertexEffect[] effects = createVertexEffectsKilominxCenter(width);
1821 bbc6da6c Leszek Koltunski
    for( VertexEffect effect : effects ) mesh.apply(effect);
1822 a2398d6b Leszek Koltunski
1823 12313693 Leszek Koltunski
    float A = (2*SQ3/3)* SIN54;
1824 a2398d6b Leszek Koltunski
    float B = 0.4f;
1825 a64e07d0 Leszek Koltunski
    float X = SIN_HALFD * SIN54 *COS54  ;
1826 12313693 Leszek Koltunski
    float Y = SIN54 * SIN54 - 0.5f;
1827 a64e07d0 Leszek Koltunski
    float Z = COS_HALFD* SIN54 *COS54  ;
1828 a2398d6b Leszek Koltunski
1829
    Static3D center = new Static3D(0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B);
1830
1831
    Static3D[] vertices = new Static3D[4];
1832
    vertices[0] = new Static3D( 0.0f, 0.0f, 0.0f);
1833
    vertices[1] = new Static3D( 0.0f,-0.5f, 0.0f);
1834
    vertices[2] = new Static3D(-X   , Y   ,-Z   );
1835
    vertices[3] = new Static3D(+X   , Y   ,-Z   );
1836
1837
    roundCorners(mesh,center,vertices,0.03f,0.10f);
1838
1839 bbc6da6c Leszek Koltunski
    mesh.mergeEffComponents();
1840
1841 a64e07d0 Leszek Koltunski
    return mesh;
1842
    }
1843
1844
///////////////////////////////////////////////////////////////////////////////////////////////////
1845 7764a67a Leszek Koltunski
// numLayers==3 --> index=0; numLayers=5 --> index=1 ...
1846
// type: 0,1,... 0 --> edge, 1 --> 1 layer deeper, etc
1847 a64e07d0 Leszek Koltunski
1848 749ef882 Leszek Koltunski
  public MeshBase createKilominxEdgeMesh(int numLayers, float width, float height, boolean left)
1849 7764a67a Leszek Koltunski
    {
1850 16f34a98 Leszek Koltunski
    MeshBase mesh = createFacesKilominxEdge(numLayers,width,height);
1851
    VertexEffect[] effects = createVertexEffectsKilominxEdge(width,height,left);
1852 7764a67a Leszek Koltunski
    for( VertexEffect effect : effects ) mesh.apply(effect);
1853
1854 16f34a98 Leszek Koltunski
// round...
1855
1856 7764a67a Leszek Koltunski
    mesh.mergeEffComponents();
1857
1858
    return mesh;
1859
    }
1860
1861
///////////////////////////////////////////////////////////////////////////////////////////////////
1862
1863 749ef882 Leszek Koltunski
  public MeshBase createMinxCornerMesh(int numLayers, float width)
1864 a64e07d0 Leszek Koltunski
    {
1865 16f34a98 Leszek Koltunski
    MeshBase mesh = createFacesMinxCorner(numLayers);
1866
    VertexEffect[] effects = createVertexEffectsMinxCorner(width);
1867 a64e07d0 Leszek Koltunski
    for( VertexEffect effect : effects ) mesh.apply(effect);
1868
1869
    float A = (2*SQ3/3)* SIN54;
1870
    float B = 0.4f;
1871 16f34a98 Leszek Koltunski
/*
1872 a64e07d0 Leszek Koltunski
    float X = SIN_HALFD* SIN54 * COS54;
1873
    float Y = SIN54 * SIN54 - 0.5f;
1874
    float Z = COS_HALFD* SIN54 * COS54;
1875 16f34a98 Leszek Koltunski
    float S = 2*width;
1876
*/
1877 a64e07d0 Leszek Koltunski
    Static3D center = new Static3D(0.0f, -(float)Math.sqrt(1-A*A)*B,-A*B);
1878 16f34a98 Leszek Koltunski
    Static3D[] vertices = new Static3D[1];
1879 a64e07d0 Leszek Koltunski
    vertices[0] = new Static3D( 0.0f, 0.0f  , 0.0f);
1880 16f34a98 Leszek Koltunski
/*
1881 a64e07d0 Leszek Koltunski
    vertices[1] = new Static3D( 0.0f,-0.5f*S, 0.0f);
1882
    vertices[2] = new Static3D(-X*S , Y*S   ,-Z*S );
1883
    vertices[3] = new Static3D(+X*S , Y*S   ,-Z*S );
1884 16f34a98 Leszek Koltunski
*/
1885 a64e07d0 Leszek Koltunski
    roundCorners(mesh,center,vertices,0.04f,0.10f);
1886
1887
    mesh.mergeEffComponents();
1888
1889 ac940e24 Leszek Koltunski
    return mesh;
1890
    }
1891 d38f1397 Leszek Koltunski
1892
///////////////////////////////////////////////////////////////////////////////////////////////////
1893
// numLayers==3 --> index=0; numLayers=5 --> index=1 ...
1894
// type: 0,1,... 0 --> edge, 1 --> 1 layer deeper, etc
1895
1896 749ef882 Leszek Koltunski
  public MeshBase createMegaminxEdgeMesh(int numLayers, float width, float height)
1897 d38f1397 Leszek Koltunski
    {
1898 61b217a5 Leszek Koltunski
    MeshBase mesh = createFacesMegaminxEdge(numLayers,width,height);
1899 db608887 Leszek Koltunski
    VertexEffect[] effects = createVertexEffectsMegaminxEdge(width,height);
1900
    for( VertexEffect effect : effects ) mesh.apply(effect);
1901
1902
    mesh.mergeEffComponents();
1903 d38f1397 Leszek Koltunski
1904 e4bf4d02 Leszek Koltunski
    return mesh;
1905
    }
1906
1907
///////////////////////////////////////////////////////////////////////////////////////////////////
1908
1909 749ef882 Leszek Koltunski
  public MeshBase createMegaminxCenterMesh(int numLayers, float width)
1910 e4bf4d02 Leszek Koltunski
    {
1911 61b217a5 Leszek Koltunski
    MeshBase mesh = createFacesMegaminxCenter(numLayers);
1912 ed01e351 Leszek Koltunski
    VertexEffect[] effects = createVertexEffectsMegaminxCenter(width);
1913 e4bf4d02 Leszek Koltunski
    for( VertexEffect effect : effects ) mesh.apply(effect);
1914
1915
    mesh.mergeEffComponents();
1916
    mesh.addEmptyTexComponent();
1917
    mesh.addEmptyTexComponent();
1918
    mesh.addEmptyTexComponent();
1919
    mesh.addEmptyTexComponent();
1920
1921 4c0a6d97 Leszek Koltunski
    return mesh;
1922
    }
1923
1924
///////////////////////////////////////////////////////////////////////////////////////////////////
1925
1926 749ef882 Leszek Koltunski
  public MeshBase createCuboidMesh(int[] dimensions)
1927 4c0a6d97 Leszek Koltunski
    {
1928 af940c29 Leszek Koltunski
    MeshBase mesh = createCuboid(dimensions);
1929 4c0a6d97 Leszek Koltunski
    VertexEffect[] effects = createCuboidEffects(dimensions);
1930
    for( VertexEffect effect : effects ) mesh.apply(effect);
1931
1932 af940c29 Leszek Koltunski
    int X = dimensions[0];
1933
    int Y = dimensions[1];
1934
    int Z = dimensions[2];
1935
1936
    float strength = 0.04f;
1937
    float radius   = 0.15f;
1938
1939
    Static3D[] vertices = new Static3D[1];
1940
    Static3D center;
1941
1942
    vertices[0] = new Static3D(+0.5f*X,+0.5f*Y,+0.5f*Z);
1943
    center = new Static3D(+0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1));
1944
    roundCorners(mesh, center, vertices, strength, radius);
1945
1946
    vertices[0] = new Static3D(+0.5f*X,+0.5f*Y,-0.5f*Z);
1947
    center = new Static3D(+0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1));
1948
    roundCorners(mesh, center, vertices, strength, radius);
1949
1950
    vertices[0] = new Static3D(+0.5f*X,-0.5f*Y,+0.5f*Z);
1951
    center = new Static3D(+0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1));
1952
    roundCorners(mesh, center, vertices, strength, radius);
1953
1954
    vertices[0] = new Static3D(+0.5f*X,-0.5f*Y,-0.5f*Z);
1955
    center = new Static3D(+0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1));
1956
    roundCorners(mesh, center, vertices, strength, radius);
1957
1958
    vertices[0] = new Static3D(-0.5f*X,+0.5f*Y,+0.5f*Z);
1959
    center = new Static3D(-0.5f*(X-1),+0.5f*(Y-1),+0.5f*(Z-1));
1960
    roundCorners(mesh, center, vertices, strength, radius);
1961
1962
    vertices[0] = new Static3D(-0.5f*X,+0.5f*Y,-0.5f*Z);
1963
    center = new Static3D(-0.5f*(X-1),+0.5f*(Y-1),-0.5f*(Z-1));
1964
    roundCorners(mesh, center, vertices, strength, radius);
1965
1966
    vertices[0] = new Static3D(-0.5f*X,-0.5f*Y,+0.5f*Z);
1967
    center = new Static3D(-0.5f*(X-1),-0.5f*(Y-1),+0.5f*(Z-1));
1968
    roundCorners(mesh, center, vertices, strength, radius);
1969
1970
    vertices[0] = new Static3D(-0.5f*X,-0.5f*Y,-0.5f*Z);
1971
    center = new Static3D(-0.5f*(X-1),-0.5f*(Y-1),-0.5f*(Z-1));
1972
    roundCorners(mesh, center, vertices, strength, radius);
1973
1974 4c0a6d97 Leszek Koltunski
    mesh.mergeEffComponents();
1975
1976 db608887 Leszek Koltunski
    return mesh;
1977 d38f1397 Leszek Koltunski
    }
1978 b1f2ccf5 Leszek Koltunski
1979
1980
1981
1982
///////////////////////////////////////////////////////////////////////////////////////////////////
1983
1984
  private boolean areColinear(double[][] vertices, int index1, int index2, int index3)
1985
    {
1986
    double x1 = vertices[index1][0];
1987
    double y1 = vertices[index1][1];
1988
    double z1 = vertices[index1][2];
1989
    double x2 = vertices[index2][0];
1990
    double y2 = vertices[index2][1];
1991
    double z2 = vertices[index2][2];
1992
    double x3 = vertices[index3][0];
1993
    double y3 = vertices[index3][1];
1994
    double z3 = vertices[index3][2];
1995
1996
    double v1x = x2-x1;
1997
    double v1y = y2-y1;
1998
    double v1z = z2-z1;
1999
    double v2x = x3-x1;
2000
    double v2y = y3-y1;
2001
    double v2z = z3-z1;
2002
2003
    double A = Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) );
2004
2005
    return (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z);
2006
    }
2007
2008
///////////////////////////////////////////////////////////////////////////////////////////////////
2009
2010
  private void computeNormalVector(double[][] vertices, int index1, int index2, int index3)
2011
    {
2012
    double x1 = vertices[index1][0];
2013
    double y1 = vertices[index1][1];
2014
    double z1 = vertices[index1][2];
2015
    double x2 = vertices[index2][0];
2016
    double y2 = vertices[index2][1];
2017
    double z2 = vertices[index2][2];
2018
    double x3 = vertices[index3][0];
2019
    double y3 = vertices[index3][1];
2020
    double z3 = vertices[index3][2];
2021
2022
    double v1x = x2-x1;
2023
    double v1y = y2-y1;
2024
    double v1z = z2-z1;
2025
    double v2x = x3-x1;
2026
    double v2y = y3-y1;
2027
    double v2z = z3-z1;
2028
2029
    mBuffer[0] = v1y*v2z - v2y*v1z;
2030
    mBuffer[1] = v1z*v2x - v2z*v1x;
2031
    mBuffer[2] = v1x*v2y - v2x*v1y;
2032
2033
    double len = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
2034
    len = Math.sqrt(len);
2035
    mBuffer[0] /= len;
2036
    mBuffer[1] /= len;
2037
    mBuffer[2] /= len;
2038
    }
2039
2040
///////////////////////////////////////////////////////////////////////////////////////////////////
2041
// return quat1*quat2
2042
2043
  private static void quatMultiply( double[] quat1, double[] quat2, double[] result )
2044
    {
2045
    double qx = quat1[0];
2046
    double qy = quat1[1];
2047
    double qz = quat1[2];
2048
    double qw = quat1[3];
2049
2050
    double rx = quat2[0];
2051
    double ry = quat2[1];
2052
    double rz = quat2[2];
2053
    double rw = quat2[3];
2054
2055
    result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
2056
    result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
2057
    result[2] = rw*qz + rz*qw - ry*qx + rx*qy;
2058
    result[3] = rw*qw - rz*qz - ry*qy - rx*qx;
2059
    }
2060
2061
///////////////////////////////////////////////////////////////////////////////////////////////////
2062
2063
  private void fitInSquare(FaceTransform info, double[][] vert3D)
2064
    {
2065
    double minX = Double.MAX_VALUE;
2066
    double maxX =-Double.MAX_VALUE;
2067
    double minY = Double.MAX_VALUE;
2068
    double maxY =-Double.MAX_VALUE;
2069
2070
    for (double[] vert : vert3D)
2071
      {
2072
      double x = vert[0];
2073
      double y = vert[1];
2074
2075
      if (x > maxX) maxX = x;
2076
      if (x < minX) minX = x;
2077
      if (y > maxY) maxY = y;
2078
      if (y < minY) minY = y;
2079
      }
2080
2081
    minX = minX<0 ? -minX:minX;
2082
    maxX = maxX<0 ? -maxX:maxX;
2083
    minY = minY<0 ? -minY:minY;
2084
    maxY = maxY<0 ? -maxY:maxY;
2085
2086
    double max1 = Math.max(minX,minY);
2087
    double max2 = Math.max(maxX,maxY);
2088
    double max3 = Math.max(max1,max2);
2089
2090
    info.scale = max3/0.5;
2091
2092
    int len = vert3D.length;
2093
    StickerCoords sInfo = new StickerCoords();
2094
    sInfo.vertices = new double[2*len];
2095
2096
    for( int vertex=0; vertex<len; vertex++ )
2097
      {
2098
      sInfo.vertices[2*vertex  ] = vert3D[vertex][0] / info.scale;
2099
      sInfo.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
2100
      }
2101
2102
    mStickerCoords.add(sInfo);
2103
2104
    info.sticker = mStickerCoords.size() -1;
2105
    info.flip = false;
2106
    }
2107
2108
///////////////////////////////////////////////////////////////////////////////////////////////////
2109
2110 31cd7256 Leszek Koltunski
  private FaceTransform constructNewTransform(final double[][] vert3D)
2111 b1f2ccf5 Leszek Koltunski
    {
2112 31cd7256 Leszek Koltunski
    FaceTransform ft = new FaceTransform();
2113
2114 b1f2ccf5 Leszek Koltunski
    // compute center of gravity
2115 31cd7256 Leszek Koltunski
    ft.vx = 0.0f;
2116
    ft.vy = 0.0f;
2117
    ft.vz = 0.0f;
2118 b1f2ccf5 Leszek Koltunski
    int len = vert3D.length;
2119
2120
    for (double[] vert : vert3D)
2121
      {
2122 31cd7256 Leszek Koltunski
      ft.vx += vert[0];
2123
      ft.vy += vert[1];
2124
      ft.vz += vert[2];
2125 b1f2ccf5 Leszek Koltunski
      }
2126
2127 31cd7256 Leszek Koltunski
    ft.vx /= len;
2128
    ft.vy /= len;
2129
    ft.vz /= len;
2130 b1f2ccf5 Leszek Koltunski
2131
    // move all vertices so that their center of gravity is at (0,0,0)
2132
    for (int i=0; i<len; i++)
2133
      {
2134 31cd7256 Leszek Koltunski
      vert3D[i][0] -= ft.vx;
2135
      vert3D[i][1] -= ft.vy;
2136
      vert3D[i][2] -= ft.vz;
2137 b1f2ccf5 Leszek Koltunski
      }
2138
2139
    // find 3 non-colinear vertices
2140
    int foundIndex = -1;
2141
2142
    for(int vertex=2; vertex<len; vertex++)
2143
      {
2144
      if( !areColinear(vert3D,0,1,vertex) )
2145
        {
2146
        foundIndex = vertex;
2147
        break;
2148
        }
2149
      }
2150
2151
    // compute the normal vector
2152
    if( foundIndex==-1 )
2153
      {
2154
      throw new RuntimeException("all vertices colinear");
2155
      }
2156
2157
    computeNormalVector(vert3D,0,1,foundIndex);
2158
2159
    // rotate so that the normal vector becomes (0,0,1)
2160
    double axisX, axisY, axisZ;
2161
2162
    if( mBuffer[0]!=0.0f || mBuffer[1]!=0.0f )
2163
      {
2164
      axisX = -mBuffer[1];
2165
      axisY =  mBuffer[0];
2166
      axisZ = 0.0f;
2167
2168
      double axiLen = axisX*axisX + axisY*axisY;
2169
      axiLen = Math.sqrt(axiLen);
2170
      axisX /= axiLen;
2171
      axisY /= axiLen;
2172
      axisZ /= axiLen;
2173
      }
2174
    else
2175
      {
2176
      axisX = 0.0f;
2177
      axisY = 1.0f;
2178
      axisZ = 0.0f;
2179
      }
2180
2181
    double cosTheta = mBuffer[2];
2182
    double sinTheta = Math.sqrt(1-cosTheta*cosTheta);
2183
    double sinHalfTheta = computeSinHalf(cosTheta);
2184
    double cosHalfTheta = computeCosHalf(sinTheta,cosTheta);
2185
2186
    mQuat1[0] = axisX*sinHalfTheta;
2187
    mQuat1[1] = axisY*sinHalfTheta;
2188
    mQuat1[2] = axisZ*sinHalfTheta;
2189
    mQuat1[3] = cosHalfTheta;
2190
    mQuat2[0] =-axisX*sinHalfTheta;
2191
    mQuat2[1] =-axisY*sinHalfTheta;
2192
    mQuat2[2] =-axisZ*sinHalfTheta;
2193
    mQuat2[3] = cosHalfTheta;
2194
2195
    for (double[] vert : vert3D)
2196
      {
2197
      quatMultiply(mQuat1, vert  , mQuat3);
2198
      quatMultiply(mQuat3, mQuat2, vert  );
2199
      }
2200
2201
    // fit the whole thing in a square and remember the scale & 2D vertices
2202 31cd7256 Leszek Koltunski
    fitInSquare(ft, vert3D);
2203 b1f2ccf5 Leszek Koltunski
2204
    // remember the rotation
2205 31cd7256 Leszek Koltunski
    ft.qx =-mQuat1[0];
2206
    ft.qy =-mQuat1[1];
2207
    ft.qz =-mQuat1[2];
2208
    ft.qw = mQuat1[3];
2209
2210
    return ft;
2211 b1f2ccf5 Leszek Koltunski
    }
2212
2213
///////////////////////////////////////////////////////////////////////////////////////////////////
2214
2215
  private double computeCos(double oldX, double oldY, double newX, double newY, double len1, double len2)
2216
    {
2217
    double ret= (oldX*newX+oldY*newY) / (len1*len2);
2218
    if( ret<-1.0 ) return -1.0;
2219
    if( ret> 1.0 ) return  1.0;
2220
2221
    return ret;
2222
    }
2223
2224
///////////////////////////////////////////////////////////////////////////////////////////////////
2225
// sin of (signed!) angle between vectors 'old' and 'new', counterclockwise!
2226
2227
  private double computeSin(double oldX, double oldY, double newX, double newY, double len1, double len2)
2228
    {
2229
    double ret= (newX*oldY-oldX*newY) / (len1*len2);
2230
    if( ret<-1.0 ) return -1.0;
2231
    if( ret> 1.0 ) return  1.0;
2232
2233
    return ret;
2234
    }
2235
2236
///////////////////////////////////////////////////////////////////////////////////////////////////
2237
2238
  private void rotateAllVertices(double[] result, int len, double[] vertices, double sin, double cos)
2239
    {
2240
    for(int i=0; i<len; i++)
2241
      {
2242
      result[2*i  ] = vertices[2*i  ]*cos - vertices[2*i+1]*sin;
2243
      result[2*i+1] = vertices[2*i  ]*sin + vertices[2*i+1]*cos;
2244
      }
2245
    }
2246
2247
///////////////////////////////////////////////////////////////////////////////////////////////////
2248
2249
  private double computeScale(double[] v1, double[] v2)
2250
    {
2251
    double lenSq1 = v1[0]*v1[0] + v1[1]*v1[1];
2252
    double lenSq2 = v2[0]*v2[0] + v2[1]*v2[1];
2253
2254
    return Math.sqrt(lenSq2/lenSq1);
2255
    }
2256
2257
///////////////////////////////////////////////////////////////////////////////////////////////////
2258 31cd7256 Leszek Koltunski
// valid for 0<angle<2*PI
2259 b1f2ccf5 Leszek Koltunski
2260
  private double computeSinHalf(double cos)
2261
    {
2262
    return Math.sqrt((1-cos)/2);
2263
    }
2264
2265
///////////////////////////////////////////////////////////////////////////////////////////////////
2266 31cd7256 Leszek Koltunski
// valid for 0<angle<2*PI
2267 b1f2ccf5 Leszek Koltunski
2268
  private double computeCosHalf(double sin, double cos)
2269
    {
2270
    double cosHalf = Math.sqrt((1+cos)/2);
2271
    return sin<0 ? -cosHalf : cosHalf;
2272
    }
2273
2274
///////////////////////////////////////////////////////////////////////////////////////////////////
2275
2276
  private int computeRotatedIndex(int oldVertex, int len, int rotatedVertex, boolean inverted)
2277
    {
2278
    int v = (rotatedVertex + (inverted? -oldVertex : oldVertex));
2279
    if( v>=len ) v-=len;
2280
    if( v< 0   ) v+=len;
2281
2282
    return v;
2283
    }
2284
2285
///////////////////////////////////////////////////////////////////////////////////////////////////
2286
2287
  private boolean isScaledVersionOf(double[] newVert, double[] oldVert, int len, int vertex, boolean inverted)
2288
    {
2289
    double EPSILON = 0.001;
2290
    double scale = computeScale(newVert,oldVert);
2291
2292
    for(int i=1; i<len; i++)
2293
      {
2294
      int index = computeRotatedIndex(i,len,vertex,inverted);
2295
2296
      double horz = oldVert[2*i  ] - scale*newVert[2*index  ];
2297
      double vert = oldVert[2*i+1] - scale*newVert[2*index+1];
2298
2299
      if( horz>EPSILON || horz<-EPSILON || vert>EPSILON || vert<-EPSILON ) return false;
2300
      }
2301
2302
    return true;
2303
    }
2304
2305
///////////////////////////////////////////////////////////////////////////////////////////////////
2306
2307
  private void mirrorAllVertices(double[] output, int len, double[] input)
2308
    {
2309
    for(int vertex=0; vertex<len; vertex++)
2310
      {
2311
      output[2*vertex  ] = input[2*vertex  ];
2312
      output[2*vertex+1] =-input[2*vertex+1];
2313
      }
2314
    }
2315
2316
///////////////////////////////////////////////////////////////////////////////////////////////////
2317
2318
  private void correctInfo(FaceTransform info, double scale, double sin, double cos, int oldSticker, boolean flip)
2319
    {
2320
    mStickerCoords.remove(info.sticker);
2321
2322
    info.flip    = flip;
2323
    info.sticker = oldSticker;
2324
    info.scale  *= scale;
2325
2326
    mQuat1[0] = info.qx;
2327
    mQuat1[1] = info.qy;
2328
    mQuat1[2] = info.qz;
2329
    mQuat1[3] = info.qw;
2330
2331
    double sinHalf = computeSinHalf(cos);
2332
    double cosHalf = computeCosHalf(sin,cos);
2333
2334
    if( flip )
2335
      {
2336
      mQuat3[0] = 0.0f;
2337
      mQuat3[1] = 0.0f;
2338
      mQuat3[2] = sinHalf;
2339
      mQuat3[3] = cosHalf;
2340
2341
      mQuat4[0] = 1.0;
2342
      mQuat4[1] = 0.0;
2343
      mQuat4[2] = 0.0;
2344
      mQuat4[3] = 0.0;
2345
2346
      quatMultiply( mQuat3, mQuat4, mQuat2 );
2347
      }
2348
    else
2349
      {
2350
      mQuat2[0] = 0.0f;
2351
      mQuat2[1] = 0.0f;
2352
      mQuat2[2] = sinHalf;
2353
      mQuat2[3] = cosHalf;
2354
      }
2355
2356
    quatMultiply( mQuat1, mQuat2, mQuat3 );
2357
2358
    info.qx = mQuat3[0];
2359
    info.qy = mQuat3[1];
2360
    info.qz = mQuat3[2];
2361
    info.qw = mQuat3[3];
2362
    }
2363
2364
///////////////////////////////////////////////////////////////////////////////////////////////////
2365
2366
  private void printVert(double[] buffer)
2367
    {
2368
    int len = buffer.length/2;
2369
    String str = "";
2370
2371
    for(int i=0; i<len; i++)
2372
      {
2373
      str += (" ("+buffer[2*i]+" , "+buffer[2*i+1]+" ) ");
2374
      }
2375
2376
    android.util.Log.d("D", str);
2377
    }
2378
2379
///////////////////////////////////////////////////////////////////////////////////////////////////
2380
2381
  private boolean foundVertex(FaceTransform info, double[] buffer, int len, double[] newVert,
2382
                              double[] oldVert, double lenFirstOld, int oldSticker, boolean inverted)
2383
    {
2384
    for(int vertex=0; vertex<len; vertex++)
2385
      {
2386
      double newX = newVert[2*vertex  ];
2387
      double newY = newVert[2*vertex+1];
2388
      double lenIthNew = Math.sqrt(newX*newX + newY*newY);
2389
      double cos = computeCos( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
2390
      double sin = computeSin( oldVert[0], oldVert[1], newX, newY, lenIthNew, lenFirstOld);
2391
2392
      rotateAllVertices(buffer,len,newVert,sin,cos);
2393
2394
      if( isScaledVersionOf(buffer,oldVert,len,vertex,inverted) )
2395
        {
2396
        double scale = computeScale(oldVert,newVert);
2397
        correctInfo(info,scale,sin,cos,oldSticker,inverted);
2398
        return true;
2399
        }
2400
      }
2401
2402
    return false;
2403
    }
2404
2405
///////////////////////////////////////////////////////////////////////////////////////////////////
2406
2407
  private boolean successfullyCollapsedStickers(final FaceTransform newInfo, final FaceTransform oldInfo)
2408
    {
2409
    StickerCoords sNewInfo = mStickerCoords.get(newInfo.sticker);
2410
    StickerCoords sOldInfo = mStickerCoords.get(oldInfo.sticker);
2411
    double[] newVert = sNewInfo.vertices;
2412
    double[] oldVert = sOldInfo.vertices;
2413
    int oldLen = oldVert.length;
2414
    int newLen = newVert.length;
2415
2416
    if( oldLen == newLen )
2417
      {
2418
      int oldSticker = oldInfo.sticker;
2419
      double[] buffer1 = new double[oldLen];
2420
      double lenFirstOld = Math.sqrt(oldVert[0]*oldVert[0] + oldVert[1]*oldVert[1]);
2421
      if( foundVertex(newInfo, buffer1, oldLen/2, newVert, oldVert, lenFirstOld, oldSticker, false) ) return true;
2422
      double[] buffer2 = new double[oldLen];
2423
      mirrorAllVertices(buffer2, newLen/2, newVert);
2424
      if( foundVertex(newInfo, buffer1, oldLen/2, buffer2, oldVert, lenFirstOld, oldSticker, true ) ) return true;
2425
      }
2426
2427
    return false;
2428
    }
2429
2430
///////////////////////////////////////////////////////////////////////////////////////////////////
2431
2432
  private double[][] constructVert(double[][] vertices, int[] index)
2433
    {
2434
    int len = index.length;
2435
    double[][] ret = new double[len][4];
2436
2437
    for(int i=0; i<len; i++)
2438
      {
2439
      ret[i][0] = vertices[index[i]][0];
2440
      ret[i][1] = vertices[index[i]][1];
2441
      ret[i][2] = vertices[index[i]][2];
2442
      ret[i][3] = 1.0f;
2443
      }
2444
2445
    return ret;
2446
    }
2447
2448
///////////////////////////////////////////////////////////////////////////////////////////////////
2449
2450
  private void prepareAndRoundCorners(MeshBase mesh, double[][] vertices, int[][] vertIndexes,
2451
                                      float[][] corners, int[] cornerIndexes )
2452
    {
2453
    int numNeig, lenFV;
2454
    int lenV = vertices.length;
2455
    int[] verts = new int[2*(lenV-1)];
2456
    Static3D[] staticVert = new Static3D[1];
2457
    Static3D center = new Static3D(0,0,0);
2458
    double cx, cy, cz;
2459
    double[] singleV;
2460
2461
    for(int v=0; v<lenV; v++)
2462
      {
2463
      // prepare verts[]
2464
      numNeig = 0;
2465
2466
      for (int[] vertIndex : vertIndexes)
2467
        {
2468
        lenFV = vertIndex.length;
2469
2470
        for (int fv = 0; fv < lenFV; fv++)
2471
          if (vertIndex[fv] == v)
2472
            {
2473
            int prev = fv > 0 ? fv - 1 : lenFV - 1;
2474
            int next = fv < lenFV - 1 ? fv + 1 : 0;
2475
2476
            verts[numNeig++] = vertIndex[prev];
2477
            verts[numNeig++] = vertIndex[next];
2478
            }
2479
        }
2480
2481
      cx=cy=cz=0.0f;
2482
2483
      // from verts[] prepare center
2484
      for(int n=0; n<numNeig; n++)
2485
        {
2486
        singleV = vertices[verts[n]];
2487
2488
        cx += singleV[0];
2489
        cy += singleV[1];
2490
        cz += singleV[2];
2491
        }
2492
      center.set( (float)(cx/numNeig - vertices[v][0]),
2493
                  (float)(cy/numNeig - vertices[v][1]),
2494
                  (float)(cz/numNeig - vertices[v][2]));
2495
2496
android.util.Log.e("D", "vertex: "+v+" CENTER: "+center.get0()+" "+center.get1()+" "+center.get2());
2497
2498
      // round Corners
2499
      staticVert[0] = new Static3D( (float)vertices[v][0], (float)vertices[v][1], (float)vertices[v][2]);
2500
2501
      int corn = cornerIndexes[v];
2502
      float strength = corners[corn][0];
2503
      float radius   = corners[corn][1];
2504
2505
      roundCorners(mesh, center, staticVert, strength, radius);
2506
      }
2507
    }
2508
2509
///////////////////////////////////////////////////////////////////////////////////////////////////
2510
2511
  private void correctComponents(MeshBase mesh, int numComponents)
2512
    {
2513
    int numTexToBeAdded = numComponents-mesh.getNumTexComponents();
2514
2515
    mesh.mergeEffComponents();
2516
2517
    for(int i=0; i<numTexToBeAdded; i++ ) mesh.addEmptyTexComponent();
2518
    }
2519
2520 31cd7256 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2521
2522
  private void printTransform(FaceTransform f)
2523
    {
2524
    android.util.Log.e("D", "q=("+f.qx+", "+f.qy+", "+f.qz+", "+f.qw+") v=("
2525
                       +f.vx+", "+f.vy+", "+f.vz+") scale="+f.scale+" sticker="+f.sticker);
2526
    }
2527
2528 b1f2ccf5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2529
// PUBLIC
2530
2531
  public void printStickerCoords()
2532
    {
2533
    int stickers = mStickerCoords.size();
2534
2535
    android.util.Log.d("D", "---- STICKER COORDS ----");
2536
2537
    for(int s=0; s<stickers; s++)
2538
      {
2539
      String ver = "{ ";
2540
      StickerCoords info = mStickerCoords.get(s);
2541
      int len = info.vertices.length/2;
2542
2543
      for(int i =0; i<len; i++)
2544
        {
2545
        if( i!=0 ) ver += ", ";
2546
        ver += ( (float)info.vertices[2*i]+"f, "+(float)info.vertices[2*i+1]+"f");
2547
        }
2548
2549
      ver += " }";
2550
      android.util.Log.d("D", ver);
2551
      }
2552
2553
    android.util.Log.d("D", "---- END STICKER COORDS ----");
2554
    }
2555
2556
///////////////////////////////////////////////////////////////////////////////////////////////////
2557
2558
  public void printFaceTransform()
2559
    {
2560 31cd7256 Leszek Koltunski
    android.util.Log.d("D", "---- OLD FACE TRANSFORM ---");
2561 b1f2ccf5 Leszek Koltunski
2562 31cd7256 Leszek Koltunski
    int oldfaces = mOldFaceTransf.size();
2563 b1f2ccf5 Leszek Koltunski
2564 31cd7256 Leszek Koltunski
    for(int f=0; f<oldfaces; f++)
2565 b1f2ccf5 Leszek Koltunski
      {
2566 31cd7256 Leszek Koltunski
      printTransform(mOldFaceTransf.get(f));
2567
      }
2568
2569
    android.util.Log.d("D", "---- NEW FACE TRANSFORM ---");
2570
2571
    int newfaces = mNewFaceTransf.size();
2572 b1f2ccf5 Leszek Koltunski
2573 31cd7256 Leszek Koltunski
    for(int f=0; f<newfaces; f++)
2574
      {
2575
      printTransform(mNewFaceTransf.get(f));
2576 b1f2ccf5 Leszek Koltunski
      }
2577
    }
2578
2579
///////////////////////////////////////////////////////////////////////////////////////////////////
2580
2581
  public void clear()
2582
    {
2583
    mStickerCoords.clear();
2584 31cd7256 Leszek Koltunski
    mNewFaceTransf.clear();
2585
    mOldFaceTransf.clear();
2586 b1f2ccf5 Leszek Koltunski
    }
2587
2588
///////////////////////////////////////////////////////////////////////////////////////////////////
2589
2590
  public void createNewFaceTransform( final double[][] vertices, final int[][] indexes)
2591
    {
2592 31cd7256 Leszek Koltunski
    FaceTransform ft;
2593
    int numNew = mNewFaceTransf.size();
2594
2595
    for(int i=0; i<numNew; i++)
2596
      {
2597
      ft = mNewFaceTransf.remove(0);
2598
      mOldFaceTransf.add(ft);
2599
      }
2600 b1f2ccf5 Leszek Koltunski
2601
    int numFaces = indexes.length;
2602 31cd7256 Leszek Koltunski
    int numOld = mOldFaceTransf.size();
2603 b1f2ccf5 Leszek Koltunski
2604 31cd7256 Leszek Koltunski
    for (int face=0; face<numFaces; face++)
2605 b1f2ccf5 Leszek Koltunski
      {
2606 31cd7256 Leszek Koltunski
      boolean collapsed = false;
2607
2608
      double[][] vert = constructVert(vertices, indexes[face]);
2609
      FaceTransform newT = constructNewTransform(vert);
2610
2611
      for (int old=0; !collapsed && old<numOld; old++)
2612
        {
2613
        ft = mOldFaceTransf.get(old);
2614
        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
2615
        }
2616 b1f2ccf5 Leszek Koltunski
2617 31cd7256 Leszek Koltunski
      for (int pre=0; !collapsed && pre<face; pre++)
2618 b1f2ccf5 Leszek Koltunski
        {
2619 31cd7256 Leszek Koltunski
        ft = mNewFaceTransf.get(pre);
2620
        if (successfullyCollapsedStickers(newT, ft)) collapsed = true;
2621 b1f2ccf5 Leszek Koltunski
        }
2622
2623 31cd7256 Leszek Koltunski
      mNewFaceTransf.add(newT);
2624 b1f2ccf5 Leszek Koltunski
      }
2625
    }
2626
2627
///////////////////////////////////////////////////////////////////////////////////////////////////
2628
2629
  public MeshBase createRoundedSolid(final double[][] vertices, final int[][] vertIndexes,
2630
                                     final float[][] bands    , final int[]   bandIndexes,
2631
                                     final float[][] corners  , final int[]   cornerIndexes,
2632
                                     final int numComponents )
2633
    {
2634
    int numFaces = vertIndexes.length;
2635
    float[] band, bandsComputed;
2636
    MeshBase[] meshes = new MeshBase[numFaces];
2637
    FaceTransform fInfo;
2638
    StickerCoords sInfo;
2639
2640
    for(int face=0; face<numFaces; face++)
2641
      {
2642 31cd7256 Leszek Koltunski
      fInfo = mNewFaceTransf.get(face);
2643 b1f2ccf5 Leszek Koltunski
      sInfo = mStickerCoords.get(fInfo.sticker);
2644
2645
      double[] verts = sInfo.vertices;
2646
      int lenVerts = verts.length;
2647
      float[] vertsFloat = new float[lenVerts];
2648
      for(int i=0; i<lenVerts; i++) vertsFloat[i] = (float)verts[i];
2649
2650
      band = bands[bandIndexes[face]];
2651
      bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
2652
      meshes[face] = new MeshPolygon(vertsFloat,bandsComputed,(int)band[5],(int)band[6]);
2653
      meshes[face].setEffectAssociation(0,(1<<face),0);
2654
      }
2655
2656
    MeshBase mesh = new MeshJoined(meshes);
2657
    Static3D center = new Static3D(0,0,0);
2658
2659
    for(int face=0; face<numFaces; face++)
2660
      {
2661
      int assoc = (1<<face);
2662 31cd7256 Leszek Koltunski
      fInfo = mNewFaceTransf.get(face);
2663 b1f2ccf5 Leszek Koltunski
2664
      float vx = (float)fInfo.vx;
2665
      float vy = (float)fInfo.vy;
2666
      float vz = (float)fInfo.vz;
2667
      float sc = (float)fInfo.scale;
2668
      float qx = (float)fInfo.qx;
2669
      float qy = (float)fInfo.qy;
2670
      float qz = (float)fInfo.qz;
2671
      float qw = (float)fInfo.qw;
2672
2673
      Static3D scale = new Static3D(sc,sc, fInfo.flip ? -sc : sc);
2674
      Static3D move3D= new Static3D(vx,vy,vz);
2675
      Static4D quat  = new Static4D(qx,qy,qz,qw);
2676
2677
      mesh.apply(new MatrixEffectScale(scale)           ,assoc,-1);
2678
      mesh.apply(new MatrixEffectQuaternion(quat,center),assoc,-1);
2679
      mesh.apply(new MatrixEffectMove(move3D)           ,assoc,-1);
2680
      }
2681
2682
    prepareAndRoundCorners(mesh, vertices, vertIndexes, corners, cornerIndexes);
2683
2684
    correctComponents(mesh,numComponents);
2685
2686
    return mesh;
2687
    }
2688 ac940e24 Leszek Koltunski
  }