Project

General

Profile

« Previous | Next » 

Revision b89898c5

Added by Leszek Koltunski about 4 years ago

Progress with Skewb familty; separate StickerFactory class.

View differences:

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

  
20
package org.distorted.objects;
21

  
22
import org.distorted.library.effect.VertexEffect;
23
import org.distorted.library.effect.VertexEffectDeform;
24
import org.distorted.library.effect.VertexEffectMove;
25
import org.distorted.library.effect.VertexEffectRotate;
26
import org.distorted.library.effect.VertexEffectScale;
27
import org.distorted.library.mesh.MeshBase;
28
import org.distorted.library.mesh.MeshJoined;
29
import org.distorted.library.mesh.MeshPolygon;
30
import org.distorted.library.type.Static1D;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33

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

  
36
public class CubitFactory
37
  {
38
  private static final float SQ2 = (float)Math.sqrt(2);
39
  private static final float SQ3 = (float)Math.sqrt(3);
40
  private static final float SQ6 = (float)Math.sqrt(6);
41

  
42
  private static final Static1D RADIUS = new Static1D(1);
43

  
44
  private static CubitFactory mThis;
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private CubitFactory()
49
    {
50

  
51
    }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  public static CubitFactory getInstance()
56
    {
57
    if( mThis==null ) mThis = new CubitFactory();
58

  
59
    return mThis;
60
    }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
// H - height of the band in the middle
64
// alpha - angle of the edge  [0,90]
65
// dist - often in a polygon the distance from edge to center is not 1, but something else.
66
// This is the distance.
67
// K - where to begin the second, much more flat part of the band. [0,1]
68
// N - number of bands. N>=3
69
//
70
// theory: two distinct parts to the band:
71
// 1) (0,B) - steep
72
// 2) (B,1) - flat
73
//
74
// In first part, we have y = g(x) ; in second - y = g(f(x)) where
75
//
76
// g(x) = sqrt( R^2 - (x-D)^2 ) - R*cos(alpha)
77
// f(x) = ((D-B)/(1-B)*x + B*(1-D)/(1-B)
78
// h(x) = R*(sin(alpha) - sin(x))
79
// R = H/(1-cos(alpha))
80
// D = H*sin(alpha)
81
// B = h(K*alpha)
82
//
83
// The N points are taken at:
84
//
85
// 1) in the second part, there are K2 = (N-3)/3 such points
86
// 2) in the first - K1 = (N-3) - K2
87
// 3) also, the 3 points 0,B,1
88
//
89
// so we have the sequence A[i] of N points
90
//
91
// 0
92
// h((i+1)*(1-K)*alpha/(K1+1)) (i=0,1,...,K1-1)
93
// B
94
// (1-B)*(i+1)/(K2+1) + B   (i=0,i,...,K2-1)
95
// 1
96

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

  
99
  private float f(float D, float B, float x)
100
    {
101
    return ((D-B)*x + B*(1-D))/(1-B);
102
    }
103

  
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

  
106
  private float g(float R, float D, float x, float cosAlpha)
107
    {
108
    float d = x-D;
109
    return (float)(Math.sqrt(R*R-d*d)-R*cosAlpha);
110
    }
111

  
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

  
114
  private float h(float R, float sinAlpha, float x)
115
    {
116
    return R*(sinAlpha-(float)Math.sin(x));
117
    }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  private float[] computeBands(float H, int alpha, float dist, float K, int N)
122
    {
123
    float[] bands = new float[2*N];
124

  
125
    bands[0] = 1.0f;
126
    bands[1] = 0.0f;
127

  
128
    float beta = (float)Math.atan(dist*Math.tan(Math.PI*alpha/180));
129
    float sinBeta = (float)Math.sin(beta);
130
    float cosBeta = (float)Math.cos(beta);
131
    float R = cosBeta<1.0f ? H/(1.0f-cosBeta) : 0.0f;
132
    float D = R*sinBeta;
133
    float B = h(R,sinBeta,K*beta);
134

  
135
    if( D>1.0f )
136
      {
137
      for(int i=1; i<N; i++)
138
        {
139
        bands[2*i  ] = (float)(N-1-i)/(N-1);
140
        bands[2*i+1] = H*(1-bands[2*i]);
141
        }
142
      }
143
    else
144
      {
145
      int K2 = (int)((N-3)*K);
146
      int K1 = (N-3)-K2;
147

  
148
      for(int i=0; i<=K1; i++)
149
        {
150
        float angle = K*beta + (1-K)*beta*(K1-i)/(K1+1);
151
        float x = h(R,sinBeta,angle);
152
        bands[2*i+2] = 1.0f - x;
153
        bands[2*i+3] = g(R,D,x,cosBeta);
154
        }
155

  
156
      for(int i=0; i<=K2; i++)
157
        {
158
        float x = (1-B)*(i+1)/(K2+1) + B;
159
        bands[2*K1+2 + 2*i+2] = 1.0f - x;
160
        bands[2*K1+2 + 2*i+3] = g(R,D,f(D,B,x),cosBeta);
161
        }
162
      }
163

  
164
    bands[2*N-2] = 0.0f;
165
    bands[2*N-1] =    H;
166

  
167
    return bands;
168
    }
169

  
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

  
172
  private void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius)
173
    {
174
    Static4D reg= new Static4D(0,0,0,regionRadius);
175

  
176
    float centX = center.get0();
177
    float centY = center.get1();
178
    float centZ = center.get2();
179

  
180
    for (Static3D vertex : vertices)
181
      {
182
      float x = strength*(centX - vertex.get0());
183
      float y = strength*(centY - vertex.get1());
184
      float z = strength*(centZ - vertex.get2());
185

  
186
      VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg);
187
      mesh.apply(effect);
188
      }
189
    }
190

  
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

  
193
  MeshBase createFacesCube(int sizeIndex)
194
    {
195
    MeshBase[] meshes = new MeshPolygon[6];
196

  
197
    float E = 0.5f;
198
    int extraI, extraV, num;
199

  
200
    switch(sizeIndex)
201
      {
202
      case 0 : num = 6; extraI = 2; extraV = 2; break;
203
      case 1 : num = 5; extraI = 2; extraV = 2; break;
204
      case 2 : num = 5; extraI = 1; extraV = 2; break;
205
      default: num = 4; extraI = 1; extraV = 1; break;
206
      }
207

  
208
    float[] vertices = { -E,-E, +E,-E, +E,+E, -E,+E };
209
    float[] bands = computeBands(0.048f,35,E,0.7f,num);
210

  
211
    meshes[0] = new MeshPolygon(vertices,bands,extraI,extraV);
212
    meshes[0].setEffectAssociation(0,1,0);
213
    meshes[1] = meshes[0].copy(true);
214
    meshes[1].setEffectAssociation(0,2,0);
215
    meshes[2] = meshes[0].copy(true);
216
    meshes[2].setEffectAssociation(0,4,0);
217
    meshes[3] = meshes[0].copy(true);
218
    meshes[3].setEffectAssociation(0,8,0);
219
    meshes[4] = meshes[0].copy(true);
220
    meshes[4].setEffectAssociation(0,16,0);
221
    meshes[5] = meshes[0].copy(true);
222
    meshes[5].setEffectAssociation(0,32,0);
223

  
224
    return new MeshJoined(meshes);
225
    }
226

  
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

  
229
  MeshBase createFacesSkewbCorner()
230
    {
231
    MeshBase[] meshes = new MeshBase[6];
232

  
233
    float E = 0.5f;
234
    float F = SQ2/2;
235
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
236
    float[] bands0 = computeBands(0.028f,35,E/3,0.7f,7);
237

  
238
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
239
    meshes[0].setEffectAssociation(0,1,0);
240
    meshes[1] = meshes[0].copy(true);
241
    meshes[1].setEffectAssociation(0,2,0);
242
    meshes[2] = meshes[0].copy(true);
243
    meshes[2].setEffectAssociation(0,4,0);
244

  
245
    float[] vertices1 = { 0,0, F,0, 7*F/8,(SQ3/8)*F, 5*F/8,(3*SQ3/8)*F, F/2,(SQ3/2)*F };
246
    float[] bands1 = computeBands(0,0,1,0,3);
247

  
248
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
249
    meshes[3].setEffectAssociation(0,8,0);
250
    meshes[4] = meshes[3].copy(true);
251
    meshes[4].setEffectAssociation(0,16,0);
252
    meshes[5] = meshes[3].copy(true);
253
    meshes[5].setEffectAssociation(0,32,0);
254

  
255
    return new MeshJoined(meshes);
256
    }
257

  
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

  
260
  MeshBase createFacesSkewbFace()
261
    {
262
    MeshBase[] meshes = new MeshBase[5];
263

  
264
    float E = SQ2/4;
265
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
266
    float[] bands0 = computeBands(0.051f,35,E/2,0.9f,7);
267

  
268
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
269
    meshes[0].setEffectAssociation(0,1,0);
270

  
271
    float[] vertices1 = { -E,-SQ3*E, -E*0.7f,-SQ3*E, +E*0.7f,-SQ3*E, +E,-SQ3*E, 0,0 };
272
    float[] bands1 = computeBands(0,0,1,0,3);
273

  
274
    meshes[1] = new MeshPolygon(vertices1,bands1,0,0);
275
    meshes[1].setEffectAssociation(0,2,0);
276
    meshes[2] = meshes[1].copy(true);
277
    meshes[2].setEffectAssociation(0,4,0);
278
    meshes[3] = meshes[1].copy(true);
279
    meshes[3].setEffectAssociation(0,8,0);
280
    meshes[4] = meshes[1].copy(true);
281
    meshes[4].setEffectAssociation(0,16,0);
282

  
283
    return new MeshJoined(meshes);
284
    }
285

  
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

  
288
  MeshBase createFacesOcta()
289
    {
290
    MeshBase[] meshes = new MeshPolygon[8];
291

  
292
    float E = SQ3/2;
293
    float F = 0.5f;
294
    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
295
    float[] bands = computeBands(0.05f,35,F,0.8f,6);
296

  
297
    meshes[0] = new MeshPolygon(vertices, bands, 2,2);
298
    meshes[0].setEffectAssociation(0,1,0);
299
    meshes[1] = meshes[0].copy(true);
300
    meshes[1].setEffectAssociation(0,2,0);
301
    meshes[2] = meshes[0].copy(true);
302
    meshes[2].setEffectAssociation(0,4,0);
303
    meshes[3] = meshes[0].copy(true);
304
    meshes[3].setEffectAssociation(0,8,0);
305
    meshes[4] = meshes[0].copy(true);
306
    meshes[4].setEffectAssociation(0,16,0);
307
    meshes[5] = meshes[0].copy(true);
308
    meshes[5].setEffectAssociation(0,32,0);
309
    meshes[6] = meshes[0].copy(true);
310
    meshes[6].setEffectAssociation(0,64,0);
311
    meshes[7] = meshes[0].copy(true);
312
    meshes[7].setEffectAssociation(0,128,0);
313

  
314
    return new MeshJoined(meshes);
315
    }
316

  
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

  
319
  MeshBase createFacesTetra()
320
    {
321
    MeshBase[] meshes = new MeshBase[4];
322

  
323
    float E = SQ3/2;
324
    float F = 0.5f;
325
    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
326
    float[] bands = computeBands(0.05f,35,F,0.8f,6);
327

  
328
    meshes[0] = new MeshPolygon(vertices, bands, 2,2);
329
    meshes[0].setEffectAssociation(0,1,0);
330
    meshes[1] = meshes[0].copy(true);
331
    meshes[1].setEffectAssociation(0,2,0);
332
    meshes[2] = meshes[0].copy(true);
333
    meshes[2].setEffectAssociation(0,4,0);
334
    meshes[3] = meshes[0].copy(true);
335
    meshes[3].setEffectAssociation(0,8,0);
336

  
337
    return new MeshJoined(meshes);
338
    }
339

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

  
342
  MeshBase createFacesDino()
343
    {
344
    MeshBase[] meshes = new MeshPolygon[4];
345

  
346
    float E = 0.5f*SQ2;
347
    float F = 0.5f;
348
    float[] vertices0 = { -F,F/3, 0,-2*F/3, +F,F/3 };
349
    float[] bands0 = computeBands(0.028f,30,F/3,0.8f,7);
350

  
351
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 5);
352
    meshes[0].setEffectAssociation(0,1,0);
353
    meshes[1] = meshes[0].copy(true);
354
    meshes[1].setEffectAssociation(0,2,0);
355

  
356
    float[] vertices1 = { -E/2,-E*(SQ3/6), E/2,-E*(SQ3/6), 0,E*(SQ3/3) };
357
    float[] bands1 = computeBands(0.02f,45,F/3,0.2f,3);
358

  
359
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
360
    meshes[2].setEffectAssociation(0,4,0);
361
    meshes[3] = meshes[2].copy(true);
362
    meshes[3].setEffectAssociation(0,8,0);
363

  
364
    return new MeshJoined(meshes);
365
    }
366

  
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

  
369
  MeshBase createFacesHelicopterCorner()
370
    {
371
    MeshBase[] meshes = new MeshBase[6];
372

  
373
    float E = 0.5f;
374
    float F = SQ2/4;
375
    float G = 1.0f/12;
376
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
377
    float[] bands0 = computeBands(0.028f,35,E/4,0.7f,7);
378

  
379
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
380
    meshes[0].setEffectAssociation(0,1,0);
381
    meshes[1] = meshes[0].copy(true);
382
    meshes[1].setEffectAssociation(0,2,0);
383
    meshes[2] = meshes[0].copy(true);
384
    meshes[2].setEffectAssociation(0,4,0);
385

  
386
    float[] vertices1 = { -F,-G, 0,-G, +F,-G, 0,2*G };
387
    float[] bands1 = computeBands(0.00f,0,0,0.0f,3);
388
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
389
    meshes[3].setEffectAssociation(0,8,0);
390
    meshes[4] = meshes[3].copy(true);
391
    meshes[4].setEffectAssociation(0,16,0);
392
    meshes[5] = meshes[3].copy(true);
393
    meshes[5].setEffectAssociation(0,32,0);
394

  
395
    return new MeshJoined(meshes);
396
    }
397

  
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

  
400
  MeshBase createFacesHelicopterFace()
401
    {
402
    MeshBase[] meshes = new MeshBase[4];
403

  
404
    float E = 0.5f;
405
    float F = SQ2/4;
406
    float G = 1.0f/12;
407
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
408
    float[] bands0 = computeBands(0.028f,35,E/4,0.7f,7);
409

  
410
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
411
    meshes[0].setEffectAssociation(0,1,0);
412

  
413
    float[] vertices1 = { -F,-G, +F,-G, 0,2*G};
414
    float[] bands1 = computeBands(0.01f,45,F,0.0f,3);
415

  
416
    meshes[1] = new MeshPolygon(vertices1, bands1, 1, 3);
417
    meshes[1].setEffectAssociation(0,2,0);
418

  
419
    float[] vertices2 = { -E/2,-F/3, +E/2,-F/3, 0,2*F/3};
420

  
421
    meshes[2] = new MeshPolygon(vertices2, bands1, 1, 3);
422
    meshes[2].setEffectAssociation(0,4,0);
423
    meshes[3] = meshes[2].copy(true);
424
    meshes[3].setEffectAssociation(0,8,0);
425

  
426
    return new MeshJoined(meshes);
427
    }
428

  
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

  
431
  MeshBase createFacesRediEdge()
432
    {
433
    MeshBase[] meshes = new MeshPolygon[6];
434

  
435
    float F = 0.25f;
436
    float[] vertices0 = { -F,+F, -F,-F, 0, -2*F, +F,-F, +F,+F };
437
    float[] bands0 = computeBands(0.038f,35,F,0.7f,7);
438

  
439
    meshes[0] = new MeshPolygon(vertices0, bands0, 2, 2);
440
    meshes[0].setEffectAssociation(0,1,0);
441
    meshes[1] = meshes[0].copy(true);
442
    meshes[1].setEffectAssociation(0,2,0);
443

  
444
    float[] bands1 = computeBands(0.02f,35,F/2,0.2f,3);
445
    float[] vertices1 = { -F/2, +F/2, -F/2, -1.5f*F, 1.5f*F, +F/2 };
446

  
447
    meshes[2] = new MeshPolygon(vertices1, bands1, 1, 2);
448
    meshes[2].setEffectAssociation(0,4,0);
449
    meshes[3] = meshes[2].copy(true);
450
    meshes[3].setEffectAssociation(0,8,0);
451

  
452
    float X = 0.25f*SQ2;
453
    float Y = SQ6/16;
454
    float[] vertices2 = { -X, Y, -1.5f*X, -Y, +1.5f*X, -Y, +X, Y };
455

  
456
    meshes[4] = new MeshPolygon(vertices2, bands1, 1, 1);
457
    meshes[4].setEffectAssociation(0,16,0);
458
    meshes[5] = meshes[4].copy(true);
459
    meshes[5].setEffectAssociation(0,32,0);
460

  
461
    return new MeshJoined(meshes);
462
    }
463

  
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

  
466
  MeshBase createFacesRediCorner()
467
    {
468
    MeshBase[] meshes = new MeshBase[6];
469

  
470
    float E = 0.5f;
471
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
472
    float[] bands0 = computeBands(0.06f,35,E,0.7f,6);
473

  
474
    meshes[0] = new MeshPolygon(vertices0,bands0,2,2);
475
    meshes[0].setEffectAssociation(0,1,0);
476
    meshes[1] = meshes[0].copy(true);
477
    meshes[1].setEffectAssociation(0,2,0);
478
    meshes[2] = meshes[0].copy(true);
479
    meshes[2].setEffectAssociation(0,4,0);
480

  
481
    float F = SQ2/2;
482
    float X = 0.5f;
483
    float G = 0.72f;
484
    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 };
485
    float[] bands1 = computeBands(0.0f,0,1.0f,0.0f,2);
486

  
487
    meshes[3] = new MeshPolygon(vertices1,bands1,0,0);
488
    meshes[3].setEffectAssociation(0,8,0);
489
    meshes[4] = meshes[3].copy(true);
490
    meshes[4].setEffectAssociation(0,16,0);
491
    meshes[5] = meshes[3].copy(true);
492
    meshes[5].setEffectAssociation(0,32,0);
493

  
494
    return new MeshJoined(meshes);
495
    }
496

  
497
///////////////////////////////////////////////////////////////////////////////////////////////////
498
// EFFECTS
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

  
501
  VertexEffect[] createVertexEffectsCube()
502
    {
503
    Static3D axisY   = new Static3D(0,1,0);
504
    Static3D axisX   = new Static3D(1,0,0);
505
    Static3D center  = new Static3D(0,0,0);
506
    Static1D angle90 = new Static1D(90);
507
    Static1D angle180= new Static1D(180);
508
    Static1D angle270= new Static1D(270);
509

  
510
    VertexEffect[] effect = new VertexEffect[6];
511

  
512
    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
513
    effect[1] = new VertexEffectRotate( angle180, axisX, center );
514
    effect[2] = new VertexEffectRotate( angle90 , axisX, center );
515
    effect[3] = new VertexEffectRotate( angle270, axisX, center );
516
    effect[4] = new VertexEffectRotate( angle270, axisY, center );
517
    effect[5] = new VertexEffectRotate( angle90 , axisY, center );
518

  
519
    effect[0].setMeshAssociation(63,-1);  // all 6 sides
520
    effect[1].setMeshAssociation(32,-1);  // back
521
    effect[2].setMeshAssociation( 8,-1);  // bottom
522
    effect[3].setMeshAssociation( 4,-1);  // top
523
    effect[4].setMeshAssociation( 2,-1);  // left
524
    effect[5].setMeshAssociation( 1,-1);  // right
525

  
526
    return effect;
527
    }
528

  
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

  
531
  VertexEffect[] createVertexEffectsSkewbCorner()
532
    {
533
    float E = 0.5f;
534

  
535
    Static3D axisX  = new Static3D(1,0,0);
536
    Static3D axisY  = new Static3D(0,1,0);
537
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
538
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
539
    Static1D angle1 = new Static1D(+90);
540
    Static1D angle2 = new Static1D(-90);
541
    Static1D angle3 = new Static1D(-15);
542
    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
543
    Static1D angle5 = new Static1D(120);
544
    Static1D angle6 = new Static1D(240);
545
    Static3D center1= new Static3D(0,0,0);
546
    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
547
    Static3D move1  = new Static3D(-E/4,-E/4,0);
548
    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
549

  
550
    VertexEffect[] effect = new VertexEffect[10];
551

  
552
    effect[0] = new VertexEffectMove(move1);
553
    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
554
    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
555
    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
556
    effect[4] = new VertexEffectMove(move2);
557
    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
558
    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
559
    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
560
    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
561
    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
562

  
563
    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
564
    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
565
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
566
    effect[3].setMeshAssociation( 4,-1);  // mesh 2
567
    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
568
    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
569
    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
570
    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
571
    effect[8].setMeshAssociation(16,-1);  // mesh 4
572
    effect[9].setMeshAssociation(32,-1);  // mesh 5
573

  
574
    return effect;
575
    }
576

  
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

  
579
  VertexEffect[] createVertexEffectsSkewbFace()
580
    {
581
    Static3D center = new Static3D(0,0,0);
582
    Static3D axisX  = new Static3D(1,0,0);
583
    Static3D axisZ  = new Static3D(0,0,1);
584
    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
585

  
586
    VertexEffect[] effect = new VertexEffect[6];
587

  
588
    effect[0] = new VertexEffectRotate( new Static1D(angle), axisX, center);
589
    effect[1] = new VertexEffectRotate( new Static1D(  135), axisZ, center);
590
    effect[2] = new VertexEffectRotate( new Static1D(   45), axisZ, center);
591
    effect[3] = new VertexEffectRotate( new Static1D(  -45), axisZ, center);
592
    effect[4] = new VertexEffectRotate( new Static1D( -135), axisZ, center);
593
    effect[5] = new VertexEffectMove( new Static3D(0,0,-0.5f) );
594

  
595
    effect[0].setMeshAssociation(30,-1);  // meshes 1,2,3,4
596
    effect[1].setMeshAssociation( 2,-1);  // mesh 1
597
    effect[2].setMeshAssociation( 5,-1);  // meshes 0,2
598
    effect[3].setMeshAssociation( 8,-1);  // mesh 3
599
    effect[4].setMeshAssociation(16,-1);  // mesh 4
600
    effect[5].setMeshAssociation(30,-1);  // meshes 1,2,3,4
601

  
602
    return effect;
603
    }
604

  
605
///////////////////////////////////////////////////////////////////////////////////////////////////
606

  
607
  VertexEffect[] createVertexEffectsOcta()
608
    {
609
    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
610
    Static1D angle1= new Static1D( 90);
611
    Static1D angle2= new Static1D(180);
612
    Static1D angle3= new Static1D(270);
613
    Static3D move1 = new Static3D(0,SQ2/2-SQ3/3,0);
614
    Static3D axisX = new Static3D(1,0,0);
615
    Static3D axisY = new Static3D(0,1,0);
616
    Static3D cent0 = new Static3D(0,0,0);
617
    Static3D cent1 = new Static3D(0,SQ2/2,0);
618
    Static3D flipY = new Static3D( 1,-1, 1);
619

  
620
    VertexEffect[] effect = new VertexEffect[6];
621

  
622
    effect[0] = new VertexEffectMove(move1);
623
    effect[1] = new VertexEffectRotate(alpha , axisX, cent1);
624
    effect[2] = new VertexEffectRotate(angle1, axisY, cent0);
625
    effect[3] = new VertexEffectRotate(angle2, axisY, cent0);
626
    effect[4] = new VertexEffectRotate(angle3, axisY, cent0);
627
    effect[5] = new VertexEffectScale(flipY);
628

  
629
    effect[2].setMeshAssociation ( 34,-1); // apply to meshes 1 & 5
630
    effect[3].setMeshAssociation ( 68,-1); // apply to meshes 2 & 6
631
    effect[4].setMeshAssociation (136,-1); // apply to meshes 3 & 7
632
    effect[5].setMeshAssociation (240,-1); // apply to meshes 4,5,6,7
633

  
634
    return effect;
635
    }
636

  
637
///////////////////////////////////////////////////////////////////////////////////////////////////
638

  
639
  VertexEffect[] createVertexEffectsTetra()
640
    {
641
    Static3D flipZ = new Static3D( 1, 1,-1);
642

  
643
    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
644
    Static1D angle1= new Static1D( 90);
645
    Static1D angle2= new Static1D(180);
646
    Static3D move1 = new Static3D(0,SQ2/4-SQ3/6,0);
647

  
648
    Static3D axisX = new Static3D(1,0,0);
649
    Static3D axisY = new Static3D(0,1,0);
650
    Static3D axisZ = new Static3D(0,0,1);
651

  
652
    Static3D cent0 = new Static3D(0,0,0);
653
    Static3D cent1 = new Static3D(0,SQ2/4,0);
654

  
655
    VertexEffect[] effect = new VertexEffect[6];
656

  
657
    effect[0] = new VertexEffectRotate(angle2, axisZ, cent0);
658
    effect[1] = new VertexEffectMove(move1);
659
    effect[2] = new VertexEffectRotate(alpha , axisX, cent1);
660
    effect[3] = new VertexEffectScale(flipZ);
661
    effect[4] = new VertexEffectRotate(angle1, axisY, cent0);
662
    effect[5] = new VertexEffectRotate(angle2, axisZ, cent0);
663

  
664
    effect[0].setMeshAssociation(15,-1); // meshes 0,1,2,3
665
    effect[1].setMeshAssociation(15,-1); // meshes 0,1,2,3
666
    effect[2].setMeshAssociation(15,-1); // meshes 0,1,2,3
667
    effect[3].setMeshAssociation(10,-1); // meshes 1 & 3
668
    effect[4].setMeshAssociation(12,-1); // meshes 2 & 3
669
    effect[5].setMeshAssociation(12,-1); // meshes 2 & 3
670

  
671
    return effect;
672
    }
673

  
674
///////////////////////////////////////////////////////////////////////////////////////////////////
675

  
676
  VertexEffect[] createVertexEffectsDino()
677
    {
678
    float E = 0.5f*SQ2;
679
    float F = 0.5f;
680
    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
681

  
682
    Static1D angle1 = new Static1D(-ANGLE);
683
    Static1D angle2 = new Static1D(+ANGLE);
684
    Static3D axisX  = new Static3D(1,0,0);
685
    Static3D axisY  = new Static3D(0,1,0);
686
    Static3D axisZ  = new Static3D(0,-1,1);
687
    Static3D center0= new Static3D(0,0,0);
688
    Static3D center1= new Static3D(0,-3*F,0);
689

  
690
    VertexEffect[] effect = new VertexEffect[10];
691

  
692
    effect[0] = new VertexEffectScale ( new Static3D(3,3,3) );
693
    effect[1] = new VertexEffectMove  ( new Static3D(0,-F,0) );
694
    effect[2] = new VertexEffectRotate( new Static1D(90), axisX, center0 );
695
    effect[3] = new VertexEffectScale ( new Static3D(1,-1,1) );
696
    effect[4] = new VertexEffectMove  ( new Static3D(3*E/2,E*(SQ3/2)-3*F,0) );
697
    effect[5] = new VertexEffectRotate( new Static1D(+90), axisY, center1 );
698
    effect[6] = new VertexEffectScale ( new Static3D(-1,1,1) );
699
    effect[7] = new VertexEffectRotate( new Static1D( 45), axisX, center1 );
700
    effect[8] = new VertexEffectRotate( angle1           , axisZ, center1 );
701
    effect[9] = new VertexEffectRotate( angle2           , axisZ, center1 );
702

  
703
    effect[0].setMeshAssociation(15,-1);  // apply to meshes 0,1,2,3
704
    effect[1].setMeshAssociation( 3,-1);  // apply to meshes 0,1
705
    effect[2].setMeshAssociation( 2,-1);  // apply to mesh 1
706
    effect[3].setMeshAssociation( 2,-1);  // apply to mesh 0
707
    effect[4].setMeshAssociation(12,-1);  // apply to meshes 2,3
708
    effect[5].setMeshAssociation(12,-1);  // apply to meshes 2,3
709
    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
710
    effect[7].setMeshAssociation(12,-1);  // apply to meshes 2,3
711
    effect[8].setMeshAssociation( 4,-1);  // apply to mesh 2
712
    effect[9].setMeshAssociation( 8,-1);  // apply to mesh 3
713

  
714
    return effect;
715
    }
716

  
717
///////////////////////////////////////////////////////////////////////////////////////////////////
718

  
719
  VertexEffect[] createVertexEffectsHelicopterCorner()
720
    {
721
    float E = 0.5f;
722

  
723
    Static3D axisX  = new Static3D(1,0,0);
724
    Static3D axisY  = new Static3D(0,1,0);
725
    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
726
    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
727
    Static1D angle1 = new Static1D(+90);
728
    Static1D angle2 = new Static1D(-90);
729
    Static1D angle3 = new Static1D(-135);
730
    Static1D angle4 = new Static1D(90);
731
    Static1D angle5 = new Static1D(120);
732
    Static1D angle6 = new Static1D(240);
733
    Static3D center1= new Static3D(0,0,0);
734
    Static3D center2= new Static3D(-0.25f,-0.25f,-0.25f);
735
    Static3D move1  = new Static3D(-E/4,-E/4,0);
736
    Static3D move2  = new Static3D(-0.25f,(-1.0f/6)-0.25f,-0.25f);
737

  
738
    VertexEffect[] effect = new VertexEffect[10];
739

  
740
    effect[0] = new VertexEffectMove(move1);
741
    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
742
    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
743
    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
744
    effect[4] = new VertexEffectMove(move2);
745
    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
746
    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
747
    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
748
    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
749
    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
750

  
751
    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
752
    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
753
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
754
    effect[3].setMeshAssociation( 4,-1);  // mesh 2
755
    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
756
    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
757
    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
758
    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
759
    effect[8].setMeshAssociation(16,-1);  // mesh 4
760
    effect[9].setMeshAssociation(32,-1);  // mesh 5
761

  
762
    return effect;
763
    }
764

  
765
///////////////////////////////////////////////////////////////////////////////////////////////////
766

  
767
  VertexEffect[] createVertexEffectsHelicopterFace()
768
    {
769
    float E = 0.5f;
770
    float F = SQ2/4;
771

  
772
    Static3D move0  = new Static3D(-E/4, -E/4, 0);
773
    Static3D move1  = new Static3D(-(SQ2/24)-E/2, -(SQ2/24)-E/2, 0);
774
    Static3D move2  = new Static3D(-E/2, F/3, 0);
775
    Static3D move3  = new Static3D(+E/2, F/3, 0);
776
    Static3D move4  = new Static3D(+E/3,+E/3, 0);
777
    Static1D angle1 = new Static1D(135);
778
    Static1D angle2 = new Static1D(90);
779
    Static1D angle3 = new Static1D(-90);
780
    Static1D angle4 = new Static1D(-135);
781
    Static3D axisX  = new Static3D(1,0,0);
782
    Static3D axisY  = new Static3D(0,1,0);
783
    Static3D axisZ  = new Static3D(0,0,1);
784
    Static3D axis1  = new Static3D(1,-1,0);
785
    Static3D center = new Static3D(0,0,0);
786
    Static3D center1= new Static3D(-E/2,-E/2,0);
787

  
788
    VertexEffect[] effect = new VertexEffect[10];
789

  
790
    effect[0] = new VertexEffectMove(move0);
791
    effect[1] = new VertexEffectRotate(angle1, axisZ, center);
792
    effect[2] = new VertexEffectMove(move1);
793
    effect[3] = new VertexEffectRotate(angle2, axis1, center1);
794
    effect[4] = new VertexEffectMove(move2);
795
    effect[5] = new VertexEffectMove(move3);
796
    effect[6] = new VertexEffectRotate(angle3, axisZ, center);
797
    effect[7] = new VertexEffectRotate(angle4, axisX, center);
798
    effect[8] = new VertexEffectRotate(angle1, axisY, center);
799
    effect[9] = new VertexEffectMove(move4);
800

  
801
    effect[0].setMeshAssociation( 1,-1);  // mesh 0
802
    effect[1].setMeshAssociation( 2,-1);  // mesh 1
803
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
804
    effect[3].setMeshAssociation( 2,-1);  // mesh 1
805
    effect[4].setMeshAssociation( 4,-1);  // mesh 2
806
    effect[5].setMeshAssociation( 8,-1);  // mesh 3
807
    effect[6].setMeshAssociation( 8,-1);  // mesh 3
808
    effect[7].setMeshAssociation( 4,-1);  // mesh 2
809
    effect[8].setMeshAssociation( 8,-1);  // mesh 3
810
    effect[9].setMeshAssociation(15,-1);  // meshes 0,1,2,3
811

  
812
    return effect;
813
    }
814

  
815
///////////////////////////////////////////////////////////////////////////////////////////////////
816

  
817
  VertexEffect[] createVertexEffectsRediEdge()
818
    {
819
    Static3D move0 = new Static3D(0.0f, -0.5f, 0.0f);
820
    Static3D move1 = new Static3D(0.25f, -0.25f, 0.0f);
821
    Static3D move2 = new Static3D(0.5f, 0.0f, 0.0f);
822
    Static3D move3 = new Static3D(0.0f, (SQ3-6)/8, (SQ3-6)/8);
823
    Static3D flipZ = new Static3D(1,1,-1);
824
    Static3D flipX = new Static3D(-1,1,1);
825
    Static3D scale = new Static3D(2,2,2);
826
    Static3D cent0 = new Static3D(0,0, 0);
827
    Static3D cent1 = new Static3D(0,0, -1.5f);
828
    Static3D axisX = new Static3D(1,0, 0);
829
    Static3D axisY = new Static3D(0,1, 0);
830
    Static3D axis  = new Static3D(0,SQ2/2,-SQ2/2);
831
    Static1D angle1= new Static1D(90);
832
    Static1D angle2= new Static1D(45);
833
    Static1D angle3= new Static1D( (float)(180/Math.PI*Math.acos(SQ3/3)) );
834

  
835
    VertexEffect[] effect = new VertexEffect[12];
836

  
837
    effect[0] = new VertexEffectScale(scale);
838
    effect[1] = new VertexEffectMove(move0);
839
    effect[2] = new VertexEffectScale(flipZ);
840
    effect[3] = new VertexEffectRotate(angle1,axisX,cent0);
841
    effect[4] = new VertexEffectMove(move1);
842
    effect[5] = new VertexEffectRotate(angle1,axisY,cent0);
843
    effect[6] = new VertexEffectMove(move2);
844
    effect[7] = new VertexEffectScale(flipX);
845
    effect[8] = new VertexEffectRotate(angle2,axisX,cent0);
846
    effect[9] = new VertexEffectMove(move3);
847
    effect[10]= new VertexEffectRotate(angle3,axis ,cent1);
848
    effect[11]= new VertexEffectScale(flipX);
849

  
850
    effect[0].setMeshAssociation(63,-1);  // meshes 0,1,2,3,4,5
851
    effect[1].setMeshAssociation( 3,-1);  // meshes 0,1
852
    effect[2].setMeshAssociation( 2,-1);  // mesh 1
853
    effect[3].setMeshAssociation( 2,-1);  // mesh 1
854
    effect[4].setMeshAssociation(12,-1);  // meshes 2,3
855
    effect[5].setMeshAssociation(60,-1);  // meshes 2,3,4,5
856
    effect[6].setMeshAssociation(12,-1);  // meshes 2,3
857
    effect[7].setMeshAssociation( 8,-1);  // mesh 3
858
    effect[8].setMeshAssociation(48,-1);  // meshes 4,5
859
    effect[9].setMeshAssociation(48,-1);  // meshes 4,5
860
    effect[10].setMeshAssociation(48,-1); // meshes 4,5
861
    effect[11].setMeshAssociation(32,-1); // mesh 5
862

  
863
    return effect;
864
    }
865

  
866
///////////////////////////////////////////////////////////////////////////////////////////////////
867

  
868
  VertexEffect[] createVertexEffectsRediCorner()
869
    {
870
    Static3D axisY   = new Static3D(0,1,0);
871
    Static3D axisX   = new Static3D(1,0,0);
872
    Static3D axisZ   = new Static3D(0,0,1);
873
    Static3D center  = new Static3D(0,0,0);
874
    Static1D angle90 = new Static1D(90);
875
    Static1D angle270= new Static1D(270);
876
    Static1D angle45 = new Static1D(-45);
877

  
878
    VertexEffect[] effect = new VertexEffect[6];
879

  
880
    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
881
    effect[1] = new VertexEffectRotate( angle270, axisX, center );
882
    effect[2] = new VertexEffectRotate( angle90 , axisY, center );
883
    effect[3] = new VertexEffectRotate( angle45 , axisX, center );
884
    effect[4] = new VertexEffectRotate( angle90 , axisY, center );
885
    effect[5] = new VertexEffectRotate( angle270, axisZ, center );
886

  
887
    effect[0].setMeshAssociation( 7,-1);  // 0,1,2
888
    effect[1].setMeshAssociation( 2,-1);  // 1
889
    effect[2].setMeshAssociation( 4,-1);  // 2
890
    effect[3].setMeshAssociation(56,-1);  // 3
891
    effect[4].setMeshAssociation(16,-1);  // 4
892
    effect[5].setMeshAssociation(32,-1);  // 5
893

  
894
    return effect;
895
    }
896

  
897
///////////////////////////////////////////////////////////////////////////////////////////////////
898
// OBJECTS
899
///////////////////////////////////////////////////////////////////////////////////////////////////
900
// CUBE
901

  
902
  MeshBase createCubeMesh(int index)
903
    {
904
    MeshBase mesh = createFacesCube(index);
905
    VertexEffect[] effects = createVertexEffectsCube();
906
    for( VertexEffect effect : effects ) mesh.apply(effect);
907

  
908
    Static3D roundingCenter  = new Static3D(0,0,0);
909
    Static3D[] vertices = new Static3D[8];
910
    vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
911
    vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
912
    vertices[2] = new Static3D(+0.5f,-0.5f,+0.5f);
913
    vertices[3] = new Static3D(+0.5f,-0.5f,-0.5f);
914
    vertices[4] = new Static3D(-0.5f,+0.5f,+0.5f);
915
    vertices[5] = new Static3D(-0.5f,+0.5f,-0.5f);
916
    vertices[6] = new Static3D(-0.5f,-0.5f,+0.5f);
917
    vertices[7] = new Static3D(-0.5f,-0.5f,-0.5f);
918

  
919
    roundCorners(mesh,roundingCenter,vertices,0.06f,0.12f);
920

  
921
    mesh.mergeEffComponents();
922

  
923
    return mesh;
924
    }
925

  
926
///////////////////////////////////////////////////////////////////////////////////////////////////
927
// SKEWB
928

  
929
  MeshBase createSkewbCornerMesh()
930
    {
931
    MeshBase mesh = createFacesSkewbCorner();
932
    VertexEffect[] effects = createVertexEffectsSkewbCorner();
933
    for( VertexEffect effect : effects ) mesh.apply(effect);
934

  
935
    float E = 0.5f;
936
    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
937

  
938
    Static3D[] verticesType1 = new Static3D[1];
939
    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
940
    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
941

  
942
    Static3D[] verticesType2 = new Static3D[3];
943
    verticesType2[0] = new Static3D(-E, 0, 0);
944
    verticesType2[1] = new Static3D( 0,-E, 0);
945
    verticesType2[2] = new Static3D( 0, 0,-E);
946
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
947

  
948
    mesh.mergeEffComponents();
949

  
950
    return mesh;
951
    }
952

  
953
///////////////////////////////////////////////////////////////////////////////////////////////////
954

  
955
  MeshBase createSkewbFaceMesh()
956
    {
957
    MeshBase mesh = createFacesSkewbFace();
958
    VertexEffect[] effects = createVertexEffectsSkewbFace();
959
    for( VertexEffect effect : effects ) mesh.apply(effect);
960

  
961
    Static3D roundingCenter = new Static3D(0,0,-0.2f);
962
    float E = SQ2/4;
963
    Static3D[] vertices = new Static3D[4];
964
    vertices[0] = new Static3D(-E*SQ2,      0, 0);
965
    vertices[1] = new Static3D(+E*SQ2,      0, 0);
966
    vertices[2] = new Static3D(     0, -E*SQ2, 0);
967
    vertices[3] = new Static3D(     0, +E*SQ2, 0);
968
    roundCorners(mesh,roundingCenter,vertices,0.10f,0.10f);
969

  
970
    mesh.mergeEffComponents();
971
    mesh.addEmptyTexComponent();
972

  
973
    return mesh;
974
    }
975

  
976
///////////////////////////////////////////////////////////////////////////////////////////////////
977
// SKEWB DIAMOND / PYRAMINX
978

  
979
  MeshBase createOctaMesh()
980
    {
981
    MeshBase mesh = createFacesOcta();
982
    VertexEffect[] effects = createVertexEffectsOcta();
983
    for( VertexEffect effect : effects ) mesh.apply(effect);
984

  
985
    Static3D roundingCenter = new Static3D(0,0,0);
986
    Static3D[] vertices = new Static3D[6];
987
    vertices[0] = new Static3D(    0, SQ2/2,    0 );
988
    vertices[1] = new Static3D( 0.5f,     0, 0.5f );
989
    vertices[2] = new Static3D(-0.5f,     0, 0.5f );
990
    vertices[3] = new Static3D(    0,-SQ2/2,    0 );
991
    vertices[4] = new Static3D(-0.5f,     0,-0.5f );
992
    vertices[5] = new Static3D( 0.5f,     0,-0.5f );
993

  
994
    roundCorners(mesh,roundingCenter,vertices,0.06f,0.20f);
995

  
996
    mesh.mergeEffComponents();
997

  
998
    return mesh;
999
    }
1000

  
1001
///////////////////////////////////////////////////////////////////////////////////////////////////
1002

  
1003
  MeshBase createTetraMesh()
1004
    {
1005
    MeshBase mesh = createFacesTetra();
1006
    VertexEffect[] effects = createVertexEffectsTetra();
1007
    for( VertexEffect effect : effects ) mesh.apply(effect);
1008

  
1009
    Static3D roundingCenter = new Static3D(0,0,0);
1010
    Static3D[] verticesRound = new Static3D[4];
1011
    verticesRound[0] = new Static3D(-0.5f,+SQ2/4,   0 );
1012
    verticesRound[1] = new Static3D(+0.5f,+SQ2/4,   0 );
1013
    verticesRound[2] = new Static3D(    0,-SQ2/4,+0.5f);
1014
    verticesRound[3] = new Static3D(    0,-SQ2/4,-0.5f);
1015
    roundCorners(mesh,roundingCenter,verticesRound,0.08f,0.15f);
1016

  
1017
    mesh.mergeEffComponents();
1018
    mesh.addEmptyTexComponent();
1019
    mesh.addEmptyTexComponent();
1020
    mesh.addEmptyTexComponent();
1021
    mesh.addEmptyTexComponent();
1022

  
1023
    return mesh;
1024
    }
1025

  
1026
///////////////////////////////////////////////////////////////////////////////////////////////////
1027
// DINO
1028

  
1029
  MeshBase createDinoMesh()
1030
    {
1031
    MeshBase mesh = createFacesDino();
1032
    VertexEffect[] effects = createVertexEffectsDino();
1033
    for( VertexEffect effect : effects ) mesh.apply(effect);
1034

  
1035
    float F = 0.5f;
1036
    Static3D roundingCenter = new Static3D(0.0f, -1.5f*F, -1.5f*F);
1037
    Static3D[] verticesRound = new Static3D[4];
1038
    verticesRound[0] = new Static3D(     0,-3*F,    0 );
1039
    verticesRound[1] = new Static3D(     0,   0, -3*F );
1040
    verticesRound[2] = new Static3D(  -3*F,   0,    0 );
1041
    verticesRound[3] = new Static3D(  +3*F,   0,    0 );
1042
    roundCorners(mesh,roundingCenter,verticesRound,0.10f,0.40f);
1043

  
1044
    mesh.mergeEffComponents();
1045

  
1046
    return mesh;
1047
    }
1048

  
1049
///////////////////////////////////////////////////////////////////////////////////////////////////
1050
// Helicopter
1051

  
1052
  MeshBase createHelicopterCornerMesh()
1053
    {
1054
    MeshBase mesh = createFacesHelicopterCorner();
1055
    VertexEffect[] effects = createVertexEffectsHelicopterCorner();
1056
    for( VertexEffect effect : effects ) mesh.apply(effect);
1057

  
1058
    float E = 0.5f;
1059
    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
1060

  
1061
    Static3D[] verticesType1 = new Static3D[1];
1062
    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
1063
    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
1064

  
1065
    Static3D[] verticesType2 = new Static3D[3];
1066
    verticesType2[0] = new Static3D(-E, 0, 0);
1067
    verticesType2[1] = new Static3D( 0,-E, 0);
1068
    verticesType2[2] = new Static3D( 0, 0,-E);
1069
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
1070

  
1071
    mesh.mergeEffComponents();
1072

  
1073
    return mesh;
1074
    }
1075

  
1076
///////////////////////////////////////////////////////////////////////////////////////////////////
1077

  
1078
  MeshBase createHelicopterFaceMesh()
1079
    {
1080
    MeshBase mesh = createFacesHelicopterFace();
1081
    VertexEffect[] effects = createVertexEffectsHelicopterFace();
1082
    for( VertexEffect effect : effects ) mesh.apply(effect);
1083

  
1084
    float E = 0.5f;
1085
    Static3D roundingCenter = new Static3D(-E/2 + E/3,-E/2 + E/3,-E/2);
1086

  
1087
    Static3D[] verticesType1 = new Static3D[1];
1088
    verticesType1[0] = new Static3D(E/3,E/3,0.0f);
1089
    roundCorners(mesh,roundingCenter,verticesType1,0.06f,0.15f);
1090

  
1091
    Static3D[] verticesType2 = new Static3D[2];
1092
    verticesType2[0] = new Static3D(-E+E/3, E/3  , 0);
1093
    verticesType2[1] = new Static3D( E/3  ,-E+E/3, 0);
1094
    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
1095

  
1096
    mesh.mergeEffComponents();
1097
    mesh.addEmptyTexComponent();
1098
    mesh.addEmptyTexComponent();
1099

  
1100
    return mesh;
1101
    }
1102

  
1103
///////////////////////////////////////////////////////////////////////////////////////////////////
1104
// Redi cube
1105

  
1106
  MeshBase createRediEdgeMesh()
1107
    {
1108
    MeshBase mesh = createFacesRediEdge();
1109
    VertexEffect[] effects = createVertexEffectsRediEdge();
1110
    for( VertexEffect effect : effects ) mesh.apply(effect);
1111

  
1112
    Static3D center = new Static3D(0.0f,-0.75f,-0.75f);
1113
    Static3D[] vertices = new Static3D[2];
1114
    vertices[0] = new Static3D( 0.5f, 0.0f, 0.0f);
1115
    vertices[1] = new Static3D(-0.5f, 0.0f, 0.0f);
1116
    roundCorners(mesh,center,vertices,0.06f,0.20f);
1117

  
1118
    mesh.mergeEffComponents();
1119

  
1120
    return mesh;
1121
    }
1122

  
1123
///////////////////////////////////////////////////////////////////////////////////////////////////
1124

  
1125
  MeshBase createRediCornerMesh()
1126
    {
1127
    MeshBase mesh = createFacesRediCorner();
1128
    VertexEffect[] effects = createVertexEffectsRediCorner();
1129
    for( VertexEffect effect : effects ) mesh.apply(effect);
1130

  
1131
    Static3D center = new Static3D(0,0,0);
1132
    Static3D[] vertices = new Static3D[8];
1133
    vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
1134
    vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
1135
    vertices[2] = new Static3D(+0.5f,-0.5f,+0.5f);
1136
    vertices[3] = new Static3D(+0.5f,-0.5f,-0.5f);
1137
    vertices[4] = new Static3D(-0.5f,+0.5f,+0.5f);
1138
    vertices[5] = new Static3D(-0.5f,+0.5f,-0.5f);
1139
    vertices[6] = new Static3D(-0.5f,-0.5f,+0.5f);
1140
    vertices[7] = new Static3D(-0.5f,-0.5f,-0.5f);
1141

  
1142
    roundCorners(mesh,center,vertices,0.06f,0.12f);
1143

  
1144
    mesh.mergeEffComponents();
1145

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

  
20
package org.distorted.objects;
21

  
22
import org.distorted.library.effect.VertexEffect;
23
import org.distorted.library.effect.VertexEffectDeform;
24
import org.distorted.library.effect.VertexEffectMove;
25
import org.distorted.library.effect.VertexEffectRotate;
26
import org.distorted.library.effect.VertexEffectScale;
27
import org.distorted.library.mesh.MeshBase;
28
import org.distorted.library.mesh.MeshJoined;
29
import org.distorted.library.mesh.MeshPolygon;
30
import org.distorted.library.type.Static1D;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33

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

  
36
class FactoryCubit
37
  {
38
  private static final float SQ2 = (float)Math.sqrt(2);
39
  private static final float SQ3 = (float)Math.sqrt(3);
40
  private static final float SQ6 = (float)Math.sqrt(6);
41

  
42
  private static final Static1D RADIUS = new Static1D(1);
43

  
44
  private static FactoryCubit mThis;
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private FactoryCubit()
49
    {
50

  
51
    }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  public static FactoryCubit getInstance()
56
    {
57
    if( mThis==null ) mThis = new FactoryCubit();
58

  
59
    return mThis;
60
    }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
// H - height of the band in the middle
64
// alpha - angle of the edge  [0,90]
65
// dist - often in a polygon the distance from edge to center is not 1, but something else.
66
// This is the distance.
67
// K - where to begin the second, much more flat part of the band. [0,1]
68
// N - number of bands. N>=3
69
//
70
// theory: two distinct parts to the band:
71
// 1) (0,B) - steep
72
// 2) (B,1) - flat
73
//
74
// In first part, we have y = g(x) ; in second - y = g(f(x)) where
75
//
76
// g(x) = sqrt( R^2 - (x-D)^2 ) - R*cos(alpha)
77
// f(x) = ((D-B)/(1-B)*x + B*(1-D)/(1-B)
78
// h(x) = R*(sin(alpha) - sin(x))
79
// R = H/(1-cos(alpha))
80
// D = H*sin(alpha)
81
// B = h(K*alpha)
82
//
83
// The N points are taken at:
84
//
85
// 1) in the second part, there are K2 = (N-3)/3 such points
86
// 2) in the first - K1 = (N-3) - K2
87
// 3) also, the 3 points 0,B,1
88
//
89
// so we have the sequence A[i] of N points
90
//
91
// 0
92
// h((i+1)*(1-K)*alpha/(K1+1)) (i=0,1,...,K1-1)
93
// B
94
// (1-B)*(i+1)/(K2+1) + B   (i=0,i,...,K2-1)
95
// 1
96

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

  
99
  private float f(float D, float B, float x)
100
    {
101
    return ((D-B)*x + B*(1-D))/(1-B);
102
    }
103

  
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

  
106
  private float g(float R, float D, float x, float cosAlpha)
107
    {
108
    float d = x-D;
109
    return (float)(Math.sqrt(R*R-d*d)-R*cosAlpha);
110
    }
111

  
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

  
114
  private float h(float R, float sinAlpha, float x)
115
    {
116
    return R*(sinAlpha-(float)Math.sin(x));
117
    }
118

  
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

  
121
  private float[] computeBands(float H, int alpha, float dist, float K, int N)
122
    {
123
    float[] bands = new float[2*N];
124

  
125
    bands[0] = 1.0f;
126
    bands[1] = 0.0f;
127

  
128
    float beta = (float)Math.atan(dist*Math.tan(Math.PI*alpha/180));
129
    float sinBeta = (float)Math.sin(beta);
130
    float cosBeta = (float)Math.cos(beta);
131
    float R = cosBeta<1.0f ? H/(1.0f-cosBeta) : 0.0f;
132
    float D = R*sinBeta;
133
    float B = h(R,sinBeta,K*beta);
134

  
135
    if( D>1.0f )
136
      {
137
      for(int i=1; i<N; i++)
138
        {
139
        bands[2*i  ] = (float)(N-1-i)/(N-1);
140
        bands[2*i+1] = H*(1-bands[2*i]);
141
        }
142
      }
143
    else
144
      {
145
      int K2 = (int)((N-3)*K);
146
      int K1 = (N-3)-K2;
147

  
148
      for(int i=0; i<=K1; i++)
149
        {
150
        float angle = K*beta + (1-K)*beta*(K1-i)/(K1+1);
151
        float x = h(R,sinBeta,angle);
152
        bands[2*i+2] = 1.0f - x;
153
        bands[2*i+3] = g(R,D,x,cosBeta);
154
        }
155

  
156
      for(int i=0; i<=K2; i++)
157
        {
158
        float x = (1-B)*(i+1)/(K2+1) + B;
159
        bands[2*K1+2 + 2*i+2] = 1.0f - x;
160
        bands[2*K1+2 + 2*i+3] = g(R,D,f(D,B,x),cosBeta);
161
        }
162
      }
163

  
164
    bands[2*N-2] = 0.0f;
165
    bands[2*N-1] =    H;
166

  
167
    return bands;
168
    }
169

  
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

  
172
  private void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius)
173
    {
174
    Static4D reg= new Static4D(0,0,0,regionRadius);
175

  
176
    float centX = center.get0();
177
    float centY = center.get1();
178
    float centZ = center.get2();
179

  
180
    for (Static3D vertex : vertices)
181
      {
182
      float x = strength*(centX - vertex.get0());
183
      float y = strength*(centY - vertex.get1());
184
      float z = strength*(centZ - vertex.get2());
185

  
186
      VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg);
187
      mesh.apply(effect);
188
      }
189
    }
190

  
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

  
193
  MeshBase createFacesCube(int sizeIndex)
194
    {
195
    MeshBase[] meshes = new MeshPolygon[6];
196

  
197
    float E = 0.5f;
198
    int extraI, extraV, num;
199

  
200
    switch(sizeIndex)
201
      {
202
      case 0 : num = 6; extraI = 2; extraV = 2; break;
203
      case 1 : num = 5; extraI = 2; extraV = 2; break;
204
      case 2 : num = 5; extraI = 1; extraV = 2; break;
205
      default: num = 4; extraI = 1; extraV = 1; break;
206
      }
207

  
208
    float[] vertices = { -E,-E, +E,-E, +E,+E, -E,+E };
209
    float[] bands = computeBands(0.048f,35,E,0.7f,num);
210

  
211
    meshes[0] = new MeshPolygon(vertices,bands,extraI,extraV);
212
    meshes[0].setEffectAssociation(0,1,0);
213
    meshes[1] = meshes[0].copy(true);
214
    meshes[1].setEffectAssociation(0,2,0);
215
    meshes[2] = meshes[0].copy(true);
216
    meshes[2].setEffectAssociation(0,4,0);
217
    meshes[3] = meshes[0].copy(true);
218
    meshes[3].setEffectAssociation(0,8,0);
219
    meshes[4] = meshes[0].copy(true);
220
    meshes[4].setEffectAssociation(0,16,0);
221
    meshes[5] = meshes[0].copy(true);
222
    meshes[5].setEffectAssociation(0,32,0);
223

  
224
    return new MeshJoined(meshes);
225
    }
226

  
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

  
229
  MeshBase createFacesSkewbCorner()
230
    {
231
    MeshBase[] meshes = new MeshBase[6];
232

  
233
    float E = 0.5f;
234
    float F = SQ2/2;
235
    float[] vertices0 = { -E+E/4,E/4, E/4,-E+E/4, E/4,E/4};
236
    float[] bands0 = computeBands(0.028f,35,E/3,0.7f,7);
237

  
238
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
239
    meshes[0].setEffectAssociation(0,1,0);
240
    meshes[1] = meshes[0].copy(true);
241
    meshes[1].setEffectAssociation(0,2,0);
242
    meshes[2] = meshes[0].copy(true);
243
    meshes[2].setEffectAssociation(0,4,0);
244

  
245
    float[] vertices1 = { 0,0, F,0, 7*F/8,(SQ3/8)*F, 5*F/8,(3*SQ3/8)*F, F/2,(SQ3/2)*F };
246
    float[] bands1 = computeBands(0,0,1,0,3);
247

  
248
    meshes[3] = new MeshPolygon(vertices1,bands1,1,5);
249
    meshes[3].setEffectAssociation(0,8,0);
250
    meshes[4] = meshes[3].copy(true);
251
    meshes[4].setEffectAssociation(0,16,0);
252
    meshes[5] = meshes[3].copy(true);
253
    meshes[5].setEffectAssociation(0,32,0);
254

  
255
    return new MeshJoined(meshes);
256
    }
257

  
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

  
260
  MeshBase createFacesSkewbFace()
261
    {
262
    MeshBase[] meshes = new MeshBase[5];
263

  
264
    float E = SQ2/4;
265
    float[] vertices0 = { -E,-E, +E,-E, +E,+E, -E,+E };
266
    float[] bands0 = computeBands(0.051f,35,E/2,0.9f,7);
267

  
268
    meshes[0] = new MeshPolygon(vertices0, bands0, 3, 3);
269
    meshes[0].setEffectAssociation(0,1,0);
270

  
271
    float[] vertices1 = { -E,-SQ3*E, -E*0.7f,-SQ3*E, +E*0.7f,-SQ3*E, +E,-SQ3*E, 0,0 };
272
    float[] bands1 = computeBands(0,0,1,0,3);
273

  
274
    meshes[1] = new MeshPolygon(vertices1,bands1,0,0);
275
    meshes[1].setEffectAssociation(0,2,0);
276
    meshes[2] = meshes[1].copy(true);
277
    meshes[2].setEffectAssociation(0,4,0);
278
    meshes[3] = meshes[1].copy(true);
279
    meshes[3].setEffectAssociation(0,8,0);
280
    meshes[4] = meshes[1].copy(true);
281
    meshes[4].setEffectAssociation(0,16,0);
282

  
283
    return new MeshJoined(meshes);
284
    }
285

  
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

  
288
  MeshBase createFacesOcta()
289
    {
290
    MeshBase[] meshes = new MeshPolygon[8];
291

  
292
    float E = SQ3/2;
293
    float F = 0.5f;
294
    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
295
    float[] bands = computeBands(0.05f,35,F,0.8f,6);
296

  
297
    meshes[0] = new MeshPolygon(vertices, bands, 2,2);
298
    meshes[0].setEffectAssociation(0,1,0);
299
    meshes[1] = meshes[0].copy(true);
300
    meshes[1].setEffectAssociation(0,2,0);
301
    meshes[2] = meshes[0].copy(true);
302
    meshes[2].setEffectAssociation(0,4,0);
303
    meshes[3] = meshes[0].copy(true);
304
    meshes[3].setEffectAssociation(0,8,0);
305
    meshes[4] = meshes[0].copy(true);
306
    meshes[4].setEffectAssociation(0,16,0);
307
    meshes[5] = meshes[0].copy(true);
308
    meshes[5].setEffectAssociation(0,32,0);
309
    meshes[6] = meshes[0].copy(true);
310
    meshes[6].setEffectAssociation(0,64,0);
311
    meshes[7] = meshes[0].copy(true);
312
    meshes[7].setEffectAssociation(0,128,0);
313

  
314
    return new MeshJoined(meshes);
315
    }
316

  
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

  
319
  MeshBase createFacesTetra()
320
    {
321
    MeshBase[] meshes = new MeshBase[4];
322

  
323
    float E = SQ3/2;
324
    float F = 0.5f;
325
    float[] vertices = { -F,-E/3, +F,-E/3, 0.0f,2*E/3};
326
    float[] bands = computeBands(0.05f,35,F,0.8f,6);
327

  
328
    meshes[0] = new MeshPolygon(vertices, bands, 2,2);
329
    meshes[0].setEffectAssociation(0,1,0);
330
    meshes[1] = meshes[0].copy(true);
331
    meshes[1].setEffectAssociation(0,2,0);
332
    meshes[2] = meshes[0].copy(true);
333
    meshes[2].setEffectAssociation(0,4,0);
334
    meshes[3] = meshes[0].copy(true);
335
    meshes[3].setEffectAssociation(0,8,0);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff